Changeset: 9963cf288abe for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9963cf288abe
Modified Files:
        sql/server/rel_dump.c
        sql/server/rel_select.c
        sql/test/BugTracker-2020/Tests/remote-table-like.Bug-6841.py
Branch: default
Log Message:

ifthenelse, coalesce, casewhen and nullif functions have unique bind requires. 
Handle them separately on remote plans


diffs (217 lines):

diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -1017,7 +1017,7 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
                                }
 
                                if (!(f = sql_bind_func_(sql, "sys", fname, tl, 
F_FILT)))
-                                       return sql_error(sql, -1, 
SQLSTATE(42000) "Filter: missing function '%s'\n", fname);
+                                       return sql_error(sql, ERR_NOTFOUND, 
SQLSTATE(42000) "Filter: missing function '%s'\n", fname);
                                if (!execute_priv(sql, f->func))
                                        return sql_error(sql, -1, 
SQLSTATE(42000) "Filter: no privilege to call filter function '%s'\n", fname);
                                return exp_filter(sql->sa, lexps, rexps, f, 
anti);
@@ -1049,7 +1049,7 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
                        }
                        convertIdent(tname);
                        if (!(tpe = sql_bind_subtype(sql->sa, tname, d, s)))
-                               return sql_error(sql, -1, SQLSTATE(42000) "SQL 
type %s(%d, %d) not found\n", tname, d, s);
+                               return sql_error(sql, ERR_NOTFOUND, 
SQLSTATE(42000) "SQL type %s(%d, %d) not found\n", tname, d, s);
                        skipWS(r, pos);
                        *e = old;
                        if (r[*pos] == '[') { /* convert */
@@ -1077,7 +1077,7 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
                tname = b;
                convertIdent(tname);
                if (!(tpe = sql_bind_subtype(sql->sa, tname, 0, 0)))
-                       return sql_error(sql, -1, SQLSTATE(42000) "SQL type %s 
not found\n", tname);
+                       return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) 
"SQL type %s not found\n", tname);
                st = readString(r,pos);
                if (st && strcmp(st, "NULL") == 0)
                        exp = exp_atom(sql->sa, atom_general(sql->sa, tpe, 
NULL));
@@ -1121,7 +1121,7 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
                convertIdent(tname);
                s = mvc_bind_schema(sql, tname);
                if (tname && !s)
-                       return sql_error(sql, -1, SQLSTATE(42000) "Schema %s 
not found\n", tname);
+                       return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) 
"Schema %s not found\n", tname);
                if (grp) {
                        if (exps && exps->h) {
                                list *ops = sa_list(sql->sa);
@@ -1132,7 +1132,7 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
                                a = sql_bind_func(sql, tname, cname, 
sql_bind_localtype("void"), NULL, F_AGGR); /* count(*) */
                        }
                        if (!a)
-                               return sql_error(sql, -1, SQLSTATE(42000) 
"Aggregate '%s%s%s %d' not found\n", tname ? tname : "", tname ? "." : "", 
cname, list_length(exps));
+                               return sql_error(sql, ERR_NOTFOUND, 
SQLSTATE(42000) "Aggregate '%s%s%s %d' not found\n", tname ? tname : "", tname 
? "." : "", cname, list_length(exps));
                        if (!execute_priv(sql, a->func))
                                return sql_error(sql, -1, SQLSTATE(42000) 
"Aggregate: no privilege to call aggregate '%s%s%s %d'\n", tname ? tname : "", 
tname ? "." : "", cname, list_length(exps));
                        exp = exp_aggr( sql->sa, exps, a, unique, no_nils, 
CARD_ATOM, 1);
@@ -1140,63 +1140,73 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
                                set_zero_if_empty(exp);
                } else {
                        int nops = list_length(exps);
-                       list *ops = sa_list(sql->sa);
-                       for( n = exps->h; n; n = n->next)
-                               append(ops, exp_subtype(n->data));
+                       if (!strcmp(tname, "sys") && (!strcmp(cname, 
"ifthenelse") || !strcmp(cname, "casewhen") || !strcmp(cname, "coalesce") || 
!strcmp(cname, "nullif"))) {
+                               /* these functions are bound on a different way 
*/
+                               if ((f = sql_find_func(sql, NULL, cname, 
!strcmp(cname, "ifthenelse") ? 3 : 2, F_FUNC, NULL))) {
+                                       if (!execute_priv(sql, f->func))
+                                               return sql_error(sql, -1, 
SQLSTATE(42000) "Function: no privilege to call function '%s%s%s %d'\n", tname 
? tname : "", tname ? "." : "", cname, nops);
+                                       sql_exp *res = exps->t->data;
+                                       sql_subtype *restype = exp_subtype(res);
+                                       f->res->h->data = 
sql_create_subtype(sql->sa, restype->type, restype->digits, restype->scale);
+                               }
+                       } else {
+                               list *ops = sa_list(sql->sa);
+                               for( n = exps->h; n; n = n->next)
+                                       append(ops, exp_subtype(n->data));
 
-                       f = sql_bind_func_(sql, tname, cname, ops, F_FUNC);
-                       if (!f) {
-                               sql->session->status = 0; /* if the function 
was not found clean the error */
-                               sql->errstr[0] = '\0';
-                               f = sql_bind_func_(sql, tname, cname, ops, 
F_ANALYTIC);
-                       }
-                       if (!f && nops > 1) { /* window functions without 
frames get 2 extra arguments */
-                               sql->session->status = 0; /* if the function 
was not found clean the error */
-                               sql->errstr[0] = '\0';
-                               list_remove_node(ops, NULL, ops->t);
-                               list_remove_node(ops, NULL, ops->t);
-                               f = sql_bind_func_(sql, tname, cname, ops, 
F_ANALYTIC);
-                       }
-                       if (!f && nops > 4) { /* window functions with frames 
get 5 extra arguments */
-                               sql->session->status = 0; /* if the function 
was not found clean the error */
-                               sql->errstr[0] = '\0';
-                               for (int i = 0 ; i < 3 ; i++)
+                               f = sql_bind_func_(sql, tname, cname, ops, 
F_FUNC);
+                               if (!f) {
+                                       sql->session->status = 0; /* if the 
function was not found clean the error */
+                                       sql->errstr[0] = '\0';
+                                       f = sql_bind_func_(sql, tname, cname, 
ops, F_ANALYTIC);
+                               }
+                               if (!f && nops > 1) { /* window functions 
without frames get 2 extra arguments */
+                                       sql->session->status = 0; /* if the 
function was not found clean the error */
+                                       sql->errstr[0] = '\0';
+                                       list_remove_node(ops, NULL, ops->t);
                                        list_remove_node(ops, NULL, ops->t);
-                               f = sql_bind_func_(sql, tname, cname, ops, 
F_ANALYTIC);
-                       }
+                                       f = sql_bind_func_(sql, tname, cname, 
ops, F_ANALYTIC);
+                               }
+                               if (!f && nops > 4) { /* window functions with 
frames get 5 extra arguments */
+                                       sql->session->status = 0; /* if the 
function was not found clean the error */
+                                       sql->errstr[0] = '\0';
+                                       for (int i = 0 ; i < 3 ; i++)
+                                               list_remove_node(ops, NULL, 
ops->t);
+                                       f = sql_bind_func_(sql, tname, cname, 
ops, F_ANALYTIC);
+                               }
+
+                               if (f && !execute_priv(sql, f->func))
+                                       return sql_error(sql, -1, 
SQLSTATE(42000) "Function: no privilege to call function '%s%s%s %d'\n", tname 
? tname : "", tname ? "." : "", cname, nops);
+                               /* fix scale of mul function, other type casts 
are explicit */
+                               if (f && f->func->fix_scale == SCALE_MUL && 
list_length(exps) == 2) {
+                                       sql_arg *ares = f->func->res->h->data;
 
-                       if (f && !execute_priv(sql, f->func))
-                               return sql_error(sql, -1, SQLSTATE(42000) 
"Function: no privilege to call function '%s%s%s %d'\n", tname ? tname : "", 
tname ? "." : "", cname, nops);
-                       /* fix scale of mul function, other type casts are 
explicit */
-                       if (f && f->func->fix_scale == SCALE_MUL && 
list_length(exps) == 2) {
-                               sql_arg *ares = f->func->res->h->data;
+                                       if (strcmp(f->func->imp, "*") == 0 && 
ares->type.type->scale == SCALE_FIX) {
+                                               sql_subtype *res = 
f->res->h->data;
+                                               sql_subtype *lt = ops->h->data;
+                                               sql_subtype *rt = 
ops->h->next->data;
 
-                               if (strcmp(f->func->imp, "*") == 0 && 
ares->type.type->scale == SCALE_FIX) {
+                                               res->digits = lt->digits;
+                                               res->scale = lt->scale + 
rt->scale;
+                                       }
+                               }
+                               /* fix scale of div function */
+                               if (f && f->func->fix_scale == SCALE_DIV && 
list_length(exps) == 2) {
+                                       sql_arg *ares = f->func->res->h->data;
+
+                                       if (strcmp(f->func->imp, "/") == 0 && 
ares->type.type->scale == SCALE_FIX) {
                                        sql_subtype *res = f->res->h->data;
-                                       sql_subtype *lt = ops->h->data;
-                                       sql_subtype *rt = ops->h->next->data;
+                                               sql_subtype *lt = ops->h->data;
+                                               sql_subtype *rt = 
ops->h->next->data;
 
-                                       res->digits = lt->digits;
-                                       res->scale = lt->scale + rt->scale;
+                                               res->scale = lt->scale - 
rt->scale;
+                                       }
                                }
                        }
-                       /* fix scale of div function */
-                       if (f && f->func->fix_scale == SCALE_DIV && 
list_length(exps) == 2) {
-                               sql_arg *ares = f->func->res->h->data;
-
-                               if (strcmp(f->func->imp, "/") == 0 && 
ares->type.type->scale == SCALE_FIX) {
-                                       sql_subtype *res = f->res->h->data;
-                                       sql_subtype *lt = ops->h->data;
-                                       sql_subtype *rt = ops->h->next->data;
-
-                                       res->scale = lt->scale - rt->scale;
-                               }
-                       }
-
                        if (f)
                                exp = exp_op(sql->sa, list_empty(exps) ? NULL : 
exps, f);
                        else
-                               return sql_error(sql, -1, SQLSTATE(42000) 
"Function '%s%s%s %d' not found\n", tname ? tname : "", tname ? "." : "", 
cname, nops);
+                               return sql_error(sql, ERR_NOTFOUND, 
SQLSTATE(42000) "Function '%s%s%s %d' not found\n", tname ? tname : "", tname ? 
"." : "", cname, nops);
                }
        }
 
@@ -1635,7 +1645,7 @@ rel_read(mvc *sql, char *r, int *pos, li
                                sql_column *c = mvc_bind_column(sql, t, cname);
 
                                if (!c)
-                                       return sql_error(sql, -1, 
SQLSTATE(42S22) "UPDATE: no such column '%s.%s'\n", t->base.name, cname);
+                                       return sql_error(sql, ERR_NOTFOUND, 
SQLSTATE(42S22) "UPDATE: no such column '%s.%s'\n", t->base.name, cname);
                                if (!(e = update_check_column(sql, t, c, e, 
rrel, c->base.name, "UPDATE")))
                                        return NULL;
                        }
@@ -1781,9 +1791,9 @@ rel_read(mvc *sql, char *r, int *pos, li
                                (*pos)++;
                                skipWS(r, pos);
                                if (!(s = mvc_bind_schema(sql, sname)))
-                                       return sql_error(sql, -1, 
SQLSTATE(3F000) "No such schema '%s'\n", sname);
+                                       return sql_error(sql, ERR_NOTFOUND, 
SQLSTATE(3F000) "No such schema '%s'\n", sname);
                                if (!(t = mvc_bind_table(sql, s, tname)))
-                                       return sql_error(sql, -1, 
SQLSTATE(42S02) "Table missing '%s.%s'\n", sname, tname);
+                                       return sql_error(sql, ERR_NOTFOUND, 
SQLSTATE(42S02) "Table missing '%s.%s'\n", sname, tname);
                                if (isMergeTable(t))
                                        return sql_error(sql, -1, 
SQLSTATE(42000) "Merge tables not supported under remote connections\n");
                                if (isRemote(t))
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
@@ -3837,8 +3837,7 @@ rel_case(sql_query *query, sql_rel **rel
                append(args, result);
        }
        assert(res);
-       if (res)
-               list_append(args, res);
+       list_append(args, res);
        list *types = sa_list(sql->sa);
        if (!opt_cond_exp)
                types = append(sa_list(sql->sa), condtype);
diff --git a/sql/test/BugTracker-2020/Tests/remote-table-like.Bug-6841.py 
b/sql/test/BugTracker-2020/Tests/remote-table-like.Bug-6841.py
--- a/sql/test/BugTracker-2020/Tests/remote-table-like.Bug-6841.py
+++ b/sql/test/BugTracker-2020/Tests/remote-table-like.Bug-6841.py
@@ -67,7 +67,10 @@ with tempfile.TemporaryDirectory() as fa
             node2_cur.execute("select count(*) over (), max(name) over (), 
min(name) over (partition by name order by name rows between 3 preceding and 2 
preceding) from remote_data")
             if node2_cur.fetchall() != [(1, 'Name 1', None)]:
                 sys.stderr.write("Just row (1, 'Name 1', None) expected")
-
+            node2_cur.execute("""select case when id = 1 then 2 when id = 2 
then 10 when id = 3 then 3 else 100 end, nullif(id, id), coalesce(id, id + 10, 
10),
+                                        case id when 1 then 5 when 2 then 10 
when 3 then 60 else 4 end, greatest(id - 7, id + 7), lead(1,1,1) over () from 
remote_data""")
+            if node2_cur.fetchall() != [(2, None, 1, 5, 8, 1)]:
+                sys.stderr.write("Just row (2, None, 1, 5, 8, 1) expected")
             # cleanup: shutdown the monetdb servers and remove tempdir
             node1_proc.communicate()
             node2_proc.communicate()
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to