Changeset: 282d9d8673fe for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=282d9d8673fe Modified Files: sql/server/rel_updates.c sql/test/SQLancer/Tests/sqlancer07.sql sql/test/SQLancer/Tests/sqlancer07.stable.out sql/test/SQLancer/Tests/sqlancer07.stable.out.int128 sql/test/SQLancer/Tests/sqlancer11.sql sql/test/SQLancer/Tests/sqlancer11.stable.out Branch: Oct2020 Log Message:
Clean projection handling on update and inserts indices. On update case there was missing a case where a hash index could add a projection into an union relation, thus generating a bad plan. As a consequence sqlancer11 crash is reproducible on sqlancer07, so move the test diffs (263 lines): diff --git a/sql/server/rel_updates.c b/sql/server/rel_updates.c --- a/sql/server/rel_updates.c +++ b/sql/server/rel_updates.c @@ -68,15 +68,6 @@ get_table(sql_rel *t) return tab; } -static list * -get_inserts( sql_rel *ins ) -{ - sql_rel *r = ins->r; - - assert(is_project(r->op) || r->op == op_table); - return r->exps; -} - static sql_rel * rel_insert_hash_idx(mvc *sql, const char* alias, sql_idx *i, sql_rel *inserts) { @@ -85,10 +76,13 @@ rel_insert_hash_idx(mvc *sql, const char sql_subtype *it, *lng; int bits = 1 + ((sizeof(lng)*8)-1)/(list_length(i->columns)+1); sql_exp *h = NULL; + sql_rel *ins = inserts->r; + assert(is_project(ins->op) || ins->op == op_table); if (list_length(i->columns) <= 1 || i->type == no_idx) { /* dummy append */ - append(get_inserts(inserts), exp_label(sql->sa, exp_atom_lng(sql->sa, 0), ++sql->label)); + inserts->r = ins = rel_project(sql->sa, ins, rel_projections(sql, ins, NULL, 1, 1)); + list_append(ins->exps, exp_label(sql->sa, exp_atom_lng(sql->sa, 0), ++sql->label)); return inserts; } @@ -96,7 +90,7 @@ rel_insert_hash_idx(mvc *sql, const char lng = sql_bind_localtype("lng"); for (m = i->columns->h; m; m = m->next) { sql_kc *c = m->data; - sql_exp *e = list_fetch(get_inserts(inserts), c->c->colnr); + sql_exp *e = list_fetch(ins->exps, c->c->colnr); e = exp_ref(sql, e); if (h && i->type == hash_idx) { @@ -124,7 +118,8 @@ rel_insert_hash_idx(mvc *sql, const char } } /* append inserts to hash */ - append(get_inserts(inserts), h); + inserts->r = ins = rel_project(sql->sa, ins, rel_projections(sql, ins, NULL, 1, 1)); + list_append(ins->exps, h); exp_setname(sql->sa, h, alias, iname); return inserts; } @@ -145,6 +140,7 @@ rel_insert_join_idx(mvc *sql, const char sql_exp *lnll_exps = NULL, *rnll_exps = NULL, *e; list *join_exps = new_exp_list(sql->sa), *pexps; + assert(is_project(ins->op) || ins->op == op_table); for (m = i->columns->h; m; m = m->next) { sql_kc *c = m->data; @@ -218,7 +214,6 @@ static sql_rel * rel_insert_idxs(mvc *sql, sql_table *t, const char* alias, sql_rel *inserts) { sql_rel *p = inserts->r; - bool need_proj = true, special_insert = false; if (!t->idxs.set) return inserts; @@ -226,23 +221,14 @@ rel_insert_idxs(mvc *sql, sql_table *t, inserts->r = rel_label(sql, inserts->r, 1); for (node *n = t->idxs.set->h; n; n = n->next) { sql_idx *i = n->data; - sql_rel *ins = inserts->r; - if (is_union(ins->op)) - inserts->r = rel_project(sql->sa, ins, rel_projections(sql, ins, NULL, 0, 1)); if (hash_index(i->type) || i->type == no_idx) { - /* needs projection for hash functions */ - if (list_length(i->columns) > 1 && hash_index(i->type) && need_proj) { - inserts->r = rel_project(sql->sa, inserts->r, rel_projections(sql, inserts->r, NULL, 1, 1)); - need_proj = false; - } rel_insert_hash_idx(sql, alias, i, inserts); } else if (i->type == join_idx) { - special_insert = true; rel_insert_join_idx(sql, alias, i, inserts); } } - if (special_insert) { + if (inserts->r != p) { sql_rel *r = rel_create(sql->sa); if(!r) return NULL; @@ -647,7 +633,9 @@ rel_update_hash_idx(mvc *sql, const char sql_subtype *it, *lng = 0; /* is not set in first if below */ int bits = 1 + ((sizeof(lng)*8)-1)/(list_length(i->columns)+1); sql_exp *h = NULL; + sql_rel *ups = updates->r; + assert(is_project(ups->op) || ups->op == op_table); if (list_length(i->columns) <= 1 || i->type == no_idx) { h = exp_label(sql->sa, exp_atom_lng(sql->sa, 0), ++sql->label); } else { @@ -655,7 +643,7 @@ rel_update_hash_idx(mvc *sql, const char lng = sql_bind_localtype("lng"); for (m = i->columns->h; m; m = m->next) { sql_kc *c = m->data; - sql_exp *e = list_fetch(get_inserts(updates), c->c->colnr+1); + sql_exp *e = list_fetch(ups->exps, c->c->colnr+1); e = exp_ref(sql, e); if (h && i->type == hash_idx) { @@ -684,7 +672,8 @@ rel_update_hash_idx(mvc *sql, const char } } /* append hash to updates */ - append(get_inserts(updates), h); + updates->r = ups = rel_project(sql->sa, ups, rel_projections(sql, ups, NULL, 1, 1)); + list_append(ups->exps, h); exp_setname(sql->sa, h, alias, iname); if (!updates->exps) @@ -738,6 +727,7 @@ rel_update_join_idx(mvc *sql, const char sql_exp *lnll_exps = NULL, *rnll_exps = NULL, *e; list *join_exps = new_exp_list(sql->sa), *pexps; + assert(is_project(ups->op) || ups->op == op_table); for (m = i->columns->h; m; m = m->next) { sql_kc *c = m->data; @@ -748,7 +738,7 @@ rel_update_join_idx(mvc *sql, const char sql_kc *c = m->data; sql_kc *rc = o->data; sql_subfunc *isnil = sql_bind_func(sql->sa, sql->session->schema, "isnull", &c->c->type, NULL, F_FUNC); - sql_exp *upd = list_fetch(get_inserts(updates), c->c->colnr + 1), *lnl, *rnl, *je; + sql_exp *upd = list_fetch(ups->exps, c->c->colnr + 1), *lnl, *rnl, *je; sql_exp *rtc = exp_column(sql->sa, rel_name(rt), rc->c->base.name, &rc->c->type, CARD_MULTI, rc->c->null, 0); /* FOR MATCH FULL/SIMPLE/PARTIAL see above */ @@ -819,7 +809,6 @@ static sql_rel * rel_update_idxs(mvc *sql, const char *alias, sql_table *t, sql_rel *relup) { sql_rel *p = relup->r; - bool need_proj = true, special_update = false; if (!t->idxs.set) return relup; @@ -839,18 +828,12 @@ rel_update_idxs(mvc *sql, const char *al */ if (hash_index(i->type) || i->type == no_idx) { - /* needs projection for hash functions */ - if (list_length(i->columns) > 1 && hash_index(i->type) && need_proj) { - relup->r = rel_project(sql->sa, relup->r, rel_projections(sql, relup->r, NULL, 1, 1)); - need_proj = false; - } rel_update_hash_idx(sql, alias, i, relup); } else if (i->type == join_idx) { - special_update = true; rel_update_join_idx(sql, alias, i, relup); } } - if (special_update) { + if (relup->r != p) { sql_rel *r = rel_create(sql->sa); if(!r) return NULL; diff --git a/sql/test/SQLancer/Tests/sqlancer07.sql b/sql/test/SQLancer/Tests/sqlancer07.sql --- a/sql/test/SQLancer/Tests/sqlancer07.sql +++ b/sql/test/SQLancer/Tests/sqlancer07.sql @@ -247,12 +247,6 @@ SELECT CAST(SUM(count) AS BIGINT) FROM ( ROLLBACK; START TRANSACTION; -CREATE TABLE "t1" ("c0" BIGINT NOT NULL,CONSTRAINT "t1_c0_pkey" PRIMARY KEY ("c0")); -INSERT INTO t1(c0) VALUES(2), (+ ((VALUES (sql_min(3, 4))))); -SELECT * from t1; -ROLLBACK; - -START TRANSACTION; CREATE TABLE "t0" ("c0" TIMESTAMP NOT NULL,CONSTRAINT "t0_c0_pkey" PRIMARY KEY ("c0"),CONSTRAINT "t0_c0_unique" UNIQUE ("c0")); COPY 5 RECORDS INTO "t0" FROM stdin USING DELIMITERS E'\t',E'\n','"'; "1970-01-06 01:52:11.000000" diff --git a/sql/test/SQLancer/Tests/sqlancer07.stable.out b/sql/test/SQLancer/Tests/sqlancer07.stable.out --- a/sql/test/SQLancer/Tests/sqlancer07.stable.out +++ b/sql/test/SQLancer/Tests/sqlancer07.stable.out @@ -360,18 +360,6 @@ stdout of test 'sqlancer07` in directory [ 0 ] #ROLLBACK; #START TRANSACTION; -#CREATE TABLE "t1" ("c0" BIGINT NOT NULL,CONSTRAINT "t1_c0_pkey" PRIMARY KEY ("c0")); -#INSERT INTO t1(c0) VALUES(2), (+ ((VALUES (sql_min(3, 4))))); -[ 2 ] -#SELECT * from t1; -% sys.t1 # table_name -% c0 # name -% bigint # type -% 1 # length -[ 2 ] -[ 3 ] -#ROLLBACK; -#START TRANSACTION; #CREATE TABLE "t0" ("c0" TIMESTAMP NOT NULL,CONSTRAINT "t0_c0_pkey" PRIMARY KEY ("c0"),CONSTRAINT "t0_c0_unique" UNIQUE ("c0")); #COPY 5 RECORDS INTO "t0" FROM stdin USING DELIMITERS E'\t',E'\n','"'; #"1970-01-06 01:52:11.000000" diff --git a/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128 b/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128 --- a/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128 +++ b/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128 @@ -360,18 +360,6 @@ stdout of test 'sqlancer07` in directory [ 0 ] #ROLLBACK; #START TRANSACTION; -#CREATE TABLE "t1" ("c0" BIGINT NOT NULL,CONSTRAINT "t1_c0_pkey" PRIMARY KEY ("c0")); -#INSERT INTO t1(c0) VALUES(2), (+ ((VALUES (sql_min(3, 4))))); -[ 2 ] -#SELECT * from t1; -% sys.t1 # table_name -% c0 # name -% bigint # type -% 1 # length -[ 2 ] -[ 3 ] -#ROLLBACK; -#START TRANSACTION; #CREATE TABLE "t0" ("c0" TIMESTAMP NOT NULL,CONSTRAINT "t0_c0_pkey" PRIMARY KEY ("c0"),CONSTRAINT "t0_c0_unique" UNIQUE ("c0")); #COPY 5 RECORDS INTO "t0" FROM stdin USING DELIMITERS E'\t',E'\n','"'; #"1970-01-06 01:52:11.000000" diff --git a/sql/test/SQLancer/Tests/sqlancer11.sql b/sql/test/SQLancer/Tests/sqlancer11.sql --- a/sql/test/SQLancer/Tests/sqlancer11.sql +++ b/sql/test/SQLancer/Tests/sqlancer11.sql @@ -1,3 +1,9 @@ +START TRANSACTION; +CREATE TABLE "t1" ("c0" BIGINT NOT NULL,CONSTRAINT "t1_c0_pkey" PRIMARY KEY ("c0")); +INSERT INTO t1(c0) VALUES(2), (+ ((VALUES (sql_min(3, 4))))); +SELECT * from t1; +ROLLBACK; + START TRANSACTION; CREATE TABLE "sys"."t0" ("c0" TIME NOT NULL, "c1" VARCHAR(143), CONSTRAINT "t0_c0_pkey" PRIMARY KEY ("c0"), CONSTRAINT "t0_c0_unique" UNIQUE ("c0"), CONSTRAINT "t0_c1_unique" UNIQUE ("c1")); diff --git a/sql/test/SQLancer/Tests/sqlancer11.stable.out b/sql/test/SQLancer/Tests/sqlancer11.stable.out --- a/sql/test/SQLancer/Tests/sqlancer11.stable.out +++ b/sql/test/SQLancer/Tests/sqlancer11.stable.out @@ -6,6 +6,18 @@ stdout of test 'sqlancer10` in directory # 13:59:46 > #START TRANSACTION; +#CREATE TABLE "t1" ("c0" BIGINT NOT NULL,CONSTRAINT "t1_c0_pkey" PRIMARY KEY ("c0")); +#INSERT INTO t1(c0) VALUES(2), (+ ((VALUES (sql_min(3, 4))))); +[ 2 ] +#SELECT * from t1; +% sys.t1 # table_name +% c0 # name +% bigint # type +% 1 # length +[ 2 ] +[ 3 ] +#ROLLBACK; +#START TRANSACTION; #CREATE TABLE "sys"."t0" ("c0" TIME NOT NULL, "c1" VARCHAR(143), # CONSTRAINT "t0_c0_pkey" PRIMARY KEY ("c0"), CONSTRAINT "t0_c0_unique" UNIQUE ("c0"), CONSTRAINT "t0_c1_unique" UNIQUE ("c1")); #COPY 7 RECORDS INTO "sys"."t0" FROM stdin USING DELIMITERS E'\t',E'\n','"'; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list