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