Changeset: 1c4f3c17b13d for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1c4f3c17b13d
Modified Files:
        MonetDB5/src/optimizer/opt_mergetable.mx
        MonetDB5/src/optimizer/opt_prelude.mx
Branch: Jun2010
Log Message:

make sure we detect topn on ordered results
For now only very simple single columns are handled by mergetable.


diffs (226 lines):

diff -r 81158356a33d -r 1c4f3c17b13d MonetDB5/src/optimizer/opt_mergetable.mx
--- a/MonetDB5/src/optimizer/opt_mergetable.mx  Wed Sep 01 09:54:39 2010 +0200
+++ b/MonetDB5/src/optimizer/opt_mergetable.mx  Wed Sep 01 09:55:48 2010 +0200
@@ -148,12 +148,11 @@
 #include "bpm.h"
 
 typedef enum mat_type {
-       mat_none = 0,
-       mat_grp = 1,
-       mat_ext = 2,
-       mat_sum = 3,
-       mat_max = 4,
-       mat_min = 5
+       mat_none = 0,   /* Simple mat aligned operations (ie batcalc etc) */
+       mat_grp = 1,    /* result of phase one of a mat - group.new/derive */
+       mat_ext = 2,    /* after mat_grp the extend gets a mat.mirror */
+       mat_tpn = 3,    /* Phase one of topn on a mat */
+       mat_srt = 4     /* Phase one of sorting, ie sorted the parts sofar */
 } mat_type;
 
 typedef struct mat {
@@ -165,6 +164,15 @@
        mat_type type;  /* type of operation */
 } mat_t;
 
+static mat_type
+useMatType( mat_t *mat, int n) 
+{
+       mat_type type = mat_none;
+       if (n >= 0)
+               type = mat[n].type;
+       return type;
+}
+
 int overlap( MalBlkPtr mb, int lv, int rv)
 {
        VarPtr llb = varGetProp(mb, lv, tlbProp); 
@@ -388,7 +396,7 @@
        stream_printf(GDKout,"MAT optimizer, mat_packAll\n");
        printInstruction(GDKout, mb, 0, mat[m].mi, LIST_MAL_ALL);
 #endif
-       if (mat[m].type == mat_none) {
+       if (mat[m].type == mat_none || mat[m].type == mat_tpn) {
                r = mat_pack_mat(mb, mi, mat, m, mtop);
                pushInstruction(mb,r);
        } else if (mat[m].type == mat_ext) {
@@ -412,7 +420,7 @@
        stream_printf(GDKout,"MAT optimizer, mat_packAll2\n");
        printInstruction(GDKout, mb, 0, mat[m].mi, LIST_MAL_ALL);
 #endif
-       if (mat[m].type == mat_none) {
+       if (mat[m].type == mat_none || mat[m].type == mat_tpn) {
                r = mat_pack_mat(mb, mi, mat, m, mtop);
                pushInstruction(mb,r);
                MATshift(mat,m,mtop);
@@ -1246,6 +1254,72 @@
        return mtop;
 }
 
+/* could use mat_unop ?? */
+static int
+mat_topn(MalBlkPtr mb, InstrPtr p, mat_t *mat, int mtop, int m)
+{
+       int tpe = getArgType(mb,p,0), k;
+       InstrPtr pck = NULL, q = NULL;
+
+#ifdef DEBUG_OPT_MERGETABLE
+       stream_printf(GDKout,"MAT optimizer, mat_topn\n");
+       printInstruction(GDKout, mb, 0, p, LIST_MAL_ALL);
+#endif
+       /* second topn, ie lets pack */
+       if (mat[m].type == mat_tpn) {
+               MATpackAll2(mb, NULL, mat, m, &mtop);
+               q = copyInstruction(p);
+               pushInstruction(mb, q);
+               return mtop;
+       }
+
+       /* we pack the partitial result */
+       pck = newInstruction(mb,ASSIGNsymbol);
+       setModuleId(pck, matRef);
+       setFunctionId(pck, packRef);
+       getArg(pck,0) = getArg(p,0);
+       for(k=1; k< mat[m].mi->argc; k++) {
+               q = copyInstruction(p);
+               getArg(q,0) = newTmpVariable(mb, tpe);
+               getArg(q,1) = getArg(mat[m].mi,k);
+               pushInstruction(mb,q);
+               
+               /* pack result */
+               pck = pushArgument(mb,pck,getArg(q,0));
+       }
+       return mat_add(mat, mtop, pck, NULL, mat_tpn);
+}
+
+#if 0
+static int
+mat_sort(MalBlkPtr mb, InstrPtr p, mat_t *mat, int mtop, int m)
+{
+       int tpe = getArgType(mb,p,0), k;
+       InstrPtr pck = NULL, q = NULL;
+
+#ifdef DEBUG_OPT_MERGETABLE
+       stream_printf(GDKout,"MAT optimizer, mat_sort\n");
+       printInstruction(GDKout, mb, 0, p, LIST_MAL_ALL);
+#endif
+
+       /* we pack the partitial result */
+       pck = newInstruction(mb,ASSIGNsymbol);
+       setModuleId(pck, matRef);
+       setFunctionId(pck, packRef);
+       getArg(pck,0) = getArg(p,0);
+       for(k=1; k< mat[m].mi->argc; k++) {
+               q = copyInstruction(p);
+               getArg(q,0) = newTmpVariable(mb, tpe);
+               getArg(q,1) = getArg(mat[m].mi,k);
+               pushInstruction(mb,q);
+               
+               /* pack result */
+               pck = pushArgument(mb,pck,getArg(q,0));
+       }
+       return mat_add(mat, mtop, pck, NULL, mat_srt);
+}
+#endif
+
 static int
 mat_union(MalBlkPtr mb, InstrPtr p, mat_t *mat, int mtop, int m, int n)
 {
@@ -1515,8 +1589,9 @@
                n = isMATalias(getArg(q,2), mat, mtop);
                *Mtop = mat_union(mb, q, mat, mtop, m, n);
                return 1;
-       } else if ((bc = mat_apply(mb, p, mat, Mtop, m, n, 0)) != NULL) 
-               *Mtop = mat_add(mat, *Mtop, bc, NULL, mat_none );
+       } else if ((bc = mat_apply(mb, p, mat, Mtop, m, n, 0)) != NULL) {
+               *Mtop = mat_add(mat, *Mtop, bc, NULL, useMatType(mat, n) );
+       }
        return 0;
 }
 
@@ -1610,6 +1685,12 @@
                   is different, ie result-head equals head-1st arg,    
                                    result-tail equals head-2nd/3rd arg */
                  
+               /* TODO:
+                  If a value join with mats on both sides fails (ie unknown
+                  how to handle) we should bail out, ie stop any further
+                  processing of any mats. This is needed because the needed 
+                  mas-crossproduct handling of projections fails. 
+                 */
                if (match > 0 && match <= 2 && isMatJoinOp(p) && 
                   (p->argc == 3 || (p->argc == 4 && getFunctionId(p) == 
thetajoinRef))) {
                        m = isMATalias(getArg(p,1), mat, mtop);
@@ -1730,6 +1811,31 @@
                        actions++;
                        continue;
                } 
+               if (match > 0 &&
+                  (m=isMATalias(getArg(p,1), mat, mtop)) >= 0 &&
+                  p->argc == 3 &&
+                  (getModuleId(p) == pqueueRef && 
+                       (getFunctionId(p) == topn_minRef ||
+                        getFunctionId(p) == topn_maxRef ||
+                        getFunctionId(p) == utopn_minRef ||
+                        getFunctionId(p) == utopn_maxRef))) { 
+                       mtop = mat_topn(mb, p, mat, mtop, m);
+                       actions++;
+                       continue;
+               }
+/*
+               if (match > 0 &&
+                  (m=isMATalias(getArg(p,1), mat, mtop)) >= 0 &&
+                  mat[m].type == type_topn &&
+                  p->argc == 2 &&
+                  (getModuleId(p) == algebraRef && 
+                       (getFunctionId(p) == sortTailRef ||
+                        getFunctionId(p) == sortReverseTailRef))) { 
+                       mtop = mat_sort(mb, p, mat, mtop, m);
+                       actions++;
+                       continue;
+               }
+*/
                if (match > 0 && (
                    getModuleId(p) == groupRef || 
                    getModuleId(p) == aggrRef || 
@@ -1738,7 +1844,9 @@
                         getFunctionId(p) == sortReverseTailRef)) ||
                   (getModuleId(p) == pqueueRef && 
                        (getFunctionId(p) == topn_minRef ||
-                        getFunctionId(p) == topn_maxRef)))) { 
+                        getFunctionId(p) == topn_maxRef ||
+                        getFunctionId(p) == utopn_minRef ||
+                        getFunctionId(p) == utopn_maxRef)))) { 
                        error++;
                        goto fail;
                        /* For order (and order related topn) 
diff -r 81158356a33d -r 1c4f3c17b13d MonetDB5/src/optimizer/opt_prelude.mx
--- a/MonetDB5/src/optimizer/opt_prelude.mx     Wed Sep 01 09:54:39 2010 +0200
+++ b/MonetDB5/src/optimizer/opt_prelude.mx     Wed Sep 01 09:55:48 2010 +0200
@@ -183,6 +183,8 @@
 opt_export  str takeRef;
 opt_export  str topn_minRef;
 opt_export  str topn_maxRef;
+opt_export  str utopn_minRef;
+opt_export  str utopn_maxRef;
 opt_export  str tuniqueRef;
 opt_export  str not_uniqueRef;
 opt_export  str unionRef;
@@ -383,6 +385,8 @@
 str takeRef;
 str topn_minRef;
 str topn_maxRef;
+str utopn_minRef;
+str utopn_maxRef;
 str tuniqueRef;
 str not_uniqueRef;
 str unionRef;
@@ -579,6 +583,8 @@
                takeRef= putName("take",5);
                topn_minRef= putName("topn_min",8);
                topn_maxRef= putName("topn_max",8);
+               utopn_minRef= putName("utopn_min",9);
+               utopn_maxRef= putName("utopn_max",9);
                tuniqueRef = putName("tunique",7);
                not_uniqueRef= putName("not_unique",10);
                unionRef= putName("union",5);
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to