package jeql.engine.function;
import java.util.List;
import jeql.engine.CompilationException;
import jeql.engine.Scope;
import jeql.engine.query.QueryScope;
import jeql.syntax.ParseTreeNode;
/**
* Implements the PREV pseudo-function semantics.
* <p>
* Syntax:
* <pre>
* PREV(valueExpr [, initValueExpr] )
* </pre>
* PREV returns the value of an expression evaluated in the context
* of the previous row appearing in the result.
* An optional initial value may be supplied for the value of the expression
* for the first row evaluated.
* Otherwise, the value of PREV(...) for the first row in the result is <code>null</code>
*
* @author Martin Davis
*
*/
public class PrevFunctionEvaluator
implements FunctionEvaluator
{
private int argCount = 0;
private ParseTreeNode valueExpr;
private ParseTreeNode initExpr = null;
public static final String FN_PREV = "prev";
public PrevFunctionEvaluator()
{
}
public void bind(Scope scope, List args)
{
argCount = args.size();
valueExpr = (ParseTreeNode) args.get(0);
if (args.size() >= 2)
initExpr = (ParseTreeNode) args.get(1);
if (argCount < 1 || argCount > 2)
throw new CompilationException("PREV() function must have 1 or 2 arguments");
}
public Object eval(Scope scope)
{
// if this fails, function is being called outside of a SELECT => error
QueryScope qScope = (QueryScope) scope;
Object prevVal = null;
if (qScope.getRowNum() <= 1) {
if (initExpr != null)
prevVal = initExpr.eval(scope);
}
else {
prevVal = qScope.getValue(this);
}
Object result = valueExpr.eval(scope);
qScope.setValue(this, result);
return prevVal;
}
public Class getType(Scope scope)
{
return valueExpr.getType(scope);
}
}