use of org.apache.calcite.sql.SqlNodeList in project flink by apache.
the class SqlValidatorImpl method validateGroupClause.
/**
* Validates the GROUP BY clause of a SELECT statement. This method is called even if no GROUP
* BY clause is present.
*/
protected void validateGroupClause(SqlSelect select) {
SqlNodeList groupList = select.getGroup();
if (groupList == null) {
return;
}
final String clause = "GROUP BY";
validateNoAggs(aggOrOverFinder, groupList, clause);
final SqlValidatorScope groupScope = getGroupScope(select);
// expand the expression in group list.
List<SqlNode> expandedList = new ArrayList<>();
for (SqlNode groupItem : groupList) {
SqlNode expandedItem = expandGroupByOrHavingExpr(groupItem, groupScope, select, false);
expandedList.add(expandedItem);
}
groupList = new SqlNodeList(expandedList, groupList.getParserPosition());
select.setGroupBy(groupList);
inferUnknownTypes(unknownType, groupScope, groupList);
for (SqlNode groupItem : expandedList) {
validateGroupByItem(select, groupItem);
}
// expressions, because they do not have a type.
for (SqlNode node : groupList) {
switch(node.getKind()) {
case GROUPING_SETS:
case ROLLUP:
case CUBE:
node.validate(this, groupScope);
break;
default:
node.validateExpr(this, groupScope);
}
}
// Derive the type of each GROUP BY item. We don't need the type, but
// it resolves functions, and that is necessary for deducing
// monotonicity.
final SqlValidatorScope selectScope = getSelectScope(select);
AggregatingSelectScope aggregatingScope = null;
if (selectScope instanceof AggregatingSelectScope) {
aggregatingScope = (AggregatingSelectScope) selectScope;
}
for (SqlNode groupItem : groupList) {
if (groupItem instanceof SqlNodeList && ((SqlNodeList) groupItem).size() == 0) {
continue;
}
validateGroupItem(groupScope, aggregatingScope, groupItem);
}
SqlNode agg = aggFinder.findAgg(groupList);
if (agg != null) {
throw newValidationError(agg, RESOURCE.aggregateIllegalInClause(clause));
}
}
use of org.apache.calcite.sql.SqlNodeList in project flink by apache.
the class SqlValidatorImpl method validateMeasure.
private List<Map.Entry<String, RelDataType>> validateMeasure(SqlMatchRecognize mr, MatchRecognizeScope scope, boolean allRows) {
final List<String> aliases = new ArrayList<>();
final List<SqlNode> sqlNodes = new ArrayList<>();
final SqlNodeList measures = mr.getMeasureList();
final List<Map.Entry<String, RelDataType>> fields = new ArrayList<>();
for (SqlNode measure : measures) {
assert measure instanceof SqlCall;
final String alias = deriveAlias(measure, aliases.size());
aliases.add(alias);
SqlNode expand = expand(measure, scope);
expand = navigationInMeasure(expand, allRows);
setOriginal(expand, measure);
inferUnknownTypes(unknownType, scope, expand);
final RelDataType type = deriveType(scope, expand);
setValidatedNodeType(measure, type);
fields.add(Pair.of(alias, type));
sqlNodes.add(SqlStdOperatorTable.AS.createCall(SqlParserPos.ZERO, expand, new SqlIdentifier(alias, SqlParserPos.ZERO)));
}
SqlNodeList list = new SqlNodeList(sqlNodes, measures.getParserPosition());
inferUnknownTypes(unknownType, scope, list);
for (SqlNode node : list) {
validateExpr(node, scope);
}
mr.setOperand(SqlMatchRecognize.OPERAND_MEASURES, list);
return fields;
}
use of org.apache.calcite.sql.SqlNodeList in project flink by apache.
the class SqlValidatorImpl method validateSelect.
/**
* Validates a SELECT statement.
*
* @param select Select statement
* @param targetRowType Desired row type, must not be null, may be the data type 'unknown'.
*/
protected void validateSelect(SqlSelect select, RelDataType targetRowType) {
assert targetRowType != null;
// Namespace is either a select namespace or a wrapper around one.
final SelectNamespace ns = getNamespace(select).unwrap(SelectNamespace.class);
// account.
assert ns.rowType == null;
if (select.isDistinct()) {
validateFeature(RESOURCE.sQLFeature_E051_01(), select.getModifierNode(SqlSelectKeyword.DISTINCT).getParserPosition());
}
final SqlNodeList selectItems = select.getSelectList();
RelDataType fromType = unknownType;
if (selectItems.size() == 1) {
final SqlNode selectItem = selectItems.get(0);
if (selectItem instanceof SqlIdentifier) {
SqlIdentifier id = (SqlIdentifier) selectItem;
if (id.isStar() && (id.names.size() == 1)) {
// Special case: for INSERT ... VALUES(?,?), the SQL
// standard says we're supposed to propagate the target
// types down. So iff the select list is an unqualified
// star (as it will be after an INSERT ... VALUES has been
// expanded), then propagate.
fromType = targetRowType;
}
}
}
// Make sure that items in FROM clause have distinct aliases.
final SelectScope fromScope = (SelectScope) getFromScope(select);
List<String> names = fromScope.getChildNames();
if (!catalogReader.nameMatcher().isCaseSensitive()) {
names = names.stream().map(s -> s.toUpperCase(Locale.ROOT)).collect(Collectors.toList());
}
final int duplicateAliasOrdinal = Util.firstDuplicate(names);
if (duplicateAliasOrdinal >= 0) {
final ScopeChild child = fromScope.children.get(duplicateAliasOrdinal);
throw newValidationError(child.namespace.getEnclosingNode(), RESOURCE.fromAliasDuplicate(child.name));
}
if (select.getFrom() == null) {
if (this.config.sqlConformance().isFromRequired()) {
throw newValidationError(select, RESOURCE.selectMissingFrom());
}
} else {
validateFrom(select.getFrom(), fromType, fromScope);
}
validateWhereClause(select);
validateGroupClause(select);
validateHavingClause(select);
validateWindowClause(select);
handleOffsetFetch(select.getOffset(), select.getFetch());
// Validate the SELECT clause late, because a select item might
// depend on the GROUP BY list, or the window function might reference
// window name in the WINDOW clause etc.
final RelDataType rowType = validateSelectList(selectItems, select, targetRowType);
ns.setType(rowType);
// Validate ORDER BY after we have set ns.rowType because in some
// dialects you can refer to columns of the select list, e.g.
// "SELECT empno AS x FROM emp ORDER BY x"
validateOrderList(select);
if (shouldCheckForRollUp(select.getFrom())) {
checkRollUpInSelectList(select);
checkRollUp(null, select, select.getWhere(), getWhereScope(select));
checkRollUp(null, select, select.getHaving(), getHavingScope(select));
checkRollUpInWindowDecl(select);
checkRollUpInGroupBy(select);
checkRollUpInOrderBy(select);
}
}
use of org.apache.calcite.sql.SqlNodeList in project flink by apache.
the class SqlValidatorImpl method validateWindowClause.
protected void validateWindowClause(SqlSelect select) {
final SqlNodeList windowList = select.getWindowList();
@SuppressWarnings("unchecked") final List<SqlWindow> windows = (List) windowList.getList();
if (windows.isEmpty()) {
return;
}
final SelectScope windowScope = (SelectScope) getFromScope(select);
assert windowScope != null;
// 2. ensure they are unique within this scope
for (SqlWindow window : windows) {
SqlIdentifier declName = window.getDeclName();
if (!declName.isSimple()) {
throw newValidationError(declName, RESOURCE.windowNameMustBeSimple());
}
if (windowScope.existingWindowName(declName.toString())) {
throw newValidationError(declName, RESOURCE.duplicateWindowName());
} else {
windowScope.addWindowName(declName.toString());
}
}
// Check for pairs of windows which are equivalent.
for (int i = 0; i < windows.size(); i++) {
SqlNode window1 = windows.get(i);
for (int j = i + 1; j < windows.size(); j++) {
SqlNode window2 = windows.get(j);
if (window1.equalsDeep(window2, Litmus.IGNORE)) {
throw newValidationError(window2, RESOURCE.dupWindowSpec());
}
}
}
for (SqlWindow window : windows) {
final SqlNodeList expandedOrderList = (SqlNodeList) expand(window.getOrderList(), windowScope);
window.setOrderList(expandedOrderList);
expandedOrderList.validate(this, windowScope);
final SqlNodeList expandedPartitionList = (SqlNodeList) expand(window.getPartitionList(), windowScope);
window.setPartitionList(expandedPartitionList);
expandedPartitionList.validate(this, windowScope);
}
// Hand off to validate window spec components
windowList.validate(this, windowScope);
}
use of org.apache.calcite.sql.SqlNodeList in project flink by apache.
the class SqlValidatorImpl method checkTypeAssignment.
/**
* Checks the type assignment of an INSERT or UPDATE query.
*
* <p>Skip the virtual columns(can not insert into) type assignment check if the source fields
* count equals with the real target table fields count, see how #checkFieldCount was used.
*
* @param sourceScope Scope of query source which is used to infer node type
* @param table Target table
* @param sourceRowType Source row type
* @param targetRowType Target row type, it should either contain all the virtual columns (can
* not insert into) or exclude all the virtual columns
* @param query The query
*/
protected void checkTypeAssignment(SqlValidatorScope sourceScope, SqlValidatorTable table, RelDataType sourceRowType, RelDataType targetRowType, final SqlNode query) {
// NOTE jvs 23-Feb-2006: subclasses may allow for extra targets
// representing system-maintained columns, so stop after all sources
// matched
boolean isUpdateModifiableViewTable = false;
if (query instanceof SqlUpdate) {
final SqlNodeList targetColumnList = ((SqlUpdate) query).getTargetColumnList();
if (targetColumnList != null) {
final int targetColumnCnt = targetColumnList.size();
targetRowType = SqlTypeUtil.extractLastNFields(typeFactory, targetRowType, targetColumnCnt);
sourceRowType = SqlTypeUtil.extractLastNFields(typeFactory, sourceRowType, targetColumnCnt);
}
isUpdateModifiableViewTable = table.unwrap(ModifiableViewTable.class) != null;
}
if (SqlTypeUtil.equalAsStructSansNullability(typeFactory, sourceRowType, targetRowType, null)) {
// Returns early if source and target row type equals sans nullability.
return;
}
if (config.typeCoercionEnabled() && !isUpdateModifiableViewTable) {
// Try type coercion first if implicit type coercion is allowed.
boolean coerced = typeCoercion.querySourceCoercion(sourceScope, sourceRowType, targetRowType, query);
if (coerced) {
return;
}
}
// Fall back to default behavior: compare the type families.
List<RelDataTypeField> sourceFields = sourceRowType.getFieldList();
List<RelDataTypeField> targetFields = targetRowType.getFieldList();
final int sourceCount = sourceFields.size();
for (int i = 0; i < sourceCount; ++i) {
RelDataType sourceType = sourceFields.get(i).getType();
RelDataType targetType = targetFields.get(i).getType();
if (!SqlTypeUtil.canAssignFrom(targetType, sourceType)) {
SqlNode node = getNthExpr(query, i, sourceCount);
if (node instanceof SqlDynamicParam) {
continue;
}
String targetTypeString;
String sourceTypeString;
if (SqlTypeUtil.areCharacterSetsMismatched(sourceType, targetType)) {
sourceTypeString = sourceType.getFullTypeString();
targetTypeString = targetType.getFullTypeString();
} else {
sourceTypeString = sourceType.toString();
targetTypeString = targetType.toString();
}
throw newValidationError(node, RESOURCE.typeNotAssignable(targetFields.get(i).getName(), targetTypeString, sourceFields.get(i).getName(), sourceTypeString));
}
}
}
Aggregations