Changeset: eb4dc8bf9ff2 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=eb4dc8bf9ff2 Modified Files: sql/server/rel_select.c sql/test/Users/Tests/userCallFunction.SQL.py Branch: default Log Message:
Merged with Oct2020 diffs (truncated from 689 to 300 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 @@ -346,7 +346,7 @@ query_exp_optname(sql_query *query, sql_ } static sql_subfunc * -bind_func_(mvc *sql, char *sname, char *fname, list *ops, sql_ftype type) +bind_func_(mvc *sql, char *sname, char *fname, list *ops, sql_ftype type, bool *found) { sql_subfunc *sf = NULL; @@ -355,13 +355,15 @@ bind_func_(mvc *sql, char *sname, char * execute_priv(sql, sql->forward) && type == sql->forward->type) return sql_dup_subfunc(sql->sa, sql->forward, NULL, NULL); sf = sql_bind_func_(sql, sname, fname, ops, type); + if (found) + *found |= sf != NULL; if (sf && execute_priv(sql, sf->func)) return sf; return NULL; } static sql_subfunc * -bind_func(mvc *sql, char *sname, char *fname, sql_subtype *t1, sql_subtype *t2, sql_ftype type) +bind_func(mvc *sql, char *sname, char *fname, sql_subtype *t1, sql_subtype *t2, sql_ftype type, bool *found) { sql_subfunc *sf = NULL; @@ -379,13 +381,15 @@ bind_func(mvc *sql, char *sname, char *f } } sf = sql_bind_func(sql, sname, fname, t1, t2, type); + if (found) + *found |= sf != NULL; if (sf && execute_priv(sql, sf->func)) return sf; return NULL; } static sql_subfunc * -bind_member_func(mvc *sql, char *sname, char *fname, sql_subtype *t, int nrargs, sql_ftype type, sql_subfunc *prev) +bind_member_func(mvc *sql, char *sname, char *fname, sql_subtype *t, int nrargs, sql_ftype type, sql_subfunc *prev, bool *found) { sql_subfunc *sf = NULL; @@ -393,19 +397,23 @@ bind_member_func(mvc *sql, char *sname, is_subtype(t, &((sql_arg *) sql->forward->ops->h->data)->type) && execute_priv(sql, sql->forward) && type == sql->forward->type) return sql_dup_subfunc(sql->sa, sql->forward, NULL, t); sf = sql_bind_member(sql, sname, fname, t, type, nrargs, prev); + if (found) + *found |= sf != NULL; if (sf && execute_priv(sql, sf->func)) return sf; return NULL; } static sql_subfunc * -find_func(mvc *sql, char *sname, char *fname, int len, sql_ftype type, sql_subfunc *prev ) +find_func(mvc *sql, char *sname, char *fname, int len, sql_ftype type, sql_subfunc *prev, bool *found) { sql_subfunc *sf = NULL; if (sql->forward && strcmp(fname, sql->forward->base.name) == 0 && list_length(sql->forward->ops) == len && execute_priv(sql, sql->forward) && type == sql->forward->type) return sql_dup_subfunc(sql->sa, sql->forward, NULL, NULL); sf = sql_find_func(sql, sname, fname, len, type, prev); + if (found) + *found |= sf != NULL; if (sf && execute_priv(sql, sf->func)) return sf; return NULL; @@ -528,10 +536,11 @@ nary_function_arg_types_2str(mvc *sql, l sql_exp * find_table_function(mvc *sql, char *sname, char *fname, list *exps, list *tl, sql_ftype type) { + bool found = false; sql_subfunc *f = NULL; assert(type == F_UNION || type == F_LOADER); - if (!(f = bind_func_(sql, sname, fname, tl, type)) && list_length(tl)) { + if (!(f = bind_func_(sql, sname, fname, tl, type, &found)) && list_length(tl)) { int len, match = 0; list *ff; @@ -539,9 +548,11 @@ find_table_function(mvc *sql, char *snam sql->errstr[0] = '\0'; if (!(ff = sql_find_funcs(sql, sname, fname, list_length(tl), type))) { char *arg_list = list_length(tl) ? nary_function_arg_types_2str(sql, tl, list_length(tl)) : NULL; - return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: no such %s function %s%s%s'%s'(%s)", - type == F_UNION ? "table returning" : "loader", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname, arg_list ? arg_list : ""); - } + return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: %s %s function %s%s%s'%s'(%s)", + found ? "insufficient privileges for" : "no such", type == F_UNION ? "table returning" : "loader", sname ? "'":"", sname ? sname : "", + sname ? "'.":"", fname, arg_list ? arg_list : ""); + } + found = true; for (node *n = ff->h; n ; ) { /* Reduce on privileges */ sql_subfunc *sf = n->data; node *nn = n->next; @@ -574,8 +585,9 @@ find_table_function(mvc *sql, char *snam return exp_op(sql->sa, exps, f); } char *arg_list = list_length(tl) ? nary_function_arg_types_2str(sql, tl, list_length(tl)) : NULL; - return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: no such %s function %s%s%s'%s'(%s)", - type == F_UNION ? "table returning" : "loader", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname, arg_list ? arg_list : ""); + return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: %s %s function %s%s%s'%s'(%s)", + found ? "insufficient privileges for" : "no such", type == F_UNION ? "table returning" : "loader", sname ? "'":"", sname ? sname : "", + sname ? "'.":"", fname, arg_list ? arg_list : ""); } static sql_rel * @@ -692,13 +704,18 @@ rel_named_table_function(sql_query *quer static sql_exp * rel_op_(mvc *sql, char *sname, char *fname, exp_kind ek) { + bool found = false; sql_subfunc *f = NULL; sql_ftype type = (ek.card == card_loader)?F_LOADER:((ek.card == card_none)?F_PROC: ((ek.card == card_relation)?F_UNION:F_FUNC)); - if ((f = bind_func_(sql, sname, fname, NULL, type)) && check_card(ek.card, f)) - return exp_op(sql->sa, NULL, f); - return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: no such operator %s%s%s'%s'()", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname); + if ((f = bind_func_(sql, sname, fname, NULL, type, &found))) { + if (check_card(ek.card, f)) + return exp_op(sql->sa, NULL, f); + found = false; + } + return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: %s operator %s%s%s'%s'()", + found ? "insufficient privileges for" : "no such", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname); } static sql_exp* @@ -1474,6 +1491,7 @@ rel_filter(mvc *sql, sql_rel *rel, list sql_exp *L = l->h->data, *R = r->h->data, *e = NULL; sql_subfunc *f = NULL; list *tl = sa_list(sql->sa); + bool found = false; for (n = l->h; n; n = n->next){ sql_exp *e = n->data; @@ -1486,10 +1504,10 @@ rel_filter(mvc *sql, sql_rel *rel, list list_append(tl, exp_subtype(e)); } /* find filter function */ - if (!(f = bind_func_(sql, sname, filter_op, tl, F_FILT))) { + if (!(f = bind_func_(sql, sname, filter_op, tl, F_FILT, &found))) { sql->session->status = 0; /* if the function was not found clean the error */ sql->errstr[0] = '\0'; - f = find_func(sql, sname, filter_op, list_length(tl), F_FILT, NULL); + f = find_func(sql, sname, filter_op, list_length(tl), F_FILT, NULL, &found); } if (f) { node *n,*m = f->func->ops->h; @@ -1518,7 +1536,8 @@ rel_filter(mvc *sql, sql_rel *rel, list r = nexps; } if (!f) - return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: no such FILTER function %s%s%s'%s'", sname ? "'":"", sname ? sname : "", sname ? "'.":"", filter_op); + return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: %s FILTER function %s%s%s'%s'", + found ? "insufficient privileges for" : "no such", sname ? "'":"", sname ? sname : "", sname ? "'.":"", filter_op); e = exp_filter(sql->sa, l, r, f, anti); if (exps_one_is_rel(l) || exps_one_is_rel(r)) /* uncorrelated subquery case */ @@ -1752,12 +1771,13 @@ rel_compare(sql_query *query, sql_rel *r static sql_exp* _rel_nop(mvc *sql, char *sname, char *fname, list *tl, sql_rel *rel, list *exps, exp_kind ek) { + bool found = false; sql_subfunc *f = NULL; int table_func = (ek.card == card_relation); sql_ftype type = (ek.card == card_loader)?F_LOADER:((ek.card == card_none)?F_PROC: ((ek.card == card_relation)?F_UNION:F_FUNC)); - if (!(f = bind_func_(sql, sname, fname, tl, type)) && list_length(tl)) { + if (!(f = bind_func_(sql, sname, fname, tl, type, &found)) && list_length(tl)) { int len, match = 0; list *ff; @@ -1765,9 +1785,10 @@ static sql_exp* sql->errstr[0] = '\0'; if (!(ff = sql_find_funcs(sql, sname, fname, list_length(tl), type))) { char *arg_list = list_length(tl) ? nary_function_arg_types_2str(sql, tl, list_length(tl)) : NULL; - return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: no such operator %s%s%s'%s'(%s)", - sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname, arg_list ? arg_list : ""); - } + return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: %s operator %s%s%s'%s'(%s)", + found ? "insufficient privileges for" : "no such", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname, arg_list ? arg_list : ""); + } + found = true; for (node *n = ff->h; n ; ) { /* Reduce on privileges */ sql_subfunc *sf = n->data; node *nn = n->next; @@ -1801,8 +1822,8 @@ static sql_exp* return exp_op(sql->sa, exps, f); } char *arg_list = list_length(tl) ? nary_function_arg_types_2str(sql, tl, list_length(tl)) : NULL; - return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: no such operator %s%s%s'%s'(%s)", - sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname, arg_list ? arg_list : ""); + return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: %s operator %s%s%s'%s'(%s)", + found ? "insufficient privileges for" : "no such", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname, arg_list ? arg_list : ""); } static sql_exp * @@ -2721,7 +2742,7 @@ rel_op(sql_query *query, sql_rel **rel, char *fname = qname_schema_object(l->data.lval); char *sname = qname_schema(l->data.lval); - if (find_func(sql, sname, fname, 0, F_AGGR, NULL)) + if (find_func(sql, sname, fname, 0, F_AGGR, NULL, NULL)) return _rel_aggr(query, rel, 0, sname, fname, NULL, f); sql->session->status = 0; /* if the function was not found clean the error */ sql->errstr[0] = '\0'; @@ -2731,6 +2752,7 @@ rel_op(sql_query *query, sql_rel **rel, sql_exp * rel_unop_(mvc *sql, sql_rel *rel, sql_exp *e, char *sname, char *fname, int card) { + bool found = false; sql_subfunc *f = NULL; sql_subtype *t = exp_subtype(e); sql_ftype type = (card == card_loader)?F_LOADER:((card == card_none)?F_PROC: @@ -2738,10 +2760,10 @@ rel_unop_(mvc *sql, sql_rel *rel, sql_ex /* handle param's early */ if (!t) { - if (!(f = find_func(sql, sname, fname, 1, type, NULL))) { + if (!(f = find_func(sql, sname, fname, 1, type, NULL, &found))) { sql->session->status = 0; /* if the function was not found clean the error */ sql->errstr[0] = '\0'; - f = find_func(sql, sname, fname, 1, F_AGGR, NULL); + f = find_func(sql, sname, fname, 1, F_AGGR, NULL, &found); } if (f) { sql_arg *a = f->func->ops->h->data; @@ -2751,10 +2773,10 @@ rel_unop_(mvc *sql, sql_rel *rel, sql_ex return NULL; } } else { - if (!(f = bind_func(sql, sname, fname, t, NULL, type))) { + if (!(f = bind_func(sql, sname, fname, t, NULL, type, &found))) { sql->session->status = 0; /* if the function was not found clean the error */ sql->errstr[0] = '\0'; - f = bind_func(sql, sname, fname, t, NULL, F_AGGR); + f = bind_func(sql, sname, fname, t, NULL, F_AGGR, &found); } } @@ -2775,9 +2797,13 @@ rel_unop_(mvc *sql, sql_rel *rel, sql_ex if (!f) { sql->session->status = 0; /* if the function was not found clean the error */ sql->errstr[0] = '\0'; - while ((f = find_func(sql, sname, fname, 1, type, f)) != NULL && check_card(card, f)) { + while ((f = find_func(sql, sname, fname, 1, type, f, &found)) != NULL) { list *args = list_append(sa_list(sql->sa), e); + if (!check_card(card, f)) { + found = false; /* reset found */ + continue; + } if (!f->func->vararg) args = check_arguments_and_find_largest_any_type(sql, rel, args, f, card == card_relation && e->card > CARD_ATOM); if (args) { @@ -2788,23 +2814,22 @@ rel_unop_(mvc *sql, sql_rel *rel, sql_ex /* reset error */ sql->session->status = 0; sql->errstr[0] = '\0'; - } - } - if (f && check_card(card, f)) { - if (f->func->fix_scale == INOUT) { - sql_subtype *res = f->res->h->data; - res->digits = t->digits; - res->scale = t->scale; - } - return exp_unop(sql->sa, e, f); - } - if ((t = exp_subtype(e))) { - char *type = t->type->sqlname; - return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: no such unary operator %s%s%s'%s'(%s)", - sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname, type); - } - return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: no such unary operator %s%s%s'%s'(?)", - sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname); + found = false; + } + } + if (f) { + if (check_card(card, f)) { + if (f->func->fix_scale == INOUT) { + sql_subtype *res = f->res->h->data; + res->digits = t->digits; + res->scale = t->scale; + } + return exp_unop(sql->sa, e, f); + } + found = false; /* reset found */ + } + return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: %s unary operator %s%s%s'%s'(%s)", + found ? "insufficient privileges for" : "no such", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname, t ? t->type->sqlname : "?"); } _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list