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