LCOV - code coverage report
Current view: top level - monetdb5/optimizer - opt_wrapper.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 39 88 44.3 %
Date: 2024-10-04 20:04:04 Functions: 1 2 50.0 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : /*  author M.L. Kersten
      14             :  * The optimizer wrapper code is the interface to the MAL optimizer calls.
      15             :  *
      16             :  * Before an optimizer is finished, it should leave a clean state behind.
      17             :  * Moreover, some information of the optimization step is saved for
      18             :  * debugging and analysis.
      19             : */
      20             : 
      21             : #include "monetdb_config.h"
      22             : #include "mal_listing.h"
      23             : 
      24             : /*
      25             :  * The optimizer used so far
      26             : */
      27             : #include "opt_aliases.h"
      28             : #include "opt_coercion.h"
      29             : #include "opt_commonTerms.h"
      30             : #include "opt_candidates.h"
      31             : #include "opt_constants.h"
      32             : #include "opt_costModel.h"
      33             : #include "opt_dataflow.h"
      34             : #include "opt_deadcode.h"
      35             : #include "opt_emptybind.h"
      36             : #include "opt_evaluate.h"
      37             : #include "opt_garbageCollector.h"
      38             : #include "opt_generator.h"
      39             : #include "opt_inline.h"
      40             : #include "opt_projectionpath.h"
      41             : #include "opt_matpack.h"
      42             : #include "opt_postfix.h"
      43             : #include "opt_for.h"
      44             : #include "opt_dict.h"
      45             : #include "opt_mergetable.h"
      46             : #include "opt_mitosis.h"
      47             : #include "opt_multiplex.h"
      48             : #include "opt_profiler.h"
      49             : #include "opt_pushselect.h"
      50             : #include "opt_querylog.h"
      51             : #include "opt_reduce.h"
      52             : #include "opt_remap.h"
      53             : #include "opt_remoteQueries.h"
      54             : #include "opt_reorder.h"
      55             : #include "opt_fastpath.h"
      56             : #include "optimizer_private.h"
      57             : 
      58             : // keep the optimizer list sorted
      59             : static struct {
      60             :         str nme;
      61             :         str (*fcn)(Client, MalBlkPtr, MalStkPtr, InstrPtr);
      62             :         int calls;
      63             :         lng timing;
      64             : } codes[] = {
      65             :         {"aliases", &OPTaliasesImplementation, 0, 0},
      66             :         {"candidates", &OPTcandidatesImplementation, 0, 0},
      67             :         {"coercions", &OPTcoercionImplementation, 0, 0},
      68             :         {"commonTerms", &OPTcommonTermsImplementation, 0, 0},
      69             :         {"constants", &OPTconstantsImplementation, 0, 0},
      70             :         {"costModel", &OPTcostModelImplementation, 0, 0},
      71             :         {"dataflow", &OPTdataflowImplementation, 0, 0},
      72             :         {"deadcode", &OPTdeadcodeImplementation, 0, 0},
      73             :         {"defaultfast", &OPTdefaultfastImplementation, 0, 0},
      74             :         {"dict", &OPTdictImplementation, 0, 0},
      75             :         {"emptybind", &OPTemptybindImplementation, 0, 0},
      76             :         {"evaluate", &OPTevaluateImplementation, 0, 0},
      77             :         {"for", &OPTforImplementation, 0, 0},
      78             :         {"garbageCollector", &OPTgarbageCollectorImplementation, 0, 0},
      79             :         {"generator", &OPTgeneratorImplementation, 0, 0},
      80             :         {"inline", &OPTinlineImplementation, 0, 0},
      81             :         {"matpack", &OPTmatpackImplementation, 0, 0},
      82             :         {"mergetable", &OPTmergetableImplementation, 0, 0},
      83             :         {"minimalfast", &OPTminimalfastImplementation, 0, 0},
      84             :         {"mitosis", &OPTmitosisImplementation, 0, 0},
      85             :         {"multiplex", &OPTmultiplexImplementation, 0, 0},
      86             :         {"postfix", &OPTpostfixImplementation, 0, 0},
      87             :         {"profiler", &OPTprofilerImplementation, 0, 0},
      88             :         {"projectionpath", &OPTprojectionpathImplementation, 0, 0},
      89             :         {"pushselect", &OPTpushselectImplementation, 0, 0},
      90             :         {"querylog", &OPTquerylogImplementation, 0, 0},
      91             :         {"reduce", &OPTreduceImplementation, 0, 0},
      92             :         {"remap", &OPTremapImplementation, 0, 0},
      93             :         {"remoteQueries", &OPTremoteQueriesImplementation, 0, 0},
      94             :         {"reorder", &OPTreorderImplementation, 0, 0},
      95             :         {0, 0, 0, 0}
      96             : };
      97             : 
      98             : static MT_Lock codeslock = MT_LOCK_INITIALIZER(codeslock);
      99             : 
     100             : str
     101    13900885 : OPTwrapper(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p)
     102             : {
     103    13900885 :         str modnme = "optimizer";
     104    13900885 :         const char *fcnnme;
     105    13900885 :         Symbol s = NULL;
     106    13900885 :         int i;
     107    13900885 :         str msg = MAL_SUCCEED;
     108    13900885 :         lng clk;
     109             : 
     110             :         // no optimizer starts with a null byte, initialization sets a zero
     111    13900885 :         if (cntxt->mode == FINISHCLIENT)
     112           0 :                 throw(MAL, "optimizer", SQLSTATE(42000) "prematurely stopped client");
     113             : 
     114    13900885 :         if (p == NULL)
     115           0 :                 throw(MAL, "opt_wrapper",
     116             :                           SQLSTATE(HY002) "missing optimizer statement");
     117             : 
     118    13900885 :         if (mb->errors) {
     119           0 :                 msg = mb->errors;
     120           0 :                 mb->errors = NULL;
     121           0 :                 return msg;
     122             :         }
     123    13900885 :         fcnnme = getFunctionId(p);
     124             : 
     125    13900885 :         if (p && p->argc > 1) {
     126          87 :                 if (getArgType(mb, p, 1) != TYPE_str
     127          87 :                         || getArgType(mb, p, 2) != TYPE_str
     128          87 :                         || !isVarConstant(mb, getArg(p, 1))
     129          87 :                         || !isVarConstant(mb, getArg(p, 2)))
     130           0 :                         throw(MAL, getFunctionId(p), SQLSTATE(42000) ILLARG_CONSTANTS);
     131             : 
     132          87 :                 if (stk != NULL) {
     133           0 :                         modnme = *getArgReference_str(stk, p, 1);
     134           0 :                         fcnnme = *getArgReference_str(stk, p, 2);
     135             :                 } else {
     136          87 :                         modnme = getArgDefault(mb, p, 1);
     137          87 :                         fcnnme = getArgDefault(mb, p, 2);
     138             :                 }
     139             :                 //removeInstruction(mb, p);
     140          87 :                 p->token = REMsymbol;
     141          87 :                 s = findSymbol(cntxt->usermodule, putName(modnme), putName(fcnnme));
     142             : 
     143          87 :                 if (s == NULL)
     144           0 :                         throw(MAL, getFunctionId(p),
     145             :                                   SQLSTATE(HY002) RUNTIME_OBJECT_UNDEFINED "%s.%s", modnme,
     146             :                                   fcnnme);
     147          87 :                 mb = s->def;
     148          87 :                 stk = NULL;
     149    13900798 :         } else if (p) {
     150    13900798 :                 p->token = REMsymbol;
     151             :         }
     152             : 
     153    13900885 :         clk = GDKusec();
     154    13900924 :         const char *id = getFunctionId(p);
     155   184341774 :         for (i = 0; codes[i].nme != NULL; i++) {
     156   184342164 :                 if (strcmp(codes[i].nme, id) == 0) {
     157    13901314 :                         msg = (*codes[i].fcn) (cntxt, mb, stk, p);
     158    13900839 :                         clk = GDKusec() - clk;
     159    13900780 :                         MT_lock_set(&codeslock);
     160    13901547 :                         codes[i].timing += clk;
     161    13901547 :                         codes[i].calls++;
     162    13901547 :                         MT_lock_unset(&codeslock);
     163    13901545 :                         p = pushLng(mb, p, clk);
     164    13900812 :                         if (msg || mb->errors) {
     165             :                                 /* we can only return one or the other */
     166             :                                 if (msg)
     167           0 :                                         freeException(mb->errors);
     168             :                                 else
     169             :                                         msg = mb->errors;
     170           0 :                                 mb->errors = NULL;
     171           0 :                                 str newmsg = createException(MAL, getFunctionId(p),
     172             :                                                                                          SQLSTATE(42000)
     173             :                                                                                          "Error in optimizer %s: %s",
     174             :                                                                                          getFunctionId(p), msg);
     175           0 :                                 freeException(msg);
     176           0 :                                 return newmsg;
     177             :                         }
     178             :                         break;
     179             :                 }
     180             :         }
     181    13900422 :         if (codes[i].nme == 0)
     182           0 :                 throw(MAL, fcnnme,
     183             :                           SQLSTATE(HY002) "Optimizer implementation '%s' missing", fcnnme);
     184             : 
     185             :         return MAL_SUCCEED;
     186             : }
     187             : 
     188             : str
     189           0 : OPTstatistics(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p)
     190             : {
     191           0 :         bat *nme = getArgReference_bat(stk, p, 0);
     192           0 :         bat *cnt = getArgReference_bat(stk, p, 1);
     193           0 :         bat *time = getArgReference_bat(stk, p, 2);
     194           0 :         BAT *n, *c, *t;
     195           0 :         int i;
     196             : 
     197           0 :         (void) cntxt;
     198           0 :         (void) mb;
     199           0 :         n = COLnew(0, TYPE_str, 256, TRANSIENT);
     200           0 :         c = COLnew(0, TYPE_int, 256, TRANSIENT);
     201           0 :         t = COLnew(0, TYPE_lng, 256, TRANSIENT);
     202           0 :         if (n == NULL || c == NULL || t == NULL) {
     203           0 :                 BBPreclaim(n);
     204           0 :                 BBPreclaim(c);
     205           0 :                 BBPreclaim(t);
     206           0 :                 throw(MAL, "optimizer.statistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     207             :         }
     208           0 :         MT_lock_set(&codeslock);
     209           0 :         for (i = 0; codes[i].nme; i++) {
     210           0 :                 if (BUNappend(n, codes[i].nme, false) != GDK_SUCCEED
     211           0 :                         || BUNappend(c, &codes[i].calls, false) != GDK_SUCCEED
     212           0 :                         || BUNappend(t, &codes[i].timing, false) != GDK_SUCCEED) {
     213           0 :                         MT_lock_unset(&codeslock);
     214           0 :                         BBPreclaim(n);
     215           0 :                         BBPreclaim(c);
     216           0 :                         BBPreclaim(t);
     217           0 :                         throw(MAL, "optimizer.statistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     218             :                 }
     219             :         }
     220           0 :         MT_lock_unset(&codeslock);
     221           0 :         *nme = n->batCacheid;
     222           0 :         BBPkeepref(n);
     223           0 :         *cnt = c->batCacheid;
     224           0 :         BBPkeepref(c);
     225           0 :         *time = t->batCacheid;
     226           0 :         BBPkeepref(t);
     227           0 :         return MAL_SUCCEED;
     228             : }

Generated by: LCOV version 1.14