コード例 #1
0
ファイル: AggFinder.java プロジェクト: richwhitjr/optiq
 public Void visit(SqlCall call) {
   final SqlOperator operator = call.getOperator();
   if (operator.isAggregator()) {
     throw new Util.FoundOne(call);
   }
   // User-defined function may not be resolved yet.
   if (operator instanceof SqlFunction
       && ((SqlFunction) operator).getFunctionType()
           == SqlFunctionCategory.USER_DEFINED_FUNCTION) {
     final List<SqlOperator> list = Lists.newArrayList();
     opTab.lookupOperatorOverloads(
         ((SqlFunction) operator).getSqlIdentifier(),
         SqlFunctionCategory.USER_DEFINED_FUNCTION,
         SqlSyntax.FUNCTION,
         list);
     for (SqlOperator sqlOperator : list) {
       if (sqlOperator.isAggregator()) {
         throw new Util.FoundOne(call);
       }
     }
   }
   if (call.isA(SqlKind.QUERY)) {
     // don't traverse into queries
     return null;
   }
   if (call.getKind() == SqlKind.OVER) {
     if (over) {
       throw new Util.FoundOne(call);
     } else {
       // an aggregate function over a window is not an aggregate!
       return null;
     }
   }
   return super.visit(call);
 }
コード例 #2
0
 public void unparse(SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) {
   final SqlWriter.Frame frame = writer.startFunCall(getName());
   call.operand(0).unparse(writer, leftPrec, rightPrec);
   writer.sep("FROM");
   call.operand(1).unparse(writer, leftPrec, rightPrec);
   writer.endFunCall(frame);
 }
コード例 #3
0
  public SqlRexConvertlet get(SqlCall call) {
    SqlRexConvertlet convertlet;
    final SqlOperator op = call.getOperator();

    // Is there a convertlet for this operator
    // (e.g. SqlStdOperatorTable.plusOperator)?
    convertlet = (SqlRexConvertlet) map.get(op);
    if (convertlet != null) {
      return convertlet;
    }

    // Is there a convertlet for this class of operator
    // (e.g. SqlBinaryOperator)?
    Class<? extends Object> clazz = op.getClass();
    while (clazz != null) {
      convertlet = (SqlRexConvertlet) map.get(clazz);
      if (convertlet != null) {
        return convertlet;
      }
      clazz = clazz.getSuperclass();
    }

    // Is there a convertlet for this class of expression
    // (e.g. SqlCall)?
    clazz = call.getClass();
    while (clazz != null) {
      convertlet = (SqlRexConvertlet) map.get(clazz);
      if (convertlet != null) {
        return convertlet;
      }
      clazz = clazz.getSuperclass();
    }
    return null;
  }
 public Void visit(SqlCall call) {
   final SqlOperator operator = call.getOperator();
   if (operator == SqlStdOperatorTable.andOperator) {
     throw new Found();
   }
   return super.visit(call);
 }
コード例 #5
0
 /**
  * Constructs a FarragoReentrantSubquery.
  *
  * @param subq the subquery to evaluate
  * @param parentConverter sqlToRelConverter associated with the parent query
  * @param isExists whether the subquery is part of an EXISTS expression
  * @param isExplain whether the subquery is part of an EXPLAIN PLAN statement
  * @param results the resulting evaluated expressions
  */
 FarragoReentrantSubquery(
     SqlCall subq,
     SqlToRelConverter parentConverter,
     boolean isExists,
     boolean isExplain,
     List<RexNode> results) {
   super(
       FennelRelUtil.getPreparingStmt(parentConverter.getCluster()).getRootStmtContext(),
       parentConverter.getRexBuilder(),
       results);
   FarragoSessionStmtContext rootContext = getRootStmtContext();
   if (rootContext != null) {
     rootContext.setSaveFirstTxnCsn();
   }
   if (!isExists) {
     assert subq.getKind() == SqlKind.SCALAR_QUERY;
   }
   this.subq = subq;
   this.parentConverter = parentConverter;
   this.isExists = isExists;
   this.isExplain = isExplain;
 }
コード例 #6
0
 public SqlMonotonicity getMonotonicity(SqlCall call, SqlValidatorScope scope) {
   return scope.getMonotonicity(call.operand(0)).unstrict();
 }
コード例 #7
0
ファイル: SqlValidatorUtil.java プロジェクト: jacques-n/optiq
 // Override to copy all arguments regardless of whether visitor changes
 // them.
 protected SqlNode visitScoped(SqlCall call) {
   ArgHandler<SqlNode> argHandler = new CallCopyingArgHandler(call, true);
   call.getOperator().acceptCall(this, call, false, argHandler);
   return argHandler.result();
 }
コード例 #8
0
  protected void executeImpl() throws Exception {
    SqlCall call = (SqlCall) subq;
    SqlSelect select = (SqlSelect) call.getOperands()[0];

    // Convert the SqlNode tree to a RelNode tree; we need to do this
    // here so the RelNode tree is associated with the new preparing
    // stmt.
    FarragoPreparingStmt preparingStmt = (FarragoPreparingStmt) getPreparingStmt();
    SqlValidator validator = preparingStmt.getSqlValidator();
    SqlToRelConverter sqlConverter = preparingStmt.getSqlToRelConverter(validator, preparingStmt);
    preparingStmt.setParentStmt(FennelRelUtil.getPreparingStmt(parentConverter.getCluster()));

    // Add to the new converter any subqueries that have already been
    // converted by the parent so we can avoid re-executing them
    sqlConverter.addConvertedNonCorrSubqs(parentConverter.getMapConvertedNonCorrSubqs());
    RelNode plan = sqlConverter.convertQuery(select, true, true);

    // The subquery cannot have dynamic parameters
    if (sqlConverter.getDynamicParamCount() > 0) {
      failed = true;
      return;
    }

    List<RexNode> exprs = new ArrayList<RexNode>();
    RelDataType resultType = null;

    if (!isExists) {
      // Non-EXISTS subqueries need to be converted to single-value
      // subqueries
      plan = sqlConverter.convertToSingleValueSubq(select, plan);

      // Create a dummy expression to store the type of the result.
      // When setting the type, derive the type based on what a
      // scalar subquery should return and create the type from the
      // type factory of the parent query.
      resultType = call.getOperator().deriveType(validator, validator.getFromScope(select), call);
      resultType = rexBuilder.getTypeFactory().copyType(resultType);
      exprs.add(rexBuilder.makeInputRef(resultType, 0));
    }

    plan = sqlConverter.decorrelate(select, plan);

    // If the subquery is part of an EXPLAIN PLAN statement, don't
    // execute the subquery, but instead just return a dynamic parameter
    // as a placeholder for the subquery result.  Otherwise, execute
    // the query to produce the constant expression.  Cast the expression
    // as needed so the type matches the expected result type.
    RexNode constExpr;
    if (isExplain) {
      if (isExists) {
        resultType = rexBuilder.getTypeFactory().createSqlType(SqlTypeName.BOOLEAN);
      }
      constExpr =
          rexBuilder.makeDynamicParam(
              resultType, parentConverter.getDynamicParamCountInExplain(true));
      results.add(constExpr);
    } else {
      executePlan(plan, exprs, isExists, false);
      if (!failed && !isExists) {
        constExpr = results.get(0);
        if (constExpr.getType() != resultType) {
          constExpr = rexBuilder.makeCast(resultType, constExpr);
          results.set(0, constExpr);
        }
      }
    }
  }