Changeset: 1fc76d2e806d for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1fc76d2e806d
Modified Files:
        monetdb5/extras/jaql/Tests/plan00.mal
        monetdb5/extras/jaql/Tests/plan00.stable.out
        monetdb5/extras/jaql/jaql.c
        monetdb5/extras/jaql/jaql.h
        monetdb5/extras/jaql/parser/jaql.l
        monetdb5/extras/jaql/parser/jaql.y
Branch: jacqueline
Log Message:

expand: add parsing support for expand unroll

expand unroll is a variant of expand that multiplies the parent of the
referenced array by the arity of the values, e.g. it results in as many
objects the parent is, but instead of the array member, for each one of
its array values.


diffs (168 lines):

diff --git a/monetdb5/extras/jaql/Tests/plan00.mal 
b/monetdb5/extras/jaql/Tests/plan00.mal
--- a/monetdb5/extras/jaql/Tests/plan00.mal
+++ b/monetdb5/extras/jaql/Tests/plan00.mal
@@ -7,6 +7,7 @@ jaql.x("plan [ {id:1, dept:1, income:120
 
 jaql.x("plan [ [3,65,8,72], [5,98,2,65] ] -> expand each arr;");
 jaql.x("plan [ {\"name\":\"Jon Doe\", \"movie_ids\":[3,65,8,72]}, 
{\"name\":\"Jane Dean\",\"movie_ids\":[5,98,2]} ] -> expand $.movie_ids;");
+jaql.x("plan [ {\"name\":\"Jon Doe\", \"movie_ids\":[3,65,8,72]}, 
{\"name\":\"Jane Dean\",\"movie_ids\":[5,98,2]} ] -> expand unroll 
$.movie_ids;");
 jaql.x("plan A -> expand -> transform $ * 2;");
 jaql.x("plan A -> expand $.ids;");
 
diff --git a/monetdb5/extras/jaql/Tests/plan00.stable.out 
b/monetdb5/extras/jaql/Tests/plan00.stable.out
--- a/monetdb5/extras/jaql/Tests/plan00.stable.out
+++ b/monetdb5/extras/jaql/Tests/plan00.stable.out
@@ -25,6 +25,7 @@ function user.main():void;
     jaql.x("plan [ {id:1, dept:1, income:12000},{id:2, dept:1, income:13000} ] 
-> filter $.dept == 1;");
     jaql.x("plan [ [3,65,8,72], [5,98,2,65] ] -> expand each arr;");
     jaql.x("plan [ {\"name\":\"Jon Doe\", \"movie_ids\":[3,65,8,72]}, 
{\"name\":\"Jane Dean\",\"movie_ids\":[5,98,2]} ] -> expand $.movie_ids;");
+    jaql.x("plan [ {\"name\":\"Jon Doe\", \"movie_ids\":[3,65,8,72]}, 
{\"name\":\"Jane Dean\",\"movie_ids\":[5,98,2]} ] -> expand unroll 
$.movie_ids;");
     jaql.x("plan A -> expand -> transform $ * 2;");
     jaql.x("plan A -> expand $.ids;");
     jaql.x("plan [1,2,3] -> transform {\"value\":$};");
@@ -44,6 +45,7 @@ e as $ -> filter: ( ( $.mgr == true ) ||
 [ {id:1, dept:1, income:12000},{id:2, dept:1, income:13000} ] as $ -> filter: 
( $.dept == 1 ) => <result> 
 [ [3,65,8,72], [5,98,2,65] ] as arr -> expand: arr => <result> 
 [ {"name":"Jon Doe", "movie_ids":[3,65,8,72]}, {"name":"Jane 
Dean","movie_ids":[5,98,2]} ] as $ -> expand: $.movie_ids => <result> 
+[ {"name":"Jon Doe", "movie_ids":[3,65,8,72]}, {"name":"Jane 
Dean","movie_ids":[5,98,2]} ] as $ -> expand: unroll $.movie_ids => <result> 
 A as $ -> expand: $ as $ -> transform: ( $ * 2 ) 
 A as $ -> expand: $.ids => <result> 
 [1,2,3] as $ -> transform: { "value": $ } 
diff --git a/monetdb5/extras/jaql/jaql.c b/monetdb5/extras/jaql/jaql.c
--- a/monetdb5/extras/jaql/jaql.c
+++ b/monetdb5/extras/jaql/jaql.c
@@ -235,7 +235,7 @@ make_jaql_expand(tree *var, tree *expr)
        res->tval1 = var;
 
        assert(var->type == j_var);
-       assert(expr == NULL || expr->type == j_var);
+       assert(expr == NULL || expr->type == j_var || expr->type == j_unroll);
 
        /* make execution easier by always giving expand an argument to
         * expand, which defaults to the var we're looping over as (usually
@@ -244,18 +244,26 @@ make_jaql_expand(tree *var, tree *expr)
                expr = GDKzalloc(sizeof(tree));
                expr->type = j_var;
                expr->sval = GDKstrdup(var->sval);
-       } else if (strcmp(var->sval, expr->sval) != 0) {
-               char buf[128];
-               snprintf(buf, sizeof(buf), "expand: unknown variable: %s", 
expr->sval);
-               res->type = j_error;
-               res->sval = GDKstrdup(buf);
-               res->tval1 = NULL;
-               freetree(expr);
-               freetree(var);
-               return res;
+       } else {
+               char *v;
+               if (expr->type == j_var)
+                       v = expr->sval;
+               if (expr->type == j_unroll && expr->tval1->type == j_var)
+                       v = expr->tval1->sval;
+               assert(v != NULL);
+               if (strcmp(var->sval, v) != 0) {
+                       char buf[128];
+                       snprintf(buf, sizeof(buf), "expand: unknown variable: 
%s", v);
+                       res->type = j_error;
+                       res->sval = GDKstrdup(buf);
+                       res->tval1 = NULL;
+                       freetree(expr);
+                       freetree(var);
+                       return res;
+               }
        }
 
-       if (expr->next != NULL) {
+       if (expr->type == j_var && expr->next != NULL) {
                /* JAQL's confusing "inner pipes" feature -- most probably to
                 * steer Hadoop's map-reduce job generationi -- is just useless
                 * for us and actually making our life harder, so just pull out
@@ -269,6 +277,21 @@ make_jaql_expand(tree *var, tree *expr)
        return res;
 }
 
+/* create a wrapper for expand unroll */
+tree *
+make_unroll(tree *var)
+{
+       tree *res;
+
+       assert(var != NULL && var->type == j_var);
+
+       res = GDKzalloc(sizeof(tree));
+       res->type = j_unroll;
+       res->tval1 = var;
+
+       return res;
+}
+
 /* create a sort operation defined by comparator in expr */
 tree *
 make_jaql_sort(tree *var, tree *expr)
@@ -834,6 +857,16 @@ printtree(tree *t, int level, char op)
                                                break;
                                }
                                break;
+                       case j_unroll:
+                               if (op) {
+                                       printf("j_unroll( ");
+                                       printtree(t->tval1, level + step, op);
+                                       printf(") ");
+                               } else {
+                                       printf("unroll ");
+                                       printtree(t->tval1, level + step, op);
+                               }
+                               break;
                        case j_pred:
                                if (op) {
                                        printf("j_pred( ");
diff --git a/monetdb5/extras/jaql/jaql.h b/monetdb5/extras/jaql/jaql.h
--- a/monetdb5/extras/jaql/jaql.h
+++ b/monetdb5/extras/jaql/jaql.h
@@ -64,6 +64,7 @@ enum treetype {
        j_filter,
        j_transform,
        j_expand,
+       j_unroll,
        j_sort,
        j_top,
        j_comp,
@@ -119,6 +120,7 @@ tree *make_jaql_transform(tree *var, tre
 tree *make_jaql_expand(tree *var, tree *expr);
 tree *make_jaql_sort(tree *var, tree *expr);
 tree *make_jaql_top(long long int num);
+tree *make_unroll(tree *var);
 tree *make_pred(tree *var, tree *comp, tree *value);
 tree *make_sort_arg(tree *var, char asc);
 tree *append_sort_arg(tree *osarg, tree *nsarg);
diff --git a/monetdb5/extras/jaql/parser/jaql.l 
b/monetdb5/extras/jaql/parser/jaql.l
--- a/monetdb5/extras/jaql/parser/jaql.l
+++ b/monetdb5/extras/jaql/parser/jaql.l
@@ -51,6 +51,7 @@ each       return EACH;
 filter     return FILTER;
 transform  return TRANSFORM;
 expand     return EXPAND;
+unroll     return UNROLL;
 group      return GROUP;
 into       return INTO;
 by         return BY;
diff --git a/monetdb5/extras/jaql/parser/jaql.y 
b/monetdb5/extras/jaql/parser/jaql.y
--- a/monetdb5/extras/jaql/parser/jaql.y
+++ b/monetdb5/extras/jaql/parser/jaql.y
@@ -21,7 +21,7 @@
 %token LEX_ERROR
 
 %token EACH FILTER TRANSFORM EXPAND GROUP INTO BY AS JOIN WHERE IN
-%token SORT TOP DESC ASC EXPLAIN PLAN PLANF
+%token SORT TOP DESC ASC EXPLAIN PLAN PLANF UNROLL
 
 %token _ARROW _DOLLAR _ASSIGN _EQUALS _NEQUAL _TRUE _FALSE
 %token _GREATER _GEQUAL _LESS _LEQUAL _NOT _AND _OR _SCOLON _DOT
@@ -134,6 +134,7 @@ action: FILTER opt_each predicates      
 
 opt_command: /* empty */            {$$ = NULL;}
                   | variable               {$$ = $1;}
+                  | UNROLL variable        {$$ = make_unroll($2);}
                   | '(' ident actions ')'  {$$ = 
append_jaql_pipe(make_varname($2), $3);}
                   ;
 
_______________________________________________
Checkin-list mailing list
Checkin-list@monetdb.org
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to