/** Variant of {@link #trimFields(RelNode, BitSet, Set)} for {@link TableModificationRel}. */ public TrimResult trimFields( TableModificationRel modifier, BitSet fieldsUsed, Set<RelDataTypeField> extraFields) { // Ignore what consumer wants. We always project all columns. Util.discard(fieldsUsed); final RelDataType rowType = modifier.getRowType(); final int fieldCount = rowType.getFieldCount(); RelNode input = modifier.getChild(); // We want all fields from the child. final int inputFieldCount = input.getRowType().getFieldCount(); BitSet inputFieldsUsed = Util.bitSetBetween(0, inputFieldCount); // Create input with trimmed columns. final Set<RelDataTypeField> inputExtraFields = Collections.emptySet(); TrimResult trimResult = trimChild(modifier, input, inputFieldsUsed, inputExtraFields); RelNode newInput = trimResult.left; final Mapping inputMapping = trimResult.right; if (!inputMapping.isIdentity()) { // We asked for all fields. Can't believe that the child decided // to permute them! throw Util.newInternal("Expected identity mapping, got " + inputMapping); } TableModificationRel newModifier = modifier; if (newInput != input) { newModifier = modifier.copy(modifier.getTraitSet(), Collections.singletonList(newInput)); } assert newModifier.getClass() == modifier.getClass(); // Always project all fields. Mapping mapping = Mappings.createIdentity(fieldCount); return new TrimResult(newModifier, mapping); }
/** * Creates a JavaRelImplementor * * @param rexBuilder Builder for {@link RexNode}s * @param implementorTable Table of implementations of operators. Must not be null */ public JavaRelImplementor(RexBuilder rexBuilder, OJRexImplementorTable implementorTable) { super(rexBuilder); Util.pre(rexBuilder != null, "rexBuilder != null"); Util.pre(implementorTable != null, "implementorTable != null"); this.implementorTable = implementorTable; nextVariableId = 0; }
@Override public ParseTree visitChildInternal(RelNode child, int ordinal) { final Convention convention = child.getConvention(); if (!(child instanceof JavaRel)) { throw Util.newInternal( "Relational expression '" + child + "' has '" + convention + "' calling convention, so must implement interface " + JavaRel.class); } JavaRel javaRel = (JavaRel) child; final ParseTree p = javaRel.implement(this); if ((convention == CallingConvention.JAVA) && (p != null)) { throw Util.newInternal( "Relational expression '" + child + "' returned '" + p + " on implement, but should have " + "returned null, because it has JAVA calling-convention. " + "(Note that similar calling-conventions, such as " + "Iterator, must return a value.)"); } return p; }
/** * Trims the fields of an input relational expression. * * @param rel Relational expression * @param input Input relational expression, whose fields to trim * @param fieldsUsed Bitmap of fields needed by the consumer * @return New relational expression and its field mapping */ protected TrimResult trimChild( RelNode rel, RelNode input, BitSet fieldsUsed, Set<RelDataTypeField> extraFields) { Util.discard(rel); if (input.getClass().getName().endsWith("MedMdrClassExtentRel")) { // MedMdrJoinRule cannot handle Join of Project of // MedMdrClassExtentRel, only naked MedMdrClassExtentRel. // So, disable trimming. fieldsUsed = Util.bitSetBetween(0, input.getRowType().getFieldCount()); } return dispatchTrimFields(input, fieldsUsed, extraFields); }
/** @pre SqlTypeUtil.sameNamedType(argTypes[0], (argTypes[1])) */ public RelDataType inferReturnType(SqlOperatorBinding opBinding) { final RelDataType argType0 = opBinding.getOperandType(0); final RelDataType argType1 = opBinding.getOperandType(1); if (!(SqlTypeUtil.inCharOrBinaryFamilies(argType0) && SqlTypeUtil.inCharOrBinaryFamilies(argType1))) { Util.pre( SqlTypeUtil.sameNamedType(argType0, argType1), "SqlTypeUtil.sameNamedType(argTypes[0], argTypes[1])"); } SqlCollation pickedCollation = null; if (SqlTypeUtil.inCharFamily(argType0)) { if (!SqlTypeUtil.isCharTypeComparable(opBinding.collectOperandTypes().subList(0, 2))) { throw opBinding.newError( RESOURCE.typeNotComparable( argType0.getFullTypeString(), argType1.getFullTypeString())); } pickedCollation = SqlCollation.getCoercibilityDyadicOperator( argType0.getCollation(), argType1.getCollation()); assert null != pickedCollation; } // Determine whether result is variable-length SqlTypeName typeName = argType0.getSqlTypeName(); if (SqlTypeUtil.isBoundedVariableWidth(argType1)) { typeName = argType1.getSqlTypeName(); } RelDataType ret; ret = opBinding .getTypeFactory() .createSqlType(typeName, argType0.getPrecision() + argType1.getPrecision()); if (null != pickedCollation) { RelDataType pickedType; if (argType0.getCollation().equals(pickedCollation)) { pickedType = argType0; } else if (argType1.getCollation().equals(pickedCollation)) { pickedType = argType1; } else { throw Util.newInternal("should never come here"); } ret = opBinding .getTypeFactory() .createTypeWithCharsetAndCollation( ret, pickedType.getCharset(), pickedType.getCollation()); } return ret; }
/** * Resolves a multi-part identifier such as "SCHEMA.EMP.EMPNO" to a namespace. The returned * namespace may represent a schema, table, column, etc. * * @pre names.size() > 0 * @post return != null */ public static SqlValidatorNamespace lookup(SqlValidatorScope scope, List<String> names) { Util.pre(names.size() > 0, "names.size() > 0"); SqlValidatorNamespace namespace = null; for (int i = 0; i < names.size(); i++) { String name = names.get(i); if (i == 0) { namespace = scope.resolve(name, null, null); } else { namespace = namespace.lookupChild(name); } } Util.permAssert(namespace != null, "post: namespace != null"); return namespace; }
public void visit(RelNode rel, int ordinal, RelNode parent) { // REVIEW: SWZ: 1/31/06: We assume that any special RelNodes, such // as the VolcanoPlanner's RelSubset always have a full complement // of traits and that they either appear as registered or do nothing // when childrenAccept is called on them. if (planner.isRegistered(rel)) { return; } RelTraitSet relTraits = rel.getTraitSet(); for (int i = 0; i < baseTraits.size(); i++) { if (i >= relTraits.size()) { // Copy traits that the new rel doesn't know about. Util.discard(RelOptUtil.addTrait(rel, baseTraits.getTrait(i))); // FIXME: Return the new rel. We can no longer traits in-place, // because rels and traits are immutable. throw new AssertionError(); } else { // Verify that the traits are from the same RelTraitDef assert relTraits.getTrait(i).getTraitDef() == baseTraits.getTrait(i).getTraitDef(); } } rel.childrenAccept(this); }
/** * Creates an expression which references correlating variable <code> * correlName</code> from the context of <code>rel</code>. For example, if <code>correlName</code> * is set by the 1st child of <code>rel</code>'s 2nd child, then this method returns <code> * $input2.$input1</code>. */ public Expression makeReference(String correlName, RelNode rel) { JavaFrame frame = (JavaFrame) mapCorrel2Frame.get(correlName); assert (frame != null); assert Util.equal(frame.rel.getCorrelVariable(), correlName); assert (frame.hasVariable()); return frame.getVariable(); }
private void bindDeferred(JavaFrame frame, final RelNode rel) { final StatementList statementList = getStatementList(); if (frame.bind == null) { // this relational expression has not bound itself, so we presume // that we can call its implementSelf() method if (!(rel instanceof JavaSelfRel)) { throw Util.newInternal( "In order to bind-deferred, a " + "relational expression must implement JavaSelfRel: " + rel); } final JavaSelfRel selfRel = (JavaSelfRel) rel; LazyBind lazyBind = new LazyBind( newVariable(), statementList, getTypeFactory(), rel.getRowType(), new VariableInitializerThunk() { public VariableInitializer getInitializer() { return selfRel.implementSelf(JavaRelImplementor.this); } }); bind(rel, lazyBind); } else if ((frame.bind instanceof LazyBind) && (((LazyBind) frame.bind).statementList != statementList)) { // Frame is already bound, but to a variable declared in a different // scope. Re-bind it. final LazyBind lazyBind = (LazyBind) frame.bind; lazyBind.statementList = statementList; lazyBind.bound = false; } }
public Interpreter() { argumentList = new ArrayList(); final Class clazz; try { clazz = Class.forName("sales.SalesInMemoryConnection"); } catch (ClassNotFoundException e) { throw Util.newInternal(e, "Could not create interpreter's default connection"); } try { connection = (RelOptConnection) clazz.newInstance(); } catch (InstantiationException e) { throw Util.newInternal(e, "Could not create interpreter's default connection"); } catch (IllegalAccessException e) { throw Util.newInternal(e, "Could not create interpreter's default connection"); } }
/** Variant of {@link #trimFields(RelNode, BitSet, Set)} for {@link TableFunctionRel}. */ public TrimResult trimFields( TableFunctionRel tabFun, BitSet fieldsUsed, Set<RelDataTypeField> extraFields) { final RelDataType rowType = tabFun.getRowType(); final int fieldCount = rowType.getFieldCount(); List<RelNode> newInputs = new ArrayList<RelNode>(); for (RelNode input : tabFun.getInputs()) { final int inputFieldCount = input.getRowType().getFieldCount(); BitSet inputFieldsUsed = Util.bitSetBetween(0, inputFieldCount); // Create input with trimmed columns. final Set<RelDataTypeField> inputExtraFields = Collections.emptySet(); TrimResult trimResult = trimChildRestore(tabFun, input, inputFieldsUsed, inputExtraFields); assert trimResult.right.isIdentity(); newInputs.add(trimResult.left); } TableFunctionRel newTabFun = tabFun; if (!tabFun.getInputs().equals(newInputs)) { newTabFun = tabFun.copy(tabFun.getTraitSet(), newInputs); } assert newTabFun.getClass() == tabFun.getClass(); // Always project all fields. Mapping mapping = Mappings.createIdentity(fieldCount); return new TrimResult(newTabFun, mapping); }
private ImmutableMap<String, JdbcTable> computeTables() { Connection connection = null; ResultSet resultSet = null; try { connection = dataSource.getConnection(); DatabaseMetaData metaData = connection.getMetaData(); resultSet = metaData.getTables(catalog, schema, null, null); final ImmutableMap.Builder<String, JdbcTable> builder = ImmutableMap.builder(); while (resultSet.next()) { final String tableName = resultSet.getString(3); final String catalogName = resultSet.getString(1); final String schemaName = resultSet.getString(2); final String tableTypeName = resultSet.getString(4); // Clean up table type. In particular, this ensures that 'SYSTEM TABLE', // returned by Phoenix among others, maps to TableType.SYSTEM_TABLE. // We know enum constants are upper-case without spaces, so we can't // make things worse. final String tableTypeName2 = tableTypeName.toUpperCase().replace(' ', '_'); final TableType tableType = Util.enumVal(TableType.class, tableTypeName2); final JdbcTable table = new JdbcTable(this, catalogName, schemaName, tableName, tableType); builder.put(tableName, table); } return builder.build(); } catch (SQLException e) { throw new RuntimeException("Exception while reading tables", e); } finally { close(connection, null, resultSet); } }
// implement BytePointer protected byte[] getBytesForString(String string) { try { return string.getBytes(getCharsetName()); } catch (UnsupportedEncodingException ex) { throw Util.newInternal(ex); } }
private RelOptTableImpl getTableFrom(List<String> names, List<String> schemaNames) { OptiqSchema schema = getSchema(Iterables.concat(schemaNames, Util.skipLast(names))); if (schema == null) { return null; } final String name = Util.last(names); Pair<String, Table> pair = schema.getTable(name, caseSensitive); if (pair == null) { pair = schema.getTableBasedOnNullaryFunction(name, caseSensitive); } if (pair != null) { final Table table = pair.getValue(); final String name2 = pair.getKey(); return RelOptTableImpl.create(this, table.getRowType(typeFactory), schema.add(name2, table)); } return null; }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner) { // Higher cost if rows are wider discourages pushing a project through a // sort. double rowCount = RelMetadataQuery.getRowCount(this); double bytesPerRow = getRowType().getFieldCount() * 4; return planner.getCostFactory().makeCost(Util.nLogN(rowCount) * bytesPerRow, rowCount, 0); }
private Mapping createMapping(BitSet fieldsUsed, int fieldCount) { final Mapping mapping = Mappings.create(MappingType.InverseSurjection, fieldCount, fieldsUsed.cardinality()); int i = 0; for (int field : Util.toIter(fieldsUsed)) { mapping.set(field, i++); } return mapping; }
/** * Creates a JDBC connection. The caller must close it when finished. Fails the test if cannot * create the connection. */ public static Connection getJdbcConnection() { String connectString = Util.getSalesConnectString(); try { return DriverManager.getConnection(connectString); } catch (SQLException e) { fail("received exception [" + e + "] while connecting to [" + connectString + "]"); return null; } }
/** * Finds an aggregate. * * @param node Parse tree to search * @return First aggregate function in parse tree, or null if not found */ public SqlNode findAgg(SqlNode node) { try { node.accept(this); return null; } catch (Util.FoundOne e) { Util.swallow(e, null); return (SqlNode) e.getNode(); } }
private SqlNode createLeftCall(SqlOperator op, List<SqlNode> nodeList) { if (nodeList.size() == 2) { return op.createCall(new SqlNodeList(nodeList, POS)); } final List<SqlNode> butLast = Util.skipLast(nodeList); final SqlNode last = nodeList.get(nodeList.size() - 1); final SqlNode call = createLeftCall(op, butLast); return op.createCall(new SqlNodeList(ImmutableList.of(call, last), POS)); }
/** * Trims unused fields from a relational expression. * * <p>We presume that all fields of the relational expression are wanted by its consumer, so only * trim fields that are not used within the tree. * * @param root Root node of relational expression * @return Trimmed relational expression */ public RelNode trim(RelNode root) { final int fieldCount = root.getRowType().getFieldCount(); final BitSet fieldsUsed = Util.bitSetBetween(0, fieldCount); final Set<RelDataTypeField> extraFields = Collections.emptySet(); final TrimResult trimResult = dispatchTrimFields(root, fieldsUsed, extraFields); if (!trimResult.right.isIdentity()) { throw new IllegalArgumentException(); } return trimResult.left; }
/** Clones a SqlNode with a different position. */ public SqlNode clone(SqlParserPos pos) { // REVIEW jvs 26-July-2006: shouldn't pos be used here? Or are // subclasses always supposed to override, in which case this // method should probably be abstract? try { return (SqlNode) super.clone(); } catch (CloneNotSupportedException e) { throw Util.newInternal(e, "error while cloning " + this); } }
// TODO: preallocate a CharsetDecoder public String toString() { if (buf == null) { return null; } try { return new String(buf, pos, count - pos, getCharsetName()); } catch (UnsupportedEncodingException ex) { throw Util.newInternal(ex); } }
public RelNode convertSqlToRel(String sql) { Util.pre(sql != null, "sql != null"); final SqlNode sqlQuery; try { sqlQuery = parseQuery(sql); } catch (Exception e) { throw Util.newInternal(e); // todo: better handling } final RelDataTypeFactory typeFactory = getTypeFactory(); final Prepare.CatalogReader catalogReader = createCatalogReader(typeFactory); final SqlValidator validator = createValidator(catalogReader, typeFactory); final SqlToRelConverter converter = createSqlToRelConverter(validator, catalogReader, typeFactory); converter.setTrimUnusedFields(true); final SqlNode validatedQuery = validator.validate(sqlQuery); final RelNode rel = converter.convertQuery(validatedQuery, false, true); Util.post(rel != null, "return != null"); return rel; }
/** * Records the fact that instances of <code>rel</code> are available via <code>bind</code> (which * may be eager or lazy). */ private void bind(RelNode rel, Bind bind) { tracer.log(Level.FINE, "Bind " + rel.toString() + " to " + bind); JavaFrame frame = (JavaFrame) mapRel2Frame.get(rel); frame.bind = bind; boolean stupid = SaffronProperties.instance().stupid.get(); if (stupid) { // trigger the declaration of the variable, even though it // may not be used Util.discard(bind.getVariable()); } }
/** Returns whether an array of expressions has any common sub-expressions. */ public static boolean containCommonExprs(RexNode[] exprs, boolean fail) { final ExpressionNormalizer visitor = new ExpressionNormalizer(false); for (int i = 0; i < exprs.length; i++) { try { exprs[i].accept(visitor); } catch (ExpressionNormalizer.SubExprExistsException e) { Util.swallow(e, null); assert !fail; } } return false; }
/** * Variant of {@link #trimFields(RelNode, BitSet, Set)} for {@link * org.eigenbase.rel.TableAccessRel}. */ public TrimResult trimFields( final TableAccessRelBase tableAccessRel, BitSet fieldsUsed, Set<RelDataTypeField> extraFields) { final int fieldCount = tableAccessRel.getRowType().getFieldCount(); if (fieldsUsed.equals(Util.bitSetBetween(0, fieldCount)) && extraFields.isEmpty()) { return trimFields((RelNode) tableAccessRel, fieldsUsed, extraFields); } final RelNode newTableAccessRel = tableAccessRel.project(fieldsUsed, extraFields); final Mapping mapping = createMapping(fieldsUsed, fieldCount); return new TrimResult(newTableAccessRel, mapping); }
private static int find(StatementList list, Statement statement) { if (statement == null) { return 0; } else { for (int i = 0, n = list.size(); i < n; i++) { if (list.get(i) == statement) { return i + 1; } } throw Util.newInternal("could not find statement " + statement + " in list " + list); } }
public boolean matches(RelOptRuleCall call) { JoinRel join = (JoinRel) call.rels[0]; switch (join.getJoinType()) { case INNER: case LEFT: return true; case FULL: case RIGHT: return false; default: throw Util.unexpected(join.getJoinType()); } }
/** * Replaces the operands of a call. The new operands' types must match the old operands' types. */ public static RexCall replaceOperands(RexCall call, RexNode[] operands) { if (call.operands == operands) { return call; } for (int i = 0; i < operands.length; i++) { RelDataType oldType = call.operands[i].getType(); RelDataType newType = operands[i].getType(); if (!oldType.isNullable() && newType.isNullable()) { throw Util.newInternal("invalid nullability"); } assert (oldType.toString().equals(newType.toString())); } return new RexCall(call.getType(), call.getOperator(), operands); }
private Collection<Function> getFunctionsFrom(List<String> names) { final List<Function> functions2 = Lists.newArrayList(); final List<? extends List<String>> schemaNameList; if (names.size() > 1) { // If name is qualified, ignore path. schemaNameList = ImmutableList.of(ImmutableList.<String>of()); } else { OptiqSchema schema = getSchema(defaultSchema); if (schema == null) { schemaNameList = ImmutableList.of(); } else { schemaNameList = schema.getPath(); } } for (List<String> schemaNames : schemaNameList) { OptiqSchema schema = getSchema(Iterables.concat(schemaNames, Util.skipLast(names))); if (schema != null) { final String name = Util.last(names); functions2.addAll(schema.getFunctions(name, true)); } } return functions2; }