LCOV - code coverage report
Current view: top level - monetdb5/optimizer - opt_generator.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 68 79 86.1 %
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             : #include "monetdb_config.h"
      10             : #include "opt_generator.h"
      11             : #include "mal_builder.h"
      12             : 
      13             : /*
      14             :  * (c) Martin Kersten, Sjoerd Mullender
      15             :  * Series generating module for integer, decimal, real, double and timestamps.
      16             :  */
      17             : 
      18             : #define errorCheck(P,IDX,MOD,I) \
      19             : setModuleId(P, generatorRef);\
      20             : typeChecker(cntxt->usermodule, mb, P, IDX, TRUE);\
      21             : if(P->typechk == TYPE_UNKNOWN){\
      22             :         setModuleId(P,MOD);\
      23             :         typeChecker(cntxt->usermodule, mb, P, IDX, TRUE);\
      24             :         setModuleId(series[I], generatorRef);\
      25             :         setFunctionId(series[I], seriesRef);\
      26             :         typeChecker(cntxt->usermodule, mb, series[I], I, TRUE);\
      27             : }\
      28             : pushInstruction(mb,P);
      29             : 
      30             : #define casting(TPE)\
      31             :                         k= getArg(p,1);\
      32             :                         p->argc = p->retc;\
      33             :                         q= newInstruction(0,calcRef, TPE##Ref);\
      34             :                         setDestVar(q, newTmpVariable(mb, TYPE_##TPE));\
      35             :                         addArgument(mb,q,getArg(series[k],1));\
      36             :                         typeChecker(cntxt->usermodule, mb, q, 0, TRUE);\
      37             :                         p = addArgument(mb,p, getArg(q,0));\
      38             :                         pushInstruction(mb,q);\
      39             :                         q= newInstruction(0,calcRef,TPE##Ref);\
      40             :                         setDestVar(q, newTmpVariable(mb, TYPE_##TPE));\
      41             :                         addArgument(mb,q,getArg(series[k],2));\
      42             :                         pushInstruction(mb,q);\
      43             :                         typeChecker(cntxt->usermodule, mb, q, 0, TRUE);\
      44             :                         p = addArgument(mb,p, getArg(q,0));\
      45             :                         if( p->argc == 4){\
      46             :                                 q= newInstruction(0,calcRef,TPE##Ref);\
      47             :                                 setDestVar(q, newTmpVariable(mb, TYPE_##TPE));\
      48             :                                 addArgument(mb,q,getArg(series[k],3));\
      49             :                                 typeChecker(cntxt->usermodule, mb, q, 0, TRUE);\
      50             :                                 p = addArgument(mb,p, getArg(q,0));\
      51             :                                 pushInstruction(mb,q);\
      52             :                         }\
      53             :                         setModuleId(p,generatorRef);\
      54             :                         setFunctionId(p,parametersRef);\
      55             :                         series[getArg(p,0)] = p;\
      56             :                         pushInstruction(mb,p);
      57             : 
      58             : str
      59      356706 : OPTgeneratorImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      60             : {
      61             :         InstrPtr p,q, *old, *series;
      62             :         int i, k, limit, slimit, actions=0;
      63      356706 :         const char *bteRef = getName("bte");
      64      356706 :         const char *shtRef = getName("sht");
      65      356706 :         const char *intRef = getName("int");
      66      356706 :         const char *lngRef = getName("lng");
      67      356706 :         const char *fltRef = getName("flt");
      68      356706 :         const char *dblRef = getName("dbl");
      69             :         str msg = MAL_SUCCEED;
      70             :         int needed = 0;
      71             : 
      72             :         (void) stk;
      73             : 
      74      356706 :         old = mb->stmt;
      75      356706 :         limit = mb->stop;
      76      356706 :         slimit = mb->ssize;
      77             : 
      78             :         // check applicability first
      79    23168423 :         for( i=0; i < limit; i++){
      80    22812092 :                 p = old[i];
      81    22812092 :                 if ( getModuleId(p) == generatorRef && getFunctionId(p) == seriesRef)
      82             :                         needed = 1;
      83             :                 /* avoid error in table-udf-column-descriptor */
      84    22812092 :                 if (p->token == RETURNsymbol || p->barrier == RETURNsymbol){
      85             :                         old = NULL;
      86         375 :                         goto wrapup;
      87             :                 }
      88             :         }
      89      356331 :         if (!needed)
      90      356169 :                 goto wrapup;
      91             : 
      92         162 :         series = (InstrPtr*) GDKzalloc(sizeof(InstrPtr) * mb->vtop);
      93         162 :         if(series == NULL)
      94           0 :                 throw(MAL,"optimizer.generator", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      95             : 
      96         162 :         if (newMalBlkStmt(mb, mb->ssize) < 0) {
      97           0 :                 GDKfree(series);
      98           0 :                 throw(MAL,"optimizer.generator", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      99             :         }
     100             : 
     101        4152 :         for( i=0; i < limit; i++){
     102        4152 :                 p = old[i];
     103        4152 :                 if (p->token == ENDsymbol){
     104         162 :                         pushInstruction(mb,p);
     105         162 :                         break;
     106             :                 }
     107        3990 :                 if ( getModuleId(p) == generatorRef && getFunctionId(p) == seriesRef){
     108         165 :                         series[getArg(p,0)] = p;
     109         165 :                         setModuleId(p, generatorRef);
     110         165 :                         setFunctionId(p, parametersRef);
     111         165 :                         typeChecker(cntxt->usermodule, mb, p, i, TRUE);
     112         165 :                         pushInstruction(mb,p);
     113        3825 :                 } else if ( getModuleId(p) == algebraRef && getFunctionId(p) == selectRef && series[getArg(p,1)]){
     114          23 :                         errorCheck(p,i, algebraRef,getArg(p,1));
     115        3802 :                 } else if ( getModuleId(p) == algebraRef && getFunctionId(p) == thetaselectRef && series[getArg(p,1)]){
     116          27 :                         errorCheck(p,i,algebraRef,getArg(p,1));
     117        3775 :                 } else if ( getModuleId(p) == algebraRef && getFunctionId(p) == projectionRef && series[getArg(p,2)]){
     118         124 :                         errorCheck(p,i,algebraRef,getArg(p,2));
     119        3651 :                 } else if ( getModuleId(p) == sqlRef && getFunctionId(p) ==  putName("exportValue") && isaBatType(getArgType(mb,p,0)) ){
     120             :                         // interface expects scalar type only, not expressable in MAL signature
     121           0 :                         mb->errors=createException(MAL, "generate_series", SQLSTATE(42000) "internal error, generate_series is a table producing function");
     122        3651 :                 }else if ( getModuleId(p) == batcalcRef && getFunctionId(p) == bteRef && series[getArg(p,1)] && p->argc == 2 ){
     123           0 :                         casting(bte);
     124        3651 :                 } else if ( getModuleId(p) == batcalcRef && getFunctionId(p) == shtRef && series[getArg(p,1)] && p->argc == 2 ){
     125           0 :                         casting(sht);
     126        3651 :                 } else if ( getModuleId(p) == batcalcRef && getFunctionId(p) == intRef && series[getArg(p,1)] && p->argc == 2 ){
     127           0 :                         casting(int);
     128        3651 :                 } else if ( getModuleId(p) == batcalcRef && getFunctionId(p) == lngRef && series[getArg(p,1)] && p->argc == 2 ){
     129           0 :                         casting(lng);
     130        3651 :                 } else if ( getModuleId(p) == batcalcRef && getFunctionId(p) == fltRef && series[getArg(p,1)] && p->argc == 2 ){
     131           0 :                         casting(flt);
     132        3651 :                 } else if ( getModuleId(p) == batcalcRef && getFunctionId(p) == dblRef && series[getArg(p,1)] && p->argc == 2 ){
     133           0 :                         casting(dbl);
     134        3651 :                 } else if ( getModuleId(p) == languageRef && getFunctionId(p) == passRef )
     135         469 :                         pushInstruction(mb,p);
     136             :                 else {
     137             :                         // check for use without conversion
     138       10771 :                         for(k = p->retc; k < p->argc; k++)
     139        7589 :                         if( series[getArg(p,k)]){
     140         157 :                                 const char *m = getModuleId(p);
     141         157 :                                 setModuleId(p, generatorRef);
     142         157 :                                 typeChecker(cntxt->usermodule, mb, p, i, TRUE);
     143         157 :                                 if(p->typechk == TYPE_UNKNOWN){
     144         157 :                                         setModuleId(p,m);
     145         157 :                                         typeChecker(cntxt->usermodule, mb, p, i, TRUE);
     146         157 :                                         InstrPtr r = series[getArg(p,k)];
     147         157 :                                         setModuleId(r, generatorRef);
     148         157 :                                         setFunctionId(r, seriesRef);
     149         157 :                                         typeChecker(cntxt->usermodule, mb, r, getPC(mb,r),  TRUE);
     150             :                                 }
     151             :                         }
     152        3182 :                         pushInstruction(mb,p);
     153             :                 }
     154             :         }
     155        5012 :         for (i++; i < limit; i++)
     156        4850 :                 pushInstruction(mb, old[i]);
     157       32632 :         for (; i < slimit; i++) {
     158       32470 :                 if (old[i])
     159           0 :                         pushInstruction(mb, old[i]);
     160             :         }
     161         162 :         GDKfree(old);
     162         162 :         GDKfree(series);
     163             : 
     164             :         /* Defense line against incorrect plans */
     165             :         /* all new/modified statements are already checked */
     166             :         // msg = chkTypes(cntxt->usermodule, mb, FALSE);
     167             :         // if (!msg)
     168             :         //      msg = chkFlow(mb);
     169             :         // if (!msg)
     170             :         //      msg = chkDeclarations(mb);
     171             :         /* keep all actions taken as a post block comment */
     172      356706 : wrapup:
     173             :         /* keep actions taken as a fake argument*/
     174      356706 :         (void) pushInt(mb, pci, actions);
     175      356706 :         return msg;
     176             : }

Generated by: LCOV version 1.14