private void pushOrderingDown(ResultSetNode rsn) throws StandardException {
   ContextManager cm = getContextManager();
   NodeFactory nf = getNodeFactory();
   OrderByList orderByList = (OrderByList) nf.getNode(C_NodeTypes.ORDER_BY_LIST, cm);
   for (int i = 0; i < intermediateOrderByColumns.length; i++) {
     OrderByColumn orderByColumn =
         (OrderByColumn)
             nf.getNode(
                 C_NodeTypes.ORDER_BY_COLUMN,
                 nf.getNode(
                     C_NodeTypes.INT_CONSTANT_NODE,
                     ReuseFactory.getInteger(intermediateOrderByColumns[i] + 1),
                     cm),
                 cm);
     if (intermediateOrderByDirection[i] < 0) orderByColumn.setDescending();
     if (intermediateOrderByNullsLow[i]) orderByColumn.setNullsOrderedLow();
     orderByList.addOrderByColumn(orderByColumn);
   }
   orderByList.bindOrderByColumns(rsn);
   rsn.pushOrderByList(orderByList);
 } // end of pushOrderingDown
Exemplo n.º 2
0
  /**
   * Preprocess a ResultSetNode - this currently means: o Generating a referenced table map for each
   * ResultSetNode. o Putting the WHERE and HAVING clauses in conjunctive normal form (CNF). o
   * Converting the WHERE and HAVING clauses into PredicateLists and classifying them. o Ensuring
   * that a ProjectRestrictNode is generated on top of every FromBaseTable and generated in place of
   * every FromSubquery. o Pushing single table predicates down to the new ProjectRestrictNodes.
   *
   * @param numTables The number of tables in the DML Statement
   * @param gbl The group by list, if any
   * @param fromList The from list, if any
   * @return ResultSetNode at top of preprocessed tree.
   * @exception StandardException Thrown on error
   */
  public ResultSetNode preprocess(int numTables, GroupByList gbl, FromList fromList)
      throws StandardException {
    // Push the order by list down to the ResultSet
    if (orderByList != null) {
      // If we have more than 1 ORDERBY columns, we may be able to
      // remove duplicate columns, e.g., "ORDER BY 1, 1, 2".
      if (orderByList.size() > 1) {
        orderByList.removeDupColumns();
      }

      subquery.pushOrderByList(orderByList);
      orderByList = null;
    }

    subquery.pushOffsetFetchFirst(offset, fetchFirst, hasJDBClimitClause);

    /* We want to chop out the FromSubquery from the tree and replace it
     * with a ProjectRestrictNode.  One complication is that there may be
     * ColumnReferences above us which point to the FromSubquery's RCL.
     * What we want to return is a tree with a PRN with the
     * FromSubquery's RCL on top.  (In addition, we don't want to be
     * introducing any redundant ProjectRestrictNodes.)
     * Another complication is that we want to be able to only push
     * projections and restrictions down to this ProjectRestrict, but
     * we want to be able to push them through as well.
     * So, we:
     *		o call subquery.preprocess() which returns a tree with
     *		  a SelectNode or a RowResultSetNode on top.
     *		o If the FSqry is flattenable(), then we return (so that the
     *		  caller can then call flatten()), otherwise we:
     *		o generate a PRN, whose RCL is the FSqry's RCL, on top of the result.
     *		o create a referencedTableMap for the PRN which represents
     *		  the FSqry's tableNumber, since ColumnReferences in the outer
     *		  query block would be referring to that one.
     *		  (This will allow us to push restrictions down to the PRN.)
     */

    subquery = subquery.preprocess(numTables, gbl, fromList);

    /* Return if the FSqry is flattenable()
     * NOTE: We can't flatten a FromSubquery if there is a group by list
     * because the group by list must be ColumnReferences.  For:
     *	select c1 from v1 group by c1,
     *	where v1 is select 1 from t1
     * The expression under the last redundant ResultColumn is an IntConstantNode,
     * not a ColumnReference.
     * We also do not flatten a subquery if tableProperties is non-null,
     * as the user is specifying 1 or more properties for the derived table,
     * which could potentially be lost on the flattening.
     * RESOLVE - this is too restrictive.
     */
    if ((gbl == null || gbl.size() == 0)
        && tableProperties == null
        && subquery.flattenableInFromSubquery(fromList)) {
      /* Set our table map to the subquery's table map. */
      setReferencedTableMap(subquery.getReferencedTableMap());
      return this;
    }

    return extractSubquery(numTables);
  }