Changeset: 069b61f984e4 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=069b61f984e4 Modified Files: sql/backends/monet5/rel_bin.c sql/backends/monet5/sql_gencode.c sql/backends/monet5/sql_statement.c sql/backends/monet5/sql_statement.h sql/server/rel_exp.c sql/server/rel_select.c sql/server/sql_semantic.c sql/test/BugDay_2005-12-19_2.9.3/Tests/bogus_prepare.SF-1377079.stable.err sql/test/BugDay_2005-12-19_2.9.3/Tests/prepare-where.SF-1238867.1238959.1238965.1240124.stable.err sql/test/BugTracker-2017/Tests/wrong_aggregation_count.Bug-6257.stable.out sql/test/BugTracker-2019/Tests/alter_table_set_schema.Bug-6701.stable.out sql/test/miscellaneous/Tests/groupby_error.sql sql/test/miscellaneous/Tests/groupby_error.stable.err sql/test/miscellaneous/Tests/groupby_error.stable.out Branch: default Log Message:
Merged with linear-hashing diffs (truncated from 1023 to 300 lines): diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c --- a/sql/backends/monet5/rel_bin.c +++ b/sql/backends/monet5/rel_bin.c @@ -2226,6 +2226,7 @@ rel2bin_semijoin(backend *be, sql_rel *r list *l; node *en = NULL, *n; stmt *left = NULL, *right = NULL, *join = NULL, *jl, *jr, *c; + int semi_used = 0; if (rel->op == op_anti && !list_empty(rel->exps) && list_length(rel->exps) == 1 && ((sql_exp*)rel->exps->h->data)->flag == mark_notin) return rel2bin_antijoin(be, rel, refs); @@ -2243,7 +2244,37 @@ rel2bin_semijoin(backend *be, sql_rel *r * first cheap join(s) (equality or idx) * second selects/filters */ - if (rel->exps) { + if (rel->op != op_anti && rel->exps && list_length(rel->exps) == 1) { + sql_exp *e = rel->exps->h->data; + + if (e->type == e_cmp && (e->flag == cmp_equal || e->flag == mark_in) && !e->anti && !e->f) { + stmt *r, *l = exp_bin(be, e->l, left, NULL, NULL, NULL, NULL, NULL); + int swap = 0; + + if (!l) { + swap = 1; + l = exp_bin(be, e->l, right, NULL, NULL, NULL, NULL, NULL); + } + r = exp_bin(be, e->r, left, right, NULL, NULL, NULL, NULL); + + if (swap) { + stmt *t = l; + l = r; + r = t; + } + + if (!l || !r) + return NULL; + join = stmt_semijoin(be, l, r); + if (join) + join = stmt_result(be, join, 0); + if (!join) + return NULL; + semi_used = 1; + } + } + + if (!semi_used && rel->exps) { int idx = 0; list *jexps = sa_list(sql->sa); list *lje = sa_list(sql->sa); @@ -2317,13 +2348,14 @@ rel2bin_semijoin(backend *be, sql_rel *r stmt *r = bin_first_column(be, right); join = stmt_join(be, l, r, 0, cmp_all); } - } else { + } else if (!semi_used) { stmt *l = bin_first_column(be, left); stmt *r = bin_first_column(be, right); join = stmt_join(be, l, r, 0, cmp_all); } - jl = stmt_result(be, join, 0); - if (en) { + if (!semi_used) + jl = stmt_result(be, join, 0); + if (!semi_used && en) { stmt *sub, *sel = NULL; list *nl; @@ -2373,13 +2405,15 @@ rel2bin_semijoin(backend *be, sql_rel *r /* construct relation */ l = sa_list(sql->sa); - /* We did a full join, thats too much. - Reduce this using difference and intersect */ - c = stmt_mirror(be, left->op4.lval->h->data); - if (rel->op == op_anti) { - join = stmt_tdiff(be, c, jl); - } else { - join = stmt_tinter(be, c, jl); + if (!semi_used) { + /* We did a full join, thats too much. + Reduce this using difference and intersect */ + c = stmt_mirror(be, left->op4.lval->h->data); + if (rel->op == op_anti) { + join = stmt_tdiff(be, c, jl); + } else { + join = stmt_tinter(be, c, jl); + } } /* project all the left columns */ diff --git a/sql/backends/monet5/sql_gencode.c b/sql/backends/monet5/sql_gencode.c --- a/sql/backends/monet5/sql_gencode.c +++ b/sql/backends/monet5/sql_gencode.c @@ -792,7 +792,7 @@ backend_dumpproc(backend *be, Client c, sql_type *tpe = a->type.type; int type, varid = 0; - if (!tpe) { + if (!tpe || tpe->eclass == EC_ANY) { sql_error(m, 003, SQLSTATE(42000) "Could not determine type for argument number %d\n", argc+1); goto cleanup; } diff --git a/sql/backends/monet5/sql_statement.c b/sql/backends/monet5/sql_statement.c --- a/sql/backends/monet5/sql_statement.c +++ b/sql/backends/monet5/sql_statement.c @@ -1976,6 +1976,40 @@ stmt_join(backend *be, stmt *op1, stmt * return NULL; } +stmt * +stmt_semijoin(backend *be, stmt *op1, stmt *op2) +{ + MalBlkPtr mb = be->mb; + InstrPtr q = NULL; + + if (op1->nr < 0 || op2->nr < 0) + return NULL; + + q = newStmt(mb, algebraRef, semijoinRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, op1->nr); + q = pushArgument(mb, q, op2->nr); + q = pushNil(mb, q, TYPE_bat); + q = pushNil(mb, q, TYPE_bat); + q = pushBit(mb, q, FALSE); + q = pushNil(mb, q, TYPE_lng); + if (q == NULL) + return NULL; + if (q) { + stmt *s = stmt_create(be->mvc->sa, st_semijoin); + + s->op1 = op1; + s->op2 = op2; + s->flag = cmp_equal; + s->key = 0; + s->nrcols = 2; + s->nr = getDestVar(q); + s->q = q; + return s; + } + return NULL; +} + static InstrPtr stmt_project_join(backend *be, stmt *op1, stmt *op2, stmt *ins) { @@ -3227,6 +3261,7 @@ tail_type(stmt *st) st = st->op2; continue; + case st_semijoin: case st_uselect: case st_uselect2: case st_limit: @@ -3315,6 +3350,7 @@ stmt_has_null(stmt *s) switch (s->type) { case st_aggr: case st_Nop: + case st_semijoin: case st_uselect: case st_uselect2: case st_atom: @@ -3383,6 +3419,7 @@ const char * case st_result: case st_append: case st_gen_group: + case st_semijoin: case st_uselect: case st_uselect2: case st_limit: @@ -3440,6 +3477,7 @@ schema_name(sql_allocator *sa, stmt *st) { switch (st->type) { case st_const: + case st_semijoin: case st_join: case st_join2: case st_joinN: diff --git a/sql/backends/monet5/sql_statement.h b/sql/backends/monet5/sql_statement.h --- a/sql/backends/monet5/sql_statement.h +++ b/sql/backends/monet5/sql_statement.h @@ -65,6 +65,7 @@ typedef enum stmt_type { st_join, st_join2, st_joinN, + st_semijoin, st_export, st_append, @@ -184,6 +185,7 @@ extern stmt *stmt_join(backend *be, stmt extern stmt *stmt_join2(backend *be, stmt *l, stmt *ra, stmt *rb, int cmp, int anti, int swapped); /* generic join operator, with a left and right statement list */ extern stmt *stmt_genjoin(backend *be, stmt *l, stmt *r, sql_subfunc *op, int anti, int swapped); +extern stmt *stmt_semijoin(backend *be, stmt *op1, stmt *op2); extern stmt *stmt_project(backend *be, stmt *op1, stmt *op2); extern stmt *stmt_project_delta(backend *be, stmt *col, stmt *upd, stmt *ins); 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; } @@ -1702,7 +1703,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) _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list