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