use of org.apache.calcite.rel.core.CorrelationId in project hive by apache.
the class HiveSubQRemoveRelBuilder method join.
public HiveSubQRemoveRelBuilder join(JoinRelType joinType, RexNode condition, Set<CorrelationId> variablesSet, boolean createSemiJoin) {
Frame right = stack.pop();
final Frame left = stack.pop();
final RelNode join;
final boolean correlate = variablesSet.size() == 1;
RexNode postCondition = literal(true);
if (correlate) {
final CorrelationId id = Iterables.getOnlyElement(variablesSet);
final ImmutableBitSet requiredColumns = RelOptUtil.correlationColumns(id, right.rel);
if (!RelOptUtil.notContainsCorrelation(left.rel, id, Litmus.IGNORE)) {
throw new IllegalArgumentException("variable " + id + " must not be used by left input to correlation");
}
switch(joinType) {
case LEFT:
// Correlate does not have an ON clause.
// For a LEFT correlate, predicate must be evaluated first.
// For INNER, we can defer.
stack.push(right);
filter(condition.accept(new Shifter(left.rel, id, right.rel)));
right = stack.pop();
break;
default:
postCondition = condition;
}
if (createSemiJoin) {
join = correlateFactory.createCorrelate(left.rel, right.rel, id, requiredColumns, SemiJoinType.SEMI);
} else {
join = correlateFactory.createCorrelate(left.rel, right.rel, id, requiredColumns, SemiJoinType.of(joinType));
}
} else {
join = joinFactory.createJoin(left.rel, right.rel, condition, variablesSet, joinType, false);
}
final List<Pair<String, RelDataType>> pairs = new ArrayList<>();
pairs.addAll(left.right);
pairs.addAll(right.right);
stack.push(new Frame(join, ImmutableList.copyOf(pairs)));
filter(postCondition);
return this;
}
use of org.apache.calcite.rel.core.CorrelationId in project hive by apache.
the class RexNodeConverter method convert.
protected RexNode convert(ExprNodeColumnDesc col) throws SemanticException {
// if this is co-rrelated we need to make RexCorrelVariable(with id and type)
// id and type should be retrieved from outerRR
InputCtx ic = getInputCtx(col);
if (ic == null) {
// we have correlated column, build data type from outer rr
RelDataType rowType = TypeConverter.getType(cluster, this.outerRR, null);
if (this.outerNameToPosMap.get(col.getColumn()) == null) {
throw new SemanticException(ErrorMsg.INVALID_COLUMN_NAME.getMsg(col.getColumn()));
}
int pos = this.outerNameToPosMap.get(col.getColumn());
CorrelationId colCorr = new CorrelationId(this.correlatedId);
RexNode corExpr = cluster.getRexBuilder().makeCorrel(rowType, colCorr);
return cluster.getRexBuilder().makeFieldAccess(corExpr, pos);
}
int pos = ic.hiveNameToPosMap.get(col.getColumn());
return cluster.getRexBuilder().makeInputRef(ic.calciteInpDataType.getFieldList().get(pos).getType(), pos + ic.offsetInCalciteSchema);
}
use of org.apache.calcite.rel.core.CorrelationId in project flink by apache.
the class HiveParserRexNodeConverter method convertColumn.
private RexNode convertColumn(ExprNodeColumnDesc col) throws SemanticException {
// if this is co-rrelated we need to make RexCorrelVariable(with id and type)
// id and type should be retrieved from outerRR
InputCtx ic = getInputCtx(col);
if (ic == null) {
// we have correlated column, build data type from outer rr
RelDataType rowType = HiveParserTypeConverter.getType(cluster, this.outerRR, null);
if (this.outerNameToPos.get(col.getColumn()) == null) {
throw new SemanticException("Invalid column name " + col.getColumn());
}
int pos = this.outerNameToPos.get(col.getColumn());
CorrelationId colCorr = new CorrelationId(this.correlatedId);
RexNode corExpr = cluster.getRexBuilder().makeCorrel(rowType, colCorr);
return cluster.getRexBuilder().makeFieldAccess(corExpr, pos);
}
int pos = ic.hiveNameToPosMap.get(col.getColumn());
return cluster.getRexBuilder().makeInputRef(ic.calciteInpDataType.getFieldList().get(pos).getType(), pos + ic.offsetInCalciteSchema);
}
use of org.apache.calcite.rel.core.CorrelationId in project flink by apache.
the class RexNodeJsonDeserializer method deserializeCorrelVariable.
private static RexNode deserializeCorrelVariable(JsonNode jsonNode, SerdeContext serdeContext) {
final String correl = jsonNode.required(FIELD_NAME_CORREL).asText();
final JsonNode logicalTypeNode = jsonNode.required(FIELD_NAME_TYPE);
final RelDataType fieldType = RelDataTypeJsonDeserializer.deserialize(logicalTypeNode, serdeContext);
return serdeContext.getRexBuilder().makeCorrel(fieldType, new CorrelationId(correl));
}
use of org.apache.calcite.rel.core.CorrelationId in project Mycat2 by MyCATApache.
the class RelJson method toRex.
RexNode toRex(RelInput relInput, Object o) {
final RelOptCluster cluster = relInput.getCluster();
final RexBuilder rexBuilder = cluster.getRexBuilder();
if (o == null) {
return null;
} else if (o instanceof Map) {
Map map = (Map) o;
final Map<String, Object> opMap = (Map) map.get("op");
final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
if (opMap != null) {
if (map.containsKey("class")) {
opMap.put("class", map.get("class"));
}
final List operands = (List) map.get("operands");
final List<RexNode> rexOperands = toRexList(relInput, operands);
final Object jsonType = map.get("type");
final Map window = (Map) map.get("window");
if (window != null) {
final SqlAggFunction operator = toAggregation(opMap);
final RelDataType type = toType(typeFactory, jsonType);
List<RexNode> partitionKeys = new ArrayList<>();
if (window.containsKey("partition")) {
partitionKeys = toRexList(relInput, (List) window.get("partition"));
}
List<RexFieldCollation> orderKeys = new ArrayList<>();
if (window.containsKey("order")) {
orderKeys = toRexFieldCollationList(relInput, (List) window.get("order"));
}
final RexWindowBound lowerBound;
final RexWindowBound upperBound;
final boolean physical;
if (window.get("rows-lower") != null) {
lowerBound = toRexWindowBound(relInput, (Map) window.get("rows-lower"));
upperBound = toRexWindowBound(relInput, (Map) window.get("rows-upper"));
physical = true;
} else if (window.get("range-lower") != null) {
lowerBound = toRexWindowBound(relInput, (Map) window.get("range-lower"));
upperBound = toRexWindowBound(relInput, (Map) window.get("range-upper"));
physical = false;
} else {
// No ROWS or RANGE clause
lowerBound = null;
upperBound = null;
physical = false;
}
final boolean distinct = (Boolean) map.get("distinct");
return rexBuilder.makeOver(type, operator, rexOperands, partitionKeys, ImmutableList.copyOf(orderKeys), lowerBound, upperBound, physical, true, false, distinct, false);
} else {
final SqlOperator operator = Objects.requireNonNull(toOp(opMap));
final RelDataType type;
if (jsonType != null) {
type = toType(typeFactory, jsonType);
} else {
type = rexBuilder.deriveReturnType(operator, rexOperands);
}
return rexBuilder.makeCall(type, operator, rexOperands);
}
}
final Integer input = (Integer) map.get("input");
if (input != null) {
// Check if it is a local ref.
if (map.containsKey("type")) {
final RelDataType type = toType(typeFactory, map.get("type"));
return rexBuilder.makeLocalRef(type, input);
}
List<RelNode> inputNodes = relInput.getInputs();
int i = input;
for (RelNode inputNode : inputNodes) {
final RelDataType rowType = inputNode.getRowType();
if (i < rowType.getFieldCount()) {
final RelDataTypeField field = rowType.getFieldList().get(i);
return rexBuilder.makeInputRef(field.getType(), input);
}
i -= rowType.getFieldCount();
}
throw new RuntimeException("input field " + input + " is out of range");
}
final String field = (String) map.get("field");
if (field != null) {
final Object jsonExpr = map.get("expr");
final RexNode expr = toRex(relInput, jsonExpr);
return rexBuilder.makeFieldAccess(expr, field, true);
}
final String correl = (String) map.get("correl");
if (correl != null) {
final Object jsonType = map.get("type");
RelDataType type = toType(typeFactory, jsonType);
return rexBuilder.makeCorrel(type, new CorrelationId(correl));
}
if (map.containsKey("literal")) {
Object literal = map.get("literal");
final RelDataType type = toType(typeFactory, map.get("type"));
if (literal == null) {
return rexBuilder.makeNullLiteral(type);
}
if (type == null) {
// we just interpret the literal
return toRex(relInput, literal);
}
if (type.getSqlTypeName() == SqlTypeName.SYMBOL) {
literal = RelEnumTypes.toEnum((String) literal);
}
if (literal == null) {
return rexBuilder.makeNullLiteral(type);
}
switch(type.getSqlTypeName()) {
case INTERVAL_MONTH:
case INTERVAL_QUARTER:
case INTERVAL_YEAR:
case INTERVAL_YEAR_MONTH:
case INTERVAL_WEEK:
break;
case VARBINARY:
case BINARY:
return new RexLiteral(ByteString.of(literal.toString(), 16), type, type.getSqlTypeName());
// //////////////////////////////////////////
case INTERVAL_DAY:
case INTERVAL_DAY_HOUR:
case INTERVAL_DAY_MINUTE:
case INTERVAL_DAY_SECOND:
case INTERVAL_HOUR:
case INTERVAL_HOUR_MINUTE:
case INTERVAL_HOUR_SECOND:
case INTERVAL_MINUTE:
case INTERVAL_MINUTE_SECOND:
case INTERVAL_SECOND:
case INTERVAL_MICROSECOND:
case INTERVAL_SECOND_MICROSECOND:
// ///////////////////////////////////////////
case TIME_WITH_LOCAL_TIME_ZONE:
case TIME:
if (literal instanceof String) {
Duration duration = Duration.parse((String) (literal));
return new RexLiteral(duration, type, type.getSqlTypeName());
}
break;
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
case TIMESTAMP:
if (literal instanceof String) {
return new RexLiteral(LocalDateTime.parse((String) literal), type, type.getSqlTypeName());
}
break;
default:
}
try {
if (literal instanceof Integer) {
literal = ((Integer) literal).longValue();
}
return rexBuilder.makeLiteral(literal, type, false);
} catch (Throwable throwable) {
throwable.printStackTrace();
return null;
}
}
if (map.containsKey("index") && map.containsKey("name")) {
final RelDataType type = toType(typeFactory, map.get("type"));
Number index = (Number) map.get("index");
return rexBuilder.makeDynamicParam(type, index.intValue());
}
throw new UnsupportedOperationException("cannot convert to rex " + o);
} else if (o instanceof Boolean) {
return rexBuilder.makeLiteral((Boolean) o);
} else if (o instanceof String) {
return rexBuilder.makeLiteral((String) o);
} else if (o instanceof Number) {
final Number number = (Number) o;
if (number instanceof Double || number instanceof Float) {
return rexBuilder.makeApproxLiteral(BigDecimal.valueOf(number.doubleValue()));
} else {
return rexBuilder.makeExactLiteral(BigDecimal.valueOf(number.longValue()));
}
} else {
throw new UnsupportedOperationException("cannot convert to rex " + o);
}
}
Aggregations