Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
c6dc716
[SPARK-37960][SQL] Reactor framework so as compile expression by JDBC…
beliefer Feb 12, 2022
fed8c2b
Update code
beliefer Feb 12, 2022
c6c9d82
Update code
beliefer Feb 14, 2022
2f44d5d
Update code
beliefer Feb 14, 2022
6666635
Update code
beliefer Feb 14, 2022
1d377b8
Update code
beliefer Feb 14, 2022
1c77ff2
Update code
beliefer Feb 15, 2022
aa5974d
Update code
beliefer Feb 19, 2022
451fd2b
Update code
beliefer Feb 20, 2022
dc0d7e6
Update code
beliefer Feb 21, 2022
dbcfd48
Update code
beliefer Feb 22, 2022
343cb85
Update code
beliefer Feb 22, 2022
46d0bdd
Update code
beliefer Feb 22, 2022
6dfbad2
Update code
beliefer Feb 22, 2022
affec97
Update code
beliefer Feb 22, 2022
40af215
Update code
beliefer Feb 22, 2022
006dc97
Update code
beliefer Feb 22, 2022
083b954
Update code
beliefer Feb 22, 2022
9e68fae
Update code
beliefer Feb 23, 2022
96196b0
Update code
beliefer Feb 23, 2022
7fa8efe
Update code
beliefer Feb 23, 2022
349f672
Update code
beliefer Feb 23, 2022
51b0d13
Update code
beliefer Feb 24, 2022
7388fb5
Update code
beliefer Feb 24, 2022
0ea06a4
Update code
beliefer Feb 24, 2022
0ab4669
Update code
beliefer Feb 24, 2022
e0f59c1
Update code
beliefer Feb 24, 2022
0254def
Update code
beliefer Feb 24, 2022
7be4ac3
Update code
beliefer Feb 24, 2022
d17366f
Update code
beliefer Feb 24, 2022
d9392a7
Update code
beliefer Feb 25, 2022
78164a8
Update code
beliefer Feb 25, 2022
b78ebd5
Update sql/catalyst/src/main/java/org/apache/spark/sql/connector/expr…
beliefer Feb 25, 2022
800dd5b
Update code
beliefer Feb 25, 2022
f227e44
Merge branch 'SPARK-37960_followup' of github.com:beliefer/spark into…
beliefer Feb 25, 2022
cf91bbf
Update code
beliefer Feb 26, 2022
3557a6f
Update code
beliefer Feb 26, 2022
eb5894c
Update code
beliefer Mar 1, 2022
e63bc98
Update code
beliefer Mar 2, 2022
2b9921d
Update code
beliefer Mar 3, 2022
dc7a260
Update code
beliefer Mar 3, 2022
de78a0b
Update code
beliefer Mar 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.spark.sql.connector.expressions;

import java.io.Serializable;
import java.util.Arrays;

import org.apache.spark.annotation.Evolving;
import org.apache.spark.sql.connector.util.V2ExpressionSQLBuilder;

// scalastyle:off line.size.limit
/**
* The general representation of SQL scalar expressions, which contains the upper-cased
* expression name and all the children expressions.
* <p>
* The currently supported SQL scalar expressions:
* <ol>
* <li>Name: <code>IS_NULL</code>
* <ul>
* <li>SQL semantic: <code>expr IS NULL</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>IS_NOT_NULL</code>
* <ul>
* <li>SQL semantic: <code>expr IS NOT NULL</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>=</code>
* <ul>
* <li>SQL semantic: <code>expr1 = expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>!=</code>
* <ul>
* <li>SQL semantic: <code>expr1 != expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>&lt;&gt;</code>
* <ul>
* <li>SQL semantic: <code>expr1 &lt;&gt; expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>&lt;=&gt;</code>
* <ul>
* <li>SQL semantic: <code>expr1 &lt;=&gt; expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>&lt;</code>
* <ul>
* <li>SQL semantic: <code>expr1 &lt; expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>&lt;=</code>
* <ul>
* <li>SQL semantic: <code>expr1 &lt;= expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>&gt;</code>
* <ul>
* <li>SQL semantic: <code>expr1 &gt; expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>&gt;=</code>
* <ul>
* <li>SQL semantic: <code>expr1 &gt;= expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>+</code>
* <ul>
* <li>SQL semantic: <code>expr1 + expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>-</code>
* <ul>
* <li>SQL semantic: <code>expr1 - expr2</code> or <code>- expr</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>*</code>
* <ul>
* <li>SQL semantic: <code>expr1 * expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>/</code>
* <ul>
* <li>SQL semantic: <code>expr1 / expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>%</code>
* <ul>
* <li>SQL semantic: <code>expr1 % expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>&amp;</code>
* <ul>
* <li>SQL semantic: <code>expr1 &amp; expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>|</code>
* <ul>
* <li>SQL semantic: <code>expr1 | expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>^</code>
* <ul>
* <li>SQL semantic: <code>expr1 ^ expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>AND</code>
* <ul>
* <li>SQL semantic: <code>expr1 AND expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>OR</code>
* <ul>
* <li>SQL semantic: <code>expr1 OR expr2</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>NOT</code>
* <ul>
* <li>SQL semantic: <code>NOT expr</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>~</code>
* <ul>
* <li>SQL semantic: <code>~ expr</code></li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* <li>Name: <code>CASE_WHEN</code>
* <ul>
* <li>SQL semantic:
* <code>CASE WHEN expr1 THEN expr2 [WHEN expr3 THEN expr4]* [ELSE expr5] END</code>
* </li>
* <li>Since version: 3.3.0</li>
* </ul>
* </li>
* </ol>
* Note: SQL semantic conforms ANSI standard, so some expressions are not supported when ANSI off,
* including: add, subtract, multiply, divide, remainder, pmod.
*
* @since 3.3.0
*/
// scalastyle:on line.size.limit
@Evolving
public class GeneralScalarExpression implements Expression, Serializable {
private String name;
private Expression[] children;

public GeneralScalarExpression(String name, Expression[] children) {
this.name = name;
this.children = children;
}

public String name() { return name; }
public Expression[] children() { return children; }

@Override
public String toString() {
V2ExpressionSQLBuilder builder = new V2ExpressionSQLBuilder();
try {
return builder.build(this);
} catch (Throwable e) {
return name + "(" +
Arrays.stream(children).map(child -> child.toString()).reduce((a,b) -> a + "," + b) + ")";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.spark.sql.connector.util;

import java.util.ArrayList;
import java.util.List;

import org.apache.spark.sql.connector.expressions.Expression;
import org.apache.spark.sql.connector.expressions.FieldReference;
import org.apache.spark.sql.connector.expressions.GeneralScalarExpression;
import org.apache.spark.sql.connector.expressions.LiteralValue;

/**
* The builder to generate SQL from V2 expressions.
*/
public class V2ExpressionSQLBuilder {
public String build(Expression expr) {
if (expr instanceof LiteralValue) {
return visitLiteral((LiteralValue) expr);
} else if (expr instanceof FieldReference) {
return visitFieldReference((FieldReference) expr);
} else if (expr instanceof GeneralScalarExpression) {
GeneralScalarExpression e = (GeneralScalarExpression) expr;
String name = e.name();
switch (name) {
case "IS_NULL":
return visitIsNull(build(e.children()[0]));
case "IS_NOT_NULL":
return visitIsNotNull(build(e.children()[0]));
case "=":
case "!=":
case "<=>":
case "<":
case "<=":
case ">":
case ">=":
return visitBinaryComparison(name, build(e.children()[0]), build(e.children()[1]));
case "+":
case "*":
case "/":
case "%":
case "&":
case "|":
case "^":
return visitBinaryArithmetic(name, build(e.children()[0]), build(e.children()[1]));
case "-":
if (e.children().length == 1) {
return visitUnaryArithmetic(name, build(e.children()[0]));
} else {
return visitBinaryArithmetic(name, build(e.children()[0]), build(e.children()[1]));
}
case "AND":
return visitAnd(name, build(e.children()[0]), build(e.children()[1]));
case "OR":
return visitOr(name, build(e.children()[0]), build(e.children()[1]));
case "NOT":
return visitNot(build(e.children()[0]));
case "~":
return visitUnaryArithmetic(name, build(e.children()[0]));
case "CASE_WHEN":
List<String> children = new ArrayList<>();
for (Expression child : e.children()) {
children.add(build(child));
}
return visitCaseWhen(children.toArray(new String[e.children().length]));
// TODO supports other expressions
default:
return visitUnexpectedExpr(expr);
}
} else {
return visitUnexpectedExpr(expr);
}
}

protected String visitLiteral(LiteralValue literalValue) {
return literalValue.toString();
}

protected String visitFieldReference(FieldReference fieldRef) {
return fieldRef.toString();
}

protected String visitIsNull(String v) {
return v + " IS NULL";
}

protected String visitIsNotNull(String v) {
return v + " IS NOT NULL";
}

protected String visitBinaryComparison(String name, String l, String r) {
return "(" + l + ") " + name + " (" + r + ")";
}

protected String visitBinaryArithmetic(String name, String l, String r) {
return "(" + l + ") " + name + " (" + r + ")";
}

protected String visitAnd(String name, String l, String r) {
return "(" + l + ") " + name + " (" + r + ")";
}

protected String visitOr(String name, String l, String r) {
return "(" + l + ") " + name + " (" + r + ")";
}

protected String visitNot(String v) {
return "NOT (" + v + ")";
}

protected String visitUnaryArithmetic(String name, String v) { return name +" (" + v + ")"; }

protected String visitCaseWhen(String[] children) {
StringBuilder sb = new StringBuilder("CASE");
for (int i = 0; i < children.length; i += 2) {
String c = children[i];
int j = i + 1;
if (j < children.length) {
String v = children[j];
sb.append(" WHEN ");
sb.append(c);
sb.append(" THEN ");
sb.append(v);
} else {
sb.append(" ELSE ");
sb.append(c);
}
}
sb.append(" END");
return sb.toString();
}

protected String visitUnexpectedExpr(Expression expr) throws IllegalArgumentException {
throw new IllegalArgumentException("Unexpected V2 expression: " + expr);
}
}
Loading