Add workspace field and function setup support.
authorJacques Nadeau <jacques@apache.org>
Thu, 18 Jul 2013 03:06:00 +0000 (20:06 -0700)
committerJacques Nadeau <jacques@apache.org>
Fri, 19 Jul 2013 21:53:31 +0000 (14:53 -0700)
Add alternate function
Add slightly better filter test.

16 files changed:
sandbox/prototype/common/src/main/java/org/apache/drill/common/expression/ArgumentValidators.java
sandbox/prototype/common/src/main/java/org/apache/drill/common/expression/FunctionCall.java
sandbox/prototype/common/src/main/java/org/apache/drill/common/expression/FunctionRegistry.java
sandbox/prototype/common/src/main/java/org/apache/drill/common/expression/NoArgValidator.java [new file with mode: 0644]
sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/CodeGenerator.java
sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/WorkSpace.java
sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionHolder.java
sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/ImportGrabber.java [new file with mode: 0644]
sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/MethodGrabbingVisitor.java
sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Alternator.java [new file with mode: 0644]
sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/vector/ValueVector.java
sandbox/prototype/exec/java-exec/src/main/resources/drill-module.conf
sandbox/prototype/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/filter/TestSimpleFilter.java
sandbox/prototype/exec/java-exec/src/test/resources/filter/test1.json

index f30733d..b745277 100644 (file)
@@ -37,12 +37,12 @@ public class ArgumentValidators {
 
     public AnyTypeAllowed(int argCount) {
       super();
-      argumentCount = Ranges.singleton(argCount);
+      argumentCount = Range.singleton(argCount);
     }
 
     public AnyTypeAllowed(int minArguments, int maxArguments) {
       super();
-      argumentCount = Ranges.closedOpen(minArguments, maxArguments);
+      argumentCount = Range.closedOpen(minArguments, maxArguments);
     }
 
     @Override
@@ -66,14 +66,14 @@ public class ArgumentValidators {
 
     public PredicateValidator(int argCount, Predicate<MajorType> predicate, boolean allSame) {
       super();
-      this.argumentCount = Ranges.singleton(argCount);
+      this.argumentCount = Range.singleton(argCount);
       this.predicate = predicate;
       this.allSame = allSame;
     }
 
     public PredicateValidator(int minArguments, int maxArguments, Predicate<MajorType> predicate, boolean allSame) {
       super();
-      this.argumentCount = Ranges.closedOpen(minArguments, maxArguments);
+      this.argumentCount = Range.closedOpen(minArguments, maxArguments);
       this.predicate = predicate;
       this.allSame = allSame;
     }
index e13e87e..d27b584 100644 (file)
@@ -24,6 +24,7 @@ import org.apache.drill.common.expression.visitors.ExprVisitor;
 import org.apache.drill.common.types.TypeProtos.MajorType;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 
 public class FunctionCall extends LogicalExpressionBase implements Iterable<LogicalExpression> {
   private final FunctionDefinition func;
@@ -33,6 +34,9 @@ public class FunctionCall extends LogicalExpressionBase implements Iterable<Logi
   public FunctionCall(FunctionDefinition func, List<LogicalExpression> args, ExpressionPosition pos) {
     super(pos);
     this.func = func;
+    
+    if(args == null) args = Lists.newArrayList();
+    
     if (!(args instanceof ImmutableList)) {
       args = ImmutableList.copyOf(args);
     }
index ed2c63e..28fa2db 100644 (file)
@@ -32,7 +32,8 @@ import org.apache.drill.common.util.PathScanner;
 import com.google.common.collect.Lists;
 
 public class FunctionRegistry {
-
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(FunctionRegistry.class);
+  
   private final Map<String, FunctionDefinition> funcMap;
 
   public FunctionRegistry(DrillConfig config){
@@ -44,7 +45,9 @@ public class FunctionRegistry {
         FunctionDefinition[] defs = p.getFunctionDefintions();
         for(FunctionDefinition d : defs){
           for(String rn : d.getRegisteredNames()){
+            
             FunctionDefinition d2 = funcs.put(rn, d);
+            logger.debug("Registering function {}", d);
             if(d2 != null){
               throw new ExceptionInInitializerError(String.format("Failure while registering functions.  The function %s tried to register with the name %s but the function %s already registered with that name.", d.getName(), rn, d2.getName()) );
             }
diff --git a/sandbox/prototype/common/src/main/java/org/apache/drill/common/expression/NoArgValidator.java b/sandbox/prototype/common/src/main/java/org/apache/drill/common/expression/NoArgValidator.java
new file mode 100644 (file)
index 0000000..2b2c46d
--- /dev/null
@@ -0,0 +1,21 @@
+package org.apache.drill.common.expression;
+
+import java.util.List;
+
+public class NoArgValidator implements ArgumentValidator{
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(NoArgValidator.class);
+
+  @Override
+  public void validateArguments(ExpressionPosition expr, List<LogicalExpression> expressions, ErrorCollector errors) {
+    if(!expressions.isEmpty()){
+      errors.addGeneralError(expr, "Expected zero arguments, received more than that.");
+    }
+  }
+
+  @Override
+  public String[] getArgumentNamesByPosition() {
+    return new String[0];
+  }
+  
+  public static final NoArgValidator VALIDATOR = new NoArgValidator();
+}
index 241c1cc..6e31dec 100644 (file)
@@ -57,6 +57,8 @@ public class CodeGenerator<T> {
       throw new IllegalStateException(e);
     }
   }
+  
+
 
   public void addExpr(LogicalExpression ex){
     logger.debug("Adding next write {}", ex);
index c219d9c..c9e3c22 100644 (file)
@@ -42,7 +42,8 @@ public class EvaluationVisitor extends AbstractExprVisitor<HoldingContainer, Cod
       args[i] = call.args.get(i).accept(this, generator);
     }
     FunctionHolder holder = registry.getFunction(call);
-    return holder.generateEvalBody(generator, args);
+    
+    return holder.renderFunction(generator, args);
   }
   
   @Override
@@ -198,7 +199,7 @@ public class EvaluationVisitor extends AbstractExprVisitor<HoldingContainer, Cod
   
   private HoldingContainer visitReturnValueExpression(ReturnValueExpression e, CodeGenerator<?> generator){
     LogicalExpression child = e.getChild();
-    Preconditions.checkArgument(child.getMajorType().equals(Types.REQUIRED_BOOLEAN));
+//    Preconditions.checkArgument(child.getMajorType().equals(Types.REQUIRED_BOOLEAN));
     HoldingContainer hc = child.accept(this, generator);
     generator.getBlock()._return(hc.getValue().eq(JExpr.lit(1)));
     return null;
index 8e0f1be..3525cbb 100644 (file)
@@ -14,7 +14,7 @@ import org.apache.drill.exec.expr.DrillFunc;
 import org.apache.drill.exec.expr.annotations.FunctionTemplate;
 import org.apache.drill.exec.expr.annotations.Output;
 import org.apache.drill.exec.expr.annotations.Param;
-import org.apache.drill.exec.expr.annotations.WorkSpace;
+import org.apache.drill.exec.expr.annotations.Workspace;
 import org.apache.drill.exec.expr.fn.FunctionHolder.ValueReference;
 import org.apache.drill.exec.expr.fn.FunctionHolder.WorkspaceReference;
 import org.apache.drill.exec.expr.holders.ValueHolder;
@@ -53,16 +53,16 @@ public class FunctionConverter {
 
       Param param = field.getAnnotation(Param.class);
       Output output = field.getAnnotation(Output.class);
-      WorkSpace workspace = field.getAnnotation(WorkSpace.class);
+      Workspace workspace = field.getAnnotation(Workspace.class);
       
       int i =0;
       if(param != null) i++;
       if(output != null) i++;
       if(workspace != null) i++;
       if(i == 0){
-        return failure("The field must be either a @Param, @Output or @WorkSpace field.", clazz, field);
+        return failure("The field must be either a @Param, @Output or @Workspace field.", clazz, field);
       }else if(i > 1){
-        return failure("The field must be only one of @Param, @Output or @WorkSpace.  It currently has more than one of these annotations.", clazz, field);
+        return failure("The field must be only one of @Param, @Output or @Workspace.  It currently has more than one of these annotations.", clazz, field);
       }
 
       
@@ -98,13 +98,14 @@ public class FunctionConverter {
         
       }else{
         // workspace work.
+        logger.debug("Found workspace field {}:{}", field.getType(), field.getName());
         workspaceFields.add(new WorkspaceReference(field.getType(), field.getName()));
       }
       
     }
     
     
-    if(!workspaceFields.isEmpty()) return failure("This function declares one or more workspace fields.  However, those have not yet been implemented.", clazz);
+   // if(!workspaceFields.isEmpty()) return failure("This function declares one or more workspace fields.  However, those have not yet been implemented.", clazz);
     if(outputField == null)  return failure("This function declares zero output fields.  A function must declare one output field.", clazz);
     
     // get function body.     
@@ -117,12 +118,21 @@ public class FunctionConverter {
     }
     
     Map<String, String> methods = MethodGrabbingVisitor.getMethods(cu, clazz);
-
+    List<String> imports = ImportGrabber.getMethods(cu);
     // return holder
     ValueReference[] ps = params.toArray(new ValueReference[params.size()]);
     WorkspaceReference[] works = workspaceFields.toArray(new WorkspaceReference[workspaceFields.size()]);
-    FunctionHolder fh = new FunctionHolder(template.scope(), template.nulls(), template.isBinaryCommutative(), template.name(), ps, outputField, works, methods);
-    return fh;
+    if(!methods.containsKey("eval")){
+      return failure("Failure finding eval method for function.", clazz);
+    }
+    
+    try{
+      FunctionHolder fh = new FunctionHolder(template.scope(), template.nulls(), template.isBinaryCommutative(), template.name(), ps, outputField, works, methods, imports);
+      return fh;
+    }catch(Exception ex){
+      return failure("Failure while creating function holder.", ex, clazz);
+    }
+    
   }
   
   
@@ -141,7 +151,7 @@ public class FunctionConverter {
       String body = IO.toString(is);
       
       //TODO: Hack to remove annotations so Janino doesn't choke.  Need to reconsider this problem...
-      body = body.replaceAll("@(?:Output|Param|FunctionTemplate\\([^\\\\]*?\\))", "");
+      body = body.replaceAll("@(?:Output|Param|Workspace|Override|FunctionTemplate\\([^\\\\]*?\\))", "");
       return new Parser(new Scanner(null, new StringReader(body))).parseCompilationUnit();
     }
     
index 9d7fc35..d249f4d 100644 (file)
@@ -1,6 +1,7 @@
 package org.apache.drill.exec.expr.fn;
 
 import java.util.Arrays;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.drill.common.expression.FunctionCall;
@@ -14,6 +15,8 @@ import org.apache.drill.exec.expr.annotations.FunctionTemplate;
 import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
 import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
 
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
 import com.sun.codemodel.JBlock;
 import com.sun.codemodel.JConditional;
 import com.sun.codemodel.JExpr;
@@ -32,11 +35,12 @@ public class FunctionHolder {
   private String evalBody;
   private String addBody;
   private String setupBody;
+  private List<String> imports;
   private WorkspaceReference[] workspaceVars;
   private ValueReference[] parameters;
   private ValueReference returnValue;
   
-  public FunctionHolder(FunctionScope scope, NullHandling nullHandling, boolean isBinaryCommutative, String functionName, ValueReference[] parameters, ValueReference returnValue, WorkspaceReference[] workspaceVars, Map<String, String> methods) {
+  public FunctionHolder(FunctionScope scope, NullHandling nullHandling, boolean isBinaryCommutative, String functionName, ValueReference[] parameters, ValueReference returnValue, WorkspaceReference[] workspaceVars, Map<String, String> methods, List<String> imports) {
     super();
     this.scope = scope;
     this.nullHandling = nullHandling;
@@ -46,17 +50,66 @@ public class FunctionHolder {
     this.setupBody = methods.get("setup");
     this.addBody = methods.get("add");
     this.evalBody = methods.get("eval");
+    Preconditions.checkNotNull(evalBody);
     this.parameters = parameters;
     this.returnValue = returnValue;
+    this.imports = imports;
+  }
+  
+  public List<String> getImports() {
+    return imports;
   }
 
-  public HoldingContainer generateEvalBody(CodeGenerator<?> g, HoldingContainer[] inputVariables){
+  private void generateSetupBody(CodeGenerator<?> g){
+    if(!Strings.isNullOrEmpty(setupBody)){
+      JBlock sub = new JBlock(true, true);
+      addProtectedBlock(g, sub, setupBody, null);
+      g.getSetupBlock().directStatement(String.format("/** start setup for function %s **/", functionName));
+      g.getSetupBlock().add(sub);
+      g.getSetupBlock().directStatement(String.format("/** end setup for function %s **/", functionName));
+    }
+  }
+  
+  public void addProtectedBlock(CodeGenerator<?> g, JBlock sub, String body, HoldingContainer[] inputVariables){
     
-    //g.getBlock().directStatement(String.format("//---- start of eval portion of %s function. ----//", functionName));
+    // create sub block with defined workspace variables.
+    JVar[] workspaceJVars = new JVar[workspaceVars.length];
+    for(int i =0 ; i < workspaceVars.length; i++){
+      workspaceJVars[i] = g.declareClassField("work", g.getModel()._ref(workspaceVars[i].type));
+    }
+
+    if(inputVariables != null){
+      for(int i =0; i < inputVariables.length; i++){
+        ValueReference parameter = parameters[i];
+        HoldingContainer inputVariable = inputVariables[i];
+        sub.decl(JMod.FINAL, inputVariable.getHolder().type(), parameter.name, inputVariable.getHolder());  
+      }
+    }
+
+    JVar[] internalVars = new JVar[workspaceJVars.length];
+    for(int i =0; i < workspaceJVars.length; i++){
+      internalVars[i] = sub.decl(JMod.FINAL, g.getModel()._ref(workspaceVars[i].type),  workspaceVars[i].name, workspaceJVars[i]);
+    }
     
-    JBlock sub = new JBlock(true, true);
+    Preconditions.checkNotNull(body);
+    sub.directStatement(body);
+    
+    // reassign workspace variables back to global space.
+    for(int i =0; i < workspaceJVars.length; i++){
+      sub.assign(workspaceJVars[i], internalVars[i]);
+    }
+  }
+
+  public HoldingContainer renderFunction(CodeGenerator<?> g, HoldingContainer[] inputVariables){
+    generateSetupBody(g);
+    return generateEvalBody(g, inputVariables);
+  }
+  
+  private HoldingContainer generateEvalBody(CodeGenerator<?> g, HoldingContainer[] inputVariables){
     
+    //g.getBlock().directStatement(String.format("//---- start of eval portion of %s function. ----//", functionName));
     
+    JBlock sub = new JBlock(true, true);
     
     HoldingContainer out = null;
 
@@ -89,40 +142,16 @@ public class FunctionHolder {
     // add the subblock after the out declaration.
     g.getBlock().add(sub);
     
-    JVar[] workspaceJVars = new JVar[workspaceVars.length];
-    for(int i =0 ; i < workspaceVars.length; i++){
-      workspaceJVars[i] = g.declareClassField("work", g.getModel()._ref(workspaceVars[i].type));
-    }
     
-//    for(WorkspaceReference r : workspaceVars){
-//      g.declareClassField(, t)
-//    }
-//  
-//    g.declareClassField(prefix, t)
-    
-    
-    // locally name external blocks.
-    
-    // internal out value.
     JVar internalOutput = sub.decl(JMod.FINAL, g.getHolderType(returnValue.type), returnValue.name, JExpr._new(g.getHolderType(returnValue.type)));
-    
-    for(int i =0; i < inputVariables.length; i++){
-      
-      ValueReference parameter = parameters[i];
-      HoldingContainer inputVariable = inputVariables[i];
-      sub.decl(JMod.FINAL, inputVariable.getHolder().type(), parameter.name, inputVariable.getHolder());  
-    }
-    
-    
-    // add function body.
-    sub.directStatement(evalBody);
-    
+    addProtectedBlock(g, sub, evalBody, inputVariables);
     sub.assign(out.getHolder(), internalOutput);
 
-    //g.getBlock().directStatement(String.format("//---- end of eval portion of %s function. ----//\n", functionName));
     return out;
   }
   
+  
+  
   public boolean matches(FunctionCall call){
     if(!softCompare(call.getMajorType(), returnValue.type)) return false;
     if(call.args.size() != parameters.length) return false;
@@ -148,6 +177,8 @@ public class FunctionHolder {
     String name;
     public ValueReference(MajorType type, String name) {
       super();
+      Preconditions.checkNotNull(type);
+      Preconditions.checkNotNull(name);
       this.type = type;
       this.name = name;
     }
@@ -155,15 +186,18 @@ public class FunctionHolder {
     public String toString() {
       return "ValueReference [type=" + type + ", name=" + name + "]";
     }
-    
-    
   }
 
+  
   public static class WorkspaceReference{
     Class<?> type;
     String name;
+
+
     public WorkspaceReference(Class<?> type, String name) {
       super();
+      Preconditions.checkNotNull(type);
+      Preconditions.checkNotNull(name);
       this.type = type;
       this.name = name;
     }
diff --git a/sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/ImportGrabber.java b/sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/ImportGrabber.java
new file mode 100644 (file)
index 0000000..8fc73c2
--- /dev/null
@@ -0,0 +1,55 @@
+package org.apache.drill.exec.expr.fn;
+
+import java.util.List;
+
+import org.codehaus.janino.Java;
+import org.codehaus.janino.Java.CompilationUnit.SingleStaticImportDeclaration;
+import org.codehaus.janino.Java.CompilationUnit.SingleTypeImportDeclaration;
+import org.codehaus.janino.Java.CompilationUnit.StaticImportOnDemandDeclaration;
+import org.codehaus.janino.Java.CompilationUnit.TypeImportOnDemandDeclaration;
+import org.codehaus.janino.util.Traverser;
+
+import com.google.common.collect.Lists;
+
+
+public class ImportGrabber{
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ImportGrabber.class);
+  
+  private List<String> imports = Lists.newArrayList();
+  private final ImportFinder finder = new ImportFinder();
+
+  private ImportGrabber() {
+  }
+  
+  public class ImportFinder extends Traverser{
+
+    @Override
+    public void traverseSingleTypeImportDeclaration(SingleTypeImportDeclaration stid) {
+      imports.add(stid.toString());
+    }
+
+    @Override
+    public void traverseSingleStaticImportDeclaration(SingleStaticImportDeclaration stid) {
+      imports.add(stid.toString());
+    }
+
+    @Override
+    public void traverseTypeImportOnDemandDeclaration(TypeImportOnDemandDeclaration tiodd) {
+      imports.add(tiodd.toString());
+    }
+
+    @Override
+    public void traverseStaticImportOnDemandDeclaration(StaticImportOnDemandDeclaration siodd) {
+      imports.add(siodd.toString());
+    }
+
+    
+  }
+  
+  public static List<String> getMethods(Java.CompilationUnit cu){
+    ImportGrabber visitor = new ImportGrabber();
+    cu.getPackageMemberTypeDeclarations()[0].accept(visitor.finder.comprehensiveVisitor());
+    return visitor.imports;
+  }
+
+}
index 57268ee..d46d008 100644 (file)
@@ -28,12 +28,16 @@ public class MethodGrabbingVisitor{
 
     @Override
     public void traverseClassDeclaration(ClassDeclaration cd) {
+      logger.debug("Traversing: {}", cd.getClassName());
+      boolean prevCapture = captureMethods;
       captureMethods = c.getName().equals(cd.getClassName());
       super.traverseClassDeclaration(cd);
+      captureMethods = prevCapture;
     }
 
     @Override
     public void traverseMethodDeclarator(MethodDeclarator md) {
+      logger.debug(c.getName() + ": Found {}, include {}", md.name, captureMethods);
       if(captureMethods){
         StringWriter writer = new StringWriter();
         ModifiedUnparseVisitor v = new ModifiedUnparseVisitor(writer);
diff --git a/sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Alternator.java b/sandbox/prototype/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Alternator.java
new file mode 100644 (file)
index 0000000..83f8368
--- /dev/null
@@ -0,0 +1,49 @@
+package org.apache.drill.exec.expr.fn.impl;
+
+import org.apache.drill.common.expression.CallProvider;
+import org.apache.drill.common.expression.FunctionDefinition;
+import org.apache.drill.common.expression.NoArgValidator;
+import org.apache.drill.common.expression.OutputTypeDeterminer;
+import org.apache.drill.common.types.TypeProtos.MinorType;
+import org.apache.drill.common.types.Types;
+import org.apache.drill.exec.expr.DrillFunc;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.annotations.Output;
+import org.apache.drill.exec.expr.annotations.Workspace;
+import org.apache.drill.exec.expr.holders.LongHolder;
+import org.apache.drill.exec.record.RecordBatch;
+
+
+
+@FunctionTemplate(name = "alternate", scope = FunctionScope.SIMPLE)
+public class Alternator implements DrillFunc{
+
+  @Workspace int val;
+  @Output LongHolder out;
+  
+  public void setup(RecordBatch incoming) {
+    val = 0;
+  }
+
+
+  public void eval() {
+    out.value = val;
+    if(val == 0){
+      val = 1;
+    }else{
+      val = 0;
+    }
+  }
+  
+  public static class Provider implements CallProvider{
+
+    @Override
+    public FunctionDefinition[] getFunctionDefintions() {
+      return new FunctionDefinition[]{
+          FunctionDefinition.simple("alternate", NoArgValidator.VALIDATOR, new OutputTypeDeterminer.FixedType(Types.required(MinorType.BIGINT)), "alternate")
+      };
+    }
+    
+  }
+}
index 27089ac..b188d5b 100644 (file)
@@ -116,7 +116,6 @@ public interface ValueVector extends Closeable {
      * @param index   Index of the value to get
      */
     public abstract Object getObject(int index);
-    
     public void reset();
   }
   
index 3ce903d..a543197 100644 (file)
@@ -1,6 +1,9 @@
 //  This file tells Drill to consider this module when class path scanning.  
 //  This file can also include any supplementary configuration information.  
 //  This file is in HOCON format, see https://github.com/typesafehub/config/blob/master/HOCON.md for more information.
+
+drill.logical.function.packages += "org.apache.drill.exec.expr.fn.impl"
+
 drill.exec: {
   cluster-id: "drillbits1"
   rpc: {
index df11aa7..e2bf25b 100644 (file)
@@ -1,5 +1,6 @@
 package org.apache.drill.exec.physical.impl.filter;
 
+import static org.junit.Assert.*;
 import mockit.Injectable;
 import mockit.NonStrictExpectations;
 
@@ -46,7 +47,7 @@ public class TestSimpleFilter {
     FragmentContext context = new FragmentContext(bitContext, FragmentHandle.getDefaultInstance(), connection, null, registry);
     SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
     while(exec.next()){
-      System.out.println(exec.getSelectionVector2().getCount());
+      assertEquals(50, exec.getSelectionVector2().getCount());
     }
   }
   
index a892c70..c9b367f 100644 (file)
@@ -23,7 +23,7 @@
             @id:2,
             child: 1,
             pop:"filter",
-            expr: "true"
+            expr: "alternate()"
         },
         {
             @id: 3,