Changeset: 6b3054359d3c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6b3054359d3c
Modified Files:
sql/common/sql_types.c
sql/server/rel_schema.c
sql/server/rel_select.c
sql/server/sql_parser.y
sql/server/sql_semantic.c
sql/test/BugTracker-2014/Tests/aggregates-intervals.Bug-3533.stable.err
Branch: statistics-analytics
Log Message:
Test fixings, allow aggregates without parameters to be parsed, at rel_unop try
to use an aggregate only when rel_value_exp fails for consistency related to
rel_binop
diffs (truncated from 919 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
@@ -783,7 +783,7 @@ sql_find_func(sql_allocator *sa, sql_sch
int found = 0;
sql_ftype filt = (type == F_FUNC)?F_FILT:type;
- assert(nrargs);
+ assert(nrargs >= -1);
MT_lock_set(&funcs->ht_lock);
he = funcs->ht->buckets[key&(funcs->ht->size-1)];
if (prev) {
diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c
--- a/sql/server/rel_schema.c
+++ b/sql/server/rel_schema.c
@@ -452,7 +452,7 @@ column_option(
sql->session->status = 0;
sql->errstr[0] = '\0';
}
- r = symbol2string(sql, s->data.sym, 0, &err);
+ r = symbol2string(sql, s->data.sym, 0, &err);
if (!r) {
(void) sql_error(sql, 02, SQLSTATE(42000) "Incorrect
default value '%s'\n", err?err:"");
if (err) _DELETE(err);
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
@@ -382,7 +382,7 @@ bind_func_(mvc *sql, sql_schema *s, char
if (sql->forward && strcmp(fname, sql->forward->base.name) == 0 &&
list_cmp(sql->forward->ops, ops, (fcmp)&arg_subtype_cmp) == 0 &&
- execute_priv(sql, sql->forward))
+ execute_priv(sql, sql->forward) && type == sql->forward->type)
return sql_dup_subfunc(sql->sa, sql->forward, NULL, NULL);
sf = sql_bind_func_(sql->sa, s, fname, ops, type);
if (sf && execute_priv(sql, sf->func))
@@ -404,7 +404,7 @@ bind_func(mvc *sql, sql_schema *s, char
(!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))) {
+ subtype_cmp(sql->forward->ops->h->next->data, t2) ==
0)) && type == sql->forward->type) {
return sql_dup_subfunc(sql->sa, sql->forward, NULL,
NULL);
}
}
@@ -433,7 +433,7 @@ find_func(mvc *sql, sql_schema *s, char
{
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))
+ 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->sa, s, fname, len, type, prev);
if (sf && execute_priv(sql, sf->func))
@@ -575,6 +575,8 @@ rel_named_table_function(sql_query *quer
tl = sa_list(sql->sa);
exps = new_exp_list(sql->sa);
+ if (l->next)
+ l = l->next; /* skip distinct */
if (l->next) { /* table call with subquery */
if (l->next->type == type_symbol && l->next->data.sym->token ==
SQL_SELECT) {
if (l->next->next != NULL)
@@ -2636,16 +2638,35 @@ rel_logical_exp(sql_query *query, sql_re
/* never reached, as all switch cases have a `return` */
}
+static sql_exp * _rel_aggr(sql_query *query, sql_rel **rel, int distinct,
sql_schema *s, char *aname, dnode *arguments, int f);
+static sql_exp *rel_aggr(sql_query *query, sql_rel **rel, symbol *se, int f);
+
static sql_exp *
-rel_op(mvc *sql, symbol *se, exp_kind ek )
+rel_op(sql_query *query, sql_rel **rel, symbol *se, int f, exp_kind ek )
{
+ mvc *sql = query->sql;
dnode *l = se->data.lval->h;
char *fname = qname_fname(l->data.lval);
char *sname = qname_schema(l->data.lval);
sql_schema *s = sql->session->schema;
+ sql_subfunc *sf = NULL;
if (sname)
s = mvc_bind_schema(sql, sname);
+ if (!s)
+ return NULL;
+
+ sf = find_func(sql, s, fname, 0, F_AGGR, NULL);
+ if (!sf && *rel && (*rel)->card == CARD_AGGR) {
+ if (is_sql_having(f) || is_sql_orderby(f))
+ return NULL;
+ /* reset error */
+ sql->session->status = 0;
+ sql->errstr[0] = '\0';
+ return sql_error(sql, 02, SQLSTATE(42000) "SELECT: no such
aggregate '%s'", fname);
+ }
+ if (sf)
+ return _rel_aggr(query, rel, 0, s, fname, NULL, f);
return rel_op_(sql, s, fname, ek);
}
@@ -2653,14 +2674,42 @@ sql_exp *
rel_unop_(mvc *sql, sql_rel *rel, sql_exp *e, sql_schema *s, char *fname, int
card)
{
sql_subfunc *f = NULL;
- sql_subtype *t = NULL;
+ sql_subtype *t = exp_subtype(e);
sql_ftype type = (card == card_loader)?F_LOADER:((card ==
card_none)?F_PROC:
((card == card_relation)?F_UNION:F_FUNC));
if (!s)
s = sql->session->schema;
- t = exp_subtype(e);
- f = bind_func(sql, s, fname, t, NULL, type);
+
+ /* handle param's early */
+ if (!t) {
+ f = find_func(sql, s, fname, 1, type, NULL);
+ if (!f)
+ f = find_func(sql, s, fname, 1, F_AGGR, NULL);
+ if (f) {
+ sql_arg *a = f->func->ops->h->data;
+
+ t = &a->type;
+ if (rel_set_type_param(sql, t, rel, e, 1) < 0)
+ return NULL;
+ }
+ } else {
+ f = bind_func(sql, s, fname, t, NULL, type);
+ if (!f)
+ f = bind_func(sql, s, fname, t, NULL, F_AGGR);
+ }
+
+ if (f && type_has_tz(t) && f->func->fix_scale == SCALE_FIX) {
+ /* set timezone (using msec (.3)) */
+ sql_subtype *intsec = sql_bind_subtype(sql->sa, "sec_interval",
10 /*hour to second */, 3);
+ atom *a = atom_int(sql->sa, intsec, sql->timezone);
+ sql_exp *tz = exp_atom(sql->sa, a);
+
+ e = rel_binop_(sql, rel, e, tz, NULL, "sql_add", card);
+ if (!e)
+ return NULL;
+ }
+
/* try to find the function without a type, and convert
* the value to the type needed by this function!
*/
@@ -2698,11 +2747,8 @@ rel_unop_(mvc *sql, sql_rel *rel, sql_ex
return NULL;
}
-static sql_exp * _rel_aggr(sql_query *query, sql_rel **rel, int distinct,
sql_schema *s, char *aname, dnode *arguments, int f);
-static sql_exp *rel_aggr(sql_query *query, sql_rel **rel, symbol *se, int f);
-
static sql_exp *
-rel_unop(sql_query *query, sql_rel **rel, symbol *se, int fs, exp_kind ek)
+rel_unop(sql_query *query, sql_rel **rel, symbol *se, int f, exp_kind ek)
{
mvc *sql = query->sql;
dnode *l = se->data.lval->h;
@@ -2711,67 +2757,44 @@ rel_unop(sql_query *query, sql_rel **rel
sql_schema *s = sql->session->schema;
exp_kind iek = {type_value, card_column, FALSE};
sql_exp *e = NULL;
- sql_subfunc *f = NULL;
- sql_subtype *t = NULL;
+ sql_subfunc *sf = NULL;
sql_ftype type = (ek.card == card_loader)?F_LOADER:((ek.card ==
card_none)?F_PROC:F_FUNC);
if (sname)
s = mvc_bind_schema(sql, sname);
-
if (!s)
return NULL;
- f = find_func(sql, s, fname, 1, F_AGGR, NULL);
- if (f) {
- e = rel_aggr(query, rel, se, fs);
- if (e)
- return e;
+
+ e = rel_value_exp(query, rel, l->next->next->data.sym, f|sql_farg, iek);
+ if (!e)
+ sf = find_func(sql, s, fname, 1, F_AGGR, NULL);
+
+ if (!sf && !e && *rel && (*rel)->card == CARD_AGGR) {
+ if (is_sql_having(f) || is_sql_orderby(f))
+ return NULL;
/* reset error */
sql->session->status = 0;
sql->errstr[0] = '\0';
- }
- e = rel_value_exp(query, rel, l->next->data.sym, fs|sql_farg, iek);
- if (!e) {
- if (!f && *rel && (*rel)->card == CARD_AGGR) {
- if (is_sql_having(fs) || is_sql_orderby(fs))
- return NULL;
- /* reset error */
- sql->session->status = 0;
- sql->errstr[0] = '\0';
- return sql_error(sql, 02, SQLSTATE(42000) "SELECT: no
such aggregate '%s'", fname);
+ return sql_error(sql, 02, SQLSTATE(42000) "SELECT: no such
aggregate '%s'", fname);
+ }
+ if (!e && sf) { /* possibly we cannot resolve the argument as the
function maybe an aggregate */
+ /* reset error */
+ sql->session->status = 0;
+ sql->errstr[0] = '\0';
+ return rel_aggr(query, rel, se, f);
+ }
+ if (type == F_FUNC) {
+ sf = find_func(sql, s, fname, 1, F_AGGR, NULL);
+ if (sf) {
+ if (!e) { /* reset error */
+ sql->session->status = 0;
+ sql->errstr[0] = '\0';
+ }
+ return _rel_aggr(query, rel, l->next->data.i_val, s,
fname, l->next->next, f);
}
+ }
+ if (!e)
return NULL;
- }
-
- t = exp_subtype(e);
- if (!t) {
- f = find_func(sql, s, fname, 1, type, NULL);
- if (!f)
- f = find_func(sql, s, fname, 1, F_AGGR, NULL);
- if (f) {
- sql_arg *a = f->func->ops->h->data;
-
- t = &a->type;
- if (rel_set_type_param(sql, t, rel ? *rel : NULL, e, 1)
< 0)
- return NULL;
- }
- } else {
- f = bind_func(sql, s, fname, t, NULL, type);
- if (!f)
- f = bind_func(sql, s, fname, t, NULL, F_AGGR);
- }
- if (f && IS_AGGR(f->func))
- return _rel_aggr(query, rel, 0, s, fname, l->next, fs);
-
- if (f && type_has_tz(t) && f->func->fix_scale == SCALE_FIX) {
- /* set timezone (using msec (.3)) */
- sql_subtype *intsec = sql_bind_subtype(sql->sa, "sec_interval",
10 /*hour to second */, 3);
- atom *a = atom_int(sql->sa, intsec, sql->timezone);
- sql_exp *tz = exp_atom(sql->sa, a);
-
- e = rel_binop_(sql, rel ? *rel : NULL, e, tz, NULL, "sql_add",
ek.card);
- if (!e)
- return NULL;
- }
return rel_unop_(sql, rel ? *rel : NULL, e, s, fname, ek.card);
}
@@ -2782,13 +2805,11 @@ sql_exp *
rel_binop_(mvc *sql, sql_rel *rel, sql_exp *l, sql_exp *r, sql_schema *s, char
*fname, int card)
{
sql_exp *res = NULL;
- sql_subtype *t1, *t2;
+ sql_subtype *t1 = exp_subtype(l), *t2 = exp_subtype(r);
sql_subfunc *f = NULL;
sql_ftype type = (card == card_loader)?F_LOADER:((card ==
card_none)?F_PROC:((card == card_relation)?F_UNION:F_FUNC));
if (card == card_loader)
card = card_none;
- t1 = exp_subtype(l);
- t2 = exp_subtype(r);
if (!s)
s = sql->session->schema;
@@ -3029,12 +3050,11 @@ rel_binop(sql_query *query, sql_rel **re
if (!s)
return NULL;
- l = rel_value_exp(query, rel, dl->next->data.sym, f|sql_farg, iek);
- r = rel_value_exp(query, rel, dl->next->next->data.sym, f|sql_farg,
iek);
-
- if (!l || !r) {
+ l = rel_value_exp(query, rel, dl->next->next->data.sym, f|sql_farg,
iek);
+ r = rel_value_exp(query, rel, dl->next->next->next->data.sym,
f|sql_farg, iek);
+
+ if (!l || !r)
sf = find_func(sql, s, fname, 2, F_AGGR, NULL);
- }
if (!sf && (!l || !r) && *rel && (*rel)->card == CARD_AGGR) {
if (mvc_status(sql) || is_sql_having(f) || is_sql_orderby(f))
return NULL;
@@ -3056,7 +3076,7 @@ rel_binop(sql_query *query, sql_rel **re
sql->session->status = 0;
sql->errstr[0] = '\0';
}
- return _rel_aggr(query, rel, 0, s, fname, dl->next, f);
+ return _rel_aggr(query, rel, dl->next->data.i_val, s,
fname, dl->next->next, f);
}
}
@@ -3096,7 +3116,7 @@ rel_nop(sql_query *query, sql_rel **rel,
mvc *sql = query->sql;
int nr_args = 0;
dnode *l = se->data.lval->h;
- dnode *ops = l->next->data.lval->h;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list