예제 #1
0
 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;
 }
예제 #2
0
    @Override
    public RelNode expandView(RelDataType rowType, String queryString) {
      expansionDepth++;

      SqlParser parser = new SqlParser(queryString);
      SqlNode sqlNode;
      try {
        sqlNode = parser.parseQuery();
      } catch (SqlParseException e) {
        throw new RuntimeException("parse failed", e);
      }
      SqlValidator validator = getSqlValidator();
      SqlNode sqlNode1 = validator.validate(sqlNode);

      SqlToRelConverter sqlToRelConverter = getSqlToRelConverter(validator, catalogReader);
      RelNode relNode = sqlToRelConverter.convertQuery(sqlNode1, true, false);

      --expansionDepth;
      return relNode;
    }
예제 #3
0
  public ParseResult parse(Context context, String sql) {
    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);

    SqlParser parser = new SqlParser(sql);
    SqlNode sqlNode;
    try {
      sqlNode = parser.parseQuery();
    } catch (SqlParseException e) {
      throw new RuntimeException("parse failed", e);
    }
    SqlValidator validator =
        new SqlValidatorImpl(
            SqlStdOperatorTable.instance(), catalogReader, typeFactory, SqlConformance.Default) {};
    SqlNode sqlNode1 = validator.validate(sqlNode);
    return new ParseResult(sql, sqlNode1, validator.getValidatedNodeType(sqlNode1));
  }
예제 #4
0
  <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());
  }
예제 #5
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);
        }
      }
    }
  }