Search in sources :

Example 1 with LanguageFactory

use of org.apache.derby.iapi.sql.LanguageFactory in project derby by apache.

the class GroupByNode method addAggregateColumns.

/**
 * In the query rewrite involving aggregates, add the columns for
 * aggregation.
 *
 * @see #addNewColumnsForAggregation
 */
private void addAggregateColumns() throws StandardException {
    DataDictionary dd = getDataDictionary();
    ColumnReference newColumnRef;
    ResultColumn newRC;
    ResultColumn tmpRC;
    ResultColumn aggResultRC;
    ResultColumnList bottomRCL = childResult.getResultColumns();
    ResultColumnList groupByRCL = getResultColumns();
    ResultColumnList aggRCL;
    int aggregatorVColId;
    int aggInputVColId;
    int aggResultVColId;
    /*
		 ** Now process all of the aggregates.  Replace
		 ** every aggregate with an RC.  We toss out
		 ** the list of RCs, we need to get each RC
		 ** as we process its corresponding aggregate.
		 */
    LanguageFactory lf = getLanguageConnectionContext().getLanguageFactory();
    ReplaceAggregatesWithCRVisitor replaceAggsVisitor = new ReplaceAggregatesWithCRVisitor(new ResultColumnList((getContextManager())), ((FromTable) childResult).getTableNumber(), ResultSetNode.class);
    parent.getResultColumns().accept(replaceAggsVisitor);
    if (havingClause != null) {
        // replace aggregates in the having clause with column references.
        replaceAggsVisitor = new ReplaceAggregatesWithCRVisitor(new ResultColumnList((getContextManager())), ((FromTable) childResult).getTableNumber());
        havingClause.accept(replaceAggsVisitor);
        // make having clause a restriction list in the parent
        // project restrict node.
        ProjectRestrictNode parentPRSN = (ProjectRestrictNode) parent;
        parentPRSN.setRestriction(havingClause);
    }
    /*
		** For each aggregate
		*/
    int alSize = aggregates.size();
    for (int index = 0; index < alSize; index++) {
        AggregateNode aggregate = aggregates.get(index);
        /*
			** AGG RESULT: Set the aggregate result to null in the
			** bottom project restrict.
			*/
        newRC = new ResultColumn("##aggregate result", aggregate.getNewNullResultExpression(), getContextManager());
        newRC.markGenerated();
        newRC.bindResultColumnToExpression();
        bottomRCL.addElement(newRC);
        newRC.setVirtualColumnId(bottomRCL.size());
        aggResultVColId = newRC.getVirtualColumnId();
        /*
			** Set the GB aggregrate result column to
			** point to this.  The GB aggregate result
			** was created when we called
			** ReplaceAggregatesWithCRVisitor()
			*/
        newColumnRef = new ColumnReference(newRC.getName(), null, getContextManager());
        newColumnRef.setSource(newRC);
        newColumnRef.setNestingLevel(this.getLevel());
        newColumnRef.setSourceLevel(this.getLevel());
        tmpRC = new ResultColumn(newRC.getColumnName(), newColumnRef, getContextManager());
        tmpRC.markGenerated();
        tmpRC.bindResultColumnToExpression();
        groupByRCL.addElement(tmpRC);
        tmpRC.setVirtualColumnId(groupByRCL.size());
        /*
			** Set the column reference to point to
			** this.
			*/
        newColumnRef = aggregate.getGeneratedRef();
        newColumnRef.setSource(tmpRC);
        /*
			** AGG INPUT: Create a ResultColumn in the bottom 
			** project restrict that has the expression that is
			** to be aggregated
			*/
        newRC = aggregate.getNewExpressionResultColumn(dd);
        newRC.markGenerated();
        newRC.bindResultColumnToExpression();
        bottomRCL.addElement(newRC);
        newRC.setVirtualColumnId(bottomRCL.size());
        aggInputVColId = newRC.getVirtualColumnId();
        aggResultRC = new ResultColumn("##aggregate expression", aggregate.getNewNullResultExpression(), getContextManager());
        /*
			** Add a reference to this column into the
			** group by columns.
			*/
        tmpRC = getColumnReference(newRC, dd);
        groupByRCL.addElement(tmpRC);
        tmpRC.setVirtualColumnId(groupByRCL.size());
        /*
			** AGGREGATOR: Add a getAggregator method call 
			** to the bottom result column list.
			*/
        newRC = aggregate.getNewAggregatorResultColumn(dd);
        newRC.markGenerated();
        newRC.bindResultColumnToExpression();
        bottomRCL.addElement(newRC);
        newRC.setVirtualColumnId(bottomRCL.size());
        aggregatorVColId = newRC.getVirtualColumnId();
        /*
			** Add a reference to this column in the Group By result
			** set.
			*/
        tmpRC = getColumnReference(newRC, dd);
        groupByRCL.addElement(tmpRC);
        tmpRC.setVirtualColumnId(groupByRCL.size());
        /*
			** Piece together a fake one column rcl that we will use
			** to generate a proper result description for input
			** to this agg if it is a user agg.
			*/
        aggRCL = new ResultColumnList((getContextManager()));
        aggRCL.addElement(aggResultRC);
        /*
			** Note that the column ids in the row are 0 based
			** so we have to subtract 1.
			*/
        aggInfo.addElement(new AggregatorInfo(aggregate.getAggregateName(), aggregate.getAggregatorClassName(), // aggregate input column
        aggInputVColId - 1, // the aggregate result column
        aggResultVColId - 1, // the aggregator column
        aggregatorVColId - 1, aggregate.isDistinct(), lf.getResultDescription(aggRCL.makeResultDescriptors(), "SELECT")));
    }
}
Also used : AggregatorInfo(org.apache.derby.impl.sql.execute.AggregatorInfo) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) LanguageFactory(org.apache.derby.iapi.sql.LanguageFactory)

Aggregations

LanguageFactory (org.apache.derby.iapi.sql.LanguageFactory)1 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)1 AggregatorInfo (org.apache.derby.impl.sql.execute.AggregatorInfo)1