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/* The SQL code generator can not always look ahead to avoid
10 * generation of intermediates.
11 * Some of these patterns are captured in a postfix optimalisation.
12 */
13#include "monetdb_config.h"
14#include "mal_instruction.h"
15#include "opt_postfix.h"
16#include "algebra.h"
17
18#define isCandidateList(M,P,I) ((M)->var[getArg(P,I)].id[0]== 'C')
19str
20OPTpostfixImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p)
21{
22 int i, slimit, actions = 0;
23 lng usec = GDKusec();
24 char buf[256];
25
26 (void) cntxt;
27 (void) stk;
28
29 slimit = mb->stop;
30 setVariableScope(mb);
31 if( OPTdebug & OPTpostfix){
32 fprintf(stderr,"POSTFIX start\n");
33 fprintFunction(stderr, mb, 0, LIST_MAL_ALL);
34 }
35 /* Remove the result from any join/group instruction when it is not used later on */
36 for( i = 0; i< slimit; i++){
37/* POSTFIX ACTION FOR THE JOIN CASE */
38 p= getInstrPtr(mb, i);
39 if ( getModuleId(p) == algebraRef && getFunctionId(p) == joinRef && getVarEolife(mb, getArg(p, p->retc -1)) == i){
40 delArgument(p, p->retc -1);
41 typeChecker(cntxt->usermodule, mb, p, TRUE);
42 actions++;
43 continue;
44 }
45 if ( getModuleId(p) == algebraRef && getFunctionId(p) == leftjoinRef && getVarEolife(mb, getArg(p, p->retc -1)) == i){
46 delArgument(p, p->retc -1);
47 typeChecker(cntxt->usermodule, mb, p, TRUE);
48 actions++;
49 continue;
50 }
51/* POSTFIX ACTION FOR THE EXTENT CASE */
52 if ( getModuleId(p) == groupRef && getFunctionId(p) == groupRef && getVarEolife(mb, getArg(p, p->retc -1)) == i){
53 delArgument(p, p->retc -1);
54 typeChecker(cntxt->usermodule, mb, p, TRUE);
55 actions++;
56 continue;
57 }
58 if ( getModuleId(p) == groupRef && getFunctionId(p) == subgroupRef && getVarEolife(mb, getArg(p, p->retc -1)) == i){
59 delArgument(p, p->retc -1);
60 typeChecker(cntxt->usermodule, mb, p, TRUE);
61 actions++;
62 continue;
63 }
64 if ( getModuleId(p) == groupRef && getFunctionId(p) == subgroupdoneRef && getVarEolife(mb, getArg(p, p->retc -1)) == i){
65 delArgument(p, p->retc -1);
66 typeChecker(cntxt->usermodule, mb, p, TRUE);
67 actions++;
68 continue;
69 }
70 if ( getModuleId(p) == groupRef && getFunctionId(p) == groupdoneRef && getVarEolife(mb, getArg(p, p->retc -1)) == i){
71 delArgument(p, p->retc -1);
72 typeChecker(cntxt->usermodule, mb, p, TRUE);
73 actions++;
74 continue;
75 }
76 }
77 /* Defense line against incorrect plans */
78 if( actions ){
79 //chkTypes(cntxt->usermodule, mb, FALSE);
80 //chkFlow(mb);
81 //chkDeclarations(mb);
82 }
83 usec= GDKusec() - usec;
84 snprintf(buf,256,"%-20s actions=%2d time=" LLFMT " usec", "postfix", actions, usec);
85 newComment(mb,buf);
86 if( OPTdebug & OPTpostfix){
87 fprintf(stderr,"POSTFIX done\n");
88 fprintFunction(stderr, mb, 0, LIST_MAL_ALL);
89 }
90 addtoMalBlkHistory(mb);
91 return MAL_SUCCEED;
92}
93