private Expression translate0(RexNode expr) { if (expr instanceof RexInputRef) { // TODO: multiple inputs, e.g. joins final Expression input = getInput(0); final int index = ((RexInputRef) expr).getIndex(); final List<RelDataTypeField> fields = program.getInputRowType().getFieldList(); final RelDataTypeField field = fields.get(index); if (fields.size() == 1) { return input; } else if (input.getType() == Object[].class) { return Expressions.convert_( Expressions.arrayIndex(input, Expressions.constant(field.getIndex())), Types.box(JavaRules.EnumUtil.javaClass(typeFactory, field.getType()))); } else { return Expressions.field(input, field.getName()); } } if (expr instanceof RexLocalRef) { return translate(program.getExprList().get(((RexLocalRef) expr).getIndex())); } if (expr instanceof RexLiteral) { return Expressions.constant( ((RexLiteral) expr).getValue(), typeFactory.getJavaClass(expr.getType())); } if (expr instanceof RexCall) { final RexCall call = (RexCall) expr; final SqlOperator operator = call.getOperator(); final ExpressionType expressionType = SQL_TO_LINQ_OPERATOR_MAP.get(operator); if (expressionType != null) { switch (operator.getSyntax()) { case Binary: return Expressions.makeBinary( expressionType, translate(call.getOperands()[0]), translate(call.getOperands()[1])); case Postfix: case Prefix: return Expressions.makeUnary(expressionType, translate(call.getOperands()[0])); default: throw new RuntimeException("unknown syntax " + operator.getSyntax()); } } Method method = SQL_OP_TO_JAVA_METHOD_MAP.get(operator); if (method != null) { List<Expression> exprs = translateList(Arrays.asList(call.operands)); return !Modifier.isStatic(method.getModifiers()) ? Expressions.call(exprs.get(0), method, exprs.subList(1, exprs.size())) : Expressions.call(method, exprs); } switch (expr.getKind()) { default: throw new RuntimeException("cannot translate expression " + expr); } } throw new RuntimeException("cannot translate expression " + expr); }
public static RelDataType createTypeFromProjection( RelDataType type, List<String> columnNameList, RelDataTypeFactory typeFactory, boolean caseSensitive) { // If the names in columnNameList and type have case-sensitive differences, // the resulting type will use those from type. These are presumably more // canonical. final List<RelDataTypeField> fields = new ArrayList<RelDataTypeField>(columnNameList.size()); for (String name : columnNameList) { RelDataTypeField field = type.getField(name, caseSensitive); fields.add(type.getFieldList().get(field.getIndex())); } return typeFactory.createStructType(fields); }
public int fieldOrdinal(RelDataType rowType, String alias) { RelDataTypeField field = field(rowType, alias); return field != null ? field.getIndex() : -1; }