use of org.apache.calcite.sql.validate.SqlNameMatcher in project flink by apache.
the class FunctionCatalogOperatorTable method lookupOperatorOverloads.
@Override
public void lookupOperatorOverloads(SqlIdentifier opName, SqlFunctionCategory category, SqlSyntax syntax, List<SqlOperator> operatorList, SqlNameMatcher nameMatcher) {
if (opName.isStar()) {
return;
}
final UnresolvedIdentifier identifier = UnresolvedIdentifier.of(opName.names);
functionCatalog.lookupFunction(identifier).flatMap(resolvedFunction -> convertToSqlFunction(category, resolvedFunction)).ifPresent(operatorList::add);
}
use of org.apache.calcite.sql.validate.SqlNameMatcher in project calcite by apache.
the class SqlToRelConverter method getCorrelationUse.
private CorrelationUse getCorrelationUse(Blackboard bb, final RelNode r0) {
final Set<CorrelationId> correlatedVariables = RelOptUtil.getVariablesUsed(r0);
if (correlatedVariables.isEmpty()) {
return null;
}
final ImmutableBitSet.Builder requiredColumns = ImmutableBitSet.builder();
final List<CorrelationId> correlNames = Lists.newArrayList();
// All correlations must refer the same namespace since correlation
// produces exactly one correlation source.
// The same source might be referenced by different variables since
// DeferredLookups are not de-duplicated at create time.
SqlValidatorNamespace prevNs = null;
for (CorrelationId correlName : correlatedVariables) {
DeferredLookup lookup = mapCorrelToDeferred.get(correlName);
RexFieldAccess fieldAccess = lookup.getFieldAccess(correlName);
String originalRelName = lookup.getOriginalRelName();
String originalFieldName = fieldAccess.getField().getName();
final SqlNameMatcher nameMatcher = lookup.bb.scope.getValidator().getCatalogReader().nameMatcher();
final SqlValidatorScope.ResolvedImpl resolved = new SqlValidatorScope.ResolvedImpl();
lookup.bb.scope.resolve(ImmutableList.of(originalRelName), nameMatcher, false, resolved);
assert resolved.count() == 1;
final SqlValidatorScope.Resolve resolve = resolved.only();
final SqlValidatorNamespace foundNs = resolve.namespace;
final RelDataType rowType = resolve.rowType();
final int childNamespaceIndex = resolve.path.steps().get(0).i;
final SqlValidatorScope ancestorScope = resolve.scope;
boolean correlInCurrentScope = ancestorScope == bb.scope;
if (!correlInCurrentScope) {
continue;
}
if (prevNs == null) {
prevNs = foundNs;
} else {
assert prevNs == foundNs : "All correlation variables should resolve" + " to the same namespace." + " Prev ns=" + prevNs + ", new ns=" + foundNs;
}
int namespaceOffset = 0;
if (childNamespaceIndex > 0) {
// of output types from all the preceding namespaces
assert ancestorScope instanceof ListScope;
List<SqlValidatorNamespace> children = ((ListScope) ancestorScope).getChildren();
for (int i = 0; i < childNamespaceIndex; i++) {
SqlValidatorNamespace child = children.get(i);
namespaceOffset += child.getRowType().getFieldCount();
}
}
RexFieldAccess topLevelFieldAccess = fieldAccess;
while (topLevelFieldAccess.getReferenceExpr() instanceof RexFieldAccess) {
topLevelFieldAccess = (RexFieldAccess) topLevelFieldAccess.getReferenceExpr();
}
final RelDataTypeField field = rowType.getFieldList().get(topLevelFieldAccess.getField().getIndex() - namespaceOffset);
int pos = namespaceOffset + field.getIndex();
assert field.getType() == topLevelFieldAccess.getField().getType();
assert pos != -1;
if (bb.mapRootRelToFieldProjection.containsKey(bb.root)) {
// bb.root is an aggregate and only projects group by
// keys.
Map<Integer, Integer> exprProjection = bb.mapRootRelToFieldProjection.get(bb.root);
// the root of the outer relation.
if (exprProjection.containsKey(pos)) {
pos = exprProjection.get(pos);
} else {
// correl not grouped
throw new AssertionError("Identifier '" + originalRelName + "." + originalFieldName + "' is not a group expr");
}
}
requiredColumns.set(pos);
correlNames.add(correlName);
}
if (correlNames.isEmpty()) {
// None of the correlating variables originated in this scope.
return null;
}
RelNode r = r0;
if (correlNames.size() > 1) {
// The same table was referenced more than once.
// So we deduplicate.
r = DeduplicateCorrelateVariables.go(rexBuilder, correlNames.get(0), Util.skip(correlNames), r0);
// Add new node to leaves.
leaves.add(r);
}
return new CorrelationUse(correlNames.get(0), requiredColumns.build(), r);
}
use of org.apache.calcite.sql.validate.SqlNameMatcher in project calcite by apache.
the class SqlToRelConverter method convertColumnList.
/**
* Creates a source for an INSERT statement.
*
* <p>If the column list is not specified, source expressions match target
* columns in order.
*
* <p>If the column list is specified, Source expressions are mapped to
* target columns by name via targetColumnList, and may not cover the entire
* target table. So, we'll make up a full row, using a combination of
* default values and the source expressions provided.
*
* @param call Insert expression
* @param source Source relational expression
* @return Converted INSERT statement
*/
protected RelNode convertColumnList(final SqlInsert call, RelNode source) {
RelDataType sourceRowType = source.getRowType();
final RexNode sourceRef = rexBuilder.makeRangeReference(sourceRowType, 0, false);
final List<String> targetColumnNames = new ArrayList<>();
final List<RexNode> columnExprs = new ArrayList<>();
collectInsertTargets(call, sourceRef, targetColumnNames, columnExprs);
final RelOptTable targetTable = getTargetTable(call);
final RelDataType targetRowType = RelOptTableImpl.realRowType(targetTable);
final List<RelDataTypeField> targetFields = targetRowType.getFieldList();
final List<RexNode> sourceExps = new ArrayList<>(Collections.<RexNode>nCopies(targetFields.size(), null));
final List<String> fieldNames = new ArrayList<>(Collections.<String>nCopies(targetFields.size(), null));
final InitializerExpressionFactory initializerFactory = getInitializerFactory(validator.getNamespace(call).getTable());
// Walk the name list and place the associated value in the
// expression list according to the ordinal value returned from
// the table construct, leaving nulls in the list for columns
// that are not referenced.
final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
for (Pair<String, RexNode> p : Pair.zip(targetColumnNames, columnExprs)) {
RelDataTypeField field = nameMatcher.field(targetRowType, p.left);
assert field != null : "column " + p.left + " not found";
sourceExps.set(field.getIndex(), p.right);
}
// Lazily create a blackboard that contains all non-generated columns.
final Supplier<Blackboard> bb = new Supplier<Blackboard>() {
public Blackboard get() {
return createInsertBlackboard(targetTable, sourceRef, targetColumnNames);
}
};
// that were not supplied in the statement. Get field names too.
for (int i = 0; i < targetFields.size(); ++i) {
final RelDataTypeField field = targetFields.get(i);
final String fieldName = field.getName();
fieldNames.set(i, fieldName);
if (sourceExps.get(i) == null || sourceExps.get(i).getKind() == SqlKind.DEFAULT) {
sourceExps.set(i, initializerFactory.newColumnDefaultValue(targetTable, i, bb.get()));
// bare nulls are dangerous in the wrong hands
sourceExps.set(i, castNullLiteralIfNeeded(sourceExps.get(i), field.getType()));
}
}
return relBuilder.push(source).projectNamed(sourceExps, fieldNames, false).build();
}
use of org.apache.calcite.sql.validate.SqlNameMatcher in project calcite by apache.
the class SqlToRelConverter method isSubQueryNonCorrelated.
/**
* Determines whether a sub-query is non-correlated. Note that a
* non-correlated sub-query can contain correlated references, provided those
* references do not reference select statements that are parents of the
* sub-query.
*
* @param subq the sub-query
* @param bb blackboard used while converting the sub-query, i.e., the
* blackboard of the parent query of this sub-query
* @return true if the sub-query is non-correlated
*/
private boolean isSubQueryNonCorrelated(RelNode subq, Blackboard bb) {
Set<CorrelationId> correlatedVariables = RelOptUtil.getVariablesUsed(subq);
for (CorrelationId correlName : correlatedVariables) {
DeferredLookup lookup = mapCorrelToDeferred.get(correlName);
String originalRelName = lookup.getOriginalRelName();
final SqlNameMatcher nameMatcher = lookup.bb.scope.getValidator().getCatalogReader().nameMatcher();
final SqlValidatorScope.ResolvedImpl resolved = new SqlValidatorScope.ResolvedImpl();
lookup.bb.scope.resolve(ImmutableList.of(originalRelName), nameMatcher, false, resolved);
SqlValidatorScope ancestorScope = resolved.only().scope;
// If the correlated reference is in a scope that's "above" the
// sub-query, then this is a correlated sub-query.
SqlValidatorScope parentScope = bb.scope;
do {
if (ancestorScope == parentScope) {
return false;
}
if (parentScope instanceof DelegatingScope) {
parentScope = ((DelegatingScope) parentScope).getParent();
} else {
break;
}
} while (parentScope != null);
}
return true;
}
use of org.apache.calcite.sql.validate.SqlNameMatcher in project calcite by apache.
the class SqlToRelConverter method convertUsing.
/**
* Returns an expression for matching columns of a USING clause or inferred
* from NATURAL JOIN. "a JOIN b USING (x, y)" becomes "a.x = b.x AND a.y =
* b.y". Returns null if the column list is empty.
*
* @param leftNamespace Namespace of left input to join
* @param rightNamespace Namespace of right input to join
* @param nameList List of column names to join on
* @return Expression to match columns from name list, or true if name list
* is empty
*/
private RexNode convertUsing(SqlValidatorNamespace leftNamespace, SqlValidatorNamespace rightNamespace, List<String> nameList) {
final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
final List<RexNode> list = Lists.newArrayList();
for (String name : nameList) {
List<RexNode> operands = new ArrayList<>();
int offset = 0;
for (SqlValidatorNamespace n : ImmutableList.of(leftNamespace, rightNamespace)) {
final RelDataType rowType = n.getRowType();
final RelDataTypeField field = nameMatcher.field(rowType, name);
operands.add(rexBuilder.makeInputRef(field.getType(), offset + field.getIndex()));
offset += rowType.getFieldList().size();
}
list.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, operands));
}
return RexUtil.composeConjunction(rexBuilder, list, false);
}
Aggregations