net.sf.farrago.fennel.rel
Class FennelWindowRel

java.lang.Object
  extended by org.eigenbase.rel.AbstractRelNode
      extended by org.eigenbase.rel.SingleRel
          extended by net.sf.farrago.fennel.rel.FennelSingleRel
              extended by net.sf.farrago.fennel.rel.FennelWindowRel
All Implemented Interfaces:
Cloneable, FennelRel, RelNode

public class FennelWindowRel
extends FennelSingleRel

FennelWindowRel is the relational expression which computes windowed aggregates inside of Fennel.

A window rel can handle several window aggregate functions, over several partitions, with pre- and post-expressions, and an optional post-filter. Each of the partitions is defined by a partition key (zero or more columns) and a range (logical or physical). The partitions expect the data to be sorted correctly on input to the relational expression.

Rules:

Since:
Dec 6, 2004
Version:
$Id: //open/dev/farrago/src/net/sf/farrago/fennel/rel/FennelWindowRel.java#2 $
Author:
jhyde

Nested Class Summary
static class FennelWindowRel.Partition
          A Partition is a collection of windowed aggregate expressions which belong to the same FennelWindowRel.Window and have the same partitioning keys.
static class FennelWindowRel.RexWinAggCall
          A call to a windowed aggregate function.
static class FennelWindowRel.Window
          A Window is a range of input rows, defined by an upper and lower bound.
 
Field Summary
private  RexProgram inputProgram
          Program which is applied on an incoming row event.
private  RexProgram outputProgram
          Program which is applied on an 'row output' event.
private  FennelWindowRel.Window[] windows
           
 
Fields inherited from class org.eigenbase.rel.AbstractRelNode
digest, id, rowType, traits
 
Fields inherited from interface net.sf.farrago.query.FennelRel
FENNEL_EXEC_CONVENTION
 
Fields inherited from interface org.eigenbase.rel.RelNode
emptyArray
 
Constructor Summary
protected FennelWindowRel(RelOptCluster cluster, RelNode child, RelDataType rowType, RexProgram inputProgram, FennelWindowRel.Window[] windows, RexProgram outputProgram)
          Creates a window relational expression.
 
Method Summary
 FennelWindowRel clone()
          Clones this RelNode.
 RelOptCost computeSelfCost(RelOptPlanner planner)
          Returns the cost of this plan (not including children).
 void explain(RelOptPlanWriter pw)
           
 RexNode[] getChildExps()
          Returns an array of this relational expression's child expressions (not including the inputs returned by RelNode.getInputs().
private  void getExplainTerms(List<String> termList, List<Object> valueList)
           
 String[] getSoleProgram()
          Assuming that this FennelWindowRel contains one window with one partition, return the add/init/drop programs for that partition.
 List<FennelWindowRel.Window> getWindows()
           
 boolean isValid(boolean fail)
          Returns whether this relational expression is valid.
static RexProgram makeProgram(RexBuilder rexBuilder, RexProgram bottomProgram, List<FennelWindowRel.RexWinAggCall> overList)
          Creates a program with one output field per windowed aggregate expression.
private static List<RelDataType> outputProgramInputTypes(RelDataType rowType, FennelWindowRel.Window[] windows)
           
private  List<RexNode> removeDuplicates(RexToCalcTranslator translator, List<FennelWindowRel.RexWinAggCall> outputExps)
           
 FemExecutionStreamDef toStreamDef(FennelRelImplementor implementor)
          Converts this relational expression to FemExecutionStreamDef form.
 
Methods inherited from class net.sf.farrago.fennel.rel.FennelSingleRel
getCollations, getFarragoTypeFactory, implementFennelChild
 
Methods inherited from class org.eigenbase.rel.SingleRel
childrenAccept, deriveRowType, getChild, getInputs, getRows, replaceInput
 
Methods inherited from class org.eigenbase.rel.AbstractRelNode
cloneTraits, collectVariablesSet, collectVariablesUsed, computeDigest, getCluster, getCollationList, getConvention, getCorrelVariable, getDescription, getDigest, getExpectedInputRowType, getId, getInput, getOrCreateCorrelVariable, getQuery, getRelTypeName, getRowType, getTable, getTraits, getVariablesStopped, inheritTraitsFrom, isAccessTo, isDistinct, onRegister, recomputeDigest, register, registerCorrelVariable, setCorrelVariable, toString
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface org.eigenbase.rel.RelNode
childrenAccept, collectVariablesSet, collectVariablesUsed, getCluster, getCollationList, getConvention, getCorrelVariable, getDescription, getDigest, getExpectedInputRowType, getId, getInput, getInputs, getOrCreateCorrelVariable, getQuery, getRelTypeName, getRows, getRowType, getTable, getTraits, getVariablesStopped, isAccessTo, isDistinct, onRegister, recomputeDigest, registerCorrelVariable, replaceInput, setCorrelVariable
 

Field Detail

inputProgram

private final RexProgram inputProgram
Program which is applied on an incoming row event.

It provides the necessary expressions for the windows to work on. The program always outputs the input fields first, then any necessary expressions.

For example, for the query

select ticker,
sum(amount * price) over last3
from Bids
window last3 as (order by orderid rows 3 preceding),
lastHour (order by orderdate range interval '1' hour preceding),
the program will output the expressions
{orderid, ticker, amount, price, amount * price}


outputProgram

private final RexProgram outputProgram
Program which is applied on an 'row output' event.

Its input is the columns of the current input row, and all accumulators of all windows of all partitions. Its output is the output row.

For example, consider the query

select ticker,
sum(amount * price) over last3,
2 * sum(amount + 1) over lastHour,
from Bids
window last3 as (order by orderid rows 3 preceding),
lastHour (order by orderdate range interval '1' hour preceding),
The program has inputs
{orderid, ticker, amount, price, sum(amount * price) over last3, sum(amount + 1) over lastHour}
and outputs
{$1, $4, 2 * $5}


windows

private final FennelWindowRel.Window[] windows
Constructor Detail

FennelWindowRel

protected FennelWindowRel(RelOptCluster cluster,
                          RelNode child,
                          RelDataType rowType,
                          RexProgram inputProgram,
                          FennelWindowRel.Window[] windows,
                          RexProgram outputProgram)
Creates a window relational expression.

Each FennelWindowRel.Window has a set of FennelWindowRel.Partition objects, and each FennelWindowRel.Partition object has a set of RexOver objects.

Parameters:
cluster - Cluster
child - Input relational expression
rowType - Output row type
inputProgram - Program which computes input expressions for all windows
windows - Windows
outputProgram - Program which computes output row from input columns and all windows
"Precondition:"
inputProgram.getCondition() == null
Method Detail

outputProgramInputTypes

private static List<RelDataType> outputProgramInputTypes(RelDataType rowType,
                                                         FennelWindowRel.Window[] windows)

clone

public FennelWindowRel clone()
Description copied from interface: RelNode
Clones this RelNode.

Traits of the RelNode must be explicitly cloned, using AbstractRelNode.inheritTraitsFrom(AbstractRelNode), as the RelNode may have traits of which it has no knowledge. Example implementation:

     public MyRelNode clone()
     {
         MyRelNode clone = new MyRelNode(...);
         clone.inheritTraitsFrom(this);
         return clone;
     }
 
N.B.: This method must be overridden whenever an existing, concrete RelNode is extended. Otherwise, calling clone() will produce a differently typed RelNode, resulting in invalid or incorrect query plans.

Specified by:
clone in interface RelNode
Specified by:
clone in class AbstractRelNode
Returns:
a clone of this RelNode

getWindows

public List<FennelWindowRel.Window> getWindows()

isValid

public boolean isValid(boolean fail)
Description copied from interface: RelNode
Returns whether this relational expression is valid.

If assertions are enabled, this method is typically called with fail = true, as follows:

assert rel.isValid(true)
This signals that the method can throw an AssertionError if it is not valid.

Specified by:
isValid in interface RelNode
Overrides:
isValid in class AbstractRelNode
Parameters:
fail - Whether to fail if invalid
Returns:
Whether relational expression is valid

getChildExps

public RexNode[] getChildExps()
Description copied from interface: RelNode
Returns an array of this relational expression's child expressions (not including the inputs returned by RelNode.getInputs(). If there are no child expressions, returns an empty array, not null.

Specified by:
getChildExps in interface RelNode
Overrides:
getChildExps in class AbstractRelNode

explain

public void explain(RelOptPlanWriter pw)
Specified by:
explain in interface RelNode
Overrides:
explain in class SingleRel

getExplainTerms

private void getExplainTerms(List<String> termList,
                             List<Object> valueList)

computeSelfCost

public RelOptCost computeSelfCost(RelOptPlanner planner)
Description copied from interface: RelNode
Returns the cost of this plan (not including children). The base implementation throws an error; derived classes should override.

NOTE jvs 29-Mar-2006: Don't call this method directly. Instead, use RelMetadataQuery.getNonCumulativeCost(org.eigenbase.rel.RelNode), which gives plugins a chance to override the rel's default ideas about cost.

Specified by:
computeSelfCost in interface RelNode
Overrides:
computeSelfCost in class AbstractRelNode

toStreamDef

public FemExecutionStreamDef toStreamDef(FennelRelImplementor implementor)
Description copied from interface: FennelRel
Converts this relational expression to FemExecutionStreamDef form. In the process, the relational expression will almost certainly call FennelRelImplementor.visitFennelChild(net.sf.farrago.query.FennelRel, int) on each of its children.

Parameters:
implementor - for generating Java code
Returns:
generated FemExecutionStreamDef

getSoleProgram

public String[] getSoleProgram()
Assuming that this FennelWindowRel contains one window with one partition, return the add/init/drop programs for that partition. For testing purposes.


makeProgram

public static RexProgram makeProgram(RexBuilder rexBuilder,
                                     RexProgram bottomProgram,
                                     List<FennelWindowRel.RexWinAggCall> overList)
Creates a program with one output field per windowed aggregate expression.

Parameters:
rexBuilder - Expression builder
bottomProgram - Calculates the inputs to the program
overList - Aggregate expressions
Returns:
Combined program
See Also:
RexProgramBuilder.mergePrograms(RexProgram, RexProgram, RexBuilder)
"Precondition:"
bottomPogram.getCondition() == null
"Postcondition:"
return.getProjectList().size() == overList.size()

removeDuplicates

private List<RexNode> removeDuplicates(RexToCalcTranslator translator,
                                       List<FennelWindowRel.RexWinAggCall> outputExps)