Changeset: 67b5fda62ad6 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=67b5fda62ad6 Modified Files: sql/server/rel_exp.c sql/server/rel_select.c sql/server/sql_semantic.c sql/test/miscellaneous/Tests/groupby_error.sql sql/test/miscellaneous/Tests/groupby_error.stable.err sql/test/miscellaneous/Tests/groupby_error.stable.out Branch: linear-hashing Log Message:
merged diffs (truncated from 489 to 300 lines): diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c --- a/sql/server/rel_exp.c +++ b/sql/server/rel_exp.c @@ -782,7 +782,8 @@ exp_rel(mvc *sql, sql_rel *rel) assert(rel); if (is_project(rel->op)) { sql_exp *last = rel->exps->t->data; - e->tpe = *exp_subtype(last); + sql_subtype *t = exp_subtype(last); + e->tpe = t ? *t : (sql_subtype) {0}; } return e; } @@ -1707,7 +1708,7 @@ exp_is_atom( sql_exp *e ) int exp_is_rel( sql_exp *e ) { - return (e->type == e_psm && e->flag == PSM_REL && e->l); + return (e && e->type == e_psm && e->flag == PSM_REL && e->l); } int 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 @@ -1251,7 +1251,10 @@ exp_fix_scale(mvc *sql, sql_subtype *ct, static int rel_set_type_param(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp *rel_exp, int upcast) { - if (!type || !rel_exp || (rel_exp->type != e_atom && rel_exp->type != e_column)) + sql_rel *r = rel; + int is_rel = exp_is_rel(rel_exp); + + if (!type || !rel_exp || (rel_exp->type != e_atom && rel_exp->type != e_column && !is_rel)) return -1; /* use largest numeric types */ @@ -1264,15 +1267,37 @@ rel_set_type_param(mvc *sql, sql_subtype if (upcast && type->type->eclass == EC_FLT) type = sql_bind_localtype("dbl"); - if ((rel_exp->type == e_atom || rel_exp->type == e_column) && (rel_exp->l || rel_exp->r || rel_exp->f)) { + if (is_rel) + r = (sql_rel*) rel_exp->l; + + if ((rel_exp->type == e_atom && (rel_exp->l || rel_exp->r || rel_exp->f)) || rel_exp->type == e_column || is_rel) { /* it's not a parameter set possible parameters below */ const char *relname = exp_relname(rel_exp), *expname = exp_name(rel_exp); - return rel_set_type_recurse(sql, type, rel, &relname, &expname); - } else if (set_type_param(sql, type, rel_exp->flag) == 0) { - rel_exp->tpe = *type; - return 0; - } - return -1; + if (rel_set_type_recurse(sql, type, r, &relname, &expname) < 0) + return -1; + } else if (set_type_param(sql, type, rel_exp->flag) != 0) + return -1; + + rel_exp->tpe = *type; + return 0; +} + +static int +rel_binop_check_types(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *rs, int upcast) +{ + sql_subtype *t1 = exp_subtype(ls), *t2 = exp_subtype(rs); + + if (!t1 || !t2) { + if (t2 && !t1 && rel_set_type_param(sql, t2, rel, ls, upcast) < 0) + return -1; + if (t1 && !t2 && rel_set_type_param(sql, t1, rel, rs, upcast) < 0) + return -1; + } + if (!exp_subtype(ls) && !exp_subtype(rs)) { + (void) sql_error(sql, 01, SQLSTATE(42000) "Cannot have a parameter (?) on both sides of an expression"); + return -1; + } + return 0; } /* try to do an in-place conversion @@ -1613,6 +1638,8 @@ rel_compare_exp_(sql_query *query, sql_r if (anti) set_anti(e); } else { + if (rel_binop_check_types(sql, rel, ls, rs, 0) < 0) + return NULL; e = exp_compare_func(sql, ls, rs, rs2, compare_func((comp_type)type, quantifier?0:anti), quantifier); if (anti && quantifier) e = rel_unop_(sql, NULL, e, NULL, "not", card_value); @@ -1631,8 +1658,6 @@ rel_compare_exp_(sql_query *query, sql_r type = (int)swap_compare((comp_type)type); } - if (!exp_subtype(ls) && !exp_subtype(rs)) - return sql_error(sql, 01, SQLSTATE(42000) "Cannot have a parameter (?) on both sides of an expression"); if (rel_convert_types(sql, rel, rel, &ls, &rs, 1, type_equal_no_any) < 0) return NULL; e = exp_compare(sql->sa, ls, rs, type); @@ -1802,8 +1827,6 @@ rel_compare(sql_query *query, sql_rel *r if (!rs2) return NULL; } - if (!rs) - return NULL; if (ls->card > rs->card && rs->card == CARD_AGGR && is_sql_having(f)) return sql_error(sql, 05, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s.%s' in query results without an aggregate function", exp_relname(ls), exp_name(ls)); if (rs->card > ls->card && ls->card == CARD_AGGR && is_sql_having(f)) @@ -1903,18 +1926,25 @@ static sql_exp* } static sql_exp * -exp_exist(sql_query *query, sql_exp *le, int exists) +exp_exist(sql_query *query, sql_rel *rel, sql_exp *le, int exists) { mvc *sql = query->sql; sql_subfunc *exists_func = NULL; - + sql_subtype *t; + + if (!exp_name(le)) + exp_label(sql->sa, le, ++sql->label); + if (!exp_subtype(le) && rel_set_type_param(sql, sql_bind_localtype("bit"), rel, le, 0) < 0) /* workaround */ + return NULL; + t = exp_subtype(le); + if (exists) - exists_func = sql_bind_func(sql->sa, sql->session->schema, "sql_exists", exp_subtype(le), NULL, F_FUNC); + exists_func = sql_bind_func(sql->sa, sql->session->schema, "sql_exists", t, NULL, F_FUNC); else - exists_func = sql_bind_func(sql->sa, sql->session->schema, "sql_not_exists", exp_subtype(le), NULL, F_FUNC); + exists_func = sql_bind_func(sql->sa, sql->session->schema, "sql_not_exists", t, NULL, F_FUNC); if (!exists_func) - return sql_error(sql, 02, SQLSTATE(42000) "exist operator on type %s missing", exp_subtype(le)->type->sqlname); + return sql_error(sql, 02, SQLSTATE(42000) "exist operator on type %s missing", t->type->sqlname); return exp_unop(sql->sa, le, exists_func); } @@ -1927,7 +1957,7 @@ rel_exists_value_exp(sql_query *query, s le = rel_value_exp(query, rel, sc->data.sym, f, ek); if (!le) return NULL; - e = exp_exist(query, le, sc->token == SQL_EXISTS); + e = exp_exist(query, rel ? *rel : NULL, le, sc->token == SQL_EXISTS); if (e) { /* only freevar should have CARD_AGGR */ e->card = CARD_ATOM; @@ -1950,7 +1980,7 @@ rel_exists_exp(sql_query *query, sql_rel assert(!is_sql_sel(f)); if (sq) { sql_exp *e = exp_rel(sql, sq); - e = exp_exist(query, e, sc->token == SQL_EXISTS); + e = exp_exist(query, rel, e, sc->token == SQL_EXISTS); if (e) { /* only freevar should have CARD_AGGR */ e->card = CARD_ATOM; @@ -1992,6 +2022,7 @@ rel_in_value_exp(sql_query *query, sql_r le = ll->h->data; } else { le = exp_values(sql->sa, ll); + exp_label(sql->sa, le, ++sql->label); ek.card = card_relation; is_tuple = 1; } @@ -2015,8 +2046,23 @@ rel_in_value_exp(sql_query *query, sql_r } values = exp_values(sql->sa, vals); - if (!is_tuple) /* if it's not a tuple, enforce coersion on the type for every element on the list */ + exp_label(sql->sa, values, ++sql->label); + if (is_tuple) { + sql_exp *e_rel = (sql_exp *) vals->h->data; + list *le_vals = le->f, *rel_vals = ((sql_rel*)e_rel->l)->exps; + + for (node *m = le_vals->h, *o = rel_vals->h ; m && o ; m = m->next, o = o->next) { + sql_exp *e = m->data, *f = o->data; + + if (rel_binop_check_types(sql, rel ? *rel : NULL, e, f, 0) < 0) + return NULL; + } + } else { /* if it's not a tuple, enforce coersion on the type for every element on the list */ values = exp_values_set_supertype(sql, values); + + if (rel_binop_check_types(sql, rel ? *rel : NULL, le, values, 0) < 0) + return NULL; + } e = exp_in_func(sql, le, values, (sc->token == SQL_IN), is_tuple); } if (e && le) @@ -2157,6 +2203,9 @@ rel_logical_value_exp(sql_query *query, rs = rel_value_exp(query, rel, ro, f, ek); if (!rs) return NULL; + + if (rel_binop_check_types(sql, rel ? *rel : NULL, ls, rs, 0) < 0) + return NULL; ls = exp_compare_func(sql, ls, rs, NULL, compare_func(compare_str2type(compare_op), quantifier?0:need_not), quantifier); if (need_not && quantifier) ls = rel_unop_(sql, NULL, ls, NULL, "not", card_value); @@ -2487,12 +2536,24 @@ rel_logical_exp(sql_query *query, sql_re sql_exp *le = rel_value_exp(query, &rel, lo, f, ek); sql_exp *re1 = rel_value_exp(query, &rel, ro1, f, ek); sql_exp *re2 = rel_value_exp(query, &rel, ro2, f, ek); + sql_subtype *t1, *t2, *t3; int flag = 0; assert(sc->data.lval->h->next->type == type_int); if (!le || !re1 || !re2) return NULL; + t1 = exp_subtype(le); + t2 = exp_subtype(re1); + t3 = exp_subtype(re2); + + if (!t1 && (t2 || t3) && rel_binop_check_types(sql, rel, le, t2 ? re1 : re2, 0) < 0) + return NULL; + if (!t2 && (t1 || t3) && rel_binop_check_types(sql, rel, le, t1 ? le : re2, 0) < 0) + return NULL; + if (!t3 && (t1 || t2) && rel_binop_check_types(sql, rel, le, t1 ? le : re1, 0) < 0) + return NULL; + if (rel_convert_types(sql, rel, rel, &le, &re1, 1, type_equal) < 0 || rel_convert_types(sql, rel, rel, &le, &re2, 1, type_equal) < 0) return NULL; @@ -2506,9 +2567,8 @@ rel_logical_exp(sql_query *query, sql_re sql_subfunc *min = sql_bind_func(sql->sa, sql->session->schema, "sql_min", exp_subtype(re1), exp_subtype(re2), F_FUNC); sql_subfunc *max = sql_bind_func(sql->sa, sql->session->schema, "sql_max", exp_subtype(re1), exp_subtype(re2), F_FUNC); - if (!min || !max) { + if (!min || !max) return sql_error(sql, 02, SQLSTATE(42000) "min or max operator on types %s %s missing", exp_subtype(re1)->type->sqlname, exp_subtype(re2)->type->sqlname); - } tmp = exp_binop(sql->sa, re1, re2, min); re2 = exp_binop(sql->sa, re1, re2, max); re1 = tmp; @@ -2793,18 +2853,12 @@ rel_binop_(mvc *sql, sql_rel *rel, sql_e if (!t2) rel_set_type_param(sql, arg_type(f->func->ops->h->next->data), rel, r, 1); f = NULL; - } else { - if (t2 && !t1 && rel_set_type_param(sql, t2, rel, l, 1) < 0) - return NULL; - if (t1 && !t2 && rel_set_type_param(sql, t1, rel, r, 1) < 0) - return NULL; - } - t1 = exp_subtype(l); - t2 = exp_subtype(r); - } - - if (!t1 || !t2) - return sql_error(sql, 01, SQLSTATE(42000) "Cannot have a parameter (?) on both sides of an expression"); + + if (!exp_subtype(l) || !exp_subtype(r)) + return sql_error(sql, 01, SQLSTATE(42000) "Cannot have a parameter (?) on both sides of an expression"); + } else if (rel_binop_check_types(sql, rel, l, r, 1) < 0) + return NULL; + } if (!f && (is_addition(fname) || is_subtraction(fname)) && ((t1->type->eclass == EC_NUM && t2->type->eclass == EC_NUM) || @@ -5279,7 +5333,7 @@ rel_select_exp(sql_query *query, sql_rel list *te = NULL; sql_exp *ce = rel_column_exp(query, &inner, n->data.sym, sql_sel | group_totals); - if (ce && exp_subtype(ce)) { + if (ce && (exp_subtype(ce) || (ce->type == e_atom && !ce->l && !ce->f))) { pexps = append(pexps, ce); rel = inner; continue; @@ -5647,7 +5701,6 @@ rel_joinquery_(sql_query *query, sql_rel static sql_rel * rel_joinquery(sql_query *query, sql_rel *rel, symbol *q) { - dnode *n = q->data.lval->h; symbol *tab_ref1 = n->data.sym; int natural = n->next->data.i_val; diff --git a/sql/server/sql_semantic.c b/sql/server/sql_semantic.c --- a/sql/server/sql_semantic.c +++ b/sql/server/sql_semantic.c @@ -192,12 +192,10 @@ qname_catalog(dlist *qname) if (dlist_length(qname) == 3) { return qname->h->data.sval; - } - + } return NULL; } - int set_type_param(mvc *sql, sql_subtype *type, int nr) { diff --git a/sql/test/miscellaneous/Tests/groupby_error.sql b/sql/test/miscellaneous/Tests/groupby_error.sql --- a/sql/test/miscellaneous/Tests/groupby_error.sql +++ b/sql/test/miscellaneous/Tests/groupby_error.sql @@ -6,10 +6,36 @@ SELECT parent."sys_id" FROM "kagami_dump _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list