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;
126 import org.apache.calcite.util.BitString;
127 import org.apache.calcite.util.Bug;
128 import org.apache.calcite.util.ImmutableBitSet;
129 import org.apache.calcite.util.ImmutableIntList;
130 import org.apache.calcite.util.ImmutableNullableList;
131 import org.apache.calcite.util.Litmus;
132 import org.apache.calcite.util.Pair;
133 import org.apache.calcite.util.Static;
134 import org.apache.calcite.util.Util;
135 import org.apache.calcite.util.trace.CalciteTrace;
137 import com.google.common.annotations.VisibleForTesting;
138 import com.google.common.base.Preconditions;
139 import com.google.common.collect.ImmutableList;
140 import com.google.common.collect.ImmutableSet;
141 import com.google.common.collect.Sets;
143 import org.slf4j.Logger;
145 import java.math.BigDecimal;
146 import java.math.BigInteger;
147 import java.util.AbstractList;
148 import java.util.ArrayDeque;
149 import java.util.ArrayList;
150 import java.util.Arrays;
151 import java.util.Calendar;
152 import java.util.Collection;
153 import java.util.Collections;
154 import java.util.Deque;
155 import java.util.GregorianCalendar;
156 import java.util.HashMap;
157 import java.util.HashSet;
158 import java.util.IdentityHashMap;
159 import java.util.List;
160 import java.util.Locale;
161 import java.util.Map;
162 import java.util.Objects;
163 import java.util.Set;
164 import java.util.function.Supplier;
165 import java.util.function.UnaryOperator;
166 import java.util.stream.Collectors;
167 import javax.annotation.Nonnull;
168 import javax.annotation.Nullable;
170 import static org.apache.calcite.sql.SqlUtil.stripAs;
171 import static org.apache.calcite.util.Static.RESOURCE;
179 public static final Logger
TRACER = CalciteTrace.PARSER_LOGGER;
199 private final SqlOperatorTable
opTab;
206 protected final Map<String, IdInfo>
idPositions =
new HashMap<>();
212 protected final Map<SqlNode, SqlValidatorScope>
scopes =
213 new IdentityHashMap<>();
218 private final Map<IdPair<SqlSelect, Clause>, SqlValidatorScope>
231 protected final Map<SqlNode, SqlValidatorNamespace>
namespaces =
232 new IdentityHashMap<>();
239 private final Set<SqlNode>
cursorSet = Sets.newIdentityHashSet();
262 new IdentityHashMap<>();
282 new SqlValidatorImpl.ValidationErrorFunction();
298 SqlOperatorTable
opTab,
302 this.opTab = Objects.requireNonNull(
opTab);
304 this.typeFactory = Objects.requireNonNull(
typeFactory);
305 this.config = Objects.requireNonNull(
config);
308 booleanType = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
310 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
311 aggFinder =
new AggFinder(opTab,
false,
true,
false, null, nameMatcher);
313 new AggFinder(opTab,
true,
true,
false, null, nameMatcher);
316 groupFinder =
new AggFinder(opTab,
false,
false,
true, null, nameMatcher);
319 this.typeCoercion = config.typeCoercionFactory().
create(typeFactory,
this);
320 if (config.typeCoercionRules() != null) {
321 SqlTypeCoercionRule.THREAD_PROVIDERS.set(config.typeCoercionRules());
328 return config.sqlConformance();
348 SqlNodeList selectList,
350 boolean includeSystemVars) {
351 final List<SqlNode> list =
new ArrayList<>();
352 final List<Map.Entry<String, RelDataType>> types =
new ArrayList<>();
353 for (
int i = 0; i < selectList.size(); i++) {
354 final SqlNode selectItem = selectList.get(i);
361 catalogReader.nameMatcher().createSet(),
366 return new SqlNodeList(list, SqlParserPos.ZERO);
370 public void declareCursor(SqlSelect select, SqlValidatorScope parentScope) {
371 cursorSet.add(select);
376 Map<Integer, SqlSelect> cursorMap = funcParamInfo.cursorPosToSelectMap;
377 int numCursors = cursorMap.size();
378 cursorMap.put(numCursors, select);
383 SelectScope cursorScope =
new SelectScope(parentScope, null, select);
384 clauseScopes.put(IdPair.of(select,
Clause.CURSOR), cursorScope);
393 functionCallStack.push(funcInfo);
398 functionCallStack.pop();
404 Map<String, String> parentCursorMap =
405 funcParamInfo.columnListParamToParentCursorMap;
406 return parentCursorMap.get(columnListParamName);
422 final SqlNode selectItem,
424 RelDataType targetType,
425 List<SqlNode> selectItems,
427 List<Map.Entry<String, RelDataType>> fields,
428 final boolean includeSystemVars) {
429 final SelectScope scope = (SelectScope)
getWhereScope(select);
430 if (
expandStar(selectItems, aliases, fields, includeSystemVars, scope,
446 if (expanded != selectItem) {
451 if (!newAlias.equals(alias)) {
453 SqlStdOperatorTable.AS.createCall(
454 selectItem.getParserPosition(),
456 new SqlIdentifier(alias, SqlParserPos.ZERO));
461 selectItems.add(expanded);
464 if (expanded != null) {
475 if (join.getConditionType() != JoinConditionType.USING) {
479 for (SqlNode node : (SqlNodeList) join.getCondition()) {
480 final String
name = ((SqlIdentifier) node).getSimple();
481 if (identifier.getSimple().equals(
name)) {
482 final List<SqlNode> qualifiedNode =
new ArrayList<>();
483 for (ScopeChild child : scope.children) {
484 if (child.namespace.getRowType()
485 .getFieldNames().
indexOf(name) >= 0) {
486 final SqlIdentifier exp =
488 ImmutableList.of(child.name, name),
489 identifier.getParserPosition());
490 qualifiedNode.add(exp);
494 assert qualifiedNode.size() == 2;
495 final SqlNode finalNode =
496 SqlStdOperatorTable.AS.createCall(SqlParserPos.ZERO,
497 SqlStdOperatorTable.COALESCE.createCall(SqlParserPos.ZERO,
498 qualifiedNode.get(0),
499 qualifiedNode.get(1)),
500 new SqlIdentifier(name, SqlParserPos.ZERO));
507 final SqlNode node = join.getLeft();
508 if (node instanceof SqlJoin) {
518 switch (join.getConditionType()) {
520 final ImmutableList.Builder<String> list = ImmutableList.builder();
521 final Set<String> names = catalogReader.nameMatcher().createSet();
522 for (SqlNode node : (SqlNodeList) join.getCondition()) {
523 final String
name = ((SqlIdentifier) node).getSimple();
524 if (names.add(name)) {
530 if (join.isNatural()) {
533 return SqlValidatorUtil.deriveNaturalJoinColumnList(
534 catalogReader.nameMatcher(), t0, t1);
542 if (!(selectItem instanceof SqlIdentifier)) {
546 final SqlNode from = sqlSelect.getFrom();
547 if (!(from instanceof SqlJoin)) {
551 final SqlIdentifier identifier = (SqlIdentifier) selectItem;
552 if (!identifier.isSimple()) {
553 if (!validator.
config().sqlConformance().allowQualifyingCommonColumn()) {
564 List<String> names = validator.usingNames(
join);
572 for (ScopeChild child : scope.children) {
573 if (child.name.equals(identifier.getComponent(0).toString())) {
574 if (names.indexOf(identifier.getComponent(1).toString()) >= 0) {
575 throw validator.newValidationError(identifier,
576 RESOURCE.disallowsQualifyingCommonColumn(identifier.toString()));
583 final SqlNode node = join.getLeft();
584 if (node instanceof SqlJoin) {
589 private boolean expandStar(List<SqlNode> selectItems, Set<String> aliases,
590 List<Map.Entry<String, RelDataType>> fields,
boolean includeSystemVars,
591 SelectScope scope, SqlNode node) {
592 if (!(node instanceof SqlIdentifier)) {
595 final SqlIdentifier identifier = (SqlIdentifier) node;
596 if (!identifier.isStar()) {
599 final SqlParserPos startPosition = identifier.getParserPosition();
600 switch (identifier.names.size()) {
602 boolean hasDynamicStruct =
false;
603 for (ScopeChild child : scope.children) {
604 final int before = fields.size();
605 if (child.namespace.getRowType().isDynamicStruct()) {
606 hasDynamicStruct =
true;
612 ImmutableList.of(child.name,
613 DynamicRecordType.DYNAMIC_STAR_PREFIX),
623 final SqlNode from = child.namespace.getNode();
624 final SqlValidatorNamespace fromNs =
getNamespace(from, scope);
625 assert fromNs != null;
626 final RelDataType rowType = fromNs.getRowType();
627 for (RelDataTypeField
field : rowType.getFieldList()) {
628 String columnName = field.getName();
631 final SqlIdentifier exp =
633 ImmutableList.of(child.name, columnName),
648 if (child.nullable) {
649 for (
int i = before; i < fields.size(); i++) {
650 final Map.Entry<String, RelDataType> entry = fields.get(i);
651 final RelDataType
type = entry.getValue();
652 if (!type.isNullable()) {
654 Pair.of(entry.getKey(),
655 typeFactory.createTypeWithNullability(type,
true)));
662 if (!hasDynamicStruct || Bug.CALCITE_2400_FIXED) {
663 new Permute(scope.getNode().getFrom(), 0).permute(selectItems, fields);
668 final SqlIdentifier prefixId = identifier.skipLast(1);
669 final SqlValidatorScope.ResolvedImpl resolved =
670 new SqlValidatorScope.ResolvedImpl();
671 final SqlNameMatcher nameMatcher =
672 scope.validator.catalogReader.nameMatcher();
673 scope.resolve(prefixId.names, nameMatcher,
true, resolved);
674 if (resolved.count() == 0) {
678 RESOURCE.unknownIdentifier(prefixId.toString()));
680 final RelDataType rowType = resolved.only().rowType();
681 if (rowType.isDynamicStruct()) {
687 prefixId.plus(DynamicRecordType.DYNAMIC_STAR_PREFIX, startPosition),
690 }
else if (rowType.isStruct()) {
691 for (RelDataTypeField
field : rowType.getFieldList()) {
692 String columnName = field.getName();
701 prefixId.plus(columnName, startPosition),
711 private SqlNode
maybeCast(SqlNode node, RelDataType currentType,
712 RelDataType desiredType) {
713 return SqlTypeUtil.equalSansNullability(
typeFactory, currentType, desiredType)
715 : SqlStdOperatorTable.CAST.createCall(SqlParserPos.ZERO,
716 node, SqlTypeUtil.convertTypeToSpec(desiredType));
720 List<Map.Entry<String, RelDataType>> fields,
boolean includeSystemVars,
721 SelectScope scope, SqlIdentifier
id, RelDataTypeField
field) {
722 switch (field.getType().getStructKind()) {
724 case PEEK_FIELDS_DEFAULT:
725 final SqlNode starExp = id.plusStar();
749 SqlValidatorScope scope =
new EmptyScope(
this);
750 scope =
new CatalogScope(scope, ImmutableList.of(
"CATALOG"));
757 public List<SqlMoniker>
lookupHints(SqlNode topNode, SqlParserPos pos) {
758 SqlValidatorScope scope =
new EmptyScope(
this);
760 cursorSet.add(outermostNode);
761 if (outermostNode.isA(SqlKind.TOP_LEVEL)) {
770 final SqlValidatorNamespace ns =
getNamespace(outermostNode);
772 throw new AssertionError(
"Not a query: " + outermostNode);
774 Collection<SqlMoniker> hintList = Sets.newTreeSet(SqlMoniker.COMPARATOR);
776 return ImmutableList.copyOf(hintList);
780 final String posString = pos.toString();
781 IdInfo info = idPositions.get(posString);
783 final SqlQualified qualified = info.scope.fullyQualify(info.id);
784 return new SqlIdentifierMoniker(qualified.identifier);
803 Collection<SqlMoniker> hintList) {
804 IdInfo info = idPositions.get(pos.toString());
805 if ((info == null) || (info.
scope == null)) {
806 SqlNode fromNode = select.getFrom();
807 final SqlValidatorScope fromScope =
getFromScope(select);
811 info.
id.getParserPosition(), hintList);
816 SqlValidatorNamespace ns,
818 Collection<SqlMoniker> hintList) {
819 final SqlNode node = ns.getNode();
820 if (node instanceof SqlSelect) {
827 SqlValidatorScope scope,
829 Collection<SqlMoniker> hintList) {
835 if (ns.isWrapperFor(IdentifierNamespace.class)) {
836 IdentifierNamespace idNs = ns.unwrap(IdentifierNamespace.class);
837 final SqlIdentifier
id = idNs.getId();
838 for (
int i = 0; i < id.names.size(); i++) {
839 if (pos.toString().equals(
840 id.getComponent(i).getParserPosition().toString())) {
841 final List<SqlMoniker> objNames =
new ArrayList<>();
842 SqlValidatorUtil.getSchemaObjectMonikers(
844 id.names.subList(0, i + 1),
846 for (SqlMoniker objName : objNames) {
847 if (objName.getType() != SqlMonikerType.FUNCTION) {
848 hintList.add(objName);
855 switch (node.getKind()) {
867 SqlValidatorScope scope,
869 Collection<SqlMoniker> hintList) {
870 SqlNode left = join.getLeft();
871 SqlNode right = join.getRight();
872 SqlNode condition = join.getCondition();
874 if (hintList.size() > 0) {
878 if (hintList.size() > 0) {
881 final JoinConditionType conditionType = join.getConditionType();
882 final SqlValidatorScope joinScope = scopes.get(
join);
883 switch (conditionType) {
885 condition.findValidOptions(
this, joinScope, pos, hintList);
903 SqlValidatorScope scope,
906 Collection<SqlMoniker> hintList) {
908 List<String> subNames = Util.skipLast(names);
910 if (subNames.size() > 0) {
912 SqlValidatorNamespace ns = null;
913 for (String
name : subNames) {
915 final SqlValidatorScope.ResolvedImpl resolved =
916 new SqlValidatorScope.ResolvedImpl();
917 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
918 scope.resolve(ImmutableList.of(
name), nameMatcher,
false, resolved);
919 if (resolved.count() == 1) {
920 ns = resolved.only().
namespace;
923 ns = ns.lookupChild(
name);
930 RelDataType rowType = ns.getRowType();
931 if (rowType.isStruct()) {
932 for (RelDataTypeField
field : rowType.getFieldList()) {
936 SqlMonikerType.COLUMN));
947 scope.findAliases(hintList);
950 SelectScope selectScope =
951 SqlValidatorUtil.getEnclosingSelectScope(scope);
952 if ((selectScope != null)
953 && (selectScope.getChildren().size() == 1)) {
954 RelDataType rowType =
955 selectScope.getChildren().
get(0).getRowType();
956 for (RelDataTypeField
field : rowType.getFieldList()) {
960 SqlMonikerType.COLUMN));
970 SqlValidator validator,
971 Collection<SqlMoniker>
result) {
972 final List<SqlMoniker> objNames =
new ArrayList<>();
973 SqlValidatorUtil.getSchemaObjectMonikers(
974 validator.getCatalogReader(),
977 for (SqlMoniker objName : objNames) {
978 if (objName.getType() == SqlMonikerType.FUNCTION) {
986 SqlValidator validator,
987 Collection<SqlMoniker>
result,
990 if (names.size() > 1) {
993 for (
SqlOperator op : validator.getOperatorTable().getOperatorList()) {
994 SqlIdentifier curOpId =
999 final SqlCall call = validator.makeNullaryCall(curOpId);
1004 SqlMonikerType.FUNCTION));
1006 if ((op.getSyntax() == SqlSyntax.FUNCTION)
1007 || (op.getSyntax() == SqlSyntax.PREFIX)) {
1008 if (op.getOperandTypeChecker() != null) {
1009 String sig = op.getAllowedSignatures();
1010 sig = sig.replace(
"'",
"");
1014 SqlMonikerType.FUNCTION));
1020 SqlMonikerType.FUNCTION));
1028 final Map<String, RelDataType> nameToTypeMap) {
1029 SqlValidatorScope scope =
new ParameterScope(
this, nameToTypeMap);
1035 SqlValidatorScope scope) {
1037 cursorSet.add(outermostNode);
1038 top = outermostNode;
1039 TRACER.trace(
"After unconditional rewrite: {}", outermostNode);
1040 if (outermostNode.isA(SqlKind.TOP_LEVEL)) {
1041 registerQuery(scope, null, outermostNode, outermostNode, null,
false);
1043 outermostNode.validate(
this, scope);
1044 if (!outermostNode.isA(SqlKind.TOP_LEVEL)) {
1049 TRACER.trace(
"After validation: {}", outermostNode);
1050 return outermostNode;
1054 RelDataType targetRowType) {
1055 final SqlValidatorNamespace ns =
getNamespace(node, scope);
1056 if (node.getKind() == SqlKind.TABLESAMPLE) {
1057 List<SqlNode> operands = ((SqlCall) node).getOperandList();
1058 SqlSampleSpec sampleSpec = SqlLiteral.sampleValue(operands.get(1));
1059 if (sampleSpec instanceof SqlSampleSpec.SqlTableSampleSpec) {
1060 validateFeature(RESOURCE.sQLFeature_T613(), node.getParserPosition());
1061 }
else if (sampleSpec
1062 instanceof SqlSampleSpec.SqlSubstitutionSampleSpec) {
1064 node.getParserPosition());
1069 switch (node.getKind()) {
1080 SqlAccessEnum.SELECT);
1093 RelDataType targetRowType) {
1094 namespace.validate(targetRowType);
1095 if (
namespace.getNode() != null) {
1102 return new EmptyScope(
this);
1110 return clauseScopes.get(IdPair.of(select,
Clause.WHERE));
1119 if (scope instanceof AggregatingSelectScope) {
1120 scope = ((AggregatingSelectScope) scope).getParent();
1122 return (SelectScope) scope;
1136 return scopes.get(select);
1140 return clauseScopes.get(IdPair.of(select,
Clause.ORDER));
1144 return scopes.get(node);
1148 return scopes.get(stripAs(node));
1152 return scopes.get(node);
1156 SqlValidatorScope scope) {
1157 if (node instanceof SqlIdentifier && scope instanceof DelegatingScope) {
1158 final SqlIdentifier
id = (SqlIdentifier) node;
1159 final DelegatingScope idScope = (DelegatingScope) ((DelegatingScope) scope).getParent();
1161 }
else if (node instanceof SqlCall) {
1163 final SqlCall call = (SqlCall) node;
1164 switch (call.getOperator().getKind()) {
1168 final SqlNode operand0 = call.getOperandList().
get(0);
1169 final SqlIdentifier identifier = operand0.getKind() == SqlKind.TABLE_REF
1170 ? ((SqlCall) operand0).operand(0)
1171 : (SqlIdentifier) operand0;
1172 final DelegatingScope idScope = (DelegatingScope) scope;
1175 final SqlNode nested = call.getOperandList().
get(0);
1176 switch (nested.getKind()) {
1187 private SqlValidatorNamespace
getNamespace(SqlIdentifier
id, DelegatingScope scope) {
1188 if (
id.isSimple()) {
1189 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
1190 final SqlValidatorScope.ResolvedImpl resolved =
1191 new SqlValidatorScope.ResolvedImpl();
1192 scope.resolve(id.names, nameMatcher,
false, resolved);
1193 if (resolved.count() == 1) {
1194 return resolved.only().
namespace;
1201 switch (node.getKind()) {
1205 final SqlValidatorNamespace ns = namespaces.get(node);
1213 case COLLECTION_TABLE:
1218 return namespaces.get(node);
1223 if (offset instanceof SqlDynamicParam) {
1227 if (fetch instanceof SqlDynamicParam) {
1244 boolean underFrom) {
1252 if (node instanceof SqlCall) {
1253 if (node instanceof SqlMerge) {
1256 SqlCall call = (SqlCall) node;
1257 final SqlKind kind = call.getKind();
1258 final List<SqlNode> operands = call.getOperandList();
1259 for (
int i = 0; i < operands.size(); i++) {
1260 SqlNode operand = operands.get(i);
1261 boolean childUnderFrom;
1262 if (kind == SqlKind.SELECT) {
1263 childUnderFrom = i == SqlSelect.FROM_OPERAND;
1264 }
else if (kind == SqlKind.AS && (i == 0)) {
1267 childUnderFrom = underFrom;
1269 childUnderFrom =
false;
1273 if (newOperand != null && newOperand != operand) {
1274 call.setOperand(i, newOperand);
1278 if (call.getOperator() instanceof SqlUnresolvedFunction) {
1279 assert call instanceof SqlBasicCall;
1280 final SqlUnresolvedFunction
function =
1281 (SqlUnresolvedFunction) call.getOperator();
1286 final List<SqlOperator> overloads =
new ArrayList<>();
1287 opTab.lookupOperatorOverloads(function.getNameAsId(),
1288 function.getFunctionType(), SqlSyntax.FUNCTION, overloads,
1289 catalogReader.nameMatcher());
1290 if (overloads.size() == 1) {
1291 ((SqlBasicCall) call).setOperator(overloads.get(0));
1294 if (
config.callRewrite()) {
1295 node = call.getOperator().rewriteCall(
this, call);
1297 }
else if (node instanceof SqlNodeList) {
1298 SqlNodeList list = (SqlNodeList) node;
1299 for (
int i = 0, count = list.size(); i < count; i++) {
1300 SqlNode operand = list.get(i);
1305 if (newOperand != null) {
1306 list.getList().set(i, newOperand);
1312 final SqlKind kind = node.getKind();
1316 if (underFrom ||
true) {
1322 final SqlNodeList selectList =
1323 new SqlNodeList(SqlParserPos.ZERO);
1324 selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
1325 return new SqlSelect(node.getParserPosition(), null, selectList, node,
1326 null, null, null, null, null, null, null, null);
1330 SqlOrderBy orderBy = (SqlOrderBy) node;
1332 if (orderBy.query instanceof SqlSelect) {
1333 SqlSelect select = (SqlSelect) orderBy.query;
1337 if (select.getOrderList() == null) {
1339 select.setOrderBy(orderBy.orderList);
1340 select.setOffset(orderBy.offset);
1341 select.setFetch(orderBy.fetch);
1345 if (orderBy.query instanceof SqlWith
1346 && ((SqlWith) orderBy.query).body instanceof SqlSelect) {
1347 SqlWith with = (SqlWith) orderBy.query;
1348 SqlSelect select = (SqlSelect) with.body;
1352 if (select.getOrderList() == null) {
1354 select.setOrderBy(orderBy.orderList);
1355 select.setOffset(orderBy.offset);
1356 select.setFetch(orderBy.fetch);
1360 final SqlNodeList selectList =
new SqlNodeList(SqlParserPos.ZERO);
1361 selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
1362 final SqlNodeList orderList;
1364 orderList = SqlNode.clone(orderBy.orderList);
1367 for (
int i = 0; i < orderList.size(); i++) {
1368 SqlNode sqlNode = orderList.get(i);
1370 for (Ord<SqlNode> sel : Ord.zip(selectList2)) {
1371 if (stripAs(sel.e).equalsDeep(sqlNode, Litmus.IGNORE)) {
1373 SqlLiteral.createExactNumeric(Integer.toString(sel.i + 1),
1374 SqlParserPos.ZERO));
1379 orderList = orderBy.orderList;
1381 return new SqlSelect(SqlParserPos.ZERO, null, selectList, orderBy.query,
1382 null, null, null, null, orderList, orderBy.offset,
1383 orderBy.fetch, null);
1386 case EXPLICIT_TABLE: {
1388 SqlCall call = (SqlCall) node;
1389 final SqlNodeList selectList =
new SqlNodeList(SqlParserPos.ZERO);
1390 selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
1391 return new SqlSelect(SqlParserPos.ZERO, null, selectList, call.operand(0),
1392 null, null, null, null, null, null, null, null);
1396 SqlDelete call = (SqlDelete) node;
1398 call.setSourceSelect(select);
1403 SqlUpdate call = (SqlUpdate) node;
1405 call.setSourceSelect(select);
1411 SqlNode selfJoinSrcExpr =
1413 call.getTargetTable(),
1415 if (selfJoinSrcExpr != null) {
1423 SqlMerge call = (SqlMerge) node;
1433 if (node instanceof SqlSelect) {
1434 return (SqlSelect) node;
1435 }
else if (node instanceof SqlOrderBy) {
1436 node = ((SqlOrderBy) node).query;
1437 }
else if (node instanceof SqlWith) {
1438 node = ((SqlWith) node).body;
1446 SqlNodeList selectList;
1447 SqlUpdate updateStmt = call.getUpdateCall();
1448 if (updateStmt != null) {
1453 selectList = SqlNode.clone(updateStmt.getSourceSelect().getSelectList());
1456 selectList =
new SqlNodeList(SqlParserPos.ZERO);
1457 selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
1459 SqlNode targetTable = call.getTargetTable();
1460 if (call.getAlias() != null) {
1462 SqlValidatorUtil.addAlias(
1464 call.getAlias().getSimple());
1472 SqlNode sourceTableRef = call.getSourceTableRef();
1473 SqlInsert insertCall = call.getInsertCall();
1475 final SqlNode leftJoinTerm = SqlNode.clone(sourceTableRef);
1477 new SqlJoin(SqlParserPos.ZERO,
1479 SqlLiteral.createBoolean(
false, SqlParserPos.ZERO),
1480 joinType.symbol(SqlParserPos.ZERO),
1482 JoinConditionType.ON.symbol(SqlParserPos.ZERO),
1483 call.getCondition());
1485 new SqlSelect(SqlParserPos.ZERO, null, selectList, outerJoin, null,
1486 null, null, null, null, null, null, null);
1487 call.setSourceSelect(select);
1494 if (insertCall != null) {
1495 SqlCall valuesCall = (SqlCall) insertCall.getSource();
1496 SqlCall rowCall = valuesCall.operand(0);
1499 rowCall.getOperandList(),
1501 final SqlNode insertSource = SqlNode.clone(sourceTableRef);
1503 new SqlSelect(SqlParserPos.ZERO, null, selectList, insertSource, null,
1504 null, null, null, null, null, null, null);
1505 insertCall.setSource(select);
1510 SqlUpdate updateCall,
1511 SqlNode selfJoinSrcExpr) {
1513 if (updateCall.getAlias() == null) {
1514 updateCall.setAlias(
1517 SqlNode selfJoinTgtExpr =
1519 updateCall.getTargetTable(),
1520 updateCall.getAlias().getSimple());
1521 assert selfJoinTgtExpr != null;
1526 SqlNode condition = updateCall.getCondition();
1527 SqlNode selfJoinCond =
1528 SqlStdOperatorTable.EQUALS.createCall(
1532 if (condition == null) {
1533 condition = selfJoinCond;
1536 SqlStdOperatorTable.AND.createCall(
1542 updateCall.getTargetTable().clone(SqlParserPos.ZERO);
1552 IdentifierNamespace ns =
1553 new IdentifierNamespace(
this, target, null, null);
1554 RelDataType rowType = ns.getRowType();
1555 SqlNode source = updateCall.getTargetTable().clone(SqlParserPos.ZERO);
1556 final SqlNodeList selectList =
new SqlNodeList(SqlParserPos.ZERO);
1558 for (RelDataTypeField
field : rowType.getFieldList()) {
1568 new SqlSelect(SqlParserPos.ZERO, null, selectList, source, null, null,
1569 null, null, null, null, null, null);
1571 SqlMerge mergeCall =
1572 new SqlMerge(updateCall.getParserPosition(), target, condition, source,
1573 updateCall, null, null, updateCall.getAlias());
1606 final SqlNodeList selectList =
new SqlNodeList(SqlParserPos.ZERO);
1607 selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
1609 for (SqlNode exp : call.getSourceExpressionList()) {
1612 String
alias = SqlUtil.deriveAliasFromOrdinal(ordinal);
1613 selectList.add(SqlValidatorUtil.addAlias(exp,
alias));
1616 SqlNode sourceTable = call.getTargetTable();
1617 if (call.getAlias() != null) {
1619 SqlValidatorUtil.addAlias(
1621 call.getAlias().getSimple());
1623 return new SqlSelect(SqlParserPos.ZERO, null, selectList, sourceTable,
1624 call.getCondition(), null, null, null, null, null, null, null);
1635 final SqlNodeList selectList =
new SqlNodeList(SqlParserPos.ZERO);
1636 selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
1637 SqlNode sourceTable = call.getTargetTable();
1638 if (call.getAlias() != null) {
1640 SqlValidatorUtil.addAlias(
1642 call.getAlias().getSimple());
1644 return new SqlSelect(SqlParserPos.ZERO, null, selectList, sourceTable,
1645 call.getCondition(), null, null, null, null, null, null, null);
1654 SqlValidatorScope scope) {
1655 final List<SqlNode> rows = values.getOperandList();
1656 assert rows.size() >= 1;
1657 final List<RelDataType> rowTypes =
new ArrayList<>();
1658 for (
final SqlNode row : rows) {
1659 assert row.getKind() == SqlKind.ROW;
1660 SqlCall rowConstructor = (SqlCall) row;
1664 final List<String> aliasList =
new ArrayList<>();
1665 final List<RelDataType> typeList =
new ArrayList<>();
1666 for (Ord<SqlNode> column : Ord.zip(rowConstructor.getOperandList())) {
1668 aliasList.add(
alias);
1672 rowTypes.add(typeFactory.createStructType(typeList, aliasList));
1674 if (rows.size() == 1) {
1677 return rowTypes.get(0);
1679 return typeFactory.leastRestrictive(rowTypes);
1685 throw Util.needToImplement(node);
1692 final RelDataType
type = nodeToTypeMap.get(node);
1698 return ns.getType();
1700 final SqlNode original = originalExprs.get(node);
1701 if (original != null && original != node) {
1704 if (node instanceof SqlIdentifier) {
1720 Objects.requireNonNull(
type);
1721 Objects.requireNonNull(node);
1727 nodeToTypeMap.put(node,
type);
1731 nodeToTypeMap.remove(node);
1735 if (
id.names.size() == 1 && !id.isComponentQuoted(0)) {
1736 final List<SqlOperator> list =
new ArrayList<>();
1737 opTab.lookupOperatorOverloads(id, null, SqlSyntax.FUNCTION, list,
1738 catalogReader.nameMatcher());
1740 if (
operator.getSyntax() == SqlSyntax.FUNCTION_ID) {
1745 return new SqlBasicCall(
operator, SqlNode.EMPTY_ARRAY,
1746 id.getParserPosition(),
true, null);
1754 SqlValidatorScope scope,
1756 Objects.requireNonNull(scope);
1757 Objects.requireNonNull(expr);
1760 RelDataType
type = nodeToTypeMap.get(expr);
1766 return ns.getType();
1769 Preconditions.checkArgument(
1771 "SqlValidator.deriveTypeInternal returned null");
1780 SqlValidatorScope scope,
1783 final RelDataType
type = operand.accept(v);
1784 return Objects.requireNonNull(scope.nullifyType(operand,
type));
1788 SqlValidatorScope scope,
1790 SqlFunction unresolvedConstructor,
1791 SqlFunction resolvedConstructor,
1792 List<RelDataType> argTypes) {
1793 SqlIdentifier sqlIdentifier = unresolvedConstructor.getSqlIdentifier();
1794 assert sqlIdentifier != null;
1795 RelDataType
type = catalogReader.getNamedType(sqlIdentifier);
1799 RESOURCE.unknownDatatypeName(sqlIdentifier.toString()));
1802 if (resolvedConstructor == null) {
1803 if (call.operandCount() > 0) {
1811 resolvedConstructor.createCall(
1812 call.getParserPosition(),
1813 call.getOperandList());
1814 RelDataType returnType =
1815 resolvedConstructor.validateOperands(
1819 assert type == returnType;
1822 if (
config.identifierExpansion()) {
1823 if (resolvedConstructor != null) {
1824 ((SqlBasicCall) call).setOperator(resolvedConstructor);
1827 ((SqlBasicCall) call).setOperator(
1829 type.getSqlIdentifier(),
1830 ReturnTypes.explicit(
type),
1834 SqlFunctionCategory.USER_DEFINED_CONSTRUCTOR));
1841 SqlFunction unresolvedFunction, List<RelDataType> argTypes,
1842 List<String> argNames) {
1844 final List<SqlOperator> overloads =
new ArrayList<>();
1845 opTab.lookupOperatorOverloads(unresolvedFunction.getNameAsId(), null,
1846 SqlSyntax.FUNCTION, overloads,
catalogReader.nameMatcher());
1847 if (overloads.size() == 1) {
1848 SqlFunction fun = (SqlFunction) overloads.get(0);
1849 if ((fun.getSqlIdentifier() == null)
1850 && (fun.getSyntax() != SqlSyntax.FUNCTION_ID)) {
1851 final int expectedArgCount =
1852 fun.getOperandCountRange().
getMin();
1854 RESOURCE.invalidArgCount(call.getOperator().getName(),
1859 AssignableOperandTypeChecker typeChecking =
1860 new AssignableOperandTypeChecker(argTypes, argNames);
1862 typeChecking.getAllowedSignatures(
1864 unresolvedFunction.getName());
1866 RESOURCE.validatorUnknownFunction(signature));
1870 @Nonnull RelDataType inferredType,
1871 @Nonnull SqlValidatorScope scope,
1872 @Nonnull SqlNode node) {
1873 Objects.requireNonNull(inferredType);
1874 Objects.requireNonNull(scope);
1875 Objects.requireNonNull(node);
1876 final SqlValidatorScope newScope = scopes.get(node);
1877 if (newScope != null) {
1880 boolean isNullLiteral = SqlUtil.isNullLiteral(node,
false);
1881 if ((node instanceof SqlDynamicParam) || isNullLiteral) {
1883 if (isNullLiteral) {
1884 if (
config.typeCoercionEnabled()) {
1897 RelDataType newInferredType =
1898 typeFactory.createTypeWithNullability(inferredType,
true);
1899 if (SqlTypeUtil.inCharFamily(inferredType)) {
1901 typeFactory.createTypeWithCharsetAndCollation(
1903 inferredType.getCharset(),
1904 inferredType.getCollation());
1907 }
else if (node instanceof SqlNodeList) {
1908 SqlNodeList nodeList = (SqlNodeList) node;
1909 if (inferredType.isStruct()) {
1910 if (inferredType.getFieldCount() != nodeList.size()) {
1918 for (SqlNode child : nodeList) {
1920 if (inferredType.isStruct()) {
1921 type = inferredType.getFieldList().
get(i).getType();
1924 type = inferredType;
1928 }
else if (node instanceof SqlCase) {
1929 final SqlCase caseCall = (SqlCase) node;
1931 final RelDataType whenType =
1933 for (SqlNode sqlNode : caseCall.getWhenOperands().getList()) {
1936 RelDataType returnType =
deriveType(scope, node);
1937 for (SqlNode sqlNode : caseCall.getThenOperands().getList()) {
1941 if (!SqlUtil.isNullLiteral(caseCall.getElseOperand(),
false)) {
1945 caseCall.getElseOperand());
1949 }
else if (node.getKind() == SqlKind.AS) {
1952 }
else if (node instanceof SqlCall) {
1953 final SqlCall call = (SqlCall) node;
1954 final SqlOperandTypeInference operandTypeInference =
1955 call.getOperator().getOperandTypeInference();
1956 final SqlCallBinding callBinding =
new SqlCallBinding(
this, scope, call);
1957 final List<SqlNode> operands = callBinding.operands();
1958 final RelDataType[] operandTypes =
new RelDataType[operands.size()];
1962 if (operandTypeInference != null) {
1963 operandTypeInference.inferOperandTypes(
1968 for (
int i = 0; i < operands.size(); ++i) {
1969 final SqlNode operand = operands.get(i);
1970 if (operand != null) {
1983 Set<String> aliases,
1984 List<Map.Entry<String, RelDataType>> fieldList,
1987 final boolean includeSystemVars) {
1988 String
alias = SqlValidatorUtil.getAlias(exp, -1);
1989 String uniqueAlias =
1990 SqlValidatorUtil.uniquify(
1991 alias, aliases, SqlValidatorUtil.EXPR_SUGGESTER);
1992 if (!Objects.equals(alias, uniqueAlias)) {
1993 exp = SqlValidatorUtil.addAlias(exp, uniqueAlias);
1995 fieldList.add(Pair.of(uniqueAlias,
deriveType(scope, exp)));
2002 return SqlValidatorUtil.getAlias(node, ordinal);
2010 SqlValidatorScope parentScope,
2011 SqlValidatorScope usingScope,
2012 SqlMatchRecognize call,
2013 SqlNode enclosingNode,
2015 boolean forceNullable) {
2017 final MatchRecognizeNamespace matchRecognizeNamespace =
2021 final MatchRecognizeScope matchRecognizeScope =
2022 new MatchRecognizeScope(parentScope, call);
2023 scopes.put(call, matchRecognizeScope);
2026 SqlNode expr = call.getTableRef();
2027 SqlNode newExpr =
registerFrom(usingScope, matchRecognizeScope,
true, expr,
2028 expr, null, null, forceNullable,
false);
2029 if (expr != newExpr) {
2030 call.setOperand(0, newExpr);
2035 SqlMatchRecognize call,
2036 SqlNode enclosingNode) {
2037 return new MatchRecognizeNamespace(
this, call, enclosingNode);
2052 SqlValidatorScope usingScope,
2054 SqlValidatorNamespace ns,
2055 boolean forceNullable) {
2056 namespaces.put(ns.getNode(), ns);
2057 if (usingScope != null) {
2058 usingScope.addChild(ns,
alias, forceNullable);
2094 SqlValidatorScope parentScope,
2095 SqlValidatorScope usingScope,
2098 SqlNode enclosingNode,
2100 SqlNodeList extendList,
2101 boolean forceNullable,
2102 final boolean lateral) {
2103 final SqlKind kind = node.getKind();
2109 SqlNode newNode = node;
2110 if (alias == null) {
2115 if (alias == null) {
2118 if (
config.identifierExpansion()) {
2119 newNode = SqlValidatorUtil.addAlias(node,
alias);
2129 case OTHER_FUNCTION:
2130 case COLLECTION_TABLE:
2131 case MATCH_RECOGNIZE:
2136 if (
config.identifierExpansion()) {
2141 newNode = SqlValidatorUtil.addAlias(node,
alias);
2148 SqlValidatorScope s = usingScope;
2149 while (s instanceof JoinScope) {
2150 s = ((JoinScope) s).getUsingScope();
2152 final SqlNode node2 = s != null ? s.getNode() : node;
2153 final TableScope
tableScope =
new TableScope(parentScope, node2);
2154 if (usingScope instanceof ListScope) {
2155 for (ScopeChild child : ((ListScope) usingScope).children) {
2156 tableScope.addChild(child.namespace,
child.name, child.nullable);
2168 call = (SqlCall) node;
2169 if (alias == null) {
2170 alias = call.operand(1).
toString();
2172 final boolean needAlias = call.operandCount() > 2;
2173 expr = call.operand(0);
2185 if (newExpr != expr) {
2186 call.setOperand(0, newExpr);
2195 new AliasNamespace(
this, call, enclosingNode),
2199 case MATCH_RECOGNIZE:
2201 (SqlMatchRecognize) node, enclosingNode, alias, forceNullable);
2204 call = (SqlCall) node;
2205 expr = call.operand(0);
2217 if (newExpr != expr) {
2218 call.setOperand(0, newExpr);
2223 final SqlJoin
join = (SqlJoin) node;
2224 final JoinScope joinScope =
2225 new JoinScope(parentScope, usingScope, join);
2226 scopes.put(
join, joinScope);
2227 final SqlNode left = join.getLeft();
2228 final SqlNode right = join.getRight();
2229 boolean forceLeftNullable = forceNullable;
2230 boolean forceRightNullable = forceNullable;
2231 switch (join.getJoinType()) {
2233 forceRightNullable =
true;
2236 forceLeftNullable =
true;
2239 forceLeftNullable =
true;
2240 forceRightNullable =
true;
2243 final SqlNode newLeft =
2254 if (newLeft != left) {
2255 join.setLeft(newLeft);
2257 final SqlNode newRight =
2268 if (newRight != right) {
2269 join.setRight(newRight);
2272 final JoinNamespace joinNamespace =
new JoinNamespace(
this, join);
2277 final SqlIdentifier
id = (SqlIdentifier) node;
2278 final IdentifierNamespace newNs =
2279 new IdentifierNamespace(
2280 this,
id, extendList, enclosingNode,
2285 tableScope =
new TableScope(parentScope, node);
2287 tableScope.addChild(newNs,
alias, forceNullable);
2288 if (extendList != null && extendList.size() != 0) {
2289 return enclosingNode;
2298 ((SqlCall) node).operand(0),
2305 case COLLECTION_TABLE:
2306 call = (SqlCall) node;
2307 operand = call.operand(0);
2317 forceNullable, lateral);
2318 if (newOperand != operand) {
2319 call.setOperand(0, newOperand);
2323 if (operand instanceof SqlBasicCall) {
2324 final SqlBasicCall call1 = (SqlBasicCall) operand;
2326 if (op instanceof SqlWindowTableFunction
2327 && call1.operand(0).getKind() == SqlKind.SELECT) {
2335 scopes.put(node, usingScope);
2340 return registerFrom(parentScope, usingScope,
register, node,
2341 enclosingNode, alias, extendList, forceNullable,
true);
2350 case OTHER_FUNCTION:
2351 if (alias == null) {
2356 register ? usingScope : null,
2365 throw Util.unexpected(kind);
2367 call = (SqlCall) node;
2368 final OverScope overScope =
new OverScope(usingScope, call);
2369 scopes.put(call, overScope);
2370 operand = call.operand(0);
2382 if (newOperand != operand) {
2383 call.setOperand(0, newOperand);
2386 for (ScopeChild child : overScope.children) {
2388 child.namespace, forceNullable);
2394 call = (SqlCall) node;
2404 if (extendList != null && extendList.size() != 0) {
2405 return enclosingNode;
2410 final SqlCall extend = (SqlCall) node;
2414 extend.getOperandList().get(0),
2417 (SqlNodeList) extend.getOperandList().
get(1),
2422 call = (SqlCall) node;
2423 operand = call.operand(0);
2434 if (newOperand != operand) {
2435 call.setOperand(0, newOperand);
2440 scopes.put(node, usingScope);
2444 throw Util.unexpected(kind);
2462 SqlNode enclosingNode) {
2463 return new SelectNamespace(
this, select, enclosingNode);
2477 SqlNode enclosingNode) {
2478 return new SetopNamespace(
this, call, enclosingNode);
2492 SqlValidatorScope parentScope,
2493 SqlValidatorScope usingScope,
2495 SqlNode enclosingNode,
2497 boolean forceNullable) {
2498 Preconditions.checkArgument(usingScope == null || alias != null);
2522 SqlValidatorScope parentScope,
2523 SqlValidatorScope usingScope,
2525 SqlNode enclosingNode,
2527 boolean forceNullable,
2528 boolean checkUpdate) {
2529 Objects.requireNonNull(node);
2530 Objects.requireNonNull(enclosingNode);
2531 Preconditions.checkArgument(usingScope == null || alias != null);
2534 List<SqlNode> operands;
2535 switch (node.getKind()) {
2537 final SqlSelect select = (SqlSelect) node;
2538 final SelectNamespace selectNs =
2541 final SqlValidatorScope windowParentScope =
2542 (usingScope != null) ? usingScope : parentScope;
2543 SelectScope selectScope =
2544 new SelectScope(parentScope, windowParentScope, select);
2545 scopes.put(select, selectScope);
2548 clauseScopes.put(IdPair.of(select,
Clause.WHERE), selectScope);
2552 SqlSelect.WHERE_OPERAND);
2557 final SqlNode from = select.getFrom();
2559 final SqlNode newFrom =
2570 if (newFrom != from) {
2571 select.setFrom(newFrom);
2578 SqlValidatorScope aggScope = selectScope;
2581 new AggregatingSelectScope(selectScope, select,
false);
2582 clauseScopes.put(IdPair.of(select,
Clause.SELECT), aggScope);
2584 clauseScopes.put(IdPair.of(select,
Clause.SELECT), selectScope);
2586 if (select.getGroup() != null) {
2587 GroupByScope groupByScope =
2588 new GroupByScope(selectScope, select.getGroup(), select);
2595 SqlSelect.HAVING_OPERAND);
2597 final SqlNodeList orderList = select.getOrderList();
2598 if (orderList != null) {
2601 if (select.isDistinct()) {
2603 new AggregatingSelectScope(selectScope, select,
true);
2605 OrderByScope orderScope =
2606 new OrderByScope(aggScope, orderList, select);
2607 clauseScopes.put(IdPair.of(select,
Clause.ORDER), orderScope);
2613 SqlNode agg = aggFinder.findAgg(orderList);
2622 validateFeature(RESOURCE.sQLFeature_F302(), node.getParserPosition());
2633 validateFeature(RESOURCE.sQLFeature_E071_03(), node.getParserPosition());
2654 registerWith(parentScope, usingScope, (SqlWith) node, enclosingNode,
2655 alias, forceNullable, checkUpdate);
2659 call = (SqlCall) node;
2660 scopes.put(call, parentScope);
2661 final TableConstructorNamespace tableConstructorNamespace =
2662 new TableConstructorNamespace(
2670 tableConstructorNamespace,
2672 operands = call.getOperandList();
2673 for (
int i = 0; i < operands.size(); ++i) {
2674 assert operands.get(i).getKind() == SqlKind.ROW;
2684 SqlInsert insertCall = (SqlInsert) node;
2695 insertCall.getSource(),
2702 SqlDelete deleteCall = (SqlDelete) node;
2713 deleteCall.getSourceSelect(),
2722 node.getParserPosition());
2724 SqlUpdate updateCall = (SqlUpdate) node;
2735 updateCall.getSourceSelect(),
2742 validateFeature(RESOURCE.sQLFeature_F312(), node.getParserPosition());
2743 SqlMerge mergeCall = (SqlMerge) node;
2754 mergeCall.getSourceSelect(),
2763 if (mergeCall.getUpdateCall() != null) {
2767 mergeCall.getUpdateCall(),
2773 if (mergeCall.getInsertCall() != null) {
2777 mergeCall.getInsertCall(),
2785 call = (SqlCall) node;
2786 final UnnestNamespace unnestNs =
2787 new UnnestNamespace(
this, call, parentScope, enclosingNode);
2794 scopes.put(node, parentScope);
2796 case OTHER_FUNCTION:
2797 call = (SqlCall) node;
2798 ProcedureNamespace procNs =
2799 new ProcedureNamespace(
2812 case MULTISET_QUERY_CONSTRUCTOR:
2813 case MULTISET_VALUE_CONSTRUCTOR:
2814 validateFeature(RESOURCE.sQLFeature_S271(), node.getParserPosition());
2815 call = (SqlCall) node;
2816 CollectScope cs =
new CollectScope(parentScope, usingScope, call);
2817 final CollectNamespace tableConstructorNs =
2818 new CollectNamespace(call, cs, enclosingNode);
2825 operands = call.getOperandList();
2826 for (
int i = 0; i < operands.size(); i++) {
2832 throw Util.unexpected(node.getKind());
2837 SqlValidatorScope parentScope,
2838 SqlValidatorScope usingScope,
2840 SqlNode enclosingNode,
2842 boolean forceNullable) {
2843 SqlCall call = (SqlCall) node;
2844 final SetopNamespace setopNamespace =
2849 scopes.put(call, parentScope);
2850 for (SqlNode operand : call.getOperandList()) {
2862 SqlValidatorScope parentScope,
2863 SqlValidatorScope usingScope,
2865 SqlNode enclosingNode,
2867 boolean forceNullable,
2868 boolean checkUpdate) {
2869 final WithNamespace withNamespace =
2870 new WithNamespace(
this, with, enclosingNode);
2873 SqlValidatorScope scope = parentScope;
2874 for (SqlNode withItem_ : with.withList) {
2875 final SqlWithItem withItem = (SqlWithItem) withItem_;
2876 final WithScope withScope =
new WithScope(scope, withItem);
2877 scopes.put(withItem, withScope);
2880 withItem.name.getSimple(),
false);
2882 new WithItemNamespace(
this, withItem, enclosingNode),
2887 registerQuery(scope, null, with.body, enclosingNode, alias, forceNullable,
2896 for (SqlCall call :
overFinder.findAll(select.getSelectList())) {
2897 assert call.getKind() == SqlKind.OVER;
2909 AggFinder nestedAggFinder =
2912 return nestedAggFinder.findAgg(node) != null;
2916 return aggFinder.findAgg(node) != null;
2926 SqlNode node = select.getGroup();
2930 node = select.getHaving();
2941 if (selectScope != null) {
2942 final List<SqlNode> selectList = selectScope.getExpandedSelectList();
2943 if (selectList != null) {
2944 return aggFinder.findAgg(selectList);
2947 return aggFinder.findAgg(select.getSelectList());
2952 return aggFinder.findAgg(selectNode) != null;
2956 switch (node.getKind()) {
2957 case MULTISET_VALUE_CONSTRUCTOR:
2958 validateFeature(RESOURCE.sQLFeature_S271(), node.getParserPosition());
2964 SqlValidatorScope parentScope,
2969 if (node.getKind().belongsTo(SqlKind.QUERY)
2970 || node.getKind() == SqlKind.MULTISET_QUERY_CONSTRUCTOR
2971 || node.getKind() == SqlKind.MULTISET_VALUE_CONSTRUCTOR) {
2973 }
else if (node instanceof SqlCall) {
2975 SqlCall call = (SqlCall) node;
2976 for (
int i = 0; i < call.operandCount(); i++) {
2979 }
else if (node instanceof SqlNodeList) {
2980 SqlNodeList list = (SqlNodeList) node;
2981 for (
int i = 0, count = list.size(); i < count; i++) {
2982 SqlNode listNode = list.get(i);
2983 if (listNode.getKind().belongsTo(SqlKind.QUERY)) {
2985 SqlStdOperatorTable.SCALAR_QUERY.createCall(
2986 listNode.getParserPosition(),
2988 list.set(i, listNode);
3007 SqlValidatorScope parentScope,
3009 int operandOrdinal) {
3010 SqlNode operand = call.operand(operandOrdinal);
3011 if (operand == null) {
3014 if (operand.getKind().belongsTo(SqlKind.QUERY)
3015 && call.getOperator().argumentMustBeScalar(operandOrdinal)) {
3017 SqlStdOperatorTable.SCALAR_QUERY.createCall(
3018 operand.getParserPosition(),
3020 call.setOperand(operandOrdinal, operand);
3026 final SqlQualified fqId = scope.fullyQualify(id);
3027 if (this.
config.columnReferenceExpansion()) {
3030 id.assignNamesFrom(fqId.identifier);
3037 switch (literal.getTypeName()) {
3048 BigDecimal bd = (BigDecimal) literal.getValue();
3049 BigInteger unscaled = bd.unscaledValue();
3050 long longValue = unscaled.longValue();
3051 if (!BigInteger.valueOf(longValue).equals(unscaled)) {
3054 RESOURCE.numberLiteralOutOfRange(bd.toString()));
3063 final BitString bitString = (BitString) literal.getValue();
3064 if ((bitString.getBitCount() % 8) != 0) {
3072 Calendar calendar = literal.getValueAs(Calendar.class);
3073 final int year = calendar.get(Calendar.YEAR);
3074 final int era = calendar.get(Calendar.ERA);
3075 if (year < 1 || era == GregorianCalendar.BC || year > 9999) {
3077 RESOURCE.dateLiteralOutOfRange(literal.toString()));
3082 case INTERVAL_YEAR_MONTH:
3083 case INTERVAL_MONTH:
3085 case INTERVAL_DAY_HOUR:
3086 case INTERVAL_DAY_MINUTE:
3087 case INTERVAL_DAY_SECOND:
3089 case INTERVAL_HOUR_MINUTE:
3090 case INTERVAL_HOUR_SECOND:
3091 case INTERVAL_MINUTE:
3092 case INTERVAL_MINUTE_SECOND:
3093 case INTERVAL_SECOND:
3094 if (literal instanceof SqlIntervalLiteral) {
3095 SqlIntervalLiteral.IntervalValue interval =
3096 literal.getValueAs(SqlIntervalLiteral.IntervalValue.class);
3097 SqlIntervalQualifier intervalQualifier =
3098 interval.getIntervalQualifier();
3102 String intervalStr = interval.getIntervalLiteral();
3104 int[] values = intervalQualifier.evaluateIntervalLiteral(intervalStr,
3105 literal.getParserPosition(),
typeFactory.getTypeSystem());
3106 Util.discard(values);
3115 BigDecimal bd = (BigDecimal) literal.getValue();
3116 double d = bd.doubleValue();
3117 if (
Double.isInfinite(d) || Double.isNaN(d)) {
3120 RESOURCE.numberLiteralOutOfRange(Util.toScientificNotation(bd)));
3127 assert qualifier != null;
3128 boolean startPrecisionOutOfRange =
false;
3129 boolean fractionalSecondPrecisionOutOfRange =
false;
3130 final RelDataTypeSystem typeSystem = typeFactory.getTypeSystem();
3132 final int startPrecision = qualifier.getStartPrecision(typeSystem);
3133 final int fracPrecision =
3134 qualifier.getFractionalSecondPrecision(typeSystem);
3135 final int maxPrecision = typeSystem.getMaxPrecision(qualifier.typeName());
3136 final int minPrecision = qualifier.typeName().getMinPrecision();
3137 final int minScale = qualifier.typeName().getMinScale();
3138 final int maxScale = typeSystem.getMaxScale(qualifier.typeName());
3139 if (startPrecision < minPrecision || startPrecision > maxPrecision) {
3140 startPrecisionOutOfRange =
true;
3142 if (fracPrecision < minScale || fracPrecision > maxScale) {
3143 fractionalSecondPrecisionOutOfRange =
true;
3147 if (startPrecisionOutOfRange) {
3149 RESOURCE.intervalStartPrecisionOutOfRange(startPrecision,
3150 "INTERVAL " + qualifier));
3151 }
else if (fractionalSecondPrecisionOutOfRange) {
3153 RESOURCE.intervalFractionalSecondPrecisionOutOfRange(
3155 "INTERVAL " + qualifier));
3171 RelDataType targetRowType,
3172 SqlValidatorScope scope) {
3173 Objects.requireNonNull(targetRowType);
3174 switch (node.getKind()) {
3178 ((SqlCall) node).operand(0),
3205 throw new AssertionError(
"OVER unexpected in this context");
3208 protected void validateUnnest(SqlCall call, SqlValidatorScope scope, RelDataType targetRowType) {
3209 for (
int i = 0; i < call.operandCount(); i++) {
3210 SqlNode expandedItem =
expand(call.operand(i), scope);
3211 call.setOperand(i, expandedItem);
3217 SqlNode leftOrRight, SqlValidatorScope scope) {
3218 SqlValidatorNamespace
namespace =
getNamespace(leftOrRight, scope);
3219 if (
namespace != null) {
3220 SqlValidatorTable sqlValidatorTable = namespace.getTable();
3221 if (sqlValidatorTable != null) {
3222 Table table = sqlValidatorTable.unwrap(Table.class);
3223 String column = Util.last(identifier.names);
3225 if (table.isRolledUp(column)) {
3227 RESOURCE.rolledUpNotAllowed(column,
"USING"));
3234 SqlNode left = join.getLeft();
3235 SqlNode right = join.getRight();
3236 SqlNode condition = join.getCondition();
3237 boolean natural = join.isNatural();
3238 final JoinType joinType = join.getJoinType();
3239 final JoinConditionType conditionType = join.getConditionType();
3240 final SqlValidatorScope joinScope = scopes.get(
join);
3245 switch (conditionType) {
3247 Preconditions.checkArgument(condition == null);
3250 Preconditions.checkArgument(condition != null);
3251 SqlNode expandedCondition =
expand(condition, joinScope);
3252 join.setOperand(5, expandedCondition);
3253 condition = join.getCondition();
3255 checkRollUp(null, join, condition, joinScope,
"ON");
3258 SqlNodeList list = (SqlNodeList) condition;
3261 Preconditions.checkArgument(list.size() > 0,
"Empty USING clause");
3262 for (SqlNode node : list) {
3263 SqlIdentifier
id = (SqlIdentifier) node;
3266 if (!SqlTypeUtil.isComparable(leftColType, rightColType)) {
3268 RESOURCE.naturalOrUsingColumnNotCompatible(
id.getSimple(),
3269 leftColType.toString(), rightColType.toString()));
3276 throw Util.unexpected(conditionType);
3281 if (condition != null) {
3283 RESOURCE.naturalDisallowsOnOrUsing());
3288 final RelDataType leftRowType =
getNamespace(left).getRowType();
3289 final RelDataType rightRowType =
getNamespace(right).getRowType();
3290 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
3291 List<String> naturalColumnNames =
3292 SqlValidatorUtil.deriveNaturalJoinColumnList(nameMatcher,
3293 leftRowType, rightRowType);
3296 for (String
name : naturalColumnNames) {
3297 final RelDataType leftColType =
3298 nameMatcher.field(leftRowType,
name).getType();
3299 final RelDataType rightColType =
3300 nameMatcher.field(rightRowType,
name).getType();
3301 if (!SqlTypeUtil.isComparable(leftColType, rightColType)) {
3303 RESOURCE.naturalOrUsingColumnNotCompatible(
name,
3304 leftColType.toString(), rightColType.toString()));
3312 case LEFT_SEMI_JOIN:
3313 if (!this.
config.sqlConformance().isLiberal()) {
3315 RESOURCE.dialectDoesNotSupportFeature(
"LEFT SEMI JOIN"));
3322 if ((condition == null) && !natural) {
3328 if (condition != null) {
3330 RESOURCE.crossJoinDisallowsCondition());
3334 RESOURCE.crossJoinDisallowsCondition());
3338 throw Util.unexpected(joinType);
3352 final SqlCall agg = aggFinder.findAgg(node);
3357 if (op == SqlStdOperatorTable.OVER) {
3359 RESOURCE.windowedAggregateIllegalInClause(clause));
3360 }
else if (op.
isGroup() || op.isGroupAuxiliary()) {
3362 RESOURCE.groupFunctionMustAppearInGroupByClause(op.
getName()));
3365 RESOURCE.aggregateIllegalInClause(clause));
3370 if (
id.names.size() == 1) {
3371 String
name = id.names.get(0);
3372 final SqlValidatorNamespace
namespace = getNamespace(leftOrRight);
3373 final RelDataType rowType = namespace.getRowType();
3374 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
3375 final RelDataTypeField
field = nameMatcher.field(rowType,
name);
3376 if (
field != null) {
3377 if (nameMatcher.frequency(rowType.getFieldNames(),
name) > 1) {
3379 RESOURCE.columnInUsingNotUnique(
id.toString()));
3381 return field.getType();
3396 RelDataType targetRowType) {
3397 assert targetRowType != null;
3399 final SelectNamespace ns =
3405 assert ns.rowType == null;
3407 if (select.isDistinct()) {
3409 select.getModifierNode(SqlSelectKeyword.DISTINCT)
3410 .getParserPosition());
3413 final SqlNodeList selectItems = select.getSelectList();
3415 if (selectItems.size() == 1) {
3416 final SqlNode selectItem = selectItems.get(0);
3417 if (selectItem instanceof SqlIdentifier) {
3418 SqlIdentifier
id = (SqlIdentifier) selectItem;
3419 if (
id.isStar() && (id.names.size() == 1)) {
3425 fromType = targetRowType;
3431 final SelectScope fromScope = (SelectScope)
getFromScope(select);
3432 List<String> names = fromScope.getChildNames();
3434 names = names.stream()
3435 .map(s -> s.toUpperCase(Locale.ROOT))
3436 .collect(Collectors.toList());
3438 final int duplicateAliasOrdinal = Util.firstDuplicate(names);
3439 if (duplicateAliasOrdinal >= 0) {
3440 final ScopeChild child =
3441 fromScope.children.get(duplicateAliasOrdinal);
3446 if (select.getFrom() == null) {
3447 if (this.
config.sqlConformance().isFromRequired()) {
3463 final RelDataType rowType =
3465 ns.setType(rowType);
3484 for (SqlNode item : select.getSelectList()) {
3490 SqlNodeList group = select.getGroup();
3491 if (group != null) {
3492 for (SqlNode node : group) {
3499 SqlNodeList orderList = select.getOrderList();
3500 if (orderList != null) {
3501 for (SqlNode node : orderList) {
3508 if (window != null) {
3509 for (SqlNode node : window.getPartitionList()) {
3510 checkRollUp(null, window, node, scope,
"PARTITION BY");
3513 for (SqlNode node : window.getOrderList()) {
3514 checkRollUp(null, window, node, scope,
"ORDER BY");
3520 for (SqlNode decl : select.getWindowList()) {
3526 if (node != null && node.getKind() == SqlKind.DOT) {
3527 return stripDot(((SqlCall) node).operand(0));
3533 SqlNode current, SqlValidatorScope scope, String optionalClause) {
3534 current = stripAs(current);
3535 if (current instanceof SqlCall && !(current instanceof SqlSelect)) {
3540 List<SqlNode> children = ((SqlCall) stripAs(
stripDot(current))).getOperandList();
3541 for (SqlNode child : children) {
3542 checkRollUp(parent, current, child, scope, optionalClause);
3544 }
else if (current instanceof SqlIdentifier) {
3545 SqlIdentifier
id = (SqlIdentifier) current;
3549 String context = optionalClause != null ? optionalClause : parent.getKind().
toString();
3551 RESOURCE.rolledUpNotAllowed(
deriveAlias(
id, 0), context));
3558 SqlNode current, SqlValidatorScope scope) {
3559 checkRollUp(grandParent, parent, current, scope, null);
3563 if (over.getKind() == SqlKind.OVER) {
3564 SqlNode window = ((SqlCall) over).getOperandList().
get(1);
3565 if (window instanceof SqlWindow) {
3566 return (SqlWindow) window;
3575 switch (node.getKind()) {
3577 return ((SqlCall) node).getOperandList().get(0);
3584 SqlValidatorScope scope) {
3589 SqlQualified qualified = scope.fullyQualify(identifier);
3590 List<String> names = qualified.identifier.names;
3592 if (names.size() < 2) {
3596 return new Pair<>(names.get(names.size() - 2), Util.last(names));
3601 SqlCall aggCall, SqlNode parent) {
3608 String columnName = pair.right;
3610 SqlValidatorTable sqlValidatorTable =
3611 scope.fullyQualify(identifier).
namespace.getTable();
3612 if (sqlValidatorTable != null) {
3613 Table table = sqlValidatorTable.unwrap(Table.class);
3614 return table.rolledUpColumnValidInsideAgg(columnName, aggCall, parent,
3615 catalogReader.getConfig());
3629 String columnName = pair.right;
3631 SqlValidatorTable sqlValidatorTable =
3632 scope.fullyQualify(identifier).
namespace.getTable();
3633 if (sqlValidatorTable != null) {
3634 Table table = sqlValidatorTable.unwrap(Table.class);
3635 return table.isRolledUp(columnName);
3642 SqlKind kind = stripAs(from).getKind();
3643 return kind != SqlKind.VALUES && kind != SqlKind.SELECT;
3652 if (query instanceof SqlSelect) {
3653 final SqlSelect select = (SqlSelect) query;
3655 }
else if (query.getKind() == SqlKind.VALUES) {
3661 assert query.isA(SqlKind.SET_QUERY);
3662 final SqlCall call = (SqlCall) query;
3663 for (SqlNode operand : call.getOperandList()) {
3666 Static.RESOURCE.streamSetOpInconsistentInputs());
3675 if (query instanceof SqlSelect) {
3676 SqlSelect select = (SqlSelect) query;
3677 return select.getModifierNode(SqlSelectKeyword.STREAM) != null
3678 ? SqlModality.STREAM
3679 : SqlModality.RELATION;
3680 }
else if (query.getKind() == SqlKind.VALUES) {
3681 return SqlModality.RELATION;
3683 assert query.isA(SqlKind.SET_QUERY);
3684 final SqlCall call = (SqlCall) query;
3695 if (scope.children.size() == 1) {
3696 for (ScopeChild child : scope.children) {
3697 if (!child.namespace.supportsModality(modality)) {
3700 Static.RESOURCE.cannotConvertToStream(
child.name));
3707 int supportsModalityCount = 0;
3708 for (ScopeChild child : scope.children) {
3709 if (child.namespace.supportsModality(modality)) {
3710 ++supportsModalityCount;
3714 if (supportsModalityCount == 0) {
3716 String inputs = String.join(
", ", scope.getChildNames());
3718 Static.RESOURCE.cannotStreamResultsForNonStreamingInputs(inputs));
3726 for (ScopeChild child : scope.children) {
3727 if (!child.namespace.supportsModality(modality)) {
3730 Static.RESOURCE.cannotConvertToRelation(
child.name));
3740 if (aggregateNode != null) {
3743 SqlNodeList groupList = select.getGroup();
3744 if (groupList == null
3745 || !SqlValidatorUtil.containsMonotonic(scope, groupList)) {
3748 Static.RESOURCE.streamMustGroupByMonotonic());
3757 final SqlNodeList orderList = select.getOrderList();
3758 if (orderList != null && orderList.size() > 0) {
3764 Static.RESOURCE.streamMustOrderByMonotonic());
3780 boolean descending) {
3781 switch (node.getKind()) {
3786 final SqlMonotonicity monotonicity = scope.getMonotonicity(node);
3787 switch (monotonicity) {
3789 case STRICTLY_INCREASING:
3792 case STRICTLY_DECREASING:
3800 final SqlNodeList windowList = select.getWindowList();
3801 @SuppressWarnings(
"unchecked")
final List<SqlWindow> windows =
3802 (List) windowList.getList();
3803 if (windows.isEmpty()) {
3807 final SelectScope windowScope = (SelectScope)
getFromScope(select);
3808 assert windowScope != null;
3812 for (SqlWindow window : windows) {
3813 SqlIdentifier declName = window.getDeclName();
3814 if (!declName.isSimple()) {
3818 if (windowScope.existingWindowName(declName.toString())) {
3821 windowScope.addWindowName(declName.toString());
3827 for (
int i = 0; i < windows.size(); i++) {
3828 SqlNode window1 = windows.get(i);
3829 for (
int j = i + 1; j < windows.size(); j++) {
3830 SqlNode window2 = windows.get(j);
3831 if (window1.equalsDeep(window2, Litmus.IGNORE)) {
3837 for (SqlWindow window : windows) {
3838 final SqlNodeList expandedOrderList =
3839 (SqlNodeList)
expand(window.getOrderList(), windowScope);
3840 window.setOrderList(expandedOrderList);
3841 expandedOrderList.validate(
this, windowScope);
3843 final SqlNodeList expandedPartitionList =
3844 (SqlNodeList)
expand(window.getPartitionList(), windowScope);
3845 window.setPartitionList(expandedPartitionList);
3846 expandedPartitionList.validate(
this, windowScope);
3850 windowList.validate(
this, windowScope);
3854 final SqlValidatorNamespace
namespace = getNamespace(with);
3859 if (withItem.columnList != null) {
3861 final int fieldCount = rowType.getFieldCount();
3862 if (withItem.columnList.size() != fieldCount) {
3864 RESOURCE.columnCountMismatch());
3866 SqlValidatorUtil.checkIdentifierListForDuplicates(
3870 final List<String> fieldNames =
3872 final int i = Util.firstDuplicate(fieldNames);
3875 RESOURCE.duplicateColumnAndNoColumnList(fieldNames.get(i)));
3882 final SqlValidatorScope.ResolvedImpl resolved =
3883 new SqlValidatorScope.ResolvedImpl();
3884 scope.resolveTable(id.names, catalogReader.nameMatcher(),
3885 SqlValidatorScope.Path.EMPTY, resolved);
3886 if (resolved.count() != 1) {
3890 final SqlValidatorNamespace ns = resolved.only().
namespace;
3891 if (ns instanceof TableNamespace) {
3892 final Table table = ns.getTable().unwrap(Table.class);
3893 switch (table.getJdbcTableType()) {
3895 case TEMPORARY_SEQUENCE:
3903 assert withItem.getKind() == SqlKind.WITH_ITEM;
3904 return scopes.get(withItem);
3908 assert config.typeCoercionEnabled();
3909 return this.typeCoercion;
3917 this.config = transform.apply(this.config);
3930 SqlNodeList orderList = select.getOrderList();
3931 if (orderList == null) {
3940 Objects.requireNonNull(orderScope);
3942 List<SqlNode> expandList =
new ArrayList<>();
3943 for (SqlNode orderItem : orderList) {
3944 SqlNode expandedOrderItem =
expand(orderItem, orderScope);
3945 expandList.add(expandedOrderItem);
3948 SqlNodeList expandedOrderList =
new SqlNodeList(
3950 orderList.getParserPosition());
3951 select.setOrderBy(expandedOrderList);
3953 for (SqlNode orderItem : expandedOrderList) {
3965 final SqlValidatorScope groupByScope =
getGroupScope(select);
3967 groupByScope.validateExpr(groupByItem);
3971 SqlValidatorScope groupByScope) {
3972 switch (groupByItem.getKind()) {
3976 final SqlCall call = (SqlCall) groupByItem;
3977 for (SqlNode operand : call.getOperandList()) {
3993 switch (orderItem.getKind()) {
3996 orderItem.getParserPosition());
3998 ((SqlCall) orderItem).operand(0));
4007 final SqlNode newSqlNode =
4009 if (newSqlNode != orderExpr) {
4023 SqlNodeList groupList = select.getGroup();
4024 if (groupList == null) {
4027 final String clause =
"GROUP BY";
4033 List<SqlNode> expandedList =
new ArrayList<>();
4034 for (SqlNode groupItem : groupList) {
4036 expandedList.add(expandedItem);
4038 groupList =
new SqlNodeList(expandedList, groupList.getParserPosition());
4039 select.setGroupBy(groupList);
4040 for (SqlNode groupItem : expandedList) {
4047 for (SqlNode node : groupList) {
4048 switch (node.getKind()) {
4052 node.validate(
this, groupScope);
4055 node.validateExpr(
this, groupScope);
4063 AggregatingSelectScope aggregatingScope = null;
4064 if (selectScope instanceof AggregatingSelectScope) {
4065 aggregatingScope = (AggregatingSelectScope) selectScope;
4067 for (SqlNode groupItem : groupList) {
4068 if (groupItem instanceof SqlNodeList
4069 && ((SqlNodeList) groupItem).size() == 0) {
4075 SqlNode agg = aggFinder.findAgg(groupList);
4082 AggregatingSelectScope aggregatingScope,
4083 SqlNode groupItem) {
4084 switch (groupItem.getKind()) {
4091 if (groupItem instanceof SqlNodeList) {
4100 AggregatingSelectScope aggregatingScope, SqlCall groupItem) {
4101 for (SqlNode node : groupItem.getOperandList()) {
4108 final SqlNode where = select.getWhere();
4109 if (where == null) {
4113 final SqlNode expandedWhere =
expand(where, whereScope);
4114 select.setWhere(expandedWhere);
4119 SqlValidatorScope scope,
4127 condition.validate(
this, scope);
4130 if (!SqlTypeUtil.inBooleanFamily(type)) {
4140 SqlNode having = select.getHaving();
4141 if (having == null) {
4144 final AggregatingScope havingScope =
4146 if (
config.sqlConformance().isHavingAlias()) {
4148 if (having != newExpr) {
4150 select.setHaving(newExpr);
4153 havingScope.checkAggregateExpr(having,
true);
4158 having.validate(
this, havingScope);
4160 if (!SqlTypeUtil.inBooleanFamily(type)) {
4166 final SqlNodeList selectItems,
4168 RelDataType targetRowType) {
4174 final List<SqlNode> expandedSelectItems =
new ArrayList<>();
4175 final Set<String> aliases =
new HashSet<>();
4176 final List<Map.Entry<String, RelDataType>> fieldList =
new ArrayList<>();
4178 for (SqlNode selectItem : selectItems) {
4179 if (selectItem instanceof SqlSelect) {
4182 (SqlSelect) selectItem,
4183 expandedSelectItems,
4189 final int fieldIdx = fieldList.size();
4190 final RelDataType fieldType =
4191 targetRowType.isStruct()
4192 && targetRowType.getFieldCount() > fieldIdx
4193 ? targetRowType.getFieldList().
get(fieldIdx).getType()
4199 expandedSelectItems,
4209 SqlNodeList newSelectList =
4211 expandedSelectItems,
4212 selectItems.getParserPosition());
4213 if (
config.identifierExpansion()) {
4214 select.setSelectList(newSelectList);
4222 for (SqlNode selectItem : expandedSelectItems) {
4227 return typeFactory.createStructType(fieldList);
4237 if (expr instanceof SqlCall) {
4238 final SqlOperator op = ((SqlCall) expr).getOperator();
4241 RESOURCE.absentOverClause());
4243 if (op instanceof SqlTableFunction) {
4244 throw RESOURCE.cannotCallTableFunctionHere(op.getName()).ex();
4249 expr.validateExpr(
this, scope);
4253 scope.validateExpr(expr);
4268 SqlSelect parentSelect,
4269 SqlSelect selectItem,
4270 List<SqlNode> expandedSelectItems,
4271 Set<String> aliasList,
4272 List<Map.Entry<String, RelDataType>> fieldList) {
4274 if (1 != selectItem.getSelectList().size()) {
4276 RESOURCE.onlyScalarSubQueryAllowed());
4280 expandedSelectItems.add(selectItem);
4283 final String
alias =
4287 aliasList.add(
alias);
4289 final SelectScope scope = (SelectScope)
getWhereScope(parentSelect);
4296 assert type instanceof RelRecordType;
4297 RelRecordType rec = (RelRecordType) type;
4299 RelDataType nodeType = rec.getFieldList().
get(0).getType();
4300 nodeType = typeFactory.createTypeWithNullability(nodeType,
true);
4301 fieldList.add(Pair.of(
alias, nodeType));
4314 SqlValidatorTable table,
4315 SqlNodeList targetColumnList,
4317 RelDataType baseRowType = table.getRowType();
4318 if (targetColumnList == null) {
4321 List<RelDataTypeField> targetFields = baseRowType.getFieldList();
4322 final List<Map.Entry<String, RelDataType>> fields =
new ArrayList<>();
4324 for (RelDataTypeField targetField : targetFields) {
4326 Pair.of(SqlUtil.deriveAliasFromOrdinal(fields.size()),
4327 targetField.getType()));
4330 final Set<Integer> assignedFields =
new HashSet<>();
4331 final RelOptTable relOptTable = table instanceof RelOptTable
4332 ? ((RelOptTable) table) : null;
4333 for (SqlNode node : targetColumnList) {
4334 SqlIdentifier
id = (SqlIdentifier) node;
4335 RelDataTypeField targetField =
4336 SqlValidatorUtil.getTargetField(
4338 if (targetField == null) {
4340 RESOURCE.unknownTargetColumn(
id.toString()));
4342 if (!assignedFields.add(targetField.getIndex())) {
4344 RESOURCE.duplicateTargetColumn(targetField.getName()));
4346 fields.add(targetField);
4348 return typeFactory.createStructType(fields);
4352 final SqlValidatorNamespace targetNamespace =
getNamespace(insert);
4354 final RelOptTable relOptTable = SqlValidatorUtil.getRelOptTable(
4355 targetNamespace, catalogReader.unwrap(Prepare.CatalogReader.class), null, null);
4356 final SqlValidatorTable table = relOptTable == null
4357 ? targetNamespace.getTable()
4358 : relOptTable.unwrap(SqlValidatorTable.class);
4363 final RelDataType targetRowType =
4366 insert.getTargetColumnList(),
4369 final SqlNode source = insert.getSource();
4370 if (source instanceof SqlSelect) {
4371 final SqlSelect sqlSelect = (SqlSelect) source;
4374 final SqlValidatorScope scope = scopes.get(source);
4383 final RelDataType sourceRowType =
getNamespace(source).getRowType();
4384 final RelDataType logicalTargetRowType =
4387 final RelDataType logicalSourceRowType =
4390 final List<ColumnStrategy> strategies =
4391 table.unwrap(RelOptTable.class).getColumnStrategies();
4393 final RelDataType realTargetRowType = typeFactory.createStructType(
4394 logicalTargetRowType.getFieldList()
4395 .stream().filter(
f -> strategies.get(f.getIndex()).canInsertInto())
4396 .collect(Collectors.toList()));
4398 final RelDataType targetRowTypeToValidate =
4399 logicalSourceRowType.getFieldCount() == logicalTargetRowType.getFieldCount()
4400 ? logicalTargetRowType
4401 : realTargetRowType;
4404 targetRowTypeToValidate, realTargetRowType,
4405 source, logicalSourceRowType, logicalTargetRowType);
4409 logicalSourceRowType,
4410 targetRowTypeToValidate,
4415 validateAccess(insert.getTargetTable(), table, SqlAccessEnum.INSERT);
4429 SqlValidatorTable validatorTable,
4431 RelDataType targetRowType) {
4432 final ModifiableViewTable modifiableViewTable =
4433 validatorTable.unwrap(ModifiableViewTable.class);
4434 if (modifiableViewTable != null && source instanceof SqlCall) {
4435 final Table table = modifiableViewTable.unwrap(Table.class);
4436 final RelDataType tableRowType = table.getRowType(
typeFactory);
4437 final List<RelDataTypeField> tableFields = tableRowType.getFieldList();
4441 final Map<Integer, RelDataTypeField> tableIndexToTargetField =
4442 SqlValidatorUtil.getIndexToFieldMap(tableFields, targetRowType);
4443 final Map<Integer, RexNode> projectMap =
4444 RelOptUtil.getColumnConstraints(modifiableViewTable, targetRowType,
typeFactory);
4448 final ImmutableBitSet targetColumns =
4449 ImmutableBitSet.of(tableIndexToTargetField.keySet());
4450 final ImmutableBitSet constrainedColumns =
4451 ImmutableBitSet.of(projectMap.keySet());
4452 final ImmutableBitSet constrainedTargetColumns =
4453 targetColumns.intersect(constrainedColumns);
4456 final List<SqlNode> values = ((SqlCall) source).getOperandList();
4457 for (
final int colIndex : constrainedTargetColumns.asList()) {
4458 final String colName = tableFields.get(colIndex).getName();
4459 final RelDataTypeField targetField = tableIndexToTargetField.get(colIndex);
4460 for (SqlNode row : values) {
4461 final SqlCall call = (SqlCall) row;
4462 final SqlNode sourceValue = call.operand(targetField.getIndex());
4465 RESOURCE.viewConstraintNotSatisfied(colName,
4466 Util.last(validatorTable.getQualifiedName())));
4467 RelOptUtil.validateValueAgainstConstraint(sourceValue,
4468 projectMap.get(colIndex), validationError);
4483 SqlValidatorTable validatorTable,
4485 RelDataType targetRowType) {
4486 final ModifiableViewTable modifiableViewTable =
4487 validatorTable.unwrap(ModifiableViewTable.class);
4488 if (modifiableViewTable != null) {
4489 final Table table = modifiableViewTable.unwrap(Table.class);
4490 final RelDataType tableRowType = table.getRowType(
typeFactory);
4492 final Map<Integer, RexNode> projectMap =
4493 RelOptUtil.getColumnConstraints(modifiableViewTable, targetRowType,
4495 final Map<String, Integer> nameToIndex =
4496 SqlValidatorUtil.mapNameToIndex(tableRowType.getFieldList());
4499 final List<SqlNode> targets = update.getTargetColumnList().getList();
4500 final List<SqlNode> sources = update.getSourceExpressionList().getList();
4501 for (
final Pair<SqlNode, SqlNode> column : Pair.zip(targets, sources)) {
4502 final String columnName = ((SqlIdentifier) column.left).getSimple();
4503 final Integer columnIndex = nameToIndex.get(columnName);
4504 if (projectMap.containsKey(columnIndex)) {
4505 final RexNode columnConstraint = projectMap.get(columnIndex);
4508 RESOURCE.viewConstraintNotSatisfied(columnName,
4509 Util.last(validatorTable.getQualifiedName())));
4510 RelOptUtil.validateValueAgainstConstraint(column.right,
4511 columnConstraint, validationError);
4533 List<ColumnStrategy> strategies, RelDataType targetRowTypeToValidate,
4534 RelDataType realTargetRowType, SqlNode source,
4535 RelDataType logicalSourceRowType, RelDataType logicalTargetRowType) {
4536 final int sourceFieldCount = logicalSourceRowType.getFieldCount();
4537 final int targetFieldCount = logicalTargetRowType.getFieldCount();
4538 final int targetRealFieldCount = realTargetRowType.getFieldCount();
4539 if (sourceFieldCount != targetFieldCount
4540 && sourceFieldCount != targetRealFieldCount) {
4545 RESOURCE.unmatchInsertColumn(targetFieldCount, sourceFieldCount));
4548 for (
final RelDataTypeField
field : table.getRowType().getFieldList()) {
4549 final RelDataTypeField targetField =
4550 targetRowTypeToValidate.getField(field.getName(),
true,
false);
4551 switch (strategies.get(
field.getIndex())) {
4553 assert !field.getType().isNullable();
4554 if (targetField == null) {
4556 RESOURCE.columnNotNullable(
field.getName()));
4560 assert field.getType().isNullable();
4564 if (targetField != null
4567 RESOURCE.insertIntoAlwaysGenerated(
field.getName()));
4576 switch (source.getKind()) {
4578 for (SqlNode operand : ((SqlCall) source).getOperandList()) {
4589 switch (operand.getKind()) {
4591 final SqlCall row = (SqlCall) operand;
4592 return row.getOperandList().size() >= column
4593 && row.getOperandList().
get(column).getKind() == SqlKind.DEFAULT;
4599 RelDataType targetRowType,
4601 if (insert.getTargetColumnList() == null
4602 && this.config.sqlConformance().isInsertSubsetColumnsAllowed()) {
4604 final SqlNode source = insert.getSource();
4605 final RelDataType sourceRowType =
getNamespace(source).getRowType();
4606 final RelDataType logicalSourceRowType =
4608 final RelDataType implicitTargetRowType =
4609 typeFactory.createStructType(
4610 targetRowType.getFieldList()
4611 .subList(0, logicalSourceRowType.getFieldCount()));
4612 final SqlValidatorNamespace targetNamespace =
getNamespace(insert);
4614 return implicitTargetRowType;
4618 return targetRowType;
4623 RelDataType sourceRowType,
4625 return sourceRowType;
4643 SqlValidatorScope sourceScope,
4644 SqlValidatorTable table,
4645 RelDataType sourceRowType,
4646 RelDataType targetRowType,
4647 final SqlNode query) {
4651 boolean isUpdateModifiableViewTable =
false;
4652 if (query instanceof SqlUpdate) {
4653 final SqlNodeList targetColumnList = ((SqlUpdate) query).getTargetColumnList();
4654 if (targetColumnList != null) {
4655 final int targetColumnCnt = targetColumnList.size();
4656 targetRowType = SqlTypeUtil.extractLastNFields(
typeFactory, targetRowType,
4658 sourceRowType = SqlTypeUtil.extractLastNFields(
typeFactory, sourceRowType,
4661 isUpdateModifiableViewTable = table.unwrap(ModifiableViewTable.class) != null;
4663 if (SqlTypeUtil.equalAsStructSansNullability(
typeFactory,
4670 if (
config.typeCoercionEnabled() && !isUpdateModifiableViewTable) {
4672 boolean coerced = typeCoercion.querySourceCoercion(sourceScope,
4682 List<RelDataTypeField> sourceFields = sourceRowType.getFieldList();
4683 List<RelDataTypeField> targetFields = targetRowType.getFieldList();
4684 final int sourceCount = sourceFields.size();
4685 for (
int i = 0; i < sourceCount; ++i) {
4686 RelDataType sourceType = sourceFields.get(i).getType();
4687 RelDataType targetType = targetFields.get(i).getType();
4688 if (!SqlTypeUtil.canAssignFrom(targetType, sourceType)) {
4689 SqlNode node =
getNthExpr(query, i, sourceCount);
4690 if (node instanceof SqlDynamicParam) {
4693 String targetTypeString;
4694 String sourceTypeString;
4695 if (SqlTypeUtil.areCharacterSetsMismatched(
4698 sourceTypeString = sourceType.getFullTypeString();
4699 targetTypeString = targetType.getFullTypeString();
4701 sourceTypeString = sourceType.toString();
4702 targetTypeString = targetType.toString();
4705 RESOURCE.typeNotAssignable(
4706 targetFields.get(i).getName(), targetTypeString,
4707 sourceFields.get(i).getName(), sourceTypeString));
4720 private SqlNode
getNthExpr(SqlNode query,
int ordinal,
int sourceCount) {
4721 if (query instanceof SqlInsert) {
4722 SqlInsert insert = (SqlInsert) query;
4723 if (insert.getTargetColumnList() != null) {
4724 return insert.getTargetColumnList().
get(ordinal);
4731 }
else if (query instanceof SqlUpdate) {
4732 SqlUpdate update = (SqlUpdate) query;
4733 if (update.getSourceExpressionList() != null) {
4734 return update.getSourceExpressionList().
get(ordinal);
4737 update.getSourceSelect(),
4741 }
else if (query instanceof SqlSelect) {
4742 SqlSelect select = (SqlSelect) query;
4743 if (select.getSelectList().size() == sourceCount) {
4744 return select.getSelectList().
get(ordinal);
4754 final SqlSelect sqlSelect = call.getSourceSelect();
4757 final SqlValidatorNamespace targetNamespace =
getNamespace(call);
4759 final SqlValidatorTable table = targetNamespace.getTable();
4761 validateAccess(call.getTargetTable(), table, SqlAccessEnum.DELETE);
4765 final SqlValidatorNamespace targetNamespace =
getNamespace(call);
4767 final RelOptTable relOptTable = SqlValidatorUtil.getRelOptTable(
4768 targetNamespace, catalogReader.unwrap(Prepare.CatalogReader.class), null, null);
4769 final SqlValidatorTable table = relOptTable == null
4770 ? targetNamespace.getTable()
4771 : relOptTable.unwrap(SqlValidatorTable.class);
4773 final RelDataType targetRowType =
4776 call.getTargetColumnList(),
4779 final SqlSelect select = call.getSourceSelect();
4791 validateAccess(call.getTargetTable(), table, SqlAccessEnum.UPDATE);
4795 SqlSelect sqlSelect = call.getSourceSelect();
4808 IdentifierNamespace targetNamespace =
4809 (IdentifierNamespace)
getNamespace(call.getTargetTable());
4812 SqlValidatorTable table = targetNamespace.getTable();
4813 validateAccess(call.getTargetTable(), table, SqlAccessEnum.UPDATE);
4817 if (call.getUpdateCall() != null) {
4820 call.getUpdateCall().getTargetColumnList(),
4823 if (call.getInsertCall() != null) {
4826 call.getInsertCall().getTargetColumnList(),
4832 if (call.getUpdateCall() != null) {
4835 if (call.getInsertCall() != null) {
4848 SqlValidatorTable table,
4849 SqlAccessEnum requiredAccess) {
4850 if (table != null) {
4851 SqlAccessType access = table.getAllowedAccess();
4852 if (!access.allowsAccess(requiredAccess)) {
4854 RESOURCE.accessNotAllowed(requiredAccess.name(),
4855 table.getQualifiedName().
toString()));
4869 SqlValidatorScope scope,
4870 SqlValidatorNamespace ns) {
4871 if (node.getKind() == SqlKind.SNAPSHOT) {
4872 SqlSnapshot snapshot = (SqlSnapshot) node;
4873 SqlNode period = snapshot.getPeriod();
4874 RelDataType dataType =
deriveType(scope, period);
4875 if (dataType.getSqlTypeName() != SqlTypeName.TIMESTAMP) {
4877 Static.RESOURCE.illegalExpressionForTemporal(dataType.getSqlTypeName().getName()));
4879 if (!ns.getTable().isTemporal()) {
4880 List<String> qualifiedName = ns.getTable().getQualifiedName();
4881 String tableName = qualifiedName.get(qualifiedName.size() - 1);
4883 Static.RESOURCE.notTemporalTable(tableName));
4897 RelDataType targetRowType,
4898 final SqlValidatorScope scope) {
4899 assert node.getKind() == SqlKind.VALUES;
4901 final List<SqlNode> operands = node.getOperandList();
4902 for (SqlNode operand : operands) {
4903 if (!(operand.getKind() == SqlKind.ROW)) {
4904 throw Util.needToImplement(
4905 "Values function where operands are scalars");
4908 SqlCall rowConstructor = (SqlCall) operand;
4909 if (this.
config.sqlConformance().isInsertSubsetColumnsAllowed()
4910 && targetRowType.isStruct()
4911 && rowConstructor.operandCount() < targetRowType.getFieldCount()) {
4913 typeFactory.createStructType(
4914 targetRowType.getFieldList()
4915 .subList(0, rowConstructor.operandCount()));
4916 }
else if (targetRowType.isStruct()
4917 && rowConstructor.operandCount() != targetRowType.getFieldCount()) {
4926 if (targetRowType.isStruct()) {
4927 for (Pair<SqlNode, RelDataTypeField> pair
4928 : Pair.zip(rowConstructor.getOperandList(),
4929 targetRowType.getFieldList())) {
4930 if (!pair.right.getType().isNullable()
4931 && SqlUtil.isNullLiteral(pair.left,
false)) {
4933 RESOURCE.columnNotNullable(pair.right.getName()));
4939 for (SqlNode operand : operands) {
4940 operand.validate(
this, scope);
4947 final int rowCount = operands.size();
4948 if (rowCount >= 2) {
4949 SqlCall firstRow = (SqlCall) operands.get(0);
4950 final int columnCount = firstRow.operandCount();
4953 for (SqlNode operand : operands) {
4954 SqlCall thisRow = (SqlCall) operand;
4955 if (columnCount != thisRow.operandCount()) {
4957 RESOURCE.incompatibleValueType(
4958 SqlStdOperatorTable.VALUES.getName()));
4963 for (
int col = 0; col < columnCount; col++) {
4965 final RelDataType
type =
4966 typeFactory.leastRestrictive(
4967 new AbstractList<RelDataType>() {
4968 public RelDataType
get(
int row) {
4969 SqlCall thisRow = (SqlCall) operands.get(row);
4970 return deriveType(scope, thisRow.operand(c));
4980 RESOURCE.incompatibleValueType(
4981 SqlStdOperatorTable.VALUES.getName()));
5007 public CalciteContextException
get() {
5017 implements Function2<SqlNode, Resources.ExInst<SqlValidatorException>,
5018 CalciteContextException> {
5019 @Override
public CalciteContextException
apply(
5020 SqlNode v0, Resources.ExInst<SqlValidatorException> v1) {
5030 Resources.ExInst<SqlValidatorException> e) {
5031 assert node != null;
5032 final SqlParserPos pos = node.getParserPosition();
5033 return SqlUtil.newContextException(pos, e);
5038 SqlValidatorScope scope) {
5039 SqlWindow window = null;
5040 if (
id.isSimple()) {
5041 final String
name = id.getSimple();
5042 window = scope.lookupWindow(
name);
5044 if (window == null) {
5051 SqlNode windowOrRef,
5052 SqlValidatorScope scope) {
5054 if (windowOrRef instanceof SqlIdentifier) {
5057 window = (SqlWindow) windowOrRef;
5060 final SqlIdentifier refId = window.getRefName();
5061 if (refId == null) {
5064 final String refName = refId.getSimple();
5065 SqlWindow refWindow = scope.lookupWindow(refName);
5066 if (refWindow == null) {
5069 window = window.overlay(refWindow,
this);
5076 SqlNode original = originalExprs.get(expr);
5077 if (original == null) {
5085 originalExprs.putIfAbsent(expr, original);
5089 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
5090 final RelDataTypeField
field = nameMatcher.field(rowType,
name);
5091 if (field == null) {
5094 return new FieldNamespace(
this, field.getType());
5099 SqlValidatorScope scope,
5104 final SqlWindow targetWindow;
5105 switch (windowOrId.getKind()) {
5112 targetWindow = (SqlWindow) windowOrId;
5115 throw Util.unexpected(windowOrId.getKind());
5118 assert targetWindow.getWindowCall() == null;
5119 targetWindow.setWindowCall(call);
5120 targetWindow.validate(
this, scope);
5121 targetWindow.setWindowCall(null);
5122 call.validate(
this, scope);
5131 final SqlMatchRecognize matchRecognize = (SqlMatchRecognize) call;
5132 final MatchRecognizeScope scope =
5135 final MatchRecognizeNamespace ns =
5136 getNamespace(call).unwrap(MatchRecognizeNamespace.class);
5137 assert ns.rowType == null;
5140 final SqlLiteral rowsPerMatch = matchRecognize.getRowsPerMatch();
5141 final boolean allRows = rowsPerMatch != null
5142 && rowsPerMatch.getValue()
5143 == SqlMatchRecognize.RowsPerMatchOption.ALL_ROWS;
5145 final RelDataTypeFactory.Builder typeBuilder =
typeFactory.builder();
5148 SqlNodeList partitionBy = matchRecognize.getPartitionList();
5149 if (partitionBy != null) {
5150 for (SqlNode node : partitionBy) {
5151 SqlIdentifier identifier = (SqlIdentifier) node;
5152 identifier.validate(
this, scope);
5154 String
name = identifier.names.get(1);
5160 SqlNodeList orderBy = matchRecognize.getOrderList();
5161 if (orderBy != null) {
5162 for (SqlNode node : orderBy) {
5163 node.validate(
this, scope);
5164 SqlIdentifier identifier;
5165 if (node instanceof SqlBasicCall) {
5166 identifier = (SqlIdentifier) ((SqlBasicCall) node).getOperands()[0];
5168 identifier = (SqlIdentifier) node;
5173 String
name = identifier.names.get(1);
5174 if (!typeBuilder.nameExists(name)) {
5182 final SqlValidatorNamespace sqlNs =
5184 final RelDataType inputDataType = sqlNs.getRowType();
5185 for (RelDataTypeField fs : inputDataType.getFieldList()) {
5186 if (!typeBuilder.nameExists(fs.getName())) {
5187 typeBuilder.add(fs);
5193 SqlNode pattern = matchRecognize.getPattern();
5195 pattern.accept(visitor);
5197 SqlLiteral interval = matchRecognize.getInterval();
5198 if (interval != null) {
5199 interval.validate(
this, scope);
5200 if (((SqlIntervalLiteral) interval).signum() < 0) {
5202 RESOURCE.intervalMustBeNonNegative(interval.toValue()));
5204 if (orderBy == null || orderBy.size() == 0) {
5206 RESOURCE.cannotUseWithinWithoutOrderBy());
5209 SqlNode firstOrderByColumn = orderBy.getList().
get(0);
5210 SqlIdentifier identifier;
5211 if (firstOrderByColumn instanceof SqlBasicCall) {
5212 identifier = (SqlIdentifier) ((SqlBasicCall) firstOrderByColumn).getOperands()[0];
5214 identifier = (SqlIdentifier) firstOrderByColumn;
5216 RelDataType firstOrderByColumnType =
deriveType(scope, identifier);
5217 if (firstOrderByColumnType.getSqlTypeName() != SqlTypeName.TIMESTAMP) {
5219 RESOURCE.firstColumnOfOrderByMustBeTimestamp());
5229 SqlNodeList subsets = matchRecognize.getSubsetList();
5230 if (subsets != null && subsets.size() > 0) {
5231 for (SqlNode node : subsets) {
5232 List<SqlNode> operands = ((SqlCall) node).getOperandList();
5233 String leftString = ((SqlIdentifier) operands.get(0)).getSimple();
5234 if (scope.getPatternVars().contains(leftString)) {
5236 RESOURCE.patternVarAlreadyDefined(leftString));
5238 scope.addPatternVar(leftString);
5239 for (SqlNode right : (SqlNodeList) operands.get(1)) {
5240 SqlIdentifier
id = (SqlIdentifier) right;
5241 if (!scope.getPatternVars().contains(id.getSimple())) {
5243 RESOURCE.unknownPattern(
id.getSimple()));
5245 scope.addPatternVar(id.getSimple());
5251 final SqlNode skipTo = matchRecognize.getAfter();
5252 if (skipTo instanceof SqlCall) {
5253 final SqlCall skipToCall = (SqlCall) skipTo;
5254 final SqlIdentifier
id = skipToCall.operand(0);
5255 if (!scope.getPatternVars().contains(id.getSimple())) {
5257 RESOURCE.unknownPattern(
id.getSimple()));
5261 List<Map.Entry<String, RelDataType>> measureColumns =
5263 for (Map.Entry<String, RelDataType> c : measureColumns) {
5264 if (!typeBuilder.nameExists(c.getKey())) {
5265 typeBuilder.add(c.getKey(), c.getValue());
5269 final RelDataType rowType = typeBuilder.build();
5270 if (matchRecognize.getMeasureList().size() == 0) {
5271 ns.setType(
getNamespace(matchRecognize.getTableRef()).getRowType());
5273 ns.setType(rowType);
5278 MatchRecognizeScope scope,
boolean allRows) {
5279 final List<String> aliases =
new ArrayList<>();
5280 final List<SqlNode> sqlNodes =
new ArrayList<>();
5281 final SqlNodeList measures = mr.getMeasureList();
5282 final List<Map.Entry<String, RelDataType>> fields =
new ArrayList<>();
5284 for (SqlNode
measure : measures) {
5285 assert
measure instanceof SqlCall;
5299 SqlStdOperatorTable.AS.createCall(SqlParserPos.ZERO,
expand,
5300 new SqlIdentifier(alias, SqlParserPos.ZERO)));
5303 SqlNodeList list =
new SqlNodeList(sqlNodes, measures.getParserPosition());
5306 for (SqlNode node : list) {
5310 mr.setOperand(SqlMatchRecognize.OPERAND_MEASURES, list);
5317 Util.discard(prefix);
5318 final List<SqlNode> ops = ((SqlCall) node).getOperandList();
5321 allRows ? SqlStdOperatorTable.RUNNING : SqlStdOperatorTable.FINAL;
5322 final SqlNode op0 = ops.get(0);
5324 || !allRows && op0.getKind() == SqlKind.RUNNING) {
5325 SqlNode newNode = defaultOp.createCall(SqlParserPos.ZERO, op0);
5326 node = SqlStdOperatorTable.AS.createCall(SqlParserPos.ZERO, newNode, ops.get(1));
5334 MatchRecognizeScope scope) {
5335 final Set<String> aliases = catalogReader.nameMatcher().createSet();
5336 for (SqlNode item : mr.getPatternDefList().getList()) {
5338 if (!aliases.add(alias)) {
5340 Static.RESOURCE.patternVarAlreadyDefined(alias));
5342 scope.addPatternVar(
alias);
5345 final List<SqlNode> sqlNodes =
new ArrayList<>();
5346 for (SqlNode item : mr.getPatternDefList().getList()) {
5353 expand.validate(
this, scope);
5358 SqlStdOperatorTable.AS.createCall(SqlParserPos.ZERO,
expand,
5359 new SqlIdentifier(alias, SqlParserPos.ZERO)));
5362 if (!SqlTypeUtil.inBooleanFamily(type)) {
5369 new SqlNodeList(sqlNodes, mr.getPatternDefList().getParserPosition());
5371 for (SqlNode node : list) {
5374 mr.setOperand(SqlMatchRecognize.OPERAND_PATTERN_DEFINES, list);
5378 private static String
alias(SqlNode item) {
5379 assert item instanceof SqlCall;
5380 assert item.getKind() == SqlKind.AS;
5381 final SqlIdentifier identifier = ((SqlCall) item).operand(1);
5382 return identifier.getSimple();
5390 Util.discard(prefix);
5397 SqlNodeList orderList, SqlValidatorScope scope) {
5421 for (SqlNode param : aggCall.getOperandList()) {
5422 if (a.findAgg(param) != null) {
5426 if (filter != null) {
5427 if (a.findAgg(filter) != null) {
5431 if (orderList != null) {
5432 for (SqlNode param : orderList) {
5433 if (a.findAgg(param) != null) {
5435 RESOURCE.aggregateInWithinGroupIllegal());
5440 final SqlAggFunction op = (SqlAggFunction) aggCall.getOperator();
5441 switch (op.requiresGroupOrder()) {
5443 if (orderList == null || orderList.size() == 0) {
5445 RESOURCE.aggregateMissingWithinGroupClause(op.getName()));
5452 if (orderList != null) {
5453 orderList.getList().clear();
5457 if (orderList != null && orderList.size() != 0) {
5459 RESOURCE.withinGroupClauseIllegalInAggregate(op.getName()));
5463 throw new AssertionError(op);
5469 SqlValidatorScope scope) {
5471 if ((call.operandCount() == 0)
5472 && (
operator.getSyntax() == SqlSyntax.FUNCTION_ID)
5473 && !call.isExpanded()
5474 && !this.config.sqlConformance().allowNiladicParentheses()) {
5479 ImmutableList.of(), null);
5482 SqlValidatorScope operandScope = scope.getOperandScope(call);
5484 if (
operator instanceof SqlFunction
5485 && ((SqlFunction)
operator).getFunctionType()
5486 == SqlFunctionCategory.MATCH_RECOGNIZE
5487 && !(operandScope instanceof MatchRecognizeScope)) {
5489 Static.RESOURCE.functionMatchRecognizeOnly(call.toString()));
5492 operator.validateCall(call,
this, scope, operandScope);
5505 SqlParserPos context) {
5508 assert feature.getProperties().
get(
"FeatureDefinition") != null;
5512 SelectScope scope, SqlSelect select) {
5514 final SqlNode newExpr = expr.accept(expander);
5515 if (expr != newExpr) {
5521 public SqlNode
expand(SqlNode expr, SqlValidatorScope scope) {
5523 SqlNode newExpr = expr.accept(expander);
5524 if (expr != newExpr) {
5531 SqlValidatorScope scope, SqlSelect select,
boolean havingExpression) {
5534 SqlNode newExpr = expr.accept(expander);
5535 if (expr != newExpr) {
5546 if (sqlQuery instanceof SqlExplain) {
5547 return Collections.emptyList();
5550 final int fieldCount = rowType.getFieldCount();
5551 if (!sqlQuery.isA(SqlKind.QUERY)) {
5552 return Collections.nCopies(fieldCount, null);
5554 final List<List<String>> list =
new ArrayList<>();
5555 for (
int i = 0; i < fieldCount; i++) {
5558 return ImmutableNullableList.copyOf(list);
5562 if (sqlQuery instanceof SqlSelect) {
5563 SqlSelect sqlSelect = (SqlSelect) sqlQuery;
5565 final List<SqlNode> selectList = scope.getExpandedSelectList();
5566 final SqlNode selectItem = stripAs(selectList.get(i));
5567 if (selectItem instanceof SqlIdentifier) {
5568 final SqlQualified qualified =
5569 scope.fullyQualify((SqlIdentifier) selectItem);
5570 SqlValidatorNamespace
namespace = qualified.namespace;
5571 final SqlValidatorTable table = namespace.getTable();
5572 if (table == null) {
5575 final List<String> origin =
5576 new ArrayList<>(table.getQualifiedName());
5577 for (String
name : qualified.suffix()) {
5578 namespace = namespace.lookupChild(name);
5579 if (
namespace == null) {
5587 }
else if (sqlQuery instanceof SqlOrderBy) {
5597 final List<RelDataType> types =
new ArrayList<>();
5600 final Set<SqlNode> alreadyVisited =
new HashSet<>();
5604 @Override
public SqlNode visit(SqlDynamicParam param) {
5605 if (alreadyVisited.add(param)) {
5612 return typeFactory.createStructType(
5614 new AbstractList<String>() {
5615 @Override
public String
get(
int index) {
5619 @Override
public int size() {
5620 return types.size();
5626 SqlFunction
function,
5627 List<RelDataType> argTypes,
5628 List<SqlNode> operands) {
5629 throw new UnsupportedOperationException();
5633 return kind == SqlKind.PREV || kind == SqlKind.NEXT;
5637 return kind == SqlKind.FIRST || kind == SqlKind.LAST;
5641 return kind == SqlKind.SUM || kind == SqlKind.SUM0
5642 || kind == SqlKind.AVG || kind == SqlKind.COUNT
5647 return kind == SqlKind.RUNNING || kind == SqlKind.FINAL;
5663 SqlNode enclosingNode, SqlValidatorScope parentScope) {
5664 super(validator,
id, enclosingNode, parentScope);
5675 SqlNode enclosingNode, SqlValidatorScope parentScope) {
5676 super(validator, node.getTargetTable(), enclosingNode, parentScope);
5677 this.node = Objects.requireNonNull(
node);
5692 SqlNode enclosingNode, SqlValidatorScope parentScope) {
5693 super(validator, node.getTargetTable(), enclosingNode, parentScope);
5694 this.node = Objects.requireNonNull(
node);
5709 SqlNode enclosingNode, SqlValidatorScope parentScope) {
5710 super(validator, node.getTargetTable(), enclosingNode, parentScope);
5711 this.node = Objects.requireNonNull(
node);
5726 SqlNode enclosingNode, SqlValidatorScope parentScope) {
5727 super(validator, node.getTargetTable(), enclosingNode, parentScope);
5728 this.node = Objects.requireNonNull(
node);
5748 for (
int i = 0; i < call.getOperandList().size(); i++) {
5749 call.getOperandList().
get(i).accept(
this);
5755 throw Util.needToImplement(nodeList);
5759 Preconditions.checkArgument(id.isSimple());
5760 scope.addPatternVar(id.getSimple());
5765 throw Util.needToImplement(
type);
5769 throw Util.needToImplement(param);
5772 @Override
public Void visit(SqlIntervalQualifier intervalQualifier) {
5773 throw Util.needToImplement(intervalQualifier);
5790 public RelDataType
visit(SqlLiteral literal) {
5794 public RelDataType
visit(SqlCall call) {
5799 public RelDataType
visit(SqlNodeList nodeList) {
5804 throw Util.needToImplement(nodeList);
5807 public RelDataType
visit(SqlIdentifier
id) {
5812 return call.getOperator().validateOperands(
5818 RelDataType
type = null;
5819 if (!(
scope instanceof EmptyScope)) {
5820 id = scope.fullyQualify(id).identifier;
5825 for (i =
id.names.size() - 1; i > 0; i--) {
5834 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
5835 final SqlValidatorScope.ResolvedImpl resolved =
5836 new SqlValidatorScope.ResolvedImpl();
5837 scope.resolve(id.names.subList(0, i), nameMatcher,
false, resolved);
5838 if (resolved.count() == 1) {
5840 final SqlValidatorScope.Resolve resolve = resolved.only();
5841 type = resolve.rowType();
5842 for (SqlValidatorScope.Step p : Util.skip(resolve.path.steps())) {
5843 type = type.getFieldList().
get(p.i).getType();
5851 if (type == null ||
id.names.size() == 1) {
5854 RelDataType colType = scope.resolveColumn(id.names.get(0),
id);
5855 if (colType != null) {
5862 final SqlIdentifier last = id.getComponent(i - 1, i);
5864 RESOURCE.unknownIdentifier(last.toString()));
5868 for (; i < id.names.size(); i++) {
5869 String
name = id.names.get(i);
5870 final RelDataTypeField
field;
5871 if (name.equals(
"")) {
5877 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
5878 field = nameMatcher.field(
type,
name);
5880 if (field == null) {
5882 RESOURCE.unknownField(name));
5884 type = field.getType();
5887 SqlTypeUtil.addCharsetAndCollation(
5893 public RelDataType
visit(SqlDataTypeSpec dataType) {
5901 public RelDataType
visit(SqlDynamicParam param) {
5905 public RelDataType
visit(SqlIntervalQualifier intervalQualifier) {
5906 return typeFactory.createSqlIntervalType(intervalQualifier);
5914 private static class Expander extends SqlScopedShuttle {
5922 @Override
public SqlNode
visit(SqlIdentifier
id) {
5925 final SqlCall call = validator.makeNullaryCall(id);
5927 return call.accept(
this);
5929 final SqlIdentifier fqId = getScope().fullyQualify(id).identifier;
5931 validator.setOriginal(expandedExpr, id);
5932 return expandedExpr;
5936 switch (call.getKind()) {
5956 boolean bCreate = call.getOperator().requiresCreate(call.getOperandList());
5957 ArgHandler<SqlNode> argHandler =
5958 new CallCopyingArgHandler(call, bCreate);
5961 call.getOperator().acceptCall(
this, call,
true, argHandler);
5962 final SqlNode
result = argHandler.result();
5963 validator.setOriginal(
result, call);
5968 if (DynamicRecordType.isDynamicStarColName(Util.last(fqId.names))
5969 && !DynamicRecordType.isDynamicStarColName(Util.last(
id.names))) {
5972 SqlNode[] inputs =
new SqlNode[2];
5974 inputs[1] = SqlLiteral.createCharString(
5975 Util.last(id.names),
5976 id.getParserPosition());
5977 return new SqlBasicCall(
5978 SqlStdOperatorTable.ITEM,
5980 id.getParserPosition());
5999 this.aliasList =
getNamespace(select).getRowType().getFieldNames();
6003 return root.accept(
this);
6006 public SqlNode
visit(SqlLiteral literal) {
6010 if (literal ==
root &&
config.sqlConformance().isSortByOrdinal()) {
6011 switch (literal.getTypeName()) {
6014 final int intValue = literal.intValue(
false);
6015 if (intValue >= 0) {
6016 if (intValue < 1 || intValue >
aliasList.size()) {
6018 literal, RESOURCE.orderByOrdinalOutOfRange());
6022 int ordinal = intValue - 1;
6029 return super.visit(literal);
6040 SqlNodeList expandedSelectList =
6045 SqlNode expr = expandedSelectList.get(ordinal);
6046 expr = stripAs(expr);
6047 if (expr instanceof SqlIdentifier) {
6048 expr = getScope().fullyQualify((SqlIdentifier) expr).identifier;
6053 return expr.clone(pos);
6056 public SqlNode
visit(SqlIdentifier
id) {
6059 &&
config.sqlConformance().isSortByAlias()) {
6060 String
alias = id.getSimple();
6062 final RelDataType rowType =
6063 selectNs.getRowTypeSansSystemColumns();
6064 final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
6065 RelDataTypeField
field = nameMatcher.field(rowType,
alias);
6066 if (field != null) {
6069 id.getParserPosition());
6074 return getScope().fullyQualify(id).identifier;
6080 if (call instanceof SqlSelect) {
6083 return super.visitScoped(call);
6097 super(validator, scope);
6101 @Override
public SqlNode
visit(SqlIdentifier
id) {
6106 return super.visit(id);
6123 super(validator, scope);
6129 @Override
public SqlNode
visit(SqlIdentifier
id) {
6133 : validator.config().sqlConformance().isGroupByAlias())) {
6134 String
name = id.getSimple();
6135 SqlNode expr = null;
6136 final SqlNameMatcher nameMatcher =
6137 validator.catalogReader.nameMatcher();
6139 for (SqlNode s :
select.getSelectList()) {
6140 final String
alias = SqlValidatorUtil.getAlias(s, -1);
6141 if (alias != null && nameMatcher.matches(alias, name)) {
6147 return super.visit(id);
6150 throw validator.newValidationError(id,
6151 RESOURCE.columnAmbiguous(
name));
6154 return super.visit(id);
6156 expr = stripAs(expr);
6157 if (expr instanceof SqlIdentifier) {
6158 SqlIdentifier sid = (SqlIdentifier) expr;
6159 final SqlIdentifier fqId = getScope().fullyQualify(sid).identifier;
6172 expr = expr.accept(
this);
6179 if (
id.isSimple()) {
6180 final SelectScope scope = validator.getRawSelectScope(
select);
6186 return super.visit(id);
6189 public SqlNode
visit(SqlLiteral literal) {
6191 return super.visit(literal);
6193 boolean isOrdinalLiteral = literal ==
root;
6194 switch (
root.getKind()) {
6198 if (
root instanceof SqlBasicCall) {
6199 List<SqlNode> operandList = ((SqlBasicCall)
root).getOperandList();
6200 for (SqlNode node : operandList) {
6201 if (node.equals(literal)) {
6202 isOrdinalLiteral =
true;
6209 if (isOrdinalLiteral) {
6210 switch (literal.getTypeName()) {
6213 final int intValue = literal.intValue(
false);
6214 if (intValue >= 0) {
6215 if (intValue < 1 || intValue >
select.getSelectList().size()) {
6216 throw validator.newValidationError(literal,
6217 RESOURCE.orderByOrdinalOutOfRange());
6221 int ordinal = intValue - 1;
6230 SqlNode node = SqlUtil.stripAs(select.getSelectList().
get(ordinal));
6234 node = node.accept(
this);
6244 return super.visit(literal);
6251 public final SqlIdentifier
id;
6288 public SqlNode
go(SqlNode node) {
6289 return node.accept(
this);
6318 @Override
public SqlNode
visit(SqlCall call) {
6319 SqlKind kind = call.getKind();
6320 List<SqlNode> operands = call.getOperandList();
6321 List<SqlNode> newOperands =
new ArrayList<>();
6323 if (call.getFunctionQuantifier() != null
6324 && call.getFunctionQuantifier().getValue() == SqlSelectKeyword.DISTINCT) {
6325 final SqlParserPos pos = call.getParserPosition();
6326 throw SqlUtil.newContextException(pos,
6327 Static.RESOURCE.functionQuantifierNotAllowed(call.toString()));
6331 SqlNode inner = operands.get(0);
6332 SqlNode
offset = operands.get(1);
6336 SqlKind innerKind = inner.getKind();
6338 List<SqlNode> innerOperands = ((SqlCall) inner).getOperandList();
6339 SqlNode innerOffset = innerOperands.get(1);
6341 ? SqlStdOperatorTable.PLUS : SqlStdOperatorTable.MINUS;
6342 offset = newOperator.createCall(SqlParserPos.ZERO,
6344 inner = call.getOperator().createCall(SqlParserPos.ZERO,
6345 innerOperands.get(0),
offset);
6348 SqlNode newInnerNode =
6351 newInnerNode = op.createCall(SqlParserPos.ZERO, newInnerNode,
6354 return newInnerNode;
6357 if (operands.size() > 0) {
6358 for (SqlNode node : operands) {
6362 newNode = op.createCall(SqlParserPos.ZERO, newNode,
offset);
6364 newOperands.add(newNode);
6366 newOperands.add(null);
6369 return call.getOperator().createCall(SqlParserPos.ZERO, newOperands);
6374 return op.createCall(SqlParserPos.ZERO, call,
offset);
6379 @Override
public SqlNode
visit(SqlIdentifier
id) {
6383 return op.createCall(SqlParserPos.ZERO, id,
offset);
6407 @Override
public SqlNode
visit(SqlCall call) {
6408 SqlKind kind = call.getKind();
6417 final List<SqlNode> operands = call.getOperandList();
6418 if (operands.get(0) instanceof SqlIdentifier) {
6419 String
name = ((SqlIdentifier) operands.get(0)).names.get(0);
6420 return name.equals(
alpha) ? call
6421 : SqlStdOperatorTable.LAST.createCall(SqlParserPos.ZERO, operands);
6424 return super.visit(call);
6427 @Override
public SqlNode
visit(SqlIdentifier
id) {
6428 if (
id.isSimple()) {
6432 ? SqlStdOperatorTable.PREV : SqlStdOperatorTable.LAST;
6434 return operator.createCall(SqlParserPos.ZERO, id,
6435 SqlLiteral.createExactNumeric(
"0", SqlParserPos.ZERO));
6456 this.aggregateCount =