Changeset: 2153348bd11a for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2153348bd11a
Modified Files:
        monetdb5/optimizer/opt_mergetable.c
        sql/server/rel_optimizer.c
        sql/server/rel_select.c
        sql/server/rel_updates.c
        sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.err
        sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out
        
sql/test/BugTracker-2015/Tests/date_comparison_incorrect_results.Bug-3834.stable.out
        
sql/test/BugTracker-2015/Tests/update_with_without_parenthesis.Bug-3838.stable.out
Branch: Jul2015
Log Message:

fix bug 3838, ie handle outer joins with updates


diffs (truncated from 332 to 300 lines):

diff --git a/monetdb5/optimizer/opt_mergetable.c 
b/monetdb5/optimizer/opt_mergetable.c
--- a/monetdb5/optimizer/opt_mergetable.c
+++ b/monetdb5/optimizer/opt_mergetable.c
@@ -847,6 +847,7 @@ mat_group_project(MalBlkPtr mb, InstrPtr
                getArg(q,1) = getArg(mat[e].mi,k);
                getArg(q,2) = getArg(mat[a].mi,k);
                pushInstruction(mb,q);
+               setPartnr(mb, getArg(mat[a].mi,k), getArg(q,0), k);
 
                /* pack the result into a mat */
                ai1 = pushArgument(mb,ai1,getArg(q,0));
@@ -1122,6 +1123,9 @@ mat_group_new(MalBlkPtr mb, InstrPtr p, 
                getArg(q, 2) = newTmpVariable(mb, tp2);
                getArg(q, 3) = getArg(ml->v[b].mi, i);
                pushInstruction(mb, q);
+               setPartnr(mb, getArg(ml->v[b].mi,i), getArg(q,0), i);
+               setPartnr(mb, getArg(ml->v[b].mi,i), getArg(q,1), i);
+               setPartnr(mb, getArg(ml->v[b].mi,i), getArg(q,2), i);
 
                /* add result to mats */
                r0 = pushArgument(mb,r0,getArg(q,0));
@@ -1132,9 +1136,9 @@ mat_group_new(MalBlkPtr mb, InstrPtr p, 
                setModuleId(r, algebraRef);
                setFunctionId(r, leftfetchjoinRef);
                getArg(r, 0) = newTmpVariable(mb, atp);
-
                r = pushArgument(mb, r, getArg(q,1));
                r = pushArgument(mb, r, getArg(ml->v[b].mi,i));
+               setPartnr(mb, getArg(ml->v[b].mi,i), getArg(r,0), i);
                pushInstruction(mb,r);
 
                attr = pushArgument(mb, attr, getArg(r, 0)); 
@@ -1206,6 +1210,9 @@ mat_group_derive(MalBlkPtr mb, InstrPtr 
                getArg(q,3) = getArg(ml->v[b].mi,i);
                getArg(q,4) = getArg(ml->v[g].mi,i);
                pushInstruction(mb,q);
+               setPartnr(mb, getArg(ml->v[b].mi,i), getArg(q,0), i);
+               setPartnr(mb, getArg(ml->v[b].mi,i), getArg(q,1), i);
+               setPartnr(mb, getArg(ml->v[b].mi,i), getArg(q,2), i);
        
                /* add result to mats */
                r0 = pushArgument(mb,r0,getArg(q,0));
@@ -1216,9 +1223,9 @@ mat_group_derive(MalBlkPtr mb, InstrPtr 
                setModuleId(r, algebraRef);
                setFunctionId(r, leftfetchjoinRef);
                getArg(r, 0) = newTmpVariable(mb, atp);
-
                r = pushArgument(mb, r, getArg(q,1));
                r = pushArgument(mb, r, getArg(ml->v[b].mi,i));
+               setPartnr(mb, getArg(ml->v[b].mi,i), getArg(r,0), i);
                pushInstruction(mb,r);
 
                attr = pushArgument(mb, attr, getArg(r, 0)); 
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
@@ -7094,6 +7094,20 @@ rel_add_identity(mvc *sql, sql_rel *rel,
        return rel;
 }
 
+static int
+exps_from_rel( list *exps, sql_rel *rel )
+{
+       node *n;
+
+       if (!rel || !exps)
+               return 0;
+       for (n=exps->h; n; n=n->next) {
+               sql_exp *e = n->data;
+               if (rel_find_exp(rel, e) )
+                       return 1;
+       }
+       return 0;
+}
 
 /* push down apply until its gone */
 static sql_rel *
@@ -7145,6 +7159,31 @@ rel_apply_rewrite(int *changes, mvc *sql
                (*changes)++;
                return nrel;
        }
+       if (rel->flag == APPLY_LOJ && r->op == op_project && 
exps_from_rel(r->exps, rel->l)) {
+               sql_exp *ident, *le = NULL;
+               sql_rel *nrel = rel_add_identity(sql, l, &ident), *arel = rel;
+
+               rel->l = nrel;
+               ident = exp_column(sql->sa, exp_relname(ident), 
exp_name(ident), exp_subtype(ident), ident->card, has_nil(ident), 
is_intern(ident));
+
+               rel = rel_project(sql->sa, rel, rel_projections(sql, rel, NULL, 
1, 1));
+
+               /* look up the identity column and label these */
+               le = exps_bind_column2(rel->exps, exp_relname(ident), 
exp_name(ident));
+               exp_label(sql->sa, le, ++sql->label);
+               /* zap rel->exps name hash tables as we changed names */
+               rel->exps->ht = NULL;
+               le = exp_column(sql->sa, exp_relname(le), exp_name(le), 
exp_subtype(le), le->card, has_nil(le), is_intern(le));
+
+               nrel = rel_crossproduct(sql->sa, rel_dup(nrel), rel, op_left);
+               nrel->exps = new_exp_list(sql->sa);
+               le = exp_compare(sql->sa, ident, le, cmp_equal);
+               append(nrel->exps, le);
+
+               arel->flag = APPLY_JOIN;
+               (*changes)++;
+               return nrel;
+       }
        /* table function (TODO should output any input cols) */
        if (r->op == op_table && r->l) {
                /*
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
@@ -354,9 +354,12 @@ rel_projections(mvc *sql, sql_rel *rel, 
        case op_left:
        case op_right:
        case op_full:
+       case op_apply:
                exps = rel_projections(sql, rel->l, tname, settname, intern );
-               rexps = rel_projections(sql, rel->r, tname, settname, intern );
-               exps = list_merge( exps, rexps, (fdup)NULL);
+               if (rel->op != op_apply || (rel->flag  == APPLY_LOJ || 
rel->flag == APPLY_JOIN)) {
+                       rexps = rel_projections(sql, rel->r, tname, settname, 
intern );
+                       exps = list_merge( exps, rexps, (fdup)NULL);
+               }
                return exps;
        case op_groupby:
        case op_project:
@@ -393,7 +396,6 @@ rel_projections(mvc *sql, sql_rel *rel, 
                }
                return exps;
        case op_ddl:
-       case op_apply:
        case op_semi:
        case op_anti:
 
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
@@ -12,6 +12,9 @@
 #include "rel_select.h"
 #include "rel_exp.h"
 #include "sql_privileges.h"
+#include "rel_optimizer.h"
+#include "rel_dump.h"
+#include "sql_symbol.h"
 
 static sql_exp *
 insert_value(mvc *sql, sql_column *c, sql_rel **r, symbol *s)
@@ -855,6 +858,52 @@ update_table(mvc *sql, dlist *qname, dli
                dnode *n;
                char *rname = NULL;
 
+#if 0
+                       dlist *selection = dlist_create(sql->sa);
+                       dlist *from_list = dlist_create(sql->sa);
+                       symbol *sym;
+                       sql_rel *sq;
+
+                       dlist_append_list(sql->sa, from_list, qname);
+                       dlist_append_symbol(sql->sa, from_list, NULL);
+                       sym = symbol_create_list(sql->sa, SQL_NAME, from_list);
+                       from_list = dlist_create(sql->sa);
+                       dlist_append_symbol(sql->sa, from_list, sym);
+
+                       {
+                               dlist *l = dlist_create(sql->sa);
+
+
+                               dlist_append_string(sql->sa, l, tname);
+                               dlist_append_string(sql->sa, l, TID);
+                               sym = symbol_create_list(sql->sa, SQL_COLUMN, 
l);
+
+                               l = dlist_create(sql->sa);
+                               dlist_append_symbol(sql->sa, l, sym);
+                               dlist_append_string(sql->sa, l, TID);
+                               dlist_append_symbol(sql->sa, selection, 
+                                 symbol_create_list(sql->sa, SQL_COLUMN, l));
+                       }
+                       for (n = assignmentlist->h; n; n = n->next) {
+                               dlist *assignment = n->data.sym->data.lval, *l;
+                               int single = (assignment->h->next->type == 
type_string);
+                               symbol *a = assignment->h->data.sym;
+
+                               l = dlist_create(sql->sa);
+                               dlist_append_symbol(sql->sa, l, a);
+                               dlist_append_string(sql->sa, l, 
(single)?assignment->h->next->data.sval:NULL);
+                               a = symbol_create_list(sql->sa, SQL_COLUMN, l);
+                               dlist_append_symbol(sql->sa, selection, a);
+                       }
+                      
+                       sym = newSelectNode(sql->sa, 0, selection, NULL, 
symbol_create_list(sql->sa, SQL_FROM, from_list), opt_where, NULL, NULL, NULL, 
NULL, NULL, NULL, NULL);
+                       sq = rel_selects(sql, sym);
+                       if (sq)
+                               sq = rel_optimizer(sql, sq);
+                       rel_print(sql,sq,0);
+               }
+#endif
+
                if (opt_where) {
                        int status = sql->session->status;
        
@@ -909,7 +958,7 @@ update_table(mvc *sql, dlist *qname, dli
                                        if (single) {
                                                v = rel_value_exp(sql, &r, a, 
sql_sel, ek);
                                        } else if (!rel_val && r) {
-                                               r = rel_subquery(sql, r, a, ek, 
APPLY_JOIN);
+                                               r = rel_subquery(sql, r, a, ek, 
APPLY_LOJ);
                                                if (r) {
                                                        list *val_exps = 
rel_projections(sql, r->r, NULL, 0, 1);
 
@@ -930,7 +979,7 @@ update_table(mvc *sql, dlist *qname, dli
                                                rel_val = rel_project(sql->sa, 
rel_val, rel_projections(sql, rel_val, NULL, 0, 1));
                                                rel_project_add_exp(sql, 
rel_val, v);
                                        }
-                                       r = rel_crossproduct(sql->sa, r, 
rel_val, op_join);
+                                       r = rel_crossproduct(sql->sa, r, 
rel_val, op_left);
                                        if (single) 
                                                v = exp_column(sql->sa, NULL, 
exp_name(v), exp_subtype(v), v->card, has_nil(v), is_intern(v));
                                }
diff --git a/sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.err 
b/sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.err
--- a/sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.err
+++ b/sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.err
@@ -30,7 +30,7 @@ stderr of test 'crash.Bug-3736` in direc
 # 10:50:37 >  "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" 
"--host=/var/tmp/mtest-30636" "--port=38510"
 # 10:50:37 >  
 
-MAPI  = (monetdb) /var/tmp/mtest-6362/.s.monetdb.36855
+MAPI  = (monetdb) /var/tmp/mtest-15304/.s.monetdb.34590
 QUERY = Select b.* FROM open_auctions o, b bidder WHERE (select b3.INCREASE 
from bidder b3 where b3.id = (select min (b3a.id) from bidder b3a where 
b3a.open_auction_id = o.open_auction_id)) * 2 <= (Select b2.INCREASE from 
bidder b2 where b2.id = (SELECT MAX (b2a.id) from bidder b2a where 
b2a.open_auction_id = o.open_auction_id)) AND o.open_auction_id = 
b.open_auction_id order by date, time;
 ERROR = !SELECT: no such table 'b'
 
diff --git a/sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out 
b/sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out
--- a/sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out
+++ b/sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out
@@ -100,11 +100,11 @@ project (
 | | | | | | | | ) [ o.id NOT NULL HASHCOL , o.open_auction_id NOT NULL, b.id 
NOT NULL HASHCOL , b.open_auction_id NOT NULL, b.date NOT NULL, b.time NOT 
NULL, b.personref NOT NULL, b.increase NOT NULL, b3.increase NOT NULL as L2.L2, 
sys.identity(o.id NOT NULL HASHCOL ) HASHCOL  as L12.L12 ],
 | | | | | | | | table(sys.bidder) [ bidder.id NOT NULL as L5.id, 
bidder.increase NOT NULL as L5.increase ] COUNT 
 | | | | | | | ) [  ]
-| | | | | | ) [ L2.L2 NOT NULL, L12.L12 HASHCOL , o.id NOT NULL HASHCOL , 
o.open_auction_id NOT NULL, b.id NOT NULL HASHCOL , b.open_auction_id NOT NULL, 
b.date NOT NULL, b.time NOT NULL, b.personref NOT NULL, b.increase NOT NULL, 
L5.id NOT NULL, L5.increase NOT NULL, sys.identity(o.id NOT NULL HASHCOL ) 
HASHCOL  as L11.L11 ]
+| | | | | | ) [ L12.L12 HASHCOL , o.id NOT NULL HASHCOL , o.open_auction_id 
NOT NULL, b.id NOT NULL HASHCOL , b.open_auction_id NOT NULL, b.date NOT NULL, 
b.time NOT NULL, b.personref NOT NULL, b.increase NOT NULL, L2.L2 NOT NULL, 
L5.id NOT NULL, L5.increase NOT NULL, sys.identity(o.id NOT NULL HASHCOL ) 
HASHCOL  as L11.L11 ]
 | | | | | ) [ L6.open_auction_id NOT NULL = o.open_auction_id NOT NULL ]
-| | | | ) [ L11.L11, L12.L12 ] [ L2.L2 NOT NULL, L12.L12 HASHCOL , b.id NOT 
NULL HASHCOL , b.open_auction_id NOT NULL, b.date NOT NULL, b.time NOT NULL, 
b.personref NOT NULL, b.increase NOT NULL, L5.id NOT NULL, L5.increase NOT 
NULL, L11.L11 HASHCOL , sys.max no nil (L6.id NOT NULL HASHCOL  as b2a.id) NOT 
NULL as L3.L3 ]
+| | | | ) [ L11.L11, L12.L12 ] [ L12.L12 HASHCOL , b.id NOT NULL HASHCOL , 
b.open_auction_id NOT NULL, b.date NOT NULL, b.time NOT NULL, b.personref NOT 
NULL, b.increase NOT NULL, L2.L2 NOT NULL, L5.id NOT NULL, L5.increase NOT 
NULL, L11.L11 HASHCOL , sys.max no nil (L6.id NOT NULL HASHCOL  as b2a.id) NOT 
NULL as L3.L3 ]
 | | | ) [ L5.id NOT NULL = L3.L3 NOT NULL ]
-| | ) [ L2.L2 NOT NULL, L12.L12 HASHCOL , b.id NOT NULL HASHCOL , 
b.open_auction_id NOT NULL, b.date NOT NULL, b.time NOT NULL, b.personref NOT 
NULL, b.increase NOT NULL, L5.id NOT NULL, L5.increase NOT NULL, L11.L11 
HASHCOL , L3.L3 NOT NULL, sys.sql_mul(L2.L2 NOT NULL, double "2.000000") as 
L13.L13, L5.increase NOT NULL as L14.L14 ]
+| | ) [ L12.L12 HASHCOL , b.id NOT NULL HASHCOL , b.open_auction_id NOT NULL, 
b.date NOT NULL, b.time NOT NULL, b.personref NOT NULL, b.increase NOT NULL, 
L2.L2 NOT NULL, L5.id NOT NULL, L5.increase NOT NULL, L11.L11 HASHCOL , L3.L3 
NOT NULL, sys.sql_mul(L2.L2 NOT NULL, double "2.000000") as L13.L13, 
L5.increase NOT NULL as L14.L14 ]
 | ) [ L13.L13 <= L14.L14 NOT NULL ]
 ) [ b.id NOT NULL HASHCOL , b.open_auction_id NOT NULL, b.date NOT NULL, 
b.time NOT NULL, b.personref NOT NULL, b.increase NOT NULL ]
 #Select b.* FROM open_auctions o, bidder b WHERE (select b3.INCREASE from 
bidder b3 where b3.id = (select min (b3a.id) from bidder b3a where 
b3a.open_auction_id = o.open_auction_id)) * 2 <= (Select b2.INCREASE from 
bidder b2 where b2.id = (SELECT MAX (b2a.id) from bidder b2a where 
b2a.open_auction_id = o.open_auction_id)) AND o.open_auction_id = 
b.open_auction_id;
diff --git 
a/sql/test/BugTracker-2015/Tests/date_comparison_incorrect_results.Bug-3834.stable.out
 
b/sql/test/BugTracker-2015/Tests/date_comparison_incorrect_results.Bug-3834.stable.out
--- 
a/sql/test/BugTracker-2015/Tests/date_comparison_incorrect_results.Bug-3834.stable.out
+++ 
b/sql/test/BugTracker-2015/Tests/date_comparison_incorrect_results.Bug-3834.stable.out
@@ -86,13 +86,13 @@ Ready.
 #      WHERE datepoint_wrong.mydate >= B.startdate
 #      AND datepoint_wrong.mydate <= B.enddate
 #);
-[ 1    ]
+[ 2    ]
 #SELECT * FROM datepoint_wrong;
 % sys.datepoint_wrong, sys.datepoint_wrong,    sys.datepoint_wrong # table_name
 % mydate,      insiderange,    rangename # name
 % date,        boolean,        char # type
 % 10,  5,      8 # length
-[ 2012-05-09,  false,  NULL    ]
+[ 2012-05-09,  NULL,   NULL    ]
 [ 2012-03-09,  true,   "A"     ]
 #CREATE TABLE datepoint_correct1 (mydate DATE, insiderange BOOLEAN DEFAULT 
FALSE, rangename CHAR(8));
 #INSERT INTO datepoint_correct1 (mydate) VALUES ('2012-05-09');
@@ -120,15 +120,15 @@ Ready.
 #      WHERE datepoint_correct1.mydate >= B.startdate
 #      AND datepoint_correct1.mydate <= B.enddate
 #);
-[ 1    ]
+[ 3    ]
 #SELECT * FROM datepoint_correct1;
 % sys.datepoint_correct1,      sys.datepoint_correct1, sys.datepoint_correct1 
# table_name
 % mydate,      insiderange,    rangename # name
 % date,        boolean,        char # type
 % 10,  5,      8 # length
-[ 2012-05-09,  false,  NULL    ]
+[ 2012-05-09,  NULL,   NULL    ]
 [ 2012-03-09,  true,   "A"     ]
-[ 2012-04-09,  false,  NULL    ]
+[ 2012-04-09,  NULL,   NULL    ]
 #CREATE TABLE datepoint_correct2 (mydate DATE, insiderange BOOLEAN DEFAULT 
FALSE, rangename CHAR(8));
 #INSERT INTO datepoint_correct2 (mydate) VALUES ('2012-03-09');
 [ 1    ]
@@ -153,14 +153,14 @@ Ready.
 #      WHERE datepoint_correct2.mydate >= B.startdate
 #      AND datepoint_correct2.mydate <= B.enddate
 #);
-[ 1    ]
+[ 2    ]
 #SELECT * FROM datepoint_correct2;
 % sys.datepoint_correct2,      sys.datepoint_correct2, sys.datepoint_correct2 
# table_name
 % mydate,      insiderange,    rangename # name
 % date,        boolean,        char # type
 % 10,  5,      8 # length
 [ 2012-03-09,  true,   "A"     ]
-[ 2012-05-09,  false,  NULL    ]
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to