LCOV - code coverage report
Current view: top level - monetdb5/optimizer - opt_wrapper.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 44 80 55.0 %
Date: 2021-10-13 02:24:04 Functions: 2 3 66.7 %

          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             : /*  author M.L. Kersten
      10             :  * The optimizer wrapper code is the interface to the MAL optimizer calls.
      11             :  *
      12             :  * Before an optimizer is finished, it should leave a clean state behind.
      13             :  * Moreover, some information of the optimization step is saved for
      14             :  * debugging and analysis.
      15             : */
      16             : 
      17             : #include "monetdb_config.h"
      18             : #include "mal_listing.h"
      19             : 
      20             : /*
      21             :  * The optimizer used so far
      22             : */
      23             : #include "opt_aliases.h"
      24             : #include "opt_bincopyfrom.h"
      25             : #include "opt_coercion.h"
      26             : #include "opt_commonTerms.h"
      27             : #include "opt_candidates.h"
      28             : #include "opt_constants.h"
      29             : #include "opt_costModel.h"
      30             : #include "opt_dataflow.h"
      31             : #include "opt_deadcode.h"
      32             : #include "opt_emptybind.h"
      33             : #include "opt_evaluate.h"
      34             : #include "opt_garbageCollector.h"
      35             : #include "opt_generator.h"
      36             : #include "opt_inline.h"
      37             : #include "opt_jit.h"
      38             : #include "opt_projectionpath.h"
      39             : #include "opt_matpack.h"
      40             : #include "opt_json.h"
      41             : #include "opt_oltp.h"
      42             : #include "opt_postfix.h"
      43             : #include "opt_mask.h"
      44             : #include "opt_mergetable.h"
      45             : #include "opt_mitosis.h"
      46             : #include "opt_multiplex.h"
      47             : #include "opt_profiler.h"
      48             : #include "opt_pushselect.h"
      49             : #include "opt_querylog.h"
      50             : #include "opt_reduce.h"
      51             : #include "opt_remap.h"
      52             : #include "opt_remoteQueries.h"
      53             : #include "opt_reorder.h"
      54             : #include "opt_volcano.h"
      55             : #include "opt_fastpath.h"
      56             : #include "opt_wlc.h"
      57             : #include "optimizer_private.h"
      58             : 
      59             : // keep the optimizer list sorted
      60             : struct{
      61             :         str nme;
      62             :         str (*fcn)();
      63             :         int calls;
      64             :         lng timing;
      65             : } codes[] = {
      66             :         {"aliases", &OPTaliasesImplementation,0,0},
      67             :         {"bincopyfrom", &OPTbincopyfromImplementation,0,0},
      68             :         {"candidates", &OPTcandidatesImplementation,0,0},
      69             :         {"coercions", &OPTcoercionImplementation,0,0},
      70             :         {"commonTerms", &OPTcommonTermsImplementation,0,0},
      71             :         {"constants", &OPTconstantsImplementation,0,0},
      72             :         {"costModel", &OPTcostModelImplementation,0,0},
      73             :         {"dataflow", &OPTdataflowImplementation,0,0},
      74             :         {"deadcode", &OPTdeadcodeImplementation,0,0},
      75             :         {"defaultfast", &OPTdefaultfastImplementation,0,0},
      76             :         {"emptybind", &OPTemptybindImplementation,0,0},
      77             :         {"evaluate", &OPTevaluateImplementation,0,0},
      78             :         {"garbageCollector", &OPTgarbageCollectorImplementation,0,0},
      79             :         {"generator", &OPTgeneratorImplementation,0,0},
      80             :         {"inline", &OPTinlineImplementation,0,0},
      81             :         {"jit", &OPTjitImplementation,0,0},
      82             :         {"json", &OPTjsonImplementation,0,0},
      83             :         {"mask", &OPTmaskImplementation,0,0},
      84             :         {"matpack", &OPTmatpackImplementation,0,0},
      85             :         {"mergetable", &OPTmergetableImplementation,0,0},
      86             :         {"minimalfast", &OPTminimalfastImplementation,0,0},
      87             :         {"mitosis", &OPTmitosisImplementation,0,0},
      88             :         {"multiplex", &OPTmultiplexImplementation,0,0},
      89             :         {"oltp", &OPToltpImplementation,0,0},
      90             :         {"postfix", &OPTpostfixImplementation,0,0},
      91             :         {"profiler", &OPTprofilerImplementation,0,0},
      92             :         {"projectionpath", &OPTprojectionpathImplementation,0,0},
      93             :         {"pushselect", &OPTpushselectImplementation,0,0},
      94             :         {"querylog", &OPTquerylogImplementation,0,0},
      95             :         {"reduce", &OPTreduceImplementation,0,0},
      96             :         {"remap", &OPTremapImplementation,0,0},
      97             :         {"remoteQueries", &OPTremoteQueriesImplementation,0,0},
      98             :         {"reorder", &OPTreorderImplementation,0,0},
      99             :         {"volcano", &OPTvolcanoImplementation,0,0},
     100             :         {"wlc", &OPTwlcImplementation,0,0},
     101             :         {0,0,0,0}
     102             : };
     103             : int codehash[256];
     104             : 
     105             : static
     106         255 : void fillcodehash(void)
     107             : {
     108             :         int i, idx;
     109             :                 
     110       65535 :         for( i=0;  i< 256; i++)
     111       65280 :                 codehash[i] = -1;
     112        9180 :         for (i=0; codes[i].nme; i++){
     113        8925 :                 idx = (int) codes[i].nme[0];
     114        8925 :                 if( codehash[idx] == -1 ){
     115        3825 :                         codehash[idx] = i;
     116             :                 }
     117             :         }
     118         255 : }
     119             : 
     120    10522571 : str OPTwrapper (Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p){
     121             :         str modnme = "(NONE)";
     122             :         const char *fcnnme = "(NONE)";
     123             :         Symbol s= NULL;
     124             :         int i;
     125             :         str msg = MAL_SUCCEED;
     126             :         lng clk;
     127             : 
     128             :         // no optimizer starts with a null byte, initialization sets a zero
     129    10522571 :         if( codehash[0] != -1 || codehash[0] == 0)
     130         255 :                 fillcodehash();
     131    10522571 :         if (cntxt->mode == FINISHCLIENT)
     132           0 :                 throw(MAL, "optimizer", SQLSTATE(42000) "prematurely stopped client");
     133             : 
     134    10522571 :         if( p == NULL)
     135           0 :                 throw(MAL, "opt_wrapper", SQLSTATE(HY002) "missing optimizer statement");
     136             : 
     137    10522571 :         if( mb->errors)
     138           0 :                 throw(MAL, "opt_wrapper", SQLSTATE(42000) "MAL block contains errors");
     139    10522571 :         fcnnme = getFunctionId(p);
     140             : 
     141    10522571 :         if( p && p->argc > 1 ){
     142          87 :                 if( getArgType(mb,p,1) != TYPE_str ||
     143          87 :                         getArgType(mb,p,2) != TYPE_str ||
     144          87 :                         !isVarConstant(mb,getArg(p,1)) ||
     145          87 :                         !isVarConstant(mb,getArg(p,2))
     146             :                         )
     147           0 :                         throw(MAL, getFunctionId(p), SQLSTATE(42000) ILLARG_CONSTANTS);
     148             : 
     149          87 :                 if( stk != 0){
     150           0 :                         modnme= *getArgReference_str(stk,p,1);
     151           0 :                         fcnnme= *getArgReference_str(stk,p,2);
     152             :                 } else {
     153          87 :                         modnme= getArgDefault(mb,p,1);
     154          87 :                         fcnnme= getArgDefault(mb,p,2);
     155             :                 }
     156             :                 //removeInstruction(mb, p);
     157          87 :                 p->token = REMsymbol;
     158          87 :                 s= findSymbol(cntxt->usermodule, putName(modnme),putName(fcnnme));
     159             : 
     160          87 :                 if( s == NULL)
     161           0 :                         throw(MAL, getFunctionId(p), SQLSTATE(HY002) RUNTIME_OBJECT_UNDEFINED "%s.%s", modnme, fcnnme);
     162          87 :                 mb = s->def;
     163          87 :                 stk= 0;
     164             :         } else if( p ){
     165    10522484 :                 p->token = REMsymbol;
     166             :         }
     167             : 
     168    10522571 :         clk = GDKusec();
     169    10522581 :         const char *id = getFunctionId(p);
     170    23229716 :         for (i=codehash[*id]; codes[i].nme; i++){
     171    23229716 :                 if (codes[i].nme[0] == *id && strcmp(codes[i].nme, getFunctionId(p)) == 0){
     172    10522581 :                         msg = (str)(*(codes[i].fcn))(cntxt, mb, stk, p);
     173    10522577 :                         clk = GDKusec() - clk;
     174    10522578 :                         codes[i].timing += clk;
     175    10522578 :                         codes[i].calls++;
     176    10522578 :                         p= pushLng(mb, p, clk);
     177    10522570 :                         codes[i].calls++;
     178    10522570 :                         if (msg) {
     179           0 :                                 str newmsg = createException(MAL, getFunctionId(p), SQLSTATE(42000) "Error in optimizer %s: %s", getFunctionId(p), msg);
     180           0 :                                 freeException(msg);
     181           0 :                                 return newmsg;
     182             :                         }
     183    10522570 :                         addtoMalBlkHistory(mb);
     184    10522570 :                         break;
     185             :                 }
     186             :         }
     187    10522570 :         if (codes[i].nme == 0)
     188           0 :                 throw(MAL, fcnnme,  SQLSTATE(HY002) "Optimizer implementation '%s' missing", fcnnme);
     189             : 
     190    10522570 :         if ( mb->errors)
     191           0 :                 throw(MAL, fcnnme, SQLSTATE(42000) PROGRAM_GENERAL "%s.%s %s", modnme, fcnnme, mb->errors);
     192             :         return MAL_SUCCEED;
     193             : }
     194             : 
     195             : str
     196           0 : OPTstatistics(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p)
     197             : {
     198           0 :         bat  *nme = (bat*) getArgReference_bat(stk, p, 0);
     199           0 :         bat  *cnt = (bat*) getArgReference_bat(stk, p, 1);
     200           0 :         bat  *time = (bat*) getArgReference_bat(stk, p, 2);
     201             :         BAT *n, *c, *t;
     202             :         int i;
     203             : 
     204             :         (void) cntxt;
     205             :         (void) mb;
     206           0 :         n = COLnew(0, TYPE_str, 256, TRANSIENT);
     207           0 :         c = COLnew(0, TYPE_int, 256, TRANSIENT);
     208           0 :         t = COLnew(0, TYPE_lng, 256, TRANSIENT);
     209           0 :         if( n == NULL || c == NULL || t == NULL){
     210           0 :                 BBPreclaim(n);
     211           0 :                 BBPreclaim(c);
     212           0 :                 BBPreclaim(t);
     213           0 :                 throw(MAL,"optimizer.statistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     214             :         }
     215           0 :         for( i= 0; codes[i].nme; i++){
     216           0 :                 if (BUNappend(n, codes[i].nme, false) != GDK_SUCCEED ||
     217           0 :                         BUNappend(c, &codes[i].calls, false) != GDK_SUCCEED ||
     218           0 :                         BUNappend(t, &codes[i].timing, false) != GDK_SUCCEED) {
     219           0 :                         BBPreclaim(n);
     220           0 :                         BBPreclaim(c);
     221           0 :                         BBPreclaim(t);
     222           0 :                         throw(MAL,"optimizer.statistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     223             :                 }
     224             :         }
     225           0 :         BBPkeepref( *nme = n->batCacheid);
     226           0 :         BBPkeepref( *cnt = c->batCacheid);
     227           0 :         BBPkeepref( *time = t->batCacheid);
     228           0 :         return MAL_SUCCEED;
     229             : }

Generated by: LCOV version 1.14