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