Changeset: 1e901f9db306 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/1e901f9db306 Modified Files: monetdb5/mal/mal_namespace.c monetdb5/mal/mal_namespace.h monetdb5/mal/mal_scenario.c monetdb5/mal/mal_scenario.h monetdb5/mal/mal_session.c monetdb5/mal/mal_session.h monetdb5/optimizer/opt_multiplex.c monetdb5/optimizer/opt_prelude.c monetdb5/optimizer/opt_prelude.h monetdb5/optimizer/opt_support.c monetdb5/optimizer/opt_support.h monetdb5/optimizer/optimizer.c sql/backends/monet5/sql_scenario.c Branch: simplify_scenario Log Message:
removed optimizer as a step in the scenario code diffs (truncated from 572 to 300 lines): diff --git a/monetdb5/mal/mal_namespace.c b/monetdb5/mal/mal_namespace.c --- a/monetdb5/mal/mal_namespace.c +++ b/monetdb5/mal/mal_namespace.c @@ -44,6 +44,8 @@ typedef struct NAME{ } *NamePtr; static NamePtr hash[MAXIDENTIFIERS]; +const char *optimizerRef; +const char *totalRef; static struct namespace { struct namespace *next; @@ -53,6 +55,8 @@ static struct namespace { void initNamespace(void) { namespace = NULL; + optimizerRef = putName("optimizer"); + totalRef = putName("total"); } void mal_namespace_reset(void) { diff --git a/monetdb5/mal/mal_namespace.h b/monetdb5/mal/mal_namespace.h --- a/monetdb5/mal/mal_namespace.h +++ b/monetdb5/mal/mal_namespace.h @@ -11,6 +11,9 @@ #ifndef _MAL_NAMESPACE_H #define _MAL_NAMESPACE_H +mal_export const char *optimizerRef; +mal_export const char *totalRef; + mal_export void initNamespace(void); mal_export const char *putName(const char *nme); mal_export const char *putNameLen(const char *nme, size_t len); diff --git a/monetdb5/mal/mal_scenario.c b/monetdb5/mal/mal_scenario.c --- a/monetdb5/mal/mal_scenario.c +++ b/monetdb5/mal/mal_scenario.c @@ -11,10 +11,10 @@ /* * (author) M. Kersten * @+ Session Scenarios - * In MonetDB multiple languages, optimizers, and execution engines can + * In MonetDB multiple languages and execution engines can * be combined at run time to satisfy a wide user-community. * Such an assemblage of components is called a @emph{scenario} - * and consists of a @emph{reader}, @emph{parser}, @emph{optimizer} + * and consists of a @emph{reader}, @emph{parser} * and @emph{engine}. These hooks allow * for both linked-in and external components. * @@ -33,15 +33,6 @@ * During this phase semantic checks are performed, such that * we end up with a type correct program. * - * The code block is subsequently sent to an MAL optimizer. - * In the default case the program is left untouched. For other languages, - * the optimizer deploys language specific code transformations, - * e.g., foreign-key optimizations in joins and remote query execution. - * All optimization information is statically derived from the - * code blocks and possible catalogues maintained for the query language - * at hand. Optimizers leave advice and their findings in properties - * in the symbol table, see @ref{Property Management}. - * * The final stage is to choose an execution paradigm, * i.e. interpretative (default), compilation of an ad-hoc user * defined function, dataflow driven interpretation, @@ -107,8 +98,6 @@ static struct SCENARIO scenarioRec[MAXSC .readerCmd = (MALfcn) MALreader, .parser = "MALparser", .parserCmd = (MALfcn) MALparser, - .optimizer = "MALoptimizer", - .optimizerCmd = NULL, .engine = "MALengine", .engineCmd = (MALfcn) MALengine, .callback = "MALcallback", @@ -172,7 +161,6 @@ showScenario(stream *f, Scenario scen) print_scenarioCommand(f, scen->initClient, scen->initClientCmd); print_scenarioCommand(f, scen->exitClient, scen->exitClientCmd); print_scenarioCommand(f, scen->parser, scen->parserCmd); - print_scenarioCommand(f, scen->optimizer, scen->optimizerCmd); print_scenarioCommand(f, scen->callback, scen->callbackCmd); print_scenarioCommand(f, scen->engine, scen->engineCmd); mnstr_printf(f, "]\n"); @@ -190,64 +178,6 @@ findScenario(str nme) return NULL; } -/* - * Functions may become resolved only after the corresponding module - * has been loaded. This should be announced as part of the module - * prelude code. - * Beware that after the update, we also have to adjust the client records. - * They contain a copy of the functions addresses. - */ -void -updateScenario(str nme, str fnme, MALfcn fcn) -{ - int phase = -1; - Scenario scen = findScenario(nme); - - if (scen == NULL) - return; - if (scen->initSystem && strcmp(scen->initSystem, fnme) == 0) - scen->initSystemCmd = fcn; - if (scen->exitSystem && strcmp(scen->exitSystem, fnme) == 0) - scen->exitSystemCmd = fcn; - if (scen->initClient && strcmp(scen->initClient, fnme) == 0) { - scen->initClientCmd = fcn; - phase = MAL_SCENARIO_INITCLIENT; - } - if (scen->exitClient && strcmp(scen->exitClient, fnme) == 0) { - scen->exitClientCmd = fcn; - phase = MAL_SCENARIO_EXITCLIENT; - } - if (scen->reader && strcmp(scen->reader, fnme) == 0) { - scen->readerCmd = fcn; - phase = MAL_SCENARIO_READER; - } - if (scen->parser && strcmp(scen->parser, fnme) == 0) { - scen->parserCmd = fcn; - phase = MAL_SCENARIO_PARSER; - } - if (scen->optimizer && strcmp(scen->optimizer, fnme) == 0) { - scen->optimizerCmd = fcn; - phase = MAL_SCENARIO_OPTIMIZE; - } - if (scen->callback && strcmp(scen->callback, fnme) == 0) { - scen->callbackCmd = fcn; - phase = MAL_SCENARIO_CALLBACK; - } - if (scen->engine && strcmp(scen->engine, fnme) == 0) { - scen->engineCmd = fcn; - phase = MAL_SCENARIO_ENGINE; - } - if (phase != -1) { - Client c1; - - for (c1 = mal_clients; c1 < mal_clients + MAL_MAXCLIENTS; c1++) { - if (c1->scenario && - strcmp(c1->scenario, scen->name) == 0) - c1->phase[phase] = fcn; - } - } -} - void showScenarioByName(stream *f, str nme) { @@ -291,7 +221,6 @@ fillScenario(Client c, Scenario scen) c->phase[MAL_SCENARIO_READER] = scen->readerCmd; c->phase[MAL_SCENARIO_PARSER] = scen->parserCmd; - c->phase[MAL_SCENARIO_OPTIMIZE] = scen->optimizerCmd; c->phase[MAL_SCENARIO_CALLBACK] = scen->callbackCmd; c->phase[MAL_SCENARIO_ENGINE] = scen->engineCmd; c->phase[MAL_SCENARIO_INITCLIENT] = scen->initClientCmd; @@ -375,9 +304,6 @@ resetScenario(Client c) * on the translation of language specific datastructures into their BAT * equivalent. * - * The @sc{xyzoptimizer(Client c)} contains language specific optimizations - * using the MAL intermediate code as a starting point. - * * The @sc{xyzengine(Client c)} contains the applicable back-end engine. * The default is the MAL interpreter, which provides good balance * between speed and ability to analysis its behavior. diff --git a/monetdb5/mal/mal_scenario.h b/monetdb5/mal/mal_scenario.h --- a/monetdb5/mal/mal_scenario.h +++ b/monetdb5/mal/mal_scenario.h @@ -45,8 +45,6 @@ typedef struct SCENARIO { MALfcn readerCmd; str parser; MALfcn parserCmd; - str optimizer; - MALfcn optimizerCmd; str engine; MALfcn engineCmd; str callback; @@ -67,7 +65,6 @@ extern void showScenario(stream *f, Scen extern void showAllScenarios(stream *f); extern void resetScenario(Client c); -extern void updateScenario(str scen, str nme, MALfcn fcn); #endif #endif /* _MAL_SCENARIO_H */ diff --git a/monetdb5/mal/mal_session.c b/monetdb5/mal/mal_session.c --- a/monetdb5/mal/mal_session.c +++ b/monetdb5/mal/mal_session.c @@ -768,12 +768,39 @@ MALcallback(Client c, str msg) return MAL_SUCCEED; } +/* + * The default MAL optimizer includes a final call to + * the multiplex expander. + * We should take care of functions marked as 'inline', + * because they should be kept in raw form. + * Their optimization takes place after inlining. + */ +static str +MALoptimizer(Client c) +{ + str msg; + + if ( c->curprg->def->inlineProp) + return MAL_SUCCEED; + // only a signature statement can be skipped + if (c ->curprg->def->stop == 1) + return MAL_SUCCEED; + msg= optimizeMALBlock(c, c->curprg->def); + /* + if( msg == MAL_SUCCEED) + msg = OPTmultiplexSimple(c, c->curprg->def); + */ + return msg; +} + str MALengine(Client c) { Symbol prg; str msg = MAL_SUCCEED; + if ((msg = MALoptimizer(c)) != MAL_SUCCEED) + return msg; if (c->blkmode) return MAL_SUCCEED; prg = c->curprg; @@ -831,3 +858,92 @@ MALengine(Client c) prg->def->errors = NULL; return msg; } + +/* Hypothetical, optimizers may massage the plan in such a way + * that multiple passes are needed. + * However, the current SQL driven approach only expects a single + * non-repeating pipeline of optimizer steps stored at the end of the MAL block. + * A single scan forward over the MAL plan is assumed. + */ +str +optimizeMALBlock(Client cntxt, MalBlkPtr mb) +{ + InstrPtr p; + int pc, oldstop; + str msg = MAL_SUCCEED; + int cnt = 0; + int actions = 0; + lng clk = GDKusec(); + + /* assume the type and flow have been checked already */ + /* SQL functions intended to be inlined should not be optimized */ + if ( mb->inlineProp) + return 0; + + mb->optimize = 0; + if (mb->errors) + throw(MAL, "optimizer.MALoptimizer", SQLSTATE(42000) "Start with inconsistent MAL plan"); + + // strong defense line, assure that MAL plan is initially correct + if( mb->errors == 0 && mb->stop > 1){ + resetMalTypes(mb, mb->stop); + msg = chkTypes(cntxt->usermodule, mb, FALSE); + if (!msg) + msg = chkFlow(mb); + if (!msg) + msg = chkDeclarations(mb); + if (msg) + return msg; + if (mb->errors != MAL_SUCCEED){ + msg = mb->errors; + mb->errors = MAL_SUCCEED; + return msg; + } + } + + oldstop = mb->stop; + for (pc = 0; pc < mb->stop; pc++) { + p = getInstrPtr(mb, pc); + if (getModuleId(p) == optimizerRef && p->fcn && p->token != REMsymbol) { + actions++; + msg = (str) (*p->fcn) (cntxt, mb, 0, p); + if (msg) { + str place = getExceptionPlace(msg); + str nmsg = NULL; + if (place){ + nmsg = createException(getExceptionType(msg), place, "%s", getExceptionMessageAndState(msg)); + GDKfree(place); + } + if (nmsg ) { + freeException(msg); + msg = nmsg; + } + goto wrapup; + } + if (cntxt->mode == FINISHCLIENT){ + mb->optimize = GDKusec() - clk; + throw(MAL, "optimizeMALBlock", SQLSTATE(42000) "prematurely stopped client"); + } + /* the MAL block may have changed */ _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org