You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by li...@apache.org on 2015/07/11 01:27:32 UTC
[46/50] [abbrv] incubator-kylin git commit: KYLIN-881 Upgrade to
Calcite 1.3.0
KYLIN-881 Upgrade to Calcite 1.3.0
Project: http://git-wip-us.apache.org/repos/asf/incubator-kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-kylin/commit/f2b92061
Tree: http://git-wip-us.apache.org/repos/asf/incubator-kylin/tree/f2b92061
Diff: http://git-wip-us.apache.org/repos/asf/incubator-kylin/diff/f2b92061
Branch: refs/heads/0.7
Commit: f2b92061444f48fa016c3bc6a4dfff9331e63b41
Parents: 88baae9
Author: Li, Yang <ya...@ebay.com>
Authored: Tue Jul 7 16:07:23 2015 +0800
Committer: Li, Yang <ya...@ebay.com>
Committed: Tue Jul 7 16:07:23 2015 +0800
----------------------------------------------------------------------
.../adapter/enumerable/EnumerableJoin.java | 26 +-
.../apache/calcite/runtime/SqlFunctions.java | 119 +++-
.../calcite/sql2rel/SqlToRelConverter.java | 660 ++++++++++---------
.../java/org/apache/kylin/jdbc/KylinClient.java | 2 +-
.../org/apache/kylin/jdbc/KylinJdbcFactory.java | 5 +-
.../java/org/apache/kylin/jdbc/KylinMeta.java | 38 +-
.../kylin/jdbc/KylinPreparedStatement.java | 50 +-
.../org/apache/kylin/jdbc/KylinResultSet.java | 9 +-
pom.xml | 2 +-
.../query/enumerator/LookupTableEnumerator.java | 2 +
.../kylin/query/optrule/OLAPFilterRule.java | 4 +-
.../kylin/query/optrule/OLAPLimitRule.java | 5 +-
.../kylin/query/optrule/OLAPProjectRule.java | 6 +-
.../kylin/query/relnode/OLAPFilterRel.java | 4 +-
.../kylin/query/relnode/OLAPProjectRel.java | 12 +-
.../kylin/query/relnode/OLAPTableScan.java | 6 +-
16 files changed, 584 insertions(+), 366 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/atopcalcite/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java
----------------------------------------------------------------------
diff --git a/atopcalcite/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java b/atopcalcite/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java
index 918b4bf..2b2ca8d 100644
--- a/atopcalcite/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java
+++ b/atopcalcite/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java
@@ -1,6 +1,6 @@
/*
* OVERRIDE POINT:
- * - constructor was private instead of public
+ * - constructor was private instead of protected
*/
/*
@@ -31,10 +31,10 @@ import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.InvalidRelException;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelNodes;
+import org.apache.calcite.rel.core.EquiJoin;
import org.apache.calcite.rel.core.JoinInfo;
import org.apache.calcite.rel.core.JoinRelType;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
-import org.apache.calcite.rel.rules.EquiJoin;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.ImmutableIntList;
@@ -47,7 +47,10 @@ import java.util.Set;
/** Implementation of {@link org.apache.calcite.rel.core.Join} in
* {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
public class EnumerableJoin extends EquiJoin implements EnumerableRel {
- public EnumerableJoin( // OVERRIDE POINT, the constructor was private
+ /** Creates an EnumerableJoin.
+ *
+ * <p>Use {@link #create} unless you know what you're doing. */
+ public EnumerableJoin(
RelOptCluster cluster,
RelTraitSet traits,
RelNode left,
@@ -70,6 +73,23 @@ public class EnumerableJoin extends EquiJoin implements EnumerableRel {
variablesStopped);
}
+ /** Creates an EnumerableJoin. */
+ public static EnumerableJoin create(
+ RelNode left,
+ RelNode right,
+ RexNode condition,
+ ImmutableIntList leftKeys,
+ ImmutableIntList rightKeys,
+ JoinRelType joinType,
+ Set<String> variablesStopped)
+ throws InvalidRelException {
+ final RelOptCluster cluster = left.getCluster();
+ final RelTraitSet traitSet =
+ cluster.traitSetOf(EnumerableConvention.INSTANCE);
+ return new EnumerableJoin(cluster, traitSet, left, right, condition,
+ leftKeys, rightKeys, joinType, variablesStopped);
+ }
+
@Override public EnumerableJoin copy(RelTraitSet traitSet, RexNode condition,
RelNode left, RelNode right, JoinRelType joinType,
boolean semiJoinDone) {
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/atopcalcite/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
----------------------------------------------------------------------
diff --git a/atopcalcite/src/main/java/org/apache/calcite/runtime/SqlFunctions.java b/atopcalcite/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
index 3b1a2e0..80b9fdd 100644
--- a/atopcalcite/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
+++ b/atopcalcite/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
@@ -549,7 +549,6 @@ public class SqlFunctions {
/** SQL <code>/</code> operator applied to BigDecimal values. */
public static BigDecimal divide(BigDecimal b0, BigDecimal b1) {
- // OVERRIDE POINT
return (b0 == null || b1 == null) ? null : b0.divide(b1, MathContext.DECIMAL64);
}
@@ -693,6 +692,124 @@ public class SqlFunctions {
return bigDecimals[1];
}
+ // FLOOR
+
+ public static double floor(double b0) {
+ return Math.floor(b0);
+ }
+
+ public static float floor(float b0) {
+ return (float) Math.floor(b0);
+ }
+
+ public static BigDecimal floor(BigDecimal b0) {
+ return b0.setScale(0, BigDecimal.ROUND_FLOOR);
+ }
+
+ /** SQL <code>FLOOR</code> operator applied to byte values. */
+ public static byte floor(byte b0, byte b1) {
+ return (byte) floor((int) b0, (int) b1);
+ }
+
+ /** SQL <code>FLOOR</code> operator applied to short values. */
+ public static short floor(short b0, short b1) {
+ return (short) floor((int) b0, (int) b1);
+ }
+
+ /** SQL <code>FLOOR</code> operator applied to int values. */
+ public static int floor(int b0, int b1) {
+ int r = b0 % b1;
+ if (r < 0) {
+ r += b1;
+ }
+ return b0 - r;
+ }
+
+ /** SQL <code>FLOOR</code> operator applied to long values. */
+ public static long floor(long b0, long b1) {
+ long r = b0 % b1;
+ if (r < 0) {
+ r += b1;
+ }
+ return b0 - r;
+ }
+
+ // temporary
+ public static BigDecimal floor(BigDecimal b0, int b1) {
+ return floor(b0, BigDecimal.valueOf(b1));
+ }
+
+ // temporary
+ public static int floor(int b0, BigDecimal b1) {
+ return floor(b0, b1.intValue());
+ }
+
+ public static BigDecimal floor(BigDecimal b0, BigDecimal b1) {
+ final BigDecimal[] bigDecimals = b0.divideAndRemainder(b1);
+ BigDecimal r = bigDecimals[1];
+ if (r.signum() < 0) {
+ r = r.add(b1);
+ }
+ return b0.subtract(r);
+ }
+
+ // CEIL
+
+ public static double ceil(double b0) {
+ return Math.ceil(b0);
+ }
+
+ public static float ceil(float b0) {
+ return (float) Math.ceil(b0);
+ }
+
+ public static BigDecimal ceil(BigDecimal b0) {
+ return b0.setScale(0, BigDecimal.ROUND_CEILING);
+ }
+
+ /** SQL <code>CEIL</code> operator applied to byte values. */
+ public static byte ceil(byte b0, byte b1) {
+ return floor((byte) (b0 + b1 - 1), b1);
+ }
+
+ /** SQL <code>CEIL</code> operator applied to short values. */
+ public static short ceil(short b0, short b1) {
+ return floor((short) (b0 + b1 - 1), b1);
+ }
+
+ /** SQL <code>CEIL</code> operator applied to int values. */
+ public static int ceil(int b0, int b1) {
+ int r = b0 % b1;
+ if (r > 0) {
+ r -= b1;
+ }
+ return b0 - r;
+ }
+
+ /** SQL <code>CEIL</code> operator applied to long values. */
+ public static long ceil(long b0, long b1) {
+ return floor(b0 + b1 - 1, b1);
+ }
+
+ // temporary
+ public static BigDecimal ceil(BigDecimal b0, int b1) {
+ return ceil(b0, BigDecimal.valueOf(b1));
+ }
+
+ // temporary
+ public static int ceil(int b0, BigDecimal b1) {
+ return ceil(b0, b1.intValue());
+ }
+
+ public static BigDecimal ceil(BigDecimal b0, BigDecimal b1) {
+ final BigDecimal[] bigDecimals = b0.divideAndRemainder(b1);
+ BigDecimal r = bigDecimals[1];
+ if (r.signum() > 0) {
+ r = r.subtract(b1);
+ }
+ return b0.subtract(r);
+ }
+
// ABS
/** SQL <code>ABS</code> operator applied to byte values. */
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
----------------------------------------------------------------------
diff --git a/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java b/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index 2508629..c643f94 100644
--- a/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -27,14 +27,13 @@ import org.apache.calcite.linq4j.Ord;
import org.apache.calcite.plan.Convention;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptPlanner;
-import org.apache.calcite.plan.RelOptQuery;
import org.apache.calcite.plan.RelOptSamplingParameters;
import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.prepare.Prepare;
import org.apache.calcite.prepare.RelOptTableImpl;
import org.apache.calcite.rel.RelCollation;
-import org.apache.calcite.rel.RelCollationImpl;
+import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelShuttle;
@@ -47,7 +46,6 @@ import org.apache.calcite.rel.core.JoinInfo;
import org.apache.calcite.rel.core.JoinRelType;
import org.apache.calcite.rel.core.Project;
import org.apache.calcite.rel.core.Sample;
-import org.apache.calcite.rel.core.Sort;
import org.apache.calcite.rel.core.Uncollect;
import org.apache.calcite.rel.logical.LogicalAggregate;
import org.apache.calcite.rel.logical.LogicalCorrelate;
@@ -55,12 +53,14 @@ import org.apache.calcite.rel.logical.LogicalIntersect;
import org.apache.calcite.rel.logical.LogicalJoin;
import org.apache.calcite.rel.logical.LogicalMinus;
import org.apache.calcite.rel.logical.LogicalProject;
+import org.apache.calcite.rel.logical.LogicalSort;
import org.apache.calcite.rel.logical.LogicalTableFunctionScan;
import org.apache.calcite.rel.logical.LogicalTableModify;
import org.apache.calcite.rel.logical.LogicalTableScan;
import org.apache.calcite.rel.logical.LogicalUnion;
import org.apache.calcite.rel.logical.LogicalValues;
import org.apache.calcite.rel.metadata.RelColumnMapping;
+import org.apache.calcite.rel.stream.LogicalDelta;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;
@@ -80,6 +80,8 @@ import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.rex.RexVisitorImpl;
import org.apache.calcite.rex.RexWindowBound;
import org.apache.calcite.schema.ModifiableTable;
+import org.apache.calcite.schema.ModifiableView;
+import org.apache.calcite.schema.Table;
import org.apache.calcite.schema.TranslatableTable;
import org.apache.calcite.sql.JoinConditionType;
import org.apache.calcite.sql.JoinType;
@@ -101,6 +103,7 @@ import org.apache.calcite.sql.SqlLiteral;
import org.apache.calcite.sql.SqlMerge;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlNumericLiteral;
import org.apache.calcite.sql.SqlOperator;
import org.apache.calcite.sql.SqlOperatorTable;
import org.apache.calcite.sql.SqlSampleSpec;
@@ -109,6 +112,7 @@ import org.apache.calcite.sql.SqlSelectKeyword;
import org.apache.calcite.sql.SqlSetOperator;
import org.apache.calcite.sql.SqlUpdate;
import org.apache.calcite.sql.SqlUtil;
+import org.apache.calcite.sql.SqlValuesOperator;
import org.apache.calcite.sql.SqlWindow;
import org.apache.calcite.sql.SqlWith;
import org.apache.calcite.sql.SqlWithItem;
@@ -146,9 +150,9 @@ import org.apache.calcite.util.Pair;
import org.apache.calcite.util.Util;
import org.apache.calcite.util.mapping.Mappings;
import org.apache.calcite.util.trace.CalciteTrace;
-import org.apache.calcite.sql.SqlNumericLiteral;
import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
@@ -189,12 +193,6 @@ public class SqlToRelConverter {
protected static final Logger SQL2REL_LOGGER =
CalciteTrace.getSqlToRelTracer();
- private static final Function<SubQuery, SqlNode> FN =
- new Function<SubQuery, SqlNode>() {
- public SqlNode apply(SubQuery input) {
- return input.node;
- }
- };
private static final BigDecimal TWO = BigDecimal.valueOf(2L);
//~ Instance fields --------------------------------------------------------
@@ -205,9 +203,8 @@ public class SqlToRelConverter {
protected final RelOptCluster cluster;
private DefaultValueFactory defaultValueFactory;
private SubqueryConverter subqueryConverter;
- protected final List<RelNode> leaves = new ArrayList<RelNode>();
- private final List<SqlDynamicParam> dynamicParamSqlNodes =
- new ArrayList<SqlDynamicParam>();
+ protected final List<RelNode> leaves = new ArrayList<>();
+ private final List<SqlDynamicParam> dynamicParamSqlNodes = new ArrayList<>();
private final SqlOperatorTable opTab;
private boolean shouldConvertTableAccess;
protected final RelDataTypeFactory typeFactory;
@@ -222,7 +219,7 @@ public class SqlToRelConverter {
* Fields used in name resolution for correlated subqueries.
*/
private final Map<String, DeferredLookup> mapCorrelToDeferred =
- new HashMap<String, DeferredLookup>();
+ new HashMap<>();
private int nextCorrel = 0;
private static final String CORREL_PREFIX = "$cor";
@@ -231,7 +228,7 @@ public class SqlToRelConverter {
* Stack of names of datasets requested by the <code>
* TABLE(SAMPLE(<datasetName>, <query>))</code> construct.
*/
- private final Stack<String> datasetStack = new Stack<String>();
+ private final Stack<String> datasetStack = new Stack<>();
/**
* Mapping of non-correlated subqueries that have been converted to their
@@ -239,7 +236,7 @@ public class SqlToRelConverter {
* already been evaluated.
*/
private final Map<SqlNode, RexNode> mapConvertedNonCorrSubqs =
- new HashMap<SqlNode, RexNode>();
+ new HashMap<>();
public final RelOptTable.ViewExpander viewExpander;
@@ -254,6 +251,7 @@ public class SqlToRelConverter {
* @param rexBuilder Rex builder
* @param convertletTable Expression converter
*/
+ @Deprecated // will be removed before 2.0
public SqlToRelConverter(
RelOptTable.ViewExpander viewExpander,
SqlValidator validator,
@@ -261,6 +259,17 @@ public class SqlToRelConverter {
RelOptPlanner planner,
RexBuilder rexBuilder,
SqlRexConvertletTable convertletTable) {
+ this(viewExpander, validator, catalogReader,
+ RelOptCluster.create(planner, rexBuilder), convertletTable);
+ }
+
+ /* Creates a converter. */
+ public SqlToRelConverter(
+ RelOptTable.ViewExpander viewExpander,
+ SqlValidator validator,
+ Prepare.CatalogReader catalogReader,
+ RelOptCluster cluster,
+ SqlRexConvertletTable convertletTable) {
this.viewExpander = viewExpander;
this.opTab =
(validator
@@ -270,10 +279,9 @@ public class SqlToRelConverter {
this.catalogReader = catalogReader;
this.defaultValueFactory = new NullDefaultValueFactory();
this.subqueryConverter = new NoOpSubqueryConverter();
- this.rexBuilder = rexBuilder;
+ this.rexBuilder = cluster.getRexBuilder();
this.typeFactory = rexBuilder.getTypeFactory();
- RelOptQuery query = new RelOptQuery(planner);
- this.cluster = query.createCluster(typeFactory, rexBuilder);
+ this.cluster = Preconditions.checkNotNull(cluster);
this.shouldConvertTableAccess = true;
this.exprConverter =
new SqlNodeToRexConverterImpl(convertletTable);
@@ -532,6 +540,9 @@ public class SqlToRelConverter {
}
RelNode result = convertQueryRecursive(query, top, null);
+ if (top && isStream(query)) {
+ result = new LogicalDelta(cluster, result.getTraitSet(), result);
+ }
checkConvertedType(query, result);
boolean dumpPlan = SQL2REL_LOGGER.isLoggable(Level.FINE);
@@ -547,6 +558,11 @@ public class SqlToRelConverter {
return result;
}
+ private static boolean isStream(SqlNode query) {
+ return query instanceof SqlSelect
+ && ((SqlSelect) query).isKeywordPresent(SqlSelectKeyword.STREAM);
+ }
+
protected boolean checkConvertedRowType(
SqlNode query,
RelDataType convertedRowType) {
@@ -554,11 +570,7 @@ public class SqlToRelConverter {
validatedRowType = uniquifyFields(validatedRowType);
return RelOptUtil.equal(
- "validated row type",
- validatedRowType,
- "converted row type",
- convertedRowType,
- false);
+ "validated row type", validatedRowType, "converted row type", convertedRowType, false);
}
protected RelDataType uniquifyFields(RelDataType rowType) {
@@ -600,9 +612,8 @@ public class SqlToRelConverter {
bb,
select.getWhere());
- List<SqlNode> orderExprList = new ArrayList<SqlNode>();
- List<RelFieldCollation> collationList =
- new ArrayList<RelFieldCollation>();
+ final List<SqlNode> orderExprList = new ArrayList<>();
+ final List<RelFieldCollation> collationList = new ArrayList<>();
gatherOrderExprs(
bb,
select,
@@ -610,7 +621,7 @@ public class SqlToRelConverter {
orderExprList,
collationList);
final RelCollation collation =
- cluster.traitSetOf().canonize(RelCollationImpl.of(collationList));
+ cluster.traitSet().canonize(RelCollations.of(collationList));
if (validator.isAggregate(select)) {
convertAgg(
@@ -656,7 +667,7 @@ public class SqlToRelConverter {
if (checkForDupExprs && (rel instanceof LogicalProject)) {
LogicalProject project = (LogicalProject) rel;
final List<RexNode> projectExprs = project.getProjects();
- List<Integer> origins = new ArrayList<Integer>();
+ final List<Integer> origins = new ArrayList<>();
int dupCount = 0;
for (int i = 0; i < projectExprs.size(); i++) {
int x = findExpr(projectExprs.get(i), projectExprs, i);
@@ -682,13 +693,8 @@ public class SqlToRelConverter {
}
}
rel =
- new LogicalProject(
- cluster,
- rel,
- Pair.left(newProjects),
- Pair.right(newProjects),
- LogicalProject.Flags.BOXED);
-
+ LogicalProject.create(rel, Pair.left(newProjects),
+ Pair.right(newProjects));
bb.root = rel;
distinctify(bb, false);
rel = bb.root;
@@ -707,13 +713,8 @@ public class SqlToRelConverter {
}
rel =
- new LogicalProject(
- cluster,
- rel,
- Pair.left(undoProjects),
- Pair.right(undoProjects),
- LogicalProject.Flags.BOXED);
-
+ LogicalProject.create(rel, Pair.left(undoProjects),
+ Pair.right(undoProjects));
bb.setRoot(
rel,
false);
@@ -772,11 +773,7 @@ public class SqlToRelConverter {
// Create a sorter using the previously constructed collations.
bb.setRoot(
- new Sort(
- cluster,
- cluster.traitSetOf(Convention.NONE, collation),
- bb.root,
- collation,
+ LogicalSort.create(bb.root, collation,
offset == null ? null : convertExpression(offset),
fetch == null ? null : convertExpression(fetch)),
false);
@@ -784,7 +781,7 @@ public class SqlToRelConverter {
// If extra expressions were added to the project list for sorting,
// add another project to remove them.
if (orderExprList.size() > 0) {
- List<RexNode> exprs = new ArrayList<RexNode>();
+ final List<RexNode> exprs = new ArrayList<>();
final RelDataType rowType = bb.root.getRowType();
final int fieldCount =
rowType.getFieldCount() - orderExprList.size();
@@ -794,12 +791,11 @@ public class SqlToRelConverter {
bb.setRoot(
new LogicalProject(
cluster,
- cluster.traitSetOf(RelCollationImpl.PRESERVE),
+ cluster.traitSetOf(RelCollations.PRESERVE),
bb.root,
exprs,
cluster.getTypeFactory().createStructType(
- rowType.getFieldList().subList(0, fieldCount)),
- Project.Flags.BOXED),
+ rowType.getFieldList().subList(0, fieldCount))),
false);
}
}
@@ -1045,16 +1041,17 @@ public class SqlToRelConverter {
final int keyCount = leftKeys.size();
final List<Integer> args = ImmutableIntList.range(0, keyCount);
LogicalAggregate aggregate =
- new LogicalAggregate(cluster, seek, false, ImmutableBitSet.of(),
- null,
+ LogicalAggregate.create(seek, false, ImmutableBitSet.of(), null,
ImmutableList.of(
- new AggregateCall(SqlStdOperatorTable.COUNT, false,
- ImmutableList.<Integer>of(), longType, null),
- new AggregateCall(SqlStdOperatorTable.COUNT, false,
- args, longType, null)));
+ AggregateCall.create(SqlStdOperatorTable.COUNT, false,
+ ImmutableList.<Integer>of(), -1, longType, null),
+ AggregateCall.create(SqlStdOperatorTable.COUNT, false,
+ args, -1, longType, null)));
LogicalJoin join =
- new LogicalJoin(cluster, bb.root, aggregate,
- rexBuilder.makeLiteral(true), JoinRelType.INNER,
+ LogicalJoin.create(bb.root,
+ aggregate,
+ rexBuilder.makeLiteral(true),
+ JoinRelType.INNER,
ImmutableSet.<String>of());
bb.setRoot(join, false);
}
@@ -1169,7 +1166,7 @@ public class SqlToRelConverter {
// on e.deptno = dt.deptno
final Join join = (Join) root;
final Project left = (Project) join.getLeft();
- final RelNode leftLeft = ((Join) left.getInput(0)).getLeft();
+ final RelNode leftLeft = ((Join) left.getInput()).getLeft();
final int leftLeftCount = leftLeft.getRowType().getFieldCount();
final RelDataType nullableBooleanType =
typeFactory.createTypeWithNullability(
@@ -1286,12 +1283,31 @@ public class SqlToRelConverter {
SqlNode selectExpr = selectList.get(0);
if (selectExpr instanceof SqlCall) {
SqlCall selectExprCall = (SqlCall) selectExpr;
- if (selectExprCall.getOperator()
- instanceof SqlAggFunction) {
+ if (Util.isSingleValue(selectExprCall)) {
+ return plan;
+ }
+ }
+
+ // If there is a limit with 0 or 1,
+ // it is ensured to produce a single value
+ if (select.getFetch() != null
+ && select.getFetch() instanceof SqlNumericLiteral) {
+ SqlNumericLiteral limitNum = (SqlNumericLiteral) select.getFetch();
+ if (((BigDecimal) limitNum.getValue()).intValue() < 2) {
return plan;
}
}
}
+ } else if (query instanceof SqlCall) {
+ // If the query is (values ...),
+ // it is necessary to look into the operands to determine
+ // whether SingleValueAgg is necessary
+ SqlCall exprCall = (SqlCall) query;
+ if (exprCall.getOperator()
+ instanceof SqlValuesOperator
+ && Util.isSingleValue(exprCall)) {
+ return plan;
+ }
}
// If not, project SingleValueAgg
@@ -1313,7 +1329,7 @@ public class SqlToRelConverter {
final List<RexNode> leftKeys,
SqlNodeList valuesList,
boolean isNotIn) {
- List<RexNode> comparisons = new ArrayList<RexNode>();
+ final List<RexNode> comparisons = new ArrayList<>();
for (SqlNode rightVals : valuesList) {
RexNode rexComparison;
if (leftKeys.size() == 1) {
@@ -1321,7 +1337,8 @@ public class SqlToRelConverter {
rexBuilder.makeCall(
SqlStdOperatorTable.EQUALS,
leftKeys.get(0),
- bb.convertExpression(rightVals));
+ rexBuilder.ensureType(leftKeys.get(0).getType(),
+ bb.convertExpression(rightVals), true));
} else {
assert rightVals instanceof SqlCall;
final SqlBasicCall call = (SqlBasicCall) rightVals;
@@ -1335,7 +1352,9 @@ public class SqlToRelConverter {
new Function<Pair<RexNode, SqlNode>, RexNode>() {
public RexNode apply(Pair<RexNode, SqlNode> pair) {
return rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
- pair.left, bb.convertExpression(pair.right));
+ pair.left,
+ rexBuilder.ensureType(pair.left.getType(),
+ bb.convertExpression(pair.right), true));
}
}),
false);
@@ -1368,8 +1387,8 @@ public class SqlToRelConverter {
* @return threshold, default 20
*/
protected int getInSubqueryThreshold() {
- // OVERRIDE POINT
- return Integer.MAX_VALUE; // was 20
+ /* OVERRIDE POINT */
+ return Integer.MAX_VALUE;
}
/**
@@ -1451,7 +1470,7 @@ public class SqlToRelConverter {
null);
}
- List<RelNode> unionInputs = new ArrayList<RelNode>();
+ final List<RelNode> unionInputs = new ArrayList<>();
for (SqlNode node : rows) {
SqlBasicCall call;
if (isRowConstructor(node)) {
@@ -1503,10 +1522,7 @@ public class SqlToRelConverter {
unionInputs.add(convertRowConstructor(bb, call));
}
LogicalValues values =
- new LogicalValues(
- cluster,
- rowType,
- tupleList.build());
+ LogicalValues.create(cluster, rowType, tupleList.build());
RelNode resultRel;
if (unionInputs.isEmpty()) {
resultRel = values;
@@ -1514,12 +1530,7 @@ public class SqlToRelConverter {
if (!values.getTuples().isEmpty()) {
unionInputs.add(values);
}
- LogicalUnion union =
- new LogicalUnion(
- cluster,
- unionInputs,
- true);
- resultRel = union;
+ resultRel = LogicalUnion.create(unionInputs, true);
}
leaves.add(resultRel);
return resultRel;
@@ -1710,8 +1721,7 @@ public class SqlToRelConverter {
public RexNode convertExpression(
SqlNode node,
Map<String, RexNode> nameToNodeMap) {
- final Map<String, RelDataType> nameToTypeMap =
- new HashMap<String, RelDataType>();
+ final Map<String, RelDataType> nameToTypeMap = new HashMap<>();
for (Map.Entry<String, RexNode> entry : nameToNodeMap.entrySet()) {
nameToTypeMap.put(entry.getKey(), entry.getValue().getType());
}
@@ -1878,7 +1888,7 @@ public class SqlToRelConverter {
if (shouldConvertTableAccess) {
tableRel = toRel(table);
} else {
- tableRel = new LogicalTableScan(cluster, table);
+ tableRel = LogicalTableScan.create(cluster, table);
}
bb.setRoot(tableRel, true);
if (usedDataset[0]) {
@@ -2020,7 +2030,7 @@ public class SqlToRelConverter {
Set<RelColumnMapping> columnMappings =
getColumnMappings(operator);
LogicalTableFunctionScan callRel =
- new LogicalTableFunctionScan(
+ LogicalTableFunctionScan.create(
cluster,
inputs,
rexCall,
@@ -2161,12 +2171,8 @@ public class SqlToRelConverter {
ImmutableSet.copyOf(Util.skip(correlNames)));
rightRel = rightRel.accept(dedup);
}
- LogicalCorrelate corr = new LogicalCorrelate(
- rightRel.getCluster(),
- leftRel,
- rightRel,
- new CorrelationId(correlNames.get(0)),
- requiredColumns.build(),
+ LogicalCorrelate corr = LogicalCorrelate.create(leftRel, rightRel,
+ new CorrelationId(correlNames.get(0)), requiredColumns.build(),
SemiJoinType.of(joinType));
if (!joinCond.isAlwaysTrue()) {
return RelOptUtil.createFilter(corr, joinCond);
@@ -2175,8 +2181,8 @@ public class SqlToRelConverter {
}
}
- final List<RexNode> extraLeftExprs = new ArrayList<RexNode>();
- final List<RexNode> extraRightExprs = new ArrayList<RexNode>();
+ final List<RexNode> extraLeftExprs = new ArrayList<>();
+ final List<RexNode> extraRightExprs = new ArrayList<>();
final int leftCount = leftRel.getRowType().getFieldCount();
final int rightCount = rightRel.getRowType().getFieldCount();
if (!containsGet(joinCond)) {
@@ -2200,8 +2206,7 @@ public class SqlToRelConverter {
new RexInputRef(index, field.getType()),
field.getName());
} else {
- return Pair.<RexNode, String>of(
- extraLeftExprs.get(index - leftCount), null);
+ return Pair.of(extraLeftExprs.get(index - leftCount), null);
}
}
},
@@ -2248,7 +2253,7 @@ public class SqlToRelConverter {
+ rightCount + extraRightExprs.size(),
0, 0, leftCount,
leftCount, leftCount + extraLeftExprs.size(), rightCount);
- return RelOptUtil.project(join, mapping);
+ return RelOptUtil.createProject(join, mapping);
}
return join;
}
@@ -2287,8 +2292,8 @@ public class SqlToRelConverter {
case AND:
case OR:
case EQUALS:
- RexCall call = (RexCall) node;
- List<RexNode> list = new ArrayList<RexNode>();
+ final RexCall call = (RexCall) node;
+ final List<RexNode> list = new ArrayList<>();
List<RexNode> operands = Lists.newArrayList(call.getOperands());
for (int i = 0; i < operands.size(); i++) {
RexNode operand = operands.get(i);
@@ -2439,8 +2444,8 @@ public class SqlToRelConverter {
bb.setRoot(ImmutableList.of(leftRel, rightRel));
return bb.convertExpression(condition);
case USING:
- SqlNodeList list = (SqlNodeList) condition;
- List<String> nameList = new ArrayList<String>();
+ final SqlNodeList list = (SqlNodeList) condition;
+ final List<String> nameList = new ArrayList<>();
for (SqlNode columnName : list) {
final SqlIdentifier id = (SqlIdentifier) columnName;
String name = id.getSimple();
@@ -2547,17 +2552,16 @@ public class SqlToRelConverter {
SqlNodeList groupList,
SqlNode having,
List<SqlNode> orderExprList) {
- SqlNodeList aggList = new SqlNodeList(SqlParserPos.ZERO);
-
- for (SqlNode selectNode : selectList) {
- if (validator.isAggregate(selectNode)) {
- aggList.add(selectNode);
- }
+ // Find aggregate functions in SELECT and HAVING clause
+ final AggregateFinder aggregateFinder = new AggregateFinder();
+ selectList.accept(aggregateFinder);
+ if (having != null) {
+ having.accept(aggregateFinder);
}
// first replace the subqueries inside the aggregates
// because they will provide input rows to the aggregates.
- replaceSubqueries(bb, aggList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
+ replaceSubqueries(bb, aggregateFinder.list, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
// If group-by clause is missing, pretend that it has zero elements.
if (groupList == null) {
@@ -2704,6 +2708,7 @@ public class SqlToRelConverter {
// (yet) appear in the validator type.
final SelectScope selectScope =
SqlValidatorUtil.getEnclosingSelectScope(bb.scope);
+ assert selectScope != null;
final SqlValidatorNamespace selectNamespace =
validator.getNamespace(selectScope.getNode());
final List<String> names =
@@ -2769,13 +2774,8 @@ public class SqlToRelConverter {
protected RelNode createAggregate(Blackboard bb, boolean indicator,
ImmutableBitSet groupSet, ImmutableList<ImmutableBitSet> groupSets,
List<AggregateCall> aggCalls) {
- return new LogicalAggregate(
- cluster,
- bb.root,
- indicator,
- groupSet,
- groupSets,
- aggCalls);
+ return LogicalAggregate.create(
+ bb.root, indicator, groupSet, groupSets, aggCalls);
}
public RexDynamicParam convertDynamicParam(
@@ -2917,8 +2917,8 @@ public class SqlToRelConverter {
* @return Whether to trim unused fields
*/
public boolean isTrimUnusedFields() {
- // OVERRIDE POINT
- return false; // was `trimUnusedFields`
+ /* OVERRIDE POINT */
+ return false;
}
/**
@@ -2974,18 +2974,12 @@ public class SqlToRelConverter {
}
switch (call.getKind()) {
case UNION:
- return new LogicalUnion(
- cluster,
- ImmutableList.of(left, right),
- all);
+ return LogicalUnion.create(ImmutableList.of(left, right), all);
case INTERSECT:
// TODO: all
if (!all) {
- return new LogicalIntersect(
- cluster,
- ImmutableList.of(left, right),
- all);
+ return LogicalIntersect.create(ImmutableList.of(left, right), all);
} else {
throw Util.newInternal(
"set operator INTERSECT ALL not suported");
@@ -2994,10 +2988,7 @@ public class SqlToRelConverter {
case EXCEPT:
// TODO: all
if (!all) {
- return new LogicalMinus(
- cluster,
- ImmutableList.of(left, right),
- all);
+ return LogicalMinus.create(ImmutableList.of(left, right), all);
} else {
throw Util.newInternal(
"set operator EXCEPT ALL not suported");
@@ -3016,31 +3007,86 @@ public class SqlToRelConverter {
assert targetRowType != null;
RelNode sourceRel =
convertQueryRecursive(
- call.getSource(),
- false,
- targetRowType);
+ call.getSource(), false, targetRowType);
RelNode massagedRel = convertColumnList(call, sourceRel);
+ return createModify(targetTable, massagedRel);
+ }
+
+ /** Creates a relational expression to modify a table or modifiable view. */
+ private RelNode createModify(RelOptTable targetTable, RelNode source) {
final ModifiableTable modifiableTable =
targetTable.unwrap(ModifiableTable.class);
if (modifiableTable != null) {
- return modifiableTable.toModificationRel(
- cluster,
- targetTable,
- catalogReader,
- massagedRel,
- LogicalTableModify.Operation.INSERT,
- null,
+ return modifiableTable.toModificationRel(cluster, targetTable,
+ catalogReader, source, LogicalTableModify.Operation.INSERT, null,
false);
}
- return new LogicalTableModify(
- cluster,
- targetTable,
- catalogReader,
- massagedRel,
- LogicalTableModify.Operation.INSERT,
- null,
- false);
+ final ModifiableView modifiableView =
+ targetTable.unwrap(ModifiableView.class);
+ if (modifiableView != null) {
+ final Table delegateTable = modifiableView.getTable();
+ final RelDataType delegateRowType = delegateTable.getRowType(typeFactory);
+ final RelOptTable delegateRelOptTable =
+ RelOptTableImpl.create(null, delegateRowType, delegateTable,
+ modifiableView.getTablePath());
+ final RelNode newSource =
+ createSource(targetTable, source, modifiableView, delegateRowType);
+ return createModify(delegateRelOptTable, newSource);
+ }
+ return LogicalTableModify.create(targetTable, catalogReader, source,
+ LogicalTableModify.Operation.INSERT, null, false);
+ }
+
+ /** Wraps a relational expression in the projects and filters implied by
+ * a {@link ModifiableView}.
+ *
+ * <p>The input relational expression is suitable for inserting into the view,
+ * and the returned relational expression is suitable for inserting into its
+ * delegate table.
+ *
+ * <p>In principle, the delegate table of a view might be another modifiable
+ * view, and if so, the process can be repeated. */
+ private RelNode createSource(RelOptTable targetTable, RelNode source,
+ ModifiableView modifiableView, RelDataType delegateRowType) {
+ final ImmutableIntList mapping = modifiableView.getColumnMapping();
+ assert mapping.size() == targetTable.getRowType().getFieldCount();
+
+ // For columns represented in the mapping, the expression is just a field
+ // reference.
+ final Map<Integer, RexNode> projectMap = new HashMap<>();
+ final List<RexNode> filters = new ArrayList<>();
+ for (int i = 0; i < mapping.size(); i++) {
+ int target = mapping.get(i);
+ if (target >= 0) {
+ projectMap.put(target, RexInputRef.of(i, source.getRowType()));
+ }
+ }
+
+ // For columns that are not in the mapping, and have a constraint of the
+ // form "column = value", the expression is the literal "value".
+ //
+ // If a column has multiple constraints, the extra ones will become a
+ // filter.
+ final RexNode constraint =
+ modifiableView.getConstraint(rexBuilder, delegateRowType);
+ RelOptUtil.inferViewPredicates(projectMap, filters, constraint);
+ final List<Pair<RexNode, String>> projects = new ArrayList<>();
+ for (RelDataTypeField field : delegateRowType.getFieldList()) {
+ RexNode node = projectMap.get(field.getIndex());
+ if (node == null) {
+ node = rexBuilder.makeNullLiteral(field.getType().getSqlTypeName());
+ }
+ projects.add(
+ Pair.of(rexBuilder.ensureType(field.getType(), node, false),
+ field.getName()));
+ }
+
+ source = RelOptUtil.createProject(source, projects, true);
+ if (filters.size() > 0) {
+ source = RelOptUtil.createFilter(source, filters);
+ }
+ return source;
}
private RelOptTable.ToRelContext createToRelContext() {
@@ -3088,8 +3134,8 @@ public class SqlToRelConverter {
RelDataType sourceRowType = sourceRel.getRowType();
final RexNode sourceRef =
rexBuilder.makeRangeReference(sourceRowType, 0, false);
- final List<String> targetColumnNames = new ArrayList<String>();
- final List<RexNode> columnExprs = new ArrayList<RexNode>();
+ final List<String> targetColumnNames = new ArrayList<>();
+ final List<RexNode> columnExprs = new ArrayList<>();
collectInsertTargets(call, sourceRef, targetColumnNames, columnExprs);
final RelOptTable targetTable = getTargetTable(call);
@@ -3097,10 +3143,10 @@ public class SqlToRelConverter {
final List<RelDataTypeField> targetFields =
targetRowType.getFieldList();
final List<RexNode> sourceExps =
- new ArrayList<RexNode>(
+ new ArrayList<>(
Collections.<RexNode>nCopies(targetFields.size(), null));
final List<String> fieldNames =
- new ArrayList<String>(
+ new ArrayList<>(
Collections.<String>nCopies(targetFields.size(), null));
// Walk the name list and place the associated value in the
@@ -3181,21 +3227,15 @@ public class SqlToRelConverter {
private RelNode convertDelete(SqlDelete call) {
RelOptTable targetTable = getTargetTable(call);
RelNode sourceRel = convertSelect(call.getSourceSelect());
- return new LogicalTableModify(
- cluster,
- targetTable,
- catalogReader,
- sourceRel,
- LogicalTableModify.Operation.DELETE,
- null,
- false);
+ return LogicalTableModify.create(targetTable, catalogReader, sourceRel,
+ LogicalTableModify.Operation.DELETE, null, false);
}
private RelNode convertUpdate(SqlUpdate call) {
RelOptTable targetTable = getTargetTable(call);
// convert update column list from SqlIdentifier to String
- List<String> targetColumnNameList = new ArrayList<String>();
+ final List<String> targetColumnNameList = new ArrayList<>();
for (SqlNode node : call.getTargetColumnList()) {
SqlIdentifier id = (SqlIdentifier) node;
String name = id.getSimple();
@@ -3204,21 +3244,15 @@ public class SqlToRelConverter {
RelNode sourceRel = convertSelect(call.getSourceSelect());
- return new LogicalTableModify(
- cluster,
- targetTable,
- catalogReader,
- sourceRel,
- LogicalTableModify.Operation.UPDATE,
- targetColumnNameList,
- false);
+ return LogicalTableModify.create(targetTable, catalogReader, sourceRel,
+ LogicalTableModify.Operation.UPDATE, targetColumnNameList, false);
}
private RelNode convertMerge(SqlMerge call) {
RelOptTable targetTable = getTargetTable(call);
// convert update column list from SqlIdentifier to String
- List<String> targetColumnNameList = new ArrayList<String>();
+ final List<String> targetColumnNameList = new ArrayList<>();
SqlUpdate updateCall = call.getUpdateCall();
if (updateCall != null) {
for (SqlNode targetColumn : updateCall.getTargetColumnList()) {
@@ -3267,7 +3301,7 @@ public class SqlToRelConverter {
LogicalJoin join = (LogicalJoin) mergeSourceRel.getInput(0);
int nSourceFields = join.getLeft().getRowType().getFieldCount();
- List<RexNode> projects = new ArrayList<RexNode>();
+ final List<RexNode> projects = new ArrayList<>();
for (int level1Idx = 0; level1Idx < nLevel1Exprs; level1Idx++) {
if ((level2InsertExprs != null)
&& (level1InsertExprs.get(level1Idx) instanceof RexInputRef)) {
@@ -3287,14 +3321,8 @@ public class SqlToRelConverter {
RelNode massagedRel =
RelOptUtil.createProject(join, projects, null, true);
- return new LogicalTableModify(
- cluster,
- targetTable,
- catalogReader,
- massagedRel,
- LogicalTableModify.Operation.MERGE,
- targetColumnNameList,
- false);
+ return LogicalTableModify.create(targetTable, catalogReader, massagedRel,
+ LogicalTableModify.Operation.MERGE, targetColumnNameList, false);
}
/**
@@ -3399,8 +3427,8 @@ public class SqlToRelConverter {
Blackboard bb) {
// NOTE: Wael 2/04/05: this implementation is not the most efficient in
// terms of planning since it generates XOs that can be reduced.
- List<Object> joinList = new ArrayList<Object>();
- List<SqlNode> lastList = new ArrayList<SqlNode>();
+ final List<Object> joinList = new ArrayList<>();
+ List<SqlNode> lastList = new ArrayList<>();
for (int i = 0; i < operands.size(); i++) {
SqlNode operand = operands.get(i);
if (!(operand instanceof SqlCall)) {
@@ -3447,7 +3475,7 @@ public class SqlToRelConverter {
if (lastList.size() > 0) {
joinList.add(lastList);
}
- lastList = new ArrayList<SqlNode>();
+ lastList = new ArrayList<>();
Collect collect =
new Collect(
cluster,
@@ -3465,8 +3493,8 @@ public class SqlToRelConverter {
Object o = joinList.get(i);
if (o instanceof List) {
List<SqlNode> projectList = (List<SqlNode>) o;
- final List<RexNode> selectList = new ArrayList<RexNode>();
- final List<String> fieldNameList = new ArrayList<String>();
+ final List<RexNode> selectList = new ArrayList<>();
+ final List<String> fieldNameList = new ArrayList<>();
for (int j = 0; j < projectList.size(); j++) {
SqlNode operand = projectList.get(j);
selectList.add(bb.convertExpression(operand));
@@ -3524,12 +3552,7 @@ public class SqlToRelConverter {
RexNode condition,
JoinRelType joinType,
Set<String> variablesStopped) {
- return new LogicalJoin(
- cluster,
- left,
- right,
- condition,
- joinType,
+ return LogicalJoin.create(left, right, condition, joinType,
variablesStopped);
}
@@ -3542,14 +3565,13 @@ public class SqlToRelConverter {
replaceSubqueries(bb, selectList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
- List<String> fieldNames = new ArrayList<String>();
- List<RexNode> exprs = new ArrayList<RexNode>();
- Collection<String> aliases = new TreeSet<String>();
+ List<String> fieldNames = new ArrayList<>();
+ final List<RexNode> exprs = new ArrayList<>();
+ final Collection<String> aliases = new TreeSet<>();
// Project any system fields. (Must be done before regular select items,
// because offsets may be affected.)
- final List<SqlMonotonicity> columnMonotonicityList =
- new ArrayList<SqlMonotonicity>();
+ final List<SqlMonotonicity> columnMonotonicityList = new ArrayList<>();
extraSelectItems(
bb,
select,
@@ -3675,14 +3697,13 @@ public class SqlToRelConverter {
return;
}
- List<RelNode> unionRels = new ArrayList<RelNode>();
+ final List<RelNode> unionRels = new ArrayList<>();
for (SqlNode rowConstructor1 : values.getOperandList()) {
SqlCall rowConstructor = (SqlCall) rowConstructor1;
Blackboard tmpBb = createBlackboard(bb.scope, null);
replaceSubqueries(tmpBb, rowConstructor,
RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
- List<Pair<RexNode, String>> exps =
- new ArrayList<Pair<RexNode, String>>();
+ final List<Pair<RexNode, String>> exps = new ArrayList<>();
for (Ord<SqlNode> operand : Ord.zip(rowConstructor.getOperandList())) {
exps.add(
Pair.of(
@@ -3709,10 +3730,7 @@ public class SqlToRelConverter {
true);
} else {
bb.setRoot(
- new LogicalUnion(
- cluster,
- unionRels,
- true),
+ LogicalUnion.create(unionRels, true),
true);
}
@@ -3746,7 +3764,7 @@ public class SqlToRelConverter {
public RelNode root;
private List<RelNode> inputs;
private final Map<String, RexNode> mapCorrelateVariableToRexNode =
- new HashMap<String, RexNode>();
+ new HashMap<>();
List<RelNode> cursors;
@@ -3756,9 +3774,6 @@ public class SqlToRelConverter {
*/
private final Set<SubQuery> subqueryList = Sets.newLinkedHashSet();
- private final Map<SqlNode, SubQuery> subqueryMap =
- Util.asIndexMap(subqueryList, FN);
-
private boolean subqueryNeedsOuterJoin;
/**
@@ -3778,14 +3793,12 @@ public class SqlToRelConverter {
* "right" to the subquery.
*/
private final Map<RelNode, Map<Integer, Integer>>
- mapRootRelToFieldProjection =
- new HashMap<RelNode, Map<Integer, Integer>>();
+ mapRootRelToFieldProjection = new HashMap<>();
private final List<SqlMonotonicity> columnMonotonicities =
- new ArrayList<SqlMonotonicity>();
+ new ArrayList<>();
- private final List<RelDataTypeField> systemFieldList =
- new ArrayList<RelDataTypeField>();
+ private final List<RelDataTypeField> systemFieldList = new ArrayList<>();
/**
* Creates a Blackboard.
@@ -3802,7 +3815,7 @@ public class SqlToRelConverter {
Map<String, RexNode> nameToNodeMap) {
this.scope = scope;
this.nameToNodeMap = nameToNodeMap;
- this.cursors = new ArrayList<RelNode>();
+ this.cursors = new ArrayList<>();
subqueryNeedsOuterJoin = false;
}
@@ -4078,9 +4091,24 @@ public class SqlToRelConverter {
}
void registerSubquery(SqlNode node, RelOptUtil.Logic logic) {
+ for (SubQuery subQuery : subqueryList) {
+ if (node.equalsDeep(subQuery.node, false)) {
+ return;
+ }
+ }
subqueryList.add(new SubQuery(node, logic));
}
+ SubQuery getSubquery(SqlNode expr) {
+ for (SubQuery subQuery : subqueryList) {
+ if (expr.equalsDeep(subQuery.node, false)) {
+ return subQuery;
+ }
+ }
+
+ return null;
+ }
+
ImmutableList<RelNode> retrieveCursors() {
try {
return ImmutableList.copyOf(cursors);
@@ -4113,26 +4141,28 @@ public class SqlToRelConverter {
return rex;
}
- boolean needTruthTest;
-
// Sub-queries and OVER expressions are not like ordinary
// expressions.
final SqlKind kind = expr.getKind();
final SubQuery subQuery;
switch (kind) {
case CURSOR:
+ case IN:
+ subQuery = getSubquery(expr);
+
+ assert subQuery != null;
+ rex = subQuery.expr;
+ assert rex != null : "rex != null";
+ return rex;
+
case SELECT:
case EXISTS:
case SCALAR_QUERY:
- subQuery = subqueryMap.get(expr);
+ subQuery = getSubquery(expr);
assert subQuery != null;
rex = subQuery.expr;
assert rex != null : "rex != null";
- if (kind == SqlKind.CURSOR) {
- // cursor reference is pre-baked
- return rex;
- }
if (((kind == SqlKind.SCALAR_QUERY)
|| (kind == SqlKind.EXISTS))
&& isConvertedSubq(rex)) {
@@ -4141,11 +4171,8 @@ public class SqlToRelConverter {
return rex;
}
- RexNode fieldAccess;
- needTruthTest = false;
-
// The indicator column is the last field of the subquery.
- fieldAccess =
+ RexNode fieldAccess =
rexBuilder.makeFieldAccess(
rex,
rex.getType().getFieldCount() - 1);
@@ -4153,13 +4180,8 @@ public class SqlToRelConverter {
// The indicator column will be nullable if it comes from
// the null-generating side of the join. For EXISTS, add an
// "IS TRUE" check so that the result is "BOOLEAN NOT NULL".
- if (fieldAccess.getType().isNullable()) {
- if (kind == SqlKind.EXISTS) {
- needTruthTest = true;
- }
- }
-
- if (needTruthTest) {
+ if (fieldAccess.getType().isNullable()
+ && kind == SqlKind.EXISTS) {
fieldAccess =
rexBuilder.makeCall(
SqlStdOperatorTable.IS_NOT_NULL,
@@ -4167,12 +4189,6 @@ public class SqlToRelConverter {
}
return fieldAccess;
- case IN:
- subQuery = subqueryMap.get(expr);
- assert subQuery != null;
- assert subQuery.expr != null : "expr != null";
- return subQuery.expr;
-
case OVER:
return convertOver(this, expr);
@@ -4246,7 +4262,7 @@ public class SqlToRelConverter {
// implement SqlRexContext
public RexRangeRef getSubqueryExpr(SqlCall call) {
- final SubQuery subQuery = subqueryMap.get(call);
+ final SubQuery subQuery = getSubquery(call);
assert subQuery != null;
return (RexRangeRef) subQuery.expr;
}
@@ -4284,7 +4300,7 @@ public class SqlToRelConverter {
public RexNode visit(SqlCall call) {
if (agg != null) {
final SqlOperator op = call.getOperator();
- if (op.isAggregator()) {
+ if (op.isAggregator() || op.getKind() == SqlKind.FILTER) {
return agg.lookupAggregates(call);
}
}
@@ -4537,81 +4553,97 @@ public class SqlToRelConverter {
}
public Void visit(SqlCall call) {
- if (call.getOperator().isAggregator()) {
- assert bb.agg == this;
- List<Integer> args = new ArrayList<Integer>();
- List<RelDataType> argTypes =
- call.getOperator() instanceof SqlCountAggFunction
- ? new ArrayList<RelDataType>(call.getOperandList().size())
- : null;
- try {
- // switch out of agg mode
- bb.agg = null;
- for (SqlNode operand : call.getOperandList()) {
- RexNode convertedExpr;
-
- // special case for COUNT(*): delete the *
- if (operand instanceof SqlIdentifier) {
- SqlIdentifier id = (SqlIdentifier) operand;
- if (id.isStar() || isSimpleCount(call)) { // OVERRIDE POINT, was just `id.isStar()`
- assert call.operandCount() == 1;
- assert args.isEmpty();
- break;
- }
- }
- convertedExpr = bb.convertExpression(operand);
- assert convertedExpr != null;
- if (argTypes != null) {
- argTypes.add(convertedExpr.getType());
- }
- args.add(lookupOrCreateGroupExpr(convertedExpr));
- }
- } finally {
- // switch back into agg mode
- bb.agg = this;
- }
-
- final SqlAggFunction aggFunction =
- (SqlAggFunction) call.getOperator();
- RelDataType type = validator.deriveType(bb.scope, call);
- boolean distinct = false;
- SqlLiteral quantifier = call.getFunctionQuantifier();
- if ((null != quantifier)
- && (quantifier.getValue() == SqlSelectKeyword.DISTINCT)) {
- distinct = true;
- }
- final AggregateCall aggCall =
- new AggregateCall(
- aggFunction,
- distinct,
- args,
- type,
- nameMap.get(call.toString()));
- RexNode rex =
- rexBuilder.addAggCall(
- aggCall,
- groupExprs.size(),
- aggregatingSelectScope.indicator,
- aggCalls,
- aggCallMapping,
- argTypes);
- aggMapping.put(call, rex);
- } else if (call instanceof SqlSelect) {
+ switch (call.getKind()) {
+ case FILTER:
+ translateAgg((SqlCall) call.operand(0), call.operand(1), call);
+ return null;
+ case SELECT:
// rchen 2006-10-17:
// for now do not detect aggregates in subqueries.
return null;
- } else {
+ }
+ if (call.getOperator().isAggregator()) {
+ translateAgg(call, null, call);
+ return null;
+ }
+ for (SqlNode operand : call.getOperandList()) {
+ // Operands are occasionally null, e.g. switched CASE arg 0.
+ if (operand != null) {
+ operand.accept(this);
+ }
+ }
+ return null;
+ }
+
+ private void translateAgg(SqlCall call, SqlNode filter, SqlCall outerCall) {
+ assert bb.agg == this;
+ final List<Integer> args = new ArrayList<>();
+ int filterArg = -1;
+ final List<RelDataType> argTypes =
+ call.getOperator() instanceof SqlCountAggFunction
+ ? new ArrayList<RelDataType>(call.getOperandList().size())
+ : null;
+ try {
+ // switch out of agg mode
+ bb.agg = null;
for (SqlNode operand : call.getOperandList()) {
- // Operands are occasionally null, e.g. switched CASE arg 0.
- if (operand != null) {
- operand.accept(this);
+
+ // special case for COUNT(*): delete the *
+ if (operand instanceof SqlIdentifier) {
+ SqlIdentifier id = (SqlIdentifier) operand;
+ if (id.isStar() || isSimpleCount(call)) { /* OVERRIDE POINT */
+ assert call.operandCount() == 1;
+ assert args.isEmpty();
+ break;
+ }
+ }
+ RexNode convertedExpr = bb.convertExpression(operand);
+ assert convertedExpr != null;
+ if (argTypes != null) {
+ argTypes.add(convertedExpr.getType());
}
+ args.add(lookupOrCreateGroupExpr(convertedExpr));
}
+
+ if (filter != null) {
+ RexNode convertedExpr = bb.convertExpression(filter);
+ assert convertedExpr != null;
+ filterArg = lookupOrCreateGroupExpr(convertedExpr);
+ }
+ } finally {
+ // switch back into agg mode
+ bb.agg = this;
}
- return null;
+
+ final SqlAggFunction aggFunction =
+ (SqlAggFunction) call.getOperator();
+ RelDataType type = validator.deriveType(bb.scope, call);
+ boolean distinct = false;
+ SqlLiteral quantifier = call.getFunctionQuantifier();
+ if ((null != quantifier)
+ && (quantifier.getValue() == SqlSelectKeyword.DISTINCT)) {
+ distinct = true;
+ }
+ final AggregateCall aggCall =
+ AggregateCall.create(
+ aggFunction,
+ distinct,
+ args,
+ filterArg,
+ type,
+ nameMap.get(outerCall.toString()));
+ RexNode rex =
+ rexBuilder.addAggCall(
+ aggCall,
+ groupExprs.size(),
+ aggregatingSelectScope.indicator,
+ aggCalls,
+ aggCallMapping,
+ argTypes);
+ aggMapping.put(outerCall, rex);
}
- // OVERRIDE POINT
+ /* OVERRIDE POINT */
private boolean isSimpleCount(SqlCall call) {
if (call.getOperator().isName("COUNT") && call.operandCount() == 1) {
final SqlNode parm = call.operand(0);
@@ -4622,7 +4654,7 @@ public class SqlToRelConverter {
}
return false;
}
-
+
private int lookupOrCreateGroupExpr(RexNode expr) {
for (int i = 0; i < convertedInputExprs.size(); i++) {
RexNode convertedInputExpr = convertedInputExprs.get(i);
@@ -4741,7 +4773,7 @@ public class SqlToRelConverter {
*/
private static class LookupContext {
private final List<Pair<RelNode, Integer>> relOffsetList =
- new ArrayList<Pair<RelNode, Integer>>();
+ new ArrayList<>();
/**
* Creates a LookupContext with multiple input relational expressions.
@@ -4848,7 +4880,7 @@ public class SqlToRelConverter {
// Replace original expression with CAST of not one
// of the supported types
if (histogramType != type) {
- exprs = new ArrayList<RexNode>(exprs);
+ exprs = new ArrayList<>(exprs);
exprs.set(
0,
reinterpretCast
@@ -4973,6 +5005,28 @@ public class SqlToRelConverter {
this.logic = logic;
}
}
+
+ /**
+ * Visitor that collects all aggregate functions in a {@link SqlNode} tree.
+ */
+ private static class AggregateFinder extends SqlBasicVisitor<Void> {
+ final SqlNodeList list = new SqlNodeList(SqlParserPos.ZERO);
+
+ @Override public Void visit(SqlCall call) {
+ if (call.getOperator().isAggregator()) {
+ list.add(call);
+ return null;
+ }
+
+ // Don't traverse into sub-queries, even if they contain aggregate
+ // functions.
+ if (call instanceof SqlSelect) {
+ return null;
+ }
+
+ return call.getOperator().acceptCall(this, call);
+ }
+ }
}
// End SqlToRelConverter.java
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/jdbc/src/main/java/org/apache/kylin/jdbc/KylinClient.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinClient.java b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinClient.java
index 4b73ad6..3d0007e 100644
--- a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinClient.java
+++ b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinClient.java
@@ -259,7 +259,7 @@ public class KylinClient implements IRemoteClient {
for (int i = 0; i < result.length; i++) {
ColumnMetaData meta = metas.get(i);
- row[i] = wrapObject(result[i], meta.type.type);
+ row[i] = wrapObject(result[i], meta.type.id);
}
data.add(row);
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/jdbc/src/main/java/org/apache/kylin/jdbc/KylinJdbcFactory.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinJdbcFactory.java b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinJdbcFactory.java
index 030dbbb..f1a4939 100644
--- a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinJdbcFactory.java
+++ b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinJdbcFactory.java
@@ -30,6 +30,7 @@ import org.apache.calcite.avatica.AvaticaPreparedStatement;
import org.apache.calcite.avatica.AvaticaResultSet;
import org.apache.calcite.avatica.AvaticaResultSetMetaData;
import org.apache.calcite.avatica.AvaticaStatement;
+import org.apache.calcite.avatica.Meta.Frame;
import org.apache.calcite.avatica.Meta.Signature;
import org.apache.calcite.avatica.Meta.StatementHandle;
import org.apache.calcite.avatica.UnregisteredDriver;
@@ -92,9 +93,9 @@ public class KylinJdbcFactory implements AvaticaFactory {
}
@Override
- public AvaticaResultSet newResultSet(AvaticaStatement statement, Signature signature, TimeZone timeZone, Iterable<Object> iterable) throws SQLException {
+ public AvaticaResultSet newResultSet(AvaticaStatement statement, Signature signature, TimeZone timeZone, Frame firstFrame) throws SQLException {
AvaticaResultSetMetaData resultSetMetaData = new AvaticaResultSetMetaData(statement, null, signature);
- return new KylinResultSet(statement, signature, resultSetMetaData, timeZone, iterable);
+ return new KylinResultSet(statement, signature, resultSetMetaData, timeZone, firstFrame);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/jdbc/src/main/java/org/apache/kylin/jdbc/KylinMeta.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinMeta.java b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinMeta.java
index 821fba5..433262f 100644
--- a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinMeta.java
+++ b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinMeta.java
@@ -31,6 +31,8 @@ import org.apache.calcite.avatica.AvaticaUtils;
import org.apache.calcite.avatica.ColumnMetaData;
import org.apache.calcite.avatica.MetaImpl;
+import com.google.common.collect.ImmutableList;
+
/**
* Implementation of Avatica interface
*/
@@ -48,26 +50,34 @@ public class KylinMeta extends MetaImpl {
// insert/update/delete go this path, ignorable for Kylin
@Override
- public Signature prepare(StatementHandle h, String sql, int maxRowCount) {
- return connection().mockPreparedSignature(sql);
+ public StatementHandle prepare(ConnectionHandle ch, String sql, int maxRowCount) {
+ StatementHandle result = super.createStatement(ch);
+ result.signature = connection().mockPreparedSignature(sql);
+ return result;
}
// mimic from CalciteMetaImpl, real execution happens via callback in KylinResultSet.execute()
@Override
- public MetaResultSet prepareAndExecute(StatementHandle h, String sql, int maxRowCount, PrepareCallback callback) {
- final Signature signature;
+ public ExecuteResult prepareAndExecute(ConnectionHandle ch, String sql, int maxRowCount, PrepareCallback callback) {
+ final StatementHandle sh;
try {
synchronized (callback.getMonitor()) {
callback.clear();
- signature = prepare(h, sql, maxRowCount);
- callback.assign(signature, null);
+ sh = prepare(ch, sql, maxRowCount);
+ callback.assign(sh.signature, null, -1);
}
callback.execute();
- return new MetaResultSet(h.id, false, signature, null);
+ final MetaResultSet metaResultSet = MetaResultSet.create(ch.id, sh.id, false, sh.signature, null);
+ return new ExecuteResult(ImmutableList.of(metaResultSet));
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
+
+ @Override
+ public void closeStatement(StatementHandle h) {
+ // nothing to do
+ }
private KMetaProject getMetaProject() {
try {
@@ -164,9 +174,10 @@ public class KylinMeta extends MetaImpl {
CursorFactory cursorFactory = CursorFactory.record(clazz, fields, fieldNames);
Signature signature = new Signature(columns, "", null, Collections.<String, Object> emptyMap(), cursorFactory);
- StatementHandle statementHandle = this.createStatement(null);
+ StatementHandle sh = this.createStatement(connection().handle);
+ Frame frame = new Frame(0, true, iterable);
- return new MetaResultSet(statementHandle.id, true, signature, iterable);
+ return MetaResultSet.create(connection().id, sh.id, true, signature, frame);
}
// ============================================================================
@@ -177,7 +188,7 @@ public class KylinMeta extends MetaImpl {
public static List<? extends NamedWithChildren> searchByPatterns(NamedWithChildren parent, Pat... patterns) {
assert patterns != null && patterns.length > 0;
-
+
List<? extends NamedWithChildren> children = findChildren(parent, patterns[0]);
if (patterns.length == 1) {
return children;
@@ -268,12 +279,12 @@ public class KylinMeta extends MetaImpl {
public List<KMetaTable> getTables(String catalog, Pat schemaPattern, Pat tableNamePattern, List<String> typeList) {
return (List<KMetaTable>) searchByPatterns(this, Pat.of(catalog), schemaPattern, tableNamePattern);
}
-
+
@SuppressWarnings("unchecked")
public List<KMetaColumn> getColumns(String catalog, Pat schemaPattern, Pat tableNamePattern, Pat columnNamePattern) {
return (List<KMetaColumn>) searchByPatterns(this, Pat.of(catalog), schemaPattern, tableNamePattern, columnNamePattern);
}
-
+
@Override
public String getName() {
return projectName;
@@ -293,7 +304,7 @@ public class KylinMeta extends MetaImpl {
this.tableCat = tableCatalog;
this.schemas = schemas;
}
-
+
@Override
public String getName() {
return tableCat;
@@ -344,4 +355,5 @@ public class KylinMeta extends MetaImpl {
return Collections.<NamedWithChildren> emptyList();
}
}
+
}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPreparedStatement.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPreparedStatement.java b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPreparedStatement.java
index 21cb162..b14865b 100644
--- a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPreparedStatement.java
+++ b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPreparedStatement.java
@@ -6,7 +6,7 @@ import java.sql.NClob;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLXML;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.List;
import org.apache.calcite.avatica.AvaticaConnection;
@@ -19,82 +19,86 @@ public class KylinPreparedStatement extends AvaticaPreparedStatement {
protected KylinPreparedStatement(AvaticaConnection connection, StatementHandle h, Signature signature, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
super(connection, h, signature, resultSetType, resultSetConcurrency, resultSetHoldability);
}
-
- protected List<Object> getParameterValues() {
- return Arrays.asList(slots);
+
+ protected List<Object> getParameterValues2() {
+ List<Object> values = new ArrayList<>(slots.length);
+ for (int i = 0; i < slots.length; i++) {
+ values.add(slots[i].value);
+ }
+ return values;
}
-
+
// ============================================================================
public void setRowId(int parameterIndex, RowId x) throws SQLException {
- getParameter(parameterIndex).setRowId(slots, parameterIndex, x);
+ getSite(parameterIndex).setRowId(x);
}
public void setNString(int parameterIndex, String value) throws SQLException {
- getParameter(parameterIndex).setNString(slots, parameterIndex, value);
+ getSite(parameterIndex).setNString(value);
}
public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
- getParameter(parameterIndex).setNCharacterStream(slots, parameterIndex, value, length);
+ getSite(parameterIndex).setNCharacterStream(value, length);
}
public void setNClob(int parameterIndex, NClob value) throws SQLException {
- getParameter(parameterIndex).setNClob(slots, parameterIndex, value);
+ getSite(parameterIndex).setNClob(value);
}
public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
- getParameter(parameterIndex).setClob(slots, parameterIndex, reader, length);
+ getSite(parameterIndex).setClob(reader, length);
}
public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
- getParameter(parameterIndex).setBlob(slots, parameterIndex, inputStream, length);
+ getSite(parameterIndex).setBlob(inputStream, length);
}
public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
- getParameter(parameterIndex).setNClob(slots, parameterIndex, reader, length);
+ getSite(parameterIndex).setNClob(reader, length);
}
public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
- getParameter(parameterIndex).setSQLXML(slots, parameterIndex, xmlObject);
+ getSite(parameterIndex).setSQLXML(xmlObject);
}
public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
- getParameter(parameterIndex).setAsciiStream(slots, parameterIndex, x, length);
+ getSite(parameterIndex).setAsciiStream(x, length);
}
public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
- getParameter(parameterIndex).setBinaryStream(slots, parameterIndex, x, length);
+ getSite(parameterIndex).setBinaryStream(x, length);
}
public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
- getParameter(parameterIndex).setCharacterStream(slots, parameterIndex, reader, length);
+ getSite(parameterIndex).setCharacterStream(reader, length);
}
public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
- getParameter(parameterIndex).setAsciiStream(slots, parameterIndex, x);
+ getSite(parameterIndex).setAsciiStream(x);
}
public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
- getParameter(parameterIndex).setBinaryStream(slots, parameterIndex, x);
+ getSite(parameterIndex).setBinaryStream(x);
}
public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
- getParameter(parameterIndex).setCharacterStream(slots, parameterIndex, reader);
+ getSite(parameterIndex).setCharacterStream(reader);
}
public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
- getParameter(parameterIndex).setNCharacterStream(slots, parameterIndex, value);
+ getSite(parameterIndex).setNCharacterStream(value);
}
public void setClob(int parameterIndex, Reader reader) throws SQLException {
- getParameter(parameterIndex).setClob(slots, parameterIndex, reader);
+ getSite(parameterIndex).setClob(reader);
}
public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
- getParameter(parameterIndex).setBlob(slots, parameterIndex, inputStream);
+ getSite(parameterIndex).setBlob(inputStream);
}
public void setNClob(int parameterIndex, Reader reader) throws SQLException {
- getParameter(parameterIndex).setNClob(slots, parameterIndex, reader);
+ getSite(parameterIndex).setNClob(reader);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/jdbc/src/main/java/org/apache/kylin/jdbc/KylinResultSet.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinResultSet.java b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinResultSet.java
index 1229d10..3320415 100644
--- a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinResultSet.java
+++ b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinResultSet.java
@@ -27,21 +27,22 @@ import java.util.TimeZone;
import org.apache.calcite.avatica.AvaticaParameter;
import org.apache.calcite.avatica.AvaticaResultSet;
import org.apache.calcite.avatica.AvaticaStatement;
+import org.apache.calcite.avatica.Meta.Frame;
import org.apache.calcite.avatica.Meta.Signature;
import org.apache.calcite.avatica.MetaImpl;
import org.apache.kylin.jdbc.IRemoteClient.QueryResult;
public class KylinResultSet extends AvaticaResultSet {
- public KylinResultSet(AvaticaStatement statement, Signature signature, ResultSetMetaData resultSetMetaData, TimeZone timeZone, Iterable<Object> iterable) {
- super(statement, signature, resultSetMetaData, timeZone, iterable);
+ public KylinResultSet(AvaticaStatement statement, Signature signature, ResultSetMetaData resultSetMetaData, TimeZone timeZone, Frame firstFrame) {
+ super(statement, signature, resultSetMetaData, timeZone, firstFrame);
}
@Override
protected AvaticaResultSet execute() throws SQLException {
// skip execution if result is already there (case of meta data lookup)
- if (this.iterable != null) {
+ if (this.firstFrame != null) {
return super.execute();
}
@@ -49,7 +50,7 @@ public class KylinResultSet extends AvaticaResultSet {
List<AvaticaParameter> params = signature.parameters;
List<Object> paramValues = null;
if (params != null && params.size() > 0) {
- paramValues = ((KylinPreparedStatement) statement).getParameterValues();
+ paramValues = ((KylinPreparedStatement) statement).getParameterValues2();
}
IRemoteClient client = ((KylinConnection) statement.connection).getRemoteClient();
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index c0a4be2..ed598fb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -84,7 +84,7 @@
<spring.framework.version>3.1.2.RELEASE</spring.framework.version>
<!-- Calcite Version -->
- <calcite.version>1.0.0-incubating</calcite.version>
+ <calcite.version>1.3.0-incubating</calcite.version>
<!-- Metrics Codahale Version -->
<metrics.version>3.0.1</metrics.version>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/query/src/main/java/org/apache/kylin/query/enumerator/LookupTableEnumerator.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/enumerator/LookupTableEnumerator.java b/query/src/main/java/org/apache/kylin/query/enumerator/LookupTableEnumerator.java
index 733e8fe..c538080 100644
--- a/query/src/main/java/org/apache/kylin/query/enumerator/LookupTableEnumerator.java
+++ b/query/src/main/java/org/apache/kylin/query/enumerator/LookupTableEnumerator.java
@@ -46,7 +46,9 @@ public class LookupTableEnumerator implements Enumerator<Object[]> {
private final Object[] current;
private Iterator<String[]> iterator;
+ @SuppressWarnings("unused")
private final static Logger logger = LoggerFactory.getLogger(LookupTableEnumerator.class);
+
public LookupTableEnumerator(OLAPContext olapContext) {
//TODO: assuming LookupTableEnumerator is handled by a cube
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/query/src/main/java/org/apache/kylin/query/optrule/OLAPFilterRule.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/optrule/OLAPFilterRule.java b/query/src/main/java/org/apache/kylin/query/optrule/OLAPFilterRule.java
index 4c34f4e..3dcbbd7 100644
--- a/query/src/main/java/org/apache/kylin/query/optrule/OLAPFilterRule.java
+++ b/query/src/main/java/org/apache/kylin/query/optrule/OLAPFilterRule.java
@@ -39,7 +39,9 @@ public class OLAPFilterRule extends RelOptRule {
public void onMatch(RelOptRuleCall call) {
LogicalFilter filter = call.rel(0);
- RelTraitSet traitSet = filter.getTraitSet().replace(OLAPRel.CONVENTION);
+ RelTraitSet origTraitSet = filter.getTraitSet();
+ RelTraitSet traitSet = origTraitSet.replace(OLAPRel.CONVENTION).simplify();
+
OLAPFilterRel olapFilter = new OLAPFilterRel(filter.getCluster(), traitSet, convert(filter.getInput(), traitSet), filter.getCondition());
call.transformTo(olapFilter);
}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/query/src/main/java/org/apache/kylin/query/optrule/OLAPLimitRule.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/optrule/OLAPLimitRule.java b/query/src/main/java/org/apache/kylin/query/optrule/OLAPLimitRule.java
index cde934e..5eb1ff8 100644
--- a/query/src/main/java/org/apache/kylin/query/optrule/OLAPLimitRule.java
+++ b/query/src/main/java/org/apache/kylin/query/optrule/OLAPLimitRule.java
@@ -42,7 +42,10 @@ public class OLAPLimitRule extends RelOptRule {
if (sort.offset == null && sort.fetch == null) {
return;
}
- final RelTraitSet traitSet = sort.getTraitSet().replace(OLAPRel.CONVENTION);
+
+ RelTraitSet origTraitSet = sort.getTraitSet();
+ RelTraitSet traitSet = origTraitSet.replace(OLAPRel.CONVENTION).simplify();
+
RelNode input = sort.getInput();
if (!sort.getCollation().getFieldCollations().isEmpty()) {
// Create a sort with the same sort key, but no offset or fetch.
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/query/src/main/java/org/apache/kylin/query/optrule/OLAPProjectRule.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/optrule/OLAPProjectRule.java b/query/src/main/java/org/apache/kylin/query/optrule/OLAPProjectRule.java
index 4867162..bee992b 100644
--- a/query/src/main/java/org/apache/kylin/query/optrule/OLAPProjectRule.java
+++ b/query/src/main/java/org/apache/kylin/query/optrule/OLAPProjectRule.java
@@ -39,9 +39,11 @@ public class OLAPProjectRule extends RelOptRule {
public void onMatch(RelOptRuleCall call) {
LogicalProject project = call.rel(0);
- RelTraitSet traitSet = project.getTraitSet().replace(OLAPRel.CONVENTION);
+ RelTraitSet origTraitSet = project.getTraitSet();
+ RelTraitSet traitSet = origTraitSet.replace(OLAPRel.CONVENTION).simplify();
+
OLAPProjectRel olapProj = new OLAPProjectRel(project.getCluster(), traitSet, //
- convert(project.getInput(), traitSet), project.getProjects(), project.getRowType(), project.getFlags());
+ convert(project.getInput(), traitSet), project.getProjects(), project.getRowType());
call.transformTo(olapProj);
}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java
index 48c1075..cf985b7 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java
@@ -33,7 +33,6 @@ import org.apache.calcite.plan.RelOptCost;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelTrait;
import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.type.RelDataType;
@@ -62,7 +61,6 @@ import org.apache.kylin.metadata.filter.TupleFilter.FilterOperatorEnum;
import org.apache.kylin.metadata.model.TblColRef;
import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
/**
@@ -307,7 +305,7 @@ public class OLAPFilterRel extends Filter implements OLAPRel {
RexProgram program = programBuilder.getProgram();
return new EnumerableCalc(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), //
- sole(inputs), program, ImmutableList.<RelCollation> of());
+ sole(inputs), program);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java
index 8f80962..cda2cbc 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java
@@ -33,7 +33,6 @@ import org.apache.calcite.plan.RelOptCost;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelTrait;
import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Project;
import org.apache.calcite.rel.type.RelDataType;
@@ -53,7 +52,6 @@ import org.apache.kylin.metadata.model.TblColRef;
import org.apache.kylin.metadata.model.TblColRef.InnerDataTypeEnum;
import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
/**
*/
@@ -67,8 +65,8 @@ public class OLAPProjectRel extends Project implements OLAPRel {
private boolean afterJoin;
private boolean afterAggregate;
- public OLAPProjectRel(RelOptCluster cluster, RelTraitSet traitSet, RelNode child, List<RexNode> exps, RelDataType rowType, int flags) {
- super(cluster, traitSet, child, exps, rowType, flags);
+ public OLAPProjectRel(RelOptCluster cluster, RelTraitSet traitSet, RelNode child, List<RexNode> exps, RelDataType rowType) {
+ super(cluster, traitSet, child, exps, rowType);
Preconditions.checkArgument(getConvention() == OLAPRel.CONVENTION);
Preconditions.checkArgument(child.getConvention() == OLAPRel.CONVENTION);
this.rewriteProjects = exps;
@@ -94,7 +92,7 @@ public class OLAPProjectRel extends Project implements OLAPRel {
@Override
public Project copy(RelTraitSet traitSet, RelNode child, List<RexNode> exps, RelDataType rowType) {
- return new OLAPProjectRel(getCluster(), traitSet, child, exps, rowType, this.flags);
+ return new OLAPProjectRel(getCluster(), traitSet, child, exps, rowType);
}
@Override
@@ -214,13 +212,13 @@ public class OLAPProjectRel extends Project implements OLAPRel {
RelNode inputOfFilter = inputs.get(0).getInput(0);
RexProgram program = RexProgram.create(inputOfFilter.getRowType(), this.rewriteProjects, filter.getCondition(), this.rowType, getCluster().getRexBuilder());
return new EnumerableCalc(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), //
- inputOfFilter, program, ImmutableList.<RelCollation> of());
+ inputOfFilter, program);
} else {
// keep project for table scan
EnumerableRel input = sole(inputs);
RexProgram program = RexProgram.create(input.getRowType(), this.rewriteProjects, null, this.rowType, getCluster().getRexBuilder());
return new EnumerableCalc(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), //
- input, program, ImmutableList.<RelCollation> of());
+ input, program);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/f2b92061/query/src/main/java/org/apache/kylin/query/relnode/OLAPTableScan.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPTableScan.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPTableScan.java
index fc1fdf5..1f2edf9 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPTableScan.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPTableScan.java
@@ -41,6 +41,8 @@ import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.rules.AggregateExpandDistinctAggregatesRule;
+import org.apache.calcite.rel.rules.AggregateJoinTransposeRule;
+import org.apache.calcite.rel.rules.AggregateProjectMergeRule;
import org.apache.calcite.rel.rules.FilterJoinRule;
import org.apache.calcite.rel.rules.FilterProjectTransposeRule;
import org.apache.calcite.rel.rules.JoinCommuteRule;
@@ -130,7 +132,9 @@ public class OLAPTableScan extends TableScan implements OLAPRel, EnumerableRel {
planner.removeRule(JoinPushThroughJoinRule.LEFT);
planner.removeRule(JoinPushThroughJoinRule.RIGHT);
- // for columns in having clause will enable table scan filter rule cause kylin does not depend on MPP
+ // keep tree structure like filter -> aggregation -> project -> join/table scan, implementOLAP() rely on this tree pattern
+ planner.removeRule(AggregateJoinTransposeRule.INSTANCE);
+ planner.removeRule(AggregateProjectMergeRule.INSTANCE);
planner.removeRule(FilterProjectTransposeRule.INSTANCE);
// distinct count will be split into a separated query that is joined with the left query
planner.removeRule(AggregateExpandDistinctAggregatesRule.INSTANCE);