47 package org.apache.calcite.sql.validate;
49 import org.apache.calcite.linq4j.Ord;
50 import org.apache.calcite.linq4j.function.Function2;
51 import org.apache.calcite.linq4j.function.Functions;
52 import org.apache.calcite.plan.RelOptTable;
53 import org.apache.calcite.plan.RelOptUtil;
54 import org.apache.calcite.prepare.Prepare;
55 import org.apache.calcite.rel.type.DynamicRecordType;
56 import org.apache.calcite.rel.type.RelDataType;
57 import org.apache.calcite.rel.type.RelDataTypeFactory;
58 import org.apache.calcite.rel.type.RelDataTypeField;
59 import org.apache.calcite.rel.type.RelDataTypeSystem;
60 import org.apache.calcite.rel.type.RelRecordType;
61 import org.apache.calcite.rex.RexNode;
62 import org.apache.calcite.rex.RexPatternFieldRef;
63 import org.apache.calcite.rex.RexVisitor;
64 import org.apache.calcite.runtime.CalciteContextException;
65 import org.apache.calcite.runtime.CalciteException;
66 import org.apache.calcite.runtime.Feature;
67 import org.apache.calcite.runtime.Resources;
68 import org.apache.calcite.schema.ColumnStrategy;
69 import org.apache.calcite.schema.Table;
70 import org.apache.calcite.schema.impl.ModifiableViewTable;
71 import org.apache.calcite.sql.JoinConditionType;
73 import org.apache.calcite.sql.SqlAccessEnum;
74 import org.apache.calcite.sql.SqlAccessType;
75 import org.apache.calcite.sql.SqlAggFunction;
76 import org.apache.calcite.sql.SqlBasicCall;
77 import org.apache.calcite.sql.SqlCall;
78 import org.apache.calcite.sql.SqlCallBinding;
79 import org.apache.calcite.sql.SqlDataTypeSpec;
80 import org.apache.calcite.sql.SqlDelete;
81 import org.apache.calcite.sql.SqlDynamicParam;
82 import org.apache.calcite.sql.SqlExplain;
83 import org.apache.calcite.sql.SqlFunction;
84 import org.apache.calcite.sql.SqlFunctionCategory;
85 import org.apache.calcite.sql.SqlIdentifier;
86 import org.apache.calcite.sql.SqlInsert;
87 import org.apache.calcite.sql.SqlIntervalLiteral;
88 import org.apache.calcite.sql.SqlIntervalQualifier;
89 import org.apache.calcite.sql.SqlJoin;
90 import org.apache.calcite.sql.SqlKind;
91 import org.apache.calcite.sql.SqlLiteral;
92 import org.apache.calcite.sql.SqlMatchRecognize;
93 import org.apache.calcite.sql.SqlMerge;
94 import org.apache.calcite.sql.SqlNode;
95 import org.apache.calcite.sql.SqlNodeList;
97 import org.apache.calcite.sql.SqlOperatorTable;
98 import org.apache.calcite.sql.SqlOrderBy;
99 import org.apache.calcite.sql.SqlSampleSpec;
100 import org.apache.calcite.sql.SqlSelect;
101 import org.apache.calcite.sql.SqlSelectKeyword;
102 import org.apache.calcite.sql.SqlSnapshot;
103 import org.apache.calcite.sql.SqlSyntax;
104 import org.apache.calcite.sql.SqlTableFunction;
105 import org.apache.calcite.sql.SqlUnresolvedFunction;
106 import org.apache.calcite.sql.SqlUpdate;
107 import org.apache.calcite.sql.SqlUtil;
108 import org.apache.calcite.sql.SqlWindow;
109 import org.apache.calcite.sql.SqlWindowTableFunction;
110 import org.apache.calcite.sql.SqlWith;
111 import org.apache.calcite.sql.SqlWithItem;
112 import org.apache.calcite.sql.fun.SqlCase;
113 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
114 import org.apache.calcite.sql.parser.SqlParserPos;
115 import org.apache.calcite.sql.type.AssignableOperandTypeChecker;
116 import org.apache.calcite.sql.type.ReturnTypes;
117 import org.apache.calcite.sql.type.SqlOperandTypeInference;
118 import org.apache.calcite.sql.type.SqlTypeCoercionRule;
119 import org.apache.calcite.sql.type.SqlTypeName;
120 import org.apache.calcite.sql.type.SqlTypeUtil;
121 import org.apache.calcite.sql.util.IdPair;
122 import org.apache.calcite.sql.util.SqlBasicVisitor;
123 import org.apache.calcite.sql.util.SqlShuttle;
124 import org.apache.calcite.sql.util.SqlVisitor;
125 import org.apache.calcite.sql.validate.implicit.TypeCoercion;
127 import org.apache.calcite.util.BitString;
128 import org.apache.calcite.util.Bug;
129 import org.apache.calcite.util.ImmutableBitSet;
130 import org.apache.calcite.util.ImmutableIntList;
131 import org.apache.calcite.util.ImmutableNullableList;
132 import org.apache.calcite.util.Litmus;
133 import org.apache.calcite.util.Pair;
134 import org.apache.calcite.util.Static;
135 import org.apache.calcite.util.Util;
136 import org.apache.calcite.util.trace.CalciteTrace;
138 import com.google.common.annotations.VisibleForTesting;
139 import com.google.common.base.Preconditions;
140 import com.google.common.collect.ImmutableList;
141 import com.google.common.collect.ImmutableSet;
142 import com.google.common.collect.Sets;
145 import org.slf4j.Logger;
147 import java.math.BigDecimal;
148 import java.math.BigInteger;
149 import java.util.AbstractList;
150 import java.util.ArrayDeque;
151 import java.util.ArrayList;
152 import java.util.Arrays;
153 import java.util.Calendar;
154 import java.util.Collection;
155 import java.util.Collections;
156 import java.util.Deque;
157 import java.util.GregorianCalendar;
158 import java.util.HashMap;
159 import java.util.HashSet;
160 import java.util.IdentityHashMap;
161 import java.util.List;
162 import java.util.Locale;
163 import java.util.Map;
164 import java.util.Objects;
165 import java.util.Set;
166 import java.util.function.Supplier;
167 import java.util.function.UnaryOperator;
168 import java.util.stream.Collectors;
169 import javax.annotation.Nonnull;
170 import javax.annotation.Nullable;
172 import static org.apache.calcite.sql.SqlUtil.stripAs;
173 import static org.apache.calcite.util.Static.RESOURCE;
181 public static final Logger
TRACER = CalciteTrace.PARSER_LOGGER;
201 private final SqlOperatorTable
opTab;
208 protected final Map<String, IdInfo>
idPositions =
new HashMap<>();
214 protected final Map<SqlNode, SqlValidatorScope>
scopes =
215 new IdentityHashMap<>();
220 private final Map<IdPair<SqlSelect, Clause>, SqlValidatorScope>
233 protected final Map<SqlNode, SqlValidatorNamespace>
namespaces =
234 new IdentityHashMap<>();
241 private final Set<SqlNode>
cursorSet = Sets.newIdentityHashSet();
264 new IdentityHashMap<>();
284 new SqlValidatorImpl.ValidationErrorFunction();
300 SqlOperatorTable
opTab,
304 this.opTab = Objects.requireNonNull(
opTab);
306 this.typeFactory = Objects.requireNonNull(
typeFactory);
307 this.config = Objects.requireNonNull(
config);
310 booleanType = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
312 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
313 aggFinder =
new AggFinder(opTab,
false,
true,
false, null, nameMatcher);
315 new AggFinder(opTab,
true,
true,
false, null, nameMatcher);
318 groupFinder =
new AggFinder(opTab,
false,
false,
true, null, nameMatcher);
322 this.typeCoercion = TypeCoercions.createHeavyDBTypeCoercion(
typeFactory,
this);
323 if (config.typeCoercionRules() != null) {
324 SqlTypeCoercionRule.THREAD_PROVIDERS.set(config.typeCoercionRules());
331 return config.sqlConformance();
351 SqlNodeList selectList,
353 boolean includeSystemVars) {
354 final List<SqlNode> list =
new ArrayList<>();
355 final List<Map.Entry<String, RelDataType>> types =
new ArrayList<>();
356 for (
int i = 0; i < selectList.size(); i++) {
357 final SqlNode selectItem = selectList.get(i);
364 catalogReader.nameMatcher().createSet(),
369 return new SqlNodeList(list, SqlParserPos.ZERO);
373 public void declareCursor(SqlSelect select, SqlValidatorScope parentScope) {
374 cursorSet.add(select);
379 Map<Integer, SqlSelect> cursorMap = funcParamInfo.cursorPosToSelectMap;
380 int numCursors = cursorMap.size();
381 cursorMap.put(numCursors, select);
386 SelectScope cursorScope =
new SelectScope(parentScope, null, select);
387 clauseScopes.put(IdPair.of(select,
Clause.CURSOR), cursorScope);
396 functionCallStack.push(funcInfo);
401 functionCallStack.pop();
407 Map<String, String> parentCursorMap =
408 funcParamInfo.columnListParamToParentCursorMap;
409 return parentCursorMap.get(columnListParamName);
425 final SqlNode selectItem,
427 RelDataType targetType,
428 List<SqlNode> selectItems,
430 List<Map.Entry<String, RelDataType>> fields,
431 final boolean includeSystemVars) {
432 final SelectScope scope = (SelectScope)
getWhereScope(select);
433 if (
expandStar(selectItems, aliases, fields, includeSystemVars, scope,
449 if (expanded != selectItem) {
454 if (!newAlias.equals(alias)) {
456 SqlStdOperatorTable.AS.createCall(
457 selectItem.getParserPosition(),
459 new SqlIdentifier(alias, SqlParserPos.ZERO));
464 selectItems.add(expanded);
467 if (expanded != null) {
478 if (join.getConditionType() != JoinConditionType.USING) {
482 for (SqlNode node : (SqlNodeList) join.getCondition()) {
483 final String
name = ((SqlIdentifier) node).getSimple();
484 if (identifier.getSimple().equals(
name)) {
485 final List<SqlNode> qualifiedNode =
new ArrayList<>();
486 for (ScopeChild child : scope.children) {
487 if (child.namespace.getRowType()
488 .getFieldNames().
indexOf(name) >= 0) {
489 final SqlIdentifier exp =
491 ImmutableList.of(child.name, name),
492 identifier.getParserPosition());
493 qualifiedNode.add(exp);
497 assert qualifiedNode.size() == 2;
498 final SqlNode finalNode =
499 SqlStdOperatorTable.AS.createCall(SqlParserPos.ZERO,
500 SqlStdOperatorTable.COALESCE.createCall(SqlParserPos.ZERO,
501 qualifiedNode.get(0),
502 qualifiedNode.get(1)),
503 new SqlIdentifier(name, SqlParserPos.ZERO));
510 final SqlNode node = join.getLeft();
511 if (node instanceof SqlJoin) {
521 switch (join.getConditionType()) {
523 final ImmutableList.Builder<String> list = ImmutableList.builder();
524 final Set<String> names = catalogReader.nameMatcher().createSet();
525 for (SqlNode node : (SqlNodeList) join.getCondition()) {
526 final String
name = ((SqlIdentifier) node).getSimple();
527 if (names.add(name)) {
533 if (join.isNatural()) {
536 return SqlValidatorUtil.deriveNaturalJoinColumnList(
537 catalogReader.nameMatcher(), t0, t1);
545 if (!(selectItem instanceof SqlIdentifier)) {
549 final SqlNode from = sqlSelect.getFrom();
550 if (!(from instanceof SqlJoin)) {
554 final SqlIdentifier identifier = (SqlIdentifier) selectItem;
555 if (!identifier.isSimple()) {
556 if (!validator.
config().sqlConformance().allowQualifyingCommonColumn()) {
567 List<String> names = validator.usingNames(
join);
575 for (ScopeChild child : scope.children) {
576 if (child.name.equals(identifier.getComponent(0).toString())) {
577 if (names.indexOf(identifier.getComponent(1).toString()) >= 0) {
578 throw validator.newValidationError(identifier,
579 RESOURCE.disallowsQualifyingCommonColumn(identifier.toString()));
586 final SqlNode node = join.getLeft();
587 if (node instanceof SqlJoin) {
592 private boolean expandStar(List<SqlNode> selectItems, Set<String> aliases,
593 List<Map.Entry<String, RelDataType>> fields,
boolean includeSystemVars,
594 SelectScope scope, SqlNode node) {
595 if (!(node instanceof SqlIdentifier)) {
598 final SqlIdentifier identifier = (SqlIdentifier) node;
599 if (!identifier.isStar()) {
602 final SqlParserPos startPosition = identifier.getParserPosition();
603 switch (identifier.names.size()) {
605 boolean hasDynamicStruct =
false;
606 for (ScopeChild child : scope.children) {
607 final int before = fields.size();
608 if (child.namespace.getRowType().isDynamicStruct()) {
609 hasDynamicStruct =
true;
615 ImmutableList.of(child.name,
616 DynamicRecordType.DYNAMIC_STAR_PREFIX),
626 final SqlNode from = child.namespace.getNode();
627 final SqlValidatorNamespace fromNs =
getNamespace(from, scope);
628 assert fromNs != null;
629 final RelDataType rowType = fromNs.getRowType();
630 for (RelDataTypeField
field : rowType.getFieldList()) {
631 String columnName = field.getName();
634 final SqlIdentifier exp =
636 ImmutableList.of(child.name, columnName),
651 if (child.nullable) {
652 for (
int i = before; i < fields.size(); i++) {
653 final Map.Entry<String, RelDataType> entry = fields.get(i);
654 final RelDataType
type = entry.getValue();
655 if (!type.isNullable()) {
657 Pair.of(entry.getKey(),
658 typeFactory.createTypeWithNullability(type,
true)));
665 if (!hasDynamicStruct || Bug.CALCITE_2400_FIXED) {
666 new Permute(scope.getNode().getFrom(), 0).permute(selectItems, fields);
671 final SqlIdentifier prefixId = identifier.skipLast(1);
672 final SqlValidatorScope.ResolvedImpl resolved =
673 new SqlValidatorScope.ResolvedImpl();
674 final SqlNameMatcher nameMatcher =
675 scope.validator.catalogReader.nameMatcher();
676 scope.resolve(prefixId.names, nameMatcher,
true, resolved);
677 if (resolved.count() == 0) {
681 RESOURCE.unknownIdentifier(prefixId.toString()));
683 final RelDataType rowType = resolved.only().rowType();
684 if (rowType.isDynamicStruct()) {
690 prefixId.plus(DynamicRecordType.DYNAMIC_STAR_PREFIX, startPosition),
693 }
else if (rowType.isStruct()) {
694 for (RelDataTypeField
field : rowType.getFieldList()) {
695 String columnName = field.getName();
704 prefixId.plus(columnName, startPosition),
714 private SqlNode
maybeCast(SqlNode node, RelDataType currentType,
715 RelDataType desiredType) {
716 return SqlTypeUtil.equalSansNullability(
typeFactory, currentType, desiredType)
718 : SqlStdOperatorTable.CAST.createCall(SqlParserPos.ZERO,
719 node, SqlTypeUtil.convertTypeToSpec(desiredType));
723 List<Map.Entry<String, RelDataType>> fields,
boolean includeSystemVars,
724 SelectScope scope, SqlIdentifier
id, RelDataTypeField
field) {
725 switch (field.getType().getStructKind()) {
727 case PEEK_FIELDS_DEFAULT:
728 final SqlNode starExp = id.plusStar();
752 SqlValidatorScope scope =
new EmptyScope(
this);
753 scope =
new CatalogScope(scope, ImmutableList.of(
"CATALOG"));
760 public List<SqlMoniker>
lookupHints(SqlNode topNode, SqlParserPos pos) {
761 SqlValidatorScope scope =
new EmptyScope(
this);
763 cursorSet.add(outermostNode);
764 if (outermostNode.isA(SqlKind.TOP_LEVEL)) {
773 final SqlValidatorNamespace ns =
getNamespace(outermostNode);
775 throw new AssertionError(
"Not a query: " + outermostNode);
777 Collection<SqlMoniker> hintList = Sets.newTreeSet(SqlMoniker.COMPARATOR);
779 return ImmutableList.copyOf(hintList);
783 final String posString = pos.toString();
784 IdInfo info = idPositions.get(posString);
786 final SqlQualified qualified = info.scope.fullyQualify(info.id);
787 return new SqlIdentifierMoniker(qualified.identifier);
806 Collection<SqlMoniker> hintList) {
807 IdInfo info = idPositions.get(pos.toString());
808 if ((info == null) || (info.
scope == null)) {
809 SqlNode fromNode = select.getFrom();
810 final SqlValidatorScope fromScope =
getFromScope(select);
814 info.
id.getParserPosition(), hintList);
819 SqlValidatorNamespace ns,
821 Collection<SqlMoniker> hintList) {
822 final SqlNode node = ns.getNode();
823 if (node instanceof SqlSelect) {
830 SqlValidatorScope scope,
832 Collection<SqlMoniker> hintList) {
838 if (ns.isWrapperFor(IdentifierNamespace.class)) {
839 IdentifierNamespace idNs = ns.unwrap(IdentifierNamespace.class);
840 final SqlIdentifier
id = idNs.getId();
841 for (
int i = 0; i < id.names.size(); i++) {
842 if (pos.toString().equals(
843 id.getComponent(i).getParserPosition().toString())) {
844 final List<SqlMoniker> objNames =
new ArrayList<>();
845 SqlValidatorUtil.getSchemaObjectMonikers(
847 id.names.subList(0, i + 1),
849 for (SqlMoniker objName : objNames) {
850 if (objName.getType() != SqlMonikerType.FUNCTION) {
851 hintList.add(objName);
858 switch (node.getKind()) {
870 SqlValidatorScope scope,
872 Collection<SqlMoniker> hintList) {
873 SqlNode left = join.getLeft();
874 SqlNode right = join.getRight();
875 SqlNode condition = join.getCondition();
877 if (hintList.size() > 0) {
881 if (hintList.size() > 0) {
884 final JoinConditionType conditionType = join.getConditionType();
885 final SqlValidatorScope joinScope = scopes.get(
join);
886 switch (conditionType) {
888 condition.findValidOptions(
this, joinScope, pos, hintList);
906 SqlValidatorScope scope,
909 Collection<SqlMoniker> hintList) {
911 List<String> subNames = Util.skipLast(names);
913 if (subNames.size() > 0) {
915 SqlValidatorNamespace ns = null;
916 for (String
name : subNames) {
918 final SqlValidatorScope.ResolvedImpl resolved =
919 new SqlValidatorScope.ResolvedImpl();
920 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
921 scope.resolve(ImmutableList.of(
name), nameMatcher,
false, resolved);
922 if (resolved.count() == 1) {
923 ns = resolved.only().
namespace;
926 ns = ns.lookupChild(
name);
933 RelDataType rowType = ns.getRowType();
934 if (rowType.isStruct()) {
935 for (RelDataTypeField
field : rowType.getFieldList()) {
939 SqlMonikerType.COLUMN));
950 scope.findAliases(hintList);
953 SelectScope selectScope =
954 SqlValidatorUtil.getEnclosingSelectScope(scope);
955 if ((selectScope != null)
956 && (selectScope.getChildren().size() == 1)) {
957 RelDataType rowType =
958 selectScope.getChildren().
get(0).getRowType();
959 for (RelDataTypeField
field : rowType.getFieldList()) {
963 SqlMonikerType.COLUMN));
973 SqlValidator validator,
974 Collection<SqlMoniker>
result) {
975 final List<SqlMoniker> objNames =
new ArrayList<>();
976 SqlValidatorUtil.getSchemaObjectMonikers(
977 validator.getCatalogReader(),
980 for (SqlMoniker objName : objNames) {
981 if (objName.getType() == SqlMonikerType.FUNCTION) {
989 SqlValidator validator,
990 Collection<SqlMoniker>
result,
993 if (names.size() > 1) {
996 for (
SqlOperator op : validator.getOperatorTable().getOperatorList()) {
997 SqlIdentifier curOpId =
1002 final SqlCall call = validator.makeNullaryCall(curOpId);
1007 SqlMonikerType.FUNCTION));
1009 if ((op.getSyntax() == SqlSyntax.FUNCTION)
1010 || (op.getSyntax() == SqlSyntax.PREFIX)) {
1011 if (op.getOperandTypeChecker() != null) {
1012 String sig = op.getAllowedSignatures();
1013 sig = sig.replace(
"'",
"");
1017 SqlMonikerType.FUNCTION));
1023 SqlMonikerType.FUNCTION));
1031 final Map<String, RelDataType> nameToTypeMap) {
1032 SqlValidatorScope scope =
new ParameterScope(
this, nameToTypeMap);
1038 SqlValidatorScope scope) {
1040 cursorSet.add(outermostNode);
1041 top = outermostNode;
1042 TRACER.trace(
"After unconditional rewrite: {}", outermostNode);
1043 if (outermostNode.isA(SqlKind.TOP_LEVEL)) {
1044 registerQuery(scope, null, outermostNode, outermostNode, null,
false);
1046 outermostNode.validate(
this, scope);
1047 if (!outermostNode.isA(SqlKind.TOP_LEVEL)) {
1052 TRACER.trace(
"After validation: {}", outermostNode);
1053 return outermostNode;
1057 RelDataType targetRowType) {
1058 final SqlValidatorNamespace ns =
getNamespace(node, scope);
1059 if (node.getKind() == SqlKind.TABLESAMPLE) {
1060 List<SqlNode> operands = ((SqlCall) node).getOperandList();
1061 SqlSampleSpec sampleSpec = SqlLiteral.sampleValue(operands.get(1));
1062 if (sampleSpec instanceof SqlSampleSpec.SqlTableSampleSpec) {
1063 validateFeature(RESOURCE.sQLFeature_T613(), node.getParserPosition());
1064 }
else if (sampleSpec
1065 instanceof SqlSampleSpec.SqlSubstitutionSampleSpec) {
1067 node.getParserPosition());
1072 switch (node.getKind()) {
1083 SqlAccessEnum.SELECT);
1096 RelDataType targetRowType) {
1097 namespace.validate(targetRowType);
1098 if (
namespace.getNode() != null) {
1105 return new EmptyScope(
this);
1113 return clauseScopes.get(IdPair.of(select,
Clause.WHERE));
1122 if (scope instanceof AggregatingSelectScope) {
1123 scope = ((AggregatingSelectScope) scope).getParent();
1125 return (SelectScope) scope;
1139 return scopes.get(select);
1143 return clauseScopes.get(IdPair.of(select,
Clause.ORDER));
1147 return scopes.get(node);
1151 return scopes.get(stripAs(node));
1155 return scopes.get(node);
1159 SqlValidatorScope scope) {
1160 if (node instanceof SqlIdentifier && scope instanceof DelegatingScope) {
1161 final SqlIdentifier
id = (SqlIdentifier) node;
1162 final DelegatingScope idScope = (DelegatingScope) ((DelegatingScope) scope).getParent();
1164 }
else if (node instanceof SqlCall) {
1166 final SqlCall call = (SqlCall) node;
1167 switch (call.getOperator().getKind()) {
1171 final SqlNode operand0 = call.getOperandList().
get(0);
1172 final SqlIdentifier identifier = operand0.getKind() == SqlKind.TABLE_REF
1173 ? ((SqlCall) operand0).operand(0)
1174 : (SqlIdentifier) operand0;
1175 final DelegatingScope idScope = (DelegatingScope) scope;
1178 final SqlNode nested = call.getOperandList().
get(0);
1179 switch (nested.getKind()) {
1190 private SqlValidatorNamespace
getNamespace(SqlIdentifier
id, DelegatingScope scope) {
1191 if (
id.isSimple()) {
1192 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
1193 final SqlValidatorScope.ResolvedImpl resolved =
1194 new SqlValidatorScope.ResolvedImpl();
1195 scope.resolve(id.names, nameMatcher,
false, resolved);
1196 if (resolved.count() == 1) {
1197 return resolved.only().
namespace;
1204 switch (node.getKind()) {
1208 final SqlValidatorNamespace ns = namespaces.get(node);
1216 case COLLECTION_TABLE:
1221 return namespaces.get(node);
1226 if (offset instanceof SqlDynamicParam) {
1230 if (fetch instanceof SqlDynamicParam) {
1247 boolean underFrom) {
1255 if (node instanceof SqlCall) {
1256 if (node instanceof SqlMerge) {
1259 SqlCall call = (SqlCall) node;
1260 final SqlKind kind = call.getKind();
1261 final List<SqlNode> operands = call.getOperandList();
1262 for (
int i = 0; i < operands.size(); i++) {
1263 SqlNode operand = operands.get(i);
1264 boolean childUnderFrom;
1265 if (kind == SqlKind.SELECT) {
1266 childUnderFrom = i == SqlSelect.FROM_OPERAND;
1267 }
else if (kind == SqlKind.AS && (i == 0)) {
1270 childUnderFrom = underFrom;
1272 childUnderFrom =
false;
1276 if (newOperand != null && newOperand != operand) {
1277 call.setOperand(i, newOperand);
1281 if (call.getOperator() instanceof SqlUnresolvedFunction) {
1282 assert call instanceof SqlBasicCall;
1283 final SqlUnresolvedFunction
function =
1284 (SqlUnresolvedFunction) call.getOperator();
1289 final List<SqlOperator> overloads =
new ArrayList<>();
1290 opTab.lookupOperatorOverloads(function.getNameAsId(),
1291 function.getFunctionType(), SqlSyntax.FUNCTION, overloads,
1292 catalogReader.nameMatcher());
1293 if (overloads.size() == 1) {
1294 ((SqlBasicCall) call).setOperator(overloads.get(0));
1297 if (
config.callRewrite()) {
1298 node = call.getOperator().rewriteCall(
this, call);
1300 }
else if (node instanceof SqlNodeList) {
1301 SqlNodeList list = (SqlNodeList) node;
1302 for (
int i = 0, count = list.size(); i < count; i++) {
1303 SqlNode operand = list.get(i);
1308 if (newOperand != null) {
1309 list.getList().set(i, newOperand);
1315 final SqlKind kind = node.getKind();
1319 if (underFrom ||
true) {
1325 final SqlNodeList selectList =
1326 new SqlNodeList(SqlParserPos.ZERO);
1327 selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
1328 return new SqlSelect(node.getParserPosition(), null, selectList, node,
1329 null, null, null, null, null, null, null, null);
1333 SqlOrderBy orderBy = (SqlOrderBy) node;
1335 if (orderBy.query instanceof SqlSelect) {
1336 SqlSelect select = (SqlSelect) orderBy.query;
1340 if (select.getOrderList() == null) {
1342 select.setOrderBy(orderBy.orderList);
1343 select.setOffset(orderBy.offset);
1344 select.setFetch(orderBy.fetch);
1348 if (orderBy.query instanceof SqlWith
1349 && ((SqlWith) orderBy.query).body instanceof SqlSelect) {
1350 SqlWith with = (SqlWith) orderBy.query;
1351 SqlSelect select = (SqlSelect) with.body;
1355 if (select.getOrderList() == null) {
1357 select.setOrderBy(orderBy.orderList);
1358 select.setOffset(orderBy.offset);
1359 select.setFetch(orderBy.fetch);
1363 final SqlNodeList selectList =
new SqlNodeList(SqlParserPos.ZERO);
1364 selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
1365 final SqlNodeList orderList;
1367 orderList = SqlNode.clone(orderBy.orderList);
1370 for (
int i = 0; i < orderList.size(); i++) {
1371 SqlNode sqlNode = orderList.get(i);
1373 for (Ord<SqlNode> sel : Ord.zip(selectList2)) {
1374 if (stripAs(sel.e).equalsDeep(sqlNode, Litmus.IGNORE)) {
1376 SqlLiteral.createExactNumeric(Integer.toString(sel.i + 1),
1377 SqlParserPos.ZERO));
1382 orderList = orderBy.orderList;
1384 return new SqlSelect(SqlParserPos.ZERO, null, selectList, orderBy.query,
1385 null, null, null, null, orderList, orderBy.offset,
1386 orderBy.fetch, null);
1389 case EXPLICIT_TABLE: {
1391 SqlCall call = (SqlCall) node;
1392 final SqlNodeList selectList =
new SqlNodeList(SqlParserPos.ZERO);
1393 selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
1394 return new SqlSelect(SqlParserPos.ZERO, null, selectList, call.operand(0),
1395 null, null, null, null, null, null, null, null);
1399 SqlDelete call = (SqlDelete) node;
1401 call.setSourceSelect(select);
1406 SqlUpdate call = (SqlUpdate) node;
1408 call.setSourceSelect(select);
1414 SqlNode selfJoinSrcExpr =
1416 call.getTargetTable(),
1418 if (selfJoinSrcExpr != null) {
1426 SqlMerge call = (SqlMerge) node;
1436 if (node instanceof SqlSelect) {
1437 return (SqlSelect) node;
1438 }
else if (node instanceof SqlOrderBy) {
1439 node = ((SqlOrderBy) node).query;
1440 }
else if (node instanceof SqlWith) {
1441 node = ((SqlWith) node).body;
1449 SqlNodeList selectList;
1450 SqlUpdate updateStmt = call.getUpdateCall();
1451 if (updateStmt != null) {
1456 selectList = SqlNode.clone(updateStmt.getSourceSelect().getSelectList());
1459 selectList =
new SqlNodeList(SqlParserPos.ZERO);
1460 selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
1462 SqlNode targetTable = call.getTargetTable();
1463 if (call.getAlias() != null) {
1465 SqlValidatorUtil.addAlias(
1467 call.getAlias().getSimple());
1475 SqlNode sourceTableRef = call.getSourceTableRef();
1476 SqlInsert insertCall = call.getInsertCall();
1478 final SqlNode leftJoinTerm = SqlNode.clone(sourceTableRef);
1480 new SqlJoin(SqlParserPos.ZERO,
1482 SqlLiteral.createBoolean(
false, SqlParserPos.ZERO),
1483 joinType.symbol(SqlParserPos.ZERO),
1485 JoinConditionType.ON.symbol(SqlParserPos.ZERO),
1486 call.getCondition());
1488 new SqlSelect(SqlParserPos.ZERO, null, selectList, outerJoin, null,
1489 null, null, null, null, null, null, null);
1490 call.setSourceSelect(select);
1497 if (insertCall != null) {
1498 SqlCall valuesCall = (SqlCall) insertCall.getSource();
1499 SqlCall rowCall = valuesCall.operand(0);
1502 rowCall.getOperandList(),
1504 final SqlNode insertSource = SqlNode.clone(sourceTableRef);
1506 new SqlSelect(SqlParserPos.ZERO, null, selectList, insertSource, null,
1507 null, null, null, null, null, null, null);
1508 insertCall.setSource(select);
1513 SqlUpdate updateCall,
1514 SqlNode selfJoinSrcExpr) {
1516 if (updateCall.getAlias() == null) {
1517 updateCall.setAlias(
1520 SqlNode selfJoinTgtExpr =
1522 updateCall.getTargetTable(),
1523 updateCall.getAlias().getSimple());
1524 assert selfJoinTgtExpr != null;
1529 SqlNode condition = updateCall.getCondition();
1530 SqlNode selfJoinCond =
1531 SqlStdOperatorTable.EQUALS.createCall(
1535 if (condition == null) {
1536 condition = selfJoinCond;
1539 SqlStdOperatorTable.AND.createCall(
1545 updateCall.getTargetTable().clone(SqlParserPos.ZERO);
1555 IdentifierNamespace ns =
1556 new IdentifierNamespace(
this, target, null, null);
1557 RelDataType rowType = ns.getRowType();
1558 SqlNode source = updateCall.getTargetTable().clone(SqlParserPos.ZERO);
1559 final SqlNodeList selectList =
new SqlNodeList(SqlParserPos.ZERO);
1561 for (RelDataTypeField
field : rowType.getFieldList()) {
1571 new SqlSelect(SqlParserPos.ZERO, null, selectList, source, null, null,
1572 null, null, null, null, null, null);
1574 SqlMerge mergeCall =
1575 new SqlMerge(updateCall.getParserPosition(), target, condition, source,
1576 updateCall, null, null, updateCall.getAlias());
1609 final SqlNodeList selectList =
new SqlNodeList(SqlParserPos.ZERO);
1610 selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
1612 for (SqlNode exp : call.getSourceExpressionList()) {
1615 String
alias = SqlUtil.deriveAliasFromOrdinal(ordinal);
1616 selectList.add(SqlValidatorUtil.addAlias(exp,
alias));
1619 SqlNode sourceTable = call.getTargetTable();
1620 if (call.getAlias() != null) {
1622 SqlValidatorUtil.addAlias(
1624 call.getAlias().getSimple());
1626 return new SqlSelect(SqlParserPos.ZERO, null, selectList, sourceTable,
1627 call.getCondition(), null, null, null, null, null, null, null);
1638 final SqlNodeList selectList =
new SqlNodeList(SqlParserPos.ZERO);
1639 selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
1640 SqlNode sourceTable = call.getTargetTable();
1641 if (call.getAlias() != null) {
1643 SqlValidatorUtil.addAlias(
1645 call.getAlias().getSimple());
1647 return new SqlSelect(SqlParserPos.ZERO, null, selectList, sourceTable,
1648 call.getCondition(), null, null, null, null, null, null, null);
1657 SqlValidatorScope scope) {
1658 final List<SqlNode>
rows = values.getOperandList();
1659 assert rows.size() >= 1;
1660 final List<RelDataType> rowTypes =
new ArrayList<>();
1661 for (
final SqlNode row : rows) {
1662 assert row.getKind() == SqlKind.ROW;
1663 SqlCall rowConstructor = (SqlCall) row;
1667 final List<String> aliasList =
new ArrayList<>();
1668 final List<RelDataType> typeList =
new ArrayList<>();
1669 for (Ord<SqlNode> column : Ord.zip(rowConstructor.getOperandList())) {
1671 aliasList.add(
alias);
1675 rowTypes.add(typeFactory.createStructType(typeList, aliasList));
1677 if (rows.size() == 1) {
1680 return rowTypes.get(0);
1682 return typeFactory.leastRestrictive(rowTypes);
1688 throw Util.needToImplement(node);
1695 final RelDataType
type = nodeToTypeMap.get(node);
1701 return ns.getType();
1703 final SqlNode original = originalExprs.get(node);
1704 if (original != null && original != node) {
1707 if (node instanceof SqlIdentifier) {
1723 Objects.requireNonNull(
type);
1724 Objects.requireNonNull(node);
1730 nodeToTypeMap.put(node,
type);
1734 nodeToTypeMap.remove(node);
1738 if (
id.names.size() == 1 && !id.isComponentQuoted(0)) {
1739 final List<SqlOperator> list =
new ArrayList<>();
1740 opTab.lookupOperatorOverloads(id, null, SqlSyntax.FUNCTION, list,
1741 catalogReader.nameMatcher());
1743 if (
operator.getSyntax() == SqlSyntax.FUNCTION_ID) {
1748 return new SqlBasicCall(
operator, SqlNode.EMPTY_ARRAY,
1749 id.getParserPosition(),
true, null);
1757 SqlValidatorScope scope,
1759 Objects.requireNonNull(scope);
1760 Objects.requireNonNull(expr);
1763 RelDataType
type = nodeToTypeMap.get(expr);
1769 return ns.getType();
1772 Preconditions.checkArgument(
1774 "SqlValidator.deriveTypeInternal returned null");
1783 SqlValidatorScope scope,
1786 final RelDataType
type = operand.accept(v);
1787 return Objects.requireNonNull(scope.nullifyType(operand,
type));
1791 SqlValidatorScope scope,
1793 SqlFunction unresolvedConstructor,
1794 SqlFunction resolvedConstructor,
1795 List<RelDataType> argTypes) {
1796 SqlIdentifier sqlIdentifier = unresolvedConstructor.getSqlIdentifier();
1797 assert sqlIdentifier != null;
1798 RelDataType
type = catalogReader.getNamedType(sqlIdentifier);
1802 RESOURCE.unknownDatatypeName(sqlIdentifier.toString()));
1805 if (resolvedConstructor == null) {
1806 if (call.operandCount() > 0) {
1814 resolvedConstructor.createCall(
1815 call.getParserPosition(),
1816 call.getOperandList());
1817 RelDataType returnType =
1818 resolvedConstructor.validateOperands(
1822 assert type == returnType;
1825 if (
config.identifierExpansion()) {
1826 if (resolvedConstructor != null) {
1827 ((SqlBasicCall) call).setOperator(resolvedConstructor);
1830 ((SqlBasicCall) call).setOperator(
1832 type.getSqlIdentifier(),
1833 ReturnTypes.explicit(
type),
1837 SqlFunctionCategory.USER_DEFINED_CONSTRUCTOR));
1844 SqlFunction unresolvedFunction, List<RelDataType> argTypes,
1845 List<String> argNames) {
1847 final List<SqlOperator> overloads =
new ArrayList<>();
1848 opTab.lookupOperatorOverloads(unresolvedFunction.getNameAsId(), null,
1849 SqlSyntax.FUNCTION, overloads,
catalogReader.nameMatcher());
1850 if (overloads.size() == 1) {
1851 SqlFunction fun = (SqlFunction) overloads.get(0);
1852 if ((fun.getSqlIdentifier() == null)
1853 && (fun.getSyntax() != SqlSyntax.FUNCTION_ID)) {
1854 final int expectedArgCount =
1855 fun.getOperandCountRange().
getMin();
1857 RESOURCE.invalidArgCount(call.getOperator().getName(),
1862 AssignableOperandTypeChecker typeChecking =
1863 new AssignableOperandTypeChecker(argTypes, argNames);
1865 typeChecking.getAllowedSignatures(
1867 unresolvedFunction.getName());
1869 RESOURCE.validatorUnknownFunction(signature));
1873 @Nonnull RelDataType inferredType,
1874 @Nonnull SqlValidatorScope scope,
1875 @Nonnull SqlNode node) {
1876 Objects.requireNonNull(inferredType);
1877 Objects.requireNonNull(scope);
1878 Objects.requireNonNull(node);
1879 final SqlValidatorScope newScope = scopes.get(node);
1880 if (newScope != null) {
1883 boolean isNullLiteral = SqlUtil.isNullLiteral(node,
false);
1884 if ((node instanceof SqlDynamicParam) || isNullLiteral) {
1886 if (isNullLiteral) {
1887 if (
config.typeCoercionEnabled()) {
1900 RelDataType newInferredType =
1901 typeFactory.createTypeWithNullability(inferredType,
true);
1902 if (SqlTypeUtil.inCharFamily(inferredType)) {
1904 typeFactory.createTypeWithCharsetAndCollation(
1906 inferredType.getCharset(),
1907 inferredType.getCollation());
1910 }
else if (node instanceof SqlNodeList) {
1911 SqlNodeList nodeList = (SqlNodeList) node;
1912 if (inferredType.isStruct()) {
1913 if (inferredType.getFieldCount() != nodeList.size()) {
1921 for (SqlNode child : nodeList) {
1923 if (inferredType.isStruct()) {
1924 type = inferredType.getFieldList().
get(i).getType();
1927 type = inferredType;
1931 }
else if (node instanceof SqlCase) {
1932 final SqlCase caseCall = (SqlCase) node;
1934 final RelDataType whenType =
1936 for (SqlNode sqlNode : caseCall.getWhenOperands().getList()) {
1939 RelDataType returnType =
deriveType(scope, node);
1940 for (SqlNode sqlNode : caseCall.getThenOperands().getList()) {
1944 if (!SqlUtil.isNullLiteral(caseCall.getElseOperand(),
false)) {
1948 caseCall.getElseOperand());
1952 }
else if (node.getKind() == SqlKind.AS) {
1955 }
else if (node instanceof SqlCall) {
1956 final SqlCall call = (SqlCall) node;
1957 final SqlOperandTypeInference operandTypeInference =
1958 call.getOperator().getOperandTypeInference();
1959 final SqlCallBinding callBinding =
new SqlCallBinding(
this, scope, call);
1960 final List<SqlNode> operands = callBinding.operands();
1961 final RelDataType[] operandTypes =
new RelDataType[operands.size()];
1965 if (operandTypeInference != null) {
1966 operandTypeInference.inferOperandTypes(
1971 for (
int i = 0; i < operands.size(); ++i) {
1972 final SqlNode operand = operands.get(i);
1973 if (operand != null) {
1986 Set<String> aliases,
1987 List<Map.Entry<String, RelDataType>> fieldList,
1990 final boolean includeSystemVars) {
1991 String
alias = SqlValidatorUtil.getAlias(exp, -1);
1992 String uniqueAlias =
1993 SqlValidatorUtil.uniquify(
1994 alias, aliases, SqlValidatorUtil.EXPR_SUGGESTER);
1995 if (!Objects.equals(alias, uniqueAlias)) {
1996 exp = SqlValidatorUtil.addAlias(exp, uniqueAlias);
1998 fieldList.add(Pair.of(uniqueAlias,
deriveType(scope, exp)));
2005 return SqlValidatorUtil.getAlias(node, ordinal);
2013 SqlValidatorScope parentScope,
2014 SqlValidatorScope usingScope,
2015 SqlMatchRecognize call,
2016 SqlNode enclosingNode,
2018 boolean forceNullable) {
2020 final MatchRecognizeNamespace matchRecognizeNamespace =
2024 final MatchRecognizeScope matchRecognizeScope =
2025 new MatchRecognizeScope(parentScope, call);
2026 scopes.put(call, matchRecognizeScope);
2029 SqlNode expr = call.getTableRef();
2030 SqlNode newExpr =
registerFrom(usingScope, matchRecognizeScope,
true, expr,
2031 expr, null, null, forceNullable,
false);
2032 if (expr != newExpr) {
2033 call.setOperand(0, newExpr);
2038 SqlMatchRecognize call,
2039 SqlNode enclosingNode) {
2040 return new MatchRecognizeNamespace(
this, call, enclosingNode);
2055 SqlValidatorScope usingScope,
2057 SqlValidatorNamespace ns,
2058 boolean forceNullable) {
2059 namespaces.put(ns.getNode(), ns);
2060 if (usingScope != null) {
2061 usingScope.addChild(ns,
alias, forceNullable);
2097 SqlValidatorScope parentScope,
2098 SqlValidatorScope usingScope,
2101 SqlNode enclosingNode,
2103 SqlNodeList extendList,
2104 boolean forceNullable,
2105 final boolean lateral) {
2106 final SqlKind kind = node.getKind();
2112 SqlNode newNode = node;
2113 if (alias == null) {
2118 if (alias == null) {
2121 if (
config.identifierExpansion()) {
2122 newNode = SqlValidatorUtil.addAlias(node,
alias);
2132 case OTHER_FUNCTION:
2133 case COLLECTION_TABLE:
2134 case MATCH_RECOGNIZE:
2139 if (
config.identifierExpansion()) {
2144 newNode = SqlValidatorUtil.addAlias(node,
alias);
2151 SqlValidatorScope s = usingScope;
2152 while (s instanceof JoinScope) {
2153 s = ((JoinScope) s).getUsingScope();
2155 final SqlNode node2 = s != null ? s.getNode() : node;
2156 final TableScope
tableScope =
new TableScope(parentScope, node2);
2157 if (usingScope instanceof ListScope) {
2158 for (ScopeChild child : ((ListScope) usingScope).children) {
2159 tableScope.addChild(child.namespace,
child.name, child.nullable);
2171 call = (SqlCall) node;
2172 if (alias == null) {
2173 alias = call.operand(1).
toString();
2175 final boolean needAlias = call.operandCount() > 2;
2176 expr = call.operand(0);
2188 if (newExpr != expr) {
2189 call.setOperand(0, newExpr);
2198 new AliasNamespace(
this, call, enclosingNode),
2202 case MATCH_RECOGNIZE:
2204 (SqlMatchRecognize) node, enclosingNode, alias, forceNullable);
2207 call = (SqlCall) node;
2208 expr = call.operand(0);
2220 if (newExpr != expr) {
2221 call.setOperand(0, newExpr);
2226 final SqlJoin
join = (SqlJoin) node;
2227 final JoinScope joinScope =
2228 new JoinScope(parentScope, usingScope, join);
2229 scopes.put(
join, joinScope);
2230 final SqlNode left = join.getLeft();
2231 final SqlNode right = join.getRight();
2232 boolean forceLeftNullable = forceNullable;
2233 boolean forceRightNullable = forceNullable;
2234 switch (join.getJoinType()) {
2236 forceRightNullable =
true;
2239 forceLeftNullable =
true;
2242 forceLeftNullable =
true;
2243 forceRightNullable =
true;
2246 final SqlNode newLeft =
2257 if (newLeft != left) {
2258 join.setLeft(newLeft);
2260 final SqlNode newRight =
2271 if (newRight != right) {
2272 join.setRight(newRight);
2275 final JoinNamespace joinNamespace =
new JoinNamespace(
this, join);
2280 final SqlIdentifier
id = (SqlIdentifier) node;
2281 final IdentifierNamespace newNs =
2282 new IdentifierNamespace(
2283 this,
id, extendList, enclosingNode,
2288 tableScope =
new TableScope(parentScope, node);
2290 tableScope.addChild(newNs,
alias, forceNullable);
2291 if (extendList != null && extendList.size() != 0) {
2292 return enclosingNode;
2301 ((SqlCall) node).operand(0),
2308 case COLLECTION_TABLE:
2309 call = (SqlCall) node;
2310 operand = call.operand(0);
2320 forceNullable, lateral);
2321 if (newOperand != operand) {
2322 call.setOperand(0, newOperand);
2326 if (operand instanceof SqlBasicCall) {
2327 final SqlBasicCall call1 = (SqlBasicCall) operand;
2329 if (op instanceof SqlWindowTableFunction
2330 && call1.operand(0).getKind() == SqlKind.SELECT) {
2338 scopes.put(node, usingScope);
2343 return registerFrom(parentScope, usingScope,
register, node,
2344 enclosingNode, alias, extendList, forceNullable,
true);
2353 case OTHER_FUNCTION:
2354 if (alias == null) {
2359 register ? usingScope : null,
2368 throw Util.unexpected(kind);
2370 call = (SqlCall) node;
2371 final OverScope overScope =
new OverScope(usingScope, call);
2372 scopes.put(call, overScope);
2373 operand = call.operand(0);
2385 if (newOperand != operand) {
2386 call.setOperand(0, newOperand);
2389 for (ScopeChild child : overScope.children) {
2391 child.namespace, forceNullable);
2397 call = (SqlCall) node;
2407 if (extendList != null && extendList.size() != 0) {
2408 return enclosingNode;
2413 final SqlCall extend = (SqlCall) node;
2417 extend.getOperandList().get(0),
2420 (SqlNodeList) extend.getOperandList().
get(1),
2425 call = (SqlCall) node;
2426 operand = call.operand(0);
2437 if (newOperand != operand) {
2438 call.setOperand(0, newOperand);
2443 scopes.put(node, usingScope);
2447 throw Util.unexpected(kind);
2465 SqlNode enclosingNode) {
2466 return new SelectNamespace(
this, select, enclosingNode);
2480 SqlNode enclosingNode) {
2481 return new SetopNamespace(
this, call, enclosingNode);
2495 SqlValidatorScope parentScope,
2496 SqlValidatorScope usingScope,
2498 SqlNode enclosingNode,
2500 boolean forceNullable) {
2501 Preconditions.checkArgument(usingScope == null || alias != null);
2525 SqlValidatorScope parentScope,
2526 SqlValidatorScope usingScope,
2528 SqlNode enclosingNode,
2530 boolean forceNullable,
2531 boolean checkUpdate) {
2532 Objects.requireNonNull(node);
2533 Objects.requireNonNull(enclosingNode);
2534 Preconditions.checkArgument(usingScope == null || alias != null);
2537 List<SqlNode> operands;
2538 switch (node.getKind()) {
2540 final SqlSelect select = (SqlSelect) node;
2541 final SelectNamespace selectNs =
2544 final SqlValidatorScope windowParentScope =
2545 (usingScope != null) ? usingScope : parentScope;
2546 SelectScope selectScope =
2547 new SelectScope(parentScope, windowParentScope, select);
2548 scopes.put(select, selectScope);
2551 clauseScopes.put(IdPair.of(select,
Clause.WHERE), selectScope);
2555 SqlSelect.WHERE_OPERAND);
2560 final SqlNode from = select.getFrom();
2562 final SqlNode newFrom =
2573 if (newFrom != from) {
2574 select.setFrom(newFrom);
2581 SqlValidatorScope aggScope = selectScope;
2584 new AggregatingSelectScope(selectScope, select,
false);
2585 clauseScopes.put(IdPair.of(select,
Clause.SELECT), aggScope);
2587 clauseScopes.put(IdPair.of(select,
Clause.SELECT), selectScope);
2589 if (select.getGroup() != null) {
2590 GroupByScope groupByScope =
2591 new GroupByScope(selectScope, select.getGroup(), select);
2598 SqlSelect.HAVING_OPERAND);
2600 final SqlNodeList orderList = select.getOrderList();
2601 if (orderList != null) {
2604 if (select.isDistinct()) {
2606 new AggregatingSelectScope(selectScope, select,
true);
2608 OrderByScope orderScope =
2609 new OrderByScope(aggScope, orderList, select);
2610 clauseScopes.put(IdPair.of(select,
Clause.ORDER), orderScope);
2616 SqlNode agg = aggFinder.findAgg(orderList);
2625 validateFeature(RESOURCE.sQLFeature_F302(), node.getParserPosition());
2636 validateFeature(RESOURCE.sQLFeature_E071_03(), node.getParserPosition());
2657 registerWith(parentScope, usingScope, (SqlWith) node, enclosingNode,
2658 alias, forceNullable, checkUpdate);
2662 call = (SqlCall) node;
2663 scopes.put(call, parentScope);
2664 final TableConstructorNamespace tableConstructorNamespace =
2665 new TableConstructorNamespace(
2673 tableConstructorNamespace,
2675 operands = call.getOperandList();
2676 for (
int i = 0; i < operands.size(); ++i) {
2677 assert operands.get(i).getKind() == SqlKind.ROW;
2687 SqlInsert insertCall = (SqlInsert) node;
2698 insertCall.getSource(),
2705 SqlDelete deleteCall = (SqlDelete) node;
2716 deleteCall.getSourceSelect(),
2725 node.getParserPosition());
2727 SqlUpdate updateCall = (SqlUpdate) node;
2738 updateCall.getSourceSelect(),
2745 validateFeature(RESOURCE.sQLFeature_F312(), node.getParserPosition());
2746 SqlMerge mergeCall = (SqlMerge) node;
2757 mergeCall.getSourceSelect(),
2766 if (mergeCall.getUpdateCall() != null) {
2770 mergeCall.getUpdateCall(),
2776 if (mergeCall.getInsertCall() != null) {
2780 mergeCall.getInsertCall(),
2788 call = (SqlCall) node;
2789 final UnnestNamespace unnestNs =
2790 new UnnestNamespace(
this, call, parentScope, enclosingNode);
2797 scopes.put(node, parentScope);
2799 case OTHER_FUNCTION:
2800 call = (SqlCall) node;
2801 ProcedureNamespace procNs =
2802 new ProcedureNamespace(
2815 case MULTISET_QUERY_CONSTRUCTOR:
2816 case MULTISET_VALUE_CONSTRUCTOR:
2817 validateFeature(RESOURCE.sQLFeature_S271(), node.getParserPosition());
2818 call = (SqlCall) node;
2819 CollectScope cs =
new CollectScope(parentScope, usingScope, call);
2820 final CollectNamespace tableConstructorNs =
2821 new CollectNamespace(call, cs, enclosingNode);
2828 operands = call.getOperandList();
2829 for (
int i = 0; i < operands.size(); i++) {
2835 throw Util.unexpected(node.getKind());
2840 SqlValidatorScope parentScope,
2841 SqlValidatorScope usingScope,
2843 SqlNode enclosingNode,
2845 boolean forceNullable) {
2846 SqlCall call = (SqlCall) node;
2847 final SetopNamespace setopNamespace =
2852 scopes.put(call, parentScope);
2853 for (SqlNode operand : call.getOperandList()) {
2865 SqlValidatorScope parentScope,
2866 SqlValidatorScope usingScope,
2868 SqlNode enclosingNode,
2870 boolean forceNullable,
2871 boolean checkUpdate) {
2872 final WithNamespace withNamespace =
2873 new WithNamespace(
this, with, enclosingNode);
2876 SqlValidatorScope scope = parentScope;
2877 for (SqlNode withItem_ : with.withList) {
2878 final SqlWithItem withItem = (SqlWithItem) withItem_;
2879 final WithScope withScope =
new WithScope(scope, withItem);
2880 scopes.put(withItem, withScope);
2883 withItem.name.getSimple(),
false);
2885 new WithItemNamespace(
this, withItem, enclosingNode),
2890 registerQuery(scope, null, with.body, enclosingNode, alias, forceNullable,
2899 for (SqlCall call :
overFinder.findAll(select.getSelectList())) {
2900 assert call.getKind() == SqlKind.OVER;
2912 AggFinder nestedAggFinder =
2915 return nestedAggFinder.findAgg(node) != null;
2919 return aggFinder.findAgg(node) != null;
2929 SqlNode node = select.getGroup();
2933 node = select.getHaving();
2944 if (selectScope != null) {
2945 final List<SqlNode> selectList = selectScope.getExpandedSelectList();
2946 if (selectList != null) {
2947 return aggFinder.findAgg(selectList);
2950 return aggFinder.findAgg(select.getSelectList());
2955 return aggFinder.findAgg(selectNode) != null;
2959 switch (node.getKind()) {
2960 case MULTISET_VALUE_CONSTRUCTOR:
2961 validateFeature(RESOURCE.sQLFeature_S271(), node.getParserPosition());
2967 SqlValidatorScope parentScope,
2972 if (node.getKind().belongsTo(SqlKind.QUERY)
2973 || node.getKind() == SqlKind.MULTISET_QUERY_CONSTRUCTOR
2974 || node.getKind() == SqlKind.MULTISET_VALUE_CONSTRUCTOR) {
2976 }
else if (node instanceof SqlCall) {
2978 SqlCall call = (SqlCall) node;
2979 for (
int i = 0; i < call.operandCount(); i++) {
2982 }
else if (node instanceof SqlNodeList) {
2983 SqlNodeList list = (SqlNodeList) node;
2984 for (
int i = 0, count = list.size(); i < count; i++) {
2985 SqlNode listNode = list.get(i);
2986 if (listNode.getKind().belongsTo(SqlKind.QUERY)) {
2988 SqlStdOperatorTable.SCALAR_QUERY.createCall(
2989 listNode.getParserPosition(),
2991 list.set(i, listNode);
3010 SqlValidatorScope parentScope,
3012 int operandOrdinal) {
3013 SqlNode operand = call.operand(operandOrdinal);
3014 if (operand == null) {
3017 if (operand.getKind().belongsTo(SqlKind.QUERY)
3018 && call.getOperator().argumentMustBeScalar(operandOrdinal)) {
3020 SqlStdOperatorTable.SCALAR_QUERY.createCall(
3021 operand.getParserPosition(),
3023 call.setOperand(operandOrdinal, operand);
3029 final SqlQualified fqId = scope.fullyQualify(id);
3030 if (this.
config.columnReferenceExpansion()) {
3033 id.assignNamesFrom(fqId.identifier);
3040 switch (literal.getTypeName()) {
3051 BigDecimal bd = (BigDecimal) literal.getValue();
3052 BigInteger unscaled = bd.unscaledValue();
3053 long longValue = unscaled.longValue();
3054 if (!BigInteger.valueOf(longValue).equals(unscaled)) {
3057 RESOURCE.numberLiteralOutOfRange(bd.toString()));
3066 final BitString bitString = (BitString) literal.getValue();
3067 if ((bitString.getBitCount() % 8) != 0) {
3075 Calendar calendar = literal.getValueAs(Calendar.class);
3076 final int year = calendar.get(Calendar.YEAR);
3077 final int era = calendar.get(Calendar.ERA);
3078 if (year < 1 || era == GregorianCalendar.BC || year > 9999) {
3080 RESOURCE.dateLiteralOutOfRange(literal.toString()));
3085 case INTERVAL_YEAR_MONTH:
3086 case INTERVAL_MONTH:
3088 case INTERVAL_DAY_HOUR:
3089 case INTERVAL_DAY_MINUTE:
3090 case INTERVAL_DAY_SECOND:
3092 case INTERVAL_HOUR_MINUTE:
3093 case INTERVAL_HOUR_SECOND:
3094 case INTERVAL_MINUTE:
3095 case INTERVAL_MINUTE_SECOND:
3096 case INTERVAL_SECOND:
3097 if (literal instanceof SqlIntervalLiteral) {
3098 SqlIntervalLiteral.IntervalValue interval =
3099 literal.getValueAs(SqlIntervalLiteral.IntervalValue.class);
3100 SqlIntervalQualifier intervalQualifier =
3101 interval.getIntervalQualifier();
3105 String intervalStr = interval.getIntervalLiteral();
3107 int[] values = intervalQualifier.evaluateIntervalLiteral(intervalStr,
3108 literal.getParserPosition(),
typeFactory.getTypeSystem());
3109 Util.discard(values);
3118 BigDecimal bd = (BigDecimal) literal.getValue();
3119 double d = bd.doubleValue();
3120 if (
Double.isInfinite(d) || Double.isNaN(d)) {
3123 RESOURCE.numberLiteralOutOfRange(Util.toScientificNotation(bd)));
3130 assert qualifier != null;
3131 boolean startPrecisionOutOfRange =
false;
3132 boolean fractionalSecondPrecisionOutOfRange =
false;
3133 final RelDataTypeSystem typeSystem = typeFactory.getTypeSystem();
3135 final int startPrecision = qualifier.getStartPrecision(typeSystem);
3136 final int fracPrecision =
3137 qualifier.getFractionalSecondPrecision(typeSystem);
3138 final int maxPrecision = typeSystem.getMaxPrecision(qualifier.typeName());
3139 final int minPrecision = qualifier.typeName().getMinPrecision();
3140 final int minScale = qualifier.typeName().getMinScale();
3141 final int maxScale = typeSystem.getMaxScale(qualifier.typeName());
3142 if (startPrecision < minPrecision || startPrecision > maxPrecision) {
3143 startPrecisionOutOfRange =
true;
3145 if (fracPrecision < minScale || fracPrecision > maxScale) {
3146 fractionalSecondPrecisionOutOfRange =
true;
3150 if (startPrecisionOutOfRange) {
3152 RESOURCE.intervalStartPrecisionOutOfRange(startPrecision,
3153 "INTERVAL " + qualifier));
3154 }
else if (fractionalSecondPrecisionOutOfRange) {
3156 RESOURCE.intervalFractionalSecondPrecisionOutOfRange(
3158 "INTERVAL " + qualifier));
3174 RelDataType targetRowType,
3175 SqlValidatorScope scope) {
3176 Objects.requireNonNull(targetRowType);
3177 switch (node.getKind()) {
3181 ((SqlCall) node).operand(0),
3208 throw new AssertionError(
"OVER unexpected in this context");
3211 protected void validateUnnest(SqlCall call, SqlValidatorScope scope, RelDataType targetRowType) {
3212 for (
int i = 0; i < call.operandCount(); i++) {
3213 SqlNode expandedItem =
expand(call.operand(i), scope);
3214 call.setOperand(i, expandedItem);
3220 SqlNode leftOrRight, SqlValidatorScope scope) {
3221 SqlValidatorNamespace
namespace =
getNamespace(leftOrRight, scope);
3222 if (
namespace != null) {
3223 SqlValidatorTable sqlValidatorTable = namespace.getTable();
3224 if (sqlValidatorTable != null) {
3225 Table table = sqlValidatorTable.unwrap(Table.class);
3226 String column = Util.last(identifier.names);
3228 if (table.isRolledUp(column)) {
3230 RESOURCE.rolledUpNotAllowed(column,
"USING"));
3237 SqlNode left = join.getLeft();
3238 SqlNode right = join.getRight();
3239 SqlNode condition = join.getCondition();
3240 boolean natural = join.isNatural();
3241 final JoinType joinType = join.getJoinType();
3242 final JoinConditionType conditionType = join.getConditionType();
3243 final SqlValidatorScope joinScope = scopes.get(
join);
3248 switch (conditionType) {
3250 Preconditions.checkArgument(condition == null);
3253 Preconditions.checkArgument(condition != null);
3254 SqlNode expandedCondition =
expand(condition, joinScope);
3255 join.setOperand(5, expandedCondition);
3256 condition = join.getCondition();
3258 checkRollUp(null, join, condition, joinScope,
"ON");
3261 SqlNodeList list = (SqlNodeList) condition;
3264 Preconditions.checkArgument(list.size() > 0,
"Empty USING clause");
3265 for (SqlNode node : list) {
3266 SqlIdentifier
id = (SqlIdentifier) node;
3269 if (!SqlTypeUtil.isComparable(leftColType, rightColType)) {
3271 RESOURCE.naturalOrUsingColumnNotCompatible(
id.getSimple(),
3272 leftColType.toString(), rightColType.toString()));
3279 throw Util.unexpected(conditionType);
3284 if (condition != null) {
3286 RESOURCE.naturalDisallowsOnOrUsing());
3291 final RelDataType leftRowType =
getNamespace(left).getRowType();
3292 final RelDataType rightRowType =
getNamespace(right).getRowType();
3293 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
3294 List<String> naturalColumnNames =
3295 SqlValidatorUtil.deriveNaturalJoinColumnList(nameMatcher,
3296 leftRowType, rightRowType);
3299 for (String
name : naturalColumnNames) {
3300 final RelDataType leftColType =
3301 nameMatcher.field(leftRowType,
name).getType();
3302 final RelDataType rightColType =
3303 nameMatcher.field(rightRowType,
name).getType();
3304 if (!SqlTypeUtil.isComparable(leftColType, rightColType)) {
3306 RESOURCE.naturalOrUsingColumnNotCompatible(
name,
3307 leftColType.toString(), rightColType.toString()));
3315 case LEFT_SEMI_JOIN:
3316 if (!this.
config.sqlConformance().isLiberal()) {
3318 RESOURCE.dialectDoesNotSupportFeature(
"LEFT SEMI JOIN"));
3325 if ((condition == null) && !natural) {
3331 if (condition != null) {
3333 RESOURCE.crossJoinDisallowsCondition());
3337 RESOURCE.crossJoinDisallowsCondition());
3341 throw Util.unexpected(joinType);
3355 final SqlCall agg = aggFinder.findAgg(node);
3360 if (op == SqlStdOperatorTable.OVER) {
3362 RESOURCE.windowedAggregateIllegalInClause(clause));
3363 }
else if (op.
isGroup() || op.isGroupAuxiliary()) {
3365 RESOURCE.groupFunctionMustAppearInGroupByClause(op.
getName()));
3368 RESOURCE.aggregateIllegalInClause(clause));
3373 if (
id.names.size() == 1) {
3374 String
name = id.names.get(0);
3375 final SqlValidatorNamespace
namespace = getNamespace(leftOrRight);
3376 final RelDataType rowType = namespace.getRowType();
3377 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
3378 final RelDataTypeField
field = nameMatcher.field(rowType,
name);
3379 if (
field != null) {
3380 if (nameMatcher.frequency(rowType.getFieldNames(),
name) > 1) {
3382 RESOURCE.columnInUsingNotUnique(
id.toString()));
3384 return field.getType();
3399 RelDataType targetRowType) {
3400 assert targetRowType != null;
3402 final SelectNamespace ns =
3408 assert ns.rowType == null;
3410 if (select.isDistinct()) {
3412 select.getModifierNode(SqlSelectKeyword.DISTINCT)
3413 .getParserPosition());
3416 final SqlNodeList selectItems = select.getSelectList();
3418 if (selectItems.size() == 1) {
3419 final SqlNode selectItem = selectItems.get(0);
3420 if (selectItem instanceof SqlIdentifier) {
3421 SqlIdentifier
id = (SqlIdentifier) selectItem;
3422 if (
id.isStar() && (id.names.size() == 1)) {
3428 fromType = targetRowType;
3434 final SelectScope fromScope = (SelectScope)
getFromScope(select);
3435 List<String> names = fromScope.getChildNames();
3437 names = names.stream()
3438 .map(s -> s.toUpperCase(Locale.ROOT))
3439 .collect(Collectors.toList());
3441 final int duplicateAliasOrdinal = Util.firstDuplicate(names);
3442 if (duplicateAliasOrdinal >= 0) {
3443 final ScopeChild child =
3444 fromScope.children.get(duplicateAliasOrdinal);
3449 if (select.getFrom() == null) {
3450 if (this.
config.sqlConformance().isFromRequired()) {
3466 final RelDataType rowType =
3468 ns.setType(rowType);
3487 for (SqlNode item : select.getSelectList()) {
3493 SqlNodeList group = select.getGroup();
3494 if (group != null) {
3495 for (SqlNode node : group) {
3502 SqlNodeList orderList = select.getOrderList();
3503 if (orderList != null) {
3504 for (SqlNode node : orderList) {
3511 if (window != null) {
3512 for (SqlNode node : window.getPartitionList()) {
3513 checkRollUp(null, window, node, scope,
"PARTITION BY");
3516 for (SqlNode node : window.getOrderList()) {
3517 checkRollUp(null, window, node, scope,
"ORDER BY");
3523 for (SqlNode decl : select.getWindowList()) {
3529 if (node != null && node.getKind() == SqlKind.DOT) {
3530 return stripDot(((SqlCall) node).operand(0));
3536 SqlNode current, SqlValidatorScope scope, String optionalClause) {
3537 current = stripAs(current);
3538 if (current instanceof SqlCall && !(current instanceof SqlSelect)) {
3543 List<SqlNode> children = ((SqlCall) stripAs(
stripDot(current))).getOperandList();
3544 for (SqlNode child : children) {
3545 checkRollUp(parent, current, child, scope, optionalClause);
3547 }
else if (current instanceof SqlIdentifier) {
3548 SqlIdentifier
id = (SqlIdentifier) current;
3552 String context = optionalClause != null ? optionalClause : parent.getKind().
toString();
3554 RESOURCE.rolledUpNotAllowed(
deriveAlias(
id, 0), context));
3561 SqlNode current, SqlValidatorScope scope) {
3562 checkRollUp(grandParent, parent, current, scope, null);
3566 if (over.getKind() == SqlKind.OVER) {
3567 SqlNode window = ((SqlCall) over).getOperandList().
get(1);
3568 if (window instanceof SqlWindow) {
3569 return (SqlWindow) window;
3578 switch (node.getKind()) {
3580 return ((SqlCall) node).getOperandList().get(0);
3587 SqlValidatorScope scope) {
3592 SqlQualified qualified = scope.fullyQualify(identifier);
3593 List<String> names = qualified.identifier.names;
3595 if (names.size() < 2) {
3599 return new Pair<>(names.get(names.size() - 2), Util.last(names));
3604 SqlCall aggCall, SqlNode parent) {
3611 String columnName = pair.right;
3613 SqlValidatorTable sqlValidatorTable =
3614 scope.fullyQualify(identifier).
namespace.getTable();
3615 if (sqlValidatorTable != null) {
3616 Table table = sqlValidatorTable.unwrap(Table.class);
3617 return table.rolledUpColumnValidInsideAgg(columnName, aggCall, parent,
3618 catalogReader.getConfig());
3632 String columnName = pair.right;
3634 SqlValidatorTable sqlValidatorTable =
3635 scope.fullyQualify(identifier).
namespace.getTable();
3636 if (sqlValidatorTable != null) {
3637 Table table = sqlValidatorTable.unwrap(Table.class);
3638 return table.isRolledUp(columnName);
3645 SqlKind kind = stripAs(from).getKind();
3646 return kind != SqlKind.VALUES && kind != SqlKind.SELECT;
3655 if (query instanceof SqlSelect) {
3656 final SqlSelect select = (SqlSelect) query;
3658 }
else if (query.getKind() == SqlKind.VALUES) {
3664 assert query.isA(SqlKind.SET_QUERY);
3665 final SqlCall call = (SqlCall) query;
3666 for (SqlNode operand : call.getOperandList()) {
3669 Static.RESOURCE.streamSetOpInconsistentInputs());
3678 if (query instanceof SqlSelect) {
3679 SqlSelect select = (SqlSelect) query;
3680 return select.getModifierNode(SqlSelectKeyword.STREAM) != null
3681 ? SqlModality.STREAM
3682 : SqlModality.RELATION;
3683 }
else if (query.getKind() == SqlKind.VALUES) {
3684 return SqlModality.RELATION;
3686 assert query.isA(SqlKind.SET_QUERY);
3687 final SqlCall call = (SqlCall) query;
3698 if (scope.children.size() == 1) {
3699 for (ScopeChild child : scope.children) {
3700 if (!child.namespace.supportsModality(modality)) {
3703 Static.RESOURCE.cannotConvertToStream(
child.name));
3710 int supportsModalityCount = 0;
3711 for (ScopeChild child : scope.children) {
3712 if (child.namespace.supportsModality(modality)) {
3713 ++supportsModalityCount;
3717 if (supportsModalityCount == 0) {
3719 String inputs = String.join(
", ", scope.getChildNames());
3721 Static.RESOURCE.cannotStreamResultsForNonStreamingInputs(inputs));
3729 for (ScopeChild child : scope.children) {
3730 if (!child.namespace.supportsModality(modality)) {
3733 Static.RESOURCE.cannotConvertToRelation(
child.name));
3743 if (aggregateNode != null) {
3746 SqlNodeList groupList = select.getGroup();
3747 if (groupList == null
3748 || !SqlValidatorUtil.containsMonotonic(scope, groupList)) {
3751 Static.RESOURCE.streamMustGroupByMonotonic());
3760 final SqlNodeList orderList = select.getOrderList();
3761 if (orderList != null && orderList.size() > 0) {
3767 Static.RESOURCE.streamMustOrderByMonotonic());
3783 boolean descending) {
3784 switch (node.getKind()) {
3789 final SqlMonotonicity monotonicity = scope.getMonotonicity(node);
3790 switch (monotonicity) {
3792 case STRICTLY_INCREASING:
3795 case STRICTLY_DECREASING:
3803 final SqlNodeList windowList = select.getWindowList();
3804 @SuppressWarnings(
"unchecked")
final List<SqlWindow> windows =
3805 (List) windowList.getList();
3806 if (windows.isEmpty()) {
3810 final SelectScope windowScope = (SelectScope)
getFromScope(select);
3811 assert windowScope != null;
3815 for (SqlWindow window : windows) {
3816 SqlIdentifier declName = window.getDeclName();
3817 if (!declName.isSimple()) {
3821 if (windowScope.existingWindowName(declName.toString())) {
3824 windowScope.addWindowName(declName.toString());
3830 for (
int i = 0; i < windows.size(); i++) {
3831 SqlNode window1 = windows.get(i);
3832 for (
int j = i + 1; j < windows.size(); j++) {
3833 SqlNode window2 = windows.get(j);
3834 if (window1.equalsDeep(window2, Litmus.IGNORE)) {
3840 for (SqlWindow window : windows) {
3841 final SqlNodeList expandedOrderList =
3842 (SqlNodeList)
expand(window.getOrderList(), windowScope);
3843 window.setOrderList(expandedOrderList);
3844 expandedOrderList.validate(
this, windowScope);
3846 final SqlNodeList expandedPartitionList =
3847 (SqlNodeList)
expand(window.getPartitionList(), windowScope);
3848 window.setPartitionList(expandedPartitionList);
3849 expandedPartitionList.validate(
this, windowScope);
3853 windowList.validate(
this, windowScope);
3857 final SqlValidatorNamespace
namespace = getNamespace(with);
3862 if (withItem.columnList != null) {
3864 final int fieldCount = rowType.getFieldCount();
3865 if (withItem.columnList.size() != fieldCount) {
3867 RESOURCE.columnCountMismatch());
3869 SqlValidatorUtil.checkIdentifierListForDuplicates(
3873 final List<String> fieldNames =
3875 final int i = Util.firstDuplicate(fieldNames);
3878 RESOURCE.duplicateColumnAndNoColumnList(fieldNames.get(i)));
3885 final SqlValidatorScope.ResolvedImpl resolved =
3886 new SqlValidatorScope.ResolvedImpl();
3887 scope.resolveTable(id.names, catalogReader.nameMatcher(),
3888 SqlValidatorScope.Path.EMPTY, resolved);
3889 if (resolved.count() != 1) {
3893 final SqlValidatorNamespace ns = resolved.only().
namespace;
3894 if (ns instanceof TableNamespace) {
3895 final Table table = ns.getTable().unwrap(Table.class);
3896 switch (table.getJdbcTableType()) {
3898 case TEMPORARY_SEQUENCE:
3906 assert withItem.getKind() == SqlKind.WITH_ITEM;
3907 return scopes.get(withItem);
3911 assert config.typeCoercionEnabled();
3912 return this.typeCoercion;
3920 this.config = transform.apply(this.config);
3933 SqlNodeList orderList = select.getOrderList();
3934 if (orderList == null) {
3943 Objects.requireNonNull(orderScope);
3945 List<SqlNode> expandList =
new ArrayList<>();
3946 for (SqlNode orderItem : orderList) {
3947 SqlNode expandedOrderItem =
expand(orderItem, orderScope);
3948 expandList.add(expandedOrderItem);
3951 SqlNodeList expandedOrderList =
new SqlNodeList(
3953 orderList.getParserPosition());
3954 select.setOrderBy(expandedOrderList);
3956 for (SqlNode orderItem : expandedOrderList) {
3968 final SqlValidatorScope groupByScope =
getGroupScope(select);
3970 groupByScope.validateExpr(groupByItem);
3974 SqlValidatorScope groupByScope) {
3975 switch (groupByItem.getKind()) {
3979 final SqlCall call = (SqlCall) groupByItem;
3980 for (SqlNode operand : call.getOperandList()) {
3996 switch (orderItem.getKind()) {
3999 orderItem.getParserPosition());
4001 ((SqlCall) orderItem).operand(0));
4010 final SqlNode newSqlNode =
4012 if (newSqlNode != orderExpr) {
4026 SqlNodeList groupList = select.getGroup();
4027 if (groupList == null) {
4030 final String clause =
"GROUP BY";
4036 List<SqlNode> expandedList =
new ArrayList<>();
4037 for (SqlNode groupItem : groupList) {
4039 expandedList.add(expandedItem);
4041 groupList =
new SqlNodeList(expandedList, groupList.getParserPosition());
4042 select.setGroupBy(groupList);
4043 for (SqlNode groupItem : expandedList) {
4050 for (SqlNode node : groupList) {
4051 switch (node.getKind()) {
4055 node.validate(
this, groupScope);
4058 node.validateExpr(
this, groupScope);
4066 AggregatingSelectScope aggregatingScope = null;
4067 if (selectScope instanceof AggregatingSelectScope) {
4068 aggregatingScope = (AggregatingSelectScope) selectScope;
4070 for (SqlNode groupItem : groupList) {
4071 if (groupItem instanceof SqlNodeList
4072 && ((SqlNodeList) groupItem).size() == 0) {
4078 SqlNode agg = aggFinder.findAgg(groupList);
4085 AggregatingSelectScope aggregatingScope,
4086 SqlNode groupItem) {
4087 switch (groupItem.getKind()) {
4094 if (groupItem instanceof SqlNodeList) {
4103 AggregatingSelectScope aggregatingScope, SqlCall groupItem) {
4104 for (SqlNode node : groupItem.getOperandList()) {
4111 final SqlNode where = select.getWhere();
4112 if (where == null) {
4116 final SqlNode expandedWhere =
expand(where, whereScope);
4117 select.setWhere(expandedWhere);
4122 SqlValidatorScope scope,
4130 condition.validate(
this, scope);
4133 if (!SqlTypeUtil.inBooleanFamily(type)) {
4143 SqlNode having = select.getHaving();
4144 if (having == null) {
4147 final AggregatingScope havingScope =
4149 if (
config.sqlConformance().isHavingAlias()) {
4151 if (having != newExpr) {
4153 select.setHaving(newExpr);
4156 havingScope.checkAggregateExpr(having,
true);
4161 having.validate(
this, havingScope);
4163 if (!SqlTypeUtil.inBooleanFamily(type)) {
4169 final SqlNodeList selectItems,
4171 RelDataType targetRowType) {
4177 final List<SqlNode> expandedSelectItems =
new ArrayList<>();
4178 final Set<String> aliases =
new HashSet<>();
4179 final List<Map.Entry<String, RelDataType>> fieldList =
new ArrayList<>();
4181 for (SqlNode selectItem : selectItems) {
4182 if (selectItem instanceof SqlSelect) {
4185 (SqlSelect) selectItem,
4186 expandedSelectItems,
4192 final int fieldIdx = fieldList.size();
4193 final RelDataType fieldType =
4194 targetRowType.isStruct()
4195 && targetRowType.getFieldCount() > fieldIdx
4196 ? targetRowType.getFieldList().
get(fieldIdx).getType()
4202 expandedSelectItems,
4212 SqlNodeList newSelectList =
4214 expandedSelectItems,
4215 selectItems.getParserPosition());
4216 if (
config.identifierExpansion()) {
4217 select.setSelectList(newSelectList);
4225 for (SqlNode selectItem : expandedSelectItems) {
4230 return typeFactory.createStructType(fieldList);
4240 if (expr instanceof SqlCall) {
4241 final SqlOperator op = ((SqlCall) expr).getOperator();
4244 RESOURCE.absentOverClause());
4246 if (op instanceof SqlTableFunction) {
4247 throw RESOURCE.cannotCallTableFunctionHere(op.getName()).ex();
4252 expr.validateExpr(
this, scope);
4256 scope.validateExpr(expr);
4271 SqlSelect parentSelect,
4272 SqlSelect selectItem,
4273 List<SqlNode> expandedSelectItems,
4274 Set<String> aliasList,
4275 List<Map.Entry<String, RelDataType>> fieldList) {
4277 if (1 != selectItem.getSelectList().size()) {
4279 RESOURCE.onlyScalarSubQueryAllowed());
4283 expandedSelectItems.add(selectItem);
4286 final String
alias =
4290 aliasList.add(
alias);
4292 final SelectScope scope = (SelectScope)
getWhereScope(parentSelect);
4299 assert type instanceof RelRecordType;
4300 RelRecordType rec = (RelRecordType) type;
4302 RelDataType nodeType = rec.getFieldList().
get(0).getType();
4303 nodeType = typeFactory.createTypeWithNullability(nodeType,
true);
4304 fieldList.add(Pair.of(
alias, nodeType));
4317 SqlValidatorTable table,
4318 SqlNodeList targetColumnList,
4320 RelDataType baseRowType = table.getRowType();
4321 if (targetColumnList == null) {
4324 List<RelDataTypeField> targetFields = baseRowType.getFieldList();
4325 final List<Map.Entry<String, RelDataType>> fields =
new ArrayList<>();
4327 for (RelDataTypeField targetField : targetFields) {
4329 Pair.of(SqlUtil.deriveAliasFromOrdinal(fields.size()),
4330 targetField.getType()));
4333 final Set<Integer> assignedFields =
new HashSet<>();
4334 final RelOptTable relOptTable = table instanceof RelOptTable
4335 ? ((RelOptTable) table) : null;
4336 for (SqlNode node : targetColumnList) {
4337 SqlIdentifier
id = (SqlIdentifier) node;
4338 RelDataTypeField targetField =
4339 SqlValidatorUtil.getTargetField(
4341 if (targetField == null) {
4343 RESOURCE.unknownTargetColumn(
id.toString()));
4345 if (!assignedFields.add(targetField.getIndex())) {
4347 RESOURCE.duplicateTargetColumn(targetField.getName()));
4349 fields.add(targetField);
4351 return typeFactory.createStructType(fields);
4355 final SqlValidatorNamespace targetNamespace =
getNamespace(insert);
4357 final RelOptTable relOptTable = SqlValidatorUtil.getRelOptTable(
4358 targetNamespace, catalogReader.unwrap(Prepare.CatalogReader.class), null, null);
4359 final SqlValidatorTable table = relOptTable == null
4360 ? targetNamespace.getTable()
4361 : relOptTable.unwrap(SqlValidatorTable.class);
4366 final RelDataType targetRowType =
4369 insert.getTargetColumnList(),
4372 final SqlNode source = insert.getSource();
4373 if (source instanceof SqlSelect) {
4374 final SqlSelect sqlSelect = (SqlSelect) source;
4377 final SqlValidatorScope scope = scopes.get(source);
4386 final RelDataType sourceRowType =
getNamespace(source).getRowType();
4387 final RelDataType logicalTargetRowType =
4390 final RelDataType logicalSourceRowType =
4393 final List<ColumnStrategy> strategies =
4394 table.unwrap(RelOptTable.class).getColumnStrategies();
4396 final RelDataType realTargetRowType = typeFactory.createStructType(
4397 logicalTargetRowType.getFieldList()
4398 .stream().filter(
f -> strategies.get(f.getIndex()).canInsertInto())
4399 .collect(Collectors.toList()));
4401 final RelDataType targetRowTypeToValidate =
4402 logicalSourceRowType.getFieldCount() == logicalTargetRowType.getFieldCount()
4403 ? logicalTargetRowType
4404 : realTargetRowType;
4407 targetRowTypeToValidate, realTargetRowType,
4408 source, logicalSourceRowType, logicalTargetRowType);
4412 logicalSourceRowType,
4413 targetRowTypeToValidate,
4418 validateAccess(insert.getTargetTable(), table, SqlAccessEnum.INSERT);
4432 SqlValidatorTable validatorTable,
4434 RelDataType targetRowType) {
4435 final ModifiableViewTable modifiableViewTable =
4436 validatorTable.unwrap(ModifiableViewTable.class);
4437 if (modifiableViewTable != null && source instanceof SqlCall) {
4438 final Table table = modifiableViewTable.unwrap(Table.class);
4439 final RelDataType tableRowType = table.getRowType(
typeFactory);
4440 final List<RelDataTypeField> tableFields = tableRowType.getFieldList();
4444 final Map<Integer, RelDataTypeField> tableIndexToTargetField =
4445 SqlValidatorUtil.getIndexToFieldMap(tableFields, targetRowType);
4446 final Map<Integer, RexNode> projectMap =
4447 RelOptUtil.getColumnConstraints(modifiableViewTable, targetRowType,
typeFactory);
4451 final ImmutableBitSet targetColumns =
4452 ImmutableBitSet.of(tableIndexToTargetField.keySet());
4453 final ImmutableBitSet constrainedColumns =
4454 ImmutableBitSet.of(projectMap.keySet());
4455 final ImmutableBitSet constrainedTargetColumns =
4456 targetColumns.intersect(constrainedColumns);
4459 final List<SqlNode> values = ((SqlCall) source).getOperandList();
4460 for (
final int colIndex : constrainedTargetColumns.asList()) {
4461 final String colName = tableFields.get(colIndex).getName();
4462 final RelDataTypeField targetField = tableIndexToTargetField.get(colIndex);
4463 for (SqlNode row : values) {
4464 final SqlCall call = (SqlCall) row;
4465 final SqlNode sourceValue = call.operand(targetField.getIndex());
4468 RESOURCE.viewConstraintNotSatisfied(colName,
4469 Util.last(validatorTable.getQualifiedName())));
4470 RelOptUtil.validateValueAgainstConstraint(sourceValue,
4471 projectMap.get(colIndex), validationError);
4486 SqlValidatorTable validatorTable,
4488 RelDataType targetRowType) {
4489 final ModifiableViewTable modifiableViewTable =
4490 validatorTable.unwrap(ModifiableViewTable.class);
4491 if (modifiableViewTable != null) {
4492 final Table table = modifiableViewTable.unwrap(Table.class);
4493 final RelDataType tableRowType = table.getRowType(
typeFactory);
4495 final Map<Integer, RexNode> projectMap =
4496 RelOptUtil.getColumnConstraints(modifiableViewTable, targetRowType,
4498 final Map<String, Integer> nameToIndex =
4499 SqlValidatorUtil.mapNameToIndex(tableRowType.getFieldList());
4502 final List<SqlNode> targets = update.getTargetColumnList().getList();
4503 final List<SqlNode> sources = update.getSourceExpressionList().getList();
4504 for (
final Pair<SqlNode, SqlNode> column : Pair.zip(targets, sources)) {
4505 final String columnName = ((SqlIdentifier) column.left).getSimple();
4506 final Integer columnIndex = nameToIndex.get(columnName);
4507 if (projectMap.containsKey(columnIndex)) {
4508 final RexNode columnConstraint = projectMap.get(columnIndex);
4511 RESOURCE.viewConstraintNotSatisfied(columnName,
4512 Util.last(validatorTable.getQualifiedName())));
4513 RelOptUtil.validateValueAgainstConstraint(column.right,
4514 columnConstraint, validationError);
4536 List<ColumnStrategy> strategies, RelDataType targetRowTypeToValidate,
4537 RelDataType realTargetRowType, SqlNode source,
4538 RelDataType logicalSourceRowType, RelDataType logicalTargetRowType) {
4539 final int sourceFieldCount = logicalSourceRowType.getFieldCount();
4540 final int targetFieldCount = logicalTargetRowType.getFieldCount();
4541 final int targetRealFieldCount = realTargetRowType.getFieldCount();
4542 if (sourceFieldCount != targetFieldCount
4543 && sourceFieldCount != targetRealFieldCount) {
4548 RESOURCE.unmatchInsertColumn(targetFieldCount, sourceFieldCount));
4551 for (
final RelDataTypeField
field : table.getRowType().getFieldList()) {
4552 final RelDataTypeField targetField =
4553 targetRowTypeToValidate.getField(field.getName(),
true,
false);
4554 switch (strategies.get(
field.getIndex())) {
4556 assert !field.getType().isNullable();
4557 if (targetField == null) {
4559 RESOURCE.columnNotNullable(
field.getName()));
4563 assert field.getType().isNullable();
4567 if (targetField != null
4570 RESOURCE.insertIntoAlwaysGenerated(
field.getName()));
4579 switch (source.getKind()) {
4581 for (SqlNode operand : ((SqlCall) source).getOperandList()) {
4592 switch (operand.getKind()) {
4594 final SqlCall row = (SqlCall) operand;
4595 return row.getOperandList().size() >= column
4596 && row.getOperandList().
get(column).getKind() == SqlKind.DEFAULT;
4602 RelDataType targetRowType,
4604 if (insert.getTargetColumnList() == null
4605 && this.config.sqlConformance().isInsertSubsetColumnsAllowed()) {
4607 final SqlNode source = insert.getSource();
4608 final RelDataType sourceRowType =
getNamespace(source).getRowType();
4609 final RelDataType logicalSourceRowType =
4611 final RelDataType implicitTargetRowType =
4612 typeFactory.createStructType(
4613 targetRowType.getFieldList()
4614 .subList(0, logicalSourceRowType.getFieldCount()));
4615 final SqlValidatorNamespace targetNamespace =
getNamespace(insert);
4617 return implicitTargetRowType;
4621 return targetRowType;
4626 RelDataType sourceRowType,
4628 return sourceRowType;
4646 SqlValidatorScope sourceScope,
4647 SqlValidatorTable table,
4648 RelDataType sourceRowType,
4649 RelDataType targetRowType,
4650 final SqlNode query) {
4654 boolean isUpdateModifiableViewTable =
false;
4655 if (query instanceof SqlUpdate) {
4656 final SqlNodeList targetColumnList = ((SqlUpdate) query).getTargetColumnList();
4657 if (targetColumnList != null) {
4658 final int targetColumnCnt = targetColumnList.size();
4659 targetRowType = SqlTypeUtil.extractLastNFields(
typeFactory, targetRowType,
4661 sourceRowType = SqlTypeUtil.extractLastNFields(
typeFactory, sourceRowType,
4664 isUpdateModifiableViewTable = table.unwrap(ModifiableViewTable.class) != null;
4666 if (SqlTypeUtil.equalAsStructSansNullability(
typeFactory,
4673 if (
config.typeCoercionEnabled() && !isUpdateModifiableViewTable) {
4675 boolean coerced = typeCoercion.querySourceCoercion(sourceScope,
4685 List<RelDataTypeField> sourceFields = sourceRowType.getFieldList();
4686 List<RelDataTypeField> targetFields = targetRowType.getFieldList();
4687 final int sourceCount = sourceFields.size();
4688 for (
int i = 0; i < sourceCount; ++i) {
4689 RelDataType sourceType = sourceFields.get(i).getType();
4690 RelDataType targetType = targetFields.get(i).getType();
4691 if (!SqlTypeUtil.canAssignFrom(targetType, sourceType)) {
4692 SqlNode node =
getNthExpr(query, i, sourceCount);
4693 if (node instanceof SqlDynamicParam) {
4696 String targetTypeString;
4697 String sourceTypeString;
4698 if (SqlTypeUtil.areCharacterSetsMismatched(
4701 sourceTypeString = sourceType.getFullTypeString();
4702 targetTypeString = targetType.getFullTypeString();
4704 sourceTypeString = sourceType.toString();
4705 targetTypeString = targetType.toString();
4708 RESOURCE.typeNotAssignable(
4709 targetFields.get(i).getName(), targetTypeString,
4710 sourceFields.get(i).getName(), sourceTypeString));
4723 private SqlNode
getNthExpr(SqlNode query,
int ordinal,
int sourceCount) {
4724 if (query instanceof SqlInsert) {
4725 SqlInsert insert = (SqlInsert) query;
4726 if (insert.getTargetColumnList() != null) {
4727 return insert.getTargetColumnList().
get(ordinal);
4734 }
else if (query instanceof SqlUpdate) {
4735 SqlUpdate update = (SqlUpdate) query;
4736 if (update.getSourceExpressionList() != null) {
4737 return update.getSourceExpressionList().
get(ordinal);
4740 update.getSourceSelect(),
4744 }
else if (query instanceof SqlSelect) {
4745 SqlSelect select = (SqlSelect) query;
4746 if (select.getSelectList().size() == sourceCount) {
4747 return select.getSelectList().
get(ordinal);
4757 final SqlSelect sqlSelect = call.getSourceSelect();
4760 final SqlValidatorNamespace targetNamespace =
getNamespace(call);
4762 final SqlValidatorTable table = targetNamespace.getTable();
4764 validateAccess(call.getTargetTable(), table, SqlAccessEnum.DELETE);
4768 final SqlValidatorNamespace targetNamespace =
getNamespace(call);
4770 final RelOptTable relOptTable = SqlValidatorUtil.getRelOptTable(
4771 targetNamespace, catalogReader.unwrap(Prepare.CatalogReader.class), null, null);
4772 final SqlValidatorTable table = relOptTable == null
4773 ? targetNamespace.getTable()
4774 : relOptTable.unwrap(SqlValidatorTable.class);
4776 final RelDataType targetRowType =
4779 call.getTargetColumnList(),
4782 final SqlSelect select = call.getSourceSelect();
4794 validateAccess(call.getTargetTable(), table, SqlAccessEnum.UPDATE);
4798 SqlSelect sqlSelect = call.getSourceSelect();
4811 IdentifierNamespace targetNamespace =
4812 (IdentifierNamespace)
getNamespace(call.getTargetTable());
4815 SqlValidatorTable table = targetNamespace.getTable();
4816 validateAccess(call.getTargetTable(), table, SqlAccessEnum.UPDATE);
4820 if (call.getUpdateCall() != null) {
4823 call.getUpdateCall().getTargetColumnList(),
4826 if (call.getInsertCall() != null) {
4829 call.getInsertCall().getTargetColumnList(),
4835 if (call.getUpdateCall() != null) {
4838 if (call.getInsertCall() != null) {
4851 SqlValidatorTable table,
4852 SqlAccessEnum requiredAccess) {
4853 if (table != null) {
4854 SqlAccessType access = table.getAllowedAccess();
4855 if (!access.allowsAccess(requiredAccess)) {
4857 RESOURCE.accessNotAllowed(requiredAccess.name(),
4858 table.getQualifiedName().
toString()));
4872 SqlValidatorScope scope,
4873 SqlValidatorNamespace ns) {
4874 if (node.getKind() == SqlKind.SNAPSHOT) {
4875 SqlSnapshot snapshot = (SqlSnapshot) node;
4876 SqlNode period = snapshot.getPeriod();
4877 RelDataType dataType =
deriveType(scope, period);
4878 if (dataType.getSqlTypeName() != SqlTypeName.TIMESTAMP) {
4880 Static.RESOURCE.illegalExpressionForTemporal(dataType.getSqlTypeName().getName()));
4882 if (!ns.getTable().isTemporal()) {
4883 List<String> qualifiedName = ns.getTable().getQualifiedName();
4884 String tableName = qualifiedName.get(qualifiedName.size() - 1);
4886 Static.RESOURCE.notTemporalTable(tableName));
4900 RelDataType targetRowType,
4901 final SqlValidatorScope scope) {
4902 assert node.getKind() == SqlKind.VALUES;
4904 final List<SqlNode> operands = node.getOperandList();
4905 for (SqlNode operand : operands) {
4906 if (!(operand.getKind() == SqlKind.ROW)) {
4907 throw Util.needToImplement(
4908 "Values function where operands are scalars");
4911 SqlCall rowConstructor = (SqlCall) operand;
4912 if (this.
config.sqlConformance().isInsertSubsetColumnsAllowed()
4913 && targetRowType.isStruct()
4914 && rowConstructor.operandCount() < targetRowType.getFieldCount()) {
4916 typeFactory.createStructType(
4917 targetRowType.getFieldList()
4918 .subList(0, rowConstructor.operandCount()));
4919 }
else if (targetRowType.isStruct()
4920 && rowConstructor.operandCount() != targetRowType.getFieldCount()) {
4929 if (targetRowType.isStruct()) {
4930 for (Pair<SqlNode, RelDataTypeField> pair
4931 : Pair.zip(rowConstructor.getOperandList(),
4932 targetRowType.getFieldList())) {
4933 if (!pair.right.getType().isNullable()
4934 && SqlUtil.isNullLiteral(pair.left,
false)) {
4936 RESOURCE.columnNotNullable(pair.right.getName()));
4942 for (SqlNode operand : operands) {
4943 operand.validate(
this, scope);
4950 final int rowCount = operands.size();
4951 if (rowCount >= 2) {
4952 SqlCall firstRow = (SqlCall) operands.get(0);
4953 final int columnCount = firstRow.operandCount();
4956 for (SqlNode operand : operands) {
4957 SqlCall thisRow = (SqlCall) operand;
4958 if (columnCount != thisRow.operandCount()) {
4960 RESOURCE.incompatibleValueType(
4961 SqlStdOperatorTable.VALUES.getName()));
4966 for (
int col = 0; col < columnCount; col++) {
4968 final RelDataType
type =
4969 typeFactory.leastRestrictive(
4970 new AbstractList<RelDataType>() {
4971 public RelDataType
get(
int row) {
4972 SqlCall thisRow = (SqlCall) operands.get(row);
4973 return deriveType(scope, thisRow.operand(c));
4983 RESOURCE.incompatibleValueType(
4984 SqlStdOperatorTable.VALUES.getName()));
5010 public CalciteContextException
get() {
5020 implements Function2<SqlNode, Resources.ExInst<SqlValidatorException>,
5021 CalciteContextException> {
5022 @Override
public CalciteContextException
apply(
5023 SqlNode v0, Resources.ExInst<SqlValidatorException> v1) {
5033 Resources.ExInst<SqlValidatorException> e) {
5034 assert node != null;
5035 final SqlParserPos pos = node.getParserPosition();
5036 return SqlUtil.newContextException(pos, e);
5041 SqlValidatorScope scope) {
5042 SqlWindow window = null;
5043 if (
id.isSimple()) {
5044 final String
name = id.getSimple();
5045 window = scope.lookupWindow(
name);
5047 if (window == null) {
5054 SqlNode windowOrRef,
5055 SqlValidatorScope scope) {
5057 if (windowOrRef instanceof SqlIdentifier) {
5060 window = (SqlWindow) windowOrRef;
5063 final SqlIdentifier refId = window.getRefName();
5064 if (refId == null) {
5067 final String refName = refId.getSimple();
5068 SqlWindow refWindow = scope.lookupWindow(refName);
5069 if (refWindow == null) {
5072 window = window.overlay(refWindow,
this);
5079 SqlNode original = originalExprs.get(expr);
5080 if (original == null) {
5088 originalExprs.putIfAbsent(expr, original);
5092 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
5093 final RelDataTypeField
field = nameMatcher.field(rowType,
name);
5094 if (field == null) {
5097 return new FieldNamespace(
this, field.getType());
5102 SqlValidatorScope scope,
5107 final SqlWindow targetWindow;
5108 switch (windowOrId.getKind()) {
5115 targetWindow = (SqlWindow) windowOrId;
5118 throw Util.unexpected(windowOrId.getKind());
5121 assert targetWindow.getWindowCall() == null;
5122 targetWindow.setWindowCall(call);
5123 targetWindow.validate(
this, scope);
5124 targetWindow.setWindowCall(null);
5125 call.validate(
this, scope);
5134 final SqlMatchRecognize matchRecognize = (SqlMatchRecognize) call;
5135 final MatchRecognizeScope scope =
5138 final MatchRecognizeNamespace ns =
5139 getNamespace(call).unwrap(MatchRecognizeNamespace.class);
5140 assert ns.rowType == null;
5143 final SqlLiteral rowsPerMatch = matchRecognize.getRowsPerMatch();
5144 final boolean allRows = rowsPerMatch != null
5145 && rowsPerMatch.getValue()
5146 == SqlMatchRecognize.RowsPerMatchOption.ALL_ROWS;
5148 final RelDataTypeFactory.Builder typeBuilder =
typeFactory.builder();
5151 SqlNodeList partitionBy = matchRecognize.getPartitionList();
5152 if (partitionBy != null) {
5153 for (SqlNode node : partitionBy) {
5154 SqlIdentifier identifier = (SqlIdentifier) node;
5155 identifier.validate(
this, scope);
5157 String
name = identifier.names.get(1);
5163 SqlNodeList orderBy = matchRecognize.getOrderList();
5164 if (orderBy != null) {
5165 for (SqlNode node : orderBy) {
5166 node.validate(
this, scope);
5167 SqlIdentifier identifier;
5168 if (node instanceof SqlBasicCall) {
5169 identifier = (SqlIdentifier) ((SqlBasicCall) node).getOperands()[0];
5171 identifier = (SqlIdentifier) node;
5176 String
name = identifier.names.get(1);
5177 if (!typeBuilder.nameExists(name)) {
5185 final SqlValidatorNamespace sqlNs =
5187 final RelDataType inputDataType = sqlNs.getRowType();
5188 for (RelDataTypeField fs : inputDataType.getFieldList()) {
5189 if (!typeBuilder.nameExists(fs.getName())) {
5190 typeBuilder.add(fs);
5196 SqlNode pattern = matchRecognize.getPattern();
5198 pattern.accept(visitor);
5200 SqlLiteral interval = matchRecognize.getInterval();
5201 if (interval != null) {
5202 interval.validate(
this, scope);
5203 if (((SqlIntervalLiteral) interval).signum() < 0) {
5205 RESOURCE.intervalMustBeNonNegative(interval.toValue()));
5207 if (orderBy == null || orderBy.size() == 0) {
5209 RESOURCE.cannotUseWithinWithoutOrderBy());
5212 SqlNode firstOrderByColumn = orderBy.getList().
get(0);
5213 SqlIdentifier identifier;
5214 if (firstOrderByColumn instanceof SqlBasicCall) {
5215 identifier = (SqlIdentifier) ((SqlBasicCall) firstOrderByColumn).getOperands()[0];
5217 identifier = (SqlIdentifier) firstOrderByColumn;
5219 RelDataType firstOrderByColumnType =
deriveType(scope, identifier);
5220 if (firstOrderByColumnType.getSqlTypeName() != SqlTypeName.TIMESTAMP) {
5222 RESOURCE.firstColumnOfOrderByMustBeTimestamp());
5232 SqlNodeList subsets = matchRecognize.getSubsetList();
5233 if (subsets != null && subsets.size() > 0) {
5234 for (SqlNode node : subsets) {
5235 List<SqlNode> operands = ((SqlCall) node).getOperandList();
5236 String leftString = ((SqlIdentifier) operands.get(0)).getSimple();
5237 if (scope.getPatternVars().contains(leftString)) {
5239 RESOURCE.patternVarAlreadyDefined(leftString));
5241 scope.addPatternVar(leftString);
5242 for (SqlNode right : (SqlNodeList) operands.get(1)) {
5243 SqlIdentifier
id = (SqlIdentifier) right;
5244 if (!scope.getPatternVars().contains(id.getSimple())) {
5246 RESOURCE.unknownPattern(
id.getSimple()));
5248 scope.addPatternVar(id.getSimple());
5254 final SqlNode skipTo = matchRecognize.getAfter();
5255 if (skipTo instanceof SqlCall) {
5256 final SqlCall skipToCall = (SqlCall) skipTo;
5257 final SqlIdentifier
id = skipToCall.operand(0);
5258 if (!scope.getPatternVars().contains(id.getSimple())) {
5260 RESOURCE.unknownPattern(
id.getSimple()));
5264 List<Map.Entry<String, RelDataType>> measureColumns =
5266 for (Map.Entry<String, RelDataType> c : measureColumns) {
5267 if (!typeBuilder.nameExists(c.getKey())) {
5268 typeBuilder.add(c.getKey(), c.getValue());
5272 final RelDataType rowType = typeBuilder.build();
5273 if (matchRecognize.getMeasureList().size() == 0) {
5274 ns.setType(
getNamespace(matchRecognize.getTableRef()).getRowType());
5276 ns.setType(rowType);
5281 MatchRecognizeScope scope,
boolean allRows) {
5282 final List<String> aliases =
new ArrayList<>();
5283 final List<SqlNode> sqlNodes =
new ArrayList<>();
5284 final SqlNodeList measures = mr.getMeasureList();
5285 final List<Map.Entry<String, RelDataType>> fields =
new ArrayList<>();
5287 for (SqlNode
measure : measures) {
5288 assert
measure instanceof SqlCall;
5302 SqlStdOperatorTable.AS.createCall(SqlParserPos.ZERO,
expand,
5303 new SqlIdentifier(alias, SqlParserPos.ZERO)));
5306 SqlNodeList list =
new SqlNodeList(sqlNodes, measures.getParserPosition());
5309 for (SqlNode node : list) {
5313 mr.setOperand(SqlMatchRecognize.OPERAND_MEASURES, list);
5320 Util.discard(prefix);
5321 final List<SqlNode> ops = ((SqlCall) node).getOperandList();
5324 allRows ? SqlStdOperatorTable.RUNNING : SqlStdOperatorTable.FINAL;
5325 final SqlNode op0 = ops.get(0);
5327 || !allRows && op0.getKind() == SqlKind.RUNNING) {
5328 SqlNode newNode = defaultOp.createCall(SqlParserPos.ZERO, op0);
5329 node = SqlStdOperatorTable.AS.createCall(SqlParserPos.ZERO, newNode, ops.get(1));
5337 MatchRecognizeScope scope) {
5338 final Set<String> aliases = catalogReader.nameMatcher().createSet();
5339 for (SqlNode item : mr.getPatternDefList().getList()) {
5341 if (!aliases.add(alias)) {
5343 Static.RESOURCE.patternVarAlreadyDefined(alias));
5345 scope.addPatternVar(
alias);
5348 final List<SqlNode> sqlNodes =
new ArrayList<>();
5349 for (SqlNode item : mr.getPatternDefList().getList()) {
5356 expand.validate(
this, scope);
5361 SqlStdOperatorTable.AS.createCall(SqlParserPos.ZERO,
expand,
5362 new SqlIdentifier(alias, SqlParserPos.ZERO)));
5365 if (!SqlTypeUtil.inBooleanFamily(type)) {
5372 new SqlNodeList(sqlNodes, mr.getPatternDefList().getParserPosition());
5374 for (SqlNode node : list) {
5377 mr.setOperand(SqlMatchRecognize.OPERAND_PATTERN_DEFINES, list);
5381 private static String
alias(SqlNode item) {
5382 assert item instanceof SqlCall;
5383 assert item.getKind() == SqlKind.AS;
5384 final SqlIdentifier identifier = ((SqlCall) item).operand(1);
5385 return identifier.getSimple();
5393 Util.discard(prefix);
5400 SqlNodeList orderList, SqlValidatorScope scope) {
5424 for (SqlNode param : aggCall.getOperandList()) {
5425 if (a.findAgg(param) != null) {
5429 if (filter != null) {
5430 if (a.findAgg(filter) != null) {
5434 if (orderList != null) {
5435 for (SqlNode param : orderList) {
5436 if (a.findAgg(param) != null) {
5438 RESOURCE.aggregateInWithinGroupIllegal());
5443 final SqlAggFunction op = (SqlAggFunction) aggCall.getOperator();
5444 switch (op.requiresGroupOrder()) {
5446 if (orderList == null || orderList.size() == 0) {
5448 RESOURCE.aggregateMissingWithinGroupClause(op.getName()));
5455 if (orderList != null) {
5456 orderList.getList().clear();
5460 if (orderList != null && orderList.size() != 0) {
5462 RESOURCE.withinGroupClauseIllegalInAggregate(op.getName()));
5466 throw new AssertionError(op);
5472 SqlValidatorScope scope) {
5474 if ((call.operandCount() == 0)
5475 && (
operator.getSyntax() == SqlSyntax.FUNCTION_ID)
5476 && !call.isExpanded()
5477 && !this.config.sqlConformance().allowNiladicParentheses()) {
5482 ImmutableList.of(), null);
5485 SqlValidatorScope operandScope = scope.getOperandScope(call);
5487 if (
operator instanceof SqlFunction
5488 && ((SqlFunction)
operator).getFunctionType()
5489 == SqlFunctionCategory.MATCH_RECOGNIZE
5490 && !(operandScope instanceof MatchRecognizeScope)) {
5492 Static.RESOURCE.functionMatchRecognizeOnly(call.toString()));
5495 operator.validateCall(call,
this, scope, operandScope);
5508 SqlParserPos context) {
5511 assert feature.getProperties().
get(
"FeatureDefinition") != null;
5515 SelectScope scope, SqlSelect select) {
5517 final SqlNode newExpr = expr.accept(expander);
5518 if (expr != newExpr) {
5524 public SqlNode
expand(SqlNode expr, SqlValidatorScope scope) {
5526 SqlNode newExpr = expr.accept(expander);
5527 if (expr != newExpr) {
5534 SqlValidatorScope scope, SqlSelect select,
boolean havingExpression) {
5537 SqlNode newExpr = expr.accept(expander);
5538 if (expr != newExpr) {
5549 if (sqlQuery instanceof SqlExplain) {
5550 return Collections.emptyList();
5553 final int fieldCount = rowType.getFieldCount();
5554 if (!sqlQuery.isA(SqlKind.QUERY)) {
5555 return Collections.nCopies(fieldCount, null);
5557 final List<List<String>> list =
new ArrayList<>();
5558 for (
int i = 0; i < fieldCount; i++) {
5561 return ImmutableNullableList.copyOf(list);
5565 if (sqlQuery instanceof SqlSelect) {
5566 SqlSelect sqlSelect = (SqlSelect) sqlQuery;
5568 final List<SqlNode> selectList = scope.getExpandedSelectList();
5569 final SqlNode selectItem = stripAs(selectList.get(i));
5570 if (selectItem instanceof SqlIdentifier) {
5571 final SqlQualified qualified =
5572 scope.fullyQualify((SqlIdentifier) selectItem);
5573 SqlValidatorNamespace
namespace = qualified.namespace;
5574 final SqlValidatorTable table = namespace.getTable();
5575 if (table == null) {
5578 final List<String> origin =
5579 new ArrayList<>(table.getQualifiedName());
5580 for (String
name : qualified.suffix()) {
5581 namespace = namespace.lookupChild(name);
5582 if (
namespace == null) {
5590 }
else if (sqlQuery instanceof SqlOrderBy) {
5600 final List<RelDataType> types =
new ArrayList<>();
5603 final Set<SqlNode> alreadyVisited =
new HashSet<>();
5607 @Override
public SqlNode visit(SqlDynamicParam param) {
5608 if (alreadyVisited.add(param)) {
5615 return typeFactory.createStructType(
5617 new AbstractList<String>() {
5618 @Override
public String
get(
int index) {
5622 @Override
public int size() {
5623 return types.size();
5629 SqlFunction
function,
5630 List<RelDataType> argTypes,
5631 List<SqlNode> operands) {
5632 throw new UnsupportedOperationException();
5636 return kind == SqlKind.PREV || kind == SqlKind.NEXT;
5640 return kind == SqlKind.FIRST || kind == SqlKind.LAST;
5644 return kind == SqlKind.SUM || kind == SqlKind.SUM0
5645 || kind == SqlKind.AVG || kind == SqlKind.COUNT
5650 return kind == SqlKind.RUNNING || kind == SqlKind.FINAL;
5666 SqlNode enclosingNode, SqlValidatorScope parentScope) {
5667 super(validator,
id, enclosingNode, parentScope);
5678 SqlNode enclosingNode, SqlValidatorScope parentScope) {
5679 super(validator, node.getTargetTable(), enclosingNode, parentScope);
5680 this.node = Objects.requireNonNull(
node);
5695 SqlNode enclosingNode, SqlValidatorScope parentScope) {
5696 super(validator, node.getTargetTable(), enclosingNode, parentScope);
5697 this.node = Objects.requireNonNull(
node);
5712 SqlNode enclosingNode, SqlValidatorScope parentScope) {
5713 super(validator, node.getTargetTable(), enclosingNode, parentScope);
5714 this.node = Objects.requireNonNull(
node);
5729 SqlNode enclosingNode, SqlValidatorScope parentScope) {
5730 super(validator, node.getTargetTable(), enclosingNode, parentScope);
5731 this.node = Objects.requireNonNull(
node);
5751 for (
int i = 0; i < call.getOperandList().size(); i++) {
5752 call.getOperandList().
get(i).accept(
this);
5758 throw Util.needToImplement(nodeList);
5762 Preconditions.checkArgument(id.isSimple());
5763 scope.addPatternVar(id.getSimple());
5768 throw Util.needToImplement(
type);
5772 throw Util.needToImplement(param);
5775 @Override
public Void visit(SqlIntervalQualifier intervalQualifier) {
5776 throw Util.needToImplement(intervalQualifier);
5793 public RelDataType
visit(SqlLiteral literal) {
5797 public RelDataType
visit(SqlCall call) {
5802 public RelDataType
visit(SqlNodeList nodeList) {
5807 throw Util.needToImplement(nodeList);
5810 public RelDataType
visit(SqlIdentifier
id) {
5815 return call.getOperator().validateOperands(
5821 RelDataType
type = null;
5822 if (!(
scope instanceof EmptyScope)) {
5823 id = scope.fullyQualify(id).identifier;
5828 for (i =
id.names.size() - 1; i > 0; i--) {
5837 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
5838 final SqlValidatorScope.ResolvedImpl resolved =
5839 new SqlValidatorScope.ResolvedImpl();
5840 scope.resolve(id.names.subList(0, i), nameMatcher,
false, resolved);
5841 if (resolved.count() == 1) {
5843 final SqlValidatorScope.Resolve resolve = resolved.only();
5844 type = resolve.rowType();
5845 for (SqlValidatorScope.Step p : Util.skip(resolve.path.steps())) {
5846 type = type.getFieldList().
get(p.i).getType();
5854 if (type == null ||
id.names.size() == 1) {
5857 RelDataType colType = scope.resolveColumn(id.names.get(0),
id);
5858 if (colType != null) {
5865 final SqlIdentifier last = id.getComponent(i - 1, i);
5867 RESOURCE.unknownIdentifier(last.toString()));
5871 for (; i < id.names.size(); i++) {
5872 String
name = id.names.get(i);
5873 final RelDataTypeField
field;
5874 if (name.equals(
"")) {
5880 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
5881 field = nameMatcher.field(
type,
name);
5883 if (field == null) {
5885 RESOURCE.unknownField(name));
5887 type = field.getType();
5890 SqlTypeUtil.addCharsetAndCollation(
5896 public RelDataType
visit(SqlDataTypeSpec dataType) {
5904 public RelDataType
visit(SqlDynamicParam param) {
5908 public RelDataType
visit(SqlIntervalQualifier intervalQualifier) {
5909 return typeFactory.createSqlIntervalType(intervalQualifier);
5917 private static class Expander extends SqlScopedShuttle {
5925 @Override
public SqlNode
visit(SqlIdentifier
id) {
5928 final SqlCall call = validator.makeNullaryCall(id);
5930 return call.accept(
this);
5932 final SqlIdentifier fqId = getScope().fullyQualify(id).identifier;
5934 validator.setOriginal(expandedExpr, id);
5935 return expandedExpr;
5939 switch (call.getKind()) {
5959 boolean bCreate = call.getOperator().requiresCreate(call.getOperandList());
5960 ArgHandler<SqlNode> argHandler =
5961 new CallCopyingArgHandler(call, bCreate);
5964 call.getOperator().acceptCall(
this, call,
true, argHandler);
5965 final SqlNode
result = argHandler.result();
5966 validator.setOriginal(
result, call);
5971 if (DynamicRecordType.isDynamicStarColName(Util.last(fqId.names))
5972 && !DynamicRecordType.isDynamicStarColName(Util.last(
id.names))) {
5975 SqlNode[] inputs =
new SqlNode[2];
5977 inputs[1] = SqlLiteral.createCharString(
5978 Util.last(id.names),
5979 id.getParserPosition());
5980 return new SqlBasicCall(
5981 SqlStdOperatorTable.ITEM,
5983 id.getParserPosition());
6002 this.aliasList =
getNamespace(select).getRowType().getFieldNames();
6006 return root.accept(
this);
6009 public SqlNode
visit(SqlLiteral literal) {
6013 if (literal ==
root &&
config.sqlConformance().isSortByOrdinal()) {
6014 switch (literal.getTypeName()) {
6017 final int intValue = literal.intValue(
false);
6018 if (intValue >= 0) {
6019 if (intValue < 1 || intValue >
aliasList.size()) {
6021 literal, RESOURCE.orderByOrdinalOutOfRange());
6025 int ordinal = intValue - 1;
6032 return super.visit(literal);
6043 SqlNodeList expandedSelectList =
6048 SqlNode expr = expandedSelectList.get(ordinal);
6049 expr = stripAs(expr);
6050 if (expr instanceof SqlIdentifier) {
6051 expr = getScope().fullyQualify((SqlIdentifier) expr).identifier;
6056 return expr.clone(pos);
6059 public SqlNode
visit(SqlIdentifier
id) {
6062 &&
config.sqlConformance().isSortByAlias()) {
6063 String
alias = id.getSimple();
6065 final RelDataType rowType =
6066 selectNs.getRowTypeSansSystemColumns();
6067 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
6068 RelDataTypeField
field = nameMatcher.field(rowType,
alias);
6069 if (field != null) {
6072 id.getParserPosition());
6077 return getScope().fullyQualify(id).identifier;
6083 if (call instanceof SqlSelect) {
6086 return super.visitScoped(call);
6100 super(validator, scope);
6104 @Override
public SqlNode
visit(SqlIdentifier
id) {
6109 return super.visit(id);
6126 super(validator, scope);
6132 @Override
public SqlNode
visit(SqlIdentifier
id) {
6133 if (
id.isSimple() && getScope() instanceof GroupByScope) {
6134 RelDataType dataType = getScope().resolveColumn(id.names.get(0),
id);
6137 if (dataType != null) {
6138 return super.visit(id);
6143 ? validator.config().sqlConformance().isHavingAlias()
6145 String
name = id.getSimple();
6146 SqlNode expr = null;
6147 final SqlNameMatcher nameMatcher =
6148 validator.catalogReader.nameMatcher();
6150 for (SqlNode s :
select.getSelectList()) {
6151 final String
alias = SqlValidatorUtil.getAlias(s, -1);
6152 if (alias != null && nameMatcher.matches(alias, name)) {
6158 return super.visit(id);
6161 throw validator.newValidationError(id,
6162 RESOURCE.columnAmbiguous(
name));
6165 return super.visit(id);
6167 expr = stripAs(expr);
6168 if (expr instanceof SqlIdentifier) {
6169 SqlIdentifier sid = (SqlIdentifier) expr;
6170 final SqlIdentifier fqId = getScope().fullyQualify(sid).identifier;
6183 expr = expr.accept(
this);
6190 if (
id.isSimple()) {
6191 final SelectScope scope = validator.getRawSelectScope(
select);
6197 return super.visit(id);
6200 public SqlNode
visit(SqlLiteral literal) {
6202 return super.visit(literal);
6204 boolean isOrdinalLiteral = literal ==
root;
6205 switch (
root.getKind()) {
6209 if (
root instanceof SqlBasicCall) {
6210 List<SqlNode> operandList = ((SqlBasicCall)
root).getOperandList();
6211 for (SqlNode node : operandList) {
6212 if (node.equals(literal)) {
6213 isOrdinalLiteral =
true;
6220 if (isOrdinalLiteral) {
6221 switch (literal.getTypeName()) {
6224 final int intValue = literal.intValue(
false);
6225 if (intValue >= 0) {
6226 if (intValue < 1 || intValue >
select.getSelectList().size()) {
6227 throw validator.newValidationError(literal,
6228 RESOURCE.orderByOrdinalOutOfRange());
6232 int ordinal = intValue - 1;
6241 SqlNode node = SqlUtil.stripAs(select.getSelectList().
get(ordinal));
6245 node = node.accept(
this);
6255 return super.visit(literal);
6262 public final SqlIdentifier
id;
6299 public SqlNode
go(SqlNode node) {
6300 return node.accept(
this);
6329 @Override
public SqlNode
visit(SqlCall call) {
6330 SqlKind kind = call.getKind();
6331 List<SqlNode> operands = call.getOperandList();
6332 List<SqlNode> newOperands =
new ArrayList<>();
6334 if (call.getFunctionQuantifier() != null
6335 && call.getFunctionQuantifier().getValue() == SqlSelectKeyword.DISTINCT) {
6336 final SqlParserPos pos = call.getParserPosition();
6337 throw SqlUtil.newContextException(pos,
6338 Static.RESOURCE.functionQuantifierNotAllowed(call.toString()));
6342 SqlNode inner = operands.get(0);
6343 SqlNode
offset = operands.get(1);
6347 SqlKind innerKind = inner.getKind();
6349 List<SqlNode> innerOperands = ((SqlCall) inner).getOperandList();
6350 SqlNode innerOffset = innerOperands.get(1);
6352 ? SqlStdOperatorTable.PLUS : SqlStdOperatorTable.MINUS;
6353 offset = newOperator.createCall(SqlParserPos.ZERO,
6355 inner = call.getOperator().createCall(SqlParserPos.ZERO,
6356 innerOperands.get(0),
offset);
6359 SqlNode newInnerNode =
6362 newInnerNode = op.createCall(SqlParserPos.ZERO, newInnerNode,
6365 return newInnerNode;
6368 if (operands.size() > 0) {
6369 for (SqlNode node : operands) {
6373 newNode = op.createCall(SqlParserPos.ZERO, newNode,
offset);
6375 newOperands.add(newNode);
6377 newOperands.add(null);
6380 return call.getOperator().createCall(SqlParserPos.ZERO, newOperands);
6385 return op.createCall(SqlParserPos.ZERO, call,
offset);
6390 @Override
public SqlNode
visit(SqlIdentifier
id) {
6394 return op.createCall(SqlParserPos.ZERO, id,
offset);
6418 @Override
public SqlNode
visit(SqlCall call) {
6419 SqlKind kind = call.getKind();
6428 final List<SqlNode> operands = call.getOperandList();
6429 if (operands.get(0) instanceof SqlIdentifier) {
6430 String
name = ((SqlIdentifier) operands.get(0)).names.get(0);
6431 return name.equals(
alpha) ? call
6432 : SqlStdOperatorTable.LAST.createCall(SqlParserPos.ZERO, operands);
6435 return super.visit(call);
6438 @Override
public SqlNode
visit(SqlIdentifier
id) {
6439 if (
id.isSimple()) {
6443 ? SqlStdOperatorTable.PREV : SqlStdOperatorTable.LAST;
6445 return operator.createCall(SqlParserPos.ZERO, id,
6446 SqlLiteral.createExactNumeric(
"0", SqlParserPos.ZERO));
6470 @Override
public Set<String>
visit(SqlCall call) {
6471 boolean isSingle =
false;
6472 Set<String> vars =
new HashSet<>();
6473 SqlKind kind = call.getKind();
6474 List<SqlNode> operands = call.getOperandList();
6481 Static.RESOURCE.patternPrevFunctionInMeasure(call.toString()));
6485 Static.RESOURCE.patternPrevFunctionOrder(call.toString()));
6491 Static.RESOURCE.patternPrevFunctionOrder(call.toString()));
6498 Static.RESOURCE.patternAggregationInNavigation(call.toString()));
6500 if (kind == SqlKind.COUNT && call.getOperandList().size() > 1) {
6502 Static.RESOURCE.patternCountFunctionArg());
6510 Static.RESOURCE.patternRunningFunctionInDefine(call.toString()));
6513 for (SqlNode node : operands) {
6525 if (vars.size() > 1) {
6527 Static.RESOURCE.patternCountFunctionArg());
6531 if (operands.size() == 0
6532 || !(operands.get(0) instanceof SqlCall)
6533 || ((SqlCall) operands.get(0)).getOperator() != SqlStdOperatorTable.CLASSIFIER) {
6534 if (vars.isEmpty()) {
6536 Static.RESOURCE.patternFunctionNullCheck(call.toString()));
6538 if (vars.size() != 1) {
6540 Static.RESOURCE.patternFunctionVariableCheck(call.toString()));
6549 @Override
public Set<String>
visit(SqlIdentifier identifier) {
6551 Set<String> vars =
new HashSet<>();
6552 if (identifier.names.size() > 1 && check) {
6553 vars.add(identifier.names.get(0));
6558 @Override
public Set<String>
visit(SqlLiteral literal) {
6559 return ImmutableSet.of();
6562 @Override
public Set<String>
visit(SqlIntervalQualifier qualifier) {
6563 return ImmutableSet.of();
6567 return ImmutableSet.of();
6570 @Override
public Set<String>
visit(SqlDynamicParam param) {
6571 return ImmutableSet.of();
6582 switch (from.getKind()) {
6584 final SqlJoin
join = (SqlJoin) from;
6586 final int fieldCount =
6589 new Permute(join.getRight(), offset + fieldCount);
6591 final List<ImmutableIntList>
sources =
new ArrayList<>();
6592 final Set<ImmutableIntList> sourceSet =
new HashSet<>();
6593 final RelDataTypeFactory.Builder b = typeFactory.builder();
6594 if (names != null) {
6595 for (String
name : names) {
6596 final RelDataTypeField
f = left.field(
name);
6597 final ImmutableIntList source = left.sources.get(f.getIndex());
6598 sourceSet.add(source);
6599 final RelDataTypeField f2 = right.field(
name);
6600 final ImmutableIntList source2 = right.sources.get(f2.getIndex());
6601 sourceSet.add(source2);
6602 sources.add(source.appendAll(source2));
6603 final boolean nullable =
6604 (f.getType().isNullable()
6605 || join.getJoinType().generatesNullsOnLeft())
6606 && (f2.getType().isNullable()
6607 || join.getJoinType().generatesNullsOnRight());
6608 b.add(
f).nullable(nullable);
6611 for (RelDataTypeField
f : left.
rowType.getFieldList()) {
6612 final ImmutableIntList source = left.sources.get(f.getIndex());
6613 if (sourceSet.add(source)) {
6614 sources.add(source);
6618 for (RelDataTypeField
f : right.rowType.getFieldList()) {
6619 final ImmutableIntList source = right.sources.get(f.getIndex());
6620 if (sourceSet.add(source)) {
6621 sources.add(source);
6626 this.sources = ImmutableList.copyOf(
sources);
6627 this.trivial = left.trivial
6629 && (names == null || names.isEmpty());
6634 this.sources = Functions.generate(rowType.getFieldCount(),
6635 i -> ImmutableIntList.of(offset + i));
6636 this.trivial =
true;
6641 return catalogReader.nameMatcher().
field(
rowType, name);
6646 List<Map.Entry<String, RelDataType>> fields) {
6651 final List<SqlNode> oldSelectItems = ImmutableList.copyOf(selectItems);
6652 selectItems.clear();
6653 final List<Map.Entry<String, RelDataType>> oldFields =
6654 ImmutableList.copyOf(fields);
6656 for (ImmutableIntList source :
sources) {
6657 final int p0 = source.get(0);
6658 Map.Entry<String, RelDataType>
field = oldFields.get(p0);
6659 final String
name = field.getKey();
6660 RelDataType
type = field.getValue();
6661 SqlNode selectItem = oldSelectItems.get(p0);
6662 for (
int p1 : Util.skip(source)) {
6663 final Map.Entry<String, RelDataType> field1 = oldFields.get(p1);
6664 final SqlNode selectItem1 = oldSelectItems.get(p1);
6665 final RelDataType type1 = field1.getValue();
6667 final boolean nullable = type.isNullable() && type1.isNullable();
6668 final RelDataType type2 =
6672 SqlStdOperatorTable.AS.createCall(SqlParserPos.ZERO,
6673 SqlStdOperatorTable.COALESCE.createCall(SqlParserPos.ZERO,
6676 new SqlIdentifier(name, SqlParserPos.ZERO));
6677 type = typeFactory.createTypeWithNullability(type2, nullable);
6680 selectItems.add(selectItem);
void rewriteMerge(SqlMerge call)
void lookupSelectHints(SqlValidatorNamespace ns, SqlParserPos pos, Collection< SqlMoniker > hintList)
void checkRollUpInOrderBy(SqlSelect select)
RelDataType validateSelectList(final SqlNodeList selectItems, SqlSelect select, RelDataType targetRowType)
SqlNode getAggregate(SqlSelect select)
SqlNode expandGroupByOrHavingExpr(SqlNode expr, SqlValidatorScope scope, SqlSelect select, boolean havingExpression)
void validateNamespace(final SqlValidatorNamespace namespace, RelDataType targetRowType)
boolean isRowWithDefault(SqlNode operand, int column)
final List< ImmutableIntList > sources
SqlValidatorImpl(SqlOperatorTable opTab, SqlValidatorCatalogReader catalogReader, RelDataTypeFactory typeFactory, Config config)
final Map< SqlNode, SqlNode > originalExprs
void registerSubQueries(SqlValidatorScope parentScope, SqlNode node)
final SqlValidatorImpl validator
SqlNode rewriteUpdateToMerge(SqlUpdate updateCall, SqlNode selfJoinSrcExpr)
final Map< String, String > columnListParamToParentCursorMap
static boolean isLogicalNavigation(SqlKind kind)
final RelDataType booleanType
void lookupJoinHints(SqlJoin join, SqlValidatorScope scope, SqlParserPos pos, Collection< SqlMoniker > hintList)
size_t append(FILE *f, const size_t size, const int8_t *buf)
Appends the specified number of bytes to the end of the file f from buf.
void checkConstraint(SqlValidatorTable validatorTable, SqlNode source, RelDataType targetRowType)
SqlValidatorScope getEmptyScope()
Set< String > visit(SqlDynamicParam param)
void checkFieldCount(SqlNode node, SqlValidatorTable table, List< ColumnStrategy > strategies, RelDataType targetRowTypeToValidate, RelDataType realTargetRowType, SqlNode source, RelDataType logicalSourceRowType, RelDataType logicalTargetRowType)
CalciteException handleUnresolvedFunction(SqlCall call, SqlFunction unresolvedFunction, List< RelDataType > argTypes, List< String > argNames)
DmlNamespace(SqlValidatorImpl validator, SqlNode id, SqlNode enclosingNode, SqlValidatorScope parentScope)
RelDataType validateUsingCol(SqlIdentifier id, SqlNode leftOrRight)
SqlValidatorNamespace getNamespace(SqlIdentifier id, DelegatingScope scope)
SqlNode validate(SqlNode topNode)
SqlCall makeNullaryCall(SqlIdentifier id)
void validateModality(SqlNode query)
List< SqlMoniker > lookupHints(SqlNode topNode, SqlParserPos pos)
void lookupSelectHints(SqlSelect select, SqlParserPos pos, Collection< SqlMoniker > hintList)
final RelDataType unknownType
SqlNode expandDynamicStar(SqlIdentifier id, SqlIdentifier fqId)
SqlValidatorScope getHavingScope(SqlSelect select)
SqlNode visit(SqlCall call)
SqlNode visit(SqlIdentifier id)
SqlWindow getWindowInOver(SqlNode over)
Set< String > visit(SqlCall call)
Set< String > visit(SqlDataTypeSpec type)
void checkRollUpInGroupBy(SqlSelect select)
void validateWith(SqlWith with, SqlValidatorScope scope)
SqlNode navigationInMeasure(SqlNode node, boolean allRows)
DeriveTypeVisitor(SqlValidatorScope scope)
static boolean isPhysicalNavigation(SqlKind kind)
final Deque< FunctionParamInfo > functionCallStack
void setOriginal(SqlNode expr, SqlNode original)
SqlSelect getInnerSelect(SqlNode node)
SqlNode registerFrom(SqlValidatorScope parentScope, SqlValidatorScope usingScope, boolean register, final SqlNode node, SqlNode enclosingNode, String alias, SqlNodeList extendList, boolean forceNullable, final boolean lateral)
SqlNode nthSelectItem(int ordinal, final SqlParserPos pos)
SqlOperatorTable getOperatorTable()
SqlValidatorNamespace getNamespace(SqlNode node, SqlValidatorScope scope)
TypeCoercion typeCoercion
RelDataType getLogicalSourceRowType(RelDataType sourceRowType, SqlInsert insert)
final AggFinder aggOrOverFinder
void validateOver(SqlCall call, SqlValidatorScope scope)
Pair< String, String > findTableColumnPair(SqlIdentifier identifier, SqlValidatorScope scope)
boolean addOrExpandField(List< SqlNode > selectItems, Set< String > aliases, List< Map.Entry< String, RelDataType >> fields, boolean includeSystemVars, SelectScope scope, SqlIdentifier id, RelDataTypeField field)
void validateWindow(SqlNode windowOrId, SqlValidatorScope scope, SqlCall call)
List< String > getFieldOrigin(SqlNode sqlQuery, int i)
CalciteContextException newValidationError(SqlNode node, Resources.ExInst< SqlValidatorException > e)
boolean shouldAllowOverRelation()
RelDataTypeFactory getTypeFactory()
SqlValidator transform(UnaryOperator< Config > transform)
void validateFrom(SqlNode node, RelDataType targetRowType, SqlValidatorScope scope)
void validateSequenceValue(SqlValidatorScope scope, SqlIdentifier id)
SelectScope getRawSelectScope(SqlSelect select)
final AggFinder aggOrOverOrGroupFinder
void registerMatchRecognize(SqlValidatorScope parentScope, SqlValidatorScope usingScope, SqlMatchRecognize call, SqlNode enclosingNode, String alias, boolean forceNullable)
void validateColumnListParams(SqlFunction function, List< RelDataType > argTypes, List< SqlNode > operands)
void validateAccess(SqlNode node, SqlValidatorTable table, SqlAccessEnum requiredAccess)
void validateDelete(SqlDelete call)
void validateSelect(SqlSelect select, RelDataType targetRowType)
void validateDataType(SqlDataTypeSpec dataType)
Permute(SqlNode from, int offset)
IdInfo(SqlValidatorScope scope, SqlIdentifier id)
SqlValidatorNamespace getNamespace(SqlNode node)
void validateUnnest(SqlCall call, SqlValidatorScope scope, RelDataType targetRowType)
final RelDataType rowType
SqlValidatorScope getGroupScope(SqlSelect select)
boolean shouldCheckForRollUp(SqlNode from)
SqlNode visit(SqlIdentifier id)
SqlNode getAgg(SqlSelect select)
RelDataType getTableConstructorRowType(SqlCall values, SqlValidatorScope scope)
void checkRollUpInSelectList(SqlSelect select)
boolean isAggregate(SqlSelect select)
SqlNode visit(SqlIdentifier id)
RelDataType getParameterRowType(SqlNode sqlQuery)
SqlValidatorScope getJoinScope(SqlNode node)
void checkRollUpInWindow(SqlWindow window, SqlValidatorScope scope)
MatchRecognizeNamespace createMatchRecognizeNameSpace(SqlMatchRecognize call, SqlNode enclosingNode)
final AggFinder overFinder
void validateMatchRecognize(SqlCall call)
OrderExpressionExpander(SqlSelect select, SqlNode root)
List< String > usingNames(SqlJoin join)
SqlMoniker lookupQualifiedName(SqlNode topNode, SqlParserPos pos)
Void visit(SqlLiteral literal)
final void lookupNameCompletionHints(SqlValidatorScope scope, List< String > names, SqlParserPos pos, Collection< SqlMoniker > hintList)
SqlSelect createSourceSelectForUpdate(SqlUpdate call)
final RelDataTypeFactory typeFactory
boolean shouldAllowIntermediateOrderBy()
void permute(List< SqlNode > selectItems, List< Map.Entry< String, RelDataType >> fields)
final AggFinder aggFinder
void validateNoAggs(AggFinder aggFinder, SqlNode node, String clause)
static boolean isRunningOrFinal(SqlKind kind)
SqlNode visit(SqlLiteral literal)
void validateGroupClause(SqlSelect select)
SqlWindow resolveWindow(SqlNode windowOrRef, SqlValidatorScope scope)
Void visit(SqlIntervalQualifier intervalQualifier)
void validateInsert(SqlInsert insert)
static boolean isSingleVarRequired(SqlKind kind)
void checkConstraint(SqlValidatorTable validatorTable, SqlUpdate update, RelDataType targetRowType)
T getMin(const ExpressionRange &other)
final SqlValidatorScope scope
static SqlNode expandExprFromJoin(SqlJoin join, SqlIdentifier identifier, SelectScope scope)
List< Map.Entry< String, RelDataType > > validateMeasure(SqlMatchRecognize mr, MatchRecognizeScope scope, boolean allRows)
void validateDynamicParam(SqlDynamicParam dynamicParam)
String deriveAlias(SqlNode node, int ordinal)
void validateLiteral(SqlLiteral literal)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
void registerQuery(SqlValidatorScope parentScope, SqlValidatorScope usingScope, SqlNode node, SqlNode enclosingNode, String alias, boolean forceNullable)
SqlValidatorScope getWithScope(SqlNode withItem)
final List< String > aliasList
DeleteNamespace(SqlValidatorImpl validator, SqlDelete node, SqlNode enclosingNode, SqlValidatorScope parentScope)
final Map< String, IdInfo > idPositions
final void setValidatedNodeType(SqlNode node, RelDataType type)
MatchRecognizeScope scope
SqlValidatorScope getSelectScope(SqlSelect select)
RelDataType visit(SqlIdentifier id)
SqlNode maybeCast(SqlNode node, RelDataType currentType, RelDataType desiredType)
SqlNode visit(SqlIdentifier id)
RelDataType visit(SqlDataTypeSpec dataType)
void checkRollUp(SqlNode grandParent, SqlNode parent, SqlNode current, SqlValidatorScope scope)
Set< String > visit(SqlLiteral literal)
CalciteContextException apply(SqlNode v0, Resources.ExInst< SqlValidatorException > v1)
ExtendedExpander(SqlValidatorImpl validator, SqlValidatorScope scope, SqlSelect select, SqlNode root, boolean havingExpr)
RelDataType createTargetRowType(SqlValidatorTable table, SqlNodeList targetColumnList, boolean append)
SqlSelect createSourceSelectForDelete(SqlDelete call)
Expander(SqlValidatorImpl validator, SqlValidatorScope scope)
TypeCoercion getTypeCoercion()
void declareCursor(SqlSelect select, SqlValidatorScope parentScope)
NavigationExpander(SqlOperator operator, SqlNode offset)
boolean isNestedAggregateWindow(SqlNode node)
void validateMerge(SqlMerge call)
static boolean isAggregation(SqlKind kind)
SqlModality deduceModality(SqlNode query)
final Set< SqlNode > cursorSet
SelectNamespace createSelectNamespace(SqlSelect select, SqlNode enclosingNode)
SqlValidatorScope getFromScope(SqlSelect select)
PatternValidator(boolean isMeasure, int firstLastCount, int prevNextCount, int aggregateCount)
final SqlValidatorScope scope
void validateGroupingSets(SqlValidatorScope groupScope, AggregatingSelectScope aggregatingScope, SqlCall groupItem)
RelDataType getValidatedNodeTypeIfKnown(SqlNode node)
void validateWithItem(SqlWithItem withItem)
Void visit(SqlDynamicParam param)
void validateGroupItem(SqlValidatorScope groupScope, AggregatingSelectScope aggregatingScope, SqlNode groupItem)
SqlNode expandOrderExpr(SqlSelect select, SqlNode orderExpr)
Void visit(SqlDataTypeSpec type)
final Map< Integer, SqlSelect > cursorPosToSelectMap
SqlValidatorCatalogReader getCatalogReader()
void validateNodeFeature(SqlNode node)
void validateQuery(SqlNode node, SqlValidatorScope scope, RelDataType targetRowType)
boolean expandSelectItem(final SqlNode selectItem, SqlSelect select, RelDataType targetType, List< SqlNode > selectItems, Set< String > aliases, List< Map.Entry< String, RelDataType >> fields, final boolean includeSystemVars)
SetopNamespace createSetopNamespace(SqlCall call, SqlNode enclosingNode)
RelDataType visit(SqlDynamicParam param)
RelDataType visit(SqlCall call)
SqlNode getSelfJoinExprForUpdate(SqlNode table, String alias)
RelDataType deriveConstructorType(SqlValidatorScope scope, SqlCall call, SqlFunction unresolvedConstructor, SqlFunction resolvedConstructor, List< RelDataType > argTypes)
void validateJoin(SqlJoin join, SqlValidatorScope scope)
void registerSetop(SqlValidatorScope parentScope, SqlValidatorScope usingScope, SqlNode node, SqlNode enclosingNode, String alias, boolean forceNullable)
final Map< IdPair< SqlSelect, Clause >, SqlValidatorScope > clauseScopes
RelDataType visit(SqlNodeList nodeList)
std::string toString(const Executor::ExtModuleKinds &kind)
SqlNode stripDot(SqlNode node)
final AggFinder groupFinder
void checkRollUpInWindowDecl(SqlSelect select)
SqlNode performUnconditionalRewrites(SqlNode node, boolean underFrom)
void handleOffsetFetch(SqlNode offset, SqlNode fetch)
InsertNamespace(SqlValidatorImpl validator, SqlInsert node, SqlNode enclosingNode, SqlValidatorScope parentScope)
size_t indexOf(std::vector< T > &vec, T val)
final Map< SqlNode, SqlValidatorNamespace > namespaces
boolean isSystemField(RelDataTypeField field)
SqlNode visit(SqlIdentifier id)
SqlNode expand(SqlNode expr, SqlValidatorScope scope)
Void visit(SqlIdentifier id)
SqlNode validateParameterizedExpression(SqlNode topNode, final Map< String, RelDataType > nameToTypeMap)
final Resources.ExInst< SqlValidatorException > validatorException
final Map< SqlNode, SqlValidatorScope > scopes
SqlNode visit(SqlIdentifier id)
SqlWindow getWindowByName(SqlIdentifier id, SqlValidatorScope scope)
static String alias(SqlNode item)
void registerWith(SqlValidatorScope parentScope, SqlValidatorScope usingScope, SqlWith with, SqlNode enclosingNode, String alias, boolean forceNullable, boolean checkUpdate)
RelDataType getLogicalTargetRowType(RelDataType targetRowType, SqlInsert insert)
void registerOperandSubQueries(SqlValidatorScope parentScope, SqlCall call, int operandOrdinal)
void validateIdentifier(SqlIdentifier id, SqlValidatorScope scope)
PatternVarVisitor(MatchRecognizeScope scope)
SqlNodeList expandStar(SqlNodeList selectList, SqlSelect select, boolean includeSystemVars)
SqlNode navigationInDefine(SqlNode node, String alpha)
void handleScalarSubQuery(SqlSelect parentSelect, SqlSelect selectItem, List< SqlNode > expandedSelectItems, Set< String > aliasList, List< Map.Entry< String, RelDataType >> fieldList)
static SqlNode expandCommonColumn(SqlSelect sqlSelect, SqlNode selectItem, SelectScope scope, SqlValidatorImpl validator)
boolean isRolledUpColumnAllowedInAgg(SqlIdentifier identifier, SqlValidatorScope scope, SqlCall aggCall, SqlNode parent)
String getParentCursor(String columnListParamName)
static SqlNode stripOver(SqlNode node)
SqlNode visitScoped(SqlCall call)
Void visit(SqlNodeList nodeList)
boolean expandStar(List< SqlNode > selectItems, Set< String > aliases, List< Map.Entry< String, RelDataType >> fields, boolean includeSystemVars, SelectScope scope, SqlNode node)
void validateDefinitions(SqlMatchRecognize mr, MatchRecognizeScope scope)
void validateSnapshot(SqlNode node, SqlValidatorScope scope, SqlValidatorNamespace ns)
UpdateNamespace(SqlValidatorImpl validator, SqlUpdate node, SqlNode enclosingNode, SqlValidatorScope parentScope)
static void findAllValidUdfNames(List< String > names, SqlValidator validator, Collection< SqlMoniker > result)
void registerQuery(SqlValidatorScope parentScope, SqlValidatorScope usingScope, SqlNode node, SqlNode enclosingNode, String alias, boolean forceNullable, boolean checkUpdate)
final SqlValidatorImpl.ValidationErrorFunction validationErrorFunction
SqlValidatorScope getOrderScope(SqlSelect select)
void lookupFromHints(SqlNode node, SqlValidatorScope scope, SqlParserPos pos, Collection< SqlMoniker > hintList)
RelDataType deriveType(SqlValidatorScope scope, SqlNode expr)
SqlNode visitScoped(SqlCall call)
static final String UPDATE_TGT_ALIAS
boolean isRolledUpColumn(SqlIdentifier identifier, SqlValidatorScope scope)
torch::Tensor f(torch::Tensor x, torch::Tensor W_target, torch::Tensor b_target)
void removeValidatedNodeType(SqlNode node)
SqlValidatorScope getMatchRecognizeScope(SqlMatchRecognize node)
SqlNode getOriginal(SqlNode expr)
static void findAllValidFunctionNames(List< String > names, SqlValidator validator, Collection< SqlMoniker > result, SqlParserPos pos)
boolean validateModality(SqlSelect select, SqlModality modality, boolean fail)
SqlNode expandSelectExpr(SqlNode expr, SelectScope scope, SqlSelect select)
void registerNamespace(SqlValidatorScope usingScope, String alias, SqlValidatorNamespace ns, boolean forceNullable)
void validateOrderList(SqlSelect select)
void inferUnknownTypes(@Nonnull RelDataType inferredType,@Nonnull SqlValidatorScope scope,@Nonnull SqlNode node)
void validateCall(SqlCall call, SqlValidatorScope scope)
static final String UPDATE_SRC_ALIAS
boolean isSortCompatible(SelectScope scope, SqlNode node, boolean descending)
void validateWindowClause(SqlSelect select)
PatternValidator(boolean isMeasure)
void validateUpdate(SqlUpdate call)
static final Logger TRACER
RelDataType deriveTypeImpl(SqlValidatorScope scope, SqlNode operand)
RelDataType getUnknownType()
boolean hasSortedPrefix(SelectScope scope, SqlNodeList orderList)
ValidationErrorFunction getValidationErrorFunction()
void checkRollUp(SqlNode grandParent, SqlNode parent, SqlNode current, SqlValidatorScope scope, String optionalClause)
void validateOrderItem(SqlSelect select, SqlNode orderItem)
SqlValidatorScope getWhereScope(SqlSelect select)
void validateLiteralAsDouble(SqlLiteral literal)
Set< String > visit(SqlIntervalQualifier qualifier)
void validateFeature(Feature feature, SqlParserPos context)
NavigationReplacer(String alpha)
void validateValues(SqlCall node, RelDataType targetRowType, final SqlValidatorScope scope)
SqlNode validateScopedExpression(SqlNode topNode, SqlValidatorScope scope)
static void validateQualifiedCommonColumn(SqlJoin join, SqlIdentifier identifier, SelectScope scope, SqlValidatorImpl validator)
RelDataTypeField field(String name)
boolean isAggregate(SqlNode selectNode)
SqlConformance getConformance()
boolean isValuesWithDefault(SqlNode source, int column)
SqlValidatorScope getOverScope(SqlNode node)
SqlNode visit(SqlLiteral literal)
void validateIntervalQualifier(SqlIntervalQualifier qualifier)
void checkTypeAssignment(SqlValidatorScope sourceScope, SqlValidatorTable table, RelDataType sourceRowType, RelDataType targetRowType, final SqlNode query)
List< List< String > > getFieldOrigins(SqlNode sqlQuery)
SqlValidatorNamespace lookupFieldNamespace(RelDataType rowType, String name)
void addToSelectList(List< SqlNode > list, Set< String > aliases, List< Map.Entry< String, RelDataType >> fieldList, SqlNode exp, SelectScope scope, final boolean includeSystemVars)
void validateGroupByItem(SqlSelect select, SqlNode groupByItem)
void checkRollUpInUsing(SqlIdentifier identifier, SqlNode leftOrRight, SqlValidatorScope scope)
SqlNode visit(SqlCall call)
Set< String > visit(SqlIdentifier identifier)
final Map< SqlNode, RelDataType > nodeToTypeMap
void validateExpr(SqlNode expr, SqlValidatorScope scope)
void validateWhereClause(SqlSelect select)
SqlNode getNthExpr(SqlNode query, int ordinal, int sourceCount)
void validateWhereOrOn(SqlValidatorScope scope, SqlNode condition, String clause)
ValidationError(SqlNode sqlNode, Resources.ExInst< SqlValidatorException > validatorException)
void validateAggregateParams(SqlCall aggCall, SqlNode filter, SqlNodeList orderList, SqlValidatorScope scope)
boolean validatingSqlMerge
SelectExpander(SqlValidatorImpl validator, SelectScope scope, SqlSelect select)
RelDataType visit(SqlIntervalQualifier intervalQualifier)
static final String UPDATE_ANON_PREFIX
RelDataType getValidatedNodeType(SqlNode node)
final SqlValidatorCatalogReader catalogReader
final SqlOperatorTable opTab
MergeNamespace(SqlValidatorImpl validator, SqlMerge node, SqlNode enclosingNode, SqlValidatorScope parentScope)
void validateGroupByExpr(SqlNode groupByItem, SqlValidatorScope groupByScope)
boolean isOverAggregateWindow(SqlNode node)
SqlValidatorScope getCursorScope(SqlSelect select)
RelDataType visit(SqlLiteral literal)
void validateHavingClause(SqlSelect select)