LCOV - code coverage report
Current view: top level - monetdb5/optimizer - opt_postfix.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 81 100 81.0 %
Date: 2021-10-13 02:24:04 Functions: 1 1 100.0 %

          Line data    Source code
       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 - 2021 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             : 
      17             : #define isCandidateList(M,P,I) ((M)->var[getArg(P,I)].id[0]== 'C')
      18             : str
      19      353093 : OPTpostfixImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      20             : {
      21             :         int i, slimit, actions = 0;
      22             :         str msg = MAL_SUCCEED;
      23             :         InstrPtr p;
      24             : 
      25             :         (void) cntxt;
      26             :         (void) stk;
      27             : 
      28      353093 :         slimit = mb->stop;
      29      353093 :         setVariableScope(mb);
      30             :         /* Remove the result from any join/group instruction when it is not used later on */
      31    23116279 :         for( i = 0; i< slimit; i++){
      32             : /* POSTFIX ACTION FOR THE JOIN CASE  */
      33    22763186 :                 p= getInstrPtr(mb, i);
      34    22763186 :                 if ( getModuleId(p) == algebraRef && p->retc == 2) {
      35      352479 :                         if ( getFunctionId(p) == leftjoinRef || getFunctionId(p) == outerjoinRef ||
      36      351830 :                                  getFunctionId(p) == bandjoinRef || getFunctionId(p) == rangejoinRef ||
      37      351693 :                                  getFunctionId(p) == likejoinRef) {
      38         826 :                                 if ( getVarEolife(mb, getArg(p, p->retc -1)) == i) {
      39          44 :                                         delArgument(p, p->retc -1);
      40          44 :                                         typeChecker(cntxt->usermodule, mb, p, i, TRUE);
      41          44 :                                         actions++;
      42          44 :                                         continue;
      43             :                                 }
      44      351653 :                         } else if ( getFunctionId(p) == semijoinRef || getFunctionId(p) == joinRef ||
      45       33848 :                                  getFunctionId(p) == thetajoinRef || getFunctionId(p) == outerjoinRef || getFunctionId(p) == crossRef) {
      46      351124 :                                 int is_first_ret_not_used = getVarEolife(mb, getArg(p, p->retc -2)) == i;
      47      351124 :                                 int is_second_ret_not_used = getVarEolife(mb, getArg(p, p->retc -1)) == i;
      48             : 
      49      351124 :                                 if (getFunctionId(p) == semijoinRef && ((is_first_ret_not_used && getVarConstant(mb, getArg(p, 7)).val.btval != 1/*not single*/) || is_second_ret_not_used)) {
      50             :                                         /* Can't swap arguments on single semijoins */
      51         117 :                                         if (is_first_ret_not_used) {
      52             :                                                 /* semijoin with just the right output is a join */
      53           0 :                                                 getArg(p, 2) ^= getArg(p, 3); /* swap join inputs */
      54           0 :                                                 getArg(p, 3) ^= getArg(p, 2);
      55           0 :                                                 getArg(p, 2) ^= getArg(p, 3);
      56             : 
      57           0 :                                                 getArg(p, 4) ^= getArg(p, 5); /* swap candidate lists */
      58           0 :                                                 getArg(p, 5) ^= getArg(p, 4);
      59           0 :                                                 getArg(p, 4) ^= getArg(p, 5);
      60           0 :                                                 setFunctionId(p, joinRef);
      61           0 :                                                 delArgument(p, 7); /* delete 'max_one' argument */
      62             :                                         } else {
      63             :                                                 /* semijoin with just the left output is an intersection */
      64         117 :                                                 setFunctionId(p, intersectRef);
      65             :                                         }
      66             : 
      67         117 :                                         delArgument(p, is_second_ret_not_used ? p->retc -1 : p->retc -2);
      68         117 :                                         typeChecker(cntxt->usermodule, mb, p, i, TRUE);
      69         117 :                                         actions++;
      70         117 :                                         continue;
      71      351007 :                                 } else if (is_second_ret_not_used) {
      72       49667 :                                         delArgument(p, p->retc -1);
      73       49667 :                                         typeChecker(cntxt->usermodule, mb, p, i, TRUE);
      74       49667 :                                         actions++;
      75       49667 :                                         continue;
      76      301340 :                                 } else if (is_first_ret_not_used && (getFunctionId(p) == joinRef || (getFunctionId(p) == thetajoinRef && isVarConstant(mb, getArg(p, 6))) ||
      77         185 :                                                    (getFunctionId(p) == crossRef && getVarConstant(mb, getArg(p, 4)).val.btval != 1/*not single*/))) {
      78             :                                         /* Can't swap arguments on single cross products */
      79             :                                         /* swap join inputs */
      80        4457 :                                         getArg(p, 2) ^= getArg(p, 3);
      81        4457 :                                         getArg(p, 3) ^= getArg(p, 2);
      82        4457 :                                         getArg(p, 2) ^= getArg(p, 3);
      83             : 
      84        4457 :                                         if (getFunctionId(p) != crossRef) { /* swap candidate lists */
      85        4341 :                                                 getArg(p, 4) ^= getArg(p, 5);
      86        4341 :                                                 getArg(p, 5) ^= getArg(p, 4);
      87        4341 :                                                 getArg(p, 4) ^= getArg(p, 5);
      88        4341 :                                                 if (getFunctionId(p) == thetajoinRef) { /* swap the comparison */
      89          21 :                                                         ValRecord *x = &getVarConstant(mb, getArg(p, 6)), cst = {.vtype = TYPE_int};
      90          21 :                                                         switch (x->val.ival) {
      91           0 :                                                         case JOIN_LT:
      92           0 :                                                                 cst.val.ival = JOIN_GT;
      93           0 :                                                                 break;
      94           8 :                                                         case JOIN_LE:
      95           8 :                                                                 cst.val.ival = JOIN_GE;
      96           8 :                                                                 break;
      97          13 :                                                         case JOIN_GT:
      98          13 :                                                                 cst.val.ival = JOIN_LT;
      99          13 :                                                                 break;
     100           0 :                                                         case JOIN_GE:
     101           0 :                                                                 cst.val.ival = JOIN_LE;
     102           0 :                                                                 break;
     103           0 :                                                         default:
     104           0 :                                                                 cst.val.ival = x->val.ival;
     105             :                                                         }
     106          21 :                                                         setArg(p, 6, defConstant(mb, TYPE_int, &cst));
     107             :                                                 }
     108             :                                         }
     109        4457 :                                         delArgument(p, p->retc -2);
     110        4457 :                                         typeChecker(cntxt->usermodule, mb, p, i, TRUE);
     111        4457 :                                         actions++;
     112        4457 :                                         continue;
     113             :                                 }
     114             :                         }
     115             :                 }
     116             : /* POSTFIX ACTION FOR THE EXTENT CASE  */
     117    22708901 :                 if ( getModuleId(p) == groupRef && getFunctionId(p) == groupRef && getVarEolife(mb, getArg(p, p->retc -1)) == i){
     118       14954 :                         delArgument(p, p->retc -1);
     119       14954 :                         typeChecker(cntxt->usermodule, mb, p, i, TRUE);
     120       14954 :                         actions++;
     121       14954 :                         continue;
     122             :                 }
     123    22693947 :                 if ( getModuleId(p) == groupRef && getFunctionId(p) == subgroupRef && getVarEolife(mb, getArg(p, p->retc -1)) == i){
     124        8909 :                         delArgument(p, p->retc -1);
     125        8909 :                         typeChecker(cntxt->usermodule, mb, p, i, TRUE);
     126        8909 :                         actions++;
     127        8909 :                         continue;
     128             :                 }
     129    22685038 :                 if ( getModuleId(p) == groupRef && getFunctionId(p) == subgroupdoneRef && getVarEolife(mb, getArg(p, p->retc -1)) == i){
     130       14833 :                         delArgument(p, p->retc -1);
     131       14833 :                         typeChecker(cntxt->usermodule, mb, p, i, TRUE);
     132       14833 :                         actions++;
     133       14833 :                         continue;
     134             :                 }
     135    22670205 :                 if ( getModuleId(p) == groupRef && getFunctionId(p) == groupdoneRef && getVarEolife(mb, getArg(p, p->retc -1)) == i){
     136       20259 :                         delArgument(p, p->retc -1);
     137       20259 :                         typeChecker(cntxt->usermodule, mb, p, i, TRUE);
     138       20259 :                         actions++;
     139       20259 :                         continue;
     140             :                 }
     141             : /* POSTFIX ACTION FOR SORT, could be dropping the last two */
     142    22649946 :                 if ( getModuleId(p) == algebraRef && getFunctionId(p) == sortRef && getVarEolife(mb, getArg(p, p->retc -1)) == i){
     143       15063 :                         delArgument(p, p->retc -1);
     144       15063 :                         typeChecker(cntxt->usermodule, mb, p, i, TRUE);
     145       15063 :                         actions++;
     146       15063 :                         if ( getModuleId(p) == algebraRef && getFunctionId(p) == sortRef && getVarEolife(mb, getArg(p, p->retc -1)) == i){
     147           0 :                                 delArgument(p, p->retc -1);
     148           0 :                                 typeChecker(cntxt->usermodule, mb, p, i, TRUE);
     149           0 :                                 actions++;
     150             :                         }
     151       15063 :                         continue;
     152             :                 }
     153             :         }
     154             :         /* Defense line against incorrect plans */
     155             :         if( actions ){
     156             :                 // msg = chkTypes(cntxt->usermodule, mb, FALSE);
     157             :                 // if (!msg)
     158             :                 //      msg = chkFlow(mb);
     159             :                 // if (!msg)
     160             :                 //      msg = chkDeclarations(mb);
     161             :         }
     162             :         /* keep actions taken as a fake argument*/
     163      353093 :         (void) pushInt(mb, pci, actions);
     164      353093 :         return msg;
     165             : }

Generated by: LCOV version 1.14