29 package org.apache.calcite.sql2rel;
31 import static org.apache.calcite.sql.SqlUtil.stripAs;
33 import com.google.common.base.Preconditions;
34 import com.google.common.collect.ImmutableList;
35 import com.google.common.collect.ImmutableList.Builder;
36 import com.google.common.collect.ImmutableMap;
37 import com.google.common.collect.ImmutableSet;
38 import com.google.common.collect.Iterables;
39 import com.google.common.collect.Sets;
42 import org.apache.calcite.avatica.util.Spaces;
43 import org.apache.calcite.linq4j.Ord;
44 import org.apache.calcite.plan.Convention;
45 import org.apache.calcite.plan.RelOptCluster;
46 import org.apache.calcite.plan.RelOptPlanner;
47 import org.apache.calcite.plan.RelOptSamplingParameters;
48 import org.apache.calcite.plan.RelOptTable;
49 import org.apache.calcite.plan.RelOptUtil;
50 import org.apache.calcite.plan.RelTraitSet;
51 import org.apache.calcite.plan.ViewExpanders;
52 import org.apache.calcite.prepare.Prepare;
53 import org.apache.calcite.prepare.RelOptTableImpl;
54 import org.apache.calcite.rel.RelCollation;
55 import org.apache.calcite.rel.RelCollationTraitDef;
56 import org.apache.calcite.rel.RelCollations;
57 import org.apache.calcite.rel.RelFieldCollation;
58 import org.apache.calcite.rel.RelNode;
59 import org.apache.calcite.rel.RelRoot;
60 import org.apache.calcite.rel.RelShuttleImpl;
61 import org.apache.calcite.rel.SingleRel;
62 import org.apache.calcite.rel.core.AggregateCall;
63 import org.apache.calcite.rel.core.Collect;
64 import org.apache.calcite.rel.core.CorrelationId;
65 import org.apache.calcite.rel.core.Filter;
66 import org.apache.calcite.rel.core.Join;
67 import org.apache.calcite.rel.core.JoinInfo;
68 import org.apache.calcite.rel.core.JoinRelType;
69 import org.apache.calcite.rel.core.Project;
70 import org.apache.calcite.rel.core.RelFactories;
71 import org.apache.calcite.rel.core.Sample;
72 import org.apache.calcite.rel.core.Sort;
73 import org.apache.calcite.rel.hint.HintStrategyTable;
74 import org.apache.calcite.rel.hint.Hintable;
75 import org.apache.calcite.rel.hint.RelHint;
76 import org.apache.calcite.rel.logical.LogicalAggregate;
77 import org.apache.calcite.rel.logical.LogicalCorrelate;
78 import org.apache.calcite.rel.logical.LogicalFilter;
79 import org.apache.calcite.rel.logical.LogicalIntersect;
80 import org.apache.calcite.rel.logical.LogicalJoin;
81 import org.apache.calcite.rel.logical.LogicalMatch;
82 import org.apache.calcite.rel.logical.LogicalMinus;
83 import org.apache.calcite.rel.logical.LogicalProject;
84 import org.apache.calcite.rel.logical.LogicalSort;
85 import org.apache.calcite.rel.logical.LogicalTableFunctionScan;
86 import org.apache.calcite.rel.logical.LogicalTableModify;
87 import org.apache.calcite.rel.logical.LogicalTableScan;
88 import org.apache.calcite.rel.logical.LogicalUnion;
89 import org.apache.calcite.rel.logical.LogicalValues;
90 import org.apache.calcite.rel.metadata.RelColumnMapping;
91 import org.apache.calcite.rel.metadata.RelMetadataQuery;
92 import org.apache.calcite.rel.stream.Delta;
93 import org.apache.calcite.rel.stream.LogicalDelta;
94 import org.apache.calcite.rel.type.RelDataType;
95 import org.apache.calcite.rel.type.RelDataTypeFactory;
96 import org.apache.calcite.rel.type.RelDataTypeField;
97 import org.apache.calcite.rex.RexBuilder;
98 import org.apache.calcite.rex.RexCall;
99 import org.apache.calcite.rex.RexCallBinding;
100 import org.apache.calcite.rex.RexCorrelVariable;
101 import org.apache.calcite.rex.RexDynamicParam;
102 import org.apache.calcite.rex.RexFieldAccess;
103 import org.apache.calcite.rex.RexFieldCollation;
104 import org.apache.calcite.rex.RexInputRef;
105 import org.apache.calcite.rex.RexLiteral;
106 import org.apache.calcite.rex.RexNode;
107 import org.apache.calcite.rex.RexPatternFieldRef;
108 import org.apache.calcite.rex.RexRangeRef;
109 import org.apache.calcite.rex.RexShuttle;
110 import org.apache.calcite.rex.RexSubQuery;
111 import org.apache.calcite.rex.RexUtil;
112 import org.apache.calcite.rex.RexWindowBound;
113 import org.apache.calcite.rex.RexWindowBounds;
114 import org.apache.calcite.schema.ColumnStrategy;
115 import org.apache.calcite.schema.ModifiableTable;
116 import org.apache.calcite.schema.ModifiableView;
117 import org.apache.calcite.schema.Table;
118 import org.apache.calcite.schema.TranslatableTable;
119 import org.apache.calcite.schema.Wrapper;
120 import org.apache.calcite.sql.JoinConditionType;
122 import org.apache.calcite.sql.SqlAggFunction;
123 import org.apache.calcite.sql.SqlBasicCall;
124 import org.apache.calcite.sql.SqlCall;
125 import org.apache.calcite.sql.SqlCallBinding;
126 import org.apache.calcite.sql.SqlDataTypeSpec;
127 import org.apache.calcite.sql.SqlDelete;
128 import org.apache.calcite.sql.SqlDynamicParam;
129 import org.apache.calcite.sql.SqlExplainFormat;
130 import org.apache.calcite.sql.SqlExplainLevel;
131 import org.apache.calcite.sql.SqlFunction;
132 import org.apache.calcite.sql.SqlIdentifier;
133 import org.apache.calcite.sql.SqlInsert;
134 import org.apache.calcite.sql.SqlIntervalQualifier;
135 import org.apache.calcite.sql.SqlJoin;
136 import org.apache.calcite.sql.SqlKind;
137 import org.apache.calcite.sql.SqlLiteral;
138 import org.apache.calcite.sql.SqlMatchRecognize;
139 import org.apache.calcite.sql.SqlMerge;
140 import org.apache.calcite.sql.SqlNode;
141 import org.apache.calcite.sql.SqlNodeList;
142 import org.apache.calcite.sql.SqlNumericLiteral;
144 import org.apache.calcite.sql.SqlOperatorTable;
145 import org.apache.calcite.sql.SqlOrderBy;
146 import org.apache.calcite.sql.SqlSampleSpec;
147 import org.apache.calcite.sql.SqlSelect;
148 import org.apache.calcite.sql.SqlSelectKeyword;
149 import org.apache.calcite.sql.SqlSetOperator;
150 import org.apache.calcite.sql.SqlSnapshot;
151 import org.apache.calcite.sql.SqlUnnestOperator;
152 import org.apache.calcite.sql.SqlUpdate;
153 import org.apache.calcite.sql.SqlUtil;
154 import org.apache.calcite.sql.SqlValuesOperator;
155 import org.apache.calcite.sql.SqlWindow;
156 import org.apache.calcite.sql.SqlWith;
157 import org.apache.calcite.sql.SqlWithItem;
158 import org.apache.calcite.sql.fun.SqlCase;
159 import org.apache.calcite.sql.fun.SqlCountAggFunction;
160 import org.apache.calcite.sql.fun.SqlInOperator;
161 import org.apache.calcite.sql.fun.SqlQuantifyOperator;
162 import org.apache.calcite.sql.fun.SqlRowOperator;
163 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
164 import org.apache.calcite.sql.parser.SqlParserPos;
165 import org.apache.calcite.sql.type.SqlReturnTypeInference;
166 import org.apache.calcite.sql.type.SqlTypeName;
167 import org.apache.calcite.sql.type.SqlTypeUtil;
168 import org.apache.calcite.sql.type.TableFunctionReturnTypeInference;
169 import org.apache.calcite.sql.util.SqlBasicVisitor;
170 import org.apache.calcite.sql.util.SqlVisitor;
171 import org.apache.calcite.sql.validate.AggregatingSelectScope;
172 import org.apache.calcite.sql.validate.CollectNamespace;
173 import org.apache.calcite.sql.validate.DelegatingScope;
174 import org.apache.calcite.sql.validate.ListScope;
175 import org.apache.calcite.sql.validate.MatchRecognizeScope;
176 import org.apache.calcite.sql.validate.ParameterScope;
177 import org.apache.calcite.sql.validate.SelectScope;
178 import org.apache.calcite.sql.validate.SqlMonotonicity;
179 import org.apache.calcite.sql.validate.SqlNameMatcher;
180 import org.apache.calcite.sql.validate.SqlQualified;
181 import org.apache.calcite.sql.validate.SqlUserDefinedTableFunction;
182 import org.apache.calcite.sql.validate.SqlUserDefinedTableMacro;
183 import org.apache.calcite.sql.validate.SqlValidator;
185 import org.apache.calcite.sql.validate.SqlValidatorNamespace;
186 import org.apache.calcite.sql.validate.SqlValidatorScope;
187 import org.apache.calcite.sql.validate.SqlValidatorTable;
188 import org.apache.calcite.sql.validate.SqlValidatorUtil;
189 import org.apache.calcite.tools.RelBuilder;
190 import org.apache.calcite.tools.RelBuilderFactory;
191 import org.apache.calcite.util.ImmutableBitSet;
192 import org.apache.calcite.util.ImmutableIntList;
193 import org.apache.calcite.util.Litmus;
194 import org.apache.calcite.util.NlsString;
195 import org.apache.calcite.util.NumberUtil;
196 import org.apache.calcite.util.Pair;
197 import org.apache.calcite.util.Util;
198 import org.apache.calcite.util.trace.CalciteTrace;
199 import org.slf4j.Logger;
202 import java.math.BigDecimal;
203 import java.util.AbstractList;
204 import java.util.ArrayDeque;
205 import java.util.ArrayList;
206 import java.util.BitSet;
207 import java.util.Collection;
208 import java.util.Collections;
209 import java.util.Deque;
210 import java.util.EnumSet;
211 import java.util.HashMap;
212 import java.util.HashSet;
213 import java.util.List;
214 import java.util.Map;
215 import java.util.Objects;
216 import java.util.Set;
217 import java.util.TreeSet;
218 import java.util.function.BiPredicate;
219 import java.util.function.Supplier;
220 import java.util.function.UnaryOperator;
221 import java.util.stream.Collectors;
223 import javax.annotation.Nonnull;
254 protected final Map<RelNode, Integer>
leaves =
new HashMap<>();
256 private final SqlOperatorTable
opTab;
261 public final SqlToRelConverter.Config
config;
299 RelOptPlanner planner,
301 SqlRexConvertletTable convertletTable) {
315 SqlRexConvertletTable convertletTable) {
329 SqlRexConvertletTable convertletTable,
332 this.opTab = (validator == null) ? SqlStdOperatorTable.instance()
333 : validator.getOperatorTable();
337 this.rexBuilder = cluster.getRexBuilder();
338 this.typeFactory = rexBuilder.getTypeFactory();
339 this.exprConverter =
new SqlNodeToRexConverterImpl(convertletTable);
340 this.explainParamCount = 0;
341 this.config =
new ConfigBuilder().withConfig(
config).build();
342 this.relBuilder = config.getRelBuilderFactory()
344 .transform(config.getRelBuilderConfigTransform());
345 this.hintStrategies = config.getHintStrategyTable();
347 cluster.setHintStrategies(this.hintStrategies);
348 this.cluster = Objects.requireNonNull(
cluster);
372 return dynamicParamSqlNodes.size();
382 SqlNode sqlNode = dynamicParamSqlNodes.get(index);
383 if (sqlNode == null) {
384 throw Util.needToImplement(
"dynamic param type inference");
386 return validator.getValidatedNodeType(sqlNode);
420 Map<SqlNode, RexNode> alreadyConvertedNonCorrSubqs) {
421 mapConvertedNonCorrSubqs.putAll(alreadyConvertedNonCorrSubqs);
440 assert config.isExplain();
445 if (query.isA(SqlKind.DML)) {
453 final List<RelDataTypeField> validatedFields =
454 validator.getValidatedNodeType(query).getFieldList();
455 final RelDataType validatedRowType =
456 validator.getTypeFactory().createStructType(Pair.right(validatedFields),
457 SqlValidatorUtil.uniquify(Pair.left(validatedFields),
460 final List<RelDataTypeField> convertedFields =
461 result.getRowType().getFieldList().subList(0, validatedFields.size());
462 final RelDataType convertedRowType =
463 validator.getTypeFactory().createStructType(convertedFields);
465 if (!RelOptUtil.equal(
"validated row type",
467 "converted row type",
470 throw new AssertionError(
"Conversion to relational algebra failed to "
471 +
"preserve datatypes:\n"
472 +
"validated type:\n" + validatedRowType.getFullTypeString()
473 +
"\nconverted type:\n" + convertedRowType.getFullTypeString() +
"\nrel:\n"
474 + RelOptUtil.toString(result));
479 RelStructuredTypeFlattener typeFlattener =
new RelStructuredTypeFlattener(
481 return typeFlattener.rewrite(rootRel);
493 if (!
config.isDecorrelationEnabled()) {
497 if (result != rootRel) {
529 final List<RelCollation> collations =
530 rootRel.getTraitSet().getTraits(RelCollationTraitDef.INSTANCE);
531 rootRel = trimmer.trim(rootRel);
532 if (!ordered && collations != null && !collations.isEmpty()
533 && !collations.equals(ImmutableList.of(RelCollations.EMPTY))) {
534 final RelTraitSet traitSet =
535 rootRel.getTraitSet().replace(RelCollationTraitDef.INSTANCE, collations);
536 rootRel = rootRel.copy(traitSet, rootRel.getInputs());
539 SQL2REL_LOGGER.debug(RelOptUtil.dumpPlan(
"Plan after trimming unused fields",
541 SqlExplainFormat.TEXT,
542 SqlExplainLevel.EXPPLAN_ATTRIBUTES));
569 SqlNode query,
final boolean needsValidation,
final boolean top) {
570 if (needsValidation) {
571 query = validator.validate(query);
577 result =
new LogicalDelta(
cluster, result.getTraitSet(),
result);
580 RelCollation collation = RelCollations.EMPTY;
581 if (!query.isA(SqlKind.DML)) {
589 SQL2REL_LOGGER.debug(RelOptUtil.dumpPlan(
"Plan after converting SqlNode to RelNode",
591 SqlExplainFormat.TEXT,
592 SqlExplainLevel.EXPPLAN_ATTRIBUTES));
595 final RelDataType validatedRowType = validator.getValidatedNodeType(query);
596 List<RelHint> hints =
new ArrayList<>();
597 if (query.getKind() == SqlKind.SELECT) {
598 final SqlSelect select = (SqlSelect) query;
599 if (select.hasHints()) {
604 result = RelOptUtil.propagateRelHints(
result,
false);
605 return RelRoot.of(
result, validatedRowType, query.getKind())
606 .withCollation(collation)
611 return query instanceof SqlSelect
612 && ((SqlSelect) query).isKeywordPresent(SqlSelectKeyword.STREAM);
616 switch (query.getKind()) {
618 return ((SqlSelect) query).getOrderList() != null
619 && ((SqlSelect) query).getOrderList().size() > 0;
621 return isOrdered(((SqlWith) query).body);
623 return ((SqlOrderBy) query).orderList.size() > 0;
630 if (r instanceof Sort) {
631 return ((Sort) r).collation;
633 if (r instanceof Project) {
636 if (r instanceof Delta) {
639 throw new AssertionError(r);
646 final SqlValidatorScope selectScope = validator.getWhereScope(select);
656 SqlValidatorScope scope, Map<String, RexNode> nameToNodeMap,
boolean top) {
657 return new Blackboard(scope, nameToNodeMap, top);
668 final List<SqlNode> orderExprList =
new ArrayList<>();
669 final List<RelFieldCollation> collationList =
new ArrayList<>();
670 gatherOrderExprs(bb, select, select.getOrderList(), orderExprList, collationList);
671 final RelCollation collation =
672 cluster.traitSet().canonize(RelCollations.of(collationList));
680 if (select.isDistinct()) {
685 select, bb, collation, orderExprList, select.getOffset(), select.getFetch());
687 if (select.hasHints()) {
688 final List<RelHint> hints = SqlUtil.getRelHint(
hintStrategies, select.getHints());
690 bb.setRoot(bb.root.accept(
new RelShuttleImpl() {
691 boolean attached =
false;
694 public RelNode visitChild(RelNode parent,
int i, RelNode child) {
695 if (parent instanceof Hintable && !attached) {
697 return ((Hintable) parent).attachHints(hints);
699 return super.visitChild(parent, i, child);
728 if (checkForDupExprs && (rel instanceof LogicalProject)) {
729 LogicalProject project = (LogicalProject) rel;
730 final List<RexNode> projectExprs = project.getProjects();
731 final List<Integer> origins =
new ArrayList<>();
733 for (
int i = 0; i < projectExprs.size(); i++) {
734 int x = projectExprs.indexOf(projectExprs.get(i));
735 if (x >= 0 && x < i) {
747 final Map<Integer, Integer> squished =
new HashMap<>();
748 final List<RelDataTypeField> fields = rel.getRowType().getFieldList();
749 final List<Pair<RexNode, String>> newProjects =
new ArrayList<>();
750 for (
int i = 0; i < fields.size(); i++) {
751 if (origins.get(i) == i) {
752 squished.put(i, newProjects.size());
753 newProjects.add(RexInputRef.of2(i, fields));
756 rel = LogicalProject.create(
757 rel, ImmutableList.of(), Pair.left(newProjects), Pair.right(newProjects));
764 final List<Pair<RexNode, String>> undoProjects =
new ArrayList<>();
765 for (
int i = 0; i < fields.size(); i++) {
766 final int origin = origins.get(i);
767 RelDataTypeField
field = fields.get(i);
768 undoProjects.add(Pair.of(
769 new RexInputRef(squished.get(origin), field.getType()), field.getName()));
772 rel = LogicalProject.create(
773 rel, ImmutableList.of(), Pair.left(undoProjects), Pair.right(undoProjects));
774 bb.setRoot(rel,
false);
781 final ImmutableBitSet groupSet =
782 ImmutableBitSet.range(rel.getRowType().getFieldCount());
783 rel =
createAggregate(bb, groupSet, ImmutableList.of(groupSet), ImmutableList.of());
785 bb.setRoot(rel,
false);
806 RelCollation collation,
807 List<SqlNode> orderExprList,
810 if (!bb.
top || select.getOrderList() == null
811 || select.getOrderList().getList().isEmpty()) {
812 assert !bb.top || collation.getFieldCollations().isEmpty();
814 || (offset instanceof SqlLiteral
815 && ((SqlLiteral) offset)
817 .equals(BigDecimal.ZERO)))
824 bb.setRoot(LogicalSort.create(
bb.root,
835 if (orderExprList.size() > 0 && !bb.top) {
836 final List<RexNode> exprs =
new ArrayList<>();
837 final RelDataType rowType = bb.root.getRowType();
838 final int fieldCount = rowType.getFieldCount() - orderExprList.size();
839 for (
int i = 0; i < fieldCount; i++) {
840 exprs.add(rexBuilder.makeInputRef(
bb.root, i));
842 bb.setRoot(LogicalProject.create(
bb.root,
845 rowType.getFieldNames().subList(0, fieldCount)),
857 SqlVisitor<Void> visitor =
new SqlBasicVisitor<Void>() {
858 public Void visit(SqlCall call) {
859 if (call.getOperator() instanceof SqlInOperator) {
860 throw new Util.FoundOne(call);
862 return super.visit(call);
865 node.accept(visitor);
867 }
catch (Util.FoundOne e) {
868 Util.swallow(e, null);
884 final SqlCall sqlCall = (SqlCall) sqlNode;
885 switch (sqlCall.getKind()) {
888 final List<SqlNode> operands =
new ArrayList<>();
889 for (SqlNode operand : sqlCall.getOperandList()) {
892 final SqlCall newCall =
893 sqlCall.getOperator().createCall(sqlCall.getParserPosition(), operands);
894 return reg(scope, newCall);
897 assert sqlCall.operand(0) instanceof SqlCall;
898 final SqlCall call = sqlCall.operand(0);
899 switch (sqlCall.operand(0).getKind()) {
901 final SqlCase caseNode = (SqlCase) call;
902 final SqlNodeList thenOperands =
new SqlNodeList(SqlParserPos.ZERO);
904 for (SqlNode thenOperand : caseNode.getThenOperands()) {
906 SqlStdOperatorTable.NOT.createCall(SqlParserPos.ZERO, thenOperand);
909 SqlNode elseOperand = caseNode.getElseOperand();
910 if (!SqlUtil.isNull(elseOperand)) {
913 SqlStdOperatorTable.NOT.createCall(SqlParserPos.ZERO, elseOperand);
918 SqlStdOperatorTable.CASE.createCall(SqlParserPos.ZERO,
919 caseNode.getValueOperand(),
920 caseNode.getWhenOperands(),
925 final List<SqlNode> orOperands =
new ArrayList<>();
926 for (SqlNode operand : call.getOperandList()) {
929 SqlStdOperatorTable.NOT.createCall(
930 SqlParserPos.ZERO, operand))));
933 SqlStdOperatorTable.OR.createCall(SqlParserPos.ZERO, orOperands));
936 final List<SqlNode> andOperands =
new ArrayList<>();
937 for (SqlNode operand : call.getOperandList()) {
940 SqlStdOperatorTable.NOT.createCall(
941 SqlParserPos.ZERO, operand))));
944 SqlStdOperatorTable.AND.createCall(SqlParserPos.ZERO, andOperands));
947 assert call.operandCount() == 1;
952 SqlStdOperatorTable.IN.createCall(
953 SqlParserPos.ZERO, call.getOperandList()));
957 SqlStdOperatorTable.NOT_IN.createCall(
958 SqlParserPos.ZERO, call.getOperandList()));
968 private static SqlNode
reg(SqlValidatorScope scope, SqlNode e) {
969 scope.getValidator().deriveType(scope, e);
985 final RexNode convertedWhere = bb.convertExpression(newWhere);
986 final RexNode convertedWhere2 =
987 RexUtil.removeNullabilityCast(
typeFactory, convertedWhere);
990 if (convertedWhere2.isAlwaysTrue()) {
994 final RelFactories.FilterFactory filterFactory = RelFactories.DEFAULT_FILTER_FACTORY;
995 final RelNode filter =
996 filterFactory.createFilter(
bb.root, convertedWhere2, ImmutableSet.of());
1000 assert p.r instanceof Filter;
1001 Filter
f = (Filter) p.r;
1002 r = LogicalFilter.create(f.getInput(), f.getCondition(), ImmutableSet.of(p.id));
1007 bb.setRoot(r,
false);
1011 final Blackboard bb,
final SqlNode expr, RelOptUtil.Logic logic) {
1019 final RexNode expr = subQuery.expr;
1025 final SqlBasicCall call;
1027 final SqlNode query;
1028 final RelOptUtil.Exists converted;
1030 boolean isExpand = config.getExpandPredicate().test(bb.
getTopNode(), subQuery.node);
1032 switch (subQuery.node.getKind()) {
1037 case MULTISET_QUERY_CONSTRUCTOR:
1038 case MULTISET_VALUE_CONSTRUCTOR:
1039 case ARRAY_QUERY_CONSTRUCTOR:
1041 subQuery.expr = bb.register(rel, JoinRelType.INNER);
1048 call = (SqlBasicCall) subQuery.node;
1049 query = call.operand(1);
1050 if (!isExpand && !(query instanceof SqlNodeList)) {
1053 final SqlNode leftKeyNode = call.operand(0);
1055 final List<RexNode> leftKeys;
1056 switch (leftKeyNode.getKind()) {
1058 leftKeys =
new ArrayList<>();
1059 for (SqlNode sqlExpr : ((SqlBasicCall) leftKeyNode).getOperandList()) {
1060 leftKeys.add(bb.convertExpression(sqlExpr));
1064 leftKeys = ImmutableList.of(bb.convertExpression(leftKeyNode));
1067 if (query instanceof SqlNodeList) {
1068 SqlNodeList valueList = (SqlNodeList) query;
1070 && valueList.size() <
config.getInSubQueryThreshold()) {
1073 bb, leftKeys, valueList, (SqlInOperator) call.getOperator());
1112 if (bb.
root == null) {
1115 final RelDataType targetRowType = SqlTypeUtil.promoteToRowType(
1116 typeFactory, validator.getValidatedNodeType(leftKeyNode), null);
1117 final boolean notIn = call.getOperator().kind == SqlKind.NOT_IN;
1119 query, RelOptUtil.SubQueryType.IN, subQuery.logic, notIn, targetRowType);
1120 if (converted.indicator) {
1124 final RelDataType longType = typeFactory.createSqlType(SqlTypeName.BIGINT);
1125 final RelNode seek = converted.r.getInput(0);
1126 final int keyCount = leftKeys.size();
1127 final List<Integer>
args = ImmutableIntList.range(0, keyCount);
1128 LogicalAggregate aggregate = LogicalAggregate.create(seek,
1130 ImmutableBitSet.of(),
1132 ImmutableList.of(AggregateCall.create(SqlStdOperatorTable.COUNT,
1138 RelCollations.EMPTY,
1141 AggregateCall.create(SqlStdOperatorTable.COUNT,
1147 RelCollations.EMPTY,
1156 bb.setRoot(
join,
false);
1158 final RexNode rex = bb.register(converted.r,
1159 converted.outerJoin ? JoinRelType.LEFT : JoinRelType.INNER,
1162 RelOptUtil.Logic logic = subQuery.logic;
1164 case TRUE_FALSE_UNKNOWN:
1165 case UNKNOWN_AS_TRUE:
1166 if (!converted.indicator) {
1167 logic = RelOptUtil.Logic.TRUE_FALSE;
1172 subQuery.expr = rexBuilder.makeCall(SqlStdOperatorTable.NOT, subQuery.expr);
1186 call = (SqlBasicCall) subQuery.node;
1187 query = call.operand(0);
1191 final SqlValidatorScope seekScope = (query instanceof SqlSelect)
1192 ?
validator.getSelectScope((SqlSelect) query)
1199 final RelMetadataQuery mq = seekRel.getCluster().getMetadataQuery();
1200 final Double minRowCount = mq.getMinRowCount(seekRel);
1201 if (minRowCount != null && minRowCount >= 1D) {
1202 subQuery.expr = rexBuilder.makeLiteral(
true);
1205 converted = RelOptUtil.createExistsPlan(seekRel,
1206 RelOptUtil.SubQueryType.EXISTS,
1210 assert !converted.indicator;
1214 subQuery.expr = bb.register(converted.r, JoinRelType.LEFT);
1223 call = (SqlBasicCall) subQuery.node;
1224 query = call.operand(0);
1226 query, RelOptUtil.SubQueryType.SCALAR, subQuery.logic,
true, null);
1227 assert !converted.indicator;
1232 subQuery.expr = bb.register(rel, JoinRelType.LEFT);
1241 RelOptUtil.SubQueryType.SCALAR,
1245 assert !converted.indicator;
1246 subQuery.expr = bb.register(converted.r, JoinRelType.LEFT);
1252 bb.cursors.add(converted.r);
1256 throw new AssertionError(
"unexpected kind of sub-query: " + subQuery.node);
1263 return rexBuilder.makeLiteral(
true);
1266 case UNKNOWN_AS_FALSE:
1267 assert rex instanceof RexRangeRef;
1268 final int fieldCount = rex.getType().getFieldCount();
1269 RexNode rexNode = rexBuilder.makeFieldAccess(rex, fieldCount - 1);
1270 rexNode = rexBuilder.makeCall(SqlStdOperatorTable.IS_TRUE, rexNode);
1280 final int k = (fieldCount - 1) / 2;
1281 for (
int i = 0; i < k; i++) {
1282 rexNode = rexBuilder.makeCall(SqlStdOperatorTable.AND,
1284 rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL,
1285 rexBuilder.makeFieldAccess(rex, i)));
1289 case TRUE_FALSE_UNKNOWN:
1290 case UNKNOWN_AS_TRUE:
1303 final Join
join = (Join) root;
1304 final Project left = (Project) join.getLeft();
1305 final RelNode leftLeft = ((Join) left.getInput()).getLeft();
1306 final int leftLeftCount = leftLeft.getRowType().getFieldCount();
1307 final RelDataType longType = typeFactory.createSqlType(SqlTypeName.BIGINT);
1308 final RexNode cRef = rexBuilder.makeInputRef(
root, leftLeftCount);
1309 final RexNode ckRef = rexBuilder.makeInputRef(
root, leftLeftCount + 1);
1310 final RexNode iRef =
1311 rexBuilder.makeInputRef(
root, root.getRowType().getFieldCount() - 1);
1313 final RexLiteral zero = rexBuilder.makeExactLiteral(BigDecimal.ZERO, longType);
1314 final RexLiteral trueLiteral = rexBuilder.makeLiteral(
true);
1315 final RexLiteral falseLiteral = rexBuilder.makeLiteral(
false);
1316 final RexNode unknownLiteral = rexBuilder.makeNullLiteral(trueLiteral.getType());
1318 final ImmutableList.Builder<RexNode>
args = ImmutableList.builder();
1319 args.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, cRef, zero),
1321 rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, iRef),
1323 final JoinInfo joinInfo = join.analyzeCondition();
1324 for (
int leftKey : joinInfo.leftKeys) {
1325 final RexNode kRef = rexBuilder.makeInputRef(
root, leftKey);
1327 rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, kRef), unknownLiteral);
1329 args.add(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, ckRef, cRef),
1333 return rexBuilder.makeCall(SqlStdOperatorTable.CASE, args.build());
1336 throw new AssertionError(logic);
1341 for (SqlNode node : valueList.getList()) {
1342 if (node instanceof SqlLiteral) {
1343 SqlLiteral lit = (SqlLiteral) node;
1344 if (lit.getValue() == null) {
1363 SubQuery subQuery,
Blackboard bb, RelNode converted,
boolean isExists) {
1364 SqlCall call = (SqlBasicCall) subQuery.node;
1370 RexNode constExpr = mapConvertedNonCorrSubqs.get(call);
1371 if (constExpr == null) {
1372 constExpr = subQueryConverter.convertSubQuery(
1373 call,
this, isExists, config.isExplain());
1375 if (constExpr != null) {
1376 subQuery.expr = constExpr;
1377 mapConvertedNonCorrSubqs.put(call, constExpr);
1394 if (query instanceof SqlSelect) {
1395 SqlSelect select = (SqlSelect) query;
1396 SqlNodeList selectList = select.getSelectList();
1397 SqlNodeList groupList = select.getGroup();
1399 if ((selectList.size() == 1) && ((groupList == null) || (groupList.size() == 0))) {
1400 SqlNode selectExpr = selectList.get(0);
1401 if (selectExpr instanceof SqlCall) {
1402 SqlCall selectExprCall = (SqlCall) selectExpr;
1403 if (Util.isSingleValue(selectExprCall)) {
1410 if (select.getFetch() != null && select.getFetch() instanceof SqlNumericLiteral) {
1411 SqlNumericLiteral limitNum = (SqlNumericLiteral) select.getFetch();
1412 if (((BigDecimal) limitNum.getValue()).intValue() < 2) {
1417 }
else if (query instanceof SqlCall) {
1421 SqlCall exprCall = (SqlCall) query;
1422 if (exprCall.getOperator() instanceof SqlValuesOperator
1423 && Util.isSingleValue(exprCall)) {
1429 return RelOptUtil.createSingleValueAggRel(
cluster, plan);
1441 final List<RexNode> leftKeys,
1442 SqlNodeList valuesList,
1444 final List<RexNode> comparisons =
new ArrayList<>();
1445 for (SqlNode rightVals : valuesList) {
1446 RexNode rexComparison;
1448 if (op instanceof SqlQuantifyOperator) {
1449 comparisonOp = RelOptUtil.op(
1450 ((SqlQuantifyOperator) op).comparisonKind, SqlStdOperatorTable.EQUALS);
1452 comparisonOp = SqlStdOperatorTable.EQUALS;
1454 if (leftKeys.size() == 1) {
1455 rexComparison = rexBuilder.makeCall(comparisonOp,
1458 leftKeys.get(0).getType(), bb.convertExpression(rightVals)));
1460 assert rightVals instanceof SqlCall;
1461 final SqlBasicCall call = (SqlBasicCall) rightVals;
1462 assert (call.getOperator() instanceof SqlRowOperator)
1463 && call.operandCount() == leftKeys.size();
1464 rexComparison = RexUtil.composeConjunction(
rexBuilder,
1465 Iterables.transform(Pair.zip(leftKeys, call.getOperandList()),
1467 -> rexBuilder.makeCall(comparisonOp,
1470 bb.convertExpression(pair.right)))));
1472 comparisons.add(rexComparison);
1477 return RexUtil.composeConjunction(
rexBuilder, comparisons,
true);
1479 return rexBuilder.makeCall(SqlStdOperatorTable.NOT,
1480 RexUtil.composeDisjunction(
rexBuilder, comparisons,
true));
1483 return RexUtil.composeDisjunction(
rexBuilder, comparisons,
true);
1485 throw new AssertionError();
1495 if (type.getSqlTypeName() == node.getType().getSqlTypeName()
1496 || (type.getSqlTypeName() == SqlTypeName.VARCHAR
1497 && node.getType().getSqlTypeName() == SqlTypeName.CHAR)) {
1500 return rexBuilder.ensureType(
type, node,
true);
1514 return config.getInSubQueryThreshold();
1535 RelOptUtil.SubQueryType subQueryType,
1536 RelOptUtil.Logic logic,
1538 RelDataType targetDataType) {
1539 final SqlValidatorScope seekScope = (seek instanceof SqlSelect)
1540 ?
validator.getSelectScope((SqlSelect) seek)
1545 return RelOptUtil.createExistsPlan(seekRel, subQueryType, logic, notIn,
relBuilder);
1549 Blackboard bb, SqlNode seek, RelDataType targetRowType) {
1556 if (seek instanceof SqlNodeList) {
1558 bb, seek, ((SqlNodeList) seek).getList(),
false, targetRowType);
1566 Collection<SqlNode>
rows,
1567 boolean allowLiteralsOnly,
1568 RelDataType targetRowType) {
1575 final ImmutableList.Builder<ImmutableList<RexLiteral>> tupleList =
1576 ImmutableList.builder();
1577 final RelDataType rowType;
1578 if (targetRowType != null) {
1579 rowType = targetRowType;
1581 rowType = SqlTypeUtil.promoteToRowType(
1582 typeFactory, validator.getValidatedNodeType(rowList), null);
1585 final List<RelNode> unionInputs =
new ArrayList<>();
1586 for (SqlNode node : rows) {
1589 call = (SqlBasicCall) node;
1590 ImmutableList.Builder<RexLiteral> tuple = ImmutableList.builder();
1591 for (Ord<SqlNode> operand : Ord.zip(call.operands)) {
1592 RexLiteral rexLiteral =
1594 if ((rexLiteral == null) && allowLiteralsOnly) {
1597 if ((rexLiteral == null) || !
config.isCreateValuesRel()) {
1602 tuple.add(rexLiteral);
1604 if (tuple != null) {
1605 tupleList.add(tuple.build());
1610 if ((rexLiteral != null) &&
config.isCreateValuesRel()) {
1611 tupleList.add(ImmutableList.of(rexLiteral));
1614 if ((rexLiteral == null) && allowLiteralsOnly) {
1620 call = (SqlBasicCall) SqlStdOperatorTable.ROW.createCall(SqlParserPos.ZERO, node);
1624 LogicalValues values = LogicalValues.create(
cluster, rowType, tupleList.build());
1626 if (unionInputs.isEmpty()) {
1629 if (!values.getTuples().isEmpty()) {
1630 unionInputs.add(values);
1632 resultRel = LogicalUnion.create(unionInputs,
true);
1634 leaves.put(resultRel, resultRel.getRowType().getFieldCount());
1639 SqlNode sqlNode,
Blackboard bb, RelDataType rowType,
int iField) {
1640 if (!(sqlNode instanceof SqlLiteral)) {
1643 RelDataTypeField
field = rowType.getFieldList().
get(iField);
1644 RelDataType
type = field.getType();
1645 if (type.isStruct()) {
1652 RexNode literalExpr = exprConverter.convertLiteral(bb, (SqlLiteral) sqlNode);
1654 if (!(literalExpr instanceof RexLiteral)) {
1655 assert literalExpr.isA(SqlKind.CAST);
1656 RexNode child = ((RexCall) literalExpr).getOperands().
get(0);
1657 assert RexLiteral.isNullLiteral(child);
1661 return (RexLiteral) child;
1664 RexLiteral literal = (RexLiteral) literalExpr;
1666 Comparable value = literal.getValue();
1668 if (SqlTypeUtil.isExactNumeric(type) && SqlTypeUtil.hasScale(
type)) {
1669 BigDecimal roundedValue =
1670 NumberUtil.rescaleBigDecimal((BigDecimal) value, type.getScale());
1671 return rexBuilder.makeExactLiteral(roundedValue,
type);
1674 if ((value instanceof NlsString) && (type.getSqlTypeName() == SqlTypeName.CHAR)) {
1676 NlsString unpadded = (NlsString) value;
1677 return rexBuilder.makeCharLiteral(
1678 new NlsString(Spaces.padRight(unpadded.getValue(), type.getPrecision()),
1679 unpadded.getCharsetName(),
1680 unpadded.getCollation()));
1686 if (!(node.getKind() == SqlKind.ROW)) {
1689 SqlCall call = (SqlCall) node;
1690 return call.getOperator().getName().equalsIgnoreCase(
"row");
1711 RelOptUtil.Logic logic,
1712 boolean registerOnlyScalarSubQueries) {
1713 final SqlKind kind = node.getKind();
1717 case MULTISET_QUERY_CONSTRUCTOR:
1718 case MULTISET_VALUE_CONSTRUCTOR:
1719 case ARRAY_QUERY_CONSTRUCTOR:
1722 if (!registerOnlyScalarSubQueries || (kind == SqlKind.SCALAR_QUERY)) {
1723 bb.registerSubQuery(node, RelOptUtil.Logic.TRUE_FALSE);
1730 logic = logic.negate();
1733 if (node instanceof SqlCall) {
1743 logic = RelOptUtil.Logic.TRUE_FALSE_UNKNOWN;
1746 for (SqlNode operand : ((SqlCall) node).getOperandList()) {
1747 if (operand != null) {
1753 kind == SqlKind.IN || kind == SqlKind.NOT_IN || kind == SqlKind.SOME
1754 || kind == SqlKind.ALL || registerOnlyScalarSubQueries);
1757 }
else if (node instanceof SqlNodeList) {
1758 for (SqlNode child : (SqlNodeList) node) {
1762 kind == SqlKind.IN || kind == SqlKind.NOT_IN || kind == SqlKind.SOME
1763 || kind == SqlKind.ALL || registerOnlyScalarSubQueries);
1777 case TRUE_FALSE_UNKNOWN:
1778 RelDataType
type = validator.getValidatedNodeTypeIfKnown(node);
1787 case UNKNOWN_AS_FALSE:
1788 logic = RelOptUtil.Logic.TRUE;
1790 bb.registerSubQuery(node, logic);
1802 Map<String, RelDataType> nameToTypeMap = Collections.emptyMap();
1803 final ParameterScope scope =
1806 return bb.convertExpression(node);
1821 final Map<String, RelDataType> nameToTypeMap =
new HashMap<>();
1822 for (Map.Entry<String, RexNode> entry : nameToNodeMap.entrySet()) {
1823 nameToTypeMap.put(entry.getKey(), entry.getValue().getType());
1825 final ParameterScope scope =
1828 return bb.convertExpression(node);
1848 SqlCall call = (SqlCall) node;
1849 SqlCall aggCall = call.operand(0);
1850 boolean ignoreNulls =
false;
1851 switch (aggCall.getKind()) {
1856 aggCall = aggCall.operand(0);
1859 SqlNode windowOrRef = call.operand(1);
1860 final SqlWindow window = validator.resolveWindow(windowOrRef, bb.scope);
1862 SqlNode sqlLowerBound = window.getLowerBound();
1863 SqlNode sqlUpperBound = window.getUpperBound();
1864 boolean rows = window.isRows();
1865 SqlNodeList orderList = window.getOrderList();
1867 if (!aggCall.getOperator().allowsFraming()) {
1870 sqlLowerBound = SqlWindow.createUnboundedPreceding(SqlParserPos.ZERO);
1871 sqlUpperBound = SqlWindow.createCurrentRow(SqlParserPos.ZERO);
1872 if (aggCall.getKind() == SqlKind.ROW_NUMBER) {
1876 }
else if (orderList.size() == 0) {
1878 sqlLowerBound = SqlWindow.createUnboundedPreceding(SqlParserPos.ZERO);
1879 sqlUpperBound = SqlWindow.createUnboundedFollowing(SqlParserPos.ZERO);
1880 }
else if (sqlLowerBound == null && sqlUpperBound == null) {
1881 sqlLowerBound = SqlWindow.createUnboundedPreceding(SqlParserPos.ZERO);
1882 sqlUpperBound = SqlWindow.createCurrentRow(SqlParserPos.ZERO);
1883 }
else if (sqlUpperBound == null) {
1884 sqlUpperBound = SqlWindow.createCurrentRow(SqlParserPos.ZERO);
1885 }
else if (sqlLowerBound == null) {
1886 sqlLowerBound = SqlWindow.createCurrentRow(SqlParserPos.ZERO);
1888 final SqlNodeList partitionList = window.getPartitionList();
1889 final ImmutableList.Builder<RexNode> partitionKeys = ImmutableList.builder();
1890 for (SqlNode partition : partitionList) {
1891 partitionKeys.add(bb.convertExpression(partition));
1893 final RexNode lowerBound = bb.convertExpression(sqlLowerBound);
1894 final RexNode upperBound = bb.convertExpression(sqlUpperBound);
1895 if (orderList.size() == 0 && !
rows) {
1899 orderList = bb.scope.getOrderList();
1900 if (orderList == null) {
1901 throw new AssertionError(
"Relation should have sort key for implicit ORDER BY");
1905 final ImmutableList.Builder<RexFieldCollation> orderKeys = ImmutableList.builder();
1906 for (SqlNode order : orderList) {
1907 orderKeys.add(bb.convertSortExpression(order,
1908 RelFieldCollation.Direction.ASCENDING,
1909 RelFieldCollation.NullDirection.UNSPECIFIED));
1913 Preconditions.checkArgument(bb.window == null,
"already in window agg mode");
1915 RexNode rexAgg = exprConverter.convertCall(bb, aggCall);
1916 rexAgg = rexBuilder.ensureType(validator.getValidatedNodeType(call), rexAgg,
false);
1922 final SqlLiteral q = aggCall.getFunctionQuantifier();
1923 final boolean isDistinct = q != null && q.getValue() == SqlSelectKeyword.DISTINCT;
1925 final RexShuttle visitor =
new HistogramShuttle(partitionKeys.build(),
1927 RexWindowBounds.create(sqlLowerBound, lowerBound),
1928 RexWindowBounds.create(sqlUpperBound, upperBound),
1930 window.isAllowPartial(),
1933 return rexAgg.accept(visitor);
1963 bb.setRoot(LogicalValues.createOneRow(
cluster),
false);
1968 final SqlNode[] operands;
1969 switch (from.getKind()) {
1970 case MATCH_RECOGNIZE:
1975 call = (SqlCall) from;
1976 SqlNode firstOperand = call.operand(0);
1977 final List<String> fieldNameList =
new ArrayList<>();
1978 if (call.operandCount() > 2) {
1979 for (SqlNode node : Util.skip(call.getOperandList(), 2)) {
1980 fieldNameList.add(((SqlIdentifier) node).getSimple());
1995 operands = ((SqlBasicCall) from).getOperands();
1996 SqlSampleSpec sampleSpec = SqlLiteral.sampleValue(operands[1]);
1997 if (sampleSpec instanceof SqlSampleSpec.SqlSubstitutionSampleSpec) {
1999 ((SqlSampleSpec.SqlSubstitutionSampleSpec) sampleSpec).getName();
2000 datasetStack.push(sampleName);
2003 }
else if (sampleSpec instanceof SqlSampleSpec.SqlTableSampleSpec) {
2004 SqlSampleSpec.SqlTableSampleSpec tableSampleSpec =
2005 (SqlSampleSpec.SqlTableSampleSpec) sampleSpec;
2007 RelOptSamplingParameters
params =
2008 new RelOptSamplingParameters(tableSampleSpec.isBernoulli(),
2009 tableSampleSpec.getSamplePercentage(),
2010 tableSampleSpec.isRepeatable(),
2011 tableSampleSpec.getRepeatableSeed());
2012 bb.setRoot(
new Sample(
cluster, bb.
root, params),
false);
2014 throw new AssertionError(
"unknown TABLESAMPLE type: " + sampleSpec);
2019 call = (SqlCall) from;
2028 call = (SqlCall) from;
2029 final SqlNode operand0 = call.getOperandList().
get(0);
2030 final SqlIdentifier
id = operand0.getKind() == SqlKind.TABLE_REF
2031 ? ((SqlCall) operand0).operand(0)
2032 : (SqlIdentifier) operand0;
2033 SqlNodeList extendedColumns = (SqlNodeList) call.getOperandList().get(1);
2042 final SqlJoin
join = (SqlJoin) from;
2043 final SqlValidatorScope scope = validator.getJoinScope(from);
2045 SqlNode left = join.getLeft();
2046 SqlNode right = join.getRight();
2047 final boolean isNatural = join.isNatural();
2048 final JoinType joinType = join.getJoinType();
2049 final SqlValidatorScope leftScope = Util.first(
2050 validator.getJoinScope(left), ((DelegatingScope) bb.scope).getParent());
2052 final SqlValidatorScope rightScope = Util.first(
2053 validator.getJoinScope(right), ((DelegatingScope) bb.scope).getParent());
2060 RexNode conditionExp;
2061 final SqlValidatorNamespace leftNamespace = validator.getNamespace(left);
2062 final SqlValidatorNamespace rightNamespace = validator.getNamespace(right);
2064 final RelDataType leftRowType = leftNamespace.getRowType();
2065 final RelDataType rightRowType = rightNamespace.getRowType();
2066 final List<String> columnList = SqlValidatorUtil.deriveNaturalJoinColumnList(
2067 catalogReader.nameMatcher(), leftRowType, rightRowType);
2068 conditionExp =
convertUsing(leftNamespace, rightNamespace, columnList);
2073 join.getCondition(),
2074 join.getConditionType(),
2080 fromBlackboard, leftRel, rightRel, conditionExp, convertedJoinType);
2081 bb.setRoot(joinRel,
false);
2089 bb.setRoot(rel,
true);
2094 if (fieldNames.size() > 0) {
2095 bb.setRoot(relBuilder.push(
bb.root).rename(fieldNames).build(),
true);
2103 case COLLECTION_TABLE:
2104 call = (SqlCall) from;
2107 assert call.getOperandList().size() == 1;
2108 final SqlCall call2 = call.operand(0);
2113 throw new AssertionError(
"not a join operator " + from);
2118 final List<SqlNode> nodes = call.getOperandList();
2119 final SqlUnnestOperator operator = (SqlUnnestOperator) call.getOperator();
2120 for (SqlNode node : nodes) {
2123 final List<RexNode> exprs =
new ArrayList<>();
2124 for (Ord<SqlNode> node : Ord.zip(nodes)) {
2125 exprs.add(relBuilder.alias(
2126 bb.convertExpression(node.e),
validator.deriveAlias(node.e, node.i)));
2130 if (
validator.config().sqlConformance().allowAliasUnnestItems()) {
2131 uncollect = relBuilder.push(child)
2133 .uncollect(fieldNames, operator.withOrdinality)
2138 uncollect = relBuilder.push(child)
2140 .uncollect(Collections.emptyList(),
operator.withOrdinality)
2144 bb.setRoot(uncollect,
true);
2148 final SqlMatchRecognize matchRecognize = (SqlMatchRecognize) call;
2149 final SqlValidatorNamespace ns = validator.getNamespace(matchRecognize);
2150 final SqlValidatorScope scope = validator.getMatchRecognizeScope(matchRecognize);
2153 final RelDataType rowType = ns.getRowType();
2155 SqlNode expr = matchRecognize.getTableRef();
2160 final SqlNodeList partitionList = matchRecognize.getPartitionList();
2161 final ImmutableBitSet.Builder partitionKeys = ImmutableBitSet.builder();
2162 for (SqlNode partition : partitionList) {
2163 RexNode e = matchBb.convertExpression(partition);
2164 partitionKeys.set(((RexInputRef) e).getIndex());
2168 final SqlNodeList orderList = matchRecognize.getOrderList();
2169 final List<RelFieldCollation> orderKeys =
new ArrayList<>();
2170 for (SqlNode order : orderList) {
2171 final RelFieldCollation.Direction direction;
2172 switch (order.getKind()) {
2174 direction = RelFieldCollation.Direction.DESCENDING;
2175 order = ((SqlCall) order).operand(0);
2179 throw new AssertionError();
2181 direction = RelFieldCollation.Direction.ASCENDING;
2184 final RelFieldCollation.NullDirection nullDirection =
2185 validator.config().defaultNullCollation().last(
desc(direction))
2186 ? RelFieldCollation.NullDirection.LAST
2187 : RelFieldCollation.NullDirection.FIRST;
2188 RexNode e = matchBb.convertExpression(order);
2189 orderKeys.add(
new RelFieldCollation(
2190 ((RexInputRef) e).getIndex(), direction, nullDirection));
2192 final RelCollation orders = cluster.traitSet().canonize(RelCollations.of(orderKeys));
2195 final Set<String> patternVarsSet =
new HashSet<>();
2196 SqlNode pattern = matchRecognize.getPattern();
2197 final SqlBasicVisitor<RexNode> patternVarVisitor =
new SqlBasicVisitor<RexNode>() {
2199 public RexNode visit(SqlCall call) {
2200 List<SqlNode> operands = call.getOperandList();
2201 List<RexNode> newOperands =
new ArrayList<>();
2202 for (SqlNode node : operands) {
2203 newOperands.add(node.accept(
this));
2205 return rexBuilder.makeCall(
2206 validator.getUnknownType(), call.getOperator(), newOperands);
2210 public RexNode visit(SqlIdentifier
id) {
2211 assert id.isSimple();
2212 patternVarsSet.add(id.getSimple());
2213 return rexBuilder.makeLiteral(id.getSimple());
2217 public RexNode visit(SqlLiteral literal) {
2218 if (literal instanceof SqlNumericLiteral) {
2219 return rexBuilder.makeExactLiteral(BigDecimal.valueOf(literal.intValue(
true)));
2221 return rexBuilder.makeLiteral(literal.booleanValue());
2225 final RexNode patternNode = pattern.accept(patternVarVisitor);
2227 SqlLiteral interval = matchRecognize.getInterval();
2228 RexNode intervalNode = null;
2229 if (interval != null) {
2230 intervalNode = matchBb.convertLiteral(interval);
2234 final SqlNodeList subsets = matchRecognize.getSubsetList();
2235 final Map<String, TreeSet<String>> subsetMap =
new HashMap<>();
2236 for (SqlNode node : subsets) {
2237 List<SqlNode> operands = ((SqlCall) node).getOperandList();
2238 SqlIdentifier left = (SqlIdentifier) operands.get(0);
2239 patternVarsSet.add(left.getSimple());
2240 SqlNodeList rights = (SqlNodeList) operands.get(1);
2241 final TreeSet<String> list =
new TreeSet<>();
2242 for (SqlNode right : rights) {
2243 assert right instanceof SqlIdentifier;
2244 list.add(((SqlIdentifier) right).getSimple());
2246 subsetMap.put(left.getSimple(), list);
2249 SqlNode afterMatch = matchRecognize.getAfter();
2250 if (afterMatch == null) {
2252 SqlMatchRecognize.AfterOption.SKIP_TO_NEXT_ROW.symbol(SqlParserPos.ZERO);
2255 final RexNode after;
2256 if (afterMatch instanceof SqlCall) {
2257 List<SqlNode> operands = ((SqlCall) afterMatch).getOperandList();
2258 SqlOperator operator = ((SqlCall) afterMatch).getOperator();
2259 assert operands.size() == 1;
2260 SqlIdentifier
id = (SqlIdentifier) operands.get(0);
2261 assert patternVarsSet.contains(id.getSimple())
2263 +
" not defined in pattern";
2264 RexNode rex = rexBuilder.makeLiteral(id.getSimple());
2265 after = rexBuilder.makeCall(
2266 validator.getUnknownType(),
operator, ImmutableList.of(rex));
2268 after = matchBb.convertExpression(afterMatch);
2271 matchBb.setPatternVarRef(
true);
2274 final ImmutableMap.Builder<String, RexNode> measureNodes = ImmutableMap.builder();
2275 for (SqlNode
measure : matchRecognize.getMeasureList()) {
2276 List<SqlNode> operands = ((SqlCall)
measure).getOperandList();
2277 String alias = ((SqlIdentifier) operands.get(1)).getSimple();
2278 RexNode rex = matchBb.convertExpression(operands.get(0));
2279 measureNodes.put(alias, rex);
2283 final ImmutableMap.Builder<String, RexNode> definitionNodes = ImmutableMap.builder();
2284 for (SqlNode def : matchRecognize.getPatternDefList()) {
2286 List<SqlNode> operands = ((SqlCall) def).getOperandList();
2287 String alias = ((SqlIdentifier) operands.get(1)).getSimple();
2288 RexNode rex = matchBb.convertExpression(operands.get(0));
2289 definitionNodes.put(alias, rex);
2292 final SqlLiteral rowsPerMatch = matchRecognize.getRowsPerMatch();
2293 final boolean allRows = rowsPerMatch != null
2294 && rowsPerMatch.getValue() == SqlMatchRecognize.RowsPerMatchOption.ALL_ROWS;
2296 matchBb.setPatternVarRef(
false);
2298 final RelFactories.MatchFactory factory = RelFactories.DEFAULT_MATCH_FACTORY;
2299 final RelNode rel = factory.createMatch(input,
2302 matchRecognize.getStrictStart().booleanValue(),
2303 matchRecognize.getStrictEnd().booleanValue(),
2304 definitionNodes.build(),
2305 measureNodes.build(),
2309 partitionKeys.build(),
2312 bb.setRoot(rel,
false);
2317 SqlNodeList extendedColumns,
2318 SqlNodeList tableHints) {
2319 final SqlValidatorNamespace fromNamespace = validator.getNamespace(id).resolve();
2320 if (fromNamespace.getNode() != null) {
2324 final String datasetName = datasetStack.isEmpty() ? null :
datasetStack.peek();
2325 final boolean[] usedDataset = {
false};
2326 RelOptTable table = SqlValidatorUtil.getRelOptTable(
2328 if (extendedColumns != null && extendedColumns.size() > 0) {
2329 assert table != null;
2330 final SqlValidatorTable validatorTable = table.unwrap(SqlValidatorTable.class);
2331 final List<RelDataTypeField> extendedFields = SqlValidatorUtil.getExtendedColumns(
2332 validator, validatorTable, extendedColumns);
2333 table = table.extend(extendedFields);
2335 final RelNode tableRel;
2338 final List<RelHint> hints =
2339 hintStrategies.apply(SqlUtil.getRelHint(
hintStrategies, tableHints),
2340 LogicalTableScan.create(
cluster, table, ImmutableList.of()));
2341 tableRel =
toRel(table, hints);
2342 bb.setRoot(tableRel,
true);
2343 if (usedDataset[0]) {
2344 bb.setDataset(datasetName);
2350 if (
operator == SqlStdOperatorTable.TABLESAMPLE) {
2351 final String sampleName =
2352 SqlLiteral.unchain(call.operand(0)).getValueAs(String.class);
2353 datasetStack.push(sampleName);
2354 SqlCall cursorCall = call.operand(1);
2355 SqlNode query = cursorCall.operand(0);
2356 RelNode converted =
convertQuery(query,
false,
false).rel;
2357 bb.setRoot(converted,
false);
2365 final SqlCallBinding callBinding =
2366 new SqlCallBinding(bb.
scope.getValidator(), bb.scope, call);
2367 if (
operator instanceof SqlUserDefinedTableMacro) {
2368 final SqlUserDefinedTableMacro udf = (SqlUserDefinedTableMacro)
operator;
2369 final TranslatableTable table = udf.getTable(callBinding);
2370 final RelDataType rowType = table.getRowType(
typeFactory);
2371 RelOptTable relOptTable =
2372 RelOptTableImpl.create(null, rowType, table, udf.getNameAsId().names);
2373 RelNode converted =
toRel(relOptTable, ImmutableList.of());
2374 bb.setRoot(converted,
true);
2379 if (
operator instanceof SqlUserDefinedTableFunction) {
2380 SqlUserDefinedTableFunction udtf = (SqlUserDefinedTableFunction)
operator;
2381 elementType = udtf.getElementType(callBinding);
2386 RexNode rexCall = bb.convertExpression(call);
2387 final List<RelNode> inputs = bb.retrieveCursors();
2389 LogicalTableFunctionScan callRel = LogicalTableFunctionScan.create(
cluster,
2393 validator.getValidatedNodeType(call),
2395 bb.setRoot(callRel,
true);
2401 LogicalTableFunctionScan callRel) {}
2404 final SqlSnapshot snapshot = (SqlSnapshot) call;
2405 final RexNode period = bb.convertExpression(snapshot.getPeriod());
2408 SqlNode expr = snapshot.getTableRef();
2411 final RelNode snapshotRel = relBuilder.push(
bb.root).snapshot(period).build();
2413 bb.setRoot(snapshotRel,
false);
2418 ExtTableFunction tf = (ExtTableFunction) op;
2419 return tf.getColumnMappings();
2421 SqlReturnTypeInference rti = op.getReturnTypeInference();
2425 if (rti instanceof TableFunctionReturnTypeInference) {
2426 TableFunctionReturnTypeInference tfrti = (TableFunctionReturnTypeInference) rti;
2427 return tfrti.getColumnMappings();
2450 int i = input.getIndex() -
rexCorrel.getType().getFieldCount();
2452 varCols.set(input.getIndex());
2453 return builder.makeFieldAccess(
rexCorrel, input.getIndex());
2455 return builder.makeInputRef(input.getType(), i);
2463 JoinRelType joinType) {
2464 assert joinCond != null;
2468 RelNode innerRel = p.r;
2469 ImmutableBitSet requiredCols = p.requiredColumns;
2471 if (!joinCond.isAlwaysTrue()) {
2472 final RelFactories.FilterFactory factory = RelFactories.DEFAULT_FILTER_FACTORY;
2473 final RexCorrelVariable rexCorrel =
2474 (RexCorrelVariable)
rexBuilder.makeCorrel(leftRel.getRowType(), p.id);
2479 final RexNode newCond = joinCond.accept(shuttle);
2480 innerRel = factory.createFilter(p.r, newCond, ImmutableSet.of());
2482 ImmutableBitSet.fromBitSet(shuttle.varCols).
union(p.requiredColumns);
2485 return LogicalCorrelate.create(leftRel, innerRel, p.id, requiredCols, joinType);
2493 final Join originalJoin = (Join) RelFactories.DEFAULT_JOIN_FACTORY.createJoin(leftRel,
2500 RelNode node = originalJoin;
2504 if (node instanceof Project) {
2505 final Join newJoin = (Join) node.getInputs().get(0);
2506 if (
leaves.containsKey(leftRel)) {
2507 leaves.put(newJoin.getLeft(),
leaves.get(leftRel));
2509 if (
leaves.containsKey(rightRel)) {
2510 leaves.put(newJoin.getRight(),
leaves.get(rightRel));
2517 final Set<CorrelationId> correlatedVariables = RelOptUtil.getVariablesUsed(r0);
2518 if (correlatedVariables.isEmpty()) {
2521 final ImmutableBitSet.Builder requiredColumns = ImmutableBitSet.builder();
2522 final List<CorrelationId> correlNames =
new ArrayList<>();
2528 SqlValidatorNamespace prevNs = null;
2530 for (CorrelationId correlName : correlatedVariables) {
2532 RexFieldAccess fieldAccess = lookup.getFieldAccess(correlName);
2533 String originalRelName = lookup.getOriginalRelName();
2534 String originalFieldName = fieldAccess.getField().getName();
2536 final SqlNameMatcher nameMatcher =
2537 bb.getValidator().getCatalogReader().nameMatcher();
2538 final SqlValidatorScope.ResolvedImpl resolved =
2539 new SqlValidatorScope.ResolvedImpl();
2540 lookup.bb.scope.resolve(
2541 ImmutableList.of(originalRelName), nameMatcher,
false, resolved);
2542 assert resolved.count() == 1;
2543 final SqlValidatorScope.Resolve resolve = resolved.only();
2544 final SqlValidatorNamespace foundNs = resolve.namespace;
2545 final RelDataType rowType = resolve.rowType();
2546 final int childNamespaceIndex = resolve.path.steps().
get(0).i;
2547 final SqlValidatorScope ancestorScope = resolve.scope;
2548 boolean correlInCurrentScope = bb.scope.isWithin(ancestorScope);
2550 if (!correlInCurrentScope) {
2554 if (prevNs == null) {
2558 == foundNs :
"All correlation variables should resolve"
2559 +
" to the same namespace."
2566 int namespaceOffset = 0;
2567 if (childNamespaceIndex > 0) {
2570 assert ancestorScope instanceof ListScope;
2571 List<SqlValidatorNamespace> children = ((ListScope) ancestorScope).getChildren();
2573 for (
int i = 0; i < childNamespaceIndex; i++) {
2574 SqlValidatorNamespace child = children.get(i);
2575 namespaceOffset += child.getRowType().getFieldCount();
2579 RexFieldAccess topLevelFieldAccess = fieldAccess;
2580 while (topLevelFieldAccess.getReferenceExpr() instanceof RexFieldAccess) {
2581 topLevelFieldAccess = (RexFieldAccess) topLevelFieldAccess.getReferenceExpr();
2583 final RelDataTypeField
field = rowType.getFieldList().
get(
2584 topLevelFieldAccess.getField().getIndex() - namespaceOffset);
2585 int pos = namespaceOffset + field.getIndex();
2587 assert field.getType() == topLevelFieldAccess.getField().getType();
2594 Map<Integer, Integer> exprProjection =
2595 bb.mapRootRelToFieldProjection.get(
bb.root);
2599 if (exprProjection.containsKey(pos)) {
2600 pos = exprProjection.get(pos);
2603 throw new AssertionError(
"Identifier '" + originalRelName +
"."
2604 + originalFieldName +
"' is not a group expr");
2608 requiredColumns.set(pos);
2609 correlNames.add(correlName);
2612 if (correlNames.isEmpty()) {
2618 if (correlNames.size() > 1) {
2621 r = DeduplicateCorrelateVariables.go(
2622 rexBuilder, correlNames.get(0), Util.skip(correlNames), r0);
2624 leaves.put(r, r.getRowType().getFieldCount());
2626 return new CorrelationUse(correlNames.get(0), requiredColumns.build(), r);
2640 Set<CorrelationId> correlatedVariables = RelOptUtil.getVariablesUsed(subq);
2641 for (CorrelationId correlName : correlatedVariables) {
2643 String originalRelName = lookup.getOriginalRelName();
2645 final SqlNameMatcher nameMatcher =
2646 lookup.bb.scope.getValidator().getCatalogReader().nameMatcher();
2647 final SqlValidatorScope.ResolvedImpl resolved =
2648 new SqlValidatorScope.ResolvedImpl();
2649 lookup.bb.scope.resolve(
2650 ImmutableList.of(originalRelName), nameMatcher,
false, resolved);
2652 SqlValidatorScope ancestorScope = resolved.only().scope;
2656 SqlValidatorScope parentScope = bb.scope;
2658 if (ancestorScope == parentScope) {
2661 if (parentScope instanceof DelegatingScope) {
2662 parentScope = ((DelegatingScope) parentScope).getParent();
2666 }
while (parentScope != null);
2677 return Collections.emptyList();
2681 SqlValidatorNamespace leftNamespace,
2682 SqlValidatorNamespace rightNamespace,
2684 JoinConditionType conditionType,
2687 if (condition == null) {
2688 return rexBuilder.makeLiteral(
true);
2690 bb.setRoot(ImmutableList.of(leftRel, rightRel));
2692 switch (conditionType) {
2694 bb.setRoot(ImmutableList.of(leftRel, rightRel));
2695 return bb.convertExpression(condition);
2697 final SqlNodeList list = (SqlNodeList) condition;
2698 final List<String> nameList =
new ArrayList<>();
2699 for (SqlNode columnName : list) {
2700 final SqlIdentifier
id = (SqlIdentifier) columnName;
2701 String
name = id.getSimple();
2704 return convertUsing(leftNamespace, rightNamespace, nameList);
2706 throw Util.unexpected(conditionType);
2722 SqlValidatorNamespace rightNamespace,
2723 List<String> nameList) {
2724 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
2725 final List<RexNode> list =
new ArrayList<>();
2726 for (String
name : nameList) {
2727 List<RexNode> operands =
new ArrayList<>();
2729 for (SqlValidatorNamespace
n : ImmutableList.of(leftNamespace, rightNamespace)) {
2730 final RelDataType rowType = n.getRowType();
2731 final RelDataTypeField
field = nameMatcher.field(rowType,
name);
2732 operands.add(rexBuilder.makeInputRef(field.getType(), offset + field.getIndex()));
2733 offset += rowType.getFieldList().size();
2735 list.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, operands));
2737 return RexUtil.composeConjunction(
rexBuilder, list);
2745 return JoinRelType.INNER;
2747 return JoinRelType.FULL;
2749 return JoinRelType.LEFT;
2751 return JoinRelType.RIGHT;
2753 throw Util.unexpected(joinType);
2771 Blackboard bb, SqlSelect select, List<SqlNode> orderExprList) {
2772 assert bb.root != null :
"precondition: child != null";
2773 SqlNodeList groupList = select.getGroup();
2774 SqlNodeList selectList = select.getSelectList();
2775 SqlNode having = select.getHaving();
2777 final AggConverter aggConverter =
new AggConverter(bb, select);
2778 createAggImpl(bb, aggConverter, selectList, groupList, having, orderExprList);
2782 final AggConverter aggConverter,
2783 SqlNodeList selectList,
2784 SqlNodeList groupList,
2786 List<SqlNode> orderExprList) {
2788 final AggregateFinder aggregateFinder =
new AggregateFinder();
2789 selectList.accept(aggregateFinder);
2790 if (having != null) {
2791 having.accept(aggregateFinder);
2796 replaceSubQueries(bb, aggregateFinder.list, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
2800 bb, aggregateFinder.filterList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
2803 replaceSubQueries(bb, aggregateFinder.orderList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
2806 if (groupList == null) {
2807 groupList = SqlNodeList.EMPTY;
2820 final AggregatingSelectScope scope = aggConverter.aggregatingSelectScope;
2821 final AggregatingSelectScope.Resolved r = scope.resolved.get();
2822 for (SqlNode groupExpr : r.groupExprList) {
2823 aggConverter.addGroupExpr(groupExpr);
2826 final RexNode havingExpr;
2827 final List<Pair<RexNode, String>> projects =
new ArrayList<>();
2830 Preconditions.checkArgument(bb.agg == null,
"already in agg mode");
2831 bb.agg = aggConverter;
2836 selectList.accept(aggConverter);
2838 assert !aggConverter.inOver;
2839 for (SqlNode expr : orderExprList) {
2840 expr.accept(aggConverter);
2841 assert !aggConverter.inOver;
2843 if (having != null) {
2844 having.accept(aggConverter);
2845 assert !aggConverter.inOver;
2849 List<Pair<RexNode, String>> preExprs = aggConverter.getPreExprs();
2851 if (preExprs.size() == 0) {
2855 final RexNode zero = rexBuilder.makeExactLiteral(BigDecimal.ZERO);
2856 preExprs = ImmutableList.of(Pair.of(zero, (String) null));
2859 final RelNode inputRel =
bb.root;
2862 bb.setRoot(relBuilder.push(inputRel)
2863 .projectNamed(Pair.left(preExprs), Pair.right(preExprs),
false)
2866 bb.mapRootRelToFieldProjection.put(
bb.root, r.groupExprProjection);
2873 bb.columnMonotonicities.clear();
2874 for (SqlNode groupItem : groupList) {
2875 bb.columnMonotonicities.add(bb.scope.getMonotonicity(groupItem));
2878 final RelNode relNode = aggConverter.containsGroupId()
2880 :
createAggregate(bb, r.groupSet, r.groupSets, aggConverter.getAggCalls());
2882 bb.setRoot(relNode,
false);
2883 bb.mapRootRelToFieldProjection.put(
bb.root, r.groupExprProjection);
2887 if (having != null) {
2890 havingExpr = bb.convertExpression(newHaving);
2892 havingExpr = relBuilder.literal(
true);
2912 final SelectScope selectScope = SqlValidatorUtil.getEnclosingSelectScope(bb.scope);
2913 assert selectScope != null;
2914 final SqlValidatorNamespace selectNamespace =
2915 validator.getNamespace(selectScope.getNode());
2916 final List<String> names = selectNamespace.getRowType().getFieldNames();
2917 int sysFieldCount = selectList.size() - names.size();
2918 for (SqlNode expr : selectList) {
2919 projects.add(Pair.of(bb.convertExpression(expr),
2920 k < sysFieldCount ?
validator.deriveAlias(expr, k++)
2921 : names.get(k++ - sysFieldCount)));
2924 for (SqlNode expr : orderExprList) {
2926 Pair.of(bb.convertExpression(expr),
validator.deriveAlias(expr, k++)));
2934 if (havingExpr != null) {
2935 relBuilder.filter(havingExpr);
2939 relBuilder.project(Pair.left(projects), Pair.right(projects))
2940 .rename(Pair.right(projects));
2941 bb.setRoot(relBuilder.build(),
false);
2944 bb.columnMonotonicities.clear();
2945 for (SqlNode selectItem : selectList) {
2946 bb.columnMonotonicities.add(bb.scope.getMonotonicity(selectItem));
2964 Blackboard bb, AggregatingSelectScope.Resolved r, AggConverter converter) {
2965 final List<AggregateCall> aggregateCalls = converter.getAggCalls();
2966 final ImmutableBitSet groupSet = r.groupSet;
2967 final Map<ImmutableBitSet, Integer> groupSetCount = r.groupSetCount;
2969 final List<String> fieldNamesIfNoRewrite =
2984 final Map<Integer, Set<ImmutableBitSet>> groupIdToGroupSets =
new HashMap<>();
2986 for (Map.Entry<ImmutableBitSet,
Integer> entry : groupSetCount.entrySet()) {
2987 int groupId = entry.getValue() - 1;
2988 if (groupId > maxGroupId) {
2989 maxGroupId = groupId;
2991 for (
int i = 0; i <= groupId; i++) {
2993 .computeIfAbsent(i, k -> Sets.newTreeSet(ImmutableBitSet.COMPARATOR))
2994 .add(entry.getKey());
2999 final List<AggregateCall> aggregateCallsWithoutGroupId =
new ArrayList<>();
3000 for (AggregateCall aggregateCall : aggregateCalls) {
3001 if (aggregateCall.getAggregation().kind != SqlKind.GROUP_ID) {
3002 aggregateCallsWithoutGroupId.add(aggregateCall);
3005 final List<RelNode> projects =
new ArrayList<>();
3009 for (
int groupId = 0; groupId <= maxGroupId; groupId++) {
3011 final ImmutableList<ImmutableBitSet> groupSets =
3012 ImmutableList.copyOf(groupIdToGroupSets.get(groupId));
3013 final RelNode aggregate =
3014 createAggregate(bb, groupSet, groupSets, aggregateCallsWithoutGroupId);
3017 final RelDataType groupIdType = typeFactory.createSqlType(SqlTypeName.BIGINT);
3018 final RexNode groupIdLiteral =
3019 rexBuilder.makeExactLiteral(BigDecimal.valueOf(groupId), groupIdType);
3021 relBuilder.push(aggregate);
3022 final List<RexNode> selectList =
new ArrayList<>();
3023 final int groupExprLength = r.groupExprList.size();
3025 for (
int i = 0; i < groupExprLength; i++) {
3026 selectList.add(relBuilder.field(i));
3029 int groupIdCount = 0;
3030 for (
int i = 0; i < aggregateCalls.size(); i++) {
3031 if (aggregateCalls.get(i).getAggregation().kind == SqlKind.GROUP_ID) {
3032 selectList.add(groupIdLiteral);
3035 int ordinal = groupExprLength + i - groupIdCount;
3036 selectList.add(relBuilder.field(ordinal));
3039 final RelNode project =
3040 relBuilder.project(selectList, fieldNamesIfNoRewrite).build();
3041 projects.add(project);
3045 if (projects.size() == 1) {
3046 return projects.get(0);
3048 return LogicalUnion.create(projects,
true);
3071 ImmutableBitSet groupSet,
3072 ImmutableList<ImmutableBitSet> groupSets,
3073 List<AggregateCall> aggCalls) {
3074 return LogicalAggregate.create(
3075 bb.root, ImmutableList.of(), groupSet, groupSets, aggCalls);
3083 while (dynamicParam.getIndex() >= dynamicParamSqlNodes.size()) {
3084 dynamicParamSqlNodes.add(null);
3087 dynamicParamSqlNodes.set(dynamicParam.getIndex(), dynamicParam);
3088 return rexBuilder.makeDynamicParam(
3108 SqlNodeList orderList,
3109 List<SqlNode> extraOrderExprs,
3110 List<RelFieldCollation> collationList) {
3112 assert bb.root != null :
"precondition: child != null";
3113 assert select != null;
3114 if (orderList == null) {
3119 SqlNode offset = select.getOffset();
3121 || (offset instanceof SqlLiteral
3122 && ((SqlLiteral) offset)
3124 .equals(BigDecimal.ZERO)))
3125 && select.getFetch() == null) {
3130 for (SqlNode orderItem : orderList) {
3134 RelFieldCollation.Direction.ASCENDING,
3135 RelFieldCollation.NullDirection.UNSPECIFIED));
3141 List<SqlNode> extraExprs,
3142 RelFieldCollation.Direction direction,
3143 RelFieldCollation.NullDirection nullDirection) {
3144 assert select != null;
3146 switch (orderItem.getKind()) {
3149 ((SqlCall) orderItem).operand(0),
3151 RelFieldCollation.Direction.DESCENDING,
3155 ((SqlCall) orderItem).operand(0),
3158 RelFieldCollation.NullDirection.FIRST);
3161 ((SqlCall) orderItem).operand(0),
3164 RelFieldCollation.NullDirection.LAST);
3167 SqlNode converted = validator.expandOrderExpr(select, orderItem);
3169 switch (nullDirection) {
3171 nullDirection = validator.config().defaultNullCollation().last(
desc(direction))
3172 ? RelFieldCollation.NullDirection.LAST
3173 : RelFieldCollation.NullDirection.FIRST;
3177 final SelectScope selectScope = validator.getRawSelectScope(select);
3179 for (SqlNode selectItem : selectScope.getExpandedSelectList()) {
3181 if (converted.equalsDeep(stripAs(selectItem), Litmus.IGNORE)) {
3182 return new RelFieldCollation(ordinal, direction, nullDirection);
3186 for (SqlNode extraExpr : extraExprs) {
3188 if (converted.equalsDeep(extraExpr, Litmus.IGNORE)) {
3189 return new RelFieldCollation(ordinal, direction, nullDirection);
3196 extraExprs.add(converted);
3197 return new RelFieldCollation(ordinal + 1, direction, nullDirection);
3200 private static boolean desc(RelFieldCollation.Direction direction) {
3201 switch (direction) {
3203 case STRICTLY_DESCENDING:
3214 return config.isDecorrelationEnabled();
3218 return RelDecorrelator.decorrelateQuery(rootRel,
relBuilder);
3228 return config.isTrimUnusedFields();
3241 SqlNode query,
boolean top, RelDataType targetRowType) {
3242 final SqlKind kind = query.getKind();
3245 return RelRoot.of(
convertSelect((SqlSelect) query, top), kind);
3253 return RelRoot.of(
convertMerge((SqlMerge) query), kind);
3257 return RelRoot.of(
convertSetOp((SqlCall) query), kind);
3261 return RelRoot.of(
convertValues((SqlCall) query, targetRowType), kind);
3263 throw new AssertionError(
"not a query: " + query);
3277 switch (call.getKind()) {
3279 return LogicalUnion.create(ImmutableList.of(left, right),
all(call));
3282 return LogicalIntersect.create(ImmutableList.of(left, right),
all(call));
3285 return LogicalMinus.create(ImmutableList.of(left, right),
all(call));
3288 throw Util.unexpected(call.getKind());
3292 private boolean all(SqlCall call) {
3293 return ((SqlSetOperator) call.getOperator()).isAll();
3299 final RelDataType targetRowType = validator.getValidatedNodeType(call);
3300 assert targetRowType != null;
3310 final ModifiableTable modifiableTable = targetTable.unwrap(ModifiableTable.class);
3311 if (modifiableTable != null && modifiableTable == targetTable.unwrap(Table.class)) {
3312 return modifiableTable.toModificationRel(
cluster,
3316 LogicalTableModify.Operation.INSERT,
3321 final ModifiableView modifiableView = targetTable.unwrap(ModifiableView.class);
3322 if (modifiableView != null) {
3323 final Table delegateTable = modifiableView.getTable();
3324 final RelDataType delegateRowType = delegateTable.getRowType(
typeFactory);
3325 final RelOptTable delegateRelOptTable = RelOptTableImpl.create(
3326 null, delegateRowType, delegateTable, modifiableView.getTablePath());
3327 final RelNode newSource =
3328 createSource(targetTable, source, modifiableView, delegateRowType);
3331 return LogicalTableModify.create(targetTable,
3334 LogicalTableModify.Operation.INSERT,
3355 ModifiableView modifiableView,
3356 RelDataType delegateRowType) {
3357 final ImmutableIntList mapping = modifiableView.getColumnMapping();
3358 assert mapping.size() == targetTable.getRowType().getFieldCount();
3362 final Map<Integer, RexNode> projectMap =
new HashMap<>();
3363 final List<RexNode> filters =
new ArrayList<>();
3364 for (
int i = 0; i < mapping.size(); i++) {
3365 int target = mapping.get(i);
3367 projectMap.put(target, RexInputRef.of(i, source.getRowType()));
3376 final RexNode constraint = modifiableView.getConstraint(
rexBuilder, delegateRowType);
3377 RelOptUtil.inferViewPredicates(projectMap, filters, constraint);
3378 final List<Pair<RexNode, String>> projects =
new ArrayList<>();
3379 for (RelDataTypeField
field : delegateRowType.getFieldList()) {
3380 RexNode node = projectMap.get(field.getIndex());
3382 node = rexBuilder.makeNullLiteral(field.getType());
3384 projects.add(Pair.of(
3385 rexBuilder.ensureType(field.getType(), node,
false), field.getName()));
3388 return relBuilder.push(source)
3389 .projectNamed(Pair.left(projects), Pair.right(projects),
false)
3398 public RelNode
toRel(
final RelOptTable table,
final List<RelHint> hints) {
3401 final InitializerExpressionFactory ief =
3402 Util.first(table.unwrap(InitializerExpressionFactory.class),
3403 NullInitializerExpressionFactory.INSTANCE);
3405 boolean hasVirtualFields = table.getRowType().getFieldList().stream().anyMatch(
3406 f -> ief.generationStrategy(table,
f.getIndex()) == ColumnStrategy.VIRTUAL);
3408 if (hasVirtualFields) {
3409 final RexNode sourceRef = rexBuilder.makeRangeReference(scan);
3411 table, sourceRef, table.getRowType().getFieldNames());
3412 final List<RexNode> list =
new ArrayList<>();
3413 for (RelDataTypeField
f : table.getRowType().getFieldList()) {
3414 final ColumnStrategy strategy = ief.generationStrategy(table, f.getIndex());
3417 list.add(ief.newColumnDefaultValue(table, f.getIndex(), bb));
3420 list.add(rexBuilder.makeInputRef(
3421 scan, RelOptTableImpl.realOrdinal(table, f.getIndex())));
3424 relBuilder.push(scan);
3425 relBuilder.project(list);
3426 final RelNode project = relBuilder.build();
3427 if (ief.postExpressionConversionHook() != null) {
3428 return ief.postExpressionConversionHook().apply(bb, project);
3438 final SqlValidatorNamespace targetNs = validator.getNamespace(call);
3440 final SqlValidatorImpl.DmlNamespace dmlNamespace =
3441 targetNs.unwrap(SqlValidatorImpl.DmlNamespace.class);
3442 return SqlValidatorUtil.getRelOptTable(dmlNamespace,
catalogReader, null, null);
3444 final SqlValidatorNamespace resolvedNamespace = targetNs.resolve();
3445 return SqlValidatorUtil.getRelOptTable(resolvedNamespace,
catalogReader, null, null);
3466 RelDataType sourceRowType = source.getRowType();
3467 final RexNode sourceRef = rexBuilder.makeRangeReference(sourceRowType, 0,
false);
3468 final List<String> targetColumnNames =
new ArrayList<>();
3469 final List<RexNode> columnExprs =
new ArrayList<>();
3473 final RelDataType targetRowType = RelOptTableImpl.realRowType(targetTable);
3474 final List<RelDataTypeField> targetFields = targetRowType.getFieldList();
3475 final List<RexNode> sourceExps =
3476 new ArrayList<>(Collections.nCopies(targetFields.size(), null));
3477 final List<String> fieldNames =
3478 new ArrayList<>(Collections.nCopies(targetFields.size(), null));
3480 final InitializerExpressionFactory initializerFactory =
3487 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
3488 for (Pair<String, RexNode> p : Pair.zip(targetColumnNames, columnExprs)) {
3489 RelDataTypeField
field = nameMatcher.field(targetRowType, p.left);
3490 assert field != null :
"column " + p.left +
" not found";
3491 sourceExps.set(field.getIndex(), p.right);
3495 final Supplier<Blackboard> bb =
3500 for (
int i = 0; i < targetFields.size(); ++i) {
3501 final RelDataTypeField
field = targetFields.get(i);
3502 final String fieldName = field.getName();
3503 fieldNames.set(i, fieldName);
3504 if (sourceExps.get(i) == null || sourceExps.get(i).getKind() == SqlKind.DEFAULT) {
3506 i, initializerFactory.newColumnDefaultValue(targetTable, i, bb.get()));
3513 return relBuilder.push(source).projectNamed(sourceExps, fieldNames,
false).build();
3521 RelOptTable targetTable, RexNode sourceRef, List<String> targetColumnNames) {
3522 final Map<String, RexNode> nameToNodeMap =
new HashMap<>();
3526 final List<ColumnStrategy> strategies = targetTable.getColumnStrategies();
3527 final List<String> targetFields = targetTable.getRowType().getFieldNames();
3528 for (String targetColumnName : targetColumnNames) {
3529 final int i = targetFields.indexOf(targetColumnName);
3530 switch (strategies.get(i)) {
3535 nameToNodeMap.put(targetColumnName, rexBuilder.makeFieldAccess(sourceRef, j++));
3542 SqlValidatorTable validatorTable) {
3544 final Table table =
unwrap(validatorTable, Table.class);
3545 if (table != null) {
3546 InitializerExpressionFactory
f =
unwrap(table, InitializerExpressionFactory.class);
3551 return NullInitializerExpressionFactory.INSTANCE;
3554 private static <T>
T unwrap(Object o, Class<T> clazz) {
3555 if (o instanceof Wrapper) {
3556 return ((Wrapper) o).unwrap(clazz);
3562 if (!RexLiteral.isNullLiteral(node)) {
3565 return rexBuilder.makeCast(
type, node);
3579 final RexNode sourceRef,
3580 final List<String> targetColumnNames,
3581 List<RexNode> columnExprs) {
3583 final RelDataType tableRowType = targetTable.getRowType();
3584 SqlNodeList targetColumnList = call.getTargetColumnList();
3585 if (targetColumnList == null) {
3586 if (
validator.config().sqlConformance().isInsertSubsetColumnsAllowed()) {
3587 final RelDataType targetRowType =
3588 typeFactory.createStructType(tableRowType.getFieldList().subList(
3589 0, sourceRef.getType().getFieldCount()));
3590 targetColumnNames.addAll(targetRowType.getFieldNames());
3592 targetColumnNames.addAll(tableRowType.getFieldNames());
3595 for (
int i = 0; i < targetColumnList.size(); i++) {
3596 SqlIdentifier
id = (SqlIdentifier) targetColumnList.get(i);
3597 RelDataTypeField
field = SqlValidatorUtil.getTargetField(
3599 assert field != null :
"column " + id.toString() +
" not found";
3600 targetColumnNames.add(field.getName());
3608 final List<ColumnStrategy> strategies = targetTable.getColumnStrategies();
3609 for (String columnName : targetColumnNames) {
3610 final int i = tableRowType.getFieldNames().
indexOf(columnName);
3612 switch (strategies.get(i)) {
3614 final InitializerExpressionFactory
f =
3615 Util.first(targetTable.unwrap(InitializerExpressionFactory.class),
3616 NullInitializerExpressionFactory.INSTANCE);
3617 expr = f.newColumnDefaultValue(targetTable, i, bb);
3623 expr = bb.nameToNodeMap.get(columnName);
3625 columnExprs.add(expr);
3629 for (
int i = 0; i < targetColumnNames.size(); i++) {
3630 if (columnExprs.get(i) == null) {
3631 columnExprs.remove(i);
3632 targetColumnNames.remove(i);
3640 RelNode sourceRel =
convertSelect(call.getSourceSelect(),
false);
3641 return LogicalTableModify.create(targetTable,
3644 LogicalTableModify.Operation.DELETE,
3651 final SqlValidatorScope scope = validator.getWhereScope(call.getSourceSelect());
3659 final List<String> targetColumnNameList =
new ArrayList<>();
3660 final RelDataType targetRowType = targetTable.getRowType();
3661 for (SqlNode node : call.getTargetColumnList()) {
3662 SqlIdentifier
id = (SqlIdentifier) node;
3663 RelDataTypeField
field = SqlValidatorUtil.getTargetField(
3665 assert field != null :
"column " + id.toString() +
" not found";
3666 targetColumnNameList.add(field.getName());
3669 RelNode sourceRel =
convertSelect(call.getSourceSelect(),
false);
3671 bb.setRoot(sourceRel,
false);
3672 Builder<RexNode> rexNodeSourceExpressionListBuilder = ImmutableList.builder();
3673 for (SqlNode
n : call.getSourceExpressionList()) {
3674 RexNode rn = bb.convertExpression(
n);
3675 rexNodeSourceExpressionListBuilder.add(rn);
3678 return LogicalTableModify.create(targetTable,
3681 LogicalTableModify.Operation.UPDATE,
3682 targetColumnNameList,
3683 rexNodeSourceExpressionListBuilder.build(),
3691 final List<String> targetColumnNameList =
new ArrayList<>();
3692 final RelDataType targetRowType = targetTable.getRowType();
3693 SqlUpdate updateCall = call.getUpdateCall();
3694 if (updateCall != null) {
3695 for (SqlNode targetColumn : updateCall.getTargetColumnList()) {
3696 SqlIdentifier
id = (SqlIdentifier) targetColumn;
3697 RelDataTypeField
field = SqlValidatorUtil.getTargetField(
3699 assert field != null :
"column " + id.toString() +
" not found";
3700 targetColumnNameList.add(field.getName());
3713 RelNode mergeSourceRel =
convertSelect(call.getSourceSelect(),
false);
3717 SqlInsert insertCall = call.getInsertCall();
3718 int nLevel1Exprs = 0;
3719 List<RexNode> level1InsertExprs = null;
3720 List<RexNode> level2InsertExprs = null;
3721 if (insertCall != null) {
3731 level1InsertExprs = ((LogicalProject) insertRel.getInput(0)).getProjects();
3732 if (insertRel.getInput(0).getInput(0) instanceof LogicalProject) {
3734 ((LogicalProject) insertRel.getInput(0).getInput(0)).getProjects();
3736 nLevel1Exprs = level1InsertExprs.size();
3739 LogicalJoin
join = (LogicalJoin) mergeSourceRel.getInput(0);
3740 int nSourceFields = join.getLeft().getRowType().getFieldCount();
3741 final List<RexNode> projects =
new ArrayList<>();
3742 for (
int level1Idx = 0; level1Idx < nLevel1Exprs; level1Idx++) {
3743 if ((level2InsertExprs != null)
3744 && (level1InsertExprs.get(level1Idx) instanceof RexInputRef)) {
3745 int level2Idx = ((RexInputRef) level1InsertExprs.get(level1Idx)).getIndex();
3746 projects.add(level2InsertExprs.get(level2Idx));
3748 projects.add(level1InsertExprs.get(level1Idx));
3751 if (updateCall != null) {
3752 final LogicalProject project = (LogicalProject) mergeSourceRel;
3753 projects.addAll(Util.skip(project.getProjects(), nSourceFields));
3756 relBuilder.push(
join).project(projects);
3758 return LogicalTableModify.create(targetTable,
3761 LogicalTableModify.Operation.MERGE,
3762 targetColumnNameList,
3773 final SqlCall call = bb.getValidator().makeNullaryCall(identifier);
3775 return bb.convertExpression(call);
3780 pv = identifier.names.get(0);
3783 final SqlQualified qualified;
3784 if (bb.
scope != null) {
3785 qualified = bb.scope.fullyQualify(identifier);
3787 qualified = SqlQualified.create(null, 1, null, identifier);
3789 final Pair<RexNode, Map<String, Integer>> e0 = bb.lookupExp(qualified);
3790 RexNode e = e0.left;
3791 for (String
name : qualified.suffix()) {
3792 if (e == e0.left && e0.right != null) {
3793 int i = e0.right.get(
name);
3794 e = rexBuilder.makeFieldAccess(e, i);
3796 final boolean caseSensitive =
true;
3797 if (identifier.isStar() && bb.scope instanceof MatchRecognizeScope) {
3798 e = rexBuilder.makeFieldAccess(e, 0);
3800 e = rexBuilder.makeFieldAccess(e,
name, caseSensitive);
3804 if (e instanceof RexInputRef) {
3808 e = RexPatternFieldRef.of(pv, (RexInputRef) e);
3812 if (e0.left instanceof RexCorrelVariable) {
3813 assert e instanceof RexFieldAccess;
3814 final RexNode prev = bb.mapCorrelateToRex.put(
3815 ((RexCorrelVariable) e0.left).id, (RexFieldAccess) e);
3816 assert prev == null;
3831 RelDataTypeField
field = bb.getRootField(inputRef);
3832 if (field != null) {
3833 return rexBuilder.makeInputRef(field.getType(), inputRef.getIndex());
3847 final List<SqlNode> operands = rowConstructor.getOperandList();
3852 final SqlCall cursorCall = (SqlCall) subQuery.node;
3853 assert cursorCall.operandCount() == 1;
3854 SqlNode query = cursorCall.operand(0);
3855 RelNode converted =
convertQuery(query,
false,
false).rel;
3856 int iCursor = bb.cursors.size();
3857 bb.cursors.add(converted);
3858 subQuery.expr =
new RexInputRef(iCursor, converted.getRowType());
3865 final List<Object> joinList =
new ArrayList<>();
3866 List<SqlNode> lastList =
new ArrayList<>();
3867 for (
int i = 0; i < operands.size(); i++) {
3868 SqlNode operand = operands.get(i);
3869 if (!(operand instanceof SqlCall)) {
3870 lastList.add(operand);
3874 final SqlCall call = (SqlCall) operand;
3875 final RelNode input;
3876 switch (call.getKind()) {
3877 case MULTISET_VALUE_CONSTRUCTOR:
3878 case ARRAY_VALUE_CONSTRUCTOR:
3879 final SqlNodeList list =
3880 new SqlNodeList(call.getOperandList(), call.getParserPosition());
3881 CollectNamespace nss = (CollectNamespace)
validator.getNamespace(call);
3887 public SqlNode getNode() {
3892 RelDataType multisetType = validator.getValidatedNodeType(call);
3893 validator.setValidatedNodeType(list, multisetType.getComponentType());
3896 case MULTISET_QUERY_CONSTRUCTOR:
3897 case ARRAY_QUERY_CONSTRUCTOR:
3902 lastList.add(operand);
3906 if (lastList.size() > 0) {
3907 joinList.add(lastList);
3909 lastList =
new ArrayList<>();
3910 Collect collect =
new Collect(
cluster,
3911 cluster.traitSetOf(Convention.NONE),
3913 validator.deriveAlias(call, i));
3914 joinList.add(collect);
3917 if (joinList.size() == 0) {
3918 joinList.add(lastList);
3921 for (
int i = 0; i < joinList.size(); i++) {
3922 Object o = joinList.get(i);
3923 if (o instanceof List) {
3924 @SuppressWarnings(
"unchecked")
3925 List<SqlNode> projectList = (List<SqlNode>) o;
3926 final List<RexNode> selectList = new ArrayList<>();
3927 final List<String> fieldNameList = new ArrayList<>();
3928 for (
int j = 0; j < projectList.size(); j++) {
3929 SqlNode operand = projectList.get(j);
3930 selectList.add(bb.convertExpression(operand));
3939 fieldNameList.add(SqlUtil.deriveAliasFromOrdinal(j));
3942 relBuilder.push(LogicalValues.createOneRow(
cluster))
3943 .projectNamed(selectList, fieldNameList,
true);
3945 joinList.set(i, relBuilder.build());
3949 RelNode ret = (RelNode) joinList.get(0);
3950 for (
int i = 1; i < joinList.size(); i++) {
3951 RelNode relNode = (RelNode) joinList.get(i);
3952 ret = RelFactories.DEFAULT_JOIN_FACTORY.createJoin(ret,
3964 Blackboard bb, SqlSelect select, List<SqlNode> orderList) {
3965 SqlNodeList selectList = select.getSelectList();
3966 selectList = validator.expandStar(selectList, select,
false);
3968 replaceSubQueries(bb, selectList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
3970 List<String> fieldNames =
new ArrayList<>();
3971 final List<RexNode> exprs =
new ArrayList<>();
3972 final Collection<String> aliases =
new TreeSet<>();
3976 final List<SqlMonotonicity> columnMonotonicityList =
new ArrayList<>();
3977 extraSelectItems(bb, select, exprs, fieldNames, aliases, columnMonotonicityList);
3981 for (SqlNode expr : selectList) {
3983 exprs.add(bb.convertExpression(expr));
3984 fieldNames.add(deriveAlias(expr, aliases, i));
3988 for (SqlNode expr : orderList) {
3990 SqlNode expr2 = validator.expandOrderExpr(select, expr);
3991 exprs.add(bb.convertExpression(expr2));
3992 fieldNames.add(deriveAlias(expr, aliases, i));
3995 fieldNames = SqlValidatorUtil.uniquify(
3996 fieldNames, catalogReader.nameMatcher().isCaseSensitive());
3998 relBuilder.push(
bb.root).projectNamed(exprs, fieldNames,
true);
3999 bb.setRoot(relBuilder.build(),
false);
4001 assert bb.columnMonotonicities.isEmpty();
4002 bb.columnMonotonicities.addAll(columnMonotonicityList);
4003 for (SqlNode selectItem : selectList) {
4004 bb.columnMonotonicities.add(selectItem.getMonotonicity(bb.scope));
4023 List<RexNode> exprList,
4024 List<String> nameList,
4025 Collection<String> aliasList,
4026 List<SqlMonotonicity> columnMonotonicityList) {}
4029 final SqlNode node, Collection<String> aliases,
final int ordinal) {
4030 String alias = validator.deriveAlias(node, ordinal);
4031 if ((alias == null) || aliases.contains(alias)) {
4032 String aliasBase = (alias == null) ?
"EXPR$" : alias;
4033 for (
int j = 0;; j++) {
4034 alias = aliasBase + j;
4035 if (!aliases.contains(alias)) {
4048 return convertQuery(with.body,
false, top);
4055 final SqlValidatorScope scope = validator.getOverScope(values);
4056 assert scope != null;
4057 final Blackboard bb = createBlackboard(scope, null,
false);
4058 convertValuesImpl(bb, values, targetRowType);
4071 Blackboard bb, SqlCall values, RelDataType targetRowType) {
4075 convertRowValues(bb, values, values.getOperandList(),
true, targetRowType);
4076 if (valuesRel != null) {
4077 bb.setRoot(valuesRel,
true);
4081 final List<RelNode> unionRels =
new ArrayList<>();
4082 for (SqlNode rowConstructor1 : values.getOperandList()) {
4083 SqlCall rowConstructor = (SqlCall) rowConstructor1;
4085 replaceSubQueries(tmpBb, rowConstructor, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
4086 final List<Pair<RexNode, String>> exps =
new ArrayList<>();
4087 for (Ord<SqlNode> operand : Ord.zip(rowConstructor.getOperandList())) {
4088 exps.add(Pair.of(tmpBb.convertExpression(operand.e),
4089 validator.deriveAlias(operand.e, operand.i)));
4094 relBuilder.push(in).project(Pair.left(exps), Pair.right(exps)).build());
4097 if (unionRels.size() == 0) {
4098 throw new AssertionError(
"empty values clause");
4099 }
else if (unionRels.size() == 1) {
4100 bb.setRoot(unionRels.get(0),
true);
4102 bb.setRoot(LogicalUnion.create(unionRels,
true),
true);
4112 implements SqlRexContext, SqlVisitor<RexNode>, InitializerContext {
4120 private final Map<CorrelationId, RexFieldAccess> mapCorrelateToRex =
new HashMap<>();
4122 private boolean isPatternVarRef =
false;
4124 final List<RelNode> cursors =
new ArrayList<>();
4130 private final List<SubQuery> subQueryList =
new ArrayList<>();
4148 private final Map<RelNode, Map<Integer, Integer>> mapRootRelToFieldProjection =
4151 private final List<SqlMonotonicity> columnMonotonicities =
new ArrayList<>();
4153 private final List<RelDataTypeField> systemFieldList =
new ArrayList<>();
4156 private final InitializerExpressionFactory initializerExpressionFactory =
4157 new NullInitializerExpressionFactory();
4171 SqlValidatorScope scope, Map<String, RexNode> nameToNodeMap,
boolean top) {
4173 this.nameToNodeMap = nameToNodeMap;
4179 if (null == scope) {
4182 return scope.getNode();
4183 }
catch (Exception e) {
4189 this.isPatternVarRef = isVarRef;
4192 public RexNode
register(RelNode rel, JoinRelType joinType) {
4193 return register(rel, joinType, null);
4205 public RexNode
register(RelNode rel, JoinRelType joinType, List<RexNode> leftKeys) {
4206 assert joinType != null;
4208 assert leftKeys == null;
4209 setRoot(rel,
false);
4210 return rexBuilder.makeRangeReference(root.getRowType(), 0,
false);
4213 final RexNode joinCond;
4214 final int origLeftInputCount = root.getRowType().getFieldCount();
4215 if (leftKeys != null) {
4216 List<RexNode> newLeftInputExprs =
new ArrayList<>();
4217 for (
int i = 0; i < origLeftInputCount; i++) {
4218 newLeftInputExprs.add(rexBuilder.makeInputRef(
root, i));
4221 final List<Integer> leftJoinKeys =
new ArrayList<>();
4222 for (RexNode leftKey : leftKeys) {
4223 int index = newLeftInputExprs.indexOf(leftKey);
4224 if (index < 0 || joinType == JoinRelType.LEFT) {
4225 index = newLeftInputExprs.size();
4226 newLeftInputExprs.add(leftKey);
4228 leftJoinKeys.add(index);
4231 RelNode newLeftInput = relBuilder.push(
root).project(newLeftInputExprs).build();
4234 if (mapRootRelToFieldProjection.containsKey(
root)) {
4235 mapRootRelToFieldProjection.put(
4236 newLeftInput, mapRootRelToFieldProjection.get(
root));
4239 setRoot(newLeftInput,
false);
4242 final int rightOffset = root.getRowType().getFieldCount()
4243 - newLeftInput.getRowType().getFieldCount();
4244 final List<Integer> rightKeys =
4245 Util.range(rightOffset, rightOffset + leftKeys.size());
4247 joinCond = RelOptUtil.createEquiJoinCondition(
4248 newLeftInput, leftJoinKeys, rel, rightKeys, rexBuilder);
4250 joinCond = rexBuilder.makeLiteral(
true);
4253 int leftFieldCount = root.getRowType().getFieldCount();
4254 final RelNode
join = createJoin(
this,
root, rel, joinCond, joinType);
4256 setRoot(join,
false);
4258 if (leftKeys != null && joinType == JoinRelType.LEFT) {
4259 final int leftKeyCount = leftKeys.size();
4260 int rightFieldLength = rel.getRowType().getFieldCount();
4261 assert leftKeyCount == rightFieldLength - 1;
4263 final int rexRangeRefLength = leftKeyCount + rightFieldLength;
4264 RelDataType returnType = typeFactory.createStructType(
4265 new AbstractList<Map.Entry<String, RelDataType>>() {
4266 public Map.Entry<String, RelDataType>
get(
int index) {
4267 return join.getRowType().getFieldList().get(
4268 origLeftInputCount + index);
4272 return rexRangeRefLength;
4276 return rexBuilder.makeRangeReference(returnType, origLeftInputCount,
false);
4278 return rexBuilder.makeRangeReference(
4279 rel.getRowType(), leftFieldCount, joinType.generatesNullsOnRight());
4295 setRoot(Collections.singletonList(root),
root, root instanceof LogicalJoin);
4297 leaves.put(
root, root.getRowType().getFieldCount());
4299 this.columnMonotonicities.clear();
4302 private void setRoot(List<RelNode> inputs, RelNode
root,
boolean hasSystemFields) {
4303 this.inputs = inputs;
4305 this.systemFieldList.clear();
4306 if (hasSystemFields) {
4307 this.systemFieldList.addAll(getSystemFields());
4324 setRoot(inputs, null,
false);
4333 Pair<RexNode, Map<String, Integer>>
lookupExp(SqlQualified qualified) {
4334 if (nameToNodeMap != null && qualified.prefixLength == 1) {
4335 RexNode node = nameToNodeMap.get(qualified.identifier.names.get(0));
4337 throw new AssertionError(
"Unknown identifier '" + qualified.identifier
4338 +
"' encountered while expanding expression");
4340 return Pair.of(node, null);
4342 final SqlNameMatcher nameMatcher =
4343 scope.getValidator().getCatalogReader().nameMatcher();
4344 final SqlValidatorScope.ResolvedImpl resolved =
4345 new SqlValidatorScope.ResolvedImpl();
4346 scope.resolve(qualified.prefix(), nameMatcher,
false, resolved);
4347 if (!(resolved.count() == 1)) {
4350 final SqlValidatorScope.Resolve resolve = resolved.only();
4351 final RelDataType rowType = resolve.rowType();
4356 final SqlValidatorScope ancestorScope = resolve.scope;
4357 boolean isParent = ancestorScope != scope;
4358 if ((inputs != null) && !isParent) {
4359 final LookupContext rels =
4360 new LookupContext(
this, inputs, systemFieldList.size());
4361 final RexNode node = lookup(resolve.path.steps().get(0).i, rels);
4365 final Map<String, Integer> fieldOffsets =
new HashMap<>();
4366 for (RelDataTypeField
f : resolve.rowType().getFieldList()) {
4367 if (!fieldOffsets.containsKey(
f.getName())) {
4368 fieldOffsets.put(f.getName(),
f.getIndex());
4371 final Map<String, Integer> map = ImmutableMap.copyOf(fieldOffsets);
4372 return Pair.of(node, map);
4381 final CorrelationId correlId = cluster.createCorrel();
4382 mapCorrelToDeferred.put(correlId, lookup);
4383 if (resolve.path.steps().get(0).i < 0) {
4384 return Pair.of(rexBuilder.makeCorrel(rowType, correlId), null);
4386 final RelDataTypeFactory.Builder builder = typeFactory.builder();
4387 final ListScope ancestorScope1 = (ListScope) resolve.scope;
4388 final ImmutableMap.Builder<String,
Integer> fields = ImmutableMap.builder();
4391 for (SqlValidatorNamespace c : ancestorScope1.getChildren()) {
4392 builder.addAll(c.getRowType().getFieldList());
4393 if (i == resolve.path.steps().get(0).i) {
4394 for (RelDataTypeField
field : c.getRowType().getFieldList()) {
4395 fields.put(field.getName(),
field.getIndex() + offset);
4399 offset += c.getRowType().getFieldCount();
4401 final RexNode c = rexBuilder.makeCorrel(builder.uniquify().build(), correlId);
4402 return Pair.of(c, fields.build());
4411 RexNode lookup(
int offset, LookupContext lookupContext) {
4412 Pair<RelNode, Integer> pair = lookupContext.findRel(offset);
4413 return rexBuilder.makeRangeReference(pair.left.getRowType(), pair.right,
false);
4416 RelDataTypeField getRootField(RexInputRef inputRef) {
4417 if (inputs == null) {
4420 int fieldOffset = inputRef.getIndex();
4421 for (RelNode input : inputs) {
4422 RelDataType rowType = input.getRowType();
4423 if (fieldOffset < rowType.getFieldCount()) {
4424 return rowType.getFieldList().
get(fieldOffset);
4426 fieldOffset -= rowType.getFieldCount();
4431 public void flatten(List<RelNode> rels,
4432 int systemFieldCount,
4434 List<Pair<RelNode, Integer>> relOffsetList) {
4435 for (RelNode rel : rels) {
4436 if (leaves.containsKey(rel)) {
4437 relOffsetList.add(Pair.of(rel, start[0]));
4438 start[0] += leaves.get(rel);
4439 }
else if (rel instanceof LogicalMatch) {
4440 relOffsetList.add(Pair.of(rel, start[0]));
4441 start[0] += rel.getRowType().getFieldCount();
4443 if (rel instanceof LogicalJoin || rel instanceof LogicalAggregate) {
4444 start[0] += systemFieldCount;
4446 flatten(rel.getInputs(), systemFieldCount, start, relOffsetList);
4451 void registerSubQuery(SqlNode node, RelOptUtil.Logic logic) {
4452 for (SubQuery subQuery : subQueryList) {
4455 if (node == subQuery.node) {
4459 subQueryList.add(
new SubQuery(node, logic));
4462 SubQuery getSubQuery(SqlNode expr) {
4463 for (SubQuery subQuery : subQueryList) {
4466 if (expr == subQuery.node) {
4474 ImmutableList<RelNode> retrieveCursors() {
4476 return ImmutableList.copyOf(cursors);
4482 public RexNode convertExpression(SqlNode expr) {
4486 final SqlNode expandedGroupExpr = validator.expand(expr, scope);
4487 final int ref = agg.lookupGroupExpr(expandedGroupExpr);
4489 return rexBuilder.makeInputRef(
root, ref);
4491 if (expr instanceof SqlCall) {
4492 final RexNode rex = agg.lookupAggregates((SqlCall) expr);
4501 RexNode rex = convertExtendedExpression(expr,
this);
4508 final SqlKind kind = expr.getKind();
4509 final SubQuery subQuery;
4510 boolean isExpand = config.getExpandPredicate().test(getTopNode(), expr);
4513 final SqlNode query;
4520 call = (SqlCall) expr;
4521 query = call.operand(1);
4522 if (!(query instanceof SqlNodeList)) {
4523 root = convertQueryRecursive(query,
false, null);
4524 final SqlNode operand = call.operand(0);
4525 List<SqlNode> nodes;
4526 switch (operand.getKind()) {
4528 nodes = ((SqlCall) operand).getOperandList();
4531 nodes = ImmutableList.of(operand);
4533 final ImmutableList.Builder<RexNode> builder = ImmutableList.builder();
4534 for (SqlNode node : nodes) {
4535 builder.add(convertExpression(node));
4537 final ImmutableList<RexNode> list = builder.build();
4540 return RexSubQuery.in(root.rel, list);
4542 return rexBuilder.makeCall(
4543 SqlStdOperatorTable.NOT, RexSubQuery.in(root.rel, list));
4545 return RexSubQuery.some(
4546 root.rel, list, (SqlQuantifyOperator) call.getOperator());
4548 return rexBuilder.makeCall(SqlStdOperatorTable.NOT,
4549 RexSubQuery.some(root.rel,
4551 negate((SqlQuantifyOperator) call.getOperator())));
4553 throw new AssertionError(kind);
4559 call = (SqlCall) expr;
4560 query = Iterables.getOnlyElement(call.getOperandList());
4561 root = convertQueryRecursive(query,
false, null);
4562 RelNode rel = root.rel;
4563 while (rel instanceof Project
4564 || rel instanceof Sort && ((Sort) rel).fetch == null
4565 && ((Sort) rel).offset == null) {
4566 rel = ((SingleRel) rel).getInput();
4568 return RexSubQuery.exists(rel);
4571 call = (SqlCall) expr;
4572 query = Iterables.getOnlyElement(call.getOperandList());
4573 root = convertQueryRecursive(query,
false, null);
4574 return RexSubQuery.scalar(root.rel);
4582 throw new RuntimeException(kind +
" is only supported if expand = false");
4588 subQuery = Objects.requireNonNull(getSubQuery(expr));
4589 rex = Objects.requireNonNull(subQuery.expr);
4590 return StandardConvertletTable.castToValidatedType(
4591 expr, rex, validator, rexBuilder);
4596 subQuery = getSubQuery(expr);
4597 assert subQuery != null;
4598 rex = subQuery.expr;
4599 assert rex != null :
"rex != null";
4601 if (((kind == SqlKind.SCALAR_QUERY) || (kind == SqlKind.EXISTS))
4602 && isConvertedSubq(rex)) {
4609 RexNode fieldAccess =
4610 rexBuilder.makeFieldAccess(rex, rex.getType().getFieldCount() - 1);
4615 if (fieldAccess.getType().isNullable() && kind == SqlKind.EXISTS) {
4617 rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, fieldAccess);
4622 return convertOver(
this, expr);
4629 rex = expr.accept(
this);
4630 return Objects.requireNonNull(rex);
4637 public RexFieldCollation convertSortExpression(SqlNode expr,
4638 RelFieldCollation.Direction direction,
4639 RelFieldCollation.NullDirection nullDirection) {
4640 switch (expr.getKind()) {
4642 return convertSortExpression(((SqlCall) expr).operand(0),
4643 RelFieldCollation.Direction.DESCENDING,
4646 return convertSortExpression(((SqlCall) expr).operand(0),
4648 RelFieldCollation.NullDirection.LAST);
4650 return convertSortExpression(((SqlCall) expr).operand(0),
4652 RelFieldCollation.NullDirection.FIRST);
4654 final Set<SqlKind> flags = EnumSet.noneOf(SqlKind.class);
4655 switch (direction) {
4657 flags.add(SqlKind.DESCENDING);
4659 switch (nullDirection) {
4661 final RelFieldCollation.NullDirection nullDefaultDirection =
4662 validator.config().defaultNullCollation().last(desc(direction))
4663 ? RelFieldCollation.NullDirection.LAST
4664 : RelFieldCollation.NullDirection.FIRST;
4665 if (nullDefaultDirection != direction.defaultNullDirection()) {
4666 SqlKind nullDirectionSqlKind =
4667 validator.config().defaultNullCollation().last(desc(direction))
4668 ? SqlKind.NULLS_LAST
4669 : SqlKind.NULLS_FIRST;
4670 flags.add(nullDirectionSqlKind);
4674 flags.add(SqlKind.NULLS_FIRST);
4677 flags.add(SqlKind.NULLS_LAST);
4680 return new RexFieldCollation(convertExpression(expr), flags);
4692 private boolean isConvertedSubq(RexNode rex) {
4693 if ((rex instanceof
RexLiteral) || (rex instanceof RexDynamicParam)) {
4696 if (rex instanceof RexCall) {
4697 RexCall call = (RexCall) rex;
4698 if (call.getOperator() == SqlStdOperatorTable.CAST) {
4699 RexNode operand = call.getOperands().
get(0);
4700 if (operand instanceof RexLiteral) {
4708 public int getGroupCount() {
4710 return agg.groupExprs.size();
4712 if (window != null) {
4713 return window.isAlwaysNonEmpty() ? 1 : 0;
4718 public RexBuilder getRexBuilder() {
4722 public SqlNode validateExpression(RelDataType rowType, SqlNode expr) {
4723 return SqlValidatorUtil
4724 .validateExprWithRowType(catalogReader.nameMatcher().isCaseSensitive(),
4732 public RexRangeRef getSubQueryExpr(SqlCall call) {
4733 final SubQuery subQuery = getSubQuery(call);
4734 assert subQuery != null;
4735 return (RexRangeRef) subQuery.expr;
4738 public RelDataTypeFactory getTypeFactory() {
4742 public InitializerExpressionFactory getInitializerExpressionFactory() {
4743 return initializerExpressionFactory;
4746 public SqlValidator getValidator() {
4750 public RexNode convertLiteral(SqlLiteral literal) {
4751 return exprConverter.convertLiteral(
this, literal);
4754 public RexNode convertInterval(SqlIntervalQualifier intervalQualifier) {
4755 return exprConverter.convertInterval(
this, intervalQualifier);
4758 public RexNode visit(SqlLiteral literal) {
4759 return exprConverter.convertLiteral(
this, literal);
4762 public RexNode visit(SqlCall call) {
4764 final SqlOperator op = call.getOperator();
4766 && (op.isAggregator() || op.getKind() == SqlKind.FILTER
4767 || op.getKind() == SqlKind.WITHIN_GROUP)) {
4768 return agg.lookupAggregates(call);
4771 SqlCall permutedCall =
4772 new SqlCallBinding(validator, scope, call).permutedCall();
4773 if (permutedCall.getOperator() instanceof ExtTableFunction) {
4774 ExtTableFunction tf =
4775 (ExtTableFunction) permutedCall.getOperator();
4776 if (tf.supportsDefaultArguments()
4777 && permutedCall.getOperandList().stream().anyMatch(
4778 op -> op.getKind() == SqlKind.DEFAULT)) {
4779 permutedCall = tf.rewriteCallWithDefaultArguments(permutedCall);
4782 return exprConverter.convertCall(
this, permutedCall);
4785 public RexNode visit(SqlNodeList nodeList) {
4786 throw new UnsupportedOperationException();
4789 public RexNode visit(SqlIdentifier
id) {
4790 return convertIdentifier(
this,
id);
4793 public RexNode visit(SqlDataTypeSpec
type) {
4794 throw new UnsupportedOperationException();
4797 public RexNode visit(SqlDynamicParam param) {
4798 return convertDynamicParam(param);
4801 public RexNode visit(SqlIntervalQualifier intervalQualifier) {
4802 return convertInterval(intervalQualifier);
4805 public List<SqlMonotonicity> getColumnMonotonicities() {
4806 return columnMonotonicities;
4810 private SqlQuantifyOperator
negate(SqlQuantifyOperator
operator) {
4812 return SqlStdOperatorTable.some(operator.comparisonKind.negateNullSafe());
4822 this.originalRelName = originalRelName;
4826 return (RexFieldAccess) bb.mapCorrelateToRex.get(
name);
4830 return originalRelName;
4845 boolean isExplain) {
4846 throw new IllegalArgumentException();
4869 protected class AggConverter
implements SqlVisitor<Void> {
4870 private final Blackboard bb;
4871 public final AggregatingSelectScope aggregatingSelectScope;
4873 private final Map<String, String> nameMap =
new HashMap<>();
4878 private final SqlNodeList groupExprs =
new SqlNodeList(SqlParserPos.ZERO);
4883 private final Map<SqlNode, Ord<AuxiliaryConverter>> auxiliaryGroupExprs =
4893 private final List<Pair<RexNode, String>> convertedInputExprs =
new ArrayList<>();
4901 private final List<AggregateCall> aggCalls =
new ArrayList<>();
4902 private final Map<SqlNode, RexNode> aggMapping =
new HashMap<>();
4903 private final Map<AggregateCall, RexNode> aggCallMapping =
new HashMap<>();
4906 private boolean inOver =
false;
4918 public AggConverter(Blackboard bb, SqlSelect select) {
4920 this.aggregatingSelectScope =
4921 (AggregatingSelectScope) bb.getValidator().getSelectScope(select);
4925 final SqlNodeList selectList = select.getSelectList();
4926 for (
int i = 0; i < selectList.size(); i++) {
4927 SqlNode selectItem = selectList.get(i);
4929 if (SqlUtil.isCallTo(selectItem, SqlStdOperatorTable.AS)) {
4930 final SqlCall call = (SqlCall) selectItem;
4931 selectItem = call.operand(0);
4935 name = validator.deriveAlias(selectItem, i);
4937 nameMap.put(selectItem.toString(), name);
4941 public int addGroupExpr(SqlNode expr) {
4942 int ref = lookupGroupExpr(expr);
4946 final int index = groupExprs.size();
4947 groupExprs.add(expr);
4948 String
name = nameMap.get(expr.toString());
4949 RexNode convExpr = bb.convertExpression(expr);
4950 addExpr(convExpr,
name);
4952 if (expr instanceof SqlCall) {
4953 SqlCall call = (SqlCall) expr;
4954 for (Pair<SqlNode, AuxiliaryConverter> p :
4955 SqlStdOperatorTable.convertGroupToAuxiliaryCalls(call)) {
4956 addAuxiliaryGroupExpr(p.left, index, p.right);
4963 void addAuxiliaryGroupExpr(SqlNode node,
int index, AuxiliaryConverter converter) {
4964 for (SqlNode node2 : auxiliaryGroupExprs.keySet()) {
4965 if (node2.equalsDeep(node, Litmus.IGNORE)) {
4969 auxiliaryGroupExprs.put(node, Ord.of(index, converter));
4978 private void addExpr(RexNode expr, String
name) {
4979 if ((name == null) && (expr instanceof RexInputRef)) {
4980 final int i = ((RexInputRef) expr).getIndex();
4981 name = bb.root.getRowType().getFieldList().get(i).getName();
4983 if (Pair.right(convertedInputExprs).contains(
name)) {
4988 convertedInputExprs.add(Pair.of(expr,
name));
4991 public Void visit(SqlIdentifier
id) {
4995 public Void visit(SqlNodeList nodeList) {
4996 for (
int i = 0; i < nodeList.size(); i++) {
4997 nodeList.get(i).accept(
this);
5002 public Void visit(SqlLiteral lit) {
5006 public Void visit(SqlDataTypeSpec
type) {
5010 public Void visit(SqlDynamicParam param) {
5014 public Void visit(SqlIntervalQualifier intervalQualifier) {
5018 public Void visit(SqlCall call) {
5019 switch (call.getKind()) {
5029 final boolean prevInOver = inOver;
5032 if (call.getOperator().getKind() == SqlKind.OVER) {
5034 List<SqlNode> operandList = call.getOperandList();
5035 assert operandList.size() == 2;
5040 operandList.get(0).accept(
this);
5044 operandList.get(1).accept(
this);
5050 if (call.getOperator().isAggregator()) {
5060 for (SqlNode operand : call.getOperandList()) {
5062 if (operand != null) {
5063 operand.accept(
this);
5067 inOver = prevInOver;
5071 private void translateAgg(SqlCall call) {
5072 translateAgg(call, null, null,
false, call);
5075 private void translateAgg(SqlCall call,
5077 SqlNodeList orderList,
5078 boolean ignoreNulls,
5079 SqlCall outerCall) {
5080 assert bb.agg ==
this;
5081 assert outerCall != null;
5082 switch (call.getKind()) {
5084 assert filter == null;
5086 call.operand(0), call.operand(1), orderList, ignoreNulls, outerCall);
5089 assert orderList == null;
5090 translateAgg(call.operand(0), filter, call.operand(1), ignoreNulls, outerCall);
5096 translateAgg(call.operand(0), filter, orderList, ignoreNulls, outerCall);
5099 final List<Integer>
args =
new ArrayList<>();
5101 final List<RelDataType> argTypes = call.getOperator() instanceof SqlCountAggFunction
5102 ?
new ArrayList<>(call.getOperandList().size())
5107 for (SqlNode operand : call.getOperandList()) {
5109 if (operand instanceof SqlIdentifier) {
5110 SqlIdentifier
id = (SqlIdentifier) operand;
5112 assert call.operandCount() == 1;
5113 assert args.isEmpty();
5117 RexNode convertedExpr = bb.convertExpression(operand);
5118 assert convertedExpr != null;
5119 if (argTypes != null) {
5120 argTypes.add(convertedExpr.getType());
5122 args.add(lookupOrCreateGroupExpr(convertedExpr));
5125 if (filter != null) {
5126 RexNode convertedExpr = bb.convertExpression(filter);
5127 assert convertedExpr != null;
5128 if (convertedExpr.getType().isNullable()) {
5130 rexBuilder.makeCall(SqlStdOperatorTable.IS_TRUE, convertedExpr);
5132 filterArg = lookupOrCreateGroupExpr(convertedExpr);
5139 SqlAggFunction aggFunction = (SqlAggFunction) call.getOperator();
5140 final RelDataType
type = validator.deriveType(bb.scope, call);
5141 boolean distinct =
false;
5142 SqlLiteral quantifier = call.getFunctionQuantifier();
5143 if ((null != quantifier) && (quantifier.getValue() == SqlSelectKeyword.DISTINCT)) {
5146 boolean approximate =
false;
5147 if (aggFunction == SqlStdOperatorTable.APPROX_COUNT_DISTINCT) {
5148 aggFunction = SqlStdOperatorTable.COUNT;
5152 final RelCollation collation;
5153 if (orderList == null || orderList.size() == 0) {
5154 collation = RelCollations.EMPTY;
5156 collation = RelCollations.of(
5160 -> bb.convertSortExpression(order,
5161 RelFieldCollation.Direction.ASCENDING,
5162 RelFieldCollation.NullDirection.UNSPECIFIED))
5164 ->
new RelFieldCollation(
5165 lookupOrCreateGroupExpr(fieldCollation.left),
5166 fieldCollation.getDirection(),
5167 fieldCollation.getNullDirection()))
5168 .collect(Collectors.toList()));
5170 final AggregateCall aggCall = AggregateCall.create(aggFunction,
5178 nameMap.get(outerCall.toString()));
5179 RexNode rex = rexBuilder.addAggCall(
5180 aggCall, groupExprs.size(), aggCalls, aggCallMapping, argTypes);
5181 aggMapping.put(outerCall, rex);
5184 private int lookupOrCreateGroupExpr(RexNode expr) {
5186 for (RexNode convertedInputExpr : Pair.left(convertedInputExprs)) {
5187 if (expr.equals(convertedInputExpr)) {
5194 addExpr(expr, null);
5202 public int lookupGroupExpr(SqlNode expr) {
5203 for (
int i = 0; i < groupExprs.size(); i++) {
5204 SqlNode groupExpr = groupExprs.get(i);
5205 if (expr.equalsDeep(groupExpr, Litmus.IGNORE)) {
5212 public RexNode lookupAggregates(SqlCall call) {
5214 assert bb.agg ==
this;
5216 for (Map.Entry<SqlNode, Ord<AuxiliaryConverter>> e :
5217 auxiliaryGroupExprs.entrySet()) {
5218 if (call.equalsDeep(e.getKey(), Litmus.IGNORE)) {
5219 AuxiliaryConverter converter = e.getValue().e;
5220 final int groupOrdinal = e.getValue().i;
5221 return converter.convert(rexBuilder,
5222 convertedInputExprs.get(groupOrdinal).left,
5223 rexBuilder.makeInputRef(bb.root, groupOrdinal));
5227 return aggMapping.get(call);
5230 public List<Pair<RexNode, String>> getPreExprs() {
5231 return convertedInputExprs;
5234 public List<AggregateCall> getAggCalls() {
5238 private boolean containsGroupId() {
5239 return aggCalls.stream().anyMatch(
5240 agg -> agg.getAggregation().kind == SqlKind.GROUP_ID);
5243 public RelDataTypeFactory getTypeFactory() {
5251 private static class LookupContext {
5252 private final List<Pair<RelNode, Integer>> relOffsetList =
new ArrayList<>();
5261 LookupContext(Blackboard bb, List<RelNode> rels,
int systemFieldCount) {
5262 bb.flatten(rels, systemFieldCount,
new int[] {0}, relOffsetList);
5277 Pair<RelNode, Integer> findRel(
int offset) {
5278 return relOffsetList.get(offset);
5314 private class HistogramShuttle
extends RexShuttle {
5319 static final boolean ENABLE_HISTOGRAM_AGG =
false;
5321 private final List<RexNode> partitionKeys;
5322 private final ImmutableList<RexFieldCollation> orderKeys;
5323 private final RexWindowBound lowerBound;
5324 private final RexWindowBound upperBound;
5325 private final boolean rows;
5326 private final boolean allowPartial;
5327 private final boolean distinct;
5328 private final boolean ignoreNulls;
5330 HistogramShuttle(List<RexNode> partitionKeys,
5331 ImmutableList<RexFieldCollation> orderKeys,
5332 RexWindowBound lowerBound,
5333 RexWindowBound upperBound,
5335 boolean allowPartial,
5337 boolean ignoreNulls) {
5338 this.partitionKeys = partitionKeys;
5339 this.orderKeys = orderKeys;
5340 this.lowerBound = lowerBound;
5341 this.upperBound = upperBound;
5343 this.allowPartial = allowPartial;
5344 this.distinct = distinct;
5345 this.ignoreNulls = ignoreNulls;
5348 public RexNode visitCall(RexCall call) {
5349 final SqlOperator op = call.getOperator();
5350 if (!(op instanceof SqlAggFunction)) {
5351 return super.visitCall(call);
5353 final SqlAggFunction aggOp = (SqlAggFunction) op;
5354 final RelDataType type = call.getType();
5355 List<RexNode> exprs = call.getOperands();
5357 SqlFunction histogramOp = !ENABLE_HISTOGRAM_AGG ? null : getHistogramOp(aggOp);
5359 if (histogramOp != null) {
5360 final RelDataType histogramType = computeHistogramType(type);
5365 boolean reinterpretCast = type.getSqlTypeName() == SqlTypeName.DECIMAL;
5369 if (histogramType != type) {
5370 exprs =
new ArrayList<>(exprs);
5372 reinterpretCast ? rexBuilder.makeReinterpretCast(
5373 histogramType, exprs.get(0), rexBuilder.makeLiteral(
false))
5374 : rexBuilder.makeCast(histogramType, exprs.get(0)));
5377 RexCallBinding bind =
new RexCallBinding(rexBuilder.getTypeFactory(),
5378 SqlStdOperatorTable.HISTOGRAM_AGG,
5380 ImmutableList.of());
5382 RexNode over = rexBuilder.makeOver(
5383 SqlStdOperatorTable.HISTOGRAM_AGG.inferReturnType(bind),
5384 SqlStdOperatorTable.HISTOGRAM_AGG,
5396 RexNode histogramCall =
5397 rexBuilder.makeCall(histogramType, histogramOp, ImmutableList.of(over));
5401 if (histogramType != type) {
5402 if (reinterpretCast) {
5403 histogramCall = rexBuilder.makeReinterpretCast(
5404 type, histogramCall, rexBuilder.makeLiteral(
false));
5406 histogramCall = rexBuilder.makeCast(
type, histogramCall);
5410 return histogramCall;
5412 boolean needSum0 = aggOp == SqlStdOperatorTable.SUM && type.isNullable();
5413 SqlAggFunction aggOpToUse = needSum0 ? SqlStdOperatorTable.SUM0 : aggOp;
5414 return rexBuilder.makeOver(
type,
5440 SqlFunction getHistogramOp(SqlAggFunction aggFunction) {
5441 if (aggFunction == SqlStdOperatorTable.MIN) {
5442 return SqlStdOperatorTable.HISTOGRAM_MIN;
5443 }
else if (aggFunction == SqlStdOperatorTable.MAX) {
5444 return SqlStdOperatorTable.HISTOGRAM_MAX;
5445 }
else if (aggFunction == SqlStdOperatorTable.FIRST_VALUE) {
5446 return SqlStdOperatorTable.HISTOGRAM_FIRST_VALUE;
5447 }
else if (aggFunction == SqlStdOperatorTable.LAST_VALUE) {
5448 return SqlStdOperatorTable.HISTOGRAM_LAST_VALUE;
5458 private RelDataType computeHistogramType(RelDataType type) {
5459 if (SqlTypeUtil.isExactNumeric(type)
5460 && type.getSqlTypeName() != SqlTypeName.BIGINT) {
5461 return typeFactory.createSqlType(SqlTypeName.BIGINT);
5462 }
else if (SqlTypeUtil.isApproximateNumeric(type)
5463 && type.getSqlTypeName() != SqlTypeName.DOUBLE) {
5464 return typeFactory.createSqlType(SqlTypeName.DOUBLE);
5474 private static class SubQuery {
5476 final RelOptUtil.Logic logic;
5479 private SubQuery(SqlNode node, RelOptUtil.Logic logic) {
5488 private static class AggregateFinder
extends SqlBasicVisitor<Void> {
5489 final SqlNodeList list =
new SqlNodeList(SqlParserPos.ZERO);
5490 final SqlNodeList filterList =
new SqlNodeList(SqlParserPos.ZERO);
5491 final SqlNodeList orderList =
new SqlNodeList(SqlParserPos.ZERO);
5494 public Void visit(SqlCall call) {
5497 if (call.getOperator().getKind() == SqlKind.OVER) {
5501 if (call.getOperator().getKind() == SqlKind.FILTER) {
5505 final SqlNode aggCall = call.getOperandList().
get(0);
5506 final SqlNode whereCall = call.getOperandList().
get(1);
5508 filterList.add(whereCall);
5512 if (call.getOperator().getKind() == SqlKind.WITHIN_GROUP) {
5516 final SqlNode aggCall = call.getOperandList().
get(0);
5517 final SqlNodeList orderList = (SqlNodeList) call.getOperandList().get(1);
5519 orderList.getList().forEach(this.orderList::add);
5523 if (call.getOperator().isAggregator()) {
5530 if (call instanceof SqlSelect) {
5534 return call.getOperator().acceptCall(
this, call);
5541 private static class CorrelationUse {
5542 private final CorrelationId id;
5543 private final ImmutableBitSet requiredColumns;
5545 private final RelNode r;
5547 CorrelationUse(CorrelationId
id, ImmutableBitSet requiredColumns, RelNode r) {
5549 this.requiredColumns = requiredColumns;
5555 public static ConfigBuilder configBuilder() {
5556 return new ConfigBuilder();
5566 public interface Config {
5568 Config
DEFAULT = configBuilder().build();
5574 boolean isDecorrelationEnabled();
5580 boolean isTrimUnusedFields();
5587 boolean isCreateValuesRel();
5593 boolean isExplain();
5610 int getInSubQueryThreshold();
5616 RelBuilderFactory getRelBuilderFactory();
5622 UnaryOperator<RelBuilder.Config> getRelBuilderConfigTransform();
5628 HintStrategyTable getHintStrategyTable();
5636 BiPredicate<SqlNode, SqlNode> getExpandPredicate();
5640 public static class ConfigBuilder {
5641 private boolean decorrelationEnabled =
true;
5642 private boolean trimUnusedFields =
false;
5643 private boolean createValuesRel =
true;
5644 private boolean explain;
5645 private boolean expand =
true;
5646 private int inSubQueryThreshold = DEFAULT_IN_SUB_QUERY_THRESHOLD;
5647 private UnaryOperator<RelBuilder.Config> relBuilderConfigTransform =
5648 c -> c.withPushJoinCondition(
true);
5649 private RelBuilderFactory relBuilderFactory = RelFactories.LOGICAL_BUILDER;
5650 private HintStrategyTable hintStrategyTable = HintStrategyTable.EMPTY;
5654 private BiPredicate<SqlNode, SqlNode> expandPredicate;
5657 private ConfigBuilder() {}
5660 public ConfigBuilder withConfig(Config config) {
5661 this.decorrelationEnabled = config.isDecorrelationEnabled();
5662 this.trimUnusedFields = config.isTrimUnusedFields();
5663 this.createValuesRel = config.isCreateValuesRel();
5664 this.explain = config.isExplain();
5665 this.expand = config.isExpand();
5666 this.inSubQueryThreshold = config.getInSubQueryThreshold();
5667 this.relBuilderConfigTransform = config.getRelBuilderConfigTransform();
5668 this.relBuilderFactory = config.getRelBuilderFactory();
5669 this.hintStrategyTable = config.getHintStrategyTable();
5672 if (!(config.getExpandPredicate() instanceof ConfigImpl.DefaultExpandPredicate)) {
5673 this.expandPredicate = config.getExpandPredicate();
5679 public ConfigBuilder withDecorrelationEnabled(
boolean enabled) {
5680 this.decorrelationEnabled = enabled;
5684 public ConfigBuilder withTrimUnusedFields(
boolean trimUnusedFields) {
5685 this.trimUnusedFields = trimUnusedFields;
5689 public ConfigBuilder withCreateValuesRel(
boolean createValuesRel) {
5690 this.createValuesRel = createValuesRel;
5694 public ConfigBuilder withExplain(
boolean explain) {
5695 this.explain = explain;
5699 public ConfigBuilder withExpand(
boolean expand) {
5700 this.expand = expand;
5704 public ConfigBuilder withExpandPredicate(BiPredicate<SqlNode, SqlNode> predicate) {
5705 this.expandPredicate = predicate;
5710 public ConfigBuilder withPushJoinCondition(
boolean pushJoinCondition) {
5711 return withRelBuilderConfigTransform(Util.andThen(relBuilderConfigTransform,
5712 c -> c.withPushJoinCondition(pushJoinCondition)));
5716 public ConfigBuilder withInSubqueryThreshold(
int inSubQueryThreshold) {
5717 return withInSubQueryThreshold(inSubQueryThreshold);
5720 public ConfigBuilder withInSubQueryThreshold(
int inSubQueryThreshold) {
5721 this.inSubQueryThreshold = inSubQueryThreshold;
5725 public ConfigBuilder withRelBuilderConfigTransform(
5726 UnaryOperator<RelBuilder.Config> relBuilderConfigTransform) {
5727 this.relBuilderConfigTransform = relBuilderConfigTransform;
5731 public ConfigBuilder withRelBuilderFactory(RelBuilderFactory relBuilderFactory) {
5732 this.relBuilderFactory = relBuilderFactory;
5736 public ConfigBuilder withHintStrategyTable(HintStrategyTable hintStrategyTable) {
5737 this.hintStrategyTable = hintStrategyTable;
5742 public Config build() {
5743 return new ConfigImpl(decorrelationEnabled,
5749 inSubQueryThreshold,
5750 relBuilderConfigTransform,
5760 private static class ConfigImpl
implements Config {
5761 private final boolean decorrelationEnabled;
5762 private final boolean trimUnusedFields;
5763 private final boolean createValuesRel;
5764 private final boolean explain;
5765 private final boolean expand;
5766 private final int inSubQueryThreshold;
5767 private final UnaryOperator<RelBuilder.Config> relBuilderConfigTransform;
5768 private final RelBuilderFactory relBuilderFactory;
5769 private final HintStrategyTable hintStrategyTable;
5771 private final BiPredicate<SqlNode, SqlNode> expandPredicate;
5774 private class DefaultExpandPredicate
implements BiPredicate<SqlNode, SqlNode> {
5776 public boolean test(SqlNode t, SqlNode u) {
5783 private ConfigImpl(
boolean decorrelationEnabled,
5784 boolean trimUnusedFields,
5785 boolean createValuesRel,
5789 BiPredicate<SqlNode, SqlNode> expandPredicate,
5791 int inSubQueryThreshold,
5792 UnaryOperator<RelBuilder.Config> relBuilderConfigTransform,
5793 RelBuilderFactory relBuilderFactory,
5794 HintStrategyTable hintStrategyTable) {
5795 this.decorrelationEnabled = decorrelationEnabled;
5796 this.trimUnusedFields = trimUnusedFields;
5797 this.createValuesRel = createValuesRel;
5799 this.explain = explain;
5800 this.expand = expand;
5802 this.inSubQueryThreshold = inSubQueryThreshold;
5803 this.relBuilderConfigTransform = relBuilderConfigTransform;
5804 this.relBuilderFactory = relBuilderFactory;
5805 this.hintStrategyTable = hintStrategyTable;
5807 if (null == expandPredicate) {
5808 expandPredicate =
new DefaultExpandPredicate();
5810 this.expandPredicate = expandPredicate;
5817 public boolean equals(Object obj) {
5819 || obj instanceof ConfigImpl
5820 && decorrelationEnabled == ((ConfigImpl) obj).decorrelationEnabled
5821 && trimUnusedFields == ((ConfigImpl) obj).trimUnusedFields
5822 && createValuesRel == ((ConfigImpl) obj).createValuesRel
5823 && explain == ((ConfigImpl) obj).explain
5824 && expand == ((ConfigImpl) obj).expand
5825 && inSubQueryThreshold == ((ConfigImpl) obj).inSubQueryThreshold
5826 && relBuilderFactory == ((ConfigImpl) obj).relBuilderFactory
5827 && hintStrategyTable == ((ConfigImpl) obj).hintStrategyTable;
5831 public int hashCode() {
5832 return Objects.hash(decorrelationEnabled,
5837 inSubQueryThreshold,
5842 public boolean isDecorrelationEnabled() {
5843 return decorrelationEnabled;
5846 public boolean isTrimUnusedFields() {
5847 return trimUnusedFields;
5850 public boolean isCreateValuesRel() {
5851 return createValuesRel;
5854 public boolean isExplain() {
5858 public boolean isExpand() {
5862 public int getInSubQueryThreshold() {
5863 return inSubQueryThreshold;
5866 public UnaryOperator<RelBuilder.Config> getRelBuilderConfigTransform() {
5867 return relBuilderConfigTransform;
5870 public RelBuilderFactory getRelBuilderFactory() {
5871 return relBuilderFactory;
5874 public HintStrategyTable getHintStrategyTable() {
5875 return hintStrategyTable;
5879 public BiPredicate<SqlNode, SqlNode> getExpandPredicate() {
5880 return expandPredicate;
RelRoot convertWith(SqlWith with, boolean top)
RelOptTable.ToRelContext createToRelContext(List< RelHint > hints)
static boolean isOrdered(SqlNode query)
Map< SqlNode, RexNode > getMapConvertedNonCorrSubqs()
final SqlNodeToRexConverter exprConverter
SqlQuantifyOperator negate(SqlQuantifyOperator operator)
int getDynamicParamCount()
RexBuilder getRexBuilder()
void setDynamicParamCountInExplain(int explainParamCount)
static SqlNode pushDownNotForIn(SqlValidatorScope scope, SqlNode sqlNode)
void extraSelectItems(Blackboard bb, SqlSelect select, List< RexNode > exprList, List< String > nameList, Collection< String > aliasList, List< SqlMonotonicity > columnMonotonicityList)
RelNode convertInsert(SqlInsert call)
static boolean isStream(SqlNode query)
static final Logger SQL2REL_LOGGER
final RelBuilder relBuilder
void substituteSubQuery(Blackboard bb, SubQuery subQuery)
void convertCollectionTable(Blackboard bb, SqlCall call)
RexNode convertSubQuery(SqlCall subQuery, SqlToRelConverter parentConverter, boolean isExists, boolean isExplain)
void checkConvertedType(SqlNode query, RelNode result)
DeferredLookup(Blackboard bb, String originalRelName)
RexNode translateIn(RelOptUtil.Logic logic, RelNode root, final RexNode rex)
RelNode convertCursor(Blackboard bb, SubQuery subQuery)
RelNode convertQueryOrInList(Blackboard bb, SqlNode seek, RelDataType targetRowType)
RexNode castNullLiteralIfNeeded(RexNode node, RelDataType type)
RexNode ensureSqlType(RelDataType type, RexNode node)
RelOptCluster getCluster()
final List< SubQuery > subQueryList
void afterTableFunction(SqlToRelConverter.Blackboard bb, SqlCall call, LogicalTableFunctionScan callRel)
final RelOptCluster cluster
RelNode toRel(final RelOptTable table, final List< RelHint > hints)
std::pair< FILE *, std::string > create(const std::string &basePath, const int fileId, const size_t pageSize, const size_t numPages)
SqlToRelConverter(RelOptTable.ViewExpander viewExpander, SqlValidator validator, Prepare.CatalogReader catalogReader, RelOptCluster cluster, SqlRexConvertletTable convertletTable)
void convertValuesImpl(Blackboard bb, SqlCall values, RelDataType targetRowType)
void convertFrom(Blackboard bb, SqlNode from)
final SqlValidatorScope scope
InitializerExpressionFactory getInitializerFactory(SqlValidatorTable validatorTable)
String deriveAlias(final SqlNode node, Collection< String > aliases, final int ordinal)
void setRoot(List< RelNode > inputs)
void setPatternVarRef(boolean isVarRef)
RelNode decorrelate(SqlNode query, RelNode rootRel)
void setRoot(List< RelNode > inputs, RelNode root, boolean hasSystemFields)
final SqlToRelConverter.Config config
RexDynamicParam convertDynamicParam(final SqlDynamicParam dynamicParam)
RelNode convertRowValues(Blackboard bb, SqlNode rowList, Collection< SqlNode > rows, boolean allowLiteralsOnly, RelDataType targetRowType)
RexNode convertInToOr(final Blackboard bb, final List< RexNode > leftKeys, SqlNodeList valuesList, SqlInOperator op)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
final Map< CorrelationId, DeferredLookup > mapCorrelToDeferred
RelOptUtil.Exists convertExists(SqlNode seek, RelOptUtil.SubQueryType subQueryType, RelOptUtil.Logic logic, boolean notIn, RelDataType targetDataType)
final SqlOperatorTable opTab
RelNode createSource(RelOptTable targetTable, RelNode source, ModifiableView modifiableView, RelDataType delegateRowType)
RelNode convertRowConstructor(Blackboard bb, SqlCall rowConstructor)
final RexBuilder rexBuilder
RelRoot convertQueryRecursive(SqlNode query, boolean top, RelDataType targetRowType)
String getOriginalRelName()
SqlToRelConverter(RelOptTable.ViewExpander viewExpander, SqlValidator validator, Prepare.CatalogReader catalogReader, RelOptPlanner planner, RexBuilder rexBuilder, SqlRexConvertletTable convertletTable)
final List< SqlDynamicParam > dynamicParamSqlNodes
void setRoot(RelNode root, boolean leaf)
final Map< SqlNode, RexNode > mapConvertedNonCorrSubqs
RexLiteral convertLiteralInValuesList(SqlNode sqlNode, Blackboard bb, RelDataType rowType, int iField)
void convertUnnest(Blackboard bb, SqlCall call, List< String > fieldNames)
final RexCorrelVariable rexCorrel
void distinctify(Blackboard bb, boolean checkForDupExprs)
RelFieldTrimmer newFieldTrimmer()
RelNode createModify(RelOptTable targetTable, RelNode source)
final Prepare.CatalogReader catalogReader
RelNode trimUnusedFields(boolean ordered, RelNode rootRel)
RexNode convertUsing(SqlValidatorNamespace leftNamespace, SqlValidatorNamespace rightNamespace, List< String > nameList)
void convertSelectImpl(final Blackboard bb, SqlSelect select)
List< RelDataTypeField > getSystemFields()
void addConvertedNonCorrSubqs(Map< SqlNode, RexNode > alreadyConvertedNonCorrSubqs)
RexNode convertJoinCondition(Blackboard bb, SqlValidatorNamespace leftNamespace, SqlValidatorNamespace rightNamespace, SqlNode condition, JoinConditionType conditionType, RelNode leftRel, RelNode rightRel)
void collectInsertTargets(SqlInsert call, final RexNode sourceRef, final List< String > targetColumnNames, List< RexNode > columnExprs)
final SqlValidator validator
std::string toString(const Executor::ExtModuleKinds &kind)
void replaceSubQueries(final Blackboard bb, final SqlNode expr, RelOptUtil.Logic logic)
final Deque< String > datasetStack
RelNode convertMerge(SqlMerge call)
static< T > T unwrap(Object o, Class< T > clazz)
size_t indexOf(std::vector< T > &vec, T val)
boolean isTrimUnusedFields()
SqlToRelConverter(RelOptTable.ViewExpander viewExpander, SqlValidator validator, Prepare.CatalogReader catalogReader, RelOptCluster cluster, SqlRexConvertletTable convertletTable, Config config)
RelNode flattenTypes(RelNode rootRel, boolean restructure)
RelNode createAggregate(Blackboard bb, ImmutableBitSet groupSet, ImmutableList< ImmutableBitSet > groupSets, List< AggregateCall > aggCalls)
CorrelationUse getCorrelationUse(Blackboard bb, final RelNode r0)
RexFieldAccess getFieldAccess(CorrelationId name)
RelNode convertSetOp(SqlCall call)
SubQueryConverter subQueryConverter
RelNode convertValues(SqlCall values, RelDataType targetRowType)
static final int DEFAULT_IN_SUBQUERY_THRESHOLD
void convertAgg(Blackboard bb, SqlSelect select, List< SqlNode > orderExprList)
int getDynamicParamCountInExplain(boolean increment)
RexNode convertOver(Blackboard bb, SqlNode node)
final void createAggImpl(Blackboard bb, final AggConverter aggConverter, SqlNodeList selectList, SqlNodeList groupList, SqlNode having, List< SqlNode > orderExprList)
boolean isRowConstructor(SqlNode node)
Blackboard createInsertBlackboard(RelOptTable targetTable, RexNode sourceRef, List< String > targetColumnNames)
static boolean containsInOperator(SqlNode node)
boolean canConvertSubQuery()
RelNode convertUpdate(SqlUpdate call)
void convertIdentifier(Blackboard bb, SqlIdentifier id, SqlNodeList extendedColumns, SqlNodeList tableHints)
RelNode convertMultisets(final List< SqlNode > operands, Blackboard bb)
torch::Tensor f(torch::Tensor x, torch::Tensor W_target, torch::Tensor b_target)
static boolean containsNullLiteral(SqlNodeList valueList)
RelNode decorrelateQuery(RelNode rootRel)
RelDataType getDynamicParamType(int index)
final RelDataTypeFactory typeFactory
void gatherOrderExprs(Blackboard bb, SqlSelect select, SqlNodeList orderList, List< SqlNode > extraOrderExprs, List< RelFieldCollation > collationList)
static final int DEFAULT_IN_SUB_QUERY_THRESHOLD
RexNode convertExtendedExpression(SqlNode node, Blackboard bb)
RexNode convertExpression(SqlNode node)
final HintStrategyTable hintStrategies
void convertMatchRecognize(Blackboard bb, SqlCall call)
void convertWhere(final Blackboard bb, final SqlNode where)
RexNode convertExpression(SqlNode node, Map< String, RexNode > nameToNodeMap)
void setDataset(String datasetName)
Blackboard(SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
RelNode rewriteAggregateWithGroupId(Blackboard bb, AggregatingSelectScope.Resolved r, AggConverter converter)
final RelOptTable.ViewExpander viewExpander
static SqlNode reg(SqlValidatorScope scope, SqlNode e)
boolean convertNonCorrelatedSubQuery(SubQuery subQuery, Blackboard bb, RelNode converted, boolean isExists)
void findSubQueries(Blackboard bb, SqlNode node, RelOptUtil.Logic logic, boolean registerOnlyScalarSubQueries)
int getInSubqueryThreshold()
Pair< RexNode, Map< String, Integer > > lookupExp(SqlQualified qualified)
boolean isSubQueryNonCorrelated(RelNode subq, Blackboard bb)
boolean enableDecorrelation()
RexNode convertIdentifier(Blackboard bb, SqlIdentifier identifier)
RelNode createJoin(Blackboard bb, RelNode leftRel, RelNode rightRel, RexNode joinCond, JoinRelType joinType)
RexAccessShuttle(RexBuilder builder, RexCorrelVariable rexCorrel)
RelNode convertColumnList(final SqlInsert call, RelNode source)
void convertFrom(Blackboard bb, SqlNode from, List< String > fieldNames)
final Map< String, RexNode > nameToNodeMap
void convertTemporalTable(Blackboard bb, SqlCall call)
static boolean desc(RelFieldCollation.Direction direction)
boolean all(SqlCall call)
Set< RelColumnMapping > getColumnMappings(SqlOperator op)
Blackboard createBlackboard(SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
RelRoot convertQuery(SqlNode query, final boolean needsValidation, final boolean top)
RelFieldCollation convertOrderItem(SqlSelect select, SqlNode orderItem, List< SqlNode > extraExprs, RelFieldCollation.Direction direction, RelFieldCollation.NullDirection nullDirection)
final Map< RelNode, Map< Integer, Integer > > mapRootRelToFieldProjection
RelNode convertToSingleValueSubq(SqlNode query, RelNode plan)
static JoinRelType convertJoinType(JoinType joinType)
RelCollation requiredCollation(RelNode r)
void setSubQueryConverter(SubQueryConverter converter)
final Map< RelNode, Integer > leaves
RelOptTable getTargetTable(SqlNode call)
RexNode adjustInputRef(Blackboard bb, RexInputRef inputRef)
void convertOrder(SqlSelect select, Blackboard bb, RelCollation collation, List< SqlNode > orderExprList, SqlNode offset, SqlNode fetch)
void convertSelectList(Blackboard bb, SqlSelect select, List< SqlNode > orderList)
RelNode convertDelete(SqlDelete call)
RexNode visitInputRef(RexInputRef input)
RelNode convertSelect(SqlSelect select, boolean top)