use of org.apache.calcite.sql.SqlCallBinding in project flink by apache.
the class ProcedureNamespace method validateImpl.
public RelDataType validateImpl(RelDataType targetRowType) {
validator.inferUnknownTypes(validator.unknownType, scope, call);
final RelDataType type = validator.deriveTypeImpl(scope, call);
final SqlOperator operator = call.getOperator();
final SqlCallBinding callBinding = new SqlCallBinding(validator, scope, call);
if (operator instanceof SqlTableFunction) {
final SqlTableFunction tableFunction = (SqlTableFunction) operator;
if (type.getSqlTypeName() != SqlTypeName.CURSOR) {
throw new IllegalArgumentException("Table function should have CURSOR " + "type, not " + type);
}
final SqlReturnTypeInference rowTypeInference = tableFunction.getRowTypeInference();
RelDataType retType = rowTypeInference.inferReturnType(callBinding);
return validator.getTypeFactory().createTypeWithNullability(retType, false);
}
// special handling of collection tables TABLE(function(...))
if (SqlUtil.stripAs(enclosingNode).getKind() == SqlKind.COLLECTION_TABLE) {
return toStruct(type, getNode());
}
return type;
}
use of org.apache.calcite.sql.SqlCallBinding in project calcite by apache.
the class SqlInOperator method deriveType.
public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) {
final List<SqlNode> operands = call.getOperandList();
assert operands.size() == 2;
final SqlNode left = operands.get(0);
final SqlNode right = operands.get(1);
final RelDataTypeFactory typeFactory = validator.getTypeFactory();
RelDataType leftType = validator.deriveType(scope, left);
RelDataType rightType;
// Derive type for RHS.
if (right instanceof SqlNodeList) {
// Handle the 'IN (expr, ...)' form.
List<RelDataType> rightTypeList = new ArrayList<>();
SqlNodeList nodeList = (SqlNodeList) right;
for (int i = 0; i < nodeList.size(); i++) {
SqlNode node = nodeList.get(i);
RelDataType nodeType = validator.deriveType(scope, node);
rightTypeList.add(nodeType);
}
rightType = typeFactory.leastRestrictive(rightTypeList);
// SQL:2003 Part 2 Section 8.4, <in predicate>).
if (null == rightType) {
throw validator.newValidationError(right, RESOURCE.incompatibleTypesInList());
}
// Record the RHS type for use by SqlToRelConverter.
((SqlValidatorImpl) validator).setValidatedNodeType(nodeList, rightType);
} else {
// Handle the 'IN (query)' form.
rightType = validator.deriveType(scope, right);
}
// Now check that the left expression is compatible with the
// type of the list. Same strategy as the '=' operator.
// Normalize the types on both sides to be row types
// for the purposes of compatibility-checking.
RelDataType leftRowType = SqlTypeUtil.promoteToRowType(typeFactory, leftType, null);
RelDataType rightRowType = SqlTypeUtil.promoteToRowType(typeFactory, rightType, null);
final ComparableOperandTypeChecker checker = (ComparableOperandTypeChecker) OperandTypes.COMPARABLE_UNORDERED_COMPARABLE_UNORDERED;
if (!checker.checkOperandTypes(new ExplicitOperatorBinding(new SqlCallBinding(validator, scope, call), ImmutableList.of(leftRowType, rightRowType)))) {
throw validator.newValidationError(call, RESOURCE.incompatibleValueType(SqlStdOperatorTable.IN.getName()));
}
// on either side.
return typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.BOOLEAN), anyNullable(leftRowType.getFieldList()) || anyNullable(rightRowType.getFieldList()));
}
use of org.apache.calcite.sql.SqlCallBinding in project calcite by apache.
the class SqlToRelConverter method convertCollectionTable.
protected void convertCollectionTable(Blackboard bb, SqlCall call) {
final SqlOperator operator = call.getOperator();
if (operator == SqlStdOperatorTable.TABLESAMPLE) {
final String sampleName = SqlLiteral.unchain(call.operand(0)).getValueAs(String.class);
datasetStack.push(sampleName);
SqlCall cursorCall = call.operand(1);
SqlNode query = cursorCall.operand(0);
RelNode converted = convertQuery(query, false, false).rel;
bb.setRoot(converted, false);
datasetStack.pop();
return;
}
replaceSubQueries(bb, call, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
// Expand table macro if possible. It's more efficient than
// LogicalTableFunctionScan.
final SqlCallBinding callBinding = new SqlCallBinding(bb.scope.getValidator(), bb.scope, call);
if (operator instanceof SqlUserDefinedTableMacro) {
final SqlUserDefinedTableMacro udf = (SqlUserDefinedTableMacro) operator;
final TranslatableTable table = udf.getTable(typeFactory, callBinding.operands());
final RelDataType rowType = table.getRowType(typeFactory);
RelOptTable relOptTable = RelOptTableImpl.create(null, rowType, table, udf.getNameAsId().names);
RelNode converted = toRel(relOptTable);
bb.setRoot(converted, true);
return;
}
Type elementType;
if (operator instanceof SqlUserDefinedTableFunction) {
SqlUserDefinedTableFunction udtf = (SqlUserDefinedTableFunction) operator;
elementType = udtf.getElementType(typeFactory, callBinding.operands());
} else {
elementType = null;
}
RexNode rexCall = bb.convertExpression(call);
final List<RelNode> inputs = bb.retrieveCursors();
Set<RelColumnMapping> columnMappings = getColumnMappings(operator);
LogicalTableFunctionScan callRel = LogicalTableFunctionScan.create(cluster, inputs, rexCall, elementType, validator.getValidatedNodeType(call), columnMappings);
bb.setRoot(callRel, true);
afterTableFunction(bb, call, callRel);
}
Aggregations