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/*
10 * Selectively inject serialization operations when we know the
11 * raw footprint of the query exceeds 80% of RAM.
12 */
13
14#include "monetdb_config.h"
15#include "mal_instruction.h"
16#include "opt_volcano.h"
17
18// delaying the startup should not be continued throughout the plan
19// after the startup phase there should be intermediate work to do
20//A heuristic to check it
21#define MAXdelays 128
22
23str
24OPTvolcanoImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
25{
26 int i, limit;
27 int mvcvar = -1;
28 int count=0;
29 InstrPtr p,q, *old = mb->stmt;
30 char buf[256];
31 lng usec = GDKusec();
32 str msg = MAL_SUCCEED;
33
34 (void) pci;
35 (void) cntxt;
36 (void) stk; /* to fool compilers */
37
38 if ( mb->inlineProp )
39 return MAL_SUCCEED;
40
41 limit= mb->stop;
42 if ( newMalBlkStmt(mb, mb->ssize + 20) < 0)
43 throw(MAL,"optimizer.volcano", SQLSTATE(HY001) MAL_MALLOC_FAIL);
44 for (i = 0; i < limit; i++) {
45 p = old[i];
46
47 pushInstruction(mb,p);
48 if( getModuleId(p) == sqlRef && getFunctionId(p)== mvcRef ){
49 mvcvar = getArg(p,0);
50 continue;
51 }
52
53 if( count < MAXdelays && getModuleId(p) == algebraRef ){
54 if( getFunctionId(p) == selectRef ||
55 getFunctionId(p) == thetaselectRef ||
56 getFunctionId(p) == likeselectRef ||
57 getFunctionId(p) == joinRef
58 ){
59 q= newInstruction(0,languageRef,blockRef);
60 setDestVar(q, newTmpVariable(mb,TYPE_any));
61 q = pushArgument(mb,q,mvcvar);
62 q = pushArgument(mb,q,getArg(p,0));
63 mvcvar= getArg(q,0);
64 pushInstruction(mb,q);
65 count++;
66 }
67 continue;
68 }
69 if( count < MAXdelays && getModuleId(p) == groupRef ){
70 if( getFunctionId(p) == subgroupdoneRef || getFunctionId(p) == groupdoneRef ){
71 q= newInstruction(0,languageRef,blockRef);
72 setDestVar(q, newTmpVariable(mb,TYPE_any));
73 q = pushArgument(mb,q,mvcvar);
74 q = pushArgument(mb,q,getArg(p,0));
75 mvcvar= getArg(q,0);
76 pushInstruction(mb,q);
77 count++;
78 }
79 }
80 if( getModuleId(p) == sqlRef){
81 if ( getFunctionId(p) == bindRef ||
82 getFunctionId(p) == bindidxRef ||
83 getFunctionId(p)== tidRef ||
84 getFunctionId(p)== appendRef ||
85 getFunctionId(p)== updateRef ||
86 getFunctionId(p)== deleteRef
87 ){
88 setArg(p,p->retc,mvcvar);
89 }
90 }
91 }
92 GDKfree(old);
93
94 /* Defense line against incorrect plans */
95 if( count){
96 chkTypes(cntxt->usermodule, mb, FALSE);
97 chkFlow(mb);
98 chkDeclarations(mb);
99 }
100 /* keep all actions taken as a post block comment */
101 usec = GDKusec()- usec;
102 snprintf(buf,256,"%-20s actions=%2d time=" LLFMT " usec","volcano",count,usec);
103 newComment(mb,buf);
104 if( count >= 0)
105 addtoMalBlkHistory(mb);
106
107 if( OPTdebug & OPTvolcano){
108 fprintf(stderr, "#volcano optimizer exit\n");
109 fprintFunction(stderr, mb, 0, LIST_MAL_ALL);
110 }
111 return msg;
112}
113