drill-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tdunn...@apache.org
Subject git commit: DRILL-4 - First version of plan parser
Date Mon, 15 Oct 2012 05:04:19 GMT
Updated Branches:
  refs/heads/master 9229caa45 -> b4e471ae1


DRILL-4 - First version of plan parser


Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/b4e471ae
Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/b4e471ae
Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/b4e471ae

Branch: refs/heads/master
Commit: b4e471ae1115d0625b7db94d3154da3b61f91a6f
Parents: 9229caa
Author: tdunning <tdunning@apache.org>
Authored: Sun Oct 14 15:14:00 2012 -0700
Committer: tdunning <tdunning@apache.org>
Committed: Sun Oct 14 22:03:51 2012 -0700

----------------------------------------------------------------------
 sandbox/plan-parser/pom.xml                        |   52 +++++++
 .../main/antlr3/org/apache/drill/plan/ast/Plan.g   |   59 ++++++++
 .../main/java/org/apache/drill/plan/ParsePlan.java |  106 ++++++++++++++
 .../main/java/org/apache/drill/plan/ast/Arg.java   |   64 +++++++++
 .../drill/plan/ast/LogicalPlanParseException.java  |   11 ++
 .../main/java/org/apache/drill/plan/ast/Op.java    |   35 +++++
 .../main/java/org/apache/drill/plan/ast/Plan.java  |   29 ++++
 .../java/org/apache/drill/plan/ParsePlanTest.java  |  107 +++++++++++++++
 .../plan-parser/src/test/resources/plan1.drillx    |    3 +
 .../plan-parser/src/test/resources/plan2.drillx    |    9 ++
 .../plan-parser/src/test/resources/plan3.drillx    |   11 ++
 .../plan-parser/src/test/resources/plan4.drillx    |   13 ++
 12 files changed, 499 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b4e471ae/sandbox/plan-parser/pom.xml
----------------------------------------------------------------------
diff --git a/sandbox/plan-parser/pom.xml b/sandbox/plan-parser/pom.xml
new file mode 100644
index 0000000..f5ccb00
--- /dev/null
+++ b/sandbox/plan-parser/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>plan-parser</groupId>
+    <artifactId>plan-parser</artifactId>
+    <version>0.1</version>
+  <dependencies>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>10.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.antlr</groupId>
+      <artifactId>antlr</artifactId>
+      <version>3.4</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.8.2</version>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.antlr</groupId>
+        <artifactId>antlr3-maven-plugin</artifactId>
+        <version>3.4</version>
+
+        <executions>
+          <execution>
+            <id>antlr-generate</id>
+            <!-- this is used for inheritance merges -->
+            <phase>generate-sources</phase>
+            <!-- bind to the packaging phase -->
+            <goals>
+              <goal>antlr</goal>
+            </goals>
+          </execution>
+        </executions>
+
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b4e471ae/sandbox/plan-parser/src/main/antlr3/org/apache/drill/plan/ast/Plan.g
----------------------------------------------------------------------
diff --git a/sandbox/plan-parser/src/main/antlr3/org/apache/drill/plan/ast/Plan.g b/sandbox/plan-parser/src/main/antlr3/org/apache/drill/plan/ast/Plan.g
new file mode 100644
index 0000000..69a9ffb
--- /dev/null
+++ b/sandbox/plan-parser/src/main/antlr3/org/apache/drill/plan/ast/Plan.g
@@ -0,0 +1,59 @@
+grammar Plan;
+
+options {
+  output = AST;
+}
+
+@header {
+package org.apache.drill.plan.ast;
+import com.google.common.collect.Lists;
+}
+
+@lexer::header {
+package org.apache.drill.plan.ast;
+}
+
+@members {
+  public void reportError(RecognitionException e) {
+    throw new LogicalPlanParseException("Syntax error in schema: ", e);
+  }
+}
+
+plan returns [Plan r]: s=statements EOF {$r = $s.r;};
+
+statements returns [Plan r]:
+     s1 = statement {$r = Plan.create($s1.r);}
+     ( s2 = statement {$r = $r.add($s2.r);} )*
+     ;
+
+statement returns [Op r]:
+     to=targets GETS o=OP from=args LINE_ENDING {$r = Op.create($o.text, $from.r, $to.r);}
+     | LINE_ENDING {$r = null; };
+
+targets returns [List<Arg> r]:
+     a = symbol {$r = Lists.newArrayList($a.r);} ( COMMA b = symbol {$r.add($b.r);} )* ;
+
+symbol returns [Arg r]:
+     s = SYMBOL { $r = Arg.createSymbol($s.text); };
+
+args returns [List<Arg> r]: a = arg {$r = Lists.newArrayList($a.r);} ( COMMA b = arg
{$r.add($b.r);} )* ;
+
+arg returns [Arg r]:
+    s = STRING {$r = Arg.createString($s.text);}
+    | n = NUMBER {$r = Arg.createNumber($n.text);}
+    | b = BOOLEAN {$r = Arg.createBoolean($b.text);}
+    | s = SYMBOL {$r = Arg.createSymbol($s.text);}
+    ;
+
+
+STRING: ('"'|'�') ( ~('"' | '\\') | '\\' .)* ('"'|'�') ;
+GETS: ':=' ;
+BOOLEAN: 'true'|'false';
+SYMBOL: '%' ('0'..'9')+;
+OP: ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'-')*
+    | '>' | '<' | '>=' | '<=' | '+' | '-' | '*' | '/';
+COMMA: ',' ;
+NUMBER: ('0'..'9')+ ;
+LINE_ENDING: '\r'? '\n';
+COMMENT: '#' (~'\n')* {$channel=HIDDEN;} ;
+WHITESPACE : ( '\t' | ' ' )+ { $channel = HIDDEN; } ;

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b4e471ae/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ParsePlan.java
----------------------------------------------------------------------
diff --git a/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ParsePlan.java b/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ParsePlan.java
new file mode 100644
index 0000000..781bc62
--- /dev/null
+++ b/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ParsePlan.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.drill.plan;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.HashMultiset;
+import com.google.common.collect.Multiset;
+import com.google.common.io.Files;
+import com.google.common.io.InputSupplier;
+import com.google.common.io.Resources;
+import org.antlr.runtime.ANTLRReaderStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RecognitionException;
+import org.apache.drill.plan.ast.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Formatter;
+
+/**
+ * Parses a plan from a resource or file.
+ *
+ * The result is validated to ensure that symbols mentioned on the left-hand side of assignments
are only mentioned
+ * once and all referenced symbols on the right hand side are defined somewhere.
+ */
+public class ParsePlan {
+    public static Plan parseResource(File file) throws IOException, RecognitionException,
ValidationException {
+        return ParsePlan.parse(Files.newReaderSupplier(file, Charsets.UTF_8));
+    }
+
+    public static Plan parseResource(String resourceName) throws IOException, RecognitionException,
ValidationException {
+        return ParsePlan.parse(Resources.newReaderSupplier(Resources.getResource(resourceName),
Charsets.UTF_8));
+    }
+
+    public static Plan parse(InputSupplier<InputStreamReader> in) throws IOException,
RecognitionException, ValidationException {
+        InputStreamReader inStream = in.getInput();
+        PlanLexer lex = new PlanLexer(new ANTLRReaderStream(inStream));
+        PlanParser r = new PlanParser(new CommonTokenStream(lex));
+        inStream.close();
+
+        Plan plan = r.plan().r;
+        validate(plan);
+        return plan;
+    }
+
+    private static void validate(Plan r) throws ValidationException {
+        int errors = 0;
+        Formatter errorMessages = new Formatter();
+
+        // make sure that each output is assigned only once
+        Multiset<Integer> counts = HashMultiset.create();
+        int line = 1;
+        for (Op op : r.getStatements()) {
+            for (Arg assignment : op.getOutputs()) {
+                int slot = ((Arg.Symbol) assignment).getSlot();
+                counts.add(slot);
+                if (counts.count(slot) != 1) {
+                    errorMessages.format("Output symbol %%%d used more than once in statement
%d\n", slot, line);
+                    errors++;
+                }
+            }
+            line++;
+        }
+
+        // make sure that each input is defined at least once
+        line = 1;
+        for (Op op : r.getStatements()) {
+            for (Arg reference : op.getInputs()) {
+                if (reference instanceof Arg.Symbol) {
+                    int slot = ((Arg.Symbol) reference).getSlot();
+                    if (counts.count(slot) <= 0) {
+                        errorMessages.format("Undefined reference to %%%d in statement %d\n",
slot, line);
+                        errors++;
+                    }
+                }
+            }
+            line++;
+        }
+
+        if (errors > 0) {
+            throw new ValidationException(errorMessages.toString());
+        }
+    }
+
+    public static class ValidationException extends Exception {
+        public ValidationException(String s) {
+            super(s);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b4e471ae/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/Arg.java
----------------------------------------------------------------------
diff --git a/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/Arg.java b/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/Arg.java
new file mode 100644
index 0000000..1890bfd
--- /dev/null
+++ b/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/Arg.java
@@ -0,0 +1,64 @@
+package org.apache.drill.plan.ast;
+
+import com.google.common.base.CharMatcher;
+
+/**
+ * Created with IntelliJ IDEA. User: tdunning Date: 10/12/12 Time: 11:40 PM To change this
template
+ * use File | Settings | File Templates.
+ */
+public class Arg {
+    private static final CharMatcher quotes = CharMatcher.is('"');
+    private static final CharMatcher percent = CharMatcher.is('%');
+
+    public static Arg createString(String s) {
+        return new QuotedString(s);
+    }
+
+    public static Arg createNumber(String n) {
+        return new Number(Double.parseDouble(n));
+    }
+
+    public static Arg createSymbol(String s) {
+        return new Symbol(Integer.parseInt(percent.trimLeadingFrom(s)));
+    }
+
+    public static Arg createBoolean(String b) {
+        return new BooleanConstant(Boolean.parseBoolean(b));
+    }
+
+    public static class QuotedString extends Arg {
+        private String s;
+
+        public QuotedString(String s) {
+            this.s = quotes.trimFrom(quotes.trimFrom(s));
+        }
+    }
+
+    public static class BooleanConstant extends Arg {
+        private boolean v;
+
+        public BooleanConstant(boolean b) {
+            v = b;
+        }
+    }
+
+    public static class Number extends Arg {
+        private double value;
+
+        public Number(double v) {
+            value = v;
+        }
+    }
+
+    public static class Symbol extends Arg {
+        private int slot;
+
+        public Symbol(int slot) {
+            this.slot = slot;
+        }
+
+        public int getSlot() {
+            return slot;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b4e471ae/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/LogicalPlanParseException.java
----------------------------------------------------------------------
diff --git a/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/LogicalPlanParseException.java
b/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/LogicalPlanParseException.java
new file mode 100644
index 0000000..5e8a547
--- /dev/null
+++ b/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/LogicalPlanParseException.java
@@ -0,0 +1,11 @@
+package org.apache.drill.plan.ast;
+
+/**
+ * Created with IntelliJ IDEA. User: tdunning Date: 10/12/12 Time: 11:25 PM To change this
template
+ * use File | Settings | File Templates.
+ */
+public class LogicalPlanParseException extends RuntimeException {
+  public LogicalPlanParseException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b4e471ae/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/Op.java
----------------------------------------------------------------------
diff --git a/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/Op.java b/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/Op.java
new file mode 100644
index 0000000..e64414f
--- /dev/null
+++ b/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/Op.java
@@ -0,0 +1,35 @@
+package org.apache.drill.plan.ast;
+
+import java.util.List;
+
+/**
+* Created with IntelliJ IDEA. User: tdunning Date: 10/12/12 Time: 11:23 PM To change this
template
+* use File | Settings | File Templates.
+*/
+public class Op {
+  private String op;
+
+  private List<Arg> inputs;
+  private List<Arg> outputs;
+
+
+  public static Op create(String op, List<Arg> inputs, List<Arg> outputs) {
+    Op r = new Op();
+    r.op = op;
+    r.inputs = inputs;
+    r.outputs = outputs;
+    return r;
+  }
+
+  public List<Arg> getInputs() {
+    return inputs;
+  }
+
+  public String getOp() {
+    return op;
+  }
+
+  public List<Arg> getOutputs() {
+    return outputs;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b4e471ae/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/Plan.java
----------------------------------------------------------------------
diff --git a/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/Plan.java b/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/Plan.java
new file mode 100644
index 0000000..a0425a9
--- /dev/null
+++ b/sandbox/plan-parser/src/main/java/org/apache/drill/plan/ast/Plan.java
@@ -0,0 +1,29 @@
+package org.apache.drill.plan.ast;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+/**
+ * Created with IntelliJ IDEA. User: tdunning Date: 10/12/12 Time: 7:41 PM To change this
template
+ * use File | Settings | File Templates.
+ */
+public class Plan {
+  private List<Op> statements = Lists.newArrayList();
+
+  public static Plan create(Op first) {
+    Plan r = new Plan();
+    return r.add(first);
+  }
+
+  public Plan add(Op next) {
+      if (next != null) {
+          statements.add(next);
+      }
+      return this;
+  }
+
+  public List<Op> getStatements() {
+    return statements;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b4e471ae/sandbox/plan-parser/src/test/java/org/apache/drill/plan/ParsePlanTest.java
----------------------------------------------------------------------
diff --git a/sandbox/plan-parser/src/test/java/org/apache/drill/plan/ParsePlanTest.java b/sandbox/plan-parser/src/test/java/org/apache/drill/plan/ParsePlanTest.java
new file mode 100644
index 0000000..e90e8e4
--- /dev/null
+++ b/sandbox/plan-parser/src/test/java/org/apache/drill/plan/ParsePlanTest.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.drill.plan;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.Lists;
+import com.google.common.io.Resources;
+import org.antlr.runtime.ANTLRReaderStream;
+import org.antlr.runtime.RecognitionException;
+import org.antlr.runtime.Token;
+import org.apache.drill.plan.ast.Plan;
+import org.apache.drill.plan.ast.PlanLexer;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Iterator;
+import java.util.List;
+
+import static junit.framework.Assert.assertEquals;
+
+public class ParsePlanTest {
+    @Test
+    public void testParse1() throws IOException, RecognitionException, ParsePlan.ValidationException
{
+        Plan r = ParsePlan.parseResource("plan1.drillx");
+        assertEquals("Lines", 3, r.getStatements().size());
+    }
+
+    @Test
+    public void testParse2() throws IOException, RecognitionException, ParsePlan.ValidationException
{
+        Plan r = ParsePlan.parseResource("plan2.drillx");
+        assertEquals("Lines", 6, r.getStatements().size());
+    }
+
+    @Test
+    public void testParse3() throws IOException, RecognitionException, ParsePlan.ValidationException
{
+        Plan r = ParsePlan.parseResource("plan3.drillx");
+        assertEquals("Lines", 8, r.getStatements().size());
+    }
+
+    @Test
+    public void testLexer() throws IOException {
+        List<String> ref = Lists.newArrayList(
+                "%3", ",", "%4", ":=", "explode", "\"data\"", ",", "\"var-to-explode\"",
"\n",
+                "%5", ":=", "modify", "%4", "\n",
+                "%6", ",", "%7", ":=", "flatten", "%3", ",", "%5", "\n");
+
+        InputStreamReader inStream = Resources.newReaderSupplier(Resources.getResource("plan1.drillx"),
Charsets.UTF_8).getInput();
+        PlanLexer lex = new PlanLexer(new ANTLRReaderStream(inStream));
+        Token t = lex.nextToken();
+        Iterator<String> i = ref.iterator();
+        while (t != null && t.getType() != -1) {
+            if (t.getChannel() != 99) {
+                assertEquals(i.next(), t.getText());
+            }
+            t = lex.nextToken();
+        }
+        inStream.close();
+
+    }
+
+    @Test
+    public void testLexer2() throws IOException {
+        List<String> ref = Lists.newArrayList(
+                "%1", ":=", "scan-json", "\"table-1\"", "EOL",
+                "EOL",
+                "%2", ":=", "bind", "\"x\"", ",", "%1", "EOL",
+                "EOL",
+                "EOL",
+                "%3", ":=", "bind", "\"y\"", ",", "%2", "EOL",
+                "%4", ":=", ">", "%2", ",", "3", "EOL",
+                "%5", ":=", "filter", "%4", ",", "%1", "EOL",
+                "%6", ":=", "project", "%5", ",", "%2", ",", "%3", "EOL");
+
+        InputStreamReader inStream = Resources.newReaderSupplier(Resources.getResource("plan2.drillx"),
Charsets.UTF_8).getInput();
+        PlanLexer lex = new PlanLexer(new ANTLRReaderStream(inStream));
+        Token t = lex.nextToken();
+        Iterator<String> i = ref.iterator();
+        while (t != null && t.getType() != -1) {
+            if (t.getChannel() != 99) {
+                String tokenText = t.getText();
+                if (t.getText().equals("\n")) {
+                    tokenText = "EOL";
+                }
+                assertEquals(i.next(), tokenText);
+            }
+            t = lex.nextToken();
+        }
+        inStream.close();
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b4e471ae/sandbox/plan-parser/src/test/resources/plan1.drillx
----------------------------------------------------------------------
diff --git a/sandbox/plan-parser/src/test/resources/plan1.drillx b/sandbox/plan-parser/src/test/resources/plan1.drillx
new file mode 100644
index 0000000..2b35353
--- /dev/null
+++ b/sandbox/plan-parser/src/test/resources/plan1.drillx
@@ -0,0 +1,3 @@
+%3, %4 := explode "data", "var-to-explode"
+%5     := modify %4
+%6, %7 := flatten %3, %5

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b4e471ae/sandbox/plan-parser/src/test/resources/plan2.drillx
----------------------------------------------------------------------
diff --git a/sandbox/plan-parser/src/test/resources/plan2.drillx b/sandbox/plan-parser/src/test/resources/plan2.drillx
new file mode 100644
index 0000000..49e7b5a
--- /dev/null
+++ b/sandbox/plan-parser/src/test/resources/plan2.drillx
@@ -0,0 +1,9 @@
+%1 := scan-json "table-1"	# from table-1
+
+%2 := bind "x", %1		# variable x
+
+# full-line comment
+%3 := bind "y", %2		# and y
+%4 := > %2, 3			# where x > 3
+%5 := filter %4, %1		# apply the filter
+%6 := project %5, %2, %3	# select columns for final output

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b4e471ae/sandbox/plan-parser/src/test/resources/plan3.drillx
----------------------------------------------------------------------
diff --git a/sandbox/plan-parser/src/test/resources/plan3.drillx b/sandbox/plan-parser/src/test/resources/plan3.drillx
new file mode 100644
index 0000000..7f3ae43
--- /dev/null
+++ b/sandbox/plan-parser/src/test/resources/plan3.drillx
@@ -0,0 +1,11 @@
+#comment taking up a full line
+
+# and then a blank line
+%1 := scan-json "table-1"	# from table-1
+%2 := bind "a.x", %1		# we will sum a.x
+%3 := > %2, 3			# where x > 3
+%4 := filter %3, %1		# apply the filter
+%5 := aggregate "sum", %3, %2, %4
+%6 := as %5, "total", %4	# rename total
+%7 := bind "total", %6		# set up final select
+%9 := project %4, %6

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b4e471ae/sandbox/plan-parser/src/test/resources/plan4.drillx
----------------------------------------------------------------------
diff --git a/sandbox/plan-parser/src/test/resources/plan4.drillx b/sandbox/plan-parser/src/test/resources/plan4.drillx
new file mode 100644
index 0000000..b78e2fc
--- /dev/null
+++ b/sandbox/plan-parser/src/test/resources/plan4.drillx
@@ -0,0 +1,13 @@
+%1    := scan-json �table-1�
+%2   := bind �y�, %1
+%3   := bind �z�, %1
+%4,%5 := group %1, %2, %3         # group by y, z, group ref in %5
+%6    := explode %4, %5           # aggregate on group value
+%7    := bind �x�, %6             # sum(x), note where ref is bound
+%8    := aggregate �sum�, %6, %7
+%9,%10:= flatten %4, %8           # splice result back into data
+%11   := as %10, �s�, %9          # name the aggregated result
+%12   := bind �s�, %11
+%13   := bind �y�, %11
+%14   := bind �z�, %11
+%14   := project %11, %12, %13, %14   # select s,y,z


Mime
View raw message