Java Code Examples for org.apache.calcite.linq4j.tree.Expressions#FluentList

The following examples show how to use org.apache.calcite.linq4j.tree.Expressions#FluentList . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SqlImplementor.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
/**
 * 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(SqlNodeList)},
 * {@link Builder#setWhere(SqlNode)} etc. call
 * {@link Builder#result(SqlNode, Collection, RelNode, Map)}
 * 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(RelNode rel, Clause... clauses) {
  final Clause maxClause = maxClause();
  boolean needNew = false;
  // If old and new clause are equal and belong to below set,
  // then new SELECT wrap is not required
  Set<Clause> nonWrapSet = ImmutableSet.of(Clause.SELECT);
  for (Clause clause : clauses) {
    if (maxClause.ordinal() > clause.ordinal()
      || (maxClause == clause && !nonWrapSet.contains(clause))) {
      needNew = true;
    }
  }
  if (rel instanceof LogicalAggregate
    && !dialect.supportsNestedAggregations()
    && hasNestedAggregations((LogicalAggregate) rel)) {
    needNew = true;
  }

  SqlSelect select;
  Expressions.FluentList<Clause> clauseList = Expressions.list();
  if (needNew) {
    select = subSelect();
  } else {
    select = asSelect();
    clauseList.addAll(this.clauses);
  }
  clauseList.appendAll(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 {
    boolean qualified =
      !dialect.hasImplicitTableAlias() || aliases.size() > 1;
    // basically, we did a subSelect() since needNew is set and neededAlias is not null
    // now, we need to make sure that we need to update the alias context.
    // if our aliases map has a single element:  <neededAlias, rowType>,
    // then we don't need to rewrite the alias but otherwise, it should be updated.
    if (needNew
      && neededAlias != null
      && (aliases.size() != 1 || !aliases.containsKey(neededAlias))) {
      final Map<String, RelDataType> newAliases =
        ImmutableMap.of(neededAlias, rel.getInput(0).getRowType());
      newContext = aliasContext(newAliases, qualified);
    } else {
      newContext = aliasContext(aliases, qualified);
    }
  }
  return new Builder(rel, clauseList, select, newContext,
    needNew ? null : aliases);
}
 
Example 2
Source File: DremioRelToSqlConverter.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
/**
 * 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(SqlNodeList)},
 * {@link Builder#setWhere(SqlNode)} etc. call
 * {@link Builder#result(SqlNode, Collection, RelNode, Map)}
 * to fix the new query.
 *
 * @param rel      Relational expression being implemented
 * @param forceNew Forces the query the result to be wrapped in a sub-query.
 * @param clauses  Clauses that will be generated to implement current
 *                 relational expression
 * @return A builder
 */
public Builder builder(RelNode rel, boolean forceNew, Clause... clauses) {
  final Clause maxClause = maxClause();
  boolean needNew = forceNew;

  // If old and new clause are equal and belong to below set,
  // then new SELECT wrap is not required
  if (!needNew) {
    Set<Clause> nonWrapSet = ImmutableSet.of(Clause.SELECT);
    for (Clause clause : clauses) {
      if (maxClause.ordinal() > clause.ordinal()
        || (maxClause == clause && !nonWrapSet.contains(clause))) {
        needNew = true;
      }
    }
  }

  if (rel instanceof LogicalAggregate
    && !dialect.supportsNestedAggregations()
    && hasNestedAggregations((LogicalAggregate) rel)) {
    needNew = true;
  }

  SqlSelect select;
  Expressions.FluentList<Clause> clauseList = Expressions.list();
  if (needNew) {
    select = subSelect();
  } else {
    select = asSelect();
    clauseList.addAll(this.clauses);
  }
  clauseList.appendAll(clauses);
  Context newContext;
  final SqlNodeList selectList = select.getSelectList();
  if (selectList != null) {
    newContext = getDremioRelToSqlConverter().selectListContext(selectList);
  } else {
    final boolean qualified = !dialect.hasImplicitTableAlias()
      || aliases.size() > 1 || getDremioRelToSqlConverter().isSubQuery();

    // basically, we did a subSelect() since needNew is set and neededAlias is not null
    // now, we need to make sure that we need to update the alias context.
    // if our aliases map has a single element:  <neededAlias, rowType>,
    // then we don't need to rewrite the alias but otherwise, it should be updated.
    if (needNew
      && neededAlias != null
      && (aliases.size() != 1 || !aliases.containsKey(neededAlias)
      || !aliases.get(neededAlias).equals(rel.getInput(0).getRowType()))) {
      final Map<String, RelDataType> newAliases =
        ImmutableMap.of(neededAlias, rel.getInput(0).getRowType());
      newContext = getDremioRelToSqlConverter().aliasContext(newAliases, qualified);
      return new Builder(rel, clauseList, select, newContext, rel.getRowType(), newAliases);
    } else {
      newContext = getDremioRelToSqlConverter().aliasContext(aliases, qualified);
    }
  }
  return new Builder(rel, clauseList, select, newContext, rel.getRowType(), aliases);
}
 
Example 3
Source File: RelToSqlConverter.java    From quark with Apache License 2.0 4 votes vote down vote up
/**
 * 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></p>
 * <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>
 * <p>When you have called
 * {@link Builder#setSelect(org.apache.calcite.sql.SqlNodeList)},
 * {@link Builder#setWhere(org.apache.calcite.sql.SqlNode)} etc. call
 * {@link Builder#result(org.apache.calcite.sql.SqlNode, java.util.Collection, org.apache.calcite.rel.RelNode)}
 * to fix the new query.</p>
 *
 * @param rel     Relational expression being implemented
 * @param clauses Clauses that will be generated to implement current
 *                relational expression
 * @return A builder
 */
public Builder builder(RelNode 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.appendAll(clauses);
  Context newContext;
  final SqlNodeList selectList = select.getSelectList();
  if (selectList != null) {
    newContext = new Context(selectList.size()) {

      @Override
      public SqlNode field(int ordinal) {
        return field(ordinal, false);
      }

      @Override
      public SqlNode field(int ordinal, boolean useAlias) {
        final SqlNode selectItem = selectList.get(ordinal);
        switch (selectItem.getKind()) {
          case AS:
            if (useAlias) {
              return ((SqlCall) selectItem).operand(1);
            } else {
              return ((SqlCall) selectItem).operand(0);
            }
        }
        return selectItem;
      }
    };
  } else {
    newContext = new AliasContext(aliases, aliases.size() > 1);
  }
  return new Builder(rel, clauseList, select, newContext);
}
 
Example 4
Source File: SqlImplementor.java    From calcite with Apache License 2.0 4 votes vote down vote up
/** 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(SqlNodeList)},
 * {@link Builder#setWhere(SqlNode)} etc. call
 * {@link Builder#result(SqlNode, Collection, RelNode, Map)}
 * 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(RelNode rel, Clause... clauses) {
  final boolean needNew = needNewSubQuery(rel, clauses);
  SqlSelect select;
  Expressions.FluentList<Clause> clauseList = Expressions.list();
  if (needNew) {
    select = subSelect();
  } else {
    select = asSelect();
    clauseList.addAll(this.clauses);
  }
  clauseList.appendAll(clauses);
  final Context newContext;
  Map<String, RelDataType> newAliases = null;
  final SqlNodeList selectList = select.getSelectList();
  if (selectList != null) {
    newContext = new Context(dialect, selectList.size()) {
      public SqlNode field(int ordinal) {
        final SqlNode selectItem = selectList.get(ordinal);
        switch (selectItem.getKind()) {
        case AS:
          return ((SqlCall) selectItem).operand(0);
        }
        return selectItem;
      }

      @Override public SqlNode orderField(int ordinal) {
        // If the field expression is an unqualified column identifier
        // and matches a different alias, use an ordinal.
        // For example, given
        //    SELECT deptno AS empno, empno AS x FROM emp ORDER BY emp.empno
        // we generate
        //    SELECT deptno AS empno, empno AS x FROM emp ORDER BY 2
        // "ORDER BY empno" would give incorrect result;
        // "ORDER BY x" is acceptable but is not preferred.
        final SqlNode node = field(ordinal);
        if (node instanceof SqlIdentifier
            && ((SqlIdentifier) node).isSimple()) {
          final String name = ((SqlIdentifier) node).getSimple();
          for (Ord<SqlNode> selectItem : Ord.zip(selectList)) {
            if (selectItem.i != ordinal) {
              final String alias =
                  SqlValidatorUtil.getAlias(selectItem.e, -1);
              if (name.equalsIgnoreCase(alias)) {
                return SqlLiteral.createExactNumeric(
                    Integer.toString(ordinal + 1), SqlParserPos.ZERO);
              }
            }
          }
        }
        return node;
      }
    };
  } else {
    boolean qualified =
        !dialect.hasImplicitTableAlias() || aliases.size() > 1;
    // basically, we did a subSelect() since needNew is set and neededAlias is not null
    // now, we need to make sure that we need to update the alias context.
    // if our aliases map has a single element:  <neededAlias, rowType>,
    // then we don't need to rewrite the alias but otherwise, it should be updated.
    if (needNew
        && neededAlias != null
        && (aliases.size() != 1 || !aliases.containsKey(neededAlias))) {
      newAliases =
          ImmutableMap.of(neededAlias, rel.getInput(0).getRowType());
      newContext = aliasContext(newAliases, qualified);
    } else {
      newContext = aliasContext(aliases, qualified);
    }
  }
  return new Builder(rel, clauseList, select, newContext, isAnon(),
      needNew && !aliases.containsKey(neededAlias) ? newAliases : aliases);
}