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 | |
23 | str |
24 | OPTvolcanoImplementation(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 | |