use of org.apache.calcite.sql.validate.SqlValidatorImpl 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.validate.SqlValidatorImpl in project calcite by apache.
the class SqlCaseOperator method inferTypeFromValidator.
private RelDataType inferTypeFromValidator(SqlCallBinding callBinding) {
SqlCase caseCall = (SqlCase) callBinding.getCall();
SqlNodeList thenList = caseCall.getThenOperands();
ArrayList<SqlNode> nullList = new ArrayList<SqlNode>();
List<RelDataType> argTypes = new ArrayList<RelDataType>();
for (SqlNode node : thenList) {
argTypes.add(callBinding.getValidator().deriveType(callBinding.getScope(), node));
if (SqlUtil.isNullLiteral(node, false)) {
nullList.add(node);
}
}
SqlNode elseOp = caseCall.getElseOperand();
argTypes.add(callBinding.getValidator().deriveType(callBinding.getScope(), caseCall.getElseOperand()));
if (SqlUtil.isNullLiteral(elseOp, false)) {
nullList.add(elseOp);
}
RelDataType ret = callBinding.getTypeFactory().leastRestrictive(argTypes);
if (null == ret) {
throw callBinding.newValidationError(RESOURCE.illegalMixingOfTypes());
}
final SqlValidatorImpl validator = (SqlValidatorImpl) callBinding.getValidator();
for (SqlNode node : nullList) {
validator.setValidatedNodeType(node, ret);
}
return ret;
}
use of org.apache.calcite.sql.validate.SqlValidatorImpl in project calcite by apache.
the class SqlToRelConverter method convertMultisets.
private RelNode convertMultisets(final List<SqlNode> operands, Blackboard bb) {
// NOTE: Wael 2/04/05: this implementation is not the most efficient in
// terms of planning since it generates XOs that can be reduced.
final List<Object> joinList = new ArrayList<>();
List<SqlNode> lastList = new ArrayList<>();
for (int i = 0; i < operands.size(); i++) {
SqlNode operand = operands.get(i);
if (!(operand instanceof SqlCall)) {
lastList.add(operand);
continue;
}
final SqlCall call = (SqlCall) operand;
final RelNode input;
switch(call.getKind()) {
case MULTISET_VALUE_CONSTRUCTOR:
case ARRAY_VALUE_CONSTRUCTOR:
final SqlNodeList list = new SqlNodeList(call.getOperandList(), call.getParserPosition());
CollectNamespace nss = (CollectNamespace) validator.getNamespace(call);
Blackboard usedBb;
if (null != nss) {
usedBb = createBlackboard(nss.getScope(), null, false);
} else {
usedBb = createBlackboard(new ListScope(bb.scope) {
public SqlNode getNode() {
return call;
}
}, null, false);
}
RelDataType multisetType = validator.getValidatedNodeType(call);
((SqlValidatorImpl) validator).setValidatedNodeType(list, multisetType.getComponentType());
input = convertQueryOrInList(usedBb, list, null);
break;
case MULTISET_QUERY_CONSTRUCTOR:
case ARRAY_QUERY_CONSTRUCTOR:
final RelRoot root = convertQuery(call.operand(0), false, true);
input = root.rel;
break;
default:
lastList.add(operand);
continue;
}
if (lastList.size() > 0) {
joinList.add(lastList);
}
lastList = new ArrayList<>();
Collect collect = new Collect(cluster, cluster.traitSetOf(Convention.NONE), input, validator.deriveAlias(call, i));
joinList.add(collect);
}
if (joinList.size() == 0) {
joinList.add(lastList);
}
for (int i = 0; i < joinList.size(); i++) {
Object o = joinList.get(i);
if (o instanceof List) {
@SuppressWarnings("unchecked") List<SqlNode> projectList = (List<SqlNode>) o;
final List<RexNode> selectList = new ArrayList<>();
final List<String> fieldNameList = new ArrayList<>();
for (int j = 0; j < projectList.size(); j++) {
SqlNode operand = projectList.get(j);
selectList.add(bb.convertExpression(operand));
// REVIEW angel 5-June-2005: Use deriveAliasFromOrdinal
// instead of deriveAlias to match field names from
// SqlRowOperator. Otherwise, get error Type
// 'RecordType(INTEGER EMPNO)' has no field 'EXPR$0' when
// doing select * from unnest( select multiset[empno]
// from sales.emps);
fieldNameList.add(SqlUtil.deriveAliasFromOrdinal(j));
}
relBuilder.push(LogicalValues.createOneRow(cluster)).projectNamed(selectList, fieldNameList, true);
joinList.set(i, relBuilder.build());
}
}
RelNode ret = (RelNode) joinList.get(0);
for (int i = 1; i < joinList.size(); i++) {
RelNode relNode = (RelNode) joinList.get(i);
ret = RelFactories.DEFAULT_JOIN_FACTORY.createJoin(ret, relNode, rexBuilder.makeLiteral(true), ImmutableSet.<CorrelationId>of(), JoinRelType.INNER, false);
}
return ret;
}
Aggregations