public void onMatch(RelOptRuleCall call) {
          JoinRel join = (JoinRel) call.rels[0];
          List<RexNode> expList = new ArrayList<RexNode>(Arrays.asList(join.getChildExps()));
          if (reduceExpressions(join, expList)) {
            call.transformTo(
                new JoinRel(
                    join.getCluster(),
                    join.getLeft(),
                    join.getRight(),
                    expList.get(0),
                    join.getJoinType(),
                    join.getVariablesStopped()));

            // New plan is absolutely better than old plan.
            call.getPlanner().setImportance(join, 0.0);
          }
        }
        public void onMatch(RelOptRuleCall call) {
          ProjectRel project = (ProjectRel) call.rels[0];
          List<RexNode> expList = new ArrayList<RexNode>(Arrays.asList(project.getChildExps()));
          if (reduceExpressions(project, expList)) {
            call.transformTo(
                new ProjectRel(
                    project.getCluster(),
                    project.getChild(),
                    expList.toArray(new RexNode[expList.size()]),
                    project.getRowType(),
                    ProjectRel.Flags.Boxed,
                    Collections.<RelCollation>emptyList()));

            // New plan is absolutely better than old plan.
            call.getPlanner().setImportance(project, 0.0);
          }
        }
        public void onMatch(RelOptRuleCall call) {
          FilterRel filter = (FilterRel) call.rels[0];
          List<RexNode> expList = new ArrayList<RexNode>(Arrays.asList(filter.getChildExps()));
          RexNode newConditionExp;
          boolean reduced;
          if (reduceExpressions(filter, expList)) {
            assert (expList.size() == 1);
            newConditionExp = expList.get(0);
            reduced = true;
          } else {
            // No reduction, but let's still test the original
            // predicate to see if it was already a constant,
            // in which case we don't need any runtime decision
            // about filtering.
            newConditionExp = filter.getChildExps()[0];
            reduced = false;
          }
          if (newConditionExp.isAlwaysTrue()) {
            call.transformTo(filter.getChild());
          } else if ((newConditionExp instanceof RexLiteral)
              || RexUtil.isNullLiteral(newConditionExp, true)) {
            call.transformTo(new EmptyRel(filter.getCluster(), filter.getRowType()));
          } else if (reduced) {
            call.transformTo(CalcRel.createFilter(filter.getChild(), expList.get(0)));
          } else {
            if (newConditionExp instanceof RexCall) {
              RexCall rexCall = (RexCall) newConditionExp;
              boolean reverse = (rexCall.getOperator() == SqlStdOperatorTable.notOperator);
              if (reverse) {
                rexCall = (RexCall) rexCall.getOperands()[0];
              }
              reduceNotNullableFilter(call, filter, rexCall, reverse);
            }
            return;
          }

          // New plan is absolutely better than old plan.
          call.getPlanner().setImportance(filter, 0.0);
        }
コード例 #4
0
ファイル: JdbcImplementor.java プロジェクト: vlsi/optiq
 /**
  * Once you have a Result of implementing a child relational expression, call this method to
  * create a Builder to implement the current relational expression by adding additional clauses
  * to the SQL query.
  *
  * <p>You need to declare which clauses you intend to add. If the clauses are "later", you can
  * add to the same query. For example, "GROUP BY" comes after "WHERE". But if they are the same
  * or earlier, this method will start a new SELECT that wraps the previous result.
  *
  * <p>When you have called {@link Builder#setSelect(org.eigenbase.sql.SqlNodeList)}, {@link
  * Builder#setWhere(org.eigenbase.sql.SqlNode)} etc. call {@link
  * Builder#result(org.eigenbase.sql.SqlNode, java.util.Collection, org.eigenbase.rel.RelNode)}
  * to fix the new query.
  *
  * @param rel Relational expression being implemented
  * @param clauses Clauses that will be generated to implement current relational expression
  * @return A builder
  */
 public Builder builder(JdbcRel rel, Clause... clauses) {
   final Clause maxClause = maxClause();
   boolean needNew = false;
   for (Clause clause : clauses) {
     if (maxClause.ordinal() >= clause.ordinal()) {
       needNew = true;
     }
   }
   SqlSelect select;
   Expressions.FluentList<Clause> clauseList = Expressions.list();
   if (needNew) {
     select = subSelect();
   } else {
     select = asSelect();
     clauseList.addAll(this.clauses);
   }
   clauseList.addAll(Arrays.asList(clauses));
   Context newContext;
   final SqlNodeList selectList = select.getSelectList();
   if (selectList != null) {
     newContext =
         new Context(selectList.size()) {
           @Override
           public SqlNode field(int ordinal) {
             final SqlNode selectItem = selectList.get(ordinal);
             switch (selectItem.getKind()) {
               case AS:
                 return ((SqlCall) selectItem).operand(0);
             }
             return selectItem;
           }
         };
   } else {
     newContext = new AliasContext(aliases, aliases.size() > 1);
   }
   return new Builder(rel, clauseList, select, newContext);
 }
コード例 #5
0
  /** Initializes this catalog reader. */
  protected void init() {
    final RelDataType intType = typeFactory.createSqlType(SqlTypeName.INTEGER);
    final RelDataType varchar10Type = typeFactory.createSqlType(SqlTypeName.VARCHAR, 10);
    final RelDataType varchar20Type = typeFactory.createSqlType(SqlTypeName.VARCHAR, 20);
    final RelDataType timestampType = typeFactory.createSqlType(SqlTypeName.TIMESTAMP);
    final RelDataType booleanType = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
    final RelDataType rectilinearCoordType =
        typeFactory.createStructType(new RelDataType[] {intType, intType}, new String[] {"X", "Y"});

    // TODO jvs 12-Feb-2005: register this canonical instance with type
    // factory
    addressType =
        new ObjectSqlType(
            SqlTypeName.STRUCTURED,
            new SqlIdentifier("ADDRESS", SqlParserPos.ZERO),
            false,
            Arrays.asList(
                new RelDataTypeFieldImpl("STREET", 0, varchar20Type),
                new RelDataTypeFieldImpl("CITY", 1, varchar20Type),
                new RelDataTypeFieldImpl("ZIP", 1, intType),
                new RelDataTypeFieldImpl("STATE", 1, varchar20Type)),
            RelDataTypeComparability.None);

    // Register "SALES" schema.
    MockSchema salesSchema = new MockSchema("SALES");
    registerSchema(salesSchema);

    // Register "EMP" table.
    MockTable empTable = new MockTable(this, salesSchema, "EMP");
    empTable.addColumn("EMPNO", intType);
    empTable.addColumn("ENAME", varchar20Type);
    empTable.addColumn("JOB", varchar10Type);
    empTable.addColumn("MGR", intType);
    empTable.addColumn("HIREDATE", timestampType);
    empTable.addColumn("SAL", intType);
    empTable.addColumn("COMM", intType);
    empTable.addColumn("DEPTNO", intType);
    empTable.addColumn("SLACKER", booleanType);
    registerTable(empTable);

    // Register "DEPT" table.
    MockTable deptTable = new MockTable(this, salesSchema, "DEPT");
    deptTable.addColumn("DEPTNO", intType);
    deptTable.addColumn("NAME", varchar10Type);
    registerTable(deptTable);

    // Register "BONUS" table.
    MockTable bonusTable = new MockTable(this, salesSchema, "BONUS");
    bonusTable.addColumn("ENAME", varchar20Type);
    bonusTable.addColumn("JOB", varchar10Type);
    bonusTable.addColumn("SAL", intType);
    bonusTable.addColumn("COMM", intType);
    registerTable(bonusTable);

    // Register "SALGRADE" table.
    MockTable salgradeTable = new MockTable(this, salesSchema, "SALGRADE");
    salgradeTable.addColumn("GRADE", intType);
    salgradeTable.addColumn("LOSAL", intType);
    salgradeTable.addColumn("HISAL", intType);
    registerTable(salgradeTable);

    // Register "EMP_ADDRESS" table
    MockTable contactAddressTable = new MockTable(this, salesSchema, "EMP_ADDRESS");
    contactAddressTable.addColumn("EMPNO", intType);
    contactAddressTable.addColumn("HOME_ADDRESS", addressType);
    contactAddressTable.addColumn("MAILING_ADDRESS", addressType);
    registerTable(contactAddressTable);

    // Register "CUSTOMER" schema.
    MockSchema customerSchema = new MockSchema("CUSTOMER");
    registerSchema(customerSchema);

    // Register "CONTACT" table.
    MockTable contactTable = new MockTable(this, customerSchema, "CONTACT");
    contactTable.addColumn("CONTACTNO", intType);
    contactTable.addColumn("FNAME", varchar10Type);
    contactTable.addColumn("LNAME", varchar10Type);
    contactTable.addColumn("EMAIL", varchar20Type);
    contactTable.addColumn("COORD", rectilinearCoordType);
    registerTable(contactTable);

    // Register "ACCOUNT" table.
    MockTable accountTable = new MockTable(this, customerSchema, "ACCOUNT");
    accountTable.addColumn("ACCTNO", intType);
    accountTable.addColumn("TYPE", varchar20Type);
    accountTable.addColumn("BALANCE", intType);
    registerTable(accountTable);
  }
コード例 #6
0
ファイル: OptiqPrepareImpl.java プロジェクト: cwensel/optiq
  <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());
  }
コード例 #7
0
ファイル: OptiqPrepareImpl.java プロジェクト: cwensel/optiq
 private RexNode binary(Expression expression, SqlBinaryOperator op) {
   BinaryExpression call = (BinaryExpression) expression;
   return rexBuilder.makeCall(op, toRex(Arrays.asList(call.expression0, call.expression1)));
 }