You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2016/12/08 06:05:00 UTC
[1/3] calcite git commit: [CALCITE-1530] Create a visitor to traverse
linq4j expressions without mutating them, and rename Visitor to Shuttle
Repository: calcite
Updated Branches:
refs/heads/master 02752fe78 -> e641211fd
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Shuttle.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Shuttle.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Shuttle.java
new file mode 100644
index 0000000..08aa1ad
--- /dev/null
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Shuttle.java
@@ -0,0 +1,335 @@
+/*
+ * 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.calcite.linq4j.tree;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Extension to {@link Visitor} that returns a mutated tree.
+ */
+public class Shuttle {
+ public Shuttle preVisit(WhileStatement whileStatement) {
+ return this;
+ }
+
+ public Statement visit(WhileStatement whileStatement, Expression condition,
+ Statement body) {
+ return condition == whileStatement.condition
+ && body == whileStatement.body
+ ? whileStatement
+ : Expressions.while_(condition, body);
+ }
+
+ public Shuttle preVisit(ConditionalStatement conditionalStatement) {
+ return this;
+ }
+
+ public Statement visit(ConditionalStatement conditionalStatement,
+ List<Node> list) {
+ return list.equals(conditionalStatement.expressionList)
+ ? conditionalStatement
+ : Expressions.ifThenElse(list);
+ }
+
+ public Shuttle preVisit(BlockStatement blockStatement) {
+ return this;
+ }
+
+ public BlockStatement visit(BlockStatement blockStatement,
+ List<Statement> statements) {
+ return statements.equals(blockStatement.statements)
+ ? blockStatement
+ : Expressions.block(statements);
+ }
+
+ public Shuttle preVisit(GotoStatement gotoStatement) {
+ return this;
+ }
+
+ public Statement visit(GotoStatement gotoStatement, Expression expression) {
+ return expression == gotoStatement.expression
+ ? gotoStatement
+ : Expressions.makeGoto(
+ gotoStatement.kind, gotoStatement.labelTarget,
+ expression);
+ }
+
+ public LabelStatement visit(LabelStatement labelStatement) {
+ return labelStatement;
+ }
+
+ public Shuttle preVisit(ForStatement forStatement) {
+ return this;
+ }
+
+ public ForStatement visit(ForStatement forStatement,
+ List<DeclarationStatement> declarations, Expression condition,
+ Expression post, Statement body) {
+ return declarations.equals(forStatement.declarations)
+ && condition == forStatement.condition
+ && post == forStatement.post
+ && body == forStatement.body
+ ? forStatement
+ : Expressions.for_(declarations, condition, post, body);
+ }
+
+ public Shuttle preVisit(ThrowStatement throwStatement) {
+ return this;
+ }
+
+ public Statement visit(ThrowStatement throwStatement, Expression expression) {
+ return expression == throwStatement.expression
+ ? throwStatement
+ : Expressions.throw_(expression);
+ }
+
+ public Shuttle preVisit(DeclarationStatement declarationStatement) {
+ return this;
+ }
+
+ public DeclarationStatement visit(DeclarationStatement declarationStatement,
+ Expression initializer) {
+ return declarationStatement.initializer == initializer
+ ? declarationStatement
+ : Expressions.declare(
+ declarationStatement.modifiers, declarationStatement.parameter,
+ initializer);
+ }
+
+ public Expression visit(LambdaExpression lambdaExpression) {
+ return lambdaExpression;
+ }
+
+ public Shuttle preVisit(FunctionExpression functionExpression) {
+ return this;
+ }
+
+ public Expression visit(FunctionExpression functionExpression,
+ BlockStatement body) {
+ return functionExpression.body.equals(body)
+ ? functionExpression
+ : Expressions.lambda(body, functionExpression.parameterList);
+ }
+
+ public Shuttle preVisit(BinaryExpression binaryExpression) {
+ return this;
+ }
+
+ public Expression visit(BinaryExpression binaryExpression,
+ Expression expression0, Expression expression1) {
+ return binaryExpression.expression0 == expression0
+ && binaryExpression.expression1 == expression1
+ ? binaryExpression
+ : Expressions.makeBinary(binaryExpression.nodeType, expression0,
+ expression1);
+ }
+
+ public Shuttle preVisit(TernaryExpression ternaryExpression) {
+ return this;
+ }
+
+ public Expression visit(TernaryExpression ternaryExpression,
+ Expression expression0, Expression expression1, Expression expression2) {
+ return ternaryExpression.expression0 == expression0
+ && ternaryExpression.expression1 == expression1
+ && ternaryExpression.expression2 == expression2
+ ? ternaryExpression
+ : Expressions.makeTernary(ternaryExpression.nodeType, expression0,
+ expression1, expression2);
+ }
+
+ public Shuttle preVisit(IndexExpression indexExpression) {
+ return this;
+ }
+
+ public Expression visit(IndexExpression indexExpression, Expression array,
+ List<Expression> indexExpressions) {
+ return indexExpression.array == array
+ && indexExpression.indexExpressions.equals(indexExpressions)
+ ? indexExpression
+ : new IndexExpression(array, indexExpressions);
+ }
+
+ public Shuttle preVisit(UnaryExpression unaryExpression) {
+ return this;
+ }
+
+ public Expression visit(UnaryExpression unaryExpression,
+ Expression expression) {
+ return unaryExpression.expression == expression
+ ? unaryExpression
+ : Expressions.makeUnary(unaryExpression.nodeType, expression,
+ unaryExpression.type, null);
+ }
+
+ public Shuttle preVisit(MethodCallExpression methodCallExpression) {
+ return this;
+ }
+
+ public Expression visit(MethodCallExpression methodCallExpression,
+ Expression targetExpression, List<Expression> expressions) {
+ return methodCallExpression.targetExpression == targetExpression
+ && methodCallExpression.expressions.equals(expressions)
+ ? methodCallExpression
+ : Expressions.call(targetExpression, methodCallExpression.method,
+ expressions);
+ }
+
+ public Expression visit(DefaultExpression defaultExpression) {
+ return defaultExpression;
+ }
+
+ public Expression visit(DynamicExpression dynamicExpression) {
+ return dynamicExpression;
+ }
+
+ public Shuttle preVisit(MemberExpression memberExpression) {
+ return this;
+ }
+
+ public Expression visit(MemberExpression memberExpression,
+ Expression expression) {
+ return memberExpression.expression == expression
+ ? memberExpression
+ : Expressions.field(expression, memberExpression.field);
+ }
+
+ public Expression visit(InvocationExpression invocationExpression) {
+ return invocationExpression;
+ }
+
+ public Shuttle preVisit(NewArrayExpression newArrayExpression) {
+ return this;
+ }
+
+ public Expression visit(NewArrayExpression newArrayExpression, int dimension,
+ Expression bound, List<Expression> expressions) {
+ return Objects.equals(expressions, newArrayExpression.expressions)
+ && Objects.equals(bound, newArrayExpression.bound)
+ ? newArrayExpression
+ : expressions == null
+ ? Expressions.newArrayBounds(
+ Types.getComponentTypeN(newArrayExpression.type), dimension, bound)
+ : Expressions.newArrayInit(
+ Types.getComponentTypeN(newArrayExpression.type),
+ dimension, expressions);
+ }
+
+ public Expression visit(ListInitExpression listInitExpression) {
+ return listInitExpression;
+ }
+
+ public Shuttle preVisit(NewExpression newExpression) {
+ return this;
+ }
+
+ public Expression visit(NewExpression newExpression,
+ List<Expression> arguments, List<MemberDeclaration> memberDeclarations) {
+ return arguments.equals(newExpression.arguments)
+ && Objects.equals(memberDeclarations, newExpression.memberDeclarations)
+ ? newExpression
+ : Expressions.new_(newExpression.type, arguments, memberDeclarations);
+ }
+
+ public Statement visit(SwitchStatement switchStatement) {
+ return switchStatement;
+ }
+
+ public Statement visit(TryStatement tryStatement) {
+ return tryStatement;
+ }
+
+ public Expression visit(MemberInitExpression memberInitExpression) {
+ return memberInitExpression;
+ }
+
+ public Shuttle preVisit(TypeBinaryExpression typeBinaryExpression) {
+ return this;
+ }
+
+ public Expression visit(TypeBinaryExpression typeBinaryExpression,
+ Expression expression) {
+ return typeBinaryExpression.expression == expression
+ ? typeBinaryExpression
+ : new TypeBinaryExpression(expression.getNodeType(), expression,
+ expression.type);
+ }
+
+ public Shuttle preVisit(MethodDeclaration methodDeclaration) {
+ return this;
+ }
+
+ public MemberDeclaration visit(MethodDeclaration methodDeclaration,
+ BlockStatement body) {
+ return body.equals(methodDeclaration.body)
+ ? methodDeclaration
+ : Expressions.methodDecl(methodDeclaration.modifier,
+ methodDeclaration.resultType, methodDeclaration.name,
+ methodDeclaration.parameters, body);
+ }
+
+ public Shuttle preVisit(FieldDeclaration fieldDeclaration) {
+ return this;
+ }
+
+ public MemberDeclaration visit(FieldDeclaration fieldDeclaration,
+ Expression initializer) {
+ return Objects.equals(initializer, fieldDeclaration.initializer)
+ ? fieldDeclaration
+ : Expressions.fieldDecl(fieldDeclaration.modifier,
+ fieldDeclaration.parameter, initializer);
+ }
+
+ public Expression visit(ParameterExpression parameterExpression) {
+ return parameterExpression;
+ }
+
+ public ConstantExpression visit(ConstantExpression constantExpression) {
+ return constantExpression;
+ }
+
+ public Shuttle preVisit(ClassDeclaration classDeclaration) {
+ return this;
+ }
+
+ public ClassDeclaration visit(ClassDeclaration classDeclaration,
+ List<MemberDeclaration> memberDeclarations) {
+ return Objects.equals(memberDeclarations,
+ classDeclaration.memberDeclarations)
+ ? classDeclaration
+ : Expressions.classDecl(classDeclaration.modifier,
+ classDeclaration.name, classDeclaration.extended,
+ classDeclaration.implemented, memberDeclarations);
+ }
+
+ public Shuttle preVisit(ConstructorDeclaration constructorDeclaration) {
+ return this;
+ }
+
+ public MemberDeclaration visit(ConstructorDeclaration constructorDeclaration,
+ BlockStatement body) {
+ return body.equals(constructorDeclaration.body)
+ ? constructorDeclaration
+ : Expressions.constructorDecl(constructorDeclaration.modifier,
+ constructorDeclaration.resultType,
+ constructorDeclaration.parameters,
+ body);
+ }
+}
+
+// End Shuttle.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Statement.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Statement.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Statement.java
index 99e17f9..8c0a225 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Statement.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Statement.java
@@ -34,7 +34,7 @@ public abstract class Statement extends AbstractNode {
// Make return type more specific. A statement can only become a different
// kind of statement; it can't become an expression.
- @Override public abstract Statement accept(Visitor visitor);
+ @Override public abstract Statement accept(Shuttle shuttle);
}
// End Statement.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/SwitchStatement.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/SwitchStatement.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/SwitchStatement.java
index b0fa124..fb787b1 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/SwitchStatement.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/SwitchStatement.java
@@ -25,9 +25,14 @@ public class SwitchStatement extends Statement {
super(nodeType, Void.TYPE);
}
- @Override public Statement accept(Visitor visitor) {
+ @Override public Statement accept(Shuttle shuttle) {
+ return shuttle.visit(this);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visit(this);
}
+
}
// End SwitchStatement.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TernaryExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TernaryExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TernaryExpression.java
index 86be802..9bc9ac5 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TernaryExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TernaryExpression.java
@@ -38,12 +38,16 @@ public class TernaryExpression extends Expression {
this.expression2 = expression2;
}
- @Override public Expression accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
- Expression expression0 = this.expression0.accept(visitor);
- Expression expression1 = this.expression1.accept(visitor);
- Expression expression2 = this.expression2.accept(visitor);
- return visitor.visit(this, expression0, expression1, expression2);
+ @Override public Expression accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
+ Expression expression0 = this.expression0.accept(shuttle);
+ Expression expression1 = this.expression1.accept(shuttle);
+ Expression expression2 = this.expression2.accept(shuttle);
+ return shuttle.visit(this, expression0, expression1, expression2);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
void accept(ExpressionWriter writer, int lprec, int rprec) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ThrowStatement.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ThrowStatement.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ThrowStatement.java
index b2939a5..221576c 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ThrowStatement.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ThrowStatement.java
@@ -29,10 +29,14 @@ public class ThrowStatement extends Statement {
this.expression = expression;
}
- @Override public Statement accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
- Expression expression = this.expression.accept(visitor);
- return visitor.visit(this, expression);
+ @Override public Statement accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
+ Expression expression = this.expression.accept(shuttle);
+ return shuttle.visit(this, expression);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
@Override void accept0(ExpressionWriter writer) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TryStatement.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TryStatement.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TryStatement.java
index 0e9d4ca..9313011 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TryStatement.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TryStatement.java
@@ -37,7 +37,11 @@ public class TryStatement extends Statement {
this.fynally = fynally;
}
- @Override public Statement accept(Visitor visitor) {
+ @Override public Statement accept(Shuttle shuttle) {
+ return shuttle.visit(this);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visit(this);
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TypeBinaryExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TypeBinaryExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TypeBinaryExpression.java
index 1890de0..f407db1 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TypeBinaryExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/TypeBinaryExpression.java
@@ -34,10 +34,14 @@ public class TypeBinaryExpression extends Expression {
this.type = type;
}
- @Override public Expression accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
- Expression expression = this.expression.accept(visitor);
- return visitor.visit(this, expression);
+ @Override public Expression accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
+ Expression expression = this.expression.accept(shuttle);
+ return shuttle.visit(this, expression);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
void accept(ExpressionWriter writer, int lprec, int rprec) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/UnaryExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/UnaryExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/UnaryExpression.java
index d9bae4d..4dfc9c3 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/UnaryExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/UnaryExpression.java
@@ -31,10 +31,14 @@ public class UnaryExpression extends Expression {
this.expression = expression;
}
- @Override public Expression accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
- Expression expression = this.expression.accept(visitor);
- return visitor.visit(this, expression);
+ @Override public Expression accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
+ Expression expression = this.expression.accept(shuttle);
+ return shuttle.visit(this, expression);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
void accept(ExpressionWriter writer, int lprec, int rprec) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Visitor.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Visitor.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Visitor.java
index cf50786..50b60d2 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Visitor.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Visitor.java
@@ -16,324 +16,45 @@
*/
package org.apache.calcite.linq4j.tree;
-import java.util.List;
-import java.util.Objects;
-
/**
* Node visitor.
+ *
+ * @param <R> Return type
*/
-public class Visitor {
- public Visitor preVisit(WhileStatement whileStatement) {
- return this;
- }
-
- public Statement visit(WhileStatement whileStatement, Expression condition,
- Statement body) {
- return condition == whileStatement.condition
- && body == whileStatement.body
- ? whileStatement
- : Expressions.while_(condition, body);
- }
-
- public Visitor preVisit(ConditionalStatement conditionalStatement) {
- return this;
- }
-
- public Statement visit(ConditionalStatement conditionalStatement,
- List<Node> list) {
- return list.equals(conditionalStatement.expressionList)
- ? conditionalStatement
- : Expressions.ifThenElse(list);
- }
-
- public Visitor preVisit(BlockStatement blockStatement) {
- return this;
- }
-
- public BlockStatement visit(BlockStatement blockStatement,
- List<Statement> statements) {
- return statements.equals(blockStatement.statements)
- ? blockStatement
- : Expressions.block(statements);
- }
-
- public Visitor preVisit(GotoStatement gotoStatement) {
- return this;
- }
-
- public Statement visit(GotoStatement gotoStatement, Expression expression) {
- return expression == gotoStatement.expression
- ? gotoStatement
- : Expressions.makeGoto(
- gotoStatement.kind, gotoStatement.labelTarget,
- expression);
- }
-
- public LabelStatement visit(LabelStatement labelStatement) {
- return labelStatement;
- }
-
- public Visitor preVisit(ForStatement forStatement) {
- return this;
- }
-
- public ForStatement visit(ForStatement forStatement,
- List<DeclarationStatement> declarations, Expression condition,
- Expression post, Statement body) {
- return declarations.equals(forStatement.declarations)
- && condition == forStatement.condition
- && post == forStatement.post
- && body == forStatement.body
- ? forStatement
- : Expressions.for_(declarations, condition, post, body);
- }
-
- public Visitor preVisit(ThrowStatement throwStatement) {
- return this;
- }
-
- public Statement visit(ThrowStatement throwStatement, Expression expression) {
- return expression == throwStatement.expression
- ? throwStatement
- : Expressions.throw_(expression);
- }
-
- public Visitor preVisit(DeclarationStatement declarationStatement) {
- return this;
- }
-
- public DeclarationStatement visit(DeclarationStatement declarationStatement,
- Expression initializer) {
- return declarationStatement.initializer == initializer
- ? declarationStatement
- : Expressions.declare(
- declarationStatement.modifiers, declarationStatement.parameter,
- initializer);
- }
-
- public Expression visit(LambdaExpression lambdaExpression) {
- return lambdaExpression;
- }
-
- public Visitor preVisit(FunctionExpression functionExpression) {
- return this;
- }
-
- public Expression visit(FunctionExpression functionExpression,
- BlockStatement body) {
- return functionExpression.body.equals(body)
- ? functionExpression
- : Expressions.lambda(body, functionExpression.parameterList);
- }
-
- public Visitor preVisit(BinaryExpression binaryExpression) {
- return this;
- }
-
- public Expression visit(BinaryExpression binaryExpression,
- Expression expression0, Expression expression1) {
- return binaryExpression.expression0 == expression0
- && binaryExpression.expression1 == expression1
- ? binaryExpression
- : Expressions.makeBinary(binaryExpression.nodeType, expression0,
- expression1);
- }
-
- public Visitor preVisit(TernaryExpression ternaryExpression) {
- return this;
- }
-
- public Expression visit(TernaryExpression ternaryExpression,
- Expression expression0, Expression expression1, Expression expression2) {
- return ternaryExpression.expression0 == expression0
- && ternaryExpression.expression1 == expression1
- && ternaryExpression.expression2 == expression2
- ? ternaryExpression
- : Expressions.makeTernary(ternaryExpression.nodeType, expression0,
- expression1, expression2);
- }
-
- public Visitor preVisit(IndexExpression indexExpression) {
- return this;
- }
-
- public Expression visit(IndexExpression indexExpression, Expression array,
- List<Expression> indexExpressions) {
- return indexExpression.array == array
- && indexExpression.indexExpressions.equals(indexExpressions)
- ? indexExpression
- : new IndexExpression(array, indexExpressions);
- }
-
- public Visitor preVisit(UnaryExpression unaryExpression) {
- return this;
- }
-
- public Expression visit(UnaryExpression unaryExpression,
- Expression expression) {
- return unaryExpression.expression == expression
- ? unaryExpression
- : Expressions.makeUnary(unaryExpression.nodeType, expression,
- unaryExpression.type, null);
- }
-
- public Visitor preVisit(MethodCallExpression methodCallExpression) {
- return this;
- }
-
- public Expression visit(MethodCallExpression methodCallExpression,
- Expression targetExpression, List<Expression> expressions) {
- return methodCallExpression.targetExpression == targetExpression
- && methodCallExpression.expressions.equals(expressions)
- ? methodCallExpression
- : Expressions.call(targetExpression, methodCallExpression.method,
- expressions);
- }
-
- public Expression visit(DefaultExpression defaultExpression) {
- return defaultExpression;
- }
-
- public Expression visit(DynamicExpression dynamicExpression) {
- return dynamicExpression;
- }
-
- public Visitor preVisit(MemberExpression memberExpression) {
- return this;
- }
-
- public Expression visit(MemberExpression memberExpression,
- Expression expression) {
- return memberExpression.expression == expression
- ? memberExpression
- : Expressions.field(expression, memberExpression.field);
- }
-
- public Expression visit(InvocationExpression invocationExpression) {
- return invocationExpression;
- }
-
- static <T> boolean eq(T t0, T t1) {
- return t0 == t1 || t0 != null && t1 != null && t0.equals(t1);
- }
-
- public Visitor preVisit(NewArrayExpression newArrayExpression) {
- return this;
- }
-
- public Expression visit(NewArrayExpression newArrayExpression, int dimension,
- Expression bound, List<Expression> expressions) {
- return eq(expressions, newArrayExpression.expressions)
- && eq(bound, newArrayExpression.bound)
- ? newArrayExpression
- : expressions == null
- ? Expressions.newArrayBounds(
- Types.getComponentTypeN(newArrayExpression.type), dimension, bound)
- : Expressions.newArrayInit(
- Types.getComponentTypeN(newArrayExpression.type),
- dimension, expressions);
- }
-
- public Expression visit(ListInitExpression listInitExpression) {
- return listInitExpression;
- }
-
- public Visitor preVisit(NewExpression newExpression) {
- return this;
- }
-
- public Expression visit(NewExpression newExpression,
- List<Expression> arguments, List<MemberDeclaration> memberDeclarations) {
- return arguments.equals(newExpression.arguments)
- && Objects.equals(memberDeclarations, newExpression.memberDeclarations)
- ? newExpression
- : Expressions.new_(newExpression.type, arguments, memberDeclarations);
- }
-
- public Statement visit(SwitchStatement switchStatement) {
- return switchStatement;
- }
-
- public Statement visit(TryStatement tryStatement) {
- return tryStatement;
- }
-
- public Expression visit(MemberInitExpression memberInitExpression) {
- return memberInitExpression;
- }
-
- public Visitor preVisit(TypeBinaryExpression typeBinaryExpression) {
- return this;
- }
-
- public Expression visit(TypeBinaryExpression typeBinaryExpression,
- Expression expression) {
- return typeBinaryExpression.expression == expression
- ? typeBinaryExpression
- : new TypeBinaryExpression(expression.getNodeType(), expression,
- expression.type);
- }
-
- public Visitor preVisit(MethodDeclaration methodDeclaration) {
- return this;
- }
-
- public MemberDeclaration visit(MethodDeclaration methodDeclaration,
- BlockStatement body) {
- return body.equals(methodDeclaration.body)
- ? methodDeclaration
- : Expressions.methodDecl(methodDeclaration.modifier,
- methodDeclaration.resultType, methodDeclaration.name,
- methodDeclaration.parameters, body);
- }
-
- public Visitor preVisit(FieldDeclaration fieldDeclaration) {
- return this;
- }
-
- public MemberDeclaration visit(FieldDeclaration fieldDeclaration,
- Expression initializer) {
- return eq(initializer, fieldDeclaration.initializer)
- ? fieldDeclaration
- : Expressions.fieldDecl(fieldDeclaration.modifier,
- fieldDeclaration.parameter, initializer);
- }
-
- public Expression visit(ParameterExpression parameterExpression) {
- return parameterExpression;
- }
-
- public ConstantExpression visit(ConstantExpression constantExpression) {
- return constantExpression;
- }
-
- public Visitor preVisit(ClassDeclaration classDeclaration) {
- return this;
- }
-
- public ClassDeclaration visit(ClassDeclaration classDeclaration,
- List<MemberDeclaration> memberDeclarations) {
- return Objects.equals(memberDeclarations,
- classDeclaration.memberDeclarations)
- ? classDeclaration
- : Expressions.classDecl(classDeclaration.modifier,
- classDeclaration.name, classDeclaration.extended,
- classDeclaration.implemented, memberDeclarations);
- }
-
- public Visitor preVisit(ConstructorDeclaration constructorDeclaration) {
- return this;
- }
-
- public MemberDeclaration visit(ConstructorDeclaration constructorDeclaration,
- BlockStatement body) {
- return body.equals(constructorDeclaration.body)
- ? constructorDeclaration
- : Expressions.constructorDecl(constructorDeclaration.modifier,
- constructorDeclaration.resultType,
- constructorDeclaration.parameters,
- body);
- }
+public interface Visitor<R> {
+ R visit(BinaryExpression binaryExpression);
+ R visit(BlockStatement blockStatement);
+ R visit(ClassDeclaration classDeclaration);
+ R visit(ConditionalExpression conditionalExpression);
+ R visit(ConditionalStatement conditionalStatement);
+ R visit(ConstantExpression constantExpression);
+ R visit(ConstructorDeclaration constructorDeclaration);
+ R visit(DeclarationStatement declarationStatement);
+ R visit(DefaultExpression defaultExpression);
+ R visit(DynamicExpression dynamicExpression);
+ R visit(FieldDeclaration fieldDeclaration);
+ R visit(ForStatement forStatement);
+ R visit(FunctionExpression functionExpression);
+ R visit(GotoStatement gotoStatement);
+ R visit(IndexExpression indexExpression);
+ R visit(InvocationExpression invocationExpression);
+ R visit(LabelStatement labelStatement);
+ R visit(LambdaExpression lambdaExpression);
+ R visit(ListInitExpression listInitExpression);
+ R visit(MemberExpression memberExpression);
+ R visit(MemberInitExpression memberInitExpression);
+ R visit(MethodCallExpression methodCallExpression);
+ R visit(MethodDeclaration methodDeclaration);
+ R visit(NewArrayExpression newArrayExpression);
+ R visit(NewExpression newExpression);
+ R visit(ParameterExpression parameterExpression);
+ R visit(SwitchStatement switchStatement);
+ R visit(TernaryExpression ternaryExpression);
+ R visit(ThrowStatement throwStatement);
+ R visit(TryStatement tryStatement);
+ R visit(TypeBinaryExpression typeBinaryExpression);
+ R visit(UnaryExpression unaryExpression);
+ R visit(WhileStatement whileStatement);
}
// End Visitor.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/VisitorImpl.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/VisitorImpl.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/VisitorImpl.java
new file mode 100644
index 0000000..2507db9
--- /dev/null
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/VisitorImpl.java
@@ -0,0 +1,206 @@
+/*
+ * 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.calcite.linq4j.tree;
+
+import java.util.List;
+
+/**
+ * Default implementation of {@link Visitor}, which traverses a tree but does
+ * nothing. In a derived class you can override selected methods.
+ *
+ * @param <R> Return type
+ */
+public class VisitorImpl<R> implements Visitor<R> {
+ public VisitorImpl() {
+ super();
+ }
+
+ public R visit(BinaryExpression binaryExpression) {
+ R r0 = binaryExpression.expression0.accept(this);
+ R r1 = binaryExpression.expression1.accept(this);
+ return r1;
+ }
+
+ public R visit(BlockStatement blockStatement) {
+ return Expressions.acceptNodes(blockStatement.statements, this);
+ }
+
+ public R visit(ClassDeclaration classDeclaration) {
+ return Expressions.acceptNodes(classDeclaration.memberDeclarations, this);
+ }
+
+ public R visit(ConditionalExpression conditionalExpression) {
+ return Expressions.acceptNodes(conditionalExpression.expressionList, this);
+ }
+
+ public R visit(ConditionalStatement conditionalStatement) {
+ return Expressions.acceptNodes(conditionalStatement.expressionList, this);
+ }
+
+ public R visit(ConstantExpression constantExpression) {
+ return null;
+ }
+
+ public R visit(ConstructorDeclaration constructorDeclaration) {
+ R r0 = Expressions.acceptNodes(constructorDeclaration.parameters, this);
+ return constructorDeclaration.body.accept(this);
+ }
+
+ public R visit(DeclarationStatement declarationStatement) {
+ R r = declarationStatement.parameter.accept(this);
+ if (declarationStatement.initializer != null) {
+ r = declarationStatement.initializer.accept(this);
+ }
+ return r;
+ }
+
+ public R visit(DefaultExpression defaultExpression) {
+ return null;
+ }
+
+ public R visit(DynamicExpression dynamicExpression) {
+ return null;
+ }
+
+ public R visit(FieldDeclaration fieldDeclaration) {
+ R r0 = fieldDeclaration.parameter.accept(this);
+ return fieldDeclaration.initializer.accept(this);
+ }
+
+ public R visit(ForStatement forStatement) {
+ R r0 = Expressions.acceptNodes(forStatement.declarations, this);
+ R r1 = forStatement.condition.accept(this);
+ R r2 = forStatement.post.accept(this);
+ return forStatement.body.accept(this);
+ }
+
+ public R visit(FunctionExpression functionExpression) {
+ @SuppressWarnings("unchecked") final List<Node> parameterList =
+ functionExpression.parameterList;
+ R r0 = Expressions.acceptNodes(parameterList, this);
+ return functionExpression.body.accept(this);
+ }
+
+ public R visit(GotoStatement gotoStatement) {
+ return gotoStatement.expression.accept(this);
+ }
+
+ public R visit(IndexExpression indexExpression) {
+ R r0 = indexExpression.array.accept(this);
+ return Expressions.acceptNodes(indexExpression.indexExpressions, this);
+ }
+
+ public R visit(InvocationExpression invocationExpression) {
+ return null;
+ }
+
+ public R visit(LabelStatement labelStatement) {
+ return labelStatement.defaultValue.accept(this);
+ }
+
+ public R visit(LambdaExpression lambdaExpression) {
+ return null;
+ }
+
+ public R visit(ListInitExpression listInitExpression) {
+ return null;
+ }
+
+ public R visit(MemberExpression memberExpression) {
+ R r = null;
+ if (memberExpression.expression != null) {
+ r = memberExpression.expression.accept(this);
+ }
+ return r;
+ }
+
+ public R visit(MemberInitExpression memberInitExpression) {
+ return null;
+ }
+
+ public R visit(MethodCallExpression methodCallExpression) {
+ R r = null;
+ if (methodCallExpression.targetExpression != null) {
+ r = methodCallExpression.targetExpression.accept(this);
+ }
+ return Expressions.acceptNodes(methodCallExpression.expressions, this);
+ }
+
+ public R visit(MethodDeclaration methodDeclaration) {
+ R r0 = Expressions.acceptNodes(methodDeclaration.parameters, this);
+ return methodDeclaration.body.accept(this);
+ }
+
+ public R visit(NewArrayExpression newArrayExpression) {
+ R r = null;
+ if (newArrayExpression.bound != null) {
+ r = newArrayExpression.bound.accept(this);
+ }
+ return Expressions.acceptNodes(newArrayExpression.expressions, this);
+ }
+
+ public R visit(NewExpression newExpression) {
+ R r0 = Expressions.acceptNodes(newExpression.arguments, this);
+ return Expressions.acceptNodes(newExpression.memberDeclarations, this);
+ }
+
+ public R visit(ParameterExpression parameterExpression) {
+ return null;
+ }
+
+ public R visit(SwitchStatement switchStatement) {
+ return null;
+ }
+
+ public R visit(TernaryExpression ternaryExpression) {
+ R r0 = ternaryExpression.expression0.accept(this);
+ R r1 = ternaryExpression.expression1.accept(this);
+ return ternaryExpression.expression2.accept(this);
+ }
+
+ public R visit(ThrowStatement throwStatement) {
+ return throwStatement.expression.accept(this);
+ }
+
+ public R visit(TryStatement tryStatement) {
+ R r = tryStatement.body.accept(this);
+ for (CatchBlock catchBlock : tryStatement.catchBlocks) {
+ r = catchBlock.parameter.accept(this);
+ r = catchBlock.body.accept(this);
+ }
+ if (tryStatement.fynally != null) {
+ r = tryStatement.fynally.accept(this);
+ }
+ return r;
+ }
+
+ public R visit(TypeBinaryExpression typeBinaryExpression) {
+ return typeBinaryExpression.expression.accept(this);
+ }
+
+ public R visit(UnaryExpression unaryExpression) {
+ return unaryExpression.expression.accept(this);
+ }
+
+ public R visit(WhileStatement whileStatement) {
+ R r0 = whileStatement.condition.accept(this);
+ return whileStatement.body.accept(this);
+ }
+
+}
+
+// End VisitorImpl.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/WhileStatement.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/WhileStatement.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/WhileStatement.java
index 9253fa7..215097a 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/WhileStatement.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/WhileStatement.java
@@ -33,11 +33,15 @@ public class WhileStatement extends Statement {
this.body = body;
}
- @Override public Statement accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
- final Expression condition1 = condition.accept(visitor);
- final Statement body1 = body.accept(visitor);
- return visitor.visit(this, condition1, body1);
+ @Override public Statement accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
+ final Expression condition1 = condition.accept(shuttle);
+ final Statement body1 = body.accept(shuttle);
+ return shuttle.visit(this, condition1, body1);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
@Override void accept0(ExpressionWriter writer) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/test/java/org/apache/calcite/linq4j/test/BlockBuilderTest.java
----------------------------------------------------------------------
diff --git a/linq4j/src/test/java/org/apache/calcite/linq4j/test/BlockBuilderTest.java b/linq4j/src/test/java/org/apache/calcite/linq4j/test/BlockBuilderTest.java
index ce8b03b..86c68c1 100644
--- a/linq4j/src/test/java/org/apache/calcite/linq4j/test/BlockBuilderTest.java
+++ b/linq4j/src/test/java/org/apache/calcite/linq4j/test/BlockBuilderTest.java
@@ -21,8 +21,8 @@ import org.apache.calcite.linq4j.tree.BlockBuilder;
import org.apache.calcite.linq4j.tree.Expression;
import org.apache.calcite.linq4j.tree.ExpressionType;
import org.apache.calcite.linq4j.tree.Expressions;
-import org.apache.calcite.linq4j.tree.OptimizeVisitor;
-import org.apache.calcite.linq4j.tree.Visitor;
+import org.apache.calcite.linq4j.tree.OptimizeShuttle;
+import org.apache.calcite.linq4j.tree.Shuttle;
import org.junit.Before;
import org.junit.Test;
@@ -62,8 +62,8 @@ public class BlockBuilderTest {
@Test public void testTestCustomOptimizer() {
BlockBuilder b = new BlockBuilder() {
- @Override protected Visitor createOptimizeVisitor() {
- return new OptimizeVisitor() {
+ @Override protected Shuttle createOptimizeShuttle() {
+ return new OptimizeShuttle() {
@Override public Expression visit(BinaryExpression binary,
Expression expression0, Expression expression1) {
if (binary.getNodeType() == ExpressionType.Add
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java
----------------------------------------------------------------------
diff --git a/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java b/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java
index 0be06c1..fe4354d 100644
--- a/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java
+++ b/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java
@@ -31,8 +31,8 @@ import org.apache.calcite.linq4j.tree.MethodCallExpression;
import org.apache.calcite.linq4j.tree.NewExpression;
import org.apache.calcite.linq4j.tree.Node;
import org.apache.calcite.linq4j.tree.ParameterExpression;
+import org.apache.calcite.linq4j.tree.Shuttle;
import org.apache.calcite.linq4j.tree.Types;
-import org.apache.calcite.linq4j.tree.Visitor;
import org.junit.Test;
@@ -899,7 +899,7 @@ public class ExpressionTest {
statements.add(Expressions.return_(null, eighteen));
BlockStatement expression = statements.toBlock();
assertEquals(expected, Expressions.toString(expression));
- expression.accept(new Visitor());
+ expression.accept(new Shuttle());
}
@Test public void testBlockBuilder2() {
@@ -930,7 +930,7 @@ public class ExpressionTest {
+ " (java.util.Comparator) null).add(null);\n"
+ "}\n",
Expressions.toString(expression));
- expression.accept(new Visitor());
+ expression.accept(new Shuttle());
}
@Test public void testBlockBuilder3() {
@@ -978,7 +978,7 @@ public class ExpressionTest {
+ " org.apache.calcite.linq4j.test.ExpressionTest.bar(1, _b, _c, _d, org.apache.calcite.linq4j.test.ExpressionTest.foo(_c));\n"
+ "}\n",
Expressions.toString(expression));
- expression.accept(new Visitor());
+ expression.accept(new Shuttle());
}
@Test public void testConstantExpression() {
@@ -1021,7 +1021,7 @@ public class ExpressionTest {
+ " \"109\",\n"
+ " null)}",
constant.toString());
- constant.accept(new Visitor());
+ constant.accept(new Shuttle());
}
@Test public void testClassDecl() {
@@ -1056,7 +1056,7 @@ public class ExpressionTest {
+ " int i;\n"
+ "}",
Expressions.toString(newExpression));
- newExpression.accept(new Visitor());
+ newExpression.accept(new Shuttle());
}
@Test public void testReturn() {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/site/_docs/adapter.md
----------------------------------------------------------------------
diff --git a/site/_docs/adapter.md b/site/_docs/adapter.md
index fd06d8c..5f9a20d 100644
--- a/site/_docs/adapter.md
+++ b/site/_docs/adapter.md
@@ -70,15 +70,18 @@ as implemented by Avatica's
| Property | Description |
|:-------- |:------------|
| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#CASE_SENSITIVE">caseSensitive</a> | Whether identifiers are matched case-sensitively. If not specified, value from `lex` is used.
-| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#CONFORMANCE">conformance</a> | SQL conformance level. Values: "default" (the default, similar to "pragmatic_2003"), "oracle_10", "pragmatic_99", "pragmatic_2003", "strict_92", "strict_99", "strict_2003".
+| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#CONFORMANCE">conformance</a> | SQL conformance level. Values: DEFAULT (the default, similar to PRAGMATIC_2003), ORACLE_10, ORACLE_12, PRAGMATIC_99, PRAGMATIC_2003, STRICT_92, STRICT_99, STRICT_2003, SQL_SERVER_2008.
| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#CREATE_MATERIALIZATIONS">createMaterializations</a> | Whether Calcite should create materializations. Default false.
| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#DEFAULT_NULL_COLLATION">materializationsEnabled</a> | How NULL values should be sorted if neither NULLS FIRST nor NULLS LAST are specified in a query. The default, HIGH, sorts NULL values the same as Oracle.
+| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#DRUID_FETCH">druidFetch</a> | How many rows the Druid adapter should fetch at a time when executing SELECT queries.
| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#FORCE_DECORRELATE">forceDecorrelate</a> | Whether the planner should try de-correlating as much as possible. Default true.
| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#FUN">fun</a> | Collection of built-in functions and operators. Valid values: "standard" (the default), "oracle".
| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#LEX">lex</a> | Lexical policy. Values are ORACLE (default), MYSQL, MYSQL_ANSI, SQL_SERVER, JAVA.
| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#MATERIALIZATIONS_ENABLED">materializationsEnabled</a> | Whether Calcite should use materializations. Default false.
| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#MODEL">model</a> | URI of the JSON model file.
+| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#PARSER_FACTORY">parserFactory</a> | Parser factory. The name of a class that implements <a href="{{ site.apiRoot }}/org/apache/calcite/sql/parser/SqlParserImplFactory.html">SqlParserImplFactory</a> and has a public default constructor or an `INSTANCE` constant.
| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#QUOTING">quoting</a> | How identifiers are quoted. Values are DOUBLE_QUOTE, BACK_QUOTE, BRACKET. If not specified, value from `lex` is used.
+| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#QUOTED_CASING">quotedCasing</a> | How identifiers are stored if they are quoted. Values are UNCHANGED, TO_UPPER, TO_LOWER. If not specified, value from `lex` is used.
| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#SCHEMA">schema</a> | Name of initial schema.
| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#SCHEMA_FACTORY">schemaFactory</a> | Schema factory. The name of a class that implements <a href="{{ site.apiRoot }}/org/apache/calcite/schema/SchemaFactory.html">SchemaFactory</a> and has a public default constructor or an `INSTANCE` constant. Ignored if `model` is specified.
| <a href="{{ site.apiRoot }}/org/apache/calcite/config/CalciteConnectionProperty.html#SCHEMA_TYPE">schemaType</a> | Schema type. Value must be "MAP" (the default), "JDBC", or "CUSTOM" (implicit if `schemaFactory` is specified). Ignored if `model` is specified.
[3/3] calcite git commit: [CALCITE-1529] Support CREATE TABLE in
tests (and only in tests)
Posted by jh...@apache.org.
[CALCITE-1529] Support CREATE TABLE in tests (and only in tests)
Upgrade freemarker.
Add "parserFactory" to config.
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/e641211f
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/e641211f
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/e641211f
Branch: refs/heads/master
Commit: e641211fd72a4f4a24f0f4644034c4b2f3c040ca
Parents: 267e2f3
Author: Julian Hyde <jh...@apache.org>
Authored: Mon Dec 5 22:49:22 2016 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Wed Dec 7 18:35:30 2016 -0800
----------------------------------------------------------------------
core/src/main/codegen/config.fmpp | 12 +-
core/src/main/codegen/templates/Parser.jj | 61 +++++++
.../enumerable/EnumerableRelImplementor.java | 13 ++
.../enumerable/EnumerableTableModify.java | 5 +-
.../adapter/enumerable/EnumerableTableScan.java | 7 +
.../calcite/config/CalciteConnectionConfig.java | 2 +
.../config/CalciteConnectionConfigImpl.java | 6 +
.../config/CalciteConnectionProperty.java | 6 +
.../calcite/prepare/CalcitePrepareImpl.java | 24 ++-
.../java/org/apache/calcite/sql/SqlCreate.java | 46 +++++
.../org/apache/calcite/sql/SqlDataTypeSpec.java | 37 +++-
.../java/org/apache/calcite/sql/SqlDrop.java | 34 ++++
.../calcite/sql/SqlExecutableStatement.java | 31 ++++
core/src/test/codegen/config.fmpp | 17 +-
core/src/test/codegen/includes/parserImpls.ftl | 13 ++
.../calcite/sql/parser/SqlParserTest.java | 2 +-
.../ExtensionSqlParserTest.java | 5 +
.../parserextensiontesting/SqlCreateTable.java | 169 +++++++++++++++++++
.../org/apache/calcite/test/CalciteAssert.java | 3 +
.../org/apache/calcite/test/QuidemTest.java | 35 ++--
core/src/test/resources/sql/blank.iq | 44 +++++
pom.xml | 2 +-
site/_docs/reference.md | 1 +
23 files changed, 538 insertions(+), 37 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/main/codegen/config.fmpp
----------------------------------------------------------------------
diff --git a/core/src/main/codegen/config.fmpp b/core/src/main/codegen/config.fmpp
index 9f7a118..41cfeee 100644
--- a/core/src/main/codegen/config.fmpp
+++ b/core/src/main/codegen/config.fmpp
@@ -70,12 +70,22 @@ data: {
dataTypeParserMethods: [
]
- # List of methods for parsing extensions to ALTER SYSTEM calls.
+ # List of methods for parsing extensions to "ALTER <scope>" calls.
# Each must accept arguments "(SqlParserPos pos, String scope)".
# Example: "SqlUploadJarNode"
alterStatementParserMethods: [
]
+ # List of methods for parsing extensions to "CREATE [OR REPLACE]" calls.
+ # Each must accept arguments "(SqlParserPos pos, boolean replace)".
+ createStatementParserMethods: [
+ ]
+
+ # List of methods for parsing extensions to "DROP" calls.
+ # Each must accept arguments "(SqlParserPos pos)".
+ dropStatementParserMethods: [
+ ]
+
# List of files in @includes directory that have parser method
# implementations for parsing custom SQL statements, literals or types
# given as part of "statementParserMethods", "literalParserMethods" or
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/main/codegen/templates/Parser.jj
----------------------------------------------------------------------
diff --git a/core/src/main/codegen/templates/Parser.jj b/core/src/main/codegen/templates/Parser.jj
index 390c75c..26d40f4 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -928,6 +928,10 @@ SqlNode SqlStmt() :
|
stmt = SqlAlter()
|
+<#if parser.createStatementParserMethods?size != 0>
+ stmt = SqlCreate()
+ |
+</#if>
stmt = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY)
|
stmt = SqlExplain()
@@ -3088,6 +3092,61 @@ String Scope() :
( <SYSTEM> | <SESSION> ) { return token.image.toUpperCase(); }
}
+<#if parser.createStatementParserMethods?size != 0>
+/**
+ * Parses a CREATE statement.
+ */
+SqlCreate SqlCreate() :
+{
+ final SqlParserPos pos;
+ boolean replace = false;
+ final SqlCreate create;
+}
+{
+ <CREATE> { pos = getPos(); }
+ [
+ <OR> <REPLACE> {
+ replace = true;
+ }
+ ]
+ (
+ <#-- additional literal parser methods are included here -->
+ <#list parser.createStatementParserMethods as method>
+ create = ${method}(pos, replace)
+ <#sep>|</#sep>
+ </#list>
+ )
+ {
+ return create;
+ }
+}
+</#if>
+
+<#if parser.dropStatementParserMethods?size != 0>
+/**
+ * Parses a DROP statement.
+ */
+SqlDrop SqlDrop() :
+{
+ final SqlParserPos pos;
+ boolean replace = false;
+ final SqlDrop drop;
+}
+{
+ <DROP> { pos = getPos(); }
+ (
+ <#-- additional literal parser methods are included here -->
+ <#list parser.dropStatementParserMethods as method>
+ drop = ${method}(pos, replace)
+ <#sep>|</#sep>
+ </#list>
+ )
+ {
+ return drop;
+ }
+}
+</#if>
+
/**
* Parses a literal expression, allowing continued string literals.
* Usually returns an SqlLiteral, but a continued string literal
@@ -5333,6 +5392,7 @@ SqlPostfixOperator PostfixRowOperator() :
| < RELATIVE: "RELATIVE" >
| < RELEASE: "RELEASE" >
| < REPEATABLE: "REPEATABLE" >
+ | < REPLACE: "REPLACE" >
| < RESET: "RESET" >
| < RESTART: "RESTART" >
| < RESTRICT: "RESTRICT" >
@@ -5733,6 +5793,7 @@ String CommonNonReservedKeyWord() :
| <READ>
| <RELATIVE>
| <REPEATABLE>
+ | <REPLACE>
| <RESTART>
| <RESTRICT>
| <RETURNED_CARDINALITY>
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java
index 90105e0..6e9033c 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java
@@ -66,6 +66,12 @@ import java.util.Set;
* operators of {@link EnumerableConvention} calling convention.
*/
public class EnumerableRelImplementor extends JavaRelImplementor {
+ /** Maximum number of arguments to a constructor. See
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-1097">[CALCITE-1097]
+ * Exception when executing query with too many aggregation columns</a> for
+ * details. */
+ private static final int MAX_CONSTRUCTOR_ARG_COUNT = 10;
+
public final Map<String, Object> map;
private final Map<String, RexToLixTranslator.InputGetter> corrVars =
Maps.newHashMap();
@@ -482,6 +488,13 @@ public class EnumerableRelImplementor extends JavaRelImplementor {
types.add(type);
return super.visit(newArrayExpression);
}
+
+ @Override public Void visit(ConstantExpression constantExpression) {
+ if (constantExpression.value instanceof Type) {
+ types.add((Type) constantExpression.value);
+ }
+ return super.visit(constantExpression);
+ }
}
/** Adds a declaration of each synthetic type found in a code block. */
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableModify.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableModify.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableModify.java
index 07128e4..14ac0de 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableModify.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableModify.java
@@ -101,9 +101,9 @@ public class EnumerableTableModify extends TableModify
if (!getInput().getRowType().equals(getRowType())) {
final JavaTypeFactory typeFactory =
(JavaTypeFactory) getCluster().getTypeFactory();
+ final JavaRowFormat format = EnumerableTableScan.deduceFormat(table);
PhysType physType =
- PhysTypeImpl.of(typeFactory, table.getRowType(),
- JavaRowFormat.CUSTOM);
+ PhysTypeImpl.of(typeFactory, table.getRowType(), format);
List<Expression> expressionList = new ArrayList<Expression>();
final PhysType childPhysType = result.physType;
final ParameterExpression o_ =
@@ -167,6 +167,7 @@ public class EnumerableTableModify extends TableModify
? JavaRowFormat.ARRAY : JavaRowFormat.SCALAR);
return implementor.result(physType, builder.toBlock());
}
+
}
// End EnumerableTableModify.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java
index d7529ce..9fd5d34 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java
@@ -127,6 +127,13 @@ public class EnumerableTableScan
}
}
+ public static JavaRowFormat deduceFormat(RelOptTable table) {
+ final Class elementType = deduceElementType(table.unwrap(Table.class));
+ return elementType == Object[].class
+ ? JavaRowFormat.ARRAY
+ : JavaRowFormat.CUSTOM;
+ }
+
private Expression getExpression(PhysType physType) {
final Expression expression = table.getExpression(Queryable.class);
final Expression expression2 = toEnumerable(expression);
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfig.java b/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfig.java
index 1c3b0d6..6eac17d 100644
--- a/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfig.java
+++ b/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfig.java
@@ -48,6 +48,8 @@ public interface CalciteConnectionConfig extends ConnectionConfig {
Casing quotedCasing();
/** @see CalciteConnectionProperty#CASE_SENSITIVE */
boolean caseSensitive();
+ /** @see CalciteConnectionProperty#PARSER_FACTORY */
+ <T> T parserFactory(Class<T> parserFactoryClass, T defaultParserFactory);
/** @see CalciteConnectionProperty#SCHEMA_FACTORY */
<T> T schemaFactory(Class<T> schemaFactoryClass, T defaultSchemaFactory);
/** @see CalciteConnectionProperty#SCHEMA_TYPE */
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java b/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java
index 5262059..c169d9d 100644
--- a/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java
+++ b/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java
@@ -120,6 +120,12 @@ public class CalciteConnectionConfigImpl extends ConnectionConfigImpl
.getBoolean(lex().caseSensitive);
}
+ public <T> T parserFactory(Class<T> parserFactoryClass,
+ T defaultParserFactory) {
+ return CalciteConnectionProperty.PARSER_FACTORY.wrap(properties)
+ .getPlugin(parserFactoryClass, defaultParserFactory);
+ }
+
public <T> T schemaFactory(Class<T> schemaFactoryClass,
T defaultSchemaFactory) {
return CalciteConnectionProperty.SCHEMA_FACTORY.wrap(properties)
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/main/java/org/apache/calcite/config/CalciteConnectionProperty.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/config/CalciteConnectionProperty.java b/core/src/main/java/org/apache/calcite/config/CalciteConnectionProperty.java
index e17740d..20baf7f 100644
--- a/core/src/main/java/org/apache/calcite/config/CalciteConnectionProperty.java
+++ b/core/src/main/java/org/apache/calcite/config/CalciteConnectionProperty.java
@@ -78,6 +78,12 @@ public enum CalciteConnectionProperty implements ConnectionProperty {
* If not specified, value from {@link #LEX} is used. */
CASE_SENSITIVE("caseSensitive", Type.BOOLEAN, null, false),
+ /** Parser factory.
+ *
+ * <p>The name of a class that implements
+ * {@link org.apache.calcite.sql.parser.SqlParserImplFactory}. */
+ PARSER_FACTORY("parserFactory", Type.PLUGIN, null, false),
+
/** Name of initial schema. */
SCHEMA("schema", Type.STRING, null, false),
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
index 9125d0b..ee7d4ee 100644
--- a/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
+++ b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
@@ -111,6 +111,7 @@ import org.apache.calcite.schema.Schemas;
import org.apache.calcite.schema.Table;
import org.apache.calcite.server.CalciteServerStatement;
import org.apache.calcite.sql.SqlBinaryOperator;
+import org.apache.calcite.sql.SqlExecutableStatement;
import org.apache.calcite.sql.SqlExplainFormat;
import org.apache.calcite.sql.SqlExplainLevel;
import org.apache.calcite.sql.SqlKind;
@@ -121,6 +122,7 @@ import org.apache.calcite.sql.SqlUtil;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.calcite.sql.parser.SqlParser;
+import org.apache.calcite.sql.parser.SqlParserImplFactory;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.util.ChainedSqlOperatorTable;
import org.apache.calcite.sql.validate.SqlConformance;
@@ -431,6 +433,11 @@ public class CalcitePrepareImpl implements CalcitePrepare {
}
@Override public void executeDdl(Context context, SqlNode node) {
+ if (node instanceof SqlExecutableStatement) {
+ SqlExecutableStatement statement = (SqlExecutableStatement) node;
+ statement.execute(context);
+ return;
+ }
throw new UnsupportedOperationException();
}
@@ -708,12 +715,17 @@ public class CalcitePrepareImpl implements CalcitePrepare {
final Meta.StatementType statementType;
if (query.sql != null) {
final CalciteConnectionConfig config = context.config();
- SqlParser parser = createParser(query.sql,
- createParserConfig()
- .setQuotedCasing(config.quotedCasing())
- .setUnquotedCasing(config.unquotedCasing())
- .setQuoting(config.quoting())
- .setConformance(config.conformance()));
+ final SqlParser.ConfigBuilder parserConfig = createParserConfig()
+ .setQuotedCasing(config.quotedCasing())
+ .setUnquotedCasing(config.unquotedCasing())
+ .setQuoting(config.quoting())
+ .setConformance(config.conformance());
+ final SqlParserImplFactory parserFactory =
+ config.parserFactory(SqlParserImplFactory.class, null);
+ if (parserFactory != null) {
+ parserConfig.setParserFactory(parserFactory);
+ }
+ SqlParser parser = createParser(query.sql, parserConfig);
SqlNode sqlNode;
try {
sqlNode = parser.parseStmt();
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/main/java/org/apache/calcite/sql/SqlCreate.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlCreate.java b/core/src/main/java/org/apache/calcite/sql/SqlCreate.java
new file mode 100644
index 0000000..57e9a71
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/sql/SqlCreate.java
@@ -0,0 +1,46 @@
+/*
+ * 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.calcite.sql;
+
+import org.apache.calcite.sql.parser.SqlParserPos;
+
+/**
+ * Base class for an CREATE statements parse tree nodes. The portion of the
+ * statement covered by this class is "CREATE [ OR REPLACE ]". Subclasses handle
+ * whatever comes afterwards.
+ */
+public abstract class SqlCreate extends SqlCall {
+
+ /** Whether "OR REPLACE" was specified. */
+ boolean replace;
+
+ public SqlCreate(SqlParserPos pos, boolean replace) {
+ super(pos);
+ this.replace = replace;
+ }
+
+ public boolean getReplace() {
+ return replace;
+ }
+
+ public void setReplace(boolean replace) {
+ this.replace = replace;
+ }
+
+}
+
+// End SqlCreate.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/main/java/org/apache/calcite/sql/SqlDataTypeSpec.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlDataTypeSpec.java b/core/src/main/java/org/apache/calcite/sql/SqlDataTypeSpec.java
index c53b832..7c4e2cb 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlDataTypeSpec.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlDataTypeSpec.java
@@ -28,6 +28,8 @@ import org.apache.calcite.sql.validate.SqlValidatorScope;
import org.apache.calcite.util.Litmus;
import org.apache.calcite.util.Util;
+import com.google.common.base.Preconditions;
+
import java.nio.charset.Charset;
import java.util.Objects;
import java.util.TimeZone;
@@ -158,6 +160,10 @@ public class SqlDataTypeSpec extends SqlNode {
return timeZone;
}
+ public Boolean getNullable() {
+ return nullable;
+ }
+
/** Returns a copy of this data type specification with a given
* nullability. */
public SqlDataTypeSpec withNullable(Boolean nullable) {
@@ -289,9 +295,22 @@ public class SqlDataTypeSpec extends SqlNode {
* Does not throw an error if the type is not built-in.
*/
public RelDataType deriveType(RelDataTypeFactory typeFactory) {
- String name = typeName.getSimple();
+ return deriveType(typeFactory, false);
+ }
- SqlTypeName sqlTypeName = SqlTypeName.get(name);
+ /**
+ * Converts this type specification to a {@link RelDataType}.
+ *
+ * <p>Does not throw an error if the type is not built-in.
+ *
+ * @param nullable Whether the type is nullable if the type specification
+ * does not explicitly state
+ */
+ public RelDataType deriveType(RelDataTypeFactory typeFactory,
+ boolean nullable) {
+ final String name = typeName.getSimple();
+ final SqlTypeName sqlTypeName =
+ Preconditions.checkNotNull(SqlTypeName.get(name));
// NOTE jvs 15-Jan-2009: earlier validation is supposed to
// have caught these, which is why it's OK for them
@@ -322,7 +341,8 @@ public class SqlDataTypeSpec extends SqlNode {
charset = typeFactory.getDefaultCharset();
} else {
String javaCharSetName =
- SqlUtil.translateCharacterSetName(charSetName);
+ Preconditions.checkNotNull(
+ SqlUtil.translateCharacterSetName(charSetName), charSetName);
charset = Charset.forName(javaCharSetName);
}
type =
@@ -334,9 +354,9 @@ public class SqlDataTypeSpec extends SqlNode {
if (null != collectionsTypeName) {
final String collectionName = collectionsTypeName.getSimple();
-
- SqlTypeName collectionsSqlTypeName =
- SqlTypeName.get(collectionName);
+ final SqlTypeName collectionsSqlTypeName =
+ Preconditions.checkNotNull(SqlTypeName.get(collectionName),
+ collectionName);
switch (collectionsSqlTypeName) {
case MULTISET:
@@ -348,9 +368,10 @@ public class SqlDataTypeSpec extends SqlNode {
}
}
- if (nullable != null) {
- type = typeFactory.createTypeWithNullability(type, nullable);
+ if (this.nullable != null) {
+ nullable = this.nullable;
}
+ type = typeFactory.createTypeWithNullability(type, nullable);
return type;
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/main/java/org/apache/calcite/sql/SqlDrop.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlDrop.java b/core/src/main/java/org/apache/calcite/sql/SqlDrop.java
new file mode 100644
index 0000000..1716d32
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/sql/SqlDrop.java
@@ -0,0 +1,34 @@
+/*
+ * 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.calcite.sql;
+
+import org.apache.calcite.sql.parser.SqlParserPos;
+
+/**
+ * Base class for an DROP statements parse tree nodes. The portion of the
+ * statement covered by this class is "DROP". Subclasses handle
+ * whatever comes afterwards.
+ */
+public abstract class SqlDrop extends SqlCall {
+
+ public SqlDrop(SqlParserPos pos) {
+ super(pos);
+ }
+
+}
+
+// End SqlDrop.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/main/java/org/apache/calcite/sql/SqlExecutableStatement.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlExecutableStatement.java b/core/src/main/java/org/apache/calcite/sql/SqlExecutableStatement.java
new file mode 100644
index 0000000..06ca55f
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/sql/SqlExecutableStatement.java
@@ -0,0 +1,31 @@
+/*
+ * 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.calcite.sql;
+
+import org.apache.calcite.jdbc.CalcitePrepare;
+
+/**
+ * Mix-in interface for {@link SqlNode} that allows DDL commands to be
+ * executed directly.
+ *
+ * <p>NOTE: Subject to change without notice.
+ */
+public interface SqlExecutableStatement {
+ void execute(CalcitePrepare.Context context);
+}
+
+// End SqlExecutableStatement.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/test/codegen/config.fmpp
----------------------------------------------------------------------
diff --git a/core/src/test/codegen/config.fmpp b/core/src/test/codegen/config.fmpp
index 7b8b8e2..bd168b1 100644
--- a/core/src/test/codegen/config.fmpp
+++ b/core/src/test/codegen/config.fmpp
@@ -21,6 +21,8 @@ data: {
# List of import statements.
imports: [
+ "org.apache.calcite.sql.SqlCreate",
+ "org.apache.calcite.sql.parser.parserextensiontesting.SqlCreateTable",
"org.apache.calcite.sql.parser.parserextensiontesting.SqlUploadJarNode"
]
@@ -47,14 +49,25 @@ data: {
dataTypeParserMethods: [
]
- # List of methods for parsing extensions to ALTER SYSTEM calls.
+ # List of methods for parsing extensions to "ALTER <scope>" calls.
# Each must accept arguments "(SqlParserPos pos, String scope)".
alterStatementParserMethods: [
"SqlUploadJarNode"
]
+ # List of methods for parsing extensions to "CREATE [OR REPLACE]" calls.
+ # Each must accept arguments "(SqlParserPos pos, boolean replace)".
+ createStatementParserMethods: [
+ "SqlCreateTable"
+ ]
+
+ # List of methods for parsing extensions to "DROP" calls.
+ # Each must accept arguments "(SqlParserPos pos)".
+ dropStatementParserMethods: [
+ ]
+
# List of files in @includes directory that have parser method
- # implementations for custom SQL statements, literals or types
+ # implementations for parsing custom SQL statements, literals or types
# given as part of "statementParserMethods", "literalParserMethods" or
# "dataTypeParserMethods".
implementationFiles: [
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/test/codegen/includes/parserImpls.ftl
----------------------------------------------------------------------
diff --git a/core/src/test/codegen/includes/parserImpls.ftl b/core/src/test/codegen/includes/parserImpls.ftl
index 2305fc1..56a4099 100644
--- a/core/src/test/codegen/includes/parserImpls.ftl
+++ b/core/src/test/codegen/includes/parserImpls.ftl
@@ -35,3 +35,16 @@ SqlAlter SqlUploadJarNode(SqlParserPos pos, String scope) :
return new SqlUploadJarNode(pos.plus(getPos()), scope, jarPathsList);
}
}
+
+SqlCreate SqlCreateTable(SqlParserPos pos, boolean replace) :
+{
+ final SqlIdentifier id;
+ final SqlNodeList columnList;
+}
+{
+ <TABLE> id = CompoundIdentifier() columnList = ExtendList() {
+ return new SqlCreateTable(pos, id, columnList);
+ }
+}
+
+// End parserImpls.ftl
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java b/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
index 294a2f3..fa12def 100644
--- a/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
@@ -7308,7 +7308,7 @@ public class SqlParserTest {
/** Helper class for building fluent code such as
* {@code sql("values 1").ok();}. */
- private class Sql {
+ protected class Sql {
private final String sql;
Sql(String sql) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/test/java/org/apache/calcite/sql/parser/parserextensiontesting/ExtensionSqlParserTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/parser/parserextensiontesting/ExtensionSqlParserTest.java b/core/src/test/java/org/apache/calcite/sql/parser/parserextensiontesting/ExtensionSqlParserTest.java
index 51e24bd..9d6fcfa 100644
--- a/core/src/test/java/org/apache/calcite/sql/parser/parserextensiontesting/ExtensionSqlParserTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/parser/parserextensiontesting/ExtensionSqlParserTest.java
@@ -44,6 +44,11 @@ public class ExtensionSqlParserTest extends SqlParserTest {
checkFails("^upload^ jar '/path/to/jar'",
"(?s).*Encountered \"upload\" at .*");
}
+
+ @Test public void testCreateTable() {
+ sql("CREATE TABLE foo.baz(i INTEGER, j VARCHAR(10) NOT NULL)")
+ .ok("CREATE TABLE `FOO`.`BAZ` (`I` INTEGER, `J` VARCHAR(10) NOT NULL)");
+ }
}
// End ExtensionSqlParserTest.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/test/java/org/apache/calcite/sql/parser/parserextensiontesting/SqlCreateTable.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/parser/parserextensiontesting/SqlCreateTable.java b/core/src/test/java/org/apache/calcite/sql/parser/parserextensiontesting/SqlCreateTable.java
new file mode 100644
index 0000000..3889c12
--- /dev/null
+++ b/core/src/test/java/org/apache/calcite/sql/parser/parserextensiontesting/SqlCreateTable.java
@@ -0,0 +1,169 @@
+/*
+ * 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.calcite.sql.parser.parserextensiontesting;
+
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.jdbc.CalcitePrepare;
+import org.apache.calcite.jdbc.CalciteSchema;
+import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
+import org.apache.calcite.linq4j.Enumerator;
+import org.apache.calcite.linq4j.Linq4j;
+import org.apache.calcite.linq4j.QueryProvider;
+import org.apache.calcite.linq4j.Queryable;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rel.type.RelDataTypeImpl;
+import org.apache.calcite.rel.type.RelProtoDataType;
+import org.apache.calcite.schema.SchemaPlus;
+import org.apache.calcite.schema.Schemas;
+import org.apache.calcite.schema.impl.AbstractTableQueryable;
+import org.apache.calcite.sql.SqlCreate;
+import org.apache.calcite.sql.SqlDataTypeSpec;
+import org.apache.calcite.sql.SqlExecutableStatement;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.SqlSpecialOperator;
+import org.apache.calcite.sql.SqlWriter;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.test.JdbcTest;
+import org.apache.calcite.util.Pair;
+import org.apache.calcite.util.Util;
+
+import com.google.common.collect.ImmutableList;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Simple test example of a CREATE TABLE statement.
+ */
+public class SqlCreateTable extends SqlCreate
+ implements SqlExecutableStatement {
+ private final SqlIdentifier name;
+ private final SqlNodeList columnList;
+
+ private static final SqlOperator OPERATOR =
+ new SqlSpecialOperator("CREATE TABLE", SqlKind.OTHER_DDL);
+
+ /** Creates a SqlCreateTable. */
+ public SqlCreateTable(SqlParserPos pos, SqlIdentifier name,
+ SqlNodeList columnList) {
+ super(pos, false);
+ this.name = name;
+ this.columnList = columnList;
+ }
+
+ @Override public SqlOperator getOperator() {
+ return OPERATOR;
+ }
+
+ @Override public List<SqlNode> getOperandList() {
+ return ImmutableList.of(name, columnList);
+ }
+
+ @Override public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {
+ writer.keyword("CREATE");
+ writer.keyword("TABLE");
+ name.unparse(writer, leftPrec, rightPrec);
+ SqlWriter.Frame frame = writer.startList("(", ")");
+ for (Pair<SqlIdentifier, SqlDataTypeSpec> pair : nameTypes()) {
+ writer.sep(",");
+ pair.left.unparse(writer, leftPrec, rightPrec); // name
+ pair.right.unparse(writer, leftPrec, rightPrec); // type
+ if (Boolean.FALSE.equals(pair.right.getNullable())) {
+ writer.keyword("NOT NULL");
+ }
+ }
+ writer.endList(frame);
+ }
+
+ /** Creates a list of (name, type) pairs from {@link #columnList}, in which
+ * they alternate. */
+ private List<Pair<SqlIdentifier, SqlDataTypeSpec>> nameTypes() {
+ final List list = columnList.getList();
+ //noinspection unchecked
+ return Pair.zip((List<SqlIdentifier>) Util.quotientList(list, 2, 0),
+ Util.quotientList((List<SqlDataTypeSpec>) list, 2, 1));
+ }
+
+ public void execute(CalcitePrepare.Context context) {
+ final List<String> path = context.getDefaultSchemaPath();
+ CalciteSchema schema = context.getRootSchema();
+ for (String p : path) {
+ schema = schema.getSubSchema(p, true);
+ }
+ final JavaTypeFactory typeFactory = new JavaTypeFactoryImpl();
+ final RelDataTypeFactory.FieldInfoBuilder builder = typeFactory.builder();
+ for (Pair<SqlIdentifier, SqlDataTypeSpec> pair : nameTypes()) {
+ builder.add(pair.left.getSimple(),
+ pair.right.deriveType(typeFactory, true));
+ }
+ final RelDataType rowType = builder.build();
+ schema.add(name.getSimple(),
+ new MutableArrayTable(name.getSimple(),
+ RelDataTypeImpl.proto(rowType)));
+ }
+
+ /** Table backed by a Java list. */
+ private static class MutableArrayTable
+ extends JdbcTest.AbstractModifiableTable {
+ final List list = new ArrayList();
+ private final RelProtoDataType protoRowType;
+
+ MutableArrayTable(String name, RelProtoDataType protoRowType) {
+ super(name);
+ this.protoRowType = protoRowType;
+ }
+
+ public Collection getModifiableCollection() {
+ return list;
+ }
+
+ public <T> Queryable<T> asQueryable(QueryProvider queryProvider,
+ SchemaPlus schema, String tableName) {
+ return new AbstractTableQueryable<T>(queryProvider, schema, this,
+ tableName) {
+ public Enumerator<T> enumerator() {
+ //noinspection unchecked
+ return (Enumerator<T>) Linq4j.enumerator(list);
+ }
+ };
+ }
+
+ public Type getElementType() {
+ return Object[].class;
+ }
+
+ public Expression getExpression(SchemaPlus schema, String tableName,
+ Class clazz) {
+ return Schemas.tableExpression(schema, getElementType(),
+ tableName, clazz);
+ }
+
+ public RelDataType getRowType(RelDataTypeFactory typeFactory) {
+ return protoRowType.apply(typeFactory);
+ }
+ }
+}
+
+// End SqlCreateTable.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
index 2eb14f4..a6ff27f 100644
--- a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
+++ b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
@@ -684,6 +684,8 @@ public class CalciteAssert {
case LINGUAL:
return rootSchema.add("SALES",
new ReflectiveSchema(new JdbcTest.LingualSchema()));
+ case BLANK:
+ return rootSchema.add("BLANK", new AbstractSchema());
case ORINOCO:
final SchemaPlus orinoco = rootSchema.add("ORINOCO", new AbstractSchema());
orinoco.add("ORDERS",
@@ -1632,6 +1634,7 @@ public class CalciteAssert {
HR,
JDBC_SCOTT,
SCOTT,
+ BLANK,
LINGUAL,
POST,
ORINOCO
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/test/java/org/apache/calcite/test/QuidemTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/QuidemTest.java b/core/src/test/java/org/apache/calcite/test/QuidemTest.java
index 78b202c..88479c6 100644
--- a/core/src/test/java/org/apache/calcite/test/QuidemTest.java
+++ b/core/src/test/java/org/apache/calcite/test/QuidemTest.java
@@ -265,46 +265,48 @@ public class QuidemTest {
}
return null;
}
- if (name.equals("hr")) {
+ switch (name) {
+ case "hr":
return CalciteAssert.hr()
.connect();
- }
- if (name.equals("foodmart")) {
+ case "foodmart":
return CalciteAssert.that()
.with(CalciteAssert.Config.FOODMART_CLONE)
.connect();
- }
- if (name.equals("scott")) {
+ case "scott":
return CalciteAssert.that()
.with(CalciteAssert.Config.SCOTT)
.connect();
- }
- if (name.equals("jdbc_scott")) {
+ case "jdbc_scott":
return CalciteAssert.that()
.with(CalciteAssert.Config.JDBC_SCOTT)
.connect();
- }
- if (name.equals("post")) {
+ case "post":
return CalciteAssert.that()
.with(CalciteAssert.Config.REGULAR)
.with(CalciteAssert.SchemaSpec.POST)
.withDefaultSchema("POST")
.connect();
- }
- if (name.equals("catchall")) {
+ case "catchall":
return CalciteAssert.that()
.withSchema("s",
new ReflectiveSchema(
new ReflectiveSchemaTest.CatchallSchema()))
.connect();
- }
- if (name.equals("orinoco")) {
+ case "orinoco":
return CalciteAssert.that()
.with(CalciteAssert.SchemaSpec.ORINOCO)
.withDefaultSchema("ORINOCO")
.connect();
- }
- if (name.equals("seq")) {
+ case "blank":
+ return CalciteAssert.that()
+ .with("parserFactory",
+ "org.apache.calcite.sql.parser.parserextensiontesting"
+ + ".ExtensionSqlParserImpl#FACTORY")
+ .with(CalciteAssert.SchemaSpec.BLANK)
+ .withDefaultSchema("BLANK")
+ .connect();
+ case "seq":
final Connection connection = CalciteAssert.that()
.withSchema("s", new AbstractSchema())
.connect();
@@ -323,8 +325,9 @@ public class QuidemTest {
}
});
return connection;
+ default:
+ throw new RuntimeException("unknown connection '" + name + "'");
}
- throw new RuntimeException("unknown connection '" + name + "'");
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/core/src/test/resources/sql/blank.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/blank.iq b/core/src/test/resources/sql/blank.iq
new file mode 100644
index 0000000..e2ce690
--- /dev/null
+++ b/core/src/test/resources/sql/blank.iq
@@ -0,0 +1,44 @@
+# blank.iq - Queries that start from a blank schema and create their own tables
+#
+# 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.
+#
+!use blank
+!set outputformat mysql
+
+create table foo (i int not null, j int);
+(-1 rows modified)
+
+!update
+insert into foo values (1, 0);
+(1 row modified)
+
+!update
+insert into foo values (0, 2);
+(1 row modified)
+
+!update
+select * from foo;
++---+---+
+| I | J |
++---+---+
+| 0 | 2 |
+| 1 | 0 |
++---+---+
+(2 rows)
+
+!ok
+
+# End blank.iq
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 2551d53..b342535 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,7 +65,7 @@ limitations under the License.
<fmpp-maven-plugin.version>1.0</fmpp-maven-plugin.version>
<foodmart-data-hsqldb.version>0.3</foodmart-data-hsqldb.version>
<foodmart-queries.version>0.4.1</foodmart-queries.version>
- <freemarker.version>2.3.19</freemarker.version>
+ <freemarker.version>2.3.25-incubating</freemarker.version>
<git-commit-id-plugin.version>2.1.9</git-commit-id-plugin.version>
<!-- We support (and test against) Guava versions between
http://git-wip-us.apache.org/repos/asf/calcite/blob/e641211f/site/_docs/reference.md
----------------------------------------------------------------------
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index 2aec223..6b4c4ab 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -606,6 +606,7 @@ READ,
RELATIVE,
**RELEASE**,
REPEATABLE,
+REPLACE,
**RESET**,
RESTART,
RESTRICT,
[2/3] calcite git commit: [CALCITE-1530] Create a visitor to traverse
linq4j expressions without mutating them, and rename Visitor to Shuttle
Posted by jh...@apache.org.
[CALCITE-1530] Create a visitor to traverse linq4j expressions without mutating them, and rename Visitor to Shuttle
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/267e2f3e
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/267e2f3e
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/267e2f3e
Branch: refs/heads/master
Commit: 267e2f3e1db71e678f80bb69015164c0d45bcfe4
Parents: 02752fe
Author: Julian Hyde <jh...@apache.org>
Authored: Mon Dec 5 19:53:41 2016 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Wed Dec 7 11:17:40 2016 -0800
----------------------------------------------------------------------
.../enumerable/EnumerableRelImplementor.java | 19 +-
.../calcite/adapter/enumerable/RexImpTable.java | 4 +-
.../calcite/linq4j/tree/AbstractNode.java | 2 +-
.../calcite/linq4j/tree/BinaryExpression.java | 6 +-
.../calcite/linq4j/tree/BlockBuilder.java | 67 +--
.../calcite/linq4j/tree/BlockStatement.java | 12 +-
.../calcite/linq4j/tree/ClassDeclaration.java | 12 +-
.../linq4j/tree/ClassDeclarationFinder.java | 8 +-
.../linq4j/tree/ConditionalExpression.java | 6 +-
.../linq4j/tree/ConditionalStatement.java | 12 +-
.../calcite/linq4j/tree/ConstantExpression.java | 6 +-
.../linq4j/tree/ConstructorDeclaration.java | 12 +-
.../linq4j/tree/DeclarationStatement.java | 12 +-
.../calcite/linq4j/tree/DefaultExpression.java | 7 +-
.../calcite/linq4j/tree/DynamicExpression.java | 7 +-
.../apache/calcite/linq4j/tree/Expression.java | 2 +-
.../apache/calcite/linq4j/tree/Expressions.java | 44 +-
.../calcite/linq4j/tree/FieldDeclaration.java | 12 +-
.../calcite/linq4j/tree/ForStatement.java | 18 +-
.../calcite/linq4j/tree/FunctionExpression.java | 12 +-
.../calcite/linq4j/tree/GotoStatement.java | 12 +-
.../calcite/linq4j/tree/IndexExpression.java | 13 +-
.../linq4j/tree/InvocationExpression.java | 7 +-
.../calcite/linq4j/tree/LabelStatement.java | 6 +-
.../calcite/linq4j/tree/LambdaExpression.java | 7 +-
.../calcite/linq4j/tree/ListInitExpression.java | 7 +-
.../calcite/linq4j/tree/MemberDeclaration.java | 2 +-
.../calcite/linq4j/tree/MemberExpression.java | 12 +-
.../linq4j/tree/MemberInitExpression.java | 7 +-
.../linq4j/tree/MethodCallExpression.java | 14 +-
.../calcite/linq4j/tree/MethodDeclaration.java | 12 +-
.../calcite/linq4j/tree/NewArrayExpression.java | 14 +-
.../calcite/linq4j/tree/NewExpression.java | 14 +-
.../org/apache/calcite/linq4j/tree/Node.java | 4 +-
.../calcite/linq4j/tree/OptimizeShuttle.java | 422 ++++++++++++++++++
.../calcite/linq4j/tree/OptimizeVisitor.java | 423 -------------------
.../linq4j/tree/ParameterExpression.java | 6 +-
.../org/apache/calcite/linq4j/tree/Shuttle.java | 335 +++++++++++++++
.../apache/calcite/linq4j/tree/Statement.java | 2 +-
.../calcite/linq4j/tree/SwitchStatement.java | 7 +-
.../calcite/linq4j/tree/TernaryExpression.java | 16 +-
.../calcite/linq4j/tree/ThrowStatement.java | 12 +-
.../calcite/linq4j/tree/TryStatement.java | 6 +-
.../linq4j/tree/TypeBinaryExpression.java | 12 +-
.../calcite/linq4j/tree/UnaryExpression.java | 12 +-
.../org/apache/calcite/linq4j/tree/Visitor.java | 351 ++-------------
.../apache/calcite/linq4j/tree/VisitorImpl.java | 206 +++++++++
.../calcite/linq4j/tree/WhileStatement.java | 14 +-
.../calcite/linq4j/test/BlockBuilderTest.java | 8 +-
.../calcite/linq4j/test/ExpressionTest.java | 12 +-
site/_docs/adapter.md | 5 +-
51 files changed, 1336 insertions(+), 924 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java
index bc88333..90105e0 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java
@@ -36,7 +36,7 @@ import org.apache.calcite.linq4j.tree.ParameterExpression;
import org.apache.calcite.linq4j.tree.Primitive;
import org.apache.calcite.linq4j.tree.Statement;
import org.apache.calcite.linq4j.tree.Types;
-import org.apache.calcite.linq4j.tree.Visitor;
+import org.apache.calcite.linq4j.tree.VisitorImpl;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.runtime.Bindable;
import org.apache.calcite.util.BuiltInMethod;
@@ -458,26 +458,19 @@ public class EnumerableRelImplementor extends JavaRelImplementor {
}
/** Visitor that finds types in an {@link Expression} tree. */
- private static class TypeFinder extends Visitor {
+ private static class TypeFinder extends VisitorImpl<Void> {
private final Collection<Type> types;
TypeFinder(Collection<Type> types) {
this.types = types;
}
- @Override public Expression visit(
- NewExpression newExpression,
- List<Expression> arguments,
- List<MemberDeclaration> memberDeclarations) {
+ @Override public Void visit(NewExpression newExpression) {
types.add(newExpression.type);
- return super.visit(
- newExpression,
- arguments,
- memberDeclarations);
+ return super.visit(newExpression);
}
- @Override public Expression visit(NewArrayExpression newArrayExpression,
- int dimension, Expression bound, List<Expression> expressions) {
+ @Override public Void visit(NewArrayExpression newArrayExpression) {
Type type = newArrayExpression.type;
for (;;) {
final Type componentType = Types.getComponentType(type);
@@ -487,7 +480,7 @@ public class EnumerableRelImplementor extends JavaRelImplementor {
type = componentType;
}
types.add(type);
- return super.visit(newArrayExpression, dimension, bound, expressions);
+ return super.visit(newArrayExpression);
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
index 5984fca..ddcb8dc 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
@@ -27,7 +27,7 @@ import org.apache.calcite.linq4j.tree.Expression;
import org.apache.calcite.linq4j.tree.ExpressionType;
import org.apache.calcite.linq4j.tree.Expressions;
import org.apache.calcite.linq4j.tree.MemberExpression;
-import org.apache.calcite.linq4j.tree.OptimizeVisitor;
+import org.apache.calcite.linq4j.tree.OptimizeShuttle;
import org.apache.calcite.linq4j.tree.ParameterExpression;
import org.apache.calcite.linq4j.tree.Primitive;
import org.apache.calcite.linq4j.tree.Types;
@@ -640,7 +640,7 @@ public class RexImpTable {
}
static Expression optimize(Expression expression) {
- return expression.accept(new OptimizeVisitor());
+ return expression.accept(new OptimizeShuttle());
}
static Expression optimize2(Expression operand, Expression expression) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/AbstractNode.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/AbstractNode.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/AbstractNode.java
index c74adc6..38aec48 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/AbstractNode.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/AbstractNode.java
@@ -65,7 +65,7 @@ public abstract class AbstractNode implements Node {
"un-parse not supported: " + getClass() + ":" + nodeType);
}
- public Node accept(Visitor visitor) {
+ public Node accept(Shuttle shuttle) {
throw new RuntimeException(
"visit not supported: " + getClass() + ":" + nodeType);
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BinaryExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BinaryExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BinaryExpression.java
index eb73da3..f8056c7 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BinaryExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BinaryExpression.java
@@ -37,13 +37,17 @@ public class BinaryExpression extends Expression {
this.primitive = Primitive.of(expression0.getType());
}
- @Override public Expression accept(Visitor visitor) {
+ @Override public Expression accept(Shuttle visitor) {
visitor = visitor.preVisit(this);
Expression expression0 = this.expression0.accept(visitor);
Expression expression1 = this.expression1.accept(visitor);
return visitor.visit(this, expression0, expression1);
}
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
+ }
+
public Object evaluate(Evaluator evaluator) {
switch (nodeType) {
case AndAlso:
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BlockBuilder.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BlockBuilder.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BlockBuilder.java
index c58a258..ff13d66 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BlockBuilder.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BlockBuilder.java
@@ -32,18 +32,18 @@ import java.util.Set;
* <p>Has methods that help ensure that variable names are unique.</p>
*/
public class BlockBuilder {
- final List<Statement> statements = new ArrayList<Statement>();
- final Set<String> variables = new HashSet<String>();
+ final List<Statement> statements = new ArrayList<>();
+ final Set<String> variables = new HashSet<>();
/** Contains final-fine-to-reuse-declarations.
* An entry to this map is added when adding final declaration of a
* statement with optimize=true parameter. */
final Map<Expression, DeclarationStatement> expressionForReuse =
- new HashMap<Expression, DeclarationStatement>();
+ new HashMap<>();
private final boolean optimizing;
private final BlockBuilder parent;
- private static final Visitor OPTIMIZE_VISITOR = new OptimizeVisitor();
+ private static final Shuttle OPTIMIZE_SHUTTLE = new OptimizeShuttle();
/**
* Creates a non-optimizing BlockBuilder.
@@ -111,13 +111,13 @@ public class BlockBuilder {
}
Expression result = null;
final Map<ParameterExpression, Expression> replacements =
- new IdentityHashMap<ParameterExpression, Expression>();
- final Visitor visitor = new SubstituteVariableVisitor(replacements);
+ new IdentityHashMap<>();
+ final Shuttle shuttle = new SubstituteVariableVisitor(replacements);
for (int i = 0; i < block.statements.size(); i++) {
Statement statement = block.statements.get(i);
if (!replacements.isEmpty()) {
// Save effort, and only substitute variables if there are some.
- statement = statement.accept(visitor);
+ statement = statement.accept(shuttle);
}
if (statement instanceof DeclarationStatement) {
DeclarationStatement declaration = (DeclarationStatement) statement;
@@ -303,11 +303,11 @@ public class BlockBuilder {
// loop. Optimize should not loop forever, however it is hard to prove if
// it always finishes in reasonable time.
for (int i = 0; i < 10; i++) {
- if (!optimize(createOptimizeVisitor(), true)) {
+ if (!optimize(createOptimizeShuttle(), true)) {
break;
}
}
- optimize(createFinishingOptimizeVisitor(), false);
+ optimize(createFinishingOptimizeShuttle(), false);
}
return Expressions.block(statements);
}
@@ -318,7 +318,7 @@ public class BlockBuilder {
*
* @return whether any optimizations were made
*/
- private boolean optimize(Visitor optimizer, boolean performInline) {
+ private boolean optimize(Shuttle optimizer, boolean performInline) {
int optimizeCount = 0;
final UseCounter useCounter = new UseCounter();
for (Statement statement : statements) {
@@ -334,12 +334,10 @@ public class BlockBuilder {
}
}
final Map<ParameterExpression, Expression> subMap =
- new IdentityHashMap<ParameterExpression, Expression>(
- useCounter.map.size());
+ new IdentityHashMap<>(useCounter.map.size());
final SubstituteVariableVisitor visitor = new SubstituteVariableVisitor(
subMap);
- final ArrayList<Statement> oldStatements = new ArrayList<Statement>(
- statements);
+ final ArrayList<Statement> oldStatements = new ArrayList<>(statements);
statements.clear();
for (Statement oldStatement : oldStatements) {
@@ -400,10 +398,10 @@ public class BlockBuilder {
DeclarationStatement newDecl =
(DeclarationStatement) oldStatement;
subMap.put(newDecl.parameter, normalizeDeclaration(newDecl));
- oldStatement = OptimizeVisitor.EMPTY_STATEMENT;
+ oldStatement = OptimizeShuttle.EMPTY_STATEMENT;
}
}
- if (oldStatement != OptimizeVisitor.EMPTY_STATEMENT) {
+ if (oldStatement != OptimizeShuttle.EMPTY_STATEMENT) {
if (oldStatement instanceof DeclarationStatement) {
addExpressionForReuse((DeclarationStatement) oldStatement);
}
@@ -420,7 +418,7 @@ public class BlockBuilder {
if (beforeOptimize != oldStatement) {
++optimizeCount;
}
- if (oldStatement != OptimizeVisitor.EMPTY_STATEMENT) {
+ if (oldStatement != OptimizeShuttle.EMPTY_STATEMENT) {
statements.add(oldStatement);
}
}
@@ -429,23 +427,23 @@ public class BlockBuilder {
}
/**
- * Creates a visitor that will be used during block optimization.
- * Subclasses might provide more specific optimizations (e.g. partial
+ * Creates a shuttle that will be used during block optimization.
+ * Sub-classes might provide more specific optimizations (e.g. partial
* evaluation).
*
- * @return visitor used to optimize the statements when converting to block
+ * @return shuttle used to optimize the statements when converting to block
*/
- protected Visitor createOptimizeVisitor() {
- return OPTIMIZE_VISITOR;
+ protected Shuttle createOptimizeShuttle() {
+ return OPTIMIZE_SHUTTLE;
}
/**
- * Creates a final optimization visitor.
+ * Creates a final optimization shuttle.
* Typically, the visitor will factor out constant expressions.
*
- * @return visitor that is used to finalize the optimization
+ * @return shuttle that is used to finalize the optimization
*/
- protected Visitor createFinishingOptimizeVisitor() {
+ protected Shuttle createFinishingOptimizeShuttle() {
return ClassDeclarationFinder.create();
}
@@ -484,10 +482,10 @@ public class BlockBuilder {
}
/** Substitute Variable Visitor. */
- private static class SubstituteVariableVisitor extends Visitor {
+ private static class SubstituteVariableVisitor extends Shuttle {
private final Map<ParameterExpression, Expression> map;
private final Map<ParameterExpression, Boolean> actives =
- new IdentityHashMap<ParameterExpression, Boolean>();
+ new IdentityHashMap<>();
public SubstituteVariableVisitor(Map<ParameterExpression, Expression> map) {
this.map = map;
@@ -544,11 +542,10 @@ public class BlockBuilder {
}
/** Use counter. */
- private static class UseCounter extends Visitor {
- private final Map<ParameterExpression, Slot> map =
- new IdentityHashMap<ParameterExpression, Slot>();
+ private static class UseCounter extends VisitorImpl<Void> {
+ private final Map<ParameterExpression, Slot> map = new IdentityHashMap<>();
- @Override public Expression visit(ParameterExpression parameter) {
+ @Override public Void visit(ParameterExpression parameter) {
final Slot slot = map.get(parameter);
if (slot != null) {
// Count use of parameter, if it's registered. It's OK if
@@ -558,6 +555,14 @@ public class BlockBuilder {
}
return super.visit(parameter);
}
+
+ @Override public Void visit(DeclarationStatement declarationStatement) {
+ // Unlike base class, do not visit declarationStatement.parameter.
+ if (declarationStatement.initializer != null) {
+ declarationStatement.initializer.accept(this);
+ }
+ return null;
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BlockStatement.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BlockStatement.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BlockStatement.java
index 26a8c09..54e62e4 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BlockStatement.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/BlockStatement.java
@@ -54,11 +54,15 @@ public class BlockStatement extends Statement {
return true;
}
- @Override public BlockStatement accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
+ @Override public BlockStatement accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
List<Statement> newStatements = Expressions.acceptStatements(statements,
- visitor);
- return visitor.visit(this, newStatements);
+ shuttle);
+ return shuttle.visit(this, newStatements);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
@Override void accept0(ExpressionWriter writer) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ClassDeclaration.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ClassDeclaration.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ClassDeclaration.java
index 172112f..424ce54 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ClassDeclaration.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ClassDeclaration.java
@@ -59,11 +59,15 @@ public class ClassDeclaration extends MemberDeclaration {
writer.newlineAndIndent();
}
- public ClassDeclaration accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
+ public ClassDeclaration accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
final List<MemberDeclaration> members1 =
- Expressions.acceptMemberDeclarations(memberDeclarations, visitor);
- return visitor.visit(this, members1);
+ Expressions.acceptMemberDeclarations(memberDeclarations, shuttle);
+ return shuttle.visit(this, members1);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
@Override public boolean equals(Object o) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ClassDeclarationFinder.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ClassDeclarationFinder.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ClassDeclarationFinder.java
index 2388538..3af0fe6 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ClassDeclarationFinder.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ClassDeclarationFinder.java
@@ -29,7 +29,7 @@ import java.util.List;
* Instances of this class should not be reused, so new visitor should be
* created for optimizing a new expression tree.
*/
-public class ClassDeclarationFinder extends Visitor {
+public class ClassDeclarationFinder extends Shuttle {
protected final ClassDeclarationFinder parent;
/**
@@ -144,7 +144,7 @@ public class ClassDeclarationFinder extends Visitor {
* @param newExpression expression to optimize
* @return nested visitor if anonymous class is given
*/
- @Override public Visitor preVisit(NewExpression newExpression) {
+ @Override public Shuttle preVisit(NewExpression newExpression) {
if (newExpression.memberDeclarations == null) {
return this;
}
@@ -159,7 +159,7 @@ public class ClassDeclarationFinder extends Visitor {
* @param classDeclaration expression to optimize
* @return nested visitor
*/
- @Override public Visitor preVisit(ClassDeclaration classDeclaration) {
+ @Override public Shuttle preVisit(ClassDeclaration classDeclaration) {
ClassDeclarationFinder visitor = goDeeper();
visitor.learnFinalStaticDeclarations(classDeclaration.memberDeclarations);
return visitor;
@@ -228,7 +228,7 @@ public class ClassDeclarationFinder extends Visitor {
return memberDeclarations;
}
List<MemberDeclaration> newDecls =
- new ArrayList<MemberDeclaration>(memberDeclarations.size()
+ new ArrayList<>(memberDeclarations.size()
+ addedDeclarations.size());
newDecls.addAll(memberDeclarations);
newDecls.addAll(addedDeclarations);
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConditionalExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConditionalExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConditionalExpression.java
index 6491aa0..1b49a81 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConditionalExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConditionalExpression.java
@@ -33,7 +33,7 @@ import java.util.Objects;
* </p>
*/
public class ConditionalExpression extends AbstractNode {
- private final List<Node> expressionList;
+ final List<Node> expressionList;
public ConditionalExpression(List<Node> expressionList, Type type) {
super(ExpressionType.Conditional, type);
@@ -41,6 +41,10 @@ public class ConditionalExpression extends AbstractNode {
this.expressionList = expressionList;
}
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
+ }
+
@Override void accept(ExpressionWriter writer, int lprec, int rprec) {
for (int i = 0; i < expressionList.size(); i += 2) {
writer.append(i > 0 ? " else if (" : "if (")
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConditionalStatement.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConditionalStatement.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConditionalStatement.java
index 2334557..64e54d4 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConditionalStatement.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConditionalStatement.java
@@ -40,10 +40,14 @@ public class ConditionalStatement extends Statement {
this.expressionList = expressionList;
}
- @Override public Statement accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
- List<Node> list = Expressions.acceptNodes(expressionList, visitor);
- return visitor.visit(this, list);
+ @Override public Statement accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
+ List<Node> list = Expressions.acceptNodes(expressionList, shuttle);
+ return shuttle.visit(this, list);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
@Override void accept0(ExpressionWriter writer) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java
index 52c6975..3fc112b 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java
@@ -58,7 +58,11 @@ public class ConstantExpression extends Expression {
return value;
}
- @Override public Expression accept(Visitor visitor) {
+ @Override public Expression accept(Shuttle shuttle) {
+ return shuttle.visit(this);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visit(this);
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstructorDeclaration.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstructorDeclaration.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstructorDeclaration.java
index 471357d..1aa28b4 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstructorDeclaration.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstructorDeclaration.java
@@ -48,11 +48,15 @@ public class ConstructorDeclaration extends MemberDeclaration {
this.body = body;
}
- @Override public MemberDeclaration accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
+ @Override public MemberDeclaration accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
// do not visit parameters
- final BlockStatement body = this.body.accept(visitor);
- return visitor.visit(this, body);
+ final BlockStatement body = this.body.accept(shuttle);
+ return shuttle.visit(this, body);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
public void accept(ExpressionWriter writer) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DeclarationStatement.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DeclarationStatement.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DeclarationStatement.java
index f835d1e..c080c84 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DeclarationStatement.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DeclarationStatement.java
@@ -36,13 +36,17 @@ public class DeclarationStatement extends Statement {
this.initializer = initializer;
}
- @Override public DeclarationStatement accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
+ @Override public DeclarationStatement accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
// do not visit parameter - visit may not return a ParameterExpression
Expression initializer = this.initializer != null
- ? this.initializer.accept(visitor)
+ ? this.initializer.accept(shuttle)
: null;
- return visitor.visit(this, initializer);
+ return shuttle.visit(this, initializer);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
@Override void accept0(ExpressionWriter writer) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DefaultExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DefaultExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DefaultExpression.java
index 8569528..c78847d 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DefaultExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DefaultExpression.java
@@ -24,9 +24,14 @@ public class DefaultExpression extends Expression {
super(ExpressionType.Default, type);
}
- @Override public Expression accept(Visitor visitor) {
+ @Override public Expression accept(Shuttle shuttle) {
+ return shuttle.visit(this);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visit(this);
}
+
}
// End DefaultExpression.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DynamicExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DynamicExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DynamicExpression.java
index ff03001..f9c7c4f 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DynamicExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/DynamicExpression.java
@@ -24,9 +24,14 @@ public class DynamicExpression extends Expression {
super(ExpressionType.Dynamic, type);
}
- @Override public Expression accept(Visitor visitor) {
+ @Override public Expression accept(Shuttle shuttle) {
+ return shuttle.visit(this);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visit(this);
}
+
}
// End DynamicExpression.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expression.java
index 4c3427b..ff5f38f 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expression.java
@@ -41,7 +41,7 @@ public abstract class Expression extends AbstractNode {
}
@Override // More specific return type.
- public abstract Expression accept(Visitor visitor);
+ public abstract Expression accept(Shuttle shuttle);
/**
* Indicates that the node can be reduced to a simpler node. If this
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java
index fae932e..0651024 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java
@@ -3090,28 +3090,28 @@ public abstract class Expressions {
return toCollection(iterable).toArray(a);
}
- static <T extends Expression> Expression accept(T node, Visitor visitor) {
+ static <T extends Expression> Expression accept(T node, Shuttle shuttle) {
if (node == null) {
return null;
}
- return node.accept(visitor);
+ return node.accept(shuttle);
}
- static <T extends Statement> Statement accept(T node, Visitor visitor) {
+ static <T extends Statement> Statement accept(T node, Shuttle shuttle) {
if (node == null) {
return null;
}
- return node.accept(visitor);
+ return node.accept(shuttle);
}
static List<Statement> acceptStatements(List<Statement> statements,
- Visitor visitor) {
+ Shuttle shuttle) {
if (statements.isEmpty()) {
return statements; // short cut
}
final List<Statement> statements1 = new ArrayList<Statement>();
for (Statement statement : statements) {
- Statement newStatement = statement.accept(visitor);
+ Statement newStatement = statement.accept(shuttle);
if (newStatement instanceof GotoStatement) {
GotoStatement goto_ = (GotoStatement) newStatement;
if (goto_.kind == GotoExpressionKind.Sequence
@@ -3125,67 +3125,77 @@ public abstract class Expressions {
return statements1;
}
- static List<Node> acceptNodes(List<Node> nodes, Visitor visitor) {
+ static List<Node> acceptNodes(List<Node> nodes, Shuttle shuttle) {
if (nodes.isEmpty()) {
return nodes; // short cut
}
final List<Node> statements1 = new ArrayList<Node>();
for (Node node : nodes) {
- statements1.add(node.accept(visitor));
+ statements1.add(node.accept(shuttle));
}
return statements1;
}
static List<Expression> acceptParameterExpressions(
- List<ParameterExpression> parameterExpressions, Visitor visitor) {
+ List<ParameterExpression> parameterExpressions, Shuttle shuttle) {
if (parameterExpressions.isEmpty()) {
return Collections.emptyList(); // short cut
}
final List<Expression> parameterExpressions1 = new ArrayList<Expression>();
for (ParameterExpression parameterExpression : parameterExpressions) {
- parameterExpressions1.add(parameterExpression.accept(visitor));
+ parameterExpressions1.add(parameterExpression.accept(shuttle));
}
return parameterExpressions1;
}
static List<DeclarationStatement> acceptDeclarations(
- List<DeclarationStatement> declarations, Visitor visitor) {
+ List<DeclarationStatement> declarations, Shuttle shuttle) {
if (declarations == null || declarations.isEmpty()) {
return declarations; // short cut
}
final List<DeclarationStatement> declarations1 =
new ArrayList<DeclarationStatement>();
for (DeclarationStatement declaration : declarations) {
- declarations1.add(declaration.accept(visitor));
+ declarations1.add(declaration.accept(shuttle));
}
return declarations1;
}
static List<MemberDeclaration> acceptMemberDeclarations(
- List<MemberDeclaration> memberDeclarations, Visitor visitor) {
+ List<MemberDeclaration> memberDeclarations, Shuttle shuttle) {
if (memberDeclarations == null || memberDeclarations.isEmpty()) {
return memberDeclarations; // short cut
}
final List<MemberDeclaration> memberDeclarations1 =
new ArrayList<MemberDeclaration>();
for (MemberDeclaration memberDeclaration : memberDeclarations) {
- memberDeclarations1.add(memberDeclaration.accept(visitor));
+ memberDeclarations1.add(memberDeclaration.accept(shuttle));
}
return memberDeclarations1;
}
static List<Expression> acceptExpressions(List<Expression> expressions,
- Visitor visitor) {
+ Shuttle shuttle) {
if (expressions.isEmpty()) {
return expressions; // short cut
}
- final List<Expression> expressions1 = new ArrayList<Expression>();
+ final List<Expression> expressions1 = new ArrayList<>();
for (Expression expression : expressions) {
- expressions1.add(expression.accept(visitor));
+ expressions1.add(expression.accept(shuttle));
}
return expressions1;
}
+ static <R> R acceptNodes(List<? extends Node> nodes, Visitor<R> visitor) {
+ R r = null;
+ if (nodes != null) {
+ for (Node node : nodes) {
+ r = node.accept(visitor);
+ }
+ }
+ return r;
+ }
+
// ~ Classes and interfaces ------------------------------------------------
// Some interfaces we'd rather not implement yet. They don't seem relevant
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/FieldDeclaration.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/FieldDeclaration.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/FieldDeclaration.java
index 2a8db07..29ea7a7 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/FieldDeclaration.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/FieldDeclaration.java
@@ -35,12 +35,16 @@ public class FieldDeclaration extends MemberDeclaration {
this.initializer = initializer;
}
- @Override public MemberDeclaration accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
+ @Override public MemberDeclaration accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
// do not visit parameter - visit may not return a ParameterExpression
final Expression initializer =
- this.initializer == null ? null : this.initializer.accept(visitor);
- return visitor.visit(this, initializer);
+ this.initializer == null ? null : this.initializer.accept(shuttle);
+ return shuttle.visit(this, initializer);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
public void accept(ExpressionWriter writer) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ForStatement.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ForStatement.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ForStatement.java
index e8a9fba..d39809b 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ForStatement.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ForStatement.java
@@ -45,15 +45,19 @@ public class ForStatement extends Statement {
this.body = body; // may be empty block, not null
}
- @Override public ForStatement accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
+ @Override public ForStatement accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
List<DeclarationStatement> decls1 =
- Expressions.acceptDeclarations(declarations, visitor);
+ Expressions.acceptDeclarations(declarations, shuttle);
final Expression condition1 =
- condition == null ? null : condition.accept(visitor);
- final Expression post1 = post == null ? null : post.accept(visitor);
- final Statement body1 = body.accept(visitor);
- return visitor.visit(this, decls1, condition1, post1, body1);
+ condition == null ? null : condition.accept(shuttle);
+ final Expression post1 = post == null ? null : post.accept(shuttle);
+ final Statement body1 = body.accept(shuttle);
+ return shuttle.visit(this, decls1, condition1, post1, body1);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
@Override void accept0(ExpressionWriter writer) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/FunctionExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/FunctionExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/FunctionExpression.java
index 4bbc99b..14c67ca 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/FunctionExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/FunctionExpression.java
@@ -68,10 +68,14 @@ public final class FunctionExpression<F extends Function<?>>
this(type, null, body, parameters);
}
- @Override public Expression accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
- BlockStatement body = this.body.accept(visitor);
- return visitor.visit(this, body);
+ @Override public Expression accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
+ BlockStatement body = this.body.accept(shuttle);
+ return shuttle.visit(this, body);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
public Invokable compile() {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/GotoStatement.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/GotoStatement.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/GotoStatement.java
index 239f0e5..ff5582a 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/GotoStatement.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/GotoStatement.java
@@ -54,11 +54,15 @@ public class GotoStatement extends Statement {
}
}
- @Override public Statement accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
+ @Override public Statement accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
Expression expression1 =
- expression == null ? null : expression.accept(visitor);
- return visitor.visit(this, expression1);
+ expression == null ? null : expression.accept(shuttle);
+ return shuttle.visit(this, expression1);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
@Override void accept0(ExpressionWriter writer) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/IndexExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/IndexExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/IndexExpression.java
index 9c7eb61..10e8463 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/IndexExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/IndexExpression.java
@@ -35,14 +35,17 @@ public class IndexExpression extends Expression {
this.indexExpressions = indexExpressions;
}
- @Override public Expression accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
- Expression array = this.array.accept(visitor);
+ @Override public Expression accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
+ Expression array = this.array.accept(shuttle);
List<Expression> indexExpressions = Expressions.acceptExpressions(
- this.indexExpressions, visitor);
- return visitor.visit(this, array, indexExpressions);
+ this.indexExpressions, shuttle);
+ return shuttle.visit(this, array, indexExpressions);
}
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
+ }
@Override void accept(ExpressionWriter writer, int lprec, int rprec) {
array.accept(writer, lprec, nodeType.lprec);
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/InvocationExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/InvocationExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/InvocationExpression.java
index 666ab07..140c20d 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/InvocationExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/InvocationExpression.java
@@ -25,9 +25,14 @@ public class InvocationExpression extends Expression {
super(nodeType, type);
}
- @Override public Expression accept(Visitor visitor) {
+ @Override public Expression accept(Shuttle shuttle) {
+ return shuttle.visit(this);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visit(this);
}
+
}
// End InvocationExpression.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/LabelStatement.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/LabelStatement.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/LabelStatement.java
index 15b6f44..4d23339 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/LabelStatement.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/LabelStatement.java
@@ -33,7 +33,11 @@ public class LabelStatement extends Statement {
this.defaultValue = defaultValue;
}
- @Override public LabelStatement accept(Visitor visitor) {
+ @Override public LabelStatement accept(Shuttle shuttle) {
+ return shuttle.visit(this);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visit(this);
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/LambdaExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/LambdaExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/LambdaExpression.java
index d406e8f..6fbf61c 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/LambdaExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/LambdaExpression.java
@@ -25,9 +25,14 @@ public class LambdaExpression extends Expression {
super(nodeType, type);
}
- @Override public Expression accept(Visitor visitor) {
+ @Override public Expression accept(Shuttle shuttle) {
+ return shuttle.visit(this);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visit(this);
}
+
}
// End LambdaExpression.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ListInitExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ListInitExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ListInitExpression.java
index bf22c11..daf289a 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ListInitExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ListInitExpression.java
@@ -24,9 +24,14 @@ public class ListInitExpression extends Expression {
super(nodeType, type);
}
- @Override public Expression accept(Visitor visitor) {
+ @Override public Expression accept(Shuttle shuttle) {
+ return shuttle.visit(this);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visit(this);
}
+
}
// End ListInitExpression.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberDeclaration.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberDeclaration.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberDeclaration.java
index c3c10b4..b553f7a 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberDeclaration.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberDeclaration.java
@@ -20,7 +20,7 @@ package org.apache.calcite.linq4j.tree;
* Declaration of a member of a class.
*/
public abstract class MemberDeclaration implements Node {
- public abstract MemberDeclaration accept(Visitor visitor);
+ public abstract MemberDeclaration accept(Shuttle shuttle);
}
// End MemberDeclaration.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberExpression.java
index 9947c10..5e0c72d 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberExpression.java
@@ -40,12 +40,16 @@ public class MemberExpression extends Expression {
this.field = field;
}
- @Override public Expression accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
+ @Override public Expression accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
Expression expression1 = expression == null
? null
- : expression.accept(visitor);
- return visitor.visit(this, expression1);
+ : expression.accept(shuttle);
+ return shuttle.visit(this, expression1);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
public Object evaluate(Evaluator evaluator) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberInitExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberInitExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberInitExpression.java
index 79b4c46..5becd3c 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberInitExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MemberInitExpression.java
@@ -25,9 +25,14 @@ public class MemberInitExpression extends Expression {
super(ExpressionType.MemberInit, Void.TYPE);
}
- @Override public Expression accept(Visitor visitor) {
+ @Override public Expression accept(Shuttle shuttle) {
+ return shuttle.visit(this);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visit(this);
}
+
}
// End MemberInitExpression.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MethodCallExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MethodCallExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MethodCallExpression.java
index 7b63a00..bd3cd91 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MethodCallExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MethodCallExpression.java
@@ -53,13 +53,17 @@ public class MethodCallExpression extends Expression {
this(method.getGenericReturnType(), method, targetExpression, expressions);
}
- @Override public Expression accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
+ @Override public Expression accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
Expression targetExpression = Expressions.accept(this.targetExpression,
- visitor);
+ shuttle);
List<Expression> expressions = Expressions.acceptExpressions(
- this.expressions, visitor);
- return visitor.visit(this, targetExpression, expressions);
+ this.expressions, shuttle);
+ return shuttle.visit(this, targetExpression, expressions);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
@Override public Object evaluate(Evaluator evaluator) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MethodDeclaration.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MethodDeclaration.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MethodDeclaration.java
index b279434..800f387 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MethodDeclaration.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/MethodDeclaration.java
@@ -47,11 +47,15 @@ public class MethodDeclaration extends MemberDeclaration {
this.body = body;
}
- @Override public MemberDeclaration accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
+ @Override public MemberDeclaration accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
// do not visit parameters
- final BlockStatement body = this.body.accept(visitor);
- return visitor.visit(this, body);
+ final BlockStatement body = this.body.accept(shuttle);
+ return shuttle.visit(this, body);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
public void accept(ExpressionWriter writer) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/NewArrayExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/NewArrayExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/NewArrayExpression.java
index 13670ae..36e64c0 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/NewArrayExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/NewArrayExpression.java
@@ -41,14 +41,18 @@ public class NewArrayExpression extends Expression {
this.expressions = expressions;
}
- @Override public Expression accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
+ @Override public Expression accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
List<Expression> expressions =
this.expressions == null
? null
- : Expressions.acceptExpressions(this.expressions, visitor);
- Expression bound = Expressions.accept(this.bound, visitor);
- return visitor.visit(this, dimension, bound, expressions);
+ : Expressions.acceptExpressions(this.expressions, shuttle);
+ Expression bound = Expressions.accept(this.bound, shuttle);
+ return shuttle.visit(this, dimension, bound, expressions);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
@Override void accept(ExpressionWriter writer, int lprec, int rprec) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/NewExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/NewExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/NewExpression.java
index e4ca7ea..0c168a3 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/NewExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/NewExpression.java
@@ -43,13 +43,17 @@ public class NewExpression extends Expression {
this.memberDeclarations = memberDeclarations;
}
- @Override public Expression accept(Visitor visitor) {
- visitor = visitor.preVisit(this);
+ @Override public Expression accept(Shuttle shuttle) {
+ shuttle = shuttle.preVisit(this);
final List<Expression> arguments = Expressions.acceptExpressions(
- this.arguments, visitor);
+ this.arguments, shuttle);
final List<MemberDeclaration> memberDeclarations =
- Expressions.acceptMemberDeclarations(this.memberDeclarations, visitor);
- return visitor.visit(this, arguments, memberDeclarations);
+ Expressions.acceptMemberDeclarations(this.memberDeclarations, shuttle);
+ return shuttle.visit(this, arguments, memberDeclarations);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visit(this);
}
@Override void accept(ExpressionWriter writer, int lprec, int rprec) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Node.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Node.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Node.java
index 7c04f08..560f66a 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Node.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Node.java
@@ -20,7 +20,9 @@ package org.apache.calcite.linq4j.tree;
* <p>Parse tree node.</p>
*/
public interface Node {
- Node accept(Visitor visitor);
+ <R> R accept(Visitor<R> visitor);
+
+ Node accept(Shuttle shuttle);
void accept(ExpressionWriter expressionWriter);
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/OptimizeShuttle.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/OptimizeShuttle.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/OptimizeShuttle.java
new file mode 100644
index 0000000..fa90a4c
--- /dev/null
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/OptimizeShuttle.java
@@ -0,0 +1,422 @@
+/*
+ * 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.calcite.linq4j.tree;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.calcite.linq4j.tree.ExpressionType.Equal;
+import static org.apache.calcite.linq4j.tree.ExpressionType.NotEqual;
+
+/**
+ * Shuttle that optimizes expressions.
+ *
+ * <p>The optimizations are essential, not mere tweaks. Without
+ * optimization, expressions such as {@code false == null} will be left in,
+ * which are invalid to Janino (because it does not automatically box
+ * primitives).
+ */
+public class OptimizeShuttle extends Shuttle {
+ public static final ConstantExpression FALSE_EXPR =
+ Expressions.constant(false);
+ public static final ConstantExpression TRUE_EXPR =
+ Expressions.constant(true);
+ public static final MemberExpression BOXED_FALSE_EXPR =
+ Expressions.field(null, Boolean.class, "FALSE");
+ public static final MemberExpression BOXED_TRUE_EXPR =
+ Expressions.field(null, Boolean.class, "TRUE");
+ public static final Statement EMPTY_STATEMENT = Expressions.statement(null);
+
+ private static final Set<Method> KNOWN_NON_NULL_METHODS = new HashSet<>();
+
+ static {
+ for (Class aClass : new Class[]{Boolean.class, Byte.class, Short.class,
+ Integer.class, Long.class, String.class}) {
+ for (Method method : aClass.getMethods()) {
+ if ("valueOf".equals(method.getName())
+ && Modifier.isStatic(method.getModifiers())) {
+ KNOWN_NON_NULL_METHODS.add(method);
+ }
+ }
+ }
+ }
+
+ private static final
+ Map<ExpressionType, ExpressionType> NOT_BINARY_COMPLEMENT =
+ new EnumMap<>(ExpressionType.class);
+
+ static {
+ addComplement(ExpressionType.Equal, ExpressionType.NotEqual);
+ addComplement(ExpressionType.GreaterThanOrEqual, ExpressionType.LessThan);
+ addComplement(ExpressionType.GreaterThan, ExpressionType.LessThanOrEqual);
+ }
+
+ private static void addComplement(ExpressionType eq, ExpressionType ne) {
+ NOT_BINARY_COMPLEMENT.put(eq, ne);
+ NOT_BINARY_COMPLEMENT.put(ne, eq);
+ }
+
+ private static final Method BOOLEAN_VALUEOF_BOOL =
+ Types.lookupMethod(Boolean.class, "valueOf", boolean.class);
+
+ @Override public Expression visit(
+ TernaryExpression ternary,
+ Expression expression0,
+ Expression expression1,
+ Expression expression2) {
+ switch (ternary.getNodeType()) {
+ case Conditional:
+ Boolean always = always(expression0);
+ if (always != null) {
+ // true ? y : z === y
+ // false ? y : z === z
+ return always
+ ? expression1
+ : expression2;
+ }
+ if (expression1.equals(expression2)) {
+ // a ? b : b === b
+ return expression1;
+ }
+ // !a ? b : c == a ? c : b
+ if (expression0 instanceof UnaryExpression) {
+ UnaryExpression una = (UnaryExpression) expression0;
+ if (una.getNodeType() == ExpressionType.Not) {
+ return Expressions.makeTernary(ternary.getNodeType(),
+ una.expression, expression2, expression1);
+ }
+ }
+
+ // a ? true : b === a || b
+ // a ? false : b === !a && b
+ always = always(expression1);
+ if (always != null && isKnownNotNull(expression2)) {
+ return (always
+ ? Expressions.orElse(expression0, expression2)
+ : Expressions.andAlso(Expressions.not(expression0),
+ expression2)).accept(this);
+ }
+
+ // a ? b : true === !a || b
+ // a ? b : false === a && b
+ always = always(expression2);
+ if (always != null && isKnownNotNull(expression1)) {
+ return (always
+ ? Expressions.orElse(Expressions.not(expression0),
+ expression1)
+ : Expressions.andAlso(expression0, expression1)).accept(this);
+ }
+
+ if (expression0 instanceof BinaryExpression
+ && (expression0.getNodeType() == ExpressionType.Equal
+ || expression0.getNodeType() == ExpressionType.NotEqual)) {
+ BinaryExpression cmp = (BinaryExpression) expression0;
+ Expression expr = null;
+ if (eq(cmp.expression0, expression2)
+ && eq(cmp.expression1, expression1)) {
+ // a == b ? b : a === a (hint: if a==b, then a == b ? a : a)
+ // a != b ? b : a === b (hint: if a==b, then a != b ? b : b)
+ expr = expression0.getNodeType() == ExpressionType.Equal
+ ? expression2 : expression1;
+ }
+ if (eq(cmp.expression0, expression1)
+ && eq(cmp.expression1, expression2)) {
+ // a == b ? a : b === b (hint: if a==b, then a == b ? b : b)
+ // a != b ? a : b === a (hint: if a==b, then a == b ? a : a)
+ expr = expression0.getNodeType() == ExpressionType.Equal
+ ? expression2 : expression1;
+ }
+ if (expr != null) {
+ return expr;
+ }
+ }
+ }
+ return super.visit(ternary, expression0, expression1, expression2);
+ }
+
+ @Override public Expression visit(
+ BinaryExpression binary,
+ Expression expression0,
+ Expression expression1) {
+ //
+ Expression result;
+ switch (binary.getNodeType()) {
+ case AndAlso:
+ case OrElse:
+ if (eq(expression0, expression1)) {
+ return expression0;
+ }
+ }
+ switch (binary.getNodeType()) {
+ case Equal:
+ case NotEqual:
+ if (eq(expression0, expression1)) {
+ return binary.getNodeType() == Equal ? TRUE_EXPR : FALSE_EXPR;
+ } else if (expression0 instanceof ConstantExpression && expression1
+ instanceof ConstantExpression) {
+ ConstantExpression c0 = (ConstantExpression) expression0;
+ ConstantExpression c1 = (ConstantExpression) expression1;
+ if (c0.getType() == c1.getType()
+ || !(Primitive.is(c0.getType()) || Primitive.is(c1.getType()))) {
+ return binary.getNodeType() == NotEqual ? TRUE_EXPR : FALSE_EXPR;
+ }
+ }
+ if (expression0 instanceof TernaryExpression
+ && expression0.getNodeType() == ExpressionType.Conditional) {
+ TernaryExpression ternary = (TernaryExpression) expression0;
+ Expression expr = null;
+ if (eq(ternary.expression1, expression1)) {
+ // (a ? b : c) == b === a || c == b
+ expr = Expressions.orElse(ternary.expression0,
+ Expressions.equal(ternary.expression2, expression1));
+ } else if (eq(ternary.expression2, expression1)) {
+ // (a ? b : c) == c === !a || b == c
+ expr = Expressions.orElse(Expressions.not(ternary.expression0),
+ Expressions.equal(ternary.expression1, expression1));
+ }
+ if (expr != null) {
+ if (binary.getNodeType() == ExpressionType.NotEqual) {
+ expr = Expressions.not(expr);
+ }
+ return expr.accept(this);
+ }
+ }
+ // drop down
+ case AndAlso:
+ case OrElse:
+ result = visit0(binary, expression0, expression1);
+ if (result != null) {
+ return result;
+ }
+ result = visit0(binary, expression1, expression0);
+ if (result != null) {
+ return result;
+ }
+ }
+ return super.visit(binary, expression0, expression1);
+ }
+
+ private Expression visit0(
+ BinaryExpression binary,
+ Expression expression0,
+ Expression expression1) {
+ Boolean always;
+ switch (binary.getNodeType()) {
+ case AndAlso:
+ always = always(expression0);
+ if (always != null) {
+ return always
+ ? expression1
+ : FALSE_EXPR;
+ }
+ break;
+ case OrElse:
+ always = always(expression0);
+ if (always != null) {
+ // true or x --> true
+ // false or x --> x
+ return always
+ ? TRUE_EXPR
+ : expression1;
+ }
+ break;
+ case Equal:
+ if (isConstantNull(expression1)
+ && Primitive.is(expression0.getType())) {
+ return FALSE_EXPR;
+ }
+ // a == true -> a
+ // a == false -> !a
+ always = always(expression0);
+ if (always != null) {
+ return always ? expression1 : Expressions.not(expression1);
+ }
+ break;
+ case NotEqual:
+ if (isConstantNull(expression1)
+ && Primitive.is(expression0.getType())) {
+ return TRUE_EXPR;
+ }
+ // a != true -> !a
+ // a != false -> a
+ always = always(expression0);
+ if (always != null) {
+ return always ? Expressions.not(expression1) : expression1;
+ }
+ break;
+ }
+ return null;
+ }
+
+ @Override public Expression visit(UnaryExpression unaryExpression,
+ Expression expression) {
+ switch (unaryExpression.getNodeType()) {
+ case Convert:
+ if (expression.getType() == unaryExpression.getType()) {
+ return expression;
+ }
+ if (expression instanceof ConstantExpression) {
+ return Expressions.constant(((ConstantExpression) expression).value,
+ unaryExpression.getType());
+ }
+ break;
+ case Not:
+ Boolean always = always(expression);
+ if (always != null) {
+ return always ? FALSE_EXPR : TRUE_EXPR;
+ }
+ if (expression instanceof UnaryExpression) {
+ UnaryExpression arg = (UnaryExpression) expression;
+ if (arg.getNodeType() == ExpressionType.Not) {
+ return arg.expression;
+ }
+ }
+ if (expression instanceof BinaryExpression) {
+ BinaryExpression bin = (BinaryExpression) expression;
+ ExpressionType comp = NOT_BINARY_COMPLEMENT.get(bin.getNodeType());
+ if (comp != null) {
+ return Expressions.makeBinary(comp, bin.expression0, bin.expression1);
+ }
+ }
+ }
+ return super.visit(unaryExpression, expression);
+ }
+
+ @Override public Statement visit(ConditionalStatement conditionalStatement,
+ List<Node> list) {
+ // if (false) { <-- remove branch
+ // } if (true) { <-- stop here
+ // } else if (...)
+ // } else {...}
+ boolean optimal = true;
+ for (int i = 0; i < list.size() - 1 && optimal; i += 2) {
+ Boolean always = always((Expression) list.get(i));
+ if (always == null) {
+ continue;
+ }
+ if (i == 0 && always) {
+ // when the very first test is always true, just return its statement
+ return (Statement) list.get(1);
+ }
+ optimal = false;
+ }
+ if (optimal) {
+ // Nothing to optimize
+ return super.visit(conditionalStatement, list);
+ }
+ List<Node> newList = new ArrayList<>(list.size());
+ // Iterate over all the tests, except the latest "else"
+ for (int i = 0; i < list.size() - 1; i += 2) {
+ Expression test = (Expression) list.get(i);
+ Node stmt = list.get(i + 1);
+ Boolean always = always(test);
+ if (always == null) {
+ newList.add(test);
+ newList.add(stmt);
+ continue;
+ }
+ if (always) {
+ // No need to verify other tests
+ newList.add(stmt);
+ break;
+ }
+ }
+ // We might have dangling "else", however if we have just single item
+ // it means we have if (false) else if(false) else if (true) {...} code.
+ // Then we just return statement from true branch
+ if (list.size() == 1) {
+ return (Statement) list.get(0);
+ }
+ // Add "else" from original list
+ if (newList.size() % 2 == 0 && list.size() % 2 == 1) {
+ Node elseBlock = list.get(list.size() - 1);
+ if (newList.isEmpty()) {
+ return (Statement) elseBlock;
+ }
+ newList.add(elseBlock);
+ }
+ if (newList.isEmpty()) {
+ return EMPTY_STATEMENT;
+ }
+ return super.visit(conditionalStatement, newList);
+ }
+
+ @Override public Expression visit(MethodCallExpression methodCallExpression,
+ Expression targetExpression,
+ List<Expression> expressions) {
+ if (BOOLEAN_VALUEOF_BOOL.equals(methodCallExpression.method)) {
+ Boolean always = always(expressions.get(0));
+ if (always != null) {
+ return always ? TRUE_EXPR : FALSE_EXPR;
+ }
+ }
+ return super.visit(methodCallExpression, targetExpression, expressions);
+ }
+
+ private boolean isConstantNull(Expression expression) {
+ return expression instanceof ConstantExpression
+ && ((ConstantExpression) expression).value == null;
+ }
+
+ /**
+ * Returns whether an expression always evaluates to true or false.
+ * Assumes that expression has already been optimized.
+ */
+ private static Boolean always(Expression x) {
+ if (x.equals(FALSE_EXPR) || x.equals(BOXED_FALSE_EXPR)) {
+ return Boolean.FALSE;
+ }
+ if (x.equals(TRUE_EXPR) || x.equals(BOXED_TRUE_EXPR)) {
+ return Boolean.TRUE;
+ }
+ return null;
+ }
+
+ /**
+ * Returns whether an expression always returns a non-null result.
+ * For instance, primitive types cannot contain null values.
+ *
+ * @param expression expression to test
+ * @return true when the expression is known to be not-null
+ */
+ protected boolean isKnownNotNull(Expression expression) {
+ return Primitive.is(expression.getType())
+ || always(expression) != null
+ || (expression instanceof MethodCallExpression
+ && KNOWN_NON_NULL_METHODS.contains(
+ ((MethodCallExpression) expression).method));
+ }
+
+ /**
+ * Treats two expressions equal even if they represent different null types
+ */
+ private static boolean eq(Expression a, Expression b) {
+ return a.equals(b)
+ || (a instanceof ConstantExpression
+ && b instanceof ConstantExpression
+ && ((ConstantExpression) a).value
+ == ((ConstantExpression) b).value);
+ }
+}
+
+// End OptimizeShuttle.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/OptimizeVisitor.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/OptimizeVisitor.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/OptimizeVisitor.java
deleted file mode 100644
index f0bed0f..0000000
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/OptimizeVisitor.java
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * 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.calcite.linq4j.tree;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.apache.calcite.linq4j.tree.ExpressionType.Equal;
-import static org.apache.calcite.linq4j.tree.ExpressionType.NotEqual;
-
-/**
- * Visitor that optimizes expressions.
- *
- * <p>The optimizations are essential, not mere tweaks. Without
- * optimization, expressions such as {@code false == null} will be left in,
- * which are invalid to Janino (because it does not automatically box
- * primitives).</p>
- */
-public class OptimizeVisitor extends Visitor {
- public static final ConstantExpression FALSE_EXPR =
- Expressions.constant(false);
- public static final ConstantExpression TRUE_EXPR =
- Expressions.constant(true);
- public static final MemberExpression BOXED_FALSE_EXPR =
- Expressions.field(null, Boolean.class, "FALSE");
- public static final MemberExpression BOXED_TRUE_EXPR =
- Expressions.field(null, Boolean.class, "TRUE");
- public static final Statement EMPTY_STATEMENT = Expressions.statement(null);
-
- private static final Set<Method> KNOWN_NON_NULL_METHODS =
- new HashSet<Method>();
-
- static {
- for (Class aClass : new Class[]{Boolean.class, Byte.class, Short.class,
- Integer.class, Long.class, String.class}) {
- for (Method method : aClass.getMethods()) {
- if ("valueOf".equals(method.getName())
- && Modifier.isStatic(method.getModifiers())) {
- KNOWN_NON_NULL_METHODS.add(method);
- }
- }
- }
- }
-
- private static final Map<ExpressionType, ExpressionType>
- NOT_BINARY_COMPLEMENT =
- new EnumMap<ExpressionType, ExpressionType>(ExpressionType.class);
-
- static {
- addComplement(ExpressionType.Equal, ExpressionType.NotEqual);
- addComplement(ExpressionType.GreaterThanOrEqual, ExpressionType.LessThan);
- addComplement(ExpressionType.GreaterThan, ExpressionType.LessThanOrEqual);
- }
-
- private static void addComplement(ExpressionType eq, ExpressionType ne) {
- NOT_BINARY_COMPLEMENT.put(eq, ne);
- NOT_BINARY_COMPLEMENT.put(ne, eq);
- }
-
- private static final Method BOOLEAN_VALUEOF_BOOL =
- Types.lookupMethod(Boolean.class, "valueOf", boolean.class);
-
- @Override public Expression visit(
- TernaryExpression ternary,
- Expression expression0,
- Expression expression1,
- Expression expression2) {
- switch (ternary.getNodeType()) {
- case Conditional:
- Boolean always = always(expression0);
- if (always != null) {
- // true ? y : z === y
- // false ? y : z === z
- return always
- ? expression1
- : expression2;
- }
- if (expression1.equals(expression2)) {
- // a ? b : b === b
- return expression1;
- }
- // !a ? b : c == a ? c : b
- if (expression0 instanceof UnaryExpression) {
- UnaryExpression una = (UnaryExpression) expression0;
- if (una.getNodeType() == ExpressionType.Not) {
- return Expressions.makeTernary(ternary.getNodeType(),
- una.expression, expression2, expression1);
- }
- }
-
- // a ? true : b === a || b
- // a ? false : b === !a && b
- always = always(expression1);
- if (always != null && isKnownNotNull(expression2)) {
- return (always
- ? Expressions.orElse(expression0, expression2)
- : Expressions.andAlso(Expressions.not(expression0),
- expression2)).accept(this);
- }
-
- // a ? b : true === !a || b
- // a ? b : false === a && b
- always = always(expression2);
- if (always != null && isKnownNotNull(expression1)) {
- return (always
- ? Expressions.orElse(Expressions.not(expression0),
- expression1)
- : Expressions.andAlso(expression0, expression1)).accept(this);
- }
-
- if (expression0 instanceof BinaryExpression
- && (expression0.getNodeType() == ExpressionType.Equal
- || expression0.getNodeType() == ExpressionType.NotEqual)) {
- BinaryExpression cmp = (BinaryExpression) expression0;
- Expression expr = null;
- if (eq(cmp.expression0, expression2)
- && eq(cmp.expression1, expression1)) {
- // a == b ? b : a === a (hint: if a==b, then a == b ? a : a)
- // a != b ? b : a === b (hint: if a==b, then a != b ? b : b)
- expr = expression0.getNodeType() == ExpressionType.Equal
- ? expression2 : expression1;
- }
- if (eq(cmp.expression0, expression1)
- && eq(cmp.expression1, expression2)) {
- // a == b ? a : b === b (hint: if a==b, then a == b ? b : b)
- // a != b ? a : b === a (hint: if a==b, then a == b ? a : a)
- expr = expression0.getNodeType() == ExpressionType.Equal
- ? expression2 : expression1;
- }
- if (expr != null) {
- return expr;
- }
- }
- }
- return super.visit(ternary, expression0, expression1, expression2);
- }
-
- @Override public Expression visit(
- BinaryExpression binary,
- Expression expression0,
- Expression expression1) {
- //
- Expression result;
- switch (binary.getNodeType()) {
- case AndAlso:
- case OrElse:
- if (eq(expression0, expression1)) {
- return expression0;
- }
- }
- switch (binary.getNodeType()) {
- case Equal:
- case NotEqual:
- if (eq(expression0, expression1)) {
- return binary.getNodeType() == Equal ? TRUE_EXPR : FALSE_EXPR;
- } else if (expression0 instanceof ConstantExpression && expression1
- instanceof ConstantExpression) {
- ConstantExpression c0 = (ConstantExpression) expression0;
- ConstantExpression c1 = (ConstantExpression) expression1;
- if (c0.getType() == c1.getType()
- || !(Primitive.is(c0.getType()) || Primitive.is(c1.getType()))) {
- return binary.getNodeType() == NotEqual ? TRUE_EXPR : FALSE_EXPR;
- }
- }
- if (expression0 instanceof TernaryExpression
- && expression0.getNodeType() == ExpressionType.Conditional) {
- TernaryExpression ternary = (TernaryExpression) expression0;
- Expression expr = null;
- if (eq(ternary.expression1, expression1)) {
- // (a ? b : c) == b === a || c == b
- expr = Expressions.orElse(ternary.expression0,
- Expressions.equal(ternary.expression2, expression1));
- } else if (eq(ternary.expression2, expression1)) {
- // (a ? b : c) == c === !a || b == c
- expr = Expressions.orElse(Expressions.not(ternary.expression0),
- Expressions.equal(ternary.expression1, expression1));
- }
- if (expr != null) {
- if (binary.getNodeType() == ExpressionType.NotEqual) {
- expr = Expressions.not(expr);
- }
- return expr.accept(this);
- }
- }
- // drop down
- case AndAlso:
- case OrElse:
- result = visit0(binary, expression0, expression1);
- if (result != null) {
- return result;
- }
- result = visit0(binary, expression1, expression0);
- if (result != null) {
- return result;
- }
- }
- return super.visit(binary, expression0, expression1);
- }
-
- private Expression visit0(
- BinaryExpression binary,
- Expression expression0,
- Expression expression1) {
- Boolean always;
- switch (binary.getNodeType()) {
- case AndAlso:
- always = always(expression0);
- if (always != null) {
- return always
- ? expression1
- : FALSE_EXPR;
- }
- break;
- case OrElse:
- always = always(expression0);
- if (always != null) {
- // true or x --> true
- // false or x --> x
- return always
- ? TRUE_EXPR
- : expression1;
- }
- break;
- case Equal:
- if (isConstantNull(expression1)
- && Primitive.is(expression0.getType())) {
- return FALSE_EXPR;
- }
- // a == true -> a
- // a == false -> !a
- always = always(expression0);
- if (always != null) {
- return always ? expression1 : Expressions.not(expression1);
- }
- break;
- case NotEqual:
- if (isConstantNull(expression1)
- && Primitive.is(expression0.getType())) {
- return TRUE_EXPR;
- }
- // a != true -> !a
- // a != false -> a
- always = always(expression0);
- if (always != null) {
- return always ? Expressions.not(expression1) : expression1;
- }
- break;
- }
- return null;
- }
-
- @Override public Expression visit(UnaryExpression unaryExpression,
- Expression expression) {
- switch (unaryExpression.getNodeType()) {
- case Convert:
- if (expression.getType() == unaryExpression.getType()) {
- return expression;
- }
- if (expression instanceof ConstantExpression) {
- return Expressions.constant(((ConstantExpression) expression).value,
- unaryExpression.getType());
- }
- break;
- case Not:
- Boolean always = always(expression);
- if (always != null) {
- return always ? FALSE_EXPR : TRUE_EXPR;
- }
- if (expression instanceof UnaryExpression) {
- UnaryExpression arg = (UnaryExpression) expression;
- if (arg.getNodeType() == ExpressionType.Not) {
- return arg.expression;
- }
- }
- if (expression instanceof BinaryExpression) {
- BinaryExpression bin = (BinaryExpression) expression;
- ExpressionType comp = NOT_BINARY_COMPLEMENT.get(bin.getNodeType());
- if (comp != null) {
- return Expressions.makeBinary(comp, bin.expression0, bin.expression1);
- }
- }
- }
- return super.visit(unaryExpression, expression);
- }
-
- @Override public Statement visit(ConditionalStatement conditionalStatement,
- List<Node> list) {
- // if (false) { <-- remove branch
- // } if (true) { <-- stop here
- // } else if (...)
- // } else {...}
- boolean optimal = true;
- for (int i = 0; i < list.size() - 1 && optimal; i += 2) {
- Boolean always = always((Expression) list.get(i));
- if (always == null) {
- continue;
- }
- if (i == 0 && always) {
- // when the very first test is always true, just return its statement
- return (Statement) list.get(1);
- }
- optimal = false;
- }
- if (optimal) {
- // Nothing to optimize
- return super.visit(conditionalStatement, list);
- }
- List<Node> newList = new ArrayList<Node>(list.size());
- // Iterate over all the tests, except the latest "else"
- for (int i = 0; i < list.size() - 1; i += 2) {
- Expression test = (Expression) list.get(i);
- Node stmt = list.get(i + 1);
- Boolean always = always(test);
- if (always == null) {
- newList.add(test);
- newList.add(stmt);
- continue;
- }
- if (always) {
- // No need to verify other tests
- newList.add(stmt);
- break;
- }
- }
- // We might have dangling "else", however if we have just single item
- // it means we have if (false) else if(false) else if (true) {...} code.
- // Then we just return statement from true branch
- if (list.size() == 1) {
- return (Statement) list.get(0);
- }
- // Add "else" from original list
- if (newList.size() % 2 == 0 && list.size() % 2 == 1) {
- Node elseBlock = list.get(list.size() - 1);
- if (newList.isEmpty()) {
- return (Statement) elseBlock;
- }
- newList.add(elseBlock);
- }
- if (newList.isEmpty()) {
- return EMPTY_STATEMENT;
- }
- return super.visit(conditionalStatement, newList);
- }
-
- @Override public Expression visit(MethodCallExpression methodCallExpression,
- Expression targetExpression,
- List<Expression> expressions) {
- if (BOOLEAN_VALUEOF_BOOL.equals(methodCallExpression.method)) {
- Boolean always = always(expressions.get(0));
- if (always != null) {
- return always ? TRUE_EXPR : FALSE_EXPR;
- }
- }
- return super.visit(methodCallExpression, targetExpression, expressions);
- }
-
- private boolean isConstantNull(Expression expression) {
- return expression instanceof ConstantExpression
- && ((ConstantExpression) expression).value == null;
- }
-
- /**
- * Returns whether an expression always evaluates to true or false.
- * Assumes that expression has already been optimized.
- */
- private static Boolean always(Expression x) {
- if (x.equals(FALSE_EXPR) || x.equals(BOXED_FALSE_EXPR)) {
- return Boolean.FALSE;
- }
- if (x.equals(TRUE_EXPR) || x.equals(BOXED_TRUE_EXPR)) {
- return Boolean.TRUE;
- }
- return null;
- }
-
- /**
- * Returns whether an expression always returns a non-null result.
- * For instance, primitive types cannot contain null values.
- *
- * @param expression expression to test
- * @return true when the expression is known to be not-null
- */
- protected boolean isKnownNotNull(Expression expression) {
- return Primitive.is(expression.getType())
- || always(expression) != null
- || (expression instanceof MethodCallExpression
- && KNOWN_NON_NULL_METHODS.contains(
- ((MethodCallExpression) expression).method));
- }
-
- /**
- * Treats two expressions equal even if they represent different null types
- */
- private static boolean eq(Expression a, Expression b) {
- return a.equals(b)
- || (a instanceof ConstantExpression
- && b instanceof ConstantExpression
- && ((ConstantExpression) a).value
- == ((ConstantExpression) b).value);
- }
-}
-
-// End OptimizeVisitor.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/267e2f3e/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ParameterExpression.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ParameterExpression.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ParameterExpression.java
index a437a46..f883f50 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ParameterExpression.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ParameterExpression.java
@@ -43,7 +43,11 @@ public class ParameterExpression extends Expression {
this.name = name;
}
- @Override public Expression accept(Visitor visitor) {
+ @Override public Expression accept(Shuttle shuttle) {
+ return shuttle.visit(this);
+ }
+
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visit(this);
}