use of org.apache.calcite.sql.JoinType in project calcite by apache.
the class RelToSqlConverter method visit.
/**
* @see #dispatch
*/
public Result visit(Join e) {
final Result leftResult = visitChild(0, e.getLeft()).resetAlias();
final Result rightResult = visitChild(1, e.getRight()).resetAlias();
final Context leftContext = leftResult.qualifiedContext();
final Context rightContext = rightResult.qualifiedContext();
SqlNode sqlCondition = null;
SqlLiteral condType = JoinConditionType.ON.symbol(POS);
JoinType joinType = joinType(e.getJoinType());
if (e.getJoinType() == JoinRelType.INNER && e.getCondition().isAlwaysTrue()) {
joinType = JoinType.COMMA;
condType = JoinConditionType.NONE.symbol(POS);
} else {
sqlCondition = convertConditionToSqlNode(e.getCondition(), leftContext, rightContext, e.getLeft().getRowType().getFieldCount());
}
SqlNode join = new SqlJoin(POS, leftResult.asFrom(), SqlLiteral.createBoolean(false, POS), joinType.symbol(POS), rightResult.asFrom(), condType, sqlCondition);
return result(join, leftResult, rightResult);
}
use of org.apache.calcite.sql.JoinType 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.JoinType in project flink by apache.
the class SqlValidatorImpl method rewriteMerge.
private void rewriteMerge(SqlMerge call) {
SqlNodeList selectList;
SqlUpdate updateStmt = call.getUpdateCall();
if (updateStmt != null) {
// if we have an update statement, just clone the select list
// from the update statement's source since it's the same as
// what we want for the select list of the merge source -- '*'
// followed by the update set expressions
selectList = SqlNode.clone(updateStmt.getSourceSelect().getSelectList());
} else {
// otherwise, just use select *
selectList = new SqlNodeList(SqlParserPos.ZERO);
selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
}
SqlNode targetTable = call.getTargetTable();
if (call.getAlias() != null) {
targetTable = SqlValidatorUtil.addAlias(targetTable, call.getAlias().getSimple());
}
// Provided there is an insert substatement, the source select for
// the merge is a left outer join between the source in the USING
// clause and the target table; otherwise, the join is just an
// inner join. Need to clone the source table reference in order
// for validation to work
SqlNode sourceTableRef = call.getSourceTableRef();
SqlInsert insertCall = call.getInsertCall();
JoinType joinType = (insertCall == null) ? JoinType.INNER : JoinType.LEFT;
final SqlNode leftJoinTerm = SqlNode.clone(sourceTableRef);
SqlNode outerJoin = new SqlJoin(SqlParserPos.ZERO, leftJoinTerm, SqlLiteral.createBoolean(false, SqlParserPos.ZERO), joinType.symbol(SqlParserPos.ZERO), targetTable, JoinConditionType.ON.symbol(SqlParserPos.ZERO), call.getCondition());
SqlSelect select = new SqlSelect(SqlParserPos.ZERO, null, selectList, outerJoin, null, null, null, null, null, null, null, null);
call.setSourceSelect(select);
// that via the from clause on the select
if (insertCall != null) {
SqlCall valuesCall = (SqlCall) insertCall.getSource();
SqlCall rowCall = valuesCall.operand(0);
selectList = new SqlNodeList(rowCall.getOperandList(), SqlParserPos.ZERO);
final SqlNode insertSource = SqlNode.clone(sourceTableRef);
select = new SqlSelect(SqlParserPos.ZERO, null, selectList, insertSource, null, null, null, null, null, null, null, null);
insertCall.setSource(select);
}
}
use of org.apache.calcite.sql.JoinType in project flink 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 (SqlNode node : list) {
SqlIdentifier id = (SqlIdentifier) node;
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, scope);
checkRollUpInUsing(id, right, scope);
}
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();
final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
List<String> naturalColumnNames = SqlValidatorUtil.deriveNaturalJoinColumnList(nameMatcher, leftRowType, rightRowType);
// Check compatibility of the chosen columns.
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 LEFT_SEMI_JOIN:
if (!this.config.sqlConformance().isLiberal()) {
throw newValidationError(join.getJoinTypeNode(), RESOURCE.dialectDoesNotSupportFeature("LEFT SEMI JOIN"));
}
// fall through
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.JoinType in project hive by apache.
the class HiveJdbcImplementor method visit.
@Override
public Result visit(Join e) {
final Result leftResult = visitInput(e, 0).resetAlias();
final Result rightResult = visitInput(e, 1).resetAlias();
final Context leftContext = leftResult.qualifiedContext();
final Context rightContext = rightResult.qualifiedContext();
SqlNode sqlCondition = null;
SqlLiteral condType = JoinConditionType.ON.symbol(POS);
JoinType joinType = joinType(e.getJoinType());
if (e.getJoinType() == JoinRelType.INNER && e.getCondition().isAlwaysTrue()) {
joinType = JoinType.COMMA;
condType = JoinConditionType.NONE.symbol(POS);
} else {
sqlCondition = convertConditionToSqlNode(e.getCondition(), leftContext, rightContext, e.getLeft().getRowType().getFieldCount());
}
SqlNode join = new SqlJoin(POS, leftResult.asFrom(), SqlLiteral.createBoolean(false, POS), joinType.symbol(POS), rightResult.asFrom(), condType, sqlCondition);
return result(join, leftResult, rightResult);
}
Aggregations