Changeset: 7a0a5759557d for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/7a0a5759557d
Modified Files:
        cmake/os_release_info.cmake
        sql/server/rel_rel.h
        sql/server/rel_select.c
        sql/server/sql_parser.y
        sql/server/sql_scan.c
        sql/server/sql_symbol.c
        sql/server/sql_symbol.h
        sql/test/Tests/window_functions.test
        sql/test/analytics/Tests/analytics18.test
Branch: default
Log Message:

initial support for qualify


diffs (truncated from 558 to 300 lines):

diff --git a/cmake/os_release_info.cmake b/cmake/os_release_info.cmake
--- a/cmake/os_release_info.cmake
+++ b/cmake/os_release_info.cmake
@@ -29,7 +29,7 @@ set(_os_release_info TRUE)
 # of the local cmake environment.
 
 # Set cmake policies for at least this level:
-cmake_minimum_required(VERSION 3.5)
+cmake_minimum_required(VERSION 3.10)
 
 
 # Function get_os_release_info - Determine and return OS name and version
diff --git a/sql/server/rel_rel.h b/sql/server/rel_rel.h
--- a/sql/server/rel_rel.h
+++ b/sql/server/rel_rel.h
@@ -36,6 +36,7 @@
 #define sql_or           (1 << 16) //ORed
 #define sql_merge        (1 << 17) //ORed
 #define sql_no_subquery  (1 << 18) //ORed
+#define sql_qualify      (1 << 19) //ORed
 
 #define is_sql_from(X)         ((X & sql_from) == sql_from)
 #define is_sql_where(X)        ((X & sql_where) == sql_where)
@@ -56,6 +57,7 @@
 #define is_sql_or(X)           ((X & sql_or) == sql_or)
 #define is_sql_merge(X)        ((X & sql_merge) == sql_merge)
 #define is_sql_no_subquery(X)  ((X & sql_no_subquery) == sql_no_subquery)
+#define is_sql_qualify(X)      ((X & sql_qualify) == sql_qualify)
 
 #define is_anyequal_func(sf) (strcmp((sf)->func->base.name, "sql_anyequal") == 
0 || strcmp((sf)->func->base.name, "sql_not_anyequal") == 0)
 #define is_anyequal(sf) (strcmp((sf)->func->base.name, "sql_anyequal") == 0)
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
@@ -1508,10 +1508,6 @@ rel_column_ref(sql_query *query, sql_rel
                                else
                                        exp->card = CARD_ATOM;
                                set_freevar(exp, i);
-                               /*
-                               if (exp->alias.label == exp->nid)
-                                       exp->alias.label = -(sql->nid++);
-                                       */
                                if (!is_sql_where(of) && !is_sql_aggr(of) && 
!is_sql_aggr(f) && !outer->grouped)
                                        set_outer(outer);
                        }
@@ -1610,10 +1606,6 @@ rel_column_ref(sql_query *query, sql_rel
                                else
                                        exp->card = CARD_ATOM;
                                set_freevar(exp, i);
-                               /*
-                               if (exp->alias.label == exp->nid)
-                                       exp->alias.label = -(sql->nid++);
-                                       */
                                if (!is_sql_where(of) && !is_sql_aggr(of) && 
!is_sql_aggr(f) && !outer->grouped)
                                        set_outer(outer);
                        }
@@ -2356,115 +2348,6 @@ rel_in_exp(sql_query *query, sql_rel *re
        return rel_select_add_exp(sql->sa, rel, e);
 }
 
-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 symbol *
-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 */
-               if (sc->data.sym->token == SQL_ATOM) {
-                       AtomNode *an = (AtomNode*) sc->data.sym;
-                       sc = newAtomNode(sql->sa, an->a);
-               } else if (sc->data.sym->token == SQL_SELECT) {
-                       SelectNode *sn = (SelectNode*) sc->data.sym;
-                       sc = newSelectNode(sql->sa, sn->distinct, 
sn->selection, sn->into, sn->from, sn->where, sn->groupby, sn->having,
-                                                          sn->orderby, 
sn->name, sn->limit, sn->offset, sn->sample, sn->seed, sn->window);
-               } else {
-                       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 */
-               if (cmp_n->next->next->next) {
-                       switch(cmp_n->next->next->next->data.i_val)
-                       {
-                       case 0: /* negating ANY/ALL */
-                               cmp_n->next->next->next->data.i_val = 1;
-                               break;
-                       case 1: /* negating ANY/ALL */
-                               cmp_n->next->next->next->data.i_val = 0;
-                               break;
-                       case 2: /* negating IS [NOT] DINSTINCT FROM */
-                               cmp_n->next->next->next->data.i_val = 3;
-                               break;
-                       case 3: /* negating IS [NOT] DINSTINCT FROM */
-                               cmp_n->next->next->next->data.i_val = 2;
-                               break;
-                       }
-               }
-               cmp_n->next->data.sval = sa_strdup(sql->sa, 
compare_func(neg_cmp_type, 0));
-       } break;
-       case SQL_AND:
-       case SQL_OR: {
-               sc->data.lval->h->data.sym = negate_symbol_tree(sql, 
sc->data.lval->h->data.sym);
-               sc->data.lval->h->next->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;
-       }
-       return sc;
-}
-
 static int
 exp_between_check_types(sql_subtype *res, sql_subtype *t1, sql_subtype *t2, 
sql_subtype *t3)
 {
@@ -2742,10 +2625,6 @@ rel_logical_value_exp(sql_query *query, 
                return le;
        }
        case SQL_NOT: {
-               if (not_symbol_can_be_propagated(sql, sc->data.sym)) {
-                       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_value_exp(query, rel, sc->data.sym, 
f|sql_farg, ek);
 
                if (!le)
@@ -3015,10 +2894,6 @@ rel_logical_exp(sql_query *query, sql_re
                return rel_select_push_compare_exp_down(sql, rel, le, le->l, 
le->r, NULL, f);
        }
        case SQL_NOT: {
-               if (not_symbol_can_be_propagated(sql, sc->data.sym)) {
-                       sc->data.sym = negate_symbol_tree(sql, sc->data.sym);
-                       return rel_logical_exp(query, rel, sc->data.sym, f);
-               }
                sql_exp *le = rel_value_exp(query, &rel, sc->data.sym, 
f|sql_farg, ek);
                sql_subtype bt;
 
@@ -4912,7 +4787,7 @@ rel_rankop(sql_query *query, sql_rel **r
        }
 
        /* window operations are only allowed in the projection */
-       if (!is_sql_sel(f))
+       if (!is_sql_sel(f) && !is_sql_qualify(f))
                return sql_error(sql, 02, SQLSTATE(42000) "OVER: only possible 
within the selection");
 
        p = *rel;
@@ -5488,50 +5363,48 @@ rel_table_exp(sql_query *query, sql_rel 
                return NULL;
        }
 
-
-               list *exps = NULL;
-               sql_rel *project = *rel, *groupby = NULL;
-
-               /* if there's a group by relation in the tree, skip it for the 
'*' case and use the underlying projection */
-               if (project) {
-                       while (is_groupby(project->op) || 
is_select(project->op)) {
-                               if (is_groupby(project->op))
-                                       groupby = project;
-                               if (project->l)
-                                       project = project->l;
-                       }
-                       assert(project);
-               }
-
-               if (project->op == op_project && project->l && project == *rel 
&& !tname && !rel_is_ref(project) && !need_distinct(project) && single_exp) {
-                       sql_rel *l = project->l;
-                       if (!l || !is_project(l->op) || 
list_length(project->exps) == list_length(l->exps)) {
-                               rel_remove_internal_exp(*rel);
-                               exps = project->exps;
-                               *rel = project->l;
-                       }
-               }
-               if ((exps || (exps = rel_table_projections(sql, project, tname, 
0)) != NULL) && !list_empty(exps)) {
-                       if (!(exps = check_distinct_exp_names(sql, exps)))
-                               return sql_error(sql, 02, SQLSTATE(42000) 
"Duplicate column names in table%s%s%s projection list", tname ? " '" : "", 
tname ? tname : "", tname ? "'" : "");
-                       if (groupby) {
-                               groupby->exps = group_merge_exps(sql, 
groupby->exps, exps);
-                               for (node *n = groupby->exps->h ; n ; n = 
n->next) {
-                                       sql_exp *e = n->data;
-
-                                       if (e->card > groupby->card) {
-                                               if (exp_name(e) && 
!has_label(e))
-                                                       return sql_error(sql, 
ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in 
query results without an aggregate function", exp_name(e));
-                                               return sql_error(sql, 
ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query 
results without an aggregate function");
-                                       }
+       list *exps = NULL;
+       sql_rel *project = *rel, *groupby = NULL;
+
+       /* if there's a group by relation in the tree, skip it for the '*' case 
and use the underlying projection */
+       if (project) {
+               while (is_groupby(project->op) || is_select(project->op)) {
+                       if (is_groupby(project->op))
+                               groupby = project;
+                       if (project->l)
+                               project = project->l;
+               }
+               assert(project);
+       }
+
+       if (project->op == op_project && project->l && project == *rel && 
!tname && !rel_is_ref(project) && !need_distinct(project) && single_exp) {
+               sql_rel *l = project->l;
+               if (!l || !is_project(l->op) || list_length(project->exps) == 
list_length(l->exps)) {
+                       rel_remove_internal_exp(*rel);
+                       exps = project->exps;
+                       *rel = project->l;
+               }
+       }
+       if ((exps || (exps = rel_table_projections(sql, project, tname, 0)) != 
NULL) && !list_empty(exps)) {
+               if (!(exps = check_distinct_exp_names(sql, exps)))
+                       return sql_error(sql, 02, SQLSTATE(42000) "Duplicate 
column names in table%s%s%s projection list", tname ? " '" : "", tname ? tname 
: "", tname ? "'" : "");
+               if (groupby) {
+                       groupby->exps = group_merge_exps(sql, groupby->exps, 
exps);
+                       for (node *n = groupby->exps->h ; n ; n = n->next) {
+                               sql_exp *e = n->data;
+
+                               if (e->card > groupby->card) {
+                                       if (exp_name(e) && !has_label(e))
+                                               return sql_error(sql, 
ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in 
query results without an aggregate function", exp_name(e));
+                                       return sql_error(sql, ERR_GROUPBY, 
SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results 
without an aggregate function");
                                }
                        }
-                       return exps;
-               }
-               if (!tname)
-                       return sql_error(sql, 02, SQLSTATE(42000) "Table 
expression without table name");
-               return sql_error(sql, 02, SQLSTATE(42000) "Column expression 
Table '%s' unknown", tname);
-       //return NULL;
+               }
+               return exps;
+       }
+       if (!tname)
+               return sql_error(sql, 02, SQLSTATE(42000) "Table expression 
without table name");
+       return sql_error(sql, 02, SQLSTATE(42000) "Column expression Table '%s' 
unknown", tname);
 }
 
 sql_exp *
@@ -5616,6 +5489,11 @@ rel_having_limits_nodes(sql_query *query
                        rel->l = inner;
        }
 
+       if (sn->qualify) {
+               if (!(rel = rel_logical_exp(query, rel, sn->qualify, 
sql_qualify)))
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to