LCOV - code coverage report
Current view: top level - monetdb5/optimizer - opt_coercion.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 48 81 59.3 %
Date: 2021-10-13 02:24:04 Functions: 3 3 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             : /* (c) M. Kersten
      10             :  * Also include down-casting decisions on the SQL code produced
      11             :  */
      12             : 
      13             : #include "monetdb_config.h"
      14             : #include "opt_coercion.h"
      15             : #include "opt_aliases.h"
      16             : 
      17             : typedef struct{
      18             :         int pc;
      19             :         int fromtype;
      20             :         int totype;
      21             :         int src;
      22             : } Coercion;
      23             : 
      24             : /* Check coercions for numeric types towards :hge that can be handled with smaller ones.
      25             :  * For now, limit to +,-,/,*,% hge expressions
      26             :  * Not every combination may be available in the MAL layer, which calls
      27             :  * for a separate type check before fixing it.
      28             :  * Superflous coercion statements will be garbagecollected later on in the pipeline
      29             :  */
      30             : static void
      31    19391549 : coercionOptimizerCalcStep(Client cntxt, MalBlkPtr mb, int i, Coercion *coerce)
      32             : {
      33    19391549 :         InstrPtr p = getInstrPtr(mb,i);
      34             :         int r, a, b, varid;
      35             : 
      36    19391549 :         r = getBatType(getVarType(mb, getArg(p,0)));
      37             : #ifdef HAVE_HGE
      38    19391549 :         if ( r != TYPE_hge)
      39             :                 return;
      40             : #endif
      41       43304 :         if( getModuleId(p) != batcalcRef || getFunctionId(p) == 0) return;
      42       27908 :         if( ! (getFunctionId(p) == plusRef || getFunctionId(p) == minusRef || getFunctionId(p) == mulRef || getFunctionId(p) == divRef || getFunctionId(p) == modRef) || p->argc !=3)
      43             :                 return;
      44             : 
      45           0 :         a = getBatType(getVarType(mb, getArg(p,1)));
      46           0 :         b = getBatType(getVarType(mb, getArg(p,2)));
      47             :         varid = getArg(p,1);
      48           0 :         if ( a == r && coerce[varid].src && coerce[varid].fromtype < r )
      49             :         {
      50             :                 // Remove upcast on first argument
      51           0 :                 getArg(p,1) = coerce[varid].src;
      52           0 :                 if ( chkInstruction(cntxt->usermodule, mb, p) || p->typechk == TYPE_UNKNOWN)
      53           0 :                         getArg(p,1) = varid;
      54             :         }
      55           0 :         varid = getArg(p,2);
      56           0 :         if ( b == r && coerce[varid].src &&  coerce[varid].fromtype < r )
      57             :         {
      58             :                 // Remove upcast on second argument
      59           0 :                 getArg(p,2) = coerce[varid].src;
      60           0 :                 if ( chkInstruction(cntxt->usermodule, mb, p) || p->typechk == TYPE_UNKNOWN)
      61           0 :                         getArg(p,2) = varid;
      62             :         }
      63             :         return;
      64             : }
      65             : 
      66             : static void
      67    19391549 : coercionOptimizerAggrStep(Client cntxt, MalBlkPtr mb, int i, Coercion *coerce)
      68             : {
      69    19391549 :         InstrPtr p = getInstrPtr(mb,i);
      70             :         int r, k;
      71             : 
      72             :         (void) cntxt;
      73             : 
      74    19391549 :         if( getModuleId(p) != aggrRef || getFunctionId(p) == 0) return;
      75       48924 :         if( ! (getFunctionId(p) == subavgRef ) || p->argc !=6)
      76             :                 return;
      77             : 
      78         191 :         r = getBatType(getVarType(mb, getArg(p,0)));
      79         191 :         k = getArg(p,1);
      80         191 :         if( r == TYPE_dbl &&  coerce[k].src ){
      81           0 :                 getArg(p,1) = coerce[k].src;
      82           0 :                 if ( chkInstruction(cntxt->usermodule, mb, p) || p->typechk == TYPE_UNKNOWN)
      83           0 :                         getArg(p,1)= k;
      84             :         }
      85             :         return;
      86             : }
      87             : 
      88             : str
      89      353098 : OPTcoercionImplementation(Client cntxt,MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      90             : {
      91             :         int i, k, t;
      92             :         InstrPtr p;
      93             :         int actions = 0;
      94      353098 :         const char *calcRef= putName("calc");
      95      353098 :         Coercion *coerce = GDKzalloc(sizeof(Coercion) * mb->vtop);
      96             :         str msg = MAL_SUCCEED;
      97             : 
      98      353098 :         if( coerce == NULL)
      99           0 :                 throw(MAL,"optimizer.coercion", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     100             :         (void) cntxt;
     101             :         (void) stk;             /* to fool compilers */
     102             : 
     103    22429049 :         for (i = 1; i < mb->stop; i++) {
     104    22075951 :                 p = getInstrPtr(mb, i);
     105    22075951 :                 if (getModuleId(p) == NULL)
     106     2684401 :                         continue;
     107             : /* Downscale the type, avoiding hge storage when lng would be sufficient.
     108             :  */
     109             : #ifdef HAVE_HGE
     110    19391550 :                 if ( getModuleId(p) == batcalcRef
     111      221061 :                          && getFunctionId(p) == hgeRef
     112       16141 :                          && p->retc == 1
     113       16141 :                          && ( p->argc == 5
     114         136 :                                    && isVarConstant(mb,getArg(p,1))
     115           0 :                                    && getArgType(mb,p,1) == TYPE_int
     116           0 :                                    && isVarConstant(mb,getArg(p,3))
     117           0 :                                    && getArgType(mb,p,3) == TYPE_int
     118           0 :                                    && isVarConstant(mb,getArg(p,4))
     119           0 :                                    && getArgType(mb,p,4) == TYPE_int
     120             :                                    /* from-scale == to-scale, i.e., no scale change */
     121           0 :                                    && *(int*) getVarValue(mb, getArg(p,1)) == *(int*) getVarValue(mb, getArg(p,4)) ) ){
     122           0 :                         k = getArg(p,0);
     123           0 :                         coerce[k].pc= i;
     124           0 :                         coerce[k].totype= TYPE_hge;
     125           0 :                         coerce[k].src= getArg(p,2);
     126           0 :                         coerce[k].fromtype= getBatType(getArgType(mb,p,2));
     127             :                 }
     128             : #endif
     129    19391550 :                 if ( getModuleId(p) == batcalcRef
     130      221061 :                          && getFunctionId(p) == dblRef
     131        1278 :                          && p->retc == 1
     132        1278 :                          && ( p->argc == 2
     133        1278 :                                   || ( p->argc == 3
     134        1217 :                                            && isVarConstant(mb,getArg(p,1))
     135           0 :                                            && getArgType(mb,p,1) == TYPE_int
     136             :                                            //to-scale == 0, i.e., no scale change
     137           0 :                                            && *(int*) getVarValue(mb, getArg(p,1)) == 0 ) ) ) {
     138           0 :                         k = getArg(p,0);
     139           0 :                         coerce[k].pc= i;
     140           0 :                         coerce[k].totype= TYPE_dbl;
     141           0 :                         coerce[k].src= getArg(p,1 + (p->argc ==3));
     142           0 :                         coerce[k].fromtype= getBatType(getArgType(mb,p,1 + (p->argc ==3)));
     143             :                 }
     144    19391550 :                 coercionOptimizerAggrStep(cntxt,mb, i, coerce);
     145    19391548 :                 coercionOptimizerCalcStep(cntxt,mb, i, coerce);
     146    19391550 :                 if (getModuleId(p)==calcRef && p->argc == 2) {
     147       20272 :                         t = getVarType(mb, getArg(p,1));
     148       20272 :                         if (getVarType(mb, getArg(p,0)) == t && strcmp(getFunctionId(p), ATOMname(t)) == 0) {
     149             :                                 /* turn it into an assignment */
     150         262 :                                 clrFunction(p);
     151         262 :                                 actions ++;
     152             :                         }
     153             :                 }
     154             :         }
     155             :         /*
     156             :          * This optimizer affects the flow, but not the type and declaration
     157             :          * structure. A cheaper optimizer is sufficient.
     158             :          */
     159      353098 :         GDKfree(coerce);
     160             : 
     161             :         /* Defense line against incorrect plans */
     162      353098 :         if( actions > 0){
     163         120 :                 msg = chkTypes(cntxt->usermodule, mb, FALSE);
     164         120 :                 if (!msg)
     165         120 :                         msg = chkFlow(mb);
     166         120 :                 if (!msg)
     167         120 :                         msg = chkDeclarations(mb);
     168             :         }
     169             :         /* keep actions taken as a fake argument*/
     170      353098 :         (void) pushInt(mb, pci, actions);
     171      353098 :         return msg;
     172             : }

Generated by: LCOV version 1.14