Changeset: fc84952632ec for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=fc84952632ec
Modified Files:
        monetdb5/extras/jaql/jaql.c
        monetdb5/extras/jaql/jaqltree.h
Branch: default
Log Message:

filter: pre-compute static comparisons


diffs (275 lines):

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
@@ -175,6 +175,23 @@ make_jaql_filter(tree *var, tree *pred)
                return pred;
        }
 
+       if (pred->type == j_bool) {
+               if (pred->nval) {
+                       freetree(var);
+                       freetree(pred);
+                       return NULL;
+               } else {
+                       /* false, must somehow inject null-pipe, return error 
for
+                        * now */
+                       freetree(var);
+                       freetree(pred);
+                       res = GDKzalloc(sizeof(tree));
+                       res->type = j_error;
+                       res->sval = GDKstrdup("filter: condition always yields 
to false");
+                       return res;
+               }
+       }
+
        assert(pred->type == j_pred);
        
        if ((res = _check_exp_var1("filter", var->sval, pred)) != NULL) {
@@ -615,6 +632,8 @@ make_pred(tree *l, tree *comp, tree *r)
 {
        tree *res;
 
+       assert(r != NULL);
+
        if (l != NULL && l->type == j_error) {
                freetree(comp);
                freetree(r);
@@ -641,7 +660,9 @@ make_pred(tree *l, tree *comp, tree *r)
                return r;
        }
 
-       if (r->type == j_bool && comp->cval != j_nequal && comp->cval != 
j_equals)
+       if ((r->type == j_bool || l->type == j_bool)
+                       && comp->cval != j_nequal && comp->cval != j_equals
+                       && comp->cval != j_and && comp->cval != j_or)
        {
                freetree(l);
                freetree(comp);
@@ -649,10 +670,194 @@ make_pred(tree *l, tree *comp, tree *r)
 
                res = GDKzalloc(sizeof(tree));
                res->type = j_error;
-               res->sval = GDKstrdup("filter: can only apply equality tests on 
booleans");
+               res->sval = GDKstrdup("filter: can only apply equality tests "
+                               "on booleans");
                return res;
        }
 
+       assert(l != NULL && comp != NULL);
+
+       /* switch arguments such that left is always <= in type compared to
+        * right */
+       if (comp->cval == j_equals || comp->cval == j_nequal
+                       || comp->cval == j_greater || comp->cval == j_gequal
+                       || comp->cval == j_less || comp->cval == j_lequal)
+       {
+               if (l->type > r->type) {
+                       tree *t = r;
+                       r = l;
+                       l = t;
+                       switch (comp->cval) {
+                               case j_greater:
+                                       comp->cval = j_less;
+                                       break;
+                               case j_gequal:
+                                       comp->cval = j_lequal;
+                                       break;
+                               case j_less:
+                                       comp->cval = j_greater;
+                                       break;
+                               case j_lequal:
+                                       comp->cval = j_gequal;
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+       }
+
+       /* precompute static statements */
+       switch (l->type) {
+               char eval;
+               case j_bool: {
+                       /* comparators have been checked above */
+                       if (r->type == j_bool) {
+                               eval = l->nval == r->nval;
+                       } else if (r->type == j_num || r->type == j_dbl) {
+                               eval = (l->nval && r->nval)
+                                       || (!l->nval && !r->nval);
+                       } else {
+                               freetree(l);
+                               freetree(comp);
+                               freetree(r);
+
+                               res = GDKzalloc(sizeof(tree));
+                               res->type = j_error;
+                               res->sval = GDKstrdup("filter: boolean 
comparison "
+                                               "with non-boolean not 
supported");
+                               return res;
+                       }
+
+                       freetree(l);
+                       freetree(comp);
+                       freetree(r);
+
+                       res = GDKzalloc(sizeof(tree));
+                       res->type = j_bool;
+                       res->nval = comp->cval == j_nequal ? !eval : eval;
+                       return res;
+               }
+               case j_num: {
+               case j_dbl:
+                       if (r->type == j_num || r->type == j_dbl) {
+                               double a, b;
+                               if (l->type == j_num && r->type == j_dbl) {
+                                       a = (double)l->nval;
+                                       b = r->dval;
+                               } else if (l->type == j_num) {
+                                       a = (double)l->nval;
+                                       b = (double)r->nval;
+                               } else {
+                                       a = l->dval;
+                                       b = r->dval;
+                               }
+                               switch (comp->cval) {
+                                       case j_equals:
+                                               eval = a == b;
+                                               break;
+                                       case j_nequal:
+                                               eval = a != b;
+                                               break;
+                                       case j_greater:
+                                               eval = a > b;
+                                               break;
+                                       case j_gequal:
+                                               eval = a >= b;
+                                               break;
+                                       case j_less:
+                                               eval = a < b;
+                                               break;
+                                       case j_lequal:
+                                               eval = a <= b;
+                                               break;
+                                       default:
+                                               freetree(l);
+                                               freetree(comp);
+                                               freetree(r);
+
+                                               res = GDKzalloc(sizeof(tree));
+                                               res->type = j_error;
+                                               res->sval = GDKstrdup("filter: 
operations IN, NOT, "
+                                                               "OR, AND on 
numbers not supported");
+                                               return res;
+                               }
+
+                               freetree(l);
+                               freetree(comp);
+                               freetree(r);
+
+                               res = GDKzalloc(sizeof(tree));
+                               res->type = j_bool;
+                               res->nval = eval;
+                               return res;
+                       } else {
+                               freetree(l);
+                               freetree(comp);
+                               freetree(r);
+
+                               res = GDKzalloc(sizeof(tree));
+                               res->type = j_error;
+                               res->sval = GDKstrdup("filter: number 
comparison "
+                                               "with non-number not 
supported");
+                               return res;
+                       }
+               }
+               case j_str:
+                       if (r->type == j_str) {
+                               switch (comp->cval) {
+                                       case j_equals:
+                                               eval = strcmp(l->sval, r->sval) 
== 0;
+                                               break;
+                                       case j_nequal:
+                                               eval = strcmp(l->sval, r->sval) 
!= 0;
+                                               break;
+                                       case j_greater:
+                                               eval = strcmp(l->sval, r->sval) 
> 0;
+                                               break;
+                                       case j_gequal:
+                                               eval = strcmp(l->sval, r->sval) 
>= 0;
+                                               break;
+                                       case j_less:
+                                               eval = strcmp(l->sval, r->sval) 
< 0;
+                                               break;
+                                       case j_lequal:
+                                               eval = strcmp(l->sval, r->sval) 
<= 0;
+                                               break;
+                                       default:
+                                               freetree(l);
+                                               freetree(comp);
+                                               freetree(r);
+
+                                               res = GDKzalloc(sizeof(tree));
+                                               res->type = j_error;
+                                               res->sval = GDKstrdup("filter: 
operations IN, NOT, "
+                                                               "OR, AND on 
strings not supported");
+                                               return res;
+                               }
+
+                               freetree(l);
+                               freetree(comp);
+                               freetree(r);
+
+                               res = GDKzalloc(sizeof(tree));
+                               res->type = j_bool;
+                               res->nval = eval;
+                               return res;
+                       } else {
+                               freetree(l);
+                               freetree(comp);
+                               freetree(r);
+
+                               res = GDKzalloc(sizeof(tree));
+                               res->type = j_error;
+                               res->sval = GDKstrdup("filter: string 
comparison "
+                                               "with non-string not 
supported");
+                               return res;
+                       }
+               default:
+                       break;
+       }
+
        res = GDKzalloc(sizeof(tree));
        res->type = j_pred;
        res->tval1 = l;
diff --git a/monetdb5/extras/jaql/jaqltree.h b/monetdb5/extras/jaql/jaqltree.h
--- a/monetdb5/extras/jaql/jaqltree.h
+++ b/monetdb5/extras/jaql/jaqltree.h
@@ -52,11 +52,15 @@ typedef struct _jc {
 
 enum treetype {
        j_invalid,
-       j_output_var,
-       j_output,
+       j_bool,
+       j_num,
+       j_dbl,
+       j_str,
        j_json,
        j_json_obj,
        j_json_arr,
+       j_output_var,
+       j_output,
        j_filter,
        j_transform,
        j_expand,
@@ -75,10 +79,6 @@ enum treetype {
        j_arr_idx,
        j_pair,
        j_var,
-       j_num,
-       j_dbl,
-       j_str,
-       j_bool,
        j_func,
        j_func_arg,
        j_error
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to