1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
7 */
8
9/* author M.L. Kersten
10 * The optimizer wrapper code is the interface to the MAL optimizer calls.
11 *
12 * Before an optimizer is finished, it should leave a clean state behind.
13 * Moreover, some information of the optimization step is saved for
14 * debugging and analysis.
15*/
16
17#include "monetdb_config.h"
18#include "mal_listing.h"
19
20/*
21 * The optimizer used so far
22*/
23#include "opt_aliases.h"
24#include "opt_coercion.h"
25#include "opt_commonTerms.h"
26#include "opt_candidates.h"
27#include "opt_constants.h"
28#include "opt_costModel.h"
29#include "opt_dataflow.h"
30#include "opt_deadcode.h"
31#include "opt_emptybind.h"
32#include "opt_evaluate.h"
33#include "opt_garbageCollector.h"
34#include "opt_generator.h"
35#include "opt_inline.h"
36#include "opt_jit.h"
37#include "opt_projectionpath.h"
38#include "opt_matpack.h"
39#include "opt_json.h"
40#include "opt_oltp.h"
41#include "opt_postfix.h"
42#include "opt_mergetable.h"
43#include "opt_mitosis.h"
44#include "opt_multiplex.h"
45#include "opt_profiler.h"
46#include "opt_pushselect.h"
47#include "opt_querylog.h"
48#include "opt_reduce.h"
49#include "opt_remap.h"
50#include "opt_remoteQueries.h"
51#include "opt_reorder.h"
52#include "opt_volcano.h"
53#include "opt_wlc.h"
54
55struct{
56 str nme;
57 str (*fcn)();
58 int calls;
59 lng timing;
60} codes[] = {
61 {"aliases", &OPTaliasesImplementation,0,0},
62 {"candidates", &OPTcandidatesImplementation,0,0},
63 {"coercions", &OPTcoercionImplementation,0,0},
64 {"commonTerms", &OPTcommonTermsImplementation,0,0},
65 {"constants", &OPTconstantsImplementation,0,0},
66 {"costModel", &OPTcostModelImplementation,0,0},
67 {"dataflow", &OPTdataflowImplementation,0,0},
68 {"deadcode", &OPTdeadcodeImplementation,0,0},
69 {"emptybind", &OPTemptybindImplementation,0,0},
70 {"evaluate", &OPTevaluateImplementation,0,0},
71 {"garbageCollector", &OPTgarbageCollectorImplementation,0,0},
72 {"generator", &OPTgeneratorImplementation,0,0},
73 {"inline", &OPTinlineImplementation,0,0},
74 {"jit", &OPTjitImplementation,0,0},
75 {"json", &OPTjsonImplementation,0,0},
76 {"matpack", &OPTmatpackImplementation,0,0},
77 {"mergetable", &OPTmergetableImplementation,0,0},
78 {"mitosis", &OPTmitosisImplementation,0,0},
79 {"multiplex", &OPTmultiplexImplementation,0,0},
80 {"oltp", &OPToltpImplementation,0,0},
81 {"postfix", &OPTpostfixImplementation,0,0},
82 {"profiler", &OPTprofilerImplementation,0,0},
83 {"projectionpath", &OPTprojectionpathImplementation,0,0},
84 {"pushselect", &OPTpushselectImplementation,0,0},
85 {"querylog", &OPTquerylogImplementation,0,0},
86 {"reduce", &OPTreduceImplementation,0,0},
87 {"remap", &OPTremapImplementation,0,0},
88 {"remoteQueries", &OPTremoteQueriesImplementation,0,0},
89 {"reorder", &OPTreorderImplementation,0,0},
90 {"volcano", &OPTvolcanoImplementation,0,0},
91 {"wlc", &OPTwlcImplementation,0,0},
92 {0,0,0,0}
93};
94mal_export str OPTwrapper(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p);
95
96str OPTwrapper (Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p){
97 str modnme = "(NONE)";
98 str fcnnme = "(NONE)";
99 Symbol s= NULL;
100 int i;
101 char optimizer[256];
102 str msg = MAL_SUCCEED;
103 lng clk;
104
105 if (cntxt->mode == FINISHCLIENT)
106 throw(MAL, "optimizer", SQLSTATE(42000) "prematurely stopped client");
107
108 if( p == NULL)
109 throw(MAL, "opt_wrapper", SQLSTATE(HY002) "missing optimizer statement");
110
111 if( mb->errors)
112 throw(MAL, "opt_wrapper", SQLSTATE(42000) "MAL block contains errors");
113 snprintf(optimizer,256,"%s", fcnnme = getFunctionId(p));
114
115 if( p && p->argc > 1 ){
116 if( getArgType(mb,p,1) != TYPE_str ||
117 getArgType(mb,p,2) != TYPE_str ||
118 !isVarConstant(mb,getArg(p,1)) ||
119 !isVarConstant(mb,getArg(p,2))
120 )
121 throw(MAL, optimizer, SQLSTATE(42000) ILLARG_CONSTANTS);
122
123 if( stk != 0){
124 modnme= *getArgReference_str(stk,p,1);
125 fcnnme= *getArgReference_str(stk,p,2);
126 } else {
127 modnme= getArgDefault(mb,p,1);
128 fcnnme= getArgDefault(mb,p,2);
129 }
130 removeInstruction(mb, p);
131 s= findSymbol(cntxt->usermodule, putName(modnme),putName(fcnnme));
132
133 if( s == NULL)
134 throw(MAL, optimizer, SQLSTATE(HY002) RUNTIME_OBJECT_UNDEFINED ":%s.%s", modnme, fcnnme);
135 mb = s->def;
136 stk= 0;
137 } else if( p )
138 removeInstruction(mb, p);
139
140 for (i=0; codes[i].nme; i++)
141 if (strcmp(codes[i].nme, optimizer) == 0){
142 clk = GDKusec();
143 msg = (str)(*(codes[i].fcn))(cntxt, mb, stk, 0);
144 codes[i].timing += GDKusec() - clk;
145 codes[i].calls++;
146 if (msg)
147 throw(MAL, optimizer, SQLSTATE(42000) "Error in optimizer %s", optimizer);
148 break;
149 }
150 if (codes[i].nme == 0)
151 throw(MAL, optimizer, SQLSTATE(HY002) "Optimizer implementation '%s' missing", fcnnme);
152
153 if ( mb->errors)
154 throw(MAL, optimizer, SQLSTATE(42000) PROGRAM_GENERAL ":%s.%s %s", modnme, fcnnme, mb->errors);
155 return MAL_SUCCEED;
156}
157
158mal_export str OPTstatistics(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p);
159
160str
161OPTstatistics(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p)
162{
163 bat *nme = (bat*) getArgReference_bat(stk, p, 0);
164 bat *cnt = (bat*) getArgReference_bat(stk, p, 1);
165 bat *time = (bat*) getArgReference_bat(stk, p, 2);
166 BAT *n, *c, *t;
167 int i;
168
169 (void) cntxt;
170 (void) mb;
171 n = COLnew(0, TYPE_str, 256, TRANSIENT);
172 c = COLnew(0, TYPE_int, 256, TRANSIENT);
173 t = COLnew(0, TYPE_lng, 256, TRANSIENT);
174 if( n == NULL || c == NULL || t == NULL){
175 BBPreclaim(n);
176 BBPreclaim(c);
177 BBPreclaim(t);
178 throw(MAL,"optimizer.statistics", SQLSTATE(HY001) MAL_MALLOC_FAIL);
179 }
180 for( i= 0; codes[i].nme; i++){
181 if (BUNappend(n, codes[i].nme, false) != GDK_SUCCEED ||
182 BUNappend(c, &codes[i].calls, false) != GDK_SUCCEED ||
183 BUNappend(t, &codes[i].timing, false) != GDK_SUCCEED) {
184 BBPreclaim(n);
185 BBPreclaim(c);
186 BBPreclaim(t);
187 throw(MAL,"optimizer.statistics", SQLSTATE(HY001) MAL_MALLOC_FAIL);
188 }
189 }
190 BBPkeepref( *nme = n->batCacheid);
191 BBPkeepref( *cnt = c->batCacheid);
192 BBPkeepref( *time = t->batCacheid);
193 return MAL_SUCCEED;
194}
195