use of org.apache.calcite.sql.SqlIdentifier in project calcite by apache.
the class SqlValidatorImpl method validateWindow.
public void validateWindow(SqlNode windowOrId, SqlValidatorScope scope, SqlCall call) {
// Enable nested aggregates with window aggregates (OVER operator)
inWindow = true;
final SqlWindow targetWindow;
switch(windowOrId.getKind()) {
case IDENTIFIER:
// Just verify the window exists in this query. It will validate
// when the definition is processed
targetWindow = getWindowByName((SqlIdentifier) windowOrId, scope);
break;
case WINDOW:
targetWindow = (SqlWindow) windowOrId;
break;
default:
throw Util.unexpected(windowOrId.getKind());
}
assert targetWindow.getWindowCall() == null;
targetWindow.setWindowCall(call);
targetWindow.validate(this, scope);
targetWindow.setWindowCall(null);
call.validate(this, scope);
validateAggregateParams(call, null, scope);
// Disable nested aggregates post validation
inWindow = false;
}
use of org.apache.calcite.sql.SqlIdentifier in project calcite by apache.
the class SqlValidatorImpl method deriveConstructorType.
public RelDataType deriveConstructorType(SqlValidatorScope scope, SqlCall call, SqlFunction unresolvedConstructor, SqlFunction resolvedConstructor, List<RelDataType> argTypes) {
SqlIdentifier sqlIdentifier = unresolvedConstructor.getSqlIdentifier();
assert sqlIdentifier != null;
RelDataType type = catalogReader.getNamedType(sqlIdentifier);
if (type == null) {
// TODO jvs 12-Feb-2005: proper type name formatting
throw newValidationError(sqlIdentifier, RESOURCE.unknownDatatypeName(sqlIdentifier.toString()));
}
if (resolvedConstructor == null) {
if (call.operandCount() > 0) {
// no user-defined constructor could be found
throw handleUnresolvedFunction(call, unresolvedConstructor, argTypes, null);
}
} else {
SqlCall testCall = resolvedConstructor.createCall(call.getParserPosition(), call.getOperandList());
RelDataType returnType = resolvedConstructor.validateOperands(this, scope, testCall);
assert type == returnType;
}
if (shouldExpandIdentifiers()) {
if (resolvedConstructor != null) {
((SqlBasicCall) call).setOperator(resolvedConstructor);
} else {
// fake a fully-qualified call to the default constructor
((SqlBasicCall) call).setOperator(new SqlFunction(type.getSqlIdentifier(), ReturnTypes.explicit(type), null, null, null, SqlFunctionCategory.USER_DEFINED_CONSTRUCTOR));
}
}
return type;
}
use of org.apache.calcite.sql.SqlIdentifier in project calcite by apache.
the class SqlValidatorImpl method validateDefinitions.
private void validateDefinitions(SqlMatchRecognize mr, MatchRecognizeScope scope) {
final Set<String> aliases = catalogReader.nameMatcher().isCaseSensitive() ? new LinkedHashSet<String>() : new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
for (SqlNode item : mr.getPatternDefList().getList()) {
final String alias = alias(item);
if (!aliases.add(alias)) {
throw newValidationError(item, Static.RESOURCE.patternVarAlreadyDefined(alias));
}
scope.addPatternVar(alias);
}
final List<SqlNode> sqlNodes = new ArrayList<>();
for (SqlNode item : mr.getPatternDefList().getList()) {
final String alias = alias(item);
SqlNode expand = expand(item, scope);
expand = navigationInDefine(expand, alias);
setOriginal(expand, item);
inferUnknownTypes(booleanType, scope, expand);
expand.validate(this, scope);
// Some extra work need required here.
// In PREV, NEXT, FINAL and LAST, only one pattern variable is allowed.
sqlNodes.add(SqlStdOperatorTable.AS.createCall(SqlParserPos.ZERO, expand, new SqlIdentifier(alias, SqlParserPos.ZERO)));
final RelDataType type = deriveType(scope, expand);
if (!SqlTypeUtil.inBooleanFamily(type)) {
throw newValidationError(expand, RESOURCE.condMustBeBoolean("DEFINE"));
}
setValidatedNodeType(item, type);
}
SqlNodeList list = new SqlNodeList(sqlNodes, mr.getPatternDefList().getParserPosition());
inferUnknownTypes(unknownType, scope, list);
for (SqlNode node : list) {
validateExpr(node, scope);
}
mr.setOperand(SqlMatchRecognize.OPERAND_PATTERN_DEFINES, list);
}
use of org.apache.calcite.sql.SqlIdentifier in project calcite by apache.
the class SqlValidatorImpl method validateJoin.
protected void validateJoin(SqlJoin join, SqlValidatorScope scope) {
SqlNode left = join.getLeft();
SqlNode right = join.getRight();
SqlNode condition = join.getCondition();
boolean natural = join.isNatural();
final JoinType joinType = join.getJoinType();
final JoinConditionType conditionType = join.getConditionType();
final SqlValidatorScope joinScope = scopes.get(join);
validateFrom(left, unknownType, joinScope);
validateFrom(right, unknownType, joinScope);
// Validate condition.
switch(conditionType) {
case NONE:
Preconditions.checkArgument(condition == null);
break;
case ON:
Preconditions.checkArgument(condition != null);
SqlNode expandedCondition = expand(condition, joinScope);
join.setOperand(5, expandedCondition);
condition = join.getCondition();
validateWhereOrOn(joinScope, condition, "ON");
checkRollUp(null, join, condition, joinScope, "ON");
break;
case USING:
SqlNodeList list = (SqlNodeList) condition;
// Parser ensures that using clause is not empty.
Preconditions.checkArgument(list.size() > 0, "Empty USING clause");
for (int i = 0; i < list.size(); i++) {
SqlIdentifier id = (SqlIdentifier) list.get(i);
final RelDataType leftColType = validateUsingCol(id, left);
final RelDataType rightColType = validateUsingCol(id, right);
if (!SqlTypeUtil.isComparable(leftColType, rightColType)) {
throw newValidationError(id, RESOURCE.naturalOrUsingColumnNotCompatible(id.getSimple(), leftColType.toString(), rightColType.toString()));
}
checkRollUpInUsing(id, left);
checkRollUpInUsing(id, right);
}
break;
default:
throw Util.unexpected(conditionType);
}
// Validate NATURAL.
if (natural) {
if (condition != null) {
throw newValidationError(condition, RESOURCE.naturalDisallowsOnOrUsing());
}
// Join on fields that occur exactly once on each side. Ignore
// fields that occur more than once on either side.
final RelDataType leftRowType = getNamespace(left).getRowType();
final RelDataType rightRowType = getNamespace(right).getRowType();
List<String> naturalColumnNames = SqlValidatorUtil.deriveNaturalJoinColumnList(leftRowType, rightRowType);
// Check compatibility of the chosen columns.
final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
for (String name : naturalColumnNames) {
final RelDataType leftColType = nameMatcher.field(leftRowType, name).getType();
final RelDataType rightColType = nameMatcher.field(rightRowType, name).getType();
if (!SqlTypeUtil.isComparable(leftColType, rightColType)) {
throw newValidationError(join, RESOURCE.naturalOrUsingColumnNotCompatible(name, leftColType.toString(), rightColType.toString()));
}
}
}
// a NATURAL keyword?
switch(joinType) {
case INNER:
case LEFT:
case RIGHT:
case FULL:
if ((condition == null) && !natural) {
throw newValidationError(join, RESOURCE.joinRequiresCondition());
}
break;
case COMMA:
case CROSS:
if (condition != null) {
throw newValidationError(join.getConditionTypeNode(), RESOURCE.crossJoinDisallowsCondition());
}
if (natural) {
throw newValidationError(join.getConditionTypeNode(), RESOURCE.crossJoinDisallowsCondition());
}
break;
default:
throw Util.unexpected(joinType);
}
}
use of org.apache.calcite.sql.SqlIdentifier in project calcite 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);
}
Aggregations