Changeset: 3f0a5649038f for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3f0a5649038f
Modified Files:
        monetdb5/modules/kernel/algebra.mx
        monetdb5/optimizer/opt_mergetable.c
        monetdb5/optimizer/opt_prelude.c
        monetdb5/optimizer/opt_prelude.h
        monetdb5/optimizer/opt_support.c
        sql/backends/monet5/sql_gencode.c
        sql/include/sql_relation.h
        sql/server/rel_bin.c
        sql/server/rel_dump.c
        
sql/test/BugTracker-2010/Tests/LIMIT_OFFSET_big-endian.Bug-2622.stable.out
Branch: default
Log Message:

added subslice
mergetable now handles slice (ie limit/offset without order by)


diffs (truncated from 557 to 300 lines):

diff --git a/monetdb5/modules/kernel/algebra.mx 
b/monetdb5/modules/kernel/algebra.mx
--- a/monetdb5/modules/kernel/algebra.mx
+++ b/monetdb5/modules/kernel/algebra.mx
@@ -236,6 +236,10 @@ command slice(b:bat[:any_1,:any_2], x:wr
 address ALGslice_wrd
 comment "Return the slice with the BUNs at position x till y.";
 
+command subslice(b:bat[:oid,:any_1], x:wrd, y:wrd) :bat[:oid,:oid] 
+address ALGsubslice_wrd
+comment "Return the oids of the slice with the BUNs at position x till y.";
+
 command topN( b:bat[:any_1,:any_2], top:lng ) :bat[:any_1,:any_2]
 address ALGtopN
 comment "Trim all but the top N tuples.";
@@ -1107,6 +1111,7 @@ algebra_export str ALGslice(int *ret, ba
 algebra_export str ALGslice_int(int *ret, bat *bid, int *start, int *end);
 algebra_export str ALGslice_wrd(int *ret, bat *bid, wrd *start, wrd *end);
 algebra_export str ALGslice_oid(int *ret, bat *bid, oid *start, oid *end);
+algebra_export str ALGsubslice_wrd(int *ret, bat *bid, wrd *start, wrd *end);
 algebra_export str ALGposition(wrd *retval, int *bid, ptr val);
 algebra_export str ALGpositionBUN(wrd *retval, int *bid, ptr val, ptr tval);
 algebra_export str ALGfetch(ptr ret, int *bid, lng *pos);
@@ -3481,6 +3486,24 @@ ALGslice_oid(int *ret, bat *bid, oid *st
        return MAL_SUCCEED;
 }
 
+str
+ALGsubslice_wrd(int *ret, bat *bid, wrd *start, wrd *end)
+{
+       lng s = *start;
+       lng e = (*end == wrd_nil ? lng_nil : *end);
+       bat slc;
+       str msg;
+
+       if ((msg = ALGslice(&slc, bid, &s, &e)) == MAL_SUCCEED) {
+               if ((msg = ALGtmark_default(ret, &slc)) == MAL_SUCCEED) {
+                       BBPdecref(slc, TRUE); 
+                       *ret = -*ret; /* ugly reverse */ 
+                       return MAL_SUCCEED;
+               }
+       }
+       return msg;
+}
+
 /*
  * @- BUN Get/Fetch
  */
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
@@ -25,7 +25,7 @@ typedef enum mat_type_t {
        mat_ext = 2,    /* after mat_grp the extend gets a mat.mirror */
        mat_cnt = 3,    /* after mat_grp the extend gets a mat.mirror */
        mat_tpn = 4,    /* Phase one of topn on a mat */
-       mat_slc = 5,    /* Phase one of topn on a mat */
+       mat_slc = 5,    /* Last phase of topn (or just slice) on a mat */
        mat_rdr = 6     /* Phase one of sorting, ie sorted the parts sofar */
 } mat_type_t;
 
@@ -938,6 +938,84 @@ mat_group_derive(MalBlkPtr mb, InstrPtr 
        return mtop;
 }
 
+static void
+mat_topn_project(MalBlkPtr mb, InstrPtr p, mat_t *mat, int m, int n)
+{
+       int tpe = getArgType(mb, p, 0), k;
+       InstrPtr pck, q;
+
+       pck = newInstruction(mb, ASSIGNsymbol);
+       setModuleId(pck,matRef);
+       setFunctionId(pck,packRef);
+       getArg(pck,0) = newTmpVariable(mb, tpe);
+
+       for(k=1; k<mat[m].mi->argc; k++) { 
+               InstrPtr q = copyInstruction(p);
+
+               getArg(q,0) = newTmpVariable(mb, tpe);
+               getArg(q,1) = getArg(mat[m].mi, k);
+               getArg(q,2) = getArg(mat[n].mi, k);
+               pushInstruction(mb, q);
+
+               pck = pushArgument(mb, pck, getArg(q, 0));
+       }
+       pushInstruction(mb, pck);
+
+               q = copyInstruction(p);
+       getArg(q,2) = getArg(pck,0);
+       pushInstruction(mb, q);
+}
+
+/* for now just slices */
+static int
+mat_topn(MalBlkPtr mb, InstrPtr p, mat_t *mat, int mtop, int m)
+{
+       int tpe = getArgType(mb,p,0), k, is_slice = isSlice(p), zero = -1;
+       InstrPtr pck, r;
+
+       /* dummy mat instruction (needed to share result of p) */
+       pck = newInstruction(mb,ASSIGNsymbol);
+       setModuleId(pck, matRef);
+       setFunctionId(pck, packRef);
+       getArg(pck,0) = getArg(p,0);
+
+       if (is_slice) {
+               ValRecord cst;
+               cst.vtype= getArgType(mb,p,2);
+               cst.val.wval= 0;
+               zero = defConstant(mb, cst.vtype, &cst);
+       }
+       for(k=1; k< mat[m].mi->argc; k++) {
+               InstrPtr q = copyInstruction(p);
+               getArg(q,0) = newTmpVariable(mb, tpe);
+               getArg(q,1) = getArg(mat[m].mi,k);
+               if (is_slice) /* lower bound should always be 0 on partial 
slices */
+                       getArg(q,2) = zero;
+               pushInstruction(mb,q);
+               
+               pck = pushArgument(mb, pck, getArg(q,0));
+       }
+
+       /* real instruction */
+       r = newInstruction(mb,ASSIGNsymbol);
+       setModuleId(r, matRef);
+       setFunctionId(r, packRef);
+       getArg(r,0) = newTmpVariable(mb, tpe);
+
+       for(k=1; k< pck->argc; k++) 
+               r = pushArgument(mb, r, getArg(pck,k));
+       pushInstruction(mb,r);
+
+       mtop = mat_add(mat, mtop, pck, is_slice?mat_slc:mat_tpn, 
getFunctionId(p));
+       if (is_slice) { /* pack */
+               InstrPtr q = copyInstruction(p);
+               getArg(q,1) = getArg(r,0);
+
+               pushInstruction(mb,q);
+       }
+       return mtop;
+}
+
 int
 OPTmergetableImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr p) 
 {
@@ -1043,6 +1121,13 @@ OPTmergetableImplementation(Client cntxt
                        actions++;
                        continue;
                } 
+               if (match == 1 && bats == 1 && p->argc == 4 && isSlice(p) &&
+                  ((m=is_a_mat(getArg(p,p->retc), mat, mtop)) >= 0)) {
+                       // mat[m].type == mat_none) {
+                       mtop = mat_topn(mb, p, mat, mtop, m);
+                       actions++;
+                       continue;
+               }
 
                /* Now we handle subgroup and aggregation statements. */
                if (match == 1 && bats == 1 && p->argc == 4 && getModuleId(p) 
== groupRef && 
@@ -1085,6 +1170,17 @@ OPTmergetableImplementation(Client cntxt
                        continue;
                }
 
+               /* Handle cases of slice.leftfetchjoin */
+               if (match == 2 && getModuleId(p) == algebraRef &&
+                   getFunctionId(p) == leftfetchjoinRef &&
+                  (m=is_a_mat(getArg(p,1), mat, mtop)) >= 0 &&
+                  (n=is_a_mat(getArg(p,2), mat, mtop)) >= 0 &&
+                  (mat[m].type == mat_slc)) {
+                       mat_topn_project(mb, p, mat, m, n);
+                       actions++;
+                       continue;
+               }
+
                /* Handle leftfetchjoin */
                if (match > 0 && getModuleId(p) == algebraRef &&
                    getFunctionId(p) == leftfetchjoinRef && 
diff --git a/monetdb5/optimizer/opt_prelude.c b/monetdb5/optimizer/opt_prelude.c
--- a/monetdb5/optimizer/opt_prelude.c
+++ b/monetdb5/optimizer/opt_prelude.c
@@ -205,6 +205,7 @@ str semijoinPathRef;
 str setAccessRef;
 str setWriteModeRef;
 str sliceRef;
+str subsliceRef;
 str sortHRef;
 str sortHTRef;
 str sortRef;
@@ -454,6 +455,7 @@ void optimizerInit(void){
                setAccessRef = putName("setAccess",9);
                setWriteModeRef= putName("setWriteMode",12);
                sliceRef = putName("slice",5);
+               subsliceRef = putName("subslice",8);
                singleRef = putName("single",6);
                sortHRef = putName("sortH",5);
                sortHTRef = putName("sortHT",6);
diff --git a/monetdb5/optimizer/opt_prelude.h b/monetdb5/optimizer/opt_prelude.h
--- a/monetdb5/optimizer/opt_prelude.h
+++ b/monetdb5/optimizer/opt_prelude.h
@@ -203,6 +203,7 @@ opt_export  str semijoinPathRef;
 opt_export  str setAccessRef;
 opt_export  str setWriteModeRef;
 opt_export  str sliceRef;
+opt_export  str subsliceRef;
 opt_export  str singleRef;
 opt_export  str sortHRef;
 opt_export  str sortHTRef;
diff --git a/monetdb5/optimizer/opt_support.c b/monetdb5/optimizer/opt_support.c
--- a/monetdb5/optimizer/opt_support.c
+++ b/monetdb5/optimizer/opt_support.c
@@ -838,7 +838,7 @@ int isTopn(InstrPtr p){
 
 int isSlice(InstrPtr p){
        return (getModuleId(p) == algebraRef &&
-               getFunctionId(p) == sliceRef);
+               getFunctionId(p) == subsliceRef);
 }
 
 int isOrderby(InstrPtr p){
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
@@ -936,10 +936,13 @@ _dumpstmt(backend *sql, MalBlkPtr mb, st
                                q = pushArgument(mb, q, topn);
                                l = getDestVar(q);
 
+                               /* pqueue doesn't handle offsets, ie use slice 
for this */
+
                                /* since both arguments of algebra.slice are
                                   inclusive correct the LIMIT value by
                                   substracting 1 */
                                if (s->op2->op4.aval->data.val.wval) {
+                                       assert(0);
                                        q = newStmt1(mb, calcRef, "-");
                                        q = pushArgument(mb, q, topn);
                                        q = pushInt(mb, q, 1);
@@ -957,7 +960,7 @@ _dumpstmt(backend *sql, MalBlkPtr mb, st
                                q = pushArgument(mb, q, len);
                                len = getDestVar(q);
 
-                               /* since both arguments of algebra.slice are
+                               /* since both arguments of algebra.subslice are
                                   inclusive correct the LIMIT value by
                                   substracting 1 */
                                q = newStmt1(mb, calcRef, "-");
@@ -965,7 +968,7 @@ _dumpstmt(backend *sql, MalBlkPtr mb, st
                                q = pushInt(mb, q, 1);
                                len = getDestVar(q);
 
-                               q = newStmt1(mb, algebraRef, "slice");
+                               q = newStmt1(mb, algebraRef, "subslice");
                                q = pushArgument(mb, q, l);
                                q = pushArgument(mb, q, offset);
                                q = pushArgument(mb, q, len);
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -225,14 +225,6 @@ typedef enum operator_type {
 #define set_nodistinct(e) \
        e->flag &= (~EXP_DISTINCT)
 
-/* limit including or excluding bounds (relations only) */
-#define need_including(r) \
-       ((r->flag&TOPN_INCLUDING)==TOPN_INCLUDING)
-#define set_including(r) \
-       r->flag |= TOPN_INCLUDING
-#define set_excluding(r) \
-       r->flag &= (~TOPN_INCLUDING)
-
 /* used for expressions and relations */
 #define is_intern(e) \
        (e->type != e_atom && (e->flag&EXP_INTERN)==EXP_INTERN)
diff --git a/sql/server/rel_bin.c b/sql/server/rel_bin.c
--- a/sql/server/rel_bin.c
+++ b/sql/server/rel_bin.c
@@ -2212,18 +2212,18 @@ rel2bin_project( mvc *sql, sql_rel *rel,
        stmt_set_nrcols(psub);
 
        /* In case of a topn 
-               if both order by and distinct: then get first order by col early
-                       do topn on it. Project all again! Then rest
+               if both order by and distinct: then get first order by col 
+               do topn on it. Project all again! Then rest
          */
        if (topn && rel->r) {
                list *oexps = rel->r, *npl = sa_list(sql->sa);
-               /* including bounds, topn returns atleast N */
-               int including = need_including(topn) || need_distinct(rel);
+               /* distinct, topn returns atleast N (unique) */
+               int distinct = need_distinct(rel);
                stmt *limit = NULL; 
 
                for (n=oexps->h; n; n = n->next) {
                        sql_exp *orderbycole = n->data; 
-                       int inc = including || n->next;
+                       int inc = distinct || n->next;
 
                        stmt *orderbycolstmt = exp_bin(sql, orderbycole, sub, 
psub, NULL, NULL, NULL, NULL); 
 
@@ -2240,7 +2240,10 @@ rel2bin_project( mvc *sql, sql_rel *rel,
                                return NULL;
_______________________________________________
checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to