コード例 #1
0
ファイル: RelFieldTrimmer.java プロジェクト: juhoautio/optiq
  /** 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);
  }
    /**
     * Casts the rhs to an {@link AssignableValue} using that interface's standard assignment
     * method. i.e.
     *
     * <pre>
     * [AssignableValueType] lhs;
     * lhs.[assignMethod](rhs);
     * </pre>
     *
     * or perhaps a type-specific cast:
     *
     * <pre>
     * [AssignableValueType] lhs;
     * lhs.[castMethod](rhs, lhs.getPrecision());
     * </pre>
     *
     * <p>Code is also generated to pad and truncate values which need special handling, such as
     * date and time types. Plus good old null handling.
     */
    private Expression castToAssignableValue() {
      ensureLhs();

      if (requiresSpecializedCast() && rhsType.isNullable()) {
        assert (lhsType.isNullable());

        // propagate null value; normally, we can rely on
        // assignFrom to do it for us, but for specialized casts,
        // we can't
        Expression nullTest =
            new MethodCall(rhsExp, NullableValue.NULL_IND_ACCESSOR_NAME, new ExpressionList());
        addStatement(
            new ExpressionStatement(
                new MethodCall(
                    lhsExp, NullableValue.NULL_IND_MUTATOR_NAME, new ExpressionList(nullTest))));
        StatementList ifStmtList = new StatementList();
        addStatement(new IfStatement(not(nullTest), ifStmtList));
        borrowStmtList(ifStmtList);
        try {
          return castToAssignableValueImpl();
        } finally {
          returnStmtList(ifStmtList);
        }
      } else {
        return castToAssignableValueImpl();
      }
    }
コード例 #3
0
ファイル: RelFieldTrimmer.java プロジェクト: juhoautio/optiq
  /** 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);
  }
コード例 #4
0
ファイル: OptiqPrepareImpl.java プロジェクト: cwensel/optiq
    public PreparedResult prepareQueryable(Queryable queryable, RelDataType resultType) {
      queryString = null;
      Class runtimeContextClass = Object.class;
      final Argument[] arguments = {new Argument(connectionVariable, runtimeContextClass, null)};
      ClassDeclaration decl = init(arguments);

      final RelOptQuery query = new RelOptQuery(planner);
      final RelOptCluster cluster =
          query.createCluster(env, rexBuilder.getTypeFactory(), rexBuilder);

      RelNode rootRel = new LixToRelTranslator(cluster).translate(queryable);

      if (timingTracer != null) {
        timingTracer.traceTime("end sql2rel");
      }

      final RelDataType jdbcType = makeStruct(rexBuilder.getTypeFactory(), resultType);
      fieldOrigins = Collections.nCopies(jdbcType.getFieldCount(), null);

      // Structured type flattening, view expansion, and plugging in
      // physical storage.
      rootRel = flattenTypes(rootRel, true);

      // Trim unused fields.
      rootRel = trimUnusedFields(rootRel);

      rootRel = optimize(resultType, rootRel);
      containsJava = treeContainsJava(rootRel);

      if (timingTracer != null) {
        timingTracer.traceTime("end optimization");
      }

      return implement(resultType, rootRel, SqlKind.SELECT, decl, arguments);
    }
コード例 #5
0
ファイル: RelFieldTrimmer.java プロジェクト: juhoautio/optiq
  /** Variant of {@link #trimFields(RelNode, BitSet, Set)} for {@link SortRel}. */
  public TrimResult trimFields(SortRel sort, BitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final RelDataType rowType = sort.getRowType();
    final int fieldCount = rowType.getFieldCount();
    final RelCollation collation = sort.getCollation();
    final RelNode input = sort.getChild();

    // We use the fields used by the consumer, plus any fields used as sort
    // keys.
    BitSet inputFieldsUsed = (BitSet) fieldsUsed.clone();
    for (RelFieldCollation field : collation.getFieldCollations()) {
      inputFieldsUsed.set(field.getFieldIndex());
    }

    // Create input with trimmed columns.
    final Set<RelDataTypeField> inputExtraFields = Collections.emptySet();
    TrimResult trimResult = trimChild(sort, input, inputFieldsUsed, inputExtraFields);
    RelNode newInput = trimResult.left;
    final Mapping inputMapping = trimResult.right;

    // If the input is unchanged, and we need to project all columns,
    // there's nothing we can do.
    if (newInput == input && inputMapping.isIdentity() && fieldsUsed.cardinality() == fieldCount) {
      return new TrimResult(sort, Mappings.createIdentity(fieldCount));
    }

    final SortRel newSort =
        sort.copy(sort.getTraitSet(), newInput, RexUtil.apply(inputMapping, collation));
    assert newSort.getClass() == sort.getClass();

    // The result has the same mapping as the input gave us. Sometimes we
    // return fields that the consumer didn't ask for, because the filter
    // needs them for its condition.
    return new TrimResult(newSort, inputMapping);
  }
コード例 #6
0
 public int getFieldJdbcType(int fieldOrdinal) {
   RelDataType type = getFieldNamedType(fieldOrdinal);
   SqlTypeName typeName = type.getSqlTypeName();
   if (typeName == null) {
     return Types.OTHER;
   }
   return typeName.getJdbcOrdinal();
 }
  /**
   * Creates projection list for scan. If the projection contains expressions, then the input
   * references from those expressions are extracted and that list of references becomes the
   * projection list.
   *
   * @param origScan row scan underneath the project
   * @param projRel ProjectRel that we will be creating the projection for
   * @param projectedColumns returns a list of the projected column ordinals, if it is possible to
   *     project
   * @param preserveExprCondition condition that identifies special expressions that should be
   *     preserved in the projection
   * @param defaultExpr expression to be used in the projection if no fields or special columns are
   *     selected
   * @param newProjList returns a new projection RelNode corresponding to a projection that now
   *     references a rowscan that is projecting the input references that were extracted from the
   *     original projection expressions; if the original expression didn't contain expressions,
   *     then this list is returned empty
   * @return true if columns in projection list from the scan need to be renamed
   */
  public boolean createProjectionList(
      FennelRel origScan,
      ProjectRel projRel,
      List<Integer> projectedColumns,
      PushProjector.ExprCondition preserveExprCondition,
      RexNode defaultExpr,
      List<ProjectRel> newProjList) {
    // REVIEW:  what about AnonFields?
    int n = projRel.getChildExps().length;
    RelDataType rowType = origScan.getRowType();
    RelDataType projType = projRel.getRowType();
    RelDataTypeField[] projFields = projType.getFields();
    List<Integer> tempProjList = new ArrayList<Integer>();
    boolean needRename = false;
    for (int i = 0; i < n; ++i) {
      RexNode exp = projRel.getChildExps()[i];
      List<String> origFieldName = new ArrayList<String>();
      Integer projIndex = mapProjCol(exp, origFieldName, rowType);
      if (projIndex == null) {
        // there are expressions in the projection; we need to extract
        // all input references and any special expressions from the
        // projection
        PushProjector pushProject =
            new PushProjector(projRel, null, origScan, preserveExprCondition);
        ProjectRel newProject = pushProject.convertProject(defaultExpr);
        if (newProject == null) {
          // can't do any further projection
          return false;
        }
        newProjList.add(newProject);

        // using the input references we just extracted, it should now
        // be possible to create a projection for the row scan
        needRename =
            createProjectionList(
                origScan,
                (ProjectRel) newProject.getChild(),
                projectedColumns,
                preserveExprCondition,
                defaultExpr,
                newProjList);
        assert (projectedColumns.size() > 0);
        return needRename;
      }
      String projFieldName = projFields[i].getName();
      if (!projFieldName.equals(origFieldName.get(0))) {
        needRename = true;
      }
      tempProjList.add(projIndex);
    }

    // now that we've determined it is possible to project, add the
    // ordinals to the return list
    projectedColumns.addAll(tempProjList);
    return needRename;
  }
コード例 #8
0
ファイル: IterCalcRel.java プロジェクト: Jach/luciddb
 /**
  * Burrows into a synthetic record and returns the underlying relation which provides the field
  * called <code>fieldName</code>.
  */
 public JavaRel implementFieldAccess(JavaRelImplementor implementor, String fieldName) {
   if (!isBoxed()) {
     return implementor.implementFieldAccess((JavaRel) getChild(), fieldName);
   }
   RelDataType type = getRowType();
   int field = type.getFieldOrdinal(fieldName);
   RexLocalRef ref = program.getProjectList().get(field);
   final int index = ref.getIndex();
   return implementor.findRel((JavaRel) this, program.getExprList().get(index));
 }
コード例 #9
0
 public RelDataType getFieldType(int fieldOrdinal) {
   RelDataType namedType = getFieldNamedType(fieldOrdinal);
   if (namedType.getSqlTypeName() == SqlTypeName.DISTINCT) {
     // for most metadata calls, report information about the
     // predefined type on which the distinct type is based
     return namedType.getFields()[0].getType();
   } else {
     return namedType;
   }
 }
 /**
  * Gets the right hand expression as a valid value to be assigned to the left hand side. Usually
  * returns the original rhs. However, if the lhs is of a primitive type, and the rhs is an
  * explicit null, returns a primitive value instead.
  */
 private Expression rhsAsValue() {
   if (SqlTypeUtil.isJavaPrimitive(lhsType) && (rhsType.getSqlTypeName() == SqlTypeName.NULL)) {
     if (lhsType.getSqlTypeName() == SqlTypeName.BOOLEAN) {
       return Literal.constantFalse();
     } else {
       return Literal.constantZero();
     }
   }
   return rhsExp;
 }
コード例 #11
0
ファイル: ReturnTypes.java プロジェクト: richwhitjr/optiq
 public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
   assert opBinding.getOperandCount() == 1;
   final RelDataType multisetType = opBinding.getOperandType(0);
   RelDataType componentType = multisetType.getComponentType();
   assert componentType != null : "expected a multiset type: " + multisetType;
   final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
   final RelDataType type =
       typeFactory.builder().add(SqlUtil.deriveAliasFromOrdinal(0), componentType).build();
   return typeFactory.createMultisetType(type, -1);
 }
コード例 #12
0
ファイル: ReturnTypes.java プロジェクト: richwhitjr/optiq
 public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
   assert opBinding.getOperandCount() == 1;
   final RelDataType recordMultisetType = opBinding.getOperandType(0);
   RelDataType multisetType = recordMultisetType.getComponentType();
   assert multisetType != null : "expected a multiset type: " + recordMultisetType;
   final List<RelDataTypeField> fields = multisetType.getFieldList();
   assert fields.size() > 0;
   final RelDataType firstColType = fields.get(0).getType();
   return opBinding.getTypeFactory().createMultisetType(firstColType, -1);
 }
コード例 #13
0
ファイル: RelFieldTrimmer.java プロジェクト: juhoautio/optiq
  /**
   * Variant of {@link #trimFields(RelNode, BitSet, Set)} for {@link SetOpRel} (including UNION and
   * UNION ALL).
   */
  public TrimResult trimFields(
      SetOpRel setOp, BitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final RelDataType rowType = setOp.getRowType();
    final int fieldCount = rowType.getFieldCount();
    int changeCount = 0;

    // Fennel abhors an empty row type, so pretend that the parent rel
    // wants the last field. (The last field is the least likely to be a
    // system field.)
    if (fieldsUsed.isEmpty()) {
      fieldsUsed.set(rowType.getFieldCount() - 1);
    }

    // Compute the desired field mapping. Give the consumer the fields they
    // want, in the order that they appear in the bitset.
    final Mapping mapping = createMapping(fieldsUsed, fieldCount);

    // Create input with trimmed columns.
    final List<RelNode> newInputs = new ArrayList<RelNode>();
    for (RelNode input : setOp.getInputs()) {
      TrimResult trimResult = trimChild(setOp, input, fieldsUsed, extraFields);
      RelNode newInput = trimResult.left;
      final Mapping inputMapping = trimResult.right;

      // We want "mapping", the input gave us "inputMapping", compute
      // "remaining" mapping.
      //    |                   |                |
      //    |---------------- mapping ---------->|
      //    |-- inputMapping -->|                |
      //    |                   |-- remaining -->|
      //
      // For instance, suppose we have columns [a, b, c, d],
      // the consumer asked for mapping = [b, d],
      // and the transformed input has columns inputMapping = [d, a, b].
      // remaining will permute [b, d] to [d, a, b].
      Mapping remaining = Mappings.divide(mapping, inputMapping);

      // Create a projection; does nothing if remaining is identity.
      newInput = CalcRel.projectMapping(newInput, remaining, null);

      if (input != newInput) {
        ++changeCount;
      }
      newInputs.add(newInput);
    }

    // If the input is unchanged, and we need to project all columns,
    // there's to do.
    if (changeCount == 0 && mapping.isIdentity()) {
      return new TrimResult(setOp, mapping);
    }

    RelNode newSetOp = setOp.copy(setOp.getTraitSet(), newInputs);
    return new TrimResult(newSetOp, mapping);
  }
 /** Generates code to throw an exception when a NULL value is casted to a NOT NULL type */
 private void checkNotNull() {
   if (!lhsType.isNullable() && rhsType.isNullable()) {
     rhsExp = rhsAsJava();
     addStatement(
         new ExpressionStatement(
             new MethodCall(
                 translator.getRelImplementor().getConnectionVariable(),
                 "checkNotNull",
                 new ExpressionList(Literal.makeLiteral(targetName), rhsExp))));
   }
 }
コード例 #15
0
ファイル: RexUtil.java プロジェクト: kunlqt/optiq
 /**
  * Generates a cast from one row type to another
  *
  * @param rexBuilder RexBuilder to use for constructing casts
  * @param lhsRowType target row type
  * @param rhsRowType source row type; fields must be 1-to-1 with lhsRowType, in same order
  * @return cast expressions
  */
 public static RexNode[] generateCastExpressions(
     RexBuilder rexBuilder, RelDataType lhsRowType, RelDataType rhsRowType) {
   int n = rhsRowType.getFieldCount();
   assert n == lhsRowType.getFieldCount()
       : "field count: lhs [" + lhsRowType + "] rhs [" + rhsRowType + "]";
   RexNode[] rhsExps = new RexNode[n];
   for (int i = 0; i < n; ++i) {
     rhsExps[i] = rexBuilder.makeInputRef(rhsRowType.getFields()[i].getType(), i);
   }
   return generateCastExpressions(rexBuilder, lhsRowType, rhsExps);
 }
コード例 #16
0
 public int getFieldScale(int fieldOrdinal) {
   RelDataType type = getFieldType(fieldOrdinal);
   SqlTypeName typeName = type.getSqlTypeName();
   if (typeName == null) {
     return 0;
   }
   if (typeName.allowsPrecScale(true, true)) {
     return type.getScale();
   } else {
     return 0;
   }
 }
コード例 #17
0
 /**
  * Creates an expression which references the <i> fieldOrdinal</i><sup>th</sup> field of the
  * <i>ordinal</i><sup>th</sup> input.
  *
  * <p>(We can potentially optimize the generation process, so we can access field values without
  * actually instantiating the row.)
  */
 public Expression translateInputField(JavaRel rel, int ordinal, int fieldOrdinal) {
   assert ordinal >= 0;
   assert ordinal < rel.getInputs().size();
   assert fieldOrdinal >= 0;
   assert fieldOrdinal < rel.getInput(ordinal).getRowType().getFieldList().size();
   RelDataType rowType = rel.getRowType();
   final RelDataTypeField[] fields = rowType.getFields();
   final int fieldIndex = computeFieldOffset(rel, ordinal) + fieldOrdinal;
   assert fieldIndex >= 0;
   assert fieldIndex < fields.length;
   final RexNode expr = rexBuilder.makeInputRef(fields[fieldIndex].getType(), fieldIndex);
   return translate(rel, expr);
 }
コード例 #18
0
ファイル: SqlValidatorUtil.java プロジェクト: jacques-n/optiq
 /**
  * Derives the list of column names suitable for NATURAL JOIN. These are the columns that occur
  * exactly once on each side of the join.
  *
  * @param leftRowType Row type of left input to the join
  * @param rightRowType Row type of right input to the join
  * @return List of columns that occur once on each side
  */
 public static List<String> deriveNaturalJoinColumnList(
     RelDataType leftRowType, RelDataType rightRowType) {
   List<String> naturalColumnNames = new ArrayList<String>();
   final List<String> leftNames = leftRowType.getFieldNames();
   final List<String> rightNames = rightRowType.getFieldNames();
   for (String name : leftNames) {
     if ((Collections.frequency(leftNames, name) == 1)
         && (Collections.frequency(rightNames, name) == 1)) {
       naturalColumnNames.add(name);
     }
   }
   return naturalColumnNames;
 }
コード例 #19
0
ファイル: JdbcImplementor.java プロジェクト: vlsi/optiq
 private SqlNode toSql(RelDataType type) {
   if (dialect.getDatabaseProduct() == SqlDialect.DatabaseProduct.MYSQL) {
     final SqlTypeName sqlTypeName = type.getSqlTypeName();
     switch (sqlTypeName) {
       case VARCHAR:
         // MySQL doesn't have a VARCHAR type, only CHAR.
         return new SqlDataTypeSpec(
             new SqlIdentifier("CHAR", POS), type.getPrecision(), -1, null, null, POS);
       case INTEGER:
         return new SqlDataTypeSpec(
             new SqlIdentifier("_UNSIGNED", POS), type.getPrecision(), -1, null, null, POS);
     }
   }
   if (type instanceof BasicSqlType) {
     return new SqlDataTypeSpec(
         new SqlIdentifier(type.getSqlTypeName().name(), POS),
         type.getPrecision(),
         type.getScale(),
         type.getCharset() != null && dialect.supportsCharSet()
             ? type.getCharset().name()
             : null,
         null,
         POS);
   }
   throw new AssertionError(type); // TODO: implement
 }
コード例 #20
0
  public Boolean areColumnsUnique(ProjectRelBase rel, BitSet columns, boolean ignoreNulls) {
    // ProjectRel maps a set of rows to a different set;
    // Without knowledge of the mapping function(whether it
    // preserves uniqueness), it is only safe to derive uniqueness
    // info from the child of a project when the mapping is f(a) => a.
    //
    // Also need to map the input column set to the corresponding child
    // references

    List<RexNode> projExprs = rel.getProjects();
    BitSet childColumns = new BitSet();
    for (int bit : BitSets.toIter(columns)) {
      RexNode projExpr = projExprs.get(bit);
      if (projExpr instanceof RexInputRef) {
        childColumns.set(((RexInputRef) projExpr).getIndex());
      } else if (projExpr instanceof RexCall && ignoreNulls) {
        // If the expression is a cast such that the types are the same
        // except for the nullability, then if we're ignoring nulls,
        // it doesn't matter whether the underlying column reference
        // is nullable.  Check that the types are the same by making a
        // nullable copy of both types and then comparing them.
        RexCall call = (RexCall) projExpr;
        if (call.getOperator() != SqlStdOperatorTable.CAST) {
          continue;
        }
        RexNode castOperand = call.getOperands().get(0);
        if (!(castOperand instanceof RexInputRef)) {
          continue;
        }
        RelDataTypeFactory typeFactory = rel.getCluster().getTypeFactory();
        RelDataType castType = typeFactory.createTypeWithNullability(projExpr.getType(), true);
        RelDataType origType = typeFactory.createTypeWithNullability(castOperand.getType(), true);
        if (castType.equals(origType)) {
          childColumns.set(((RexInputRef) castOperand).getIndex());
        }
      } else {
        // If the expression will not influence uniqueness of the
        // projection, then skip it.
        continue;
      }
    }

    // If no columns can affect uniqueness, then return unknown
    if (childColumns.cardinality() == 0) {
      return null;
    }

    return RelMetadataQuery.areColumnsUnique(rel.getChild(), childColumns, ignoreNulls);
  }
コード例 #21
0
ファイル: ReturnTypes.java プロジェクト: richwhitjr/optiq
        public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
          assert opBinding.getOperandCount() == 1;

          final RelDataType recordType = opBinding.getOperandType(0);

          boolean isStruct = recordType.isStruct();
          int fieldCount = recordType.getFieldCount();

          assert isStruct && (fieldCount == 1);

          RelDataTypeField fieldType = recordType.getFieldList().get(0);
          assert fieldType != null : "expected a record type with one field: " + recordType;
          final RelDataType firstColType = fieldType.getType();
          return opBinding.getTypeFactory().createTypeWithNullability(firstColType, true);
        }
コード例 #22
0
ファイル: SqlValidatorUtil.java プロジェクト: jacques-n/optiq
 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);
 }
    /**
     * Implements a cast from any Java primitive to a nullable Java primitive as a simple
     * assignment. i.e.
     *
     * <pre>
     * [NullablePrimitiveType] lhs;
     * lhs.[nullIndicator] = ...;
     * if (! lhs.[nullIndicator]) {
     *     // check overflow ...
     *     // round ...
     *     lhs.[value] = ...;
     * }
     * </pre>
     */
    private Expression castPrimitiveToNullablePrimitive() {
      ensureLhs();
      boolean nullableSource = rhsType.isNullable();
      Expression rhsIsNull;
      if (nullableSource) {
        rhsIsNull = getNullIndicator(rhsExp);
        rhsExp = getValue(rhsType, rhsExp);
      } else {
        rhsIsNull = Literal.constantFalse();
      }

      addStatement(assign(getNullIndicator(lhsExp), rhsIsNull));
      StatementList setValueBlock = new StatementList();
      StatementList oldList = borrowStmtList(setValueBlock);
      try {
        checkOverflow();
        roundAsNeeded();
        addStatement(assign(getValue(lhsType, lhsExp), new CastExpression(getLhsClass(), rhsExp)));
      } finally {
        returnStmtList(oldList);
      }
      if (nullableSource) {
        addStatement(new IfStatement(not(getNullIndicator(lhsExp)), setValueBlock));
      } else {
        addStatementList(setValueBlock);
      }
      return lhsExp;
    }
コード例 #24
0
ファイル: RexUtil.java プロジェクト: kunlqt/optiq
 public Void visitInputRef(RexInputRef inputRef) {
   super.visitInputRef(inputRef);
   if (inputRef.getIndex() >= inputRowType.getFieldCount()) {
     throw new IllegalForwardRefException();
   }
   return null;
 }
コード例 #25
0
 public String getFieldTypeName(int fieldOrdinal) {
   RelDataType type = getFieldNamedType(fieldOrdinal);
   SqlTypeName typeName = type.getSqlTypeName();
   if (typeName == null) {
     return type.toString();
   }
   switch (typeName) {
     case STRUCTURED:
     case DISTINCT:
       return type.getSqlIdentifier().toString();
     case INTERVAL_DAY_TIME:
     case INTERVAL_YEAR_MONTH:
       return type.toString();
   }
   return typeName.name();
 }
コード例 #26
0
 public RelDataType getNamedType(SqlIdentifier typeName) {
   if (typeName.equalsDeep(addressType.getSqlIdentifier(), false)) {
     return addressType;
   } else {
     return null;
   }
 }
コード例 #27
0
ファイル: ReturnTypes.java プロジェクト: richwhitjr/optiq
 public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
   RelDataType type1 = opBinding.getOperandType(0);
   if (SqlTypeUtil.isDecimal(type1)) {
     if (type1.getScale() == 0) {
       return type1;
     } else {
       int p = type1.getPrecision();
       RelDataType ret;
       ret = opBinding.getTypeFactory().createSqlType(SqlTypeName.DECIMAL, p, 0);
       if (type1.isNullable()) {
         ret = opBinding.getTypeFactory().createTypeWithNullability(ret, true);
       }
       return ret;
     }
   }
   return null;
 }
コード例 #28
0
ファイル: RexUtil.java プロジェクト: kunlqt/optiq
 /** Creates an array of {@link RexLocalRef} objects, one for each field of a given rowtype. */
 public static RexLocalRef[] toLocalRefs(RelDataType rowType) {
   final RelDataTypeField[] fields = rowType.getFields();
   final RexLocalRef[] refs = new RexLocalRef[fields.length];
   for (int i = 0; i < refs.length; i++) {
     refs[i] = new RexLocalRef(i, fields[i].getType());
   }
   return refs;
 }
コード例 #29
0
 /**
  * Creates a FarragoJdbcMetaDataImpl.
  *
  * @param rowType Type info to return
  * @param fieldOrigins Origin of each field in column of catalog object
  */
 protected FarragoJdbcMetaDataImpl(RelDataType rowType, List<List<String>> fieldOrigins) {
   this.rowType = rowType;
   this.fieldOrigins = fieldOrigins;
   assert rowType != null;
   assert fieldOrigins != null;
   assert fieldOrigins.size() == rowType.getFieldCount()
       : "field origins " + fieldOrigins + " have different count than row type " + rowType;
 }
    /**
     * Checks for overflow when assigning one primitive type to another. Non-primitive types check
     * for overflow during assignment.
     */
    private void checkOverflow() {
      String maxLiteral = null;
      String minLiteral = null;
      if (lhsType == null) {
        return;
      }

      // Assume that equivalent types can be assigned without overflow
      if (lhsType.getSqlTypeName() == rhsType.getSqlTypeName()) {
        return;
      }

      // Approximate numerics have a wider range than exact numerics
      if (SqlTypeUtil.isApproximateNumeric(lhsType) && SqlTypeUtil.isExactNumeric(rhsType)) {
        return;
      }

      // We can skip an error check if the left type is "larger"
      if (SqlTypeUtil.isIntType(lhsType)
          && SqlTypeUtil.isIntType(rhsType)
          && (SqlTypeUtil.maxValue(lhsType) >= SqlTypeUtil.maxValue(rhsType))) {
        return;
      }
      if (SqlTypeUtil.isExactNumeric(lhsType)) {
        String numClassName = SqlTypeUtil.getNumericJavaClassName(lhsType);
        minLiteral = numClassName + ".MIN_VALUE";
        maxLiteral = numClassName + ".MAX_VALUE";
      } else if (SqlTypeUtil.isApproximateNumeric(lhsType)) {
        String numClassName = SqlTypeUtil.getNumericJavaClassName(lhsType);
        maxLiteral = numClassName + ".MAX_VALUE";
        minLiteral = "-" + maxLiteral;
      }
      if (maxLiteral == null) {
        return;
      }
      Statement ifstmt =
          new IfStatement(
              new BinaryExpression(
                  new BinaryExpression(
                      rhsExp, BinaryExpression.LESS, new Literal(Literal.STRING, minLiteral)),
                  BinaryExpression.LOGICAL_OR,
                  new BinaryExpression(
                      rhsExp, BinaryExpression.GREATER, new Literal(Literal.STRING, maxLiteral))),
              getThrowStmtList());
      addStatement(ifstmt);
    }