use of org.apache.calcite.rex.RexRangeRef in project calcite by apache.
the class SqlToRelConverter method translateIn.
private RexNode translateIn(RelOptUtil.Logic logic, RelNode root, final RexNode rex) {
switch(logic) {
case TRUE:
return rexBuilder.makeLiteral(true);
case TRUE_FALSE:
case UNKNOWN_AS_FALSE:
assert rex instanceof RexRangeRef;
final int fieldCount = rex.getType().getFieldCount();
RexNode rexNode = rexBuilder.makeFieldAccess(rex, fieldCount - 1);
rexNode = rexBuilder.makeCall(SqlStdOperatorTable.IS_TRUE, rexNode);
// Then append the IS NOT NULL(leftKeysForIn).
//
// RexRangeRef contains the following fields:
// leftKeysForIn,
// rightKeysForIn (the original sub-query select list),
// nullIndicator
//
// The first two lists contain the same number of fields.
final int k = (fieldCount - 1) / 2;
for (int i = 0; i < k; i++) {
rexNode = rexBuilder.makeCall(SqlStdOperatorTable.AND, rexNode, rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, rexBuilder.makeFieldAccess(rex, i)));
}
return rexNode;
case TRUE_FALSE_UNKNOWN:
case UNKNOWN_AS_TRUE:
// select e.deptno,
// case
// when ct.c = 0 then false
// when dt.i is not null then true
// when e.deptno is null then null
// when ct.ck < ct.c then null
// else false
// end
// from e
// cross join (select count(*) as c, count(deptno) as ck from v) as ct
// left join (select distinct deptno, true as i from v) as dt
// on e.deptno = dt.deptno
final Join join = (Join) root;
final Project left = (Project) join.getLeft();
final RelNode leftLeft = ((Join) left.getInput()).getLeft();
final int leftLeftCount = leftLeft.getRowType().getFieldCount();
final RelDataType longType = typeFactory.createSqlType(SqlTypeName.BIGINT);
final RexNode cRef = rexBuilder.makeInputRef(root, leftLeftCount);
final RexNode ckRef = rexBuilder.makeInputRef(root, leftLeftCount + 1);
final RexNode iRef = rexBuilder.makeInputRef(root, root.getRowType().getFieldCount() - 1);
final RexLiteral zero = rexBuilder.makeExactLiteral(BigDecimal.ZERO, longType);
final RexLiteral trueLiteral = rexBuilder.makeLiteral(true);
final RexLiteral falseLiteral = rexBuilder.makeLiteral(false);
final RexNode unknownLiteral = rexBuilder.makeNullLiteral(trueLiteral.getType());
final ImmutableList.Builder<RexNode> args = ImmutableList.builder();
args.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, cRef, zero), falseLiteral, rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, iRef), trueLiteral);
final JoinInfo joinInfo = join.analyzeCondition();
for (int leftKey : joinInfo.leftKeys) {
final RexNode kRef = rexBuilder.makeInputRef(root, leftKey);
args.add(rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, kRef), unknownLiteral);
}
args.add(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, ckRef, cRef), unknownLiteral, falseLiteral);
return rexBuilder.makeCall(SqlStdOperatorTable.CASE, args.build());
default:
throw new AssertionError(logic);
}
}
use of org.apache.calcite.rex.RexRangeRef in project calcite by apache.
the class StandardConvertletTable method convertMultiset.
public RexNode convertMultiset(SqlRexContext cx, SqlMultisetValueConstructor op, SqlCall call) {
final RelDataType originalType = cx.getValidator().getValidatedNodeType(call);
RexRangeRef rr = cx.getSubQueryExpr(call);
assert rr != null;
RelDataType msType = rr.getType().getFieldList().get(0).getType();
RexNode expr = cx.getRexBuilder().makeInputRef(msType, rr.getOffset());
assert msType.getComponentType().isStruct();
if (!originalType.getComponentType().isStruct()) {
// If the type is not a struct, the multiset operator will have
// wrapped the type as a record. Add a call to the $SLICE operator
// to compensate. For example,
// if '<ms>' has type 'RECORD (INTEGER x) MULTISET',
// then '$SLICE(<ms>) has type 'INTEGER MULTISET'.
// This will be removed as the expression is translated.
expr = cx.getRexBuilder().makeCall(originalType, SqlStdOperatorTable.SLICE, ImmutableList.of(expr));
}
return expr;
}
use of org.apache.calcite.rex.RexRangeRef in project calcite by apache.
the class StandardConvertletTable method convertMultisetQuery.
public RexNode convertMultisetQuery(SqlRexContext cx, SqlMultisetQueryConstructor op, SqlCall call) {
final RelDataType originalType = cx.getValidator().getValidatedNodeType(call);
RexRangeRef rr = cx.getSubQueryExpr(call);
assert rr != null;
RelDataType msType = rr.getType().getFieldList().get(0).getType();
RexNode expr = cx.getRexBuilder().makeInputRef(msType, rr.getOffset());
assert msType.getComponentType().isStruct();
if (!originalType.getComponentType().isStruct()) {
// If the type is not a struct, the multiset operator will have
// wrapped the type as a record. Add a call to the $SLICE operator
// to compensate. For example,
// if '<ms>' has type 'RECORD (INTEGER x) MULTISET',
// then '$SLICE(<ms>) has type 'INTEGER MULTISET'.
// This will be removed as the expression is translated.
expr = cx.getRexBuilder().makeCall(SqlStdOperatorTable.SLICE, expr);
}
return expr;
}
Aggregations