Changeset: cc19c3e6a79a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=cc19c3e6a79a
Modified Files:
        sql/server/rel_select.c
        sql/server/sql_parser.y
        sql/test/analytics/Tests/analytics01.sql
        sql/test/analytics/Tests/analytics01.stable.err
Branch: statistics-analytics
Log Message:

Add distinct case to rank functions


diffs (224 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
@@ -4459,7 +4459,7 @@ rel_rankop(sql_query *query, sql_rel **r
        sql_rel *p;
        list *gbe = NULL, *obe = NULL, *args = NULL, *types = NULL, *fargs = 
NULL;
        sql_schema *s = sql->session->schema;
-       dnode *dn = window_function->data.lval->h;
+       dnode *dn = window_function->data.lval->h, *dargs = NULL;
        int distinct = 0, frame_type, pos, nf = f;
        bool is_nth_value, supports_frames;
 
@@ -4546,13 +4546,13 @@ rel_rankop(sql_query *query, sql_rel **r
 
        fargs = sa_list(sql->sa);
        if (window_function->token == SQL_RANK) { /* rank function call */
-               dlist* dnn = window_function->data.lval->h->next->data.lval;
+               dlist *dl = dn->next->data.lval;
                bool is_ntile = (strcmp(s->base.name, "sys") == 0 && 
strcmp(aname, "ntile") == 0),
                         is_lag = (strcmp(s->base.name, "sys") == 0 && 
strcmp(aname, "lag") == 0),
                         is_lead = (strcmp(s->base.name, "sys") == 0 && 
strcmp(aname, "lead") == 0);
                int nfargs = 0;
 
-               if (!dnn || is_ntile) { /* pass an input column for analytic 
functions that don't require it */
+               if (!dl || is_ntile) { /* pass an input column for analytic 
functions that don't require it */
                        in = rel_first_column(sql, p);
                        if (is_atom(in->type)) {
                                in = exp_copy(sql, in);
@@ -4566,11 +4566,11 @@ rel_rankop(sql_query *query, sql_rel **r
                        append(fargs, in);
                        nfargs++;
                }
-               if (dnn) {
-                       for (dnode *nn = dnn->h ; nn ; nn = nn->next) {
+               if (dl)
+                       for (dargs = dl->h ; dargs ; dargs = dargs->next) { /* 
the last dnode is the distinct flag */
                                exp_kind ek = {type_value, card_column, FALSE};
 
-                               in = rel_value_exp2(query, &p, nn->data.sym, f 
| sql_window, ek);
+                               in = rel_value_exp2(query, &p, dargs->data.sym, 
f | sql_window, ek);
                                if (!in)
                                        return NULL;
                                if(is_ntile && nfargs == 1) { /* ntile first 
argument null handling case */
@@ -4595,16 +4595,15 @@ rel_rankop(sql_query *query, sql_rel **r
                                append(fargs, in);
                                nfargs++;
                        }
-               }
+               dargs = dn->next->next;
        } else { /* aggregation function call */
-               dnode *n = dn->next;
                bool has_args = false;
 
-               for ( ; n->next && n->data.sym ; n = n->next) { /* the last 
dnode is the distinct flag */
+               for (dargs = dn->next ; dargs->next && dargs->data.sym ; dargs 
= dargs->next) { /* the last dnode is the distinct flag */
                        exp_kind ek = {type_value, card_column, FALSE};
 
                        has_args = true;
-                       in = rel_value_exp2(query, &p, n->data.sym, f | 
sql_window, ek);
+                       in = rel_value_exp2(query, &p, dargs->data.sym, f | 
sql_window, ek);
                        if (!in)
                                return NULL;
 
@@ -4620,8 +4619,6 @@ rel_rankop(sql_query *query, sql_rel **r
                        in = exp_ref_save(sql, in);
                }
 
-               distinct = n->data.i_val;
-
                if (!has_args) { /* count(*) */
                        in = rel_first_column(sql, p);
                        if (!exp_name(in))
@@ -4633,6 +4630,7 @@ rel_rankop(sql_query *query, sql_rel **r
                }
        }
 
+       distinct = dargs && dargs->data.i_val;
        if (distinct)
                return sql_error(sql, 02, SQLSTATE(42000) "SELECT: DISTINCT 
clause is not implemented for window functions");
 
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -196,7 +196,6 @@ int yydebug=1;
        call_statement
        case_exp
        case_opt_else
-       case_scalar_exp
        case_statement
        cast_exp
        cast_value
@@ -4390,11 +4389,25 @@ aggr_or_window_ref:
                { dlist *l = L();
                  append_list(l, $1);
                  append_list(l, NULL);
+                 append_int(l, FALSE);
                  $$ = _symbol_create_list( SQL_RANK, l ); }
  |  qrank '(' scalar_exp_list ')'
                { dlist *l = L();
                  append_list(l, $1);
                  append_list(l, $3);
+                 append_int(l, FALSE);
+                 $$ = _symbol_create_list( SQL_RANK, l ); }
+ |  qrank '(' DISTINCT scalar_exp_list ')'
+               { dlist *l = L();
+                 append_list(l, $1);
+                 append_list(l, $4);
+                 append_int(l, TRUE);
+                 $$ = _symbol_create_list( SQL_RANK, l ); }
+ |  qrank '(' ALL scalar_exp_list ')'
+               { dlist *l = L();
+                 append_list(l, $1);
+                 append_list(l, $4);
+                 append_int(l, FALSE);
                  $$ = _symbol_create_list( SQL_RANK, l ); }
  |  qfunc '(' '*' ')'
                { dlist *l = L();
@@ -4408,18 +4421,6 @@ aggr_or_window_ref:
                  append_symbol(l, NULL);
                  append_int(l, FALSE);
                  $$ = _symbol_create_list( SQL_AGGR, l ); }
- |  qfunc '(' DISTINCT case_scalar_exp ')'
-               { dlist *l = L();
-                 append_list(l, $1);
-                 append_symbol(l, $4);
-                 append_int(l, TRUE);
-                 $$ = _symbol_create_list( SQL_AGGR, l ); }
- |  qfunc '(' ALL case_scalar_exp ')'
-               { dlist *l = L();
-                 append_list(l, $1);
-                 append_symbol(l, $4);
-                 append_int(l, FALSE);
-                 $$ = _symbol_create_list( SQL_AGGR, l ); }
  |  qfunc '(' ')'
                { dlist *l = L();
                  append_list(l, $1);
@@ -4443,7 +4444,43 @@ aggr_or_window_ref:
                        append_int(l, FALSE);
                        $$ = _symbol_create_list( SQL_NOP, l ); 
                  }
-       }
+               }
+ |  qfunc '(' DISTINCT scalar_exp_list ')'
+               { dlist *l = L();
+                 append_list(l, $1);
+                 if (dlist_length($4) == 1) {
+                       append_symbol(l, $4->h->data.sym);
+                       append_int(l, TRUE);
+                       $$ = _symbol_create_list( SQL_UNOP, l ); 
+                 } else if (dlist_length($4) == 2) {
+                       append_symbol(l, $4->h->data.sym);
+                       append_symbol(l, $4->h->next->data.sym);
+                       append_int(l, TRUE);
+                       $$ = _symbol_create_list( SQL_BINOP, l ); 
+                 } else {
+                       append_list(l, $4);
+                       append_int(l, TRUE);
+                       $$ = _symbol_create_list( SQL_NOP, l ); 
+                 }
+               }
+ |  qfunc '(' ALL scalar_exp_list ')'
+               { dlist *l = L();
+                 append_list(l, $1);
+                 if (dlist_length($4) == 1) {
+                       append_symbol(l, $4->h->data.sym);
+                       append_int(l, FALSE);
+                       $$ = _symbol_create_list( SQL_UNOP, l ); 
+                 } else if (dlist_length($4) == 2) {
+                       append_symbol(l, $4->h->data.sym);
+                       append_symbol(l, $4->h->next->data.sym);
+                       append_int(l, FALSE);
+                       $$ = _symbol_create_list( SQL_BINOP, l ); 
+                 } else {
+                       append_list(l, $4);
+                       append_int(l, FALSE);
+                       $$ = _symbol_create_list( SQL_NOP, l ); 
+                 }
+               }
  |  XML_aggregate
  ;
 
@@ -5110,9 +5147,6 @@ case_opt_else:
  |  ELSE scalar_exp    { $$ = $2; }
  ;
 
-case_scalar_exp:
-    scalar_exp 
- ;
                /* data types, more types to come */
 
 nonzero:
diff --git a/sql/test/analytics/Tests/analytics01.sql 
b/sql/test/analytics/Tests/analytics01.sql
--- a/sql/test/analytics/Tests/analytics01.sql
+++ b/sql/test/analytics/Tests/analytics01.sql
@@ -268,6 +268,9 @@ WHERE (t0.start_time >= '2017/12/01 00:0
 
 rollback;
 
+select ntile(distinct aa) over () from analytics; --error
+select nth_value(distinct aa, bb) over () from analytics; --error
+
 select lag(null, aa) over () from analytics; --error
 select lag(null, null, aa) over () from analytics; --error
 select lead(null, aa) over () from analytics; --error
diff --git a/sql/test/analytics/Tests/analytics01.stable.err 
b/sql/test/analytics/Tests/analytics01.stable.err
--- a/sql/test/analytics/Tests/analytics01.stable.err
+++ b/sql/test/analytics/Tests/analytics01.stable.err
@@ -28,7 +28,15 @@ stderr of test 'analytics01` in director
 # 16:22:53 >  "mclient" "-lsql" "-ftest" "-tnone" "-Eutf-8" "-i" "-e" 
"--host=/var/tmp/mtest-23680" "--port=30581"
 # 16:22:53 >  
 
-MAPI  = (monetdb) /var/tmp/mtest-84677/.s.monetdb.37473
+MAPI  = (monetdb) /var/tmp/mtest-163525/.s.monetdb.30467
+QUERY = select ntile(distinct aa) over () from analytics; --error
+ERROR = !SELECT: DISTINCT clause is not implemented for window functions
+CODE  = 42000
+MAPI  = (monetdb) /var/tmp/mtest-163525/.s.monetdb.30467
+QUERY = select nth_value(distinct aa, bb) over () from analytics; --error
+ERROR = !SELECT: DISTINCT clause is not implemented for window functions
+CODE  = 42000
+MAPI  = (monetdb) /var/tmp/mtest-163525/.s.monetdb.30467
 QUERY = select lag(null, aa) over () from analytics; --error
 ERROR = !lag second argument must be a single atom
 CODE  = 42000
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to