private List<Expression> translate(List<Statement> list, List<RexLocalRef> rexList) { // First pass. Count how many times each sub-expression is used. this.list = null; for (RexNode rexExpr : rexList) { translate(rexExpr); } // Mark expressions as inline if they are not used more than once. for (Map.Entry<RexNode, Slot> entry : map.entrySet()) { if (entry.getValue().count < 2 || entry.getKey() instanceof RexLiteral) { inlineRexSet.add(entry.getKey()); } } // Second pass. When translating each expression, if it is used more // than once, the first time it is encountered, add a declaration to the // list and set its usage count to 0. this.list = list; this.map.clear(); List<Expression> translateds = new ArrayList<Expression>(); for (RexNode rexExpr : rexList) { translateds.add(translate(rexExpr)); } return translateds; }
public RexNode parameter(ParameterExpression param) { int i = parameterList.indexOf(param); if (i >= 0) { return values.get(i); } throw new RuntimeException("unknown parameter " + param); }
private List<Expression> translateList(List<RexNode> operandList) { final List<Expression> list = new ArrayList<Expression>(); for (RexNode rex : operandList) { list.add(translate(rex)); } return list; }
public List<RexNode> toRexList(BlockExpression expression) { final List<Expression> simpleList = simpleList(expression); final List<RexNode> list = new ArrayList<RexNode>(); for (Expression expression1 : simpleList) { list.add(toRex(expression1)); } return list; }
public static Expression translateCondition( List<Expression> inputs, RexProgram program, JavaTypeFactory typeFactory, List<Statement> list) { List<Expression> x = new RexToLixTranslator(program, typeFactory, inputs) .translate(list, Collections.singletonList(program.getCondition())); assert x.size() == 1; return x.get(0); }
/** * Gets the expression for an input and counts it. * * @param index Input ordinal * @return Expression to which an input should be translated */ private Expression getInput(int index) { Slot slot = inputSlots.get(index); if (list == null) { slot.count++; } else { if (slot.count > 1 && slot.parameterExpression == null) { slot.parameterExpression = Expressions.parameter(slot.expression.type, "current" + index); list.add(Expressions.declare(Modifier.FINAL, slot.parameterExpression, slot.expression)); } } return slot.parameterExpression != null ? slot.parameterExpression : slot.expression; }
public List<SqlOperator> lookupOperatorOverloads( SqlIdentifier opName, SqlFunctionCategory category, SqlSyntax syntax) { if (syntax != SqlSyntax.Function) { return Collections.emptyList(); } // FIXME: ignoring prefix of opName String name = opName.names[opName.names.length - 1]; List<TableFunction> tableFunctions = rootSchema.getTableFunctions(name); if (tableFunctions.isEmpty()) { return Collections.emptyList(); } return toOps(name, tableFunctions); }
/** Returns the path of a schema, appending the name of a table if not null. */ public static List<String> path(Schema schema, String name) { final List<String> list = new ArrayList<String>(); if (name != null) { list.add(name); } for (Schema s = schema; s != null; s = s.getParentSchema()) { if (s.getParentSchema() != null || !s.getName().equals("")) { // Omit the root schema's name from the path if it's the empty string, // which it usually is. list.add(s.getName()); } } return ImmutableList.copyOf(Lists.reverse(list)); }
private RexToLixTranslator( RexProgram program, JavaTypeFactory typeFactory, List<Expression> inputs) { this.program = program; this.typeFactory = typeFactory; for (Expression input : inputs) { inputSlots.add(new Slot(null, input)); } }
public static TableFunction methodMember(final Method method, final JavaTypeFactory typeFactory) { final List<Parameter> parameters = new ArrayList<Parameter>(); for (final Class<?> parameterType : method.getParameterTypes()) { parameters.add( new Parameter() { final int ordinal = parameters.size(); final RelDataType type = typeFactory.createType(parameterType); public int getOrdinal() { return ordinal; } public String getName() { return "a" + ordinal; } public RelDataType getType(RelDataTypeFactory typeFactory) { return type; } }); } return new TableFunction() { public List<Parameter> getParameters() { return parameters; } public Table apply(List<Object> arguments) { try { //noinspection unchecked return (Table) method.invoke(null, arguments.toArray()); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } public RelDataType getRowType(RelDataTypeFactory typeFactory) { final Class<?> returnType = method.getReturnType(); return ((JavaTypeFactory) typeFactory).createType(returnType); } }; }
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 OptiqSchema.TableFunctionEntry resolve( RelDataTypeFactory typeFactory, String name, Collection<OptiqSchema.TableFunctionEntry> tableFunctions, List<RelDataType> argumentTypes) { final List<OptiqSchema.TableFunctionEntry> matches = new ArrayList<OptiqSchema.TableFunctionEntry>(); for (OptiqSchema.TableFunctionEntry member : tableFunctions) { if (matches(typeFactory, member.getTableFunction(), argumentTypes)) { matches.add(member); } } switch (matches.size()) { case 0: return null; case 1: return matches.get(0); default: throw new RuntimeException( "More than one match for " + name + " with arguments " + argumentTypes); } }
private SqlOperator toOp(String name, TableFunction fun) { List<RelDataType> argTypes = new ArrayList<RelDataType>(); List<SqlTypeFamily> typeFamilies = new ArrayList<SqlTypeFamily>(); Parameter p; for (net.hydromatic.optiq.Parameter o : (List<net.hydromatic.optiq.Parameter>) fun.getParameters()) { argTypes.add(o.getType()); typeFamilies.add(SqlTypeFamily.ANY); } return new SqlFunction( name, SqlKind.OTHER_FUNCTION, new ExplicitReturnTypeInference(typeFactory.createType(fun.getElementType())), new ExplicitOperandTypeInference(argTypes.toArray(new RelDataType[argTypes.size()])), new FamilyOperandTypeChecker( typeFamilies.toArray(new SqlTypeFamily[typeFamilies.size()])), null); }
private Expression translate(RexNode expr) { Slot slot = map.get(expr); if (slot == null) { Expression expression = translate0(expr); assert expression != null; final ParameterExpression parameter; if (!inlineRexSet.contains(expr) && !(expr instanceof RexLocalRef)) { parameter = Expressions.parameter(expression.getType(), "v" + map.size()); } else { parameter = null; } slot = new Slot(parameter, expression); if (parameter != null && list != null) { list.add(Expressions.declare(Modifier.FINAL, slot.parameterExpression, slot.expression)); } map.put(expr, slot); } slot.count++; return slot.parameterExpression != null ? slot.parameterExpression : slot.expression; }
private static boolean matches( RelDataTypeFactory typeFactory, TableFunction member, List<RelDataType> argumentTypes) { List<Parameter> parameters = member.getParameters(); if (parameters.size() != argumentTypes.size()) { return false; } for (int i = 0; i < argumentTypes.size(); i++) { RelDataType argumentType = argumentTypes.get(i); Parameter parameter = parameters.get(i); if (!canConvert(argumentType, parameter.getType(typeFactory))) { return false; } } return true; }
<T> PrepareResult<T> prepare_( Context context, String sql, Queryable<T> queryable, Type elementType) { final JavaTypeFactory typeFactory = context.getTypeFactory(); OptiqCatalogReader catalogReader = new OptiqCatalogReader(context.getRootSchema(), typeFactory); final OptiqPreparingStmt preparingStmt = new OptiqPreparingStmt(catalogReader, typeFactory, context.getRootSchema()); preparingStmt.setResultCallingConvention(CallingConvention.ENUMERABLE); final RelDataType x; final PreparedResult preparedResult; if (sql != null) { assert queryable == null; SqlParser parser = new SqlParser(sql); SqlNode sqlNode; try { sqlNode = parser.parseQuery(); } catch (SqlParseException e) { throw new RuntimeException("parse failed", e); } final Schema rootSchema = context.getRootSchema(); SqlValidator validator = new SqlValidatorImpl( new ChainedSqlOperatorTable( Arrays.<SqlOperatorTable>asList( SqlStdOperatorTable.instance(), new MySqlOperatorTable(rootSchema, typeFactory))), catalogReader, typeFactory, SqlConformance.Default) {}; preparedResult = preparingStmt.prepareSql(sqlNode, Object.class, validator, true); x = validator.getValidatedNodeType(sqlNode); } else { assert queryable != null; x = context.getTypeFactory().createType(elementType); preparedResult = preparingStmt.prepareQueryable(queryable, x); } // TODO: parameters final List<Parameter> parameters = Collections.emptyList(); // TODO: column meta data final List<ColumnMetaData> columns = new ArrayList<ColumnMetaData>(); RelDataType jdbcType = makeStruct(typeFactory, x); for (RelDataTypeField field : jdbcType.getFields()) { RelDataType type = field.getType(); SqlTypeName sqlTypeName = type.getSqlTypeName(); columns.add( new ColumnMetaData( columns.size(), false, true, false, false, type.isNullable() ? 1 : 0, true, 0, field.getName(), field.getName(), null, sqlTypeName.allowsPrec() && false ? type.getPrecision() : -1, sqlTypeName.allowsScale() ? type.getScale() : -1, null, null, sqlTypeName.getJdbcOrdinal(), sqlTypeName.getName(), true, false, false, null)); } return new PrepareResult<T>(sql, parameters, columns, (Enumerable<T>) preparedResult.execute()); }