Changeset: d1e786a2c7a7 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d1e786a2c7a7
Added Files:
        monetdb5/optimizer/opt_postfix.c
        monetdb5/optimizer/opt_postfix.h
Modified Files:
        clients/Tests/MAL-signatures.stable.out
        clients/Tests/MAL-signatures.stable.out.int128
        clients/Tests/exports.stable.out
        monetdb5/extras/mal_optimizer_template/Tests/opt_sql_append.stable.out
        monetdb5/modules/kernel/algebra.c
        monetdb5/modules/kernel/algebra.h
        monetdb5/modules/kernel/algebra.mal
        monetdb5/optimizer/opt_pipes.c
        monetdb5/optimizer/opt_wrapper.c
        sql/test/Tests/setoptimizer.stable.out
Branch: default
Log Message:

Push the projection step into the count function
A simple postfix optimizer to avoid generating the projection list
to calculate the count.


diffs (truncated from 363 to 300 lines):

diff --git a/clients/Tests/MAL-signatures.stable.out 
b/clients/Tests/MAL-signatures.stable.out
--- a/clients/Tests/MAL-signatures.stable.out
+++ b/clients/Tests/MAL-signatures.stable.out
@@ -83,9 +83,12 @@ Ready.
 [ "aggr",      "corr", "function aggr.corr(e1:bat[:sht], e2:bat[:sht]):dbl;",  
"",     ""      ]
 [ "aggr",      "count",        "command aggr.count(b:bat[:any_1], g:bat[:oid], 
e:bat[:any_2], ignorenils:bit):bat[:lng] ",     "AGGRcount3;",  ""      ]
 [ "aggr",      "count",        "command aggr.count(b:bat[:any_1], g:bat[:oid], 
e:bat[:any_2]):bat[:lng] ",     "AGGRcount3nils;",      "Grouped count" ]
+[ "aggr",      "count",        "command aggr.count(b:bat[:any], 
cnd:bat[:oid]):lng ",  "ALGcountCND_bat;",     "Return the current size (in 
number of elements) in a BAT."     ]
+[ "aggr",      "count",        "command aggr.count(b:bat[:any], cnd:bat[:oid], 
ignore_nils:bit):lng ", "ALGcountCND_nil;",     "Return the number of elements 
currently in a BAT ignores\n\t\tBUNs with nil-tail iff ignore_nils==TRUE."      
 ]
 [ "aggr",      "count",        "command aggr.count(b:bat[:any]):lng ", 
"ALGcount_bat;",        "Return the current size (in number of elements) in a 
BAT."     ]
 [ "aggr",      "count",        "command aggr.count(b:bat[:any], 
ignore_nils:bit):lng ",        "ALGcount_nil;",        "Return the number of 
elements currently in a BAT ignores\n\t\tBUNs with nil-tail iff 
ignore_nils==TRUE."       ]
 [ "aggr",      "count_no_nil", "command aggr.count_no_nil(b:bat[:any_1], 
g:bat[:oid], e:bat[:any_2]):bat[:lng] ",      "AGGRcount3nonils;",    ""      ]
+[ "aggr",      "count_no_nil", "command aggr.count_no_nil(b:bat[:any_2], 
cnd:bat[:oid]):lng ", "ALGcountCND_no_nil;",  "Return the number of elements 
currently\n\tin a BAT ignoring BUNs with nil-tail"       ]
 [ "aggr",      "count_no_nil", "command aggr.count_no_nil(b:bat[:any_2]):lng 
",        "ALGcount_no_nil;",     "Return the number of elements 
currently\n\tin a BAT ignoring BUNs with nil-tail"       ]
 [ "aggr",      "covar",        "function aggr.covar(e1:bat[:bte], 
e2:bat[:bte]):dbl;", "",     ""      ]
 [ "aggr",      "covar",        "function aggr.covar(e1:bat[:dbl], 
e2:bat[:dbl]):dbl;", "",     ""      ]
diff --git a/clients/Tests/MAL-signatures.stable.out.int128 
b/clients/Tests/MAL-signatures.stable.out.int128
--- a/clients/Tests/MAL-signatures.stable.out.int128
+++ b/clients/Tests/MAL-signatures.stable.out.int128
@@ -90,9 +90,12 @@ Ready.
 [ "aggr",      "corr", "function aggr.corr(e1:bat[:sht], e2:bat[:sht]):dbl;",  
"",     ""      ]
 [ "aggr",      "count",        "command aggr.count(b:bat[:any_1], g:bat[:oid], 
e:bat[:any_2], ignorenils:bit):bat[:lng] ",     "AGGRcount3;",  ""      ]
 [ "aggr",      "count",        "command aggr.count(b:bat[:any_1], g:bat[:oid], 
e:bat[:any_2]):bat[:lng] ",     "AGGRcount3nils;",      "Grouped count" ]
+[ "aggr",      "count",        "command aggr.count(b:bat[:any], 
cnd:bat[:oid]):lng ",  "ALGcountCND_bat;",     "Return the current size (in 
number of elements) in a BAT."     ]
+[ "aggr",      "count",        "command aggr.count(b:bat[:any], cnd:bat[:oid], 
ignore_nils:bit):lng ", "ALGcountCND_nil;",     "Return the number of elements 
currently in a BAT ignores\n\t\tBUNs with nil-tail iff ignore_nils==TRUE."      
 ]
 [ "aggr",      "count",        "command aggr.count(b:bat[:any]):lng ", 
"ALGcount_bat;",        "Return the current size (in number of elements) in a 
BAT."     ]
 [ "aggr",      "count",        "command aggr.count(b:bat[:any], 
ignore_nils:bit):lng ",        "ALGcount_nil;",        "Return the number of 
elements currently in a BAT ignores\n\t\tBUNs with nil-tail iff 
ignore_nils==TRUE."       ]
 [ "aggr",      "count_no_nil", "command aggr.count_no_nil(b:bat[:any_1], 
g:bat[:oid], e:bat[:any_2]):bat[:lng] ",      "AGGRcount3nonils;",    ""      ]
+[ "aggr",      "count_no_nil", "command aggr.count_no_nil(b:bat[:any_2], 
cnd:bat[:oid]):lng ", "ALGcountCND_no_nil;",  "Return the number of elements 
currently\n\tin a BAT ignoring BUNs with nil-tail"       ]
 [ "aggr",      "count_no_nil", "command aggr.count_no_nil(b:bat[:any_2]):lng 
",        "ALGcount_no_nil;",     "Return the number of elements 
currently\n\tin a BAT ignoring BUNs with nil-tail"       ]
 [ "aggr",      "covar",        "function aggr.covar(e1:bat[:bte], 
e2:bat[:bte]):dbl;", "",     ""      ]
 [ "aggr",      "covar",        "function aggr.covar(e1:bat[:dbl], 
e2:bat[:dbl]):dbl;", "",     ""      ]
diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -683,6 +683,9 @@ str ALARMusec(lng *ret);
 str ALGbandjoin(bat *r1, bat *r2, const bat *lid, const bat *rid, const bat 
*slid, const bat *srid, const void *low, const void *high, const bit *li, const 
bit *hi, const lng *estimate);
 str ALGcard(lng *result, const bat *bid);
 str ALGcopy(bat *result, const bat *bid);
+str ALGcountCND_bat(lng *result, const bat *bid, const bat *cnd);
+str ALGcountCND_nil(lng *result, const bat *bid, const bat *cnd, const bit 
*ignore_nils);
+str ALGcountCND_no_nil(lng *result, const bat *bid, const bat *cnd);
 str ALGcount_bat(lng *result, const bat *bid);
 str ALGcount_nil(lng *result, const bat *bid, const bit *ignore_nils);
 str ALGcount_no_nil(lng *result, const bat *bid);
diff --git 
a/monetdb5/extras/mal_optimizer_template/Tests/opt_sql_append.stable.out 
b/monetdb5/extras/mal_optimizer_template/Tests/opt_sql_append.stable.out
--- a/monetdb5/extras/mal_optimizer_template/Tests/opt_sql_append.stable.out
+++ b/monetdb5/extras/mal_optimizer_template/Tests/opt_sql_append.stable.out
@@ -55,8 +55,8 @@ Ready.
 % .L1 # table_name
 % def # name
 % clob # type
-% 539 # length
-[ 
"optimizer.inline();optimizer.remap();optimizer.costModel();optimizer.coercions();optimizer.evaluate();optimizer.emptybind();optimizer.pushselect();optimizer.aliases();optimizer.mergetable();optimizer.deadcode();optimizer.aliases();optimizer.constants();optimizer.commonTerms();optimizer.projectionpath();optimizer.reorder();optimizer.deadcode();optimizer.matpack();optimizer.querylog();optimizer.multiplex();optimizer.generator();optimizer.profiler();optimizer.candidates();optimizer.postfix();optimizer.wlc();optimizer.garbageCollector();"
        ]
+% 560 # length
+[ 
"optimizer.inline();optimizer.remap();optimizer.costModel();optimizer.coercions();optimizer.evaluate();optimizer.emptybind();optimizer.pushselect();optimizer.aliases();optimizer.mergetable();optimizer.deadcode();optimizer.aliases();optimizer.constants();optimizer.commonTerms();optimizer.projectionpath();optimizer.reorder();optimizer.deadcode();optimizer.matpack();optimizer.querylog();optimizer.multiplex();optimizer.generator();optimizer.profiler();optimizer.candidates();optimizer.postfix();optimizer.deadcode();optimizer.wlc();optimizer.garbageCollector();"
   ]
 #explain copy into ttt from '/tmp/xyz';
 % .explain # table_name
 % mal # name
@@ -114,8 +114,8 @@ end user.s10_1;
 % .L1 # table_name
 % def # name
 % clob # type
-% 562 # length
-[ 
"optimizer.inline();optimizer.remap();optimizer.costModel();optimizer.coercions();optimizer.evaluate();optimizer.emptybind();optimizer.pushselect();optimizer.aliases();optimizer.mergetable();optimizer.deadcode();optimizer.aliases();optimizer.constants();optimizer.commonTerms();optimizer.projectionpath();optimizer.reorder();optimizer.deadcode();optimizer.matpack();optimizer.querylog();optimizer.multiplex();optimizer.generator();optimizer.profiler();optimizer.candidates();optimizer.postfix();optimizer.wlc();optimizer.sql_append();optimizer.garbageCollector();"
 ]
+% 583 # length
+[ 
"optimizer.inline();optimizer.remap();optimizer.costModel();optimizer.coercions();optimizer.evaluate();optimizer.emptybind();optimizer.pushselect();optimizer.aliases();optimizer.mergetable();optimizer.deadcode();optimizer.aliases();optimizer.constants();optimizer.commonTerms();optimizer.projectionpath();optimizer.reorder();optimizer.deadcode();optimizer.matpack();optimizer.querylog();optimizer.multiplex();optimizer.generator();optimizer.profiler();optimizer.candidates();optimizer.postfix();optimizer.deadcode();optimizer.wlc();optimizer.sql_append();optimizer.garbageCollector();"
    ]
 #explain copy into ttt from '/tmp/xyz';
 % .explain # table_name
 % mal # name
diff --git a/monetdb5/modules/kernel/algebra.c 
b/monetdb5/modules/kernel/algebra.c
--- a/monetdb5/modules/kernel/algebra.c
+++ b/monetdb5/modules/kernel/algebra.c
@@ -816,6 +816,65 @@ ALGcount_no_nil(lng *result, const bat *
 }
 
 str
+ALGcountCND_bat(lng *result, const bat *bid, const bat *cnd)
+{
+       BAT *b;
+
+       if ( *cnd) {
+               if ((b = BATdescriptor(*cnd)) == NULL) {
+                       throw(MAL, "aggr.count", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
+               }               
+               *result = (lng) BATcount(b);
+               BBPunfix(b->batCacheid);
+               return MAL_SUCCEED;
+       }
+       if ((b = BATdescriptor(*bid)) == NULL) {
+               throw(MAL, "aggr.count", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
+       }
+       *result = (lng) BATcount(b);
+       BBPunfix(b->batCacheid);
+       return MAL_SUCCEED;
+}
+
+str
+ALGcountCND_nil(lng *result, const bat *bid, const bat *cnd, const bit 
*ignore_nils)
+{
+       BAT *b;
+       BUN cnt;
+
+       if (*ignore_nils){
+               if ((b = BATdescriptor(*bid)) == NULL) {
+                       throw(MAL, "aggr.count", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
+               }
+               cnt = BATcount_no_nil(b);
+       } else{
+               if ( *cnd) {
+                       if ((b = BATdescriptor(*cnd)) == NULL) {
+                               throw(MAL, "aggr.count", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
+                       }               
+                       *result = (lng) BATcount(b);
+                       BBPunfix(b->batCacheid);
+                       return MAL_SUCCEED;
+               }
+               if ((b = BATdescriptor(*bid)) == NULL) {
+                       throw(MAL, "aggr.count", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
+               }
+               cnt = BATcount(b);
+       }
+       *result = (lng) cnt;
+       BBPunfix(b->batCacheid);
+       return MAL_SUCCEED;
+}
+
+str
+ALGcountCND_no_nil(lng *result, const bat *bid, const bat *cnd)
+{
+       bit ignore_nils = 1;
+
+       return ALGcountCND_nil(result, bid, cnd, &ignore_nils);
+}
+
+str
 ALGslice(bat *ret, const bat *bid, const lng *start, const lng *end)
 {
        BAT *b, *bn = NULL;
diff --git a/monetdb5/modules/kernel/algebra.h 
b/monetdb5/modules/kernel/algebra.h
--- a/monetdb5/modules/kernel/algebra.h
+++ b/monetdb5/modules/kernel/algebra.h
@@ -60,6 +60,9 @@ mal_export str ALGsort33(bat *result, ba
 mal_export str ALGcount_bat(lng *result, const bat *bid);
 mal_export str ALGcount_nil(lng *result, const bat *bid, const bit 
*ignore_nils);
 mal_export str ALGcount_no_nil(lng *result, const bat *bid);
+mal_export str ALGcountCND_bat(lng *result, const bat *bid, const bat *cnd);
+mal_export str ALGcountCND_nil(lng *result, const bat *bid, const bat *cnd, 
const bit *ignore_nils);
+mal_export str ALGcountCND_no_nil(lng *result, const bat *bid, const bat *cnd);
 mal_export str ALGslice(bat *ret, const bat *bid, const lng *start, const lng 
*end);
 mal_export str ALGslice_int(bat *ret, const bat *bid, const int *start, const 
int *end);
 mal_export str ALGslice_lng(bat *ret, const bat *bid, const lng *start, const 
lng *end);
diff --git a/monetdb5/modules/kernel/algebra.mal 
b/monetdb5/modules/kernel/algebra.mal
--- a/monetdb5/modules/kernel/algebra.mal
+++ b/monetdb5/modules/kernel/algebra.mal
@@ -286,6 +286,19 @@ address ALGcount_no_nil
 comment "Return the number of elements currently
        in a BAT ignoring BUNs with nil-tail";
 
+# the variants with a candidate list
+command count( b:bat[:any], cnd:bat[:oid] ) :lng
+address ALGcountCND_bat
+comment "Return the current size (in number of elements) in a BAT.";
+command count ( b:bat[:any], cnd:bat[:oid], ignore_nils:bit ) :lng
+address ALGcountCND_nil
+comment "Return the number of elements currently in a BAT ignores
+               BUNs with nil-tail iff ignore_nils==TRUE.";
+command count_no_nil ( b:bat[:any_2], cnd:bat[:oid]) :lng
+address ALGcountCND_no_nil
+comment "Return the number of elements currently
+       in a BAT ignoring BUNs with nil-tail";
+
 #  Default Min and Max
 # Implementations a generic Min and Max routines get declared first. The
 # @emph{min()} and @emph{max()} routines below catch any tail-type.
diff --git a/monetdb5/optimizer/opt_pipes.c b/monetdb5/optimizer/opt_pipes.c
--- a/monetdb5/optimizer/opt_pipes.c
+++ b/monetdb5/optimizer/opt_pipes.c
@@ -90,6 +90,7 @@ static struct PIPELINES {
         "optimizer.profiler();"
         "optimizer.candidates();"
         "optimizer.postfix();"
+        "optimizer.deadcode();"
 //      "optimizer.jit();" awaiting the new batcalc api
 //      "optimizer.oltp();"awaiting the autocommit front-end changes
         "optimizer.wlc();"
@@ -126,6 +127,7 @@ static struct PIPELINES {
         "optimizer.profiler();"
         "optimizer.candidates();"
         "optimizer.postfix();"
+        "optimizer.deadcode();"
 //      "optimizer.jit();" awaiting the new batcalc api
 //      "optimizer.oltp();"awaiting the autocommit front-end changes
         "optimizer.wlc();"
@@ -167,6 +169,7 @@ static struct PIPELINES {
         "optimizer.profiler();"
         "optimizer.candidates();"
         "optimizer.postfix();"
+        "optimizer.deadcode();"
 //      "optimizer.jit();" awaiting the new batcalc api
 //      "optimizer.oltp();"awaiting the autocommit front-end changes
         "optimizer.wlc();"
@@ -207,6 +210,7 @@ static struct PIPELINES {
         "optimizer.profiler();"
         "optimizer.candidates();"
         "optimizer.postfix();"
+        "optimizer.deadcode();"
 //      "optimizer.jit();" awaiting the new batcalc api
 //      "optimizer.oltp();"awaiting the autocommit front-end changes
         "optimizer.wlc();"
diff --git a/monetdb5/optimizer/opt_postfix.c b/monetdb5/optimizer/opt_postfix.c
new file mode 100644
--- /dev/null
+++ b/monetdb5/optimizer/opt_postfix.c
@@ -0,0 +1,92 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2017 MonetDB B.V.
+ */
+
+/* The SQL code generator can not always look ahead to avoid
+ * generation of intermediates.
+ * Some of these patterns are captured in a postfix optimalisation.
+ */
+#include "monetdb_config.h"
+#include "mal_instruction.h"
+#include "opt_postfix.h"
+
+#define isCandidateList(M,P,I) ((M)->var[getArg(P,I)].id[0]== 'C')
+str
+OPTpostfixImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p)
+{
+       int i, j, slimit, limit, actions=0;
+       InstrPtr *old = 0;
+    InstrPtr q, *vars = 0;
+       lng usec = GDKusec();
+       char buf[256];
+       str msg = MAL_SUCCEED;
+
+       (void) stk;
+       (void) cntxt;
+
+       limit = mb->stop;
+       slimit = mb->ssize;
+       /* the first postfix concerns pushing projections into the count()  we 
check if it is needed*/
+       for ( i = 0; i < limit; i++){
+               p= getInstrPtr(mb,i);
+               if( getFunctionId(p) == countRef  && getModuleId(p)== aggrRef 
&& p->argc == 2){
+                       actions ++;
+               }
+       }
+       if( actions == 0)
+               goto finished;
+
+    vars= (InstrPtr*) GDKzalloc(sizeof(InstrPtr)* mb->vtop);
+    if (vars == NULL)
+        throw(MAL,"optimizer.batcalc", SQLSTATE(HY001) MAL_MALLOC_FAIL);
+
+       old = mb->stmt;
+    if (newMalBlkStmt(mb, mb->ssize) < 0) {
+        msg= createException(MAL,"optimizer.postfix", SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
+        goto wrapup;
+    }
+       /* collect where variables are assigned last */
+       for ( i = 0; i < limit; i++){
+               p= old[i];
+               for( j = 0; j< p->retc; j++)
+                       vars[getArg(p,j)]= p;
+       }
+       /* construct the new plan */
+       for ( i = 0; i < limit; i++)
+       {
+               p= old[i];
+               if( getFunctionId(p) == countRef  && getModuleId(p)== aggrRef 
&& p->argc == 2 ){
+                       q= vars[getArg(p,1)];
+                       if( getArg(q,0) == getArg(p,1) && getFunctionId(q) == 
projectionRef && getModuleId(q) == algebraRef && q->argc == 3 && 
isCandidateList(mb, q, 1)){
+                               getArg(p,1) = getArg(q,2);
+                               p = pushArgument(mb, p, getArg(q,1));
+                       }
+               }
+               pushInstruction(mb,p);
+       }
+       for( ;i < slimit; i++)
+               if( old[i])
+                       freeInstruction(old[i]);
+
+       /* Defense line against incorrect plans */
+       if( actions ){
+               chkTypes(cntxt->usermodule, mb, FALSE);
+               chkFlow(mb);
+               chkDeclarations(mb);
+       }
+    /* keep all actions taken as a post block comment and update statics */
+    GDKfree(old);
+finished:
+       usec= GDKusec() - usec;
+    snprintf(buf,256,"%-20s actions=%2d time=" LLFMT " usec", "postfix", 
actions, usec);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to