Changeset: c638761448c3 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c638761448c3
Added Files:
        sql/test/BugTracker-2014/Tests/orderby_column_exp.Bug-3620.sql
        sql/test/BugTracker-2014/Tests/orderby_column_exp.Bug-3620.stable.err
        sql/test/BugTracker-2014/Tests/orderby_column_exp.Bug-3620.stable.out
Modified Files:
        sql/common/sql_types.c
        sql/common/sql_types.h
        sql/server/rel_psm.c
        sql/server/rel_select.c
        sql/server/sql_mvc.h
        sql/test/BugTracker-2014/Tests/All
Branch: default
Log Message:

merged with Oct2014


diffs (truncated from 438 to 300 lines):

diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c
--- a/sql/common/sql_types.c
+++ b/sql/common/sql_types.c
@@ -404,7 +404,7 @@ subfunc_cmp( sql_subfunc *f1, sql_subfun
        return -1;
 }
 
-static int
+int
 arg_subtype_cmp(sql_arg *a, sql_subtype *t)
 {
        if (a->type.type->eclass == EC_ANY)
@@ -568,8 +568,8 @@ is_sqlfunc(sql_func *f)
        return f->sql;
 }
 
-static sql_subfunc*
-_dup_subfunc(sql_allocator *sa, sql_func *f, list *ops, sql_subtype *member)
+sql_subfunc*
+sql_dup_subfunc(sql_allocator *sa, sql_func *f, list *ops, sql_subtype *member)
 {
        node *tn;
        unsigned int scale = 0, digits = 0;
@@ -636,9 +636,9 @@ func_cmp(sql_allocator *sa, sql_func *f,
 {
        if (strcmp(f->base.name, name) == 0) {
                if (f->vararg) 
-                       return _dup_subfunc(sa, f, NULL, NULL);
+                       return sql_dup_subfunc(sa, f, NULL, NULL);
                if (nrargs < 0 || list_length(f->ops) == nrargs) 
-                       return _dup_subfunc(sa, f, NULL, NULL);
+                       return sql_dup_subfunc(sa, f, NULL, NULL);
        }
        return NULL;
 }
@@ -716,7 +716,7 @@ sql_bind_member(sql_allocator *sa, sql_s
                        continue;
                if (strcmp(f->base.name, sqlfname) == 0) {
                        if (list_length(f->ops) == nrargs && is_subtype(tp, 
&((sql_arg *) f->ops->h->data)->type)) 
-                               return _dup_subfunc(sa, f, NULL, tp);
+                               return sql_dup_subfunc(sa, f, NULL, tp);
                }
        }
        if (tp && tp->type->eclass == EC_NUM) {
@@ -729,7 +729,7 @@ sql_bind_member(sql_allocator *sa, sql_s
                        if (strcmp(f->base.name, sqlfname) == 0 && 
list_length(f->ops) == nrargs) {
                                if (((sql_arg *) 
f->ops->h->data)->type.type->eclass == EC_DEC && 
                                    ((sql_arg *) 
f->ops->h->data)->type.type->localtype == tp->type->localtype) 
-                                       return _dup_subfunc(sa, f, NULL, tp);
+                                       return sql_dup_subfunc(sa, f, NULL, tp);
                        }
                }
        }
@@ -743,7 +743,7 @@ sql_bind_member(sql_allocator *sa, sql_s
                                continue;
                        if (strcmp(f->base.name, sqlfname) == 0) {
                                if (list_length(f->ops) == nrargs && 
is_subtype(tp, &((sql_arg *) f->ops->h->data)->type)) 
-                                       return _dup_subfunc(sa, f, NULL, tp);
+                                       return sql_dup_subfunc(sa, f, NULL, tp);
                        }
                }
        }
@@ -795,7 +795,7 @@ sql_bind_func_(sql_allocator *sa, sql_sc
                        continue;
                if (strcmp(f->base.name, sqlfname) == 0) {
                        if (list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 
0) 
-                               return _dup_subfunc(sa, f, ops, NULL);
+                               return sql_dup_subfunc(sa, f, ops, NULL);
                }
        }
        if (s) {
@@ -808,7 +808,7 @@ sql_bind_func_(sql_allocator *sa, sql_sc
                                continue;
                        if (strcmp(f->base.name, sqlfname) == 0) {
                                if (list_cmp(f->ops, ops, (fcmp) 
&arg_subtype_cmp) == 0) 
-                                       return _dup_subfunc(sa, f, ops, NULL);
+                                       return sql_dup_subfunc(sa, f, ops, 
NULL);
                        }
                }
        }
@@ -862,7 +862,7 @@ sql_bind_func_result_(sql_allocator *sa,
                        continue;
                firstres = f->res->h->data;
                if (strcmp(f->base.name, sqlfname) == 0 && 
(is_subtype(&firstres->type, res) || firstres->type.type->eclass == EC_ANY) && 
list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 0) 
-                       return _dup_subfunc(sa, f, ops, NULL);
+                       return sql_dup_subfunc(sa, f, ops, NULL);
        }
        return NULL;
 }
diff --git a/sql/common/sql_types.h b/sql/common/sql_types.h
--- a/sql/common/sql_types.h
+++ b/sql/common/sql_types.h
@@ -83,6 +83,7 @@ extern char *sql_subtype_string(sql_subt
 
 extern int type_cmp(sql_type *t1, sql_type *t2);
 extern int subtype_cmp(sql_subtype *t1, sql_subtype *t2);
+extern int arg_subtype_cmp(sql_arg *a, sql_subtype *t);
 extern int is_subtype(sql_subtype *t1, sql_subtype *t2);
 extern char *subtype2string(sql_subtype *t);
 
@@ -118,6 +119,7 @@ extern sql_func *sql_create_func4(sql_al
 extern sql_func *sql_create_func_(sql_allocator *sa, char *name, char *mod, 
char *imp, list *ops, sql_arg *res, bit side_effect, int type, int fix_scale);
 
 extern sql_func *sql_create_sqlfunc(sql_allocator *sa, char *name, char *imp, 
list *ops, sql_arg *res);
+extern sql_subfunc* sql_dup_subfunc(sql_allocator *sa, sql_func *f, list *ops, 
sql_subtype *member);
 
 extern char *sql_func_imp(sql_func *f);
 extern char *sql_func_mod(sql_func *f);
diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c
--- a/sql/server/rel_psm.c
+++ b/sql/server/rel_psm.c
@@ -791,8 +791,11 @@ rel_create_func(mvc *sql, dlist *qname, 
                                list *b = NULL;
                                sql_schema *old_schema = cur_schema(sql);
        
+                               if (create) /* needed for recursive functions */
+                                       sql->forward = f = mvc_create_func(sql, 
sql->sa, s, fname, l, restype, type, lang, "user", q, q, FALSE, vararg);
                                sql->session->schema = s;
                                b = sequential_block(sql, (ra)?&ra->type:NULL, 
ra?NULL:restype, body, NULL, is_func);
+                               sql->forward = NULL;
                                sql->session->schema = old_schema;
                                sql->params = NULL;
                                if (!b) 
@@ -811,8 +814,6 @@ rel_create_func(mvc *sql, dlist *qname, 
                                /* in execute mode we instantiate the function 
*/
                                if (instantiate || deps) {
                                        return rel_psm_block(sql->sa, b);
-                               } else if (create) {
-                                       f = mvc_create_func(sql, sql->sa, s, 
fname, l, restype, type, lang, "user", q, q, FALSE, vararg);
                                }
                        } else {
                                char *fmod = qname_module(ext_name);
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
@@ -1422,6 +1422,49 @@ rel_bind_column2( mvc *sql, sql_rel *rel
        return NULL;
 }
 
+static sql_subfunc *
+bind_func_(mvc *sql, sql_schema *s, char *fname, list *ops, int type )
+{
+       if (sql->forward && strcmp(fname, sql->forward->base.name) == 0 && 
+           list_cmp(sql->forward->ops, ops, (fcmp)&arg_subtype_cmp) == 0) 
+               return sql_dup_subfunc(sql->sa, sql->forward, NULL, NULL);
+       return sql_bind_func_(sql->sa, s, fname, ops, type);
+}
+
+static sql_subfunc *
+bind_func(mvc *sql, sql_schema *s, char *fname, sql_subtype *t1, sql_subtype 
*t2, int type )
+{
+       assert(t1);
+       if (sql->forward) {
+               if (strcmp(fname, sql->forward->base.name) == 0 && 
+                  ((!t1 && list_length(sql->forward->ops) == 0) || 
+                   (!t2 && list_length(sql->forward->ops) == 1 && 
subtype_cmp(sql->forward->ops->h->data, t1) == 0) ||
+                   (list_length(sql->forward->ops) == 2 && 
+                       subtype_cmp(sql->forward->ops->h->data, t1) == 0 &&
+                       subtype_cmp(sql->forward->ops->h->next->data, t2) == 
0))) {
+                       return sql_dup_subfunc(sql->sa, sql->forward, NULL, 
NULL);
+               }
+       }
+       return sql_bind_func(sql->sa, s, fname, t1, t2, type);
+}
+
+static sql_subfunc *
+bind_member_func(mvc *sql, sql_schema *s, char *fname, sql_subtype *t, int 
nrargs)
+{
+       if (sql->forward && strcmp(fname, sql->forward->base.name) == 0 && 
+               list_length(sql->forward->ops) == nrargs && is_subtype(t, 
&((sql_arg *) sql->forward->ops->h->data)->type)) 
+               return sql_dup_subfunc(sql->sa, sql->forward, NULL, t);
+       return sql_bind_member(sql->sa, s, fname, t, nrargs);
+}
+
+static sql_subfunc *
+find_func(mvc *sql, sql_schema *s, char *fname, int len, int type )
+{
+       if (sql->forward && strcmp(fname, sql->forward->base.name) == 0 && 
list_length(sql->forward->ops) == len) 
+               return sql_dup_subfunc(sql->sa, sql->forward, NULL, NULL);
+       return sql_find_func(sql->sa, s, fname, len, type);
+}
+
 static sql_rel *
 rel_named_table_function(mvc *sql, sql_rel *rel, symbol *query)
 {
@@ -1490,12 +1533,12 @@ rel_named_table_function(mvc *sql, sql_r
                
                if (sname)
                        s = mvc_bind_schema(sql, sname);
-               sf = sql_bind_func_(sql->sa, s, fname, tl, F_UNION);
+               sf = bind_func_(sql, s, fname, tl, F_UNION);
                if (sf) {
                        e = exp_op(sql->sa, exps, sf);
                } else if (list_length(tl) &&
-                          ((sf = sql_bind_member(sql->sa, s, fname, 
tl->h->data, list_length(tl))) != NULL ||
-                           (sf = sql_find_func(sql->sa, s, fname, 
list_length(tl), F_UNION)) != NULL)){
+                          ((sf = bind_member_func(sql, s, fname, tl->h->data, 
list_length(tl))) != NULL ||
+                           (sf = find_func(sql, s, fname, list_length(tl), 
F_UNION)) != NULL)){
                        node *n, *m;
                        list *nexps;
 
@@ -3495,12 +3538,12 @@ rel_unop_(mvc *sql, sql_exp *e, sql_sche
        if (!s)
                s = sql->session->schema;
        t = exp_subtype(e);
-       f = sql_bind_func(sql->sa, s, fname, t, NULL, type);
+       f = bind_func(sql, s, fname, t, NULL, type);
        /* try to find the function without a type, and convert
         * the value to the type needed by this function!
         */
        if (!f &&
-          (f = sql_find_func(sql->sa, s, fname, 1, type)) != NULL &&
+          (f = find_func(sql, s, fname, 1, type)) != NULL &&
           ((card == card_none && !f->res) || 
            (card != card_none && f->res))) {
 
@@ -3563,9 +3606,9 @@ rel_unop(mvc *sql, sql_rel **rel, symbol
        if (!s)
                s = sql->session->schema;
        t = exp_subtype(e);
-       f = sql_bind_func(sql->sa, s, fname, t, NULL, type);
+       f = bind_func(sql, s, fname, t, NULL, type);
        if (!f)
-               f = sql_bind_func(sql->sa, s, fname, t, NULL, F_AGGR);
+               f = bind_func(sql, s, fname, t, NULL, F_AGGR);
        if (f && IS_AGGR(f->func))
                return _rel_aggr(sql, rel, 0, s, fname, l->next, fs);
 
@@ -3628,9 +3671,9 @@ rel_binop_(mvc *sql, sql_exp *l, sql_exp
                t2 = exp_subtype(r);
        }
 
-       f = sql_bind_func(sql->sa, s, fname, t1, t2, type);
+       f = bind_func(sql, s, fname, t1, t2, type);
        if (!f && is_commutative(fname)) {
-               f = sql_bind_func(sql->sa, s, fname, t2, t1, type);
+               f = bind_func(sql, s, fname, t2, t1, type);
                if (f) {
                        sql_subtype *tmp = t1;
                        t1 = t2;        
@@ -3677,7 +3720,7 @@ rel_binop_(mvc *sql, sql_exp *l, sql_exp
                sql_exp *or = r;
 
                if (!EC_NUMBER(t1->type->eclass) &&
-                  (f = sql_bind_member(sql->sa, s, fname, t1, 2)) != NULL &&
+                  (f = bind_member_func(sql, s, fname, t1, 2)) != NULL &&
                   ((card == card_none && !f->res) || 
                    (card != card_none && f->res))) {
                        /* try finding function based on first argument */
@@ -3701,7 +3744,7 @@ rel_binop_(mvc *sql, sql_exp *l, sql_exp
                        /* try operators */
                        t1 = exp_subtype(l);
                        t2 = exp_subtype(r);
-                       f = sql_bind_func(sql->sa, s, fname, t1, t2, type);
+                       f = bind_func(sql, s, fname, t1, t2, type);
                        if (f && 
                           ((card == card_none && !f->res) || 
                            (card != card_none && f->res))) {
@@ -3735,7 +3778,7 @@ rel_binop_(mvc *sql, sql_exp *l, sql_exp
                t1 = exp_subtype(l);
                (void) exp_subtype(r);
 
-               if ((f = sql_bind_member(sql->sa, s, fname, t1, 2)) != NULL &&
+               if ((f = bind_member_func(sql, s, fname, t1, 2)) != NULL &&
                   ((card == card_none && !f->res) || 
                    (card != card_none && f->res))) {
                        /* try finding function based on first argument */
@@ -3755,7 +3798,7 @@ rel_binop_(mvc *sql, sql_exp *l, sql_exp
                l = ol;
                r = or;
                /* everything failed, fall back to bind on function name only */
-               if ((f = sql_find_func(sql->sa, s, fname, 2, type)) != NULL &&
+               if ((f = find_func(sql, s, fname, 2, type)) != NULL &&
                   ((card == card_none && !f->res) || 
                    (card != card_none && f->res))) {
 
@@ -3807,7 +3850,7 @@ rel_binop(mvc *sql, sql_rel **rel, symbo
                s = mvc_bind_schema(sql, sname);
 
        if (type == F_FUNC) {
-               sql_subfunc *func = sql_find_func(sql->sa, s, fname, 2, F_AGGR);
+               sql_subfunc *func = find_func(sql, s, fname, 2, F_AGGR);
                if (func) {
                        if (!l || !r) { /* reset error */
                                sql->session->status = 0;
@@ -3839,7 +3882,7 @@ rel_nop_(mvc *sql, sql_exp *a1, sql_exp 
 
        if (!s)
                s = sql->session->schema;
-       f = sql_bind_func_(sql->sa, s, fname, tl, type);
+       f = bind_func_(sql, s, fname, tl, type);
        if (!f)
                return sql_error(sql, 02, "SELECT: no such operator '%s'", 
fname);
        if (!a4)
@@ -3879,11 +3922,11 @@ rel_nop(mvc *sql, sql_rel **rel, symbol 
        }
        if (sname)
                s = mvc_bind_schema(sql, sname);
-       f = sql_bind_func_(sql->sa, s, fname, tl, type);
+       f = bind_func_(sql, s, fname, tl, type);
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to