Changeset: 5ed6b50c85cb for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5ed6b50c85cb
Modified Files:
        sql/server/rel_select.c
Branch: Jun2020
Log Message:

Propagate not through 'and' and 'or' symbols if possible. No more rewrites on 
this file today


diffs (164 lines):

diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -2208,52 +2208,90 @@ rel_in_exp(sql_query *query, sql_rel *re
        return rel_select_add_exp(sql->sa, rel, e);;
 }
 
-#define SIMPLIFY_NOT(sc, NEXT_CALL) \
-       switch (sc->data.sym->token) { \
-       case SQL_IN: \
-               sc->data.sym->token = SQL_NOT_IN; \
-               return NEXT_CALL; \
-       case SQL_NOT_IN: \
-               sc->data.sym->token = SQL_IN; \
-               return NEXT_CALL; \
-       case SQL_EXISTS: \
-               sc->data.sym->token = SQL_NOT_EXISTS; \
-               return NEXT_CALL; \
-       case SQL_NOT_EXISTS: \
-               sc->data.sym->token = SQL_EXISTS; \
-               return NEXT_CALL; \
-       case SQL_LIKE: \
-               sc->data.sym->token = SQL_NOT_LIKE; \
-               return NEXT_CALL; \
-       case SQL_NOT_LIKE: \
-               sc->data.sym->token = SQL_LIKE; \
-               return NEXT_CALL; \
-       case SQL_BETWEEN: \
-               sc->data.sym->token = SQL_NOT_BETWEEN; \
-               return NEXT_CALL; \
-       case SQL_NOT_BETWEEN: \
-               sc->data.sym->token = SQL_BETWEEN; \
-               return NEXT_CALL; \
-       case SQL_IS_NULL: \
-               sc->data.sym->token = SQL_IS_NOT_NULL; \
-               return NEXT_CALL; \
-       case SQL_IS_NOT_NULL: \
-               sc->data.sym->token = SQL_IS_NULL; \
-               return NEXT_CALL; \
-       case SQL_NOT: /* nested NOTs eliminate each other */ \
-               sc->data.sym = sc->data.sym->data.sym; \
-               return NEXT_CALL; \
-       case SQL_COMPARE: { \
-               dnode *cmp_n = sc->data.sym->data.lval->h; \
-               comp_type neg_cmp_type = 
negate_compare(compare_str2type(cmp_n->next->data.sval)); /* negate the 
comparator */ \
-               cmp_n->next->data.sval = sa_strdup(sql->sa, 
compare_func(neg_cmp_type, 0)); \
-               if (cmp_n->next->next->next) /* negating ANY/ALL */ \
-                       cmp_n->next->next->next->data.i_val = 
cmp_n->next->next->next->data.i_val == 0 ? 1 : 0; \
-               return NEXT_CALL; \
-       } \
-       default: \
-               break; \
+static bool 
+not_symbol_can_be_propagated(mvc *sql, symbol *sc)
+{
+       switch (sc->token) {
+       case SQL_IN:
+       case SQL_NOT_IN:
+       case SQL_EXISTS:
+       case SQL_NOT_EXISTS:
+       case SQL_LIKE:
+       case SQL_NOT_LIKE:
+       case SQL_BETWEEN:
+       case SQL_NOT_BETWEEN:
+       case SQL_IS_NULL:
+       case SQL_IS_NOT_NULL:
+       case SQL_NOT:
+       case SQL_COMPARE:
+               return true;
+       case SQL_AND:
+       case SQL_OR: {
+               symbol *lo = sc->data.lval->h->data.sym;
+               symbol *ro = sc->data.lval->h->next->data.sym;
+               return not_symbol_can_be_propagated(sql, lo) && 
not_symbol_can_be_propagated(sql, ro);
+       }
+       default:
+               return false;
        } 
+}
+
+/* Warning, this function assumes the entire bison tree can be negated, so 
call it after 'not_symbol_can_be_propagated' */
+static void
+negate_symbol_tree(mvc *sql, symbol *sc)
+{
+       switch (sc->token) {
+       case SQL_IN:
+               sc->token = SQL_NOT_IN;
+               break;
+       case SQL_NOT_IN:
+               sc->token = SQL_IN;
+               break;
+       case SQL_EXISTS:
+               sc->token = SQL_NOT_EXISTS;
+               break;
+       case SQL_NOT_EXISTS:
+               sc->token = SQL_EXISTS;
+               break;
+       case SQL_LIKE:
+               sc->token = SQL_NOT_LIKE;
+               break;
+       case SQL_NOT_LIKE:
+               sc->token = SQL_LIKE;
+               break;
+       case SQL_BETWEEN:
+               sc->token = SQL_NOT_BETWEEN;
+               break;
+       case SQL_NOT_BETWEEN:
+               sc->token = SQL_BETWEEN;
+               break;
+       case SQL_IS_NULL:
+               sc->token = SQL_IS_NOT_NULL;
+               break;
+       case SQL_IS_NOT_NULL:
+               sc->token = SQL_IS_NULL;
+               break;
+       case SQL_NOT: /* nested NOTs eliminate each other */
+               memmove(sc, sc->data.sym, sizeof(symbol));
+               break;
+       case SQL_COMPARE: {
+               dnode *cmp_n = sc->data.lval->h;
+               comp_type neg_cmp_type = 
negate_compare(compare_str2type(cmp_n->next->data.sval)); /* negate the 
comparator */
+               cmp_n->next->data.sval = sa_strdup(sql->sa, 
compare_func(neg_cmp_type, 0));
+               if (cmp_n->next->next->next) /* negating ANY/ALL */
+                       cmp_n->next->next->next->data.i_val = 
cmp_n->next->next->next->data.i_val == 0 ? 1 : 0;
+       } break;
+       case SQL_AND:
+       case SQL_OR: {
+               negate_symbol_tree(sql, sc->data.lval->h->data.sym);
+               negate_symbol_tree(sql, sc->data.lval->h->next->data.sym);
+               sc->token = sc->token == SQL_AND ? SQL_OR : SQL_AND;
+               break;
+       }
+       default:
+               break;
+       }
+}
 
 sql_exp *
 rel_logical_value_exp(sql_query *query, sql_rel **rel, symbol *sc, int f, 
exp_kind ek)
@@ -2511,7 +2549,10 @@ rel_logical_value_exp(sql_query *query, 
                return le;
        }
        case SQL_NOT: {
-               SIMPLIFY_NOT(sc, rel_logical_value_exp(query, rel, 
sc->data.sym, f, ek));
+               if (not_symbol_can_be_propagated(sql, sc->data.sym)) {
+                       negate_symbol_tree(sql, sc->data.sym);
+                       return rel_logical_value_exp(query, rel, sc->data.sym, 
f, ek);
+               }
                sql_exp *le = rel_logical_value_exp(query, rel, sc->data.sym, 
f, ek);
 
                if (!le)
@@ -2825,7 +2866,11 @@ rel_logical_exp(sql_query *query, sql_re
        }
        case SQL_NOT: {
                sql_exp *le, *ls;
-               SIMPLIFY_NOT(sc, rel_logical_exp(query, rel, sc->data.sym, f));
+
+               if (not_symbol_can_be_propagated(sql, sc->data.sym)) {
+                       negate_symbol_tree(sql, sc->data.sym);
+                       return rel_logical_exp(query, rel, sc->data.sym, f);
+               }
                ls = le = rel_value_exp(query, &rel, sc->data.sym, f|sql_farg, 
ek);
 
                if (!le)
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to