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));