Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Namespace builder #3961

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ public SqlCall permutedCall() {
@Override public RelDataType getOperandType(int ordinal) {
final SqlNode operand = call.operand(ordinal);
final RelDataType type = SqlTypeUtil.deriveType(this, operand);
final SqlValidatorNamespace namespace = validator.getNamespace(operand);
final SqlValidatorNamespace namespace = validator.getScopeMap().getNamespace(operand);
if (namespace != null) {
return namespace.getType();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ private PercentileDiscCallBinding(SqlValidator validator,

@Override public RelDataType getCollationType() {
final RelDataType type = SqlTypeUtil.deriveType(this, collationColumn);
final SqlValidatorNamespace namespace = super.getValidator().getNamespace(collationColumn);
final SqlValidatorNamespace namespace = super.getValidator().getScopeMap()
.getNamespace(collationColumn);
return namespace != null ? namespace.getType() : type;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,11 @@ private void registerId(SqlIdentifier id, SqlValidatorScope scope) {

@Override protected void validateOver(SqlCall call, SqlValidatorScope scope) {
try {
final OverScope overScope = (OverScope) getOverScope(call);
final OverScope overScope = (OverScope) getScopeMap().getOverScope(call);
final SqlNode relation = call.operand(0);
validateFrom(relation, unknownType, scope);
final SqlNode window = call.operand(1);
SqlValidatorScope opScope = scopes.get(relation);
SqlValidatorScope opScope = getScopeMap().getScope(relation);
if (opScope == null) {
opScope = overScope;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ protected SqlMultisetQueryConstructor(String name, SqlKind kind,
SqlSelect subSelect = call.operand(0);
subSelect.validateExpr(validator, scope);
final SqlValidatorNamespace ns =
requireNonNull(validator.getNamespace(subSelect),
requireNonNull(validator.getScopeMap().getNamespace(subSelect),
() -> "namespace is missing for " + subSelect);
final RelDataType rowType = requireNonNull(ns.getRowType(), "rowType");
final SqlCallBinding opBinding = new SqlCallBinding(validator, scope, call);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1732,7 +1732,7 @@ private static class LambdaFamilyOperandTypeChecker
&& !argFamilies.stream().allMatch(f -> f == SqlTypeFamily.ANY)) {
// Replace the parameter types in the lambda expression.
final SqlLambdaScope scope =
(SqlLambdaScope) validator.getLambdaScope(lambdaExpr);
(SqlLambdaScope) validator.getScopeMap().getLambdaScope(lambdaExpr);
for (int i = 0; i < argFamilies.size(); i++) {
final SqlNode param = lambdaExpr.getParameters().get(i);
final RelDataType type =
Expand Down Expand Up @@ -1794,7 +1794,7 @@ private static class LambdaRelOperandTypeChecker
// Replace the parameter types in the lambda expression.
final SqlValidator validator = callBinding.getValidator();
final SqlLambdaScope scope =
(SqlLambdaScope) validator.getLambdaScope(lambdaExpr);
(SqlLambdaScope) validator.getScopeMap().getLambdaScope(lambdaExpr);
for (int i = 0; i < argTypes.size(); i++) {
final SqlNode param = lambdaExpr.getParameters().get(i);
final RelDataType type = argTypes.get(i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,8 @@ protected RelDataType toStruct(RelDataType type, @Nullable SqlNode unnest) {
.add(SqlValidatorUtil.alias(requireNonNull(unnest, "unnest"), 0), type)
.build();
}

protected ScopeMap getScopeMap() {
return getValidator().getScopeMap();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ && isMeasureExp(id)) {
if (scope instanceof AggregatingSelectScope) {
final SqlSelect select = (SqlSelect) scope.getNode();
SelectScope selectScope =
requireNonNull(validator.getRawSelectScope(select),
requireNonNull(validator.getScopeMap().getRawSelectScope(select),
() -> "rawSelectScope for " + scope.getNode());
List<SqlNode> selectList =
requireNonNull(selectScope.getExpandedSelectList(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ protected AliasNamespace(
@Override public boolean supportsModality(SqlModality modality) {
final List<SqlNode> operands = call.getOperandList();
final SqlValidatorNamespace childNs =
validator.getNamespaceOrThrow(operands.get(0));
getScopeMap().getNamespaceOrThrow(operands.get(0));
return childNs.supportsModality(modality);
}

@Override protected RelDataType validateImpl(RelDataType targetRowType) {
final List<SqlNode> operands = call.getOperandList();
final SqlValidatorNamespace childNs =
validator.getNamespaceOrThrow(operands.get(0));
getScopeMap().getNamespaceOrThrow(operands.get(0));
final RelDataType rowType = childNs.getRowTypeSansSystemColumns();
final RelDataType aliasedType;
if (operands.size() == 2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ protected void addColumnNames(

@Override public SqlValidatorScope getOperandScope(SqlCall call) {
if (call instanceof SqlSelect) {
return validator.getSelectScope((SqlSelect) call);
return getScopeMap().getSelectScope((SqlSelect) call);
} else if (call instanceof SqlLambda) {
return validator.getLambdaScope((SqlLambda) call);
return getScopeMap().getLambdaScope((SqlLambda) call);
}
return this;
}
Expand Down Expand Up @@ -673,7 +673,7 @@ public SqlValidatorScope getParent() {
return null;
case 1:
final SqlValidatorNamespace selectNs =
validator.getNamespaceOrThrow(select);
getScopeMap().getNamespaceOrThrow(select);
return SqlQualified.create(this, 1, selectNs, identifier);
default:
// More than one column has this alias.
Expand All @@ -682,6 +682,10 @@ public SqlValidatorScope getParent() {
}
}

protected ScopeMap getScopeMap() {
return validator.getScopeMap();
}

/** Returns the number of columns in the SELECT clause that have {@code name}
* as their implicit (e.g. {@code t.name}) or explicit (e.g.
* {@code t.c as name}) alias. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ class JoinNamespace extends AbstractNamespace {

@Override protected RelDataType validateImpl(RelDataType targetRowType) {
RelDataType leftType =
validator.getNamespaceOrThrow(join.getLeft()).getRowType();
getScopeMap().getNamespaceOrThrow(join.getLeft()).getRowType();
RelDataType rightType =
validator.getNamespaceOrThrow(join.getRight()).getRowType();
getScopeMap().getNamespaceOrThrow(join.getRight()).getRowType();
final RelDataTypeFactory typeFactory = validator.getTypeFactory();
switch (join.getJoinType()) {
case LEFT:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.calcite.sql.validate;

import org.apache.calcite.sql.SqlCall;
import org.apache.calcite.sql.SqlDelete;
import org.apache.calcite.sql.SqlInsert;
import org.apache.calcite.sql.SqlMatchRecognize;
import org.apache.calcite.sql.SqlMerge;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlPivot;
import org.apache.calcite.sql.SqlSelect;
import org.apache.calcite.sql.SqlUnpivot;
import org.apache.calcite.sql.SqlUpdate;

import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import org.checkerframework.checker.nullness.qual.Nullable;

import static java.util.Objects.requireNonNull;

/**
* A builder to allow for customization of namespaces down stream.
*/
public class NamespaceBuilder {

private final SqlValidatorImpl sqlValidatorImpl;

public NamespaceBuilder(@UnknownInitialization SqlValidatorImpl sqlValidatorImpl) {
@SuppressWarnings("argument.type.incompatible")
SqlValidatorImpl sqlValidatorCast = sqlValidatorImpl;
this.sqlValidatorImpl = sqlValidatorCast;

Check failure on line 45 in core/src/main/java/org/apache/calcite/sql/validate/NamespaceBuilder.java

View workflow job for this annotation

GitHub Actions / CheckerFramework (JDK 11)

[Task :core:compileJava] [assignment.type.incompatible] incompatible types in assignment. this.sqlValidatorImpl = sqlValidatorCast; ^ found : @UnknownInitialization @nonnull SqlValidatorImpl

Check failure on line 45 in core/src/main/java/org/apache/calcite/sql/validate/NamespaceBuilder.java

View workflow job for this annotation

GitHub Actions / CheckerFramework (JDK 11), oldest Guava

[Task :core:compileJava] [assignment.type.incompatible] incompatible types in assignment. this.sqlValidatorImpl = sqlValidatorCast; ^ found : @UnknownInitialization @nonnull SqlValidatorImpl
}

/**
* Creates a namespace for a <code>SELECT</code> node. Derived class may
* override this factory method.
*
* @param select Select node
* @param enclosingNode Enclosing node
* @return Select namespace
*/
public SelectNamespace createSelectNamespace(
SqlSelect select,
SqlNode enclosingNode) {
return new SelectNamespace(sqlValidatorImpl, select, enclosingNode);
}

/**
* Creates a namespace for a set operation (<code>UNION</code>, <code>
* INTERSECT</code>, or <code>EXCEPT</code>). Derived class may override
* this factory method.
*
* @param call Call to set operation
* @param enclosingNode Enclosing node
* @return Set operation namespace
*/
public SetopNamespace createSetopNamespace(
SqlCall call,
SqlNode enclosingNode) {
return new SetopNamespace(sqlValidatorImpl, call, enclosingNode);
}


public MatchRecognizeNamespace createMatchRecognizeNameSpace(
SqlMatchRecognize call,
SqlNode enclosingNode) {
return new MatchRecognizeNamespace(sqlValidatorImpl, call, enclosingNode);
}

public UnpivotNamespace createUnpivotNameSpace(
SqlUnpivot call,
SqlNode enclosingNode) {
return new UnpivotNamespace(sqlValidatorImpl, call, enclosingNode);
}


public PivotNamespace createPivotNameSpace(
SqlPivot call,
SqlNode enclosingNode) {
return new PivotNamespace(sqlValidatorImpl, call, enclosingNode);
}

public DmlNamespace createDeleteNamespace(SqlDelete delete,
SqlNode enclosingNode, SqlValidatorScope parentScope) {
return new DeleteNamespace(sqlValidatorImpl, delete, enclosingNode, parentScope);
}

public DmlNamespace createInsertNamespace(SqlInsert insert,
SqlNode enclosingNode, SqlValidatorScope parentScope) {
return new InsertNamespace(sqlValidatorImpl, insert, enclosingNode, parentScope);
}

public DmlNamespace createMergeNamespace(SqlMerge merge, SqlNode enclosing,
SqlValidatorScope parentScope) {
return new MergeNamespace(sqlValidatorImpl, merge, enclosing, parentScope);
}

public DmlNamespace createUpdate(SqlUpdate sqlUpdate, SqlNode enclosing,
SqlValidatorScope parentScope) {
return new UpdateNamespace(sqlValidatorImpl, sqlUpdate, enclosing, parentScope);
}

/**
* Interface for creating new {@link NamespaceBuilder}.
*/
public interface Factory {
NamespaceBuilder create(@UnknownInitialization SqlValidatorImpl sqlValidatorImpl);
}


/**
* Common base class for DML statement namespaces.
*/
public abstract static class DmlNamespace extends IdentifierNamespace {
protected DmlNamespace(SqlValidatorImpl validator, SqlNode id,
SqlNode enclosingNode, SqlValidatorScope parentScope) {
super(validator, id, enclosingNode, parentScope);
}
}

/**
* Namespace for an INSERT statement.
*/
private static class InsertNamespace extends DmlNamespace {
private final SqlInsert node;

InsertNamespace(SqlValidatorImpl validator, SqlInsert node,
SqlNode enclosingNode, SqlValidatorScope parentScope) {
super(validator, node.getTargetTable(), enclosingNode, parentScope);
this.node = requireNonNull(node, "node");
}

@Override public @Nullable SqlNode getNode() {
return node;
}
}

/**
* Namespace for an UPDATE statement.
*/
private static class UpdateNamespace extends DmlNamespace {
private final SqlUpdate node;

UpdateNamespace(SqlValidatorImpl validator, SqlUpdate node,
SqlNode enclosingNode, SqlValidatorScope parentScope) {
super(validator, node.getTargetTable(), enclosingNode, parentScope);
this.node = requireNonNull(node, "node");
}

@Override public @Nullable SqlNode getNode() {
return node;
}
}

/**
* Namespace for a DELETE statement.
*/
private static class DeleteNamespace extends DmlNamespace {
private final SqlDelete node;

DeleteNamespace(SqlValidatorImpl validator, SqlDelete node,
SqlNode enclosingNode, SqlValidatorScope parentScope) {
super(validator, node.getTargetTable(), enclosingNode, parentScope);
this.node = requireNonNull(node, "node");
}

@Override public @Nullable SqlNode getNode() {
return node;
}
}

/**
* Namespace for a MERGE statement.
*/
private static class MergeNamespace extends DmlNamespace {
private final SqlMerge node;

MergeNamespace(SqlValidatorImpl validator, SqlMerge node,
SqlNode enclosingNode, SqlValidatorScope parentScope) {
super(validator, node.getTargetTable(), enclosingNode, parentScope);
this.node = requireNonNull(node, "node");
}

@Override public @Nullable SqlNode getNode() {
return node;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public class OrderByScope extends DelegatingScope {
}

@Override public void findAllColumnNames(List<SqlMoniker> result) {
final SqlValidatorNamespace ns = validator.getNamespaceOrThrow(select);
final SqlValidatorNamespace ns = getScopeMap().getNamespaceOrThrow(select);
addColumnNames(ns, result);
}

Expand All @@ -80,14 +80,15 @@ public class OrderByScope extends DelegatingScope {
}

@Override public @Nullable RelDataType resolveColumn(String name, SqlNode ctx) {
final SqlValidatorNamespace selectNs = validator.getNamespaceOrThrow(select);
final SqlValidatorNamespace selectNs =
getScopeMap().getNamespaceOrThrow(select);
final RelDataType rowType = selectNs.getRowType();
final SqlNameMatcher nameMatcher = validator.catalogReader.nameMatcher();
final RelDataTypeField field = nameMatcher.field(rowType, name);
if (field != null) {
return field.getType();
}
final SqlValidatorScope selectScope = validator.getSelectScope(select);
final SqlValidatorScope selectScope = getScopeMap().getSelectScope(select);
return selectScope.resolveColumn(name, ctx);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public PivotScope(SqlValidatorScope parent, SqlPivot pivot) {
* scope only has one namespace, and it is anonymous. */
public SqlValidatorNamespace getChild() {
return requireNonNull(
validator.getNamespace(pivot.query),
getScopeMap().getNamespace(pivot.query),
() -> "namespace for pivot.query " + pivot.query);
}

Expand Down
Loading
Loading