Changeset: 2d6a1bb0e0cb for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2d6a1bb0e0cb Added Files: sql/test/BugTracker-2013/Tests/not_null.Bug-3403.sql sql/test/BugTracker-2013/Tests/not_null.Bug-3403.stable.err sql/test/BugTracker-2013/Tests/not_null.Bug-3403.stable.out Modified Files: sql/backends/monet5/sql.c sql/server/rel_exp.c sql/server/rel_exp.h sql/server/rel_optimizer.c sql/server/rel_planner.c sql/server/rel_planner.h sql/test/BugTracker-2013/Tests/All sql/test/BugTracker-2013/Tests/between.Bug-3259.stable.out Branch: Jan2014 Log Message:
merged with Feb2013, resolved conflicts diffs (truncated from 361 to 300 lines): diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c --- a/sql/backends/monet5/sql.c +++ b/sql/backends/monet5/sql.c @@ -546,15 +546,9 @@ alter_table(mvc *sql, char *sname, sql_t mvc_null(sql, nc, c->null); /* for non empty check for nulls */ if (c->null == 0) { - BAT *b = store_funcs.bind_col(sql->session->tr, nc, 0); - - /* TODO also check updates and inserts */ - if (BATcount(b) && b->T->nonil != TRUE) { - BUN bun = BUNfnd(BATmirror(b), ATOMnilptr(b->ttype)); - if (bun != BUN_NONE) - return sql_message("40002!ALTER TABLE: NOT NULL constraint violated for column %s.%s", c->t->base.name, c->base.name); - } - BBPunfix(b->batCacheid); + void *nilptr = ATOMnilptr(c->type.type->localtype); + if (table_funcs.column_find_row(sql->session->tr, nc, nilptr, NULL) != oid_nil) + return sql_message("40002!ALTER TABLE: NOT NULL constraint violated for column %s.%s", c->t->base.name, c->base.name); } } if (c->def != nc->def) 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 @@ -796,7 +796,7 @@ exps_are_joins( list *l ) int exp_is_join_exp(sql_exp *e) { - if (exp_is_join(e) == 0) + if (exp_is_join(e, NULL) == 0) return 0; if (e->type == e_cmp && e->flag == cmp_or && e->card >= CARD_AGGR) if (exps_are_joins(e->l) == 0 && exps_are_joins(e->r) == 0) @@ -883,8 +883,42 @@ distinct_rel(sql_exp *e, char **rname) } return 0; } + +int +rel_has_exp(sql_rel *rel, sql_exp *e) +{ + if (rel_find_exp(rel, e) != NULL) + return 0; + return -1; +} + +sql_rel * +find_rel(list *rels, sql_exp *e) +{ + node *n = list_find(rels, e, (fcmp)&rel_has_exp); + if (n) + return n->data; + return NULL; +} + +sql_rel * +find_one_rel(list *rels, sql_exp *e) +{ + node *n; + sql_rel *fnd = NULL; + + for(n = rels->h; n; n = n->next) { + if (rel_has_exp(n->data, e) == 0) { + if (fnd) + return NULL; + fnd = n->data; + } + } + return fnd; +} + static int -exp_is_rangejoin(sql_exp *e) +exp_is_rangejoin(sql_exp *e, list *rels) { /* assume e is a e_cmp with 3 args * Need to check e->r and e->f only touch one table. @@ -893,11 +927,17 @@ exp_is_rangejoin(sql_exp *e) if (distinct_rel(e->r, &rname) && distinct_rel(e->f, &rname)) return 0; + if (rels) { + sql_rel *r = find_rel(rels, e->r); + sql_rel *f = find_rel(rels, e->f); + if (r && f && r == f) + return 0; + } return -1; } int -exp_is_join(sql_exp *e) +exp_is_join(sql_exp *e, list *rels) { /* only simple compare expressions, ie not or lists or range expressions (e->f) @@ -908,7 +948,7 @@ exp_is_join(sql_exp *e) return 0; /* range expression */ if (e->type == e_cmp && !is_complex_exp(e->flag) && e->l && e->r && e->f && e->card >= CARD_AGGR && !complex_select(e)) - return exp_is_rangejoin(e); + return exp_is_rangejoin(e, rels); return -1; } diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h --- a/sql/server/rel_exp.h +++ b/sql/server/rel_exp.h @@ -105,13 +105,17 @@ extern int exp_match_exp( sql_exp *e1, s /* match just the column (cmp equality) expressions */ extern int exp_match_col_exps( sql_exp *e, list *l); extern int exps_match_col_exps( sql_exp *e1, sql_exp *e2); -extern int exp_is_join(sql_exp *e); +extern int exp_is_join(sql_exp *e, list *rels); extern int exp_is_eqjoin(sql_exp *e); extern int exp_is_correlation(sql_exp *e, sql_rel *r ); extern int exp_is_join_exp(sql_exp *e); extern int exp_is_atom(sql_exp *e); extern int exp_has_func(sql_exp *e); +extern int rel_has_exp(sql_rel *rel, sql_exp *e); +extern sql_rel *find_rel(list *rels, sql_exp *e); +extern sql_rel *find_one_rel(list *rels, sql_exp *e); + extern sql_exp *exps_bind_column( list *exps, char *cname, int *ambiguous); extern sql_exp *exps_bind_column2( list *exps, char *rname, char *cname); extern sql_exp *exps_bind_alias( list *exps, char *rname, char *cname); diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c --- a/sql/server/rel_optimizer.c +++ b/sql/server/rel_optimizer.c @@ -419,15 +419,6 @@ exp_keyvalue(sql_exp *e) return cnt; } -static sql_rel * -find_rel(list *rels, sql_exp *e) -{ - node *n = list_find(rels, e, (fcmp)&rel_has_exp); - if (n) - return n->data; - return NULL; -} - static int joinexp_cmp(list *rels, sql_exp *h, sql_exp *key) { @@ -654,7 +645,7 @@ find_fk( mvc *sql, list *rels, list *exp list *sdje, *aje, *dje; /* first find the distinct join expressions */ - aje = list_select(exps, (void*)1, (fcmp) &exp_is_join, (fdup)NULL); + aje = list_select(exps, rels, (fcmp) &exp_is_join, (fdup)NULL); dje = list_distinct2(aje, rels, (fcmp2) &joinexp_cmp, (fdup)NULL); for(djn=dje->h; djn; djn = djn->next) { /* equal join expressions */ diff --git a/sql/server/rel_planner.c b/sql/server/rel_planner.c --- a/sql/server/rel_planner.c +++ b/sql/server/rel_planner.c @@ -748,27 +748,4 @@ rel_planner(mvc *sql, list *rels, list * return top; } -int -rel_has_exp(sql_rel *rel, sql_exp *e) -{ - if (rel_find_exp(rel, e) != NULL) - return 0; - return -1; -} -sql_rel * -find_one_rel(list *rels, sql_exp *e) -{ - node *n; - sql_rel *fnd = NULL; - - for(n = rels->h; n; n = n->next) { - if (rel_has_exp(n->data, e) == 0) { - if (fnd) - return NULL; - fnd = n->data; - } - } - return fnd; -} - diff --git a/sql/server/rel_planner.h b/sql/server/rel_planner.h --- a/sql/server/rel_planner.h +++ b/sql/server/rel_planner.h @@ -24,7 +24,4 @@ extern sql_rel * rel_planner(mvc *sql, list *rels, list *jes); -extern int rel_has_exp(sql_rel *rel, sql_exp *e); -extern sql_rel *find_one_rel(list *rels, sql_exp *e); - #endif /*_REL_PLANNER_H_ */ diff --git a/sql/test/BugTracker-2013/Tests/All b/sql/test/BugTracker-2013/Tests/All --- a/sql/test/BugTracker-2013/Tests/All +++ b/sql/test/BugTracker-2013/Tests/All @@ -61,3 +61,4 @@ case_when.Bug-3395 udf_error.Bug-3396 syntaxerror.Bug-3399 timestamp.Bug-3401 +not_null.Bug-3403 diff --git a/sql/test/BugTracker-2013/Tests/between.Bug-3259.stable.out b/sql/test/BugTracker-2013/Tests/between.Bug-3259.stable.out --- a/sql/test/BugTracker-2013/Tests/between.Bug-3259.stable.out +++ b/sql/test/BugTracker-2013/Tests/between.Bug-3259.stable.out @@ -46,39 +46,29 @@ Ready. % clob # type % 173 # length function user.s2_1():void; -barrier X_58 := language.dataflow(); +barrier X_46 := language.dataflow(); X_1 := sql.mvc(); X_2:bat[:oid,:oid] := sql.tid(X_1,"sys","treeitems"); - X_5 := sql.bind(X_1,"sys","treeitems","subject",0); + X_5 := sql.bind(X_1,"sys","treeitems","pre",0); X_8 := algebra.leftfetchjoin(X_2,X_5); - (X_9,r1_12) := algebra.crossproduct(X_8,X_8); - X_11 := sql.bind(X_1,"sys","treeitems","pre",0); - X_13 := algebra.leftfetchjoin(X_2,X_11); - X_14 := algebra.leftfetchjoin(r1_12,X_13); - X_15 := algebra.leftfetchjoin(X_9,X_13); - X_25:bat[:oid,:bit] := batcalc.>=(X_14,X_15); - X_16 := sql.bind(X_1,"sys","treeitems","size",0); + X_9 := sql.bind(X_1,"sys","treeitems","size",0); + X_11 := algebra.leftfetchjoin(X_2,X_9); + X_12:bat[:oid,:lng] := batcalc.+(X_8,X_11); + (X_13,r1_18) := algebra.join(X_8,X_8,X_12,true,true); + X_16 := sql.bind(X_1,"sys","treeitems","subject",0); X_18 := algebra.leftfetchjoin(X_2,X_16); - X_19:bat[:oid,:lng] := batcalc.+(X_13,X_18); - X_20 := algebra.leftfetchjoin(X_9,X_19); - X_21:bat[:oid,:bit] := batcalc.<=(X_14,X_20); - X_22 := algebra.subselect(X_21,true,true,true,true,false); - X_26 := algebra.subselect(X_25,X_22,true,true,true,true,false); - X_27:bat[:oid,:int] := algebra.leftfetchjoinPath(X_26,X_9,X_8); - X_28:bat[:oid,:int] := algebra.leftfetchjoinPath(X_26,r1_12,X_8); + X_19 := algebra.leftfetchjoin(r1_18,X_18); + X_20 := algebra.leftfetchjoin(X_13,X_18); + language.pass(X_8); + language.pass(X_8); language.pass(X_2); - language.pass(X_13); - language.pass(X_14); - language.pass(X_9); - language.pass(X_26); - language.pass(r1_12); - language.pass(X_8); -exit X_58; - X_29 := sql.resultSet(2,1,X_27); - sql.rsColumn(X_29,"sys.L","id1","int",32,0,X_27); - sql.rsColumn(X_29,"sys.L","id2","int",32,0,X_28); - X_40 := io.stdout(); - sql.exportResult(X_40,X_29); + language.pass(X_18); +exit X_46; + X_21 := sql.resultSet(2,1,X_19); + sql.rsColumn(X_21,"sys.L","id1","int",32,0,X_19); + sql.rsColumn(X_21,"sys.L","id2","int",32,0,X_20); + X_31 := io.stdout(); + sql.exportResult(X_31,X_21); end s2_1; # querylog.define("explain\nselect t1.subject as id1, t2.subject as id2\nfrom treeitems t1, treeitems t2\nwhere t2.pre between t1.pre and t1.pre + t1.size;","default_pipe") #ROLLBACK; diff --git a/sql/test/BugTracker-2013/Tests/not_null.Bug-3403.sql b/sql/test/BugTracker-2013/Tests/not_null.Bug-3403.sql new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2013/Tests/not_null.Bug-3403.sql @@ -0,0 +1,5 @@ +CREATE TABLE foo (i INT); +INSERT INTO foo (i) VALUES (NULL); +DELETE from foo where i IS NULL; +ALTER TABLE foo ALTER COLUMN i SET NOT NULL; +DROP TABLE foo; diff --git a/sql/test/BugTracker-2013/Tests/not_null.Bug-3403.stable.err b/sql/test/BugTracker-2013/Tests/not_null.Bug-3403.stable.err new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2013/Tests/not_null.Bug-3403.stable.err @@ -0,0 +1,35 @@ +stderr of test 'not_null.Bug-3403` in directory 'sql/test/BugTracker-2013` itself: + + +# 11:21:51 > +# 11:21:51 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "mapi_open=true" "--set" "mapi_port=38824" "--set" "mapi_usock=/var/tmp/mtest-18545/.s.monetdb.38824" "--set" "monet_prompt=" "--forcemito" "--set" "mal_listing=2" "--dbpath=/home/niels/scratch/rc-clean/Linux-x86_64/var/MonetDB/mTests_sql_test_BugTracker-2013" "--set" "mal_listing=0" +# 11:21:51 > + +# builtin opt gdk_dbpath = /home/niels/scratch/rc-clean/Linux-x86_64/var/monetdb5/dbfarm/demo +# builtin opt gdk_debug = 0 +# builtin opt gdk_vmtrim = yes +# builtin opt monet_prompt = > +# builtin opt monet_daemon = no +# builtin opt mapi_port = 50000 +# builtin opt mapi_open = false +# builtin opt mapi_autosense = false +# builtin opt sql_optimizer = default_pipe +# builtin opt sql_debug = 0 +# cmdline opt gdk_nr_threads = 0 _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list