str QOTshowFlowGraph(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { str fname; str modnme; str fcnnme; Symbol s = NULL; (void) cntxt; if (stk != 0) { modnme = *getArgReference_str(stk, p, 1); fcnnme = *getArgReference_str(stk, p, 2); fname = *getArgReference_str(stk, p, 3); } else { modnme = getArgDefault(mb, p, 1); fcnnme = getArgDefault(mb, p, 2); fname = getArgDefault(mb, p, 3); } s = findSymbol(cntxt->nspace,putName(modnme, strlen(modnme)), putName(fcnnme, strlen(fcnnme))); if (s == NULL) { char buf[1024]; snprintf(buf,1024, "%s.%s", modnme, fcnnme); throw(MAL, "optimizer.showFlowGraph", RUNTIME_OBJECT_UNDEFINED ":%s", buf); } showFlowGraph(s->def, stk, fname); return MAL_SUCCEED; }
/* * Display routines */ str MDBlifespan(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { Lifespan span; str modnme; str fcnnme; Symbol s = NULL; (void) cntxt; if (stk != 0) { modnme = *getArgReference_str(stk, p, 1); fcnnme = *getArgReference_str(stk, p, 2); } else { modnme = getArgDefault(mb, p, 1); fcnnme = getArgDefault(mb, p, 2); } s = findSymbol(cntxt->nspace, putName(modnme), putName(fcnnme)); if (s == NULL) throw(MAL, "mdb.inspect", RUNTIME_SIGNATURE_MISSING); span = setLifespan(s->def); if( span == NULL) throw(MAL,"mdb.inspect", MAL_MALLOC_FAIL); debugLifespan(cntxt, s->def, span); GDKfree(span); (void) p; (void) stk; return MAL_SUCCEED; }
str QOTshowPlan(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { str modnme; str fcnnme; Symbol s = NULL; if (stk != 0) { modnme = *getArgReference_str(stk, p, 1); fcnnme = *getArgReference_str(stk, p, 2); } else { modnme = getArgDefault(mb, p, 1); fcnnme = getArgDefault(mb, p, 2); } mnstr_printf(cntxt->fdout,"#showPlan()\n"); removeInstruction(mb, p); if( modnme ) { s = findSymbol(cntxt->nspace, putName(modnme, strlen(modnme)), putName(fcnnme, strlen(fcnnme))); if (s == NULL) { char buf[1024]; snprintf(buf,1024, "%s.%s", modnme, fcnnme); throw(MAL, "optimizer.showPlan", RUNTIME_OBJECT_UNDEFINED ":%s", buf); } mb= s->def; } printFunction(cntxt->fdout, mb, 0, LIST_INPUT); return MAL_SUCCEED; }
str OPTsql_append(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p){ str modnme; str fcnnme; str msg= MAL_SUCCEED; Symbol s= NULL; lng t,clk= GDKusec(); int actions = 0; if( p ) removeInstruction(mb, p); OPTDEBUGsql_append mnstr_printf(cntxt->fdout,"=APPLY OPTIMIZER sql_append\n"); if( p && p->argc > 1 ){ if( getArgType(mb,p,1) != TYPE_str || getArgType(mb,p,2) != TYPE_str || !isVarConstant(mb,getArg(p,1)) || !isVarConstant(mb,getArg(p,2)) ) { throw(MAL, "optimizer.sql_append", ILLARG_CONSTANTS); } if( stk != 0){ modnme= *getArgReference_str(stk,p,1); fcnnme= *getArgReference_str(stk,p,2); } else { modnme= getArgDefault(mb,p,1); fcnnme= getArgDefault(mb,p,2); } s= findSymbol(cntxt->nspace, putName(modnme,strlen(modnme)),putName(fcnnme,strlen(fcnnme))); if( s == NULL) { char buf[1024]; snprintf(buf,1024, "%s.%s",modnme,fcnnme); throw(MAL, "optimizer.sql_append", RUNTIME_OBJECT_UNDEFINED ":%s", buf); } mb = s->def; stk= 0; } if( mb->errors ){ /* when we have errors, we still want to see them */ addtoMalBlkHistory(mb,"sql_append"); return MAL_SUCCEED; } actions= OPTsql_appendImplementation(cntxt, mb,stk,p); msg= optimizerCheck(cntxt, mb, "optimizer.sql_append", actions, t=(GDKusec() - clk)); OPTDEBUGsql_append { mnstr_printf(cntxt->fdout,"=FINISHED sql_append %d\n",actions); printFunction(cntxt->fdout,mb,0,LIST_MAL_ALL ); } DEBUGoptimizers mnstr_printf(cntxt->fdout,"#opt_reduce: " LLFMT " ms\n",t); QOTupdateStatistics("sql_append",actions,t); addtoMalBlkHistory(mb,"sql_append"); return msg; }
str MDBvar3(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { str modnme = *getArgReference_str(stk, p, 1); str fcnnme = *getArgReference_str(stk, p, 2); Symbol s = NULL; s = findSymbol(cntxt->nspace, putName(modnme), putName(fcnnme)); if (s == NULL) throw(MAL,"mdb.var","Could not find %s.%s", modnme, fcnnme); printStack(cntxt->fdout, s->def, (s->def == mb ? stk : 0)); (void) mb; return NULL; }
str MDBlist3Detail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { str modnme = *getArgReference_str(stk, p, 1); str fcnnme = *getArgReference_str(stk, p, 2); Symbol s = NULL; s = findSymbol(cntxt->nspace, putName(modnme), putName(fcnnme)); if (s == NULL) throw(MAL,"mdb.list","Could not find %s.%s", modnme, fcnnme); debugFunction(cntxt->fdout, s->def, 0, LIST_MAL_NAME | LIST_MAL_VALUE | LIST_MAL_TYPE | LIST_MAL_PROPS , 0, s->def->stop); (void) mb; /* fool compiler */ return NULL; }
str MDBlist3(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { str modnme = *getArgReference_str(stk, p, 1); str fcnnme = *getArgReference_str(stk, p, 2); Symbol s = NULL; s = findSymbol(cntxt->nspace, putName(modnme), putName(fcnnme)); if (s == NULL) throw(MAL,"mdb.list","Could not find %s.%s", modnme, fcnnme); printFunction(cntxt->fdout, s->def, 0, LIST_MAL_NAME ); (void) mb; /* fool compiler */ return MAL_SUCCEED; }
str FCTshutdown(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { str mod = *getArgReference_str(stk, pci, 1); str fcn = *getArgReference_str(stk, pci, 2); Symbol s; (void) mb; s = findSymbol(cntxt->nspace, putName(mod), putName(fcn)); if (s == NULL) throw(MAL, "factories.shutdown", RUNTIME_OBJECT_MISSING); shutdownFactory(cntxt,s->def); return MAL_SUCCEED; }
str OPTorcam(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p){ Symbol t; str msg,mod,fcn; lng clk= GDKusec(); int actions = 0; if( p ==NULL ) return 0; removeInstruction(mb, p); if( p->argc == 3){ mod= getArgDefault(mb,p,1); fcn= getArgDefault(mb,p,2); } else { mod= getArgDefault(mb,p,3); fcn= getArgDefault(mb,p,4); } t= findSymbol(cntxt->nspace, putName(mod, strlen(mod)), fcn); if( t == 0) return 0; msg = MACROvalidate(t->def); if( msg) return msg; if( mb->errors == 0) actions= OPTorcamImplementation(cntxt,mb,stk,p); return optimizerCheck(cntxt,mb, "optimizer.orcam", actions, GDKusec() - clk, OPT_CHECK_ALL); }
/* * The MonetDB server uses a startup script to boot the system. * This script is an ordinary MAL program, but will mostly * consist of include statements to load modules of general interest. * The startup script is run as user Admin. */ int malBootstrap(void) { Client c; str msg, bootfile = "mal_init", s; c = MCinitClient((oid) 0, 0, 0); assert(c != NULL); c->nspace = newModule(NULL, putName("user", 4)); initLibraries(); if ( (msg = defaultScenario(c)) ) { GDKfree(msg); GDKerror("Failed to initialise default scenario"); return 0; } MSinitClientPrg(c, "user", "main"); (void) MCinitClientThread(c); s = malInclude(c, bootfile, 0); if (s != NULL) { mnstr_printf(GDKout, "!%s\n", s); GDKfree(s); return 0; } pushEndInstruction(c->curprg->def); chkProgram(c->fdout, c->nspace, c->curprg->def); if (c->curprg->def->errors) showErrors(c); s = MALengine(c); if (s) GDKfree(s); return 1; }
str shutdownFactoryByName(Client cntxt, Module m, str nme){ Plant pl, plim; InstrPtr p; Symbol s; plim = plants + lastPlant; for (pl = plants; pl < plim; pl++) if (pl->factory ) { MalStkPtr stk; p= getInstrPtr(pl->factory,0); if( strcmp(nme, getFunctionId(p)) != 0) continue; s = findSymbolInModule(m, nme ); if (s == NULL){ throw(MAL, "factory.remove", OPERATION_FAILED " SQL entry '%s' not found", putName(nme)); } stk = pl->stk; MSresetVariables(cntxt, pl->factory, stk, 0); shutdownFactory(cntxt, pl->factory); freeStack(stk); deleteSymbol(m,s); return MAL_SUCCEED; } return MAL_SUCCEED; }
/* * Forking is a relatively cheap way to create a new client. The new * client record shares the IO descriptors. To avoid interference, we * limit children to only produce output by closing the input-side. * * If the father itself is a temporary client, let the new child depend * on the grandfather. */ Client MCforkClient(Client father) { Client son = NULL; if (father == NULL) return NULL; if (father->father != NULL) father = father->father; if ((son = MCinitClient(father->user, father->fdin, father->fdout))) { son->fdin = NULL; son->fdout = father->fdout; son->bak = NULL; son->yycur = 0; son->father = father; son->scenario = father->scenario; if (son->prompt) GDKfree(son->prompt); son->prompt = GDKstrdup(father->prompt); son->promptlength = strlen(father->prompt); /* reuse the scopes wherever possible */ if (son->nspace == 0) son->nspace = newModule(NULL, putName("child", 5)); son->nspace->outer = father->nspace->outer; } return son; }
static int isNewSource(InstrPtr p) { str mp= getModuleId(p); if( mp == sqlRef && getFunctionId(p) == bindRef) return 1; if( mp == calcRef) return 1; if( mp == batcalcRef) return 1; if( mp == strRef) return 1; if( mp == batstrRef) return 1; if( mp == putName("array",5)) return 1; if( mp == putName("url",3)) return 1; if( mp == putName("daytime",7)) return 1; if( mp == putName("day",3)) return 1; if( mp == putName("date",4)) return 1; if( mp == putName("time",4)) return 1; if( mp == putName("tzone",5)) return 1; if( mp == putName("color",4)) return 1; if( mp == putName("batcolor",8)) return 1; if( mp == putName("blob",4)) return 1; return 0; }
int OPTorcamImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { MalBlkPtr target= mb; Module s; Symbol t; str mod,fcn; int j; str msg; (void) cntxt; (void) stk; if( p->argc == 3){ mod= getArgDefault(mb,p,1); fcn= getArgDefault(mb,p,2); } else { mod= getArgDefault(mb,p,1); fcn= getArgDefault(mb,p,2); t= findSymbol(cntxt->nspace, putName(mod, strlen(mod)), fcn); if( t == 0) return 0; target= t->def; mod= getArgDefault(mb,p,3); fcn= getArgDefault(mb,p,4); } s = findModule(cntxt->nspace, putName(mod, strlen(mod))); if (s == 0) return 0; if (s->subscope) { j = getSubScope(fcn); for (t = s->subscope[j]; t != NULL; t = t->peer) if (t->def->errors == 0) { if (getSignature(t)->token == FUNCTIONsymbol) { msg =ORCAMprocessor(cntxt, target, t); if( msg) GDKfree(msg); } } } return 1; }
void MSinitClientPrg(Client cntxt, str mod, str nme) { InstrPtr p; MalBlkPtr mb; if (cntxt->curprg && idcmp(nme, cntxt->curprg->name) == 0) { MSresetClientPrg(cntxt); return; } cntxt->curprg = newFunction(putName("user", 4), putName(nme, strlen(nme)), FUNCTIONsymbol); mb = cntxt->curprg->def; p = getSignature(cntxt->curprg); if (mod) setModuleId(p, mod); else setModuleScope(p, cntxt->nspace); setVarType(mb, findVariable(mb, nme), TYPE_void); insertSymbol(cntxt->nspace, cntxt->curprg); cntxt->glb = 0; assert(cntxt->curprg->def != NULL); }
str MDBshowFlowGraph(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { str fname; str modnme; str fcnnme; Symbol s = NULL; (void)cntxt; if (stk != 0) { if (p->argc == 2) { modnme = fcnnme = NULL; fname = *getArgReference_str(stk, p, 1); } else { modnme = *getArgReference_str(stk, p, 1); fcnnme = *getArgReference_str(stk, p, 2); fname = *getArgReference_str(stk, p, 3); } } else { modnme = getArgDefault(mb, p, 1); fcnnme = getArgDefault(mb, p, 2); fname = getArgDefault(mb, p, 3); } if (modnme != NULL) { s = findSymbol(cntxt->nspace, putName(modnme), putName(fcnnme)); if (s == NULL) { char buf[1024]; snprintf(buf,1024, "Could not find %s.%s\n", modnme, fcnnme); throw(MAL, "mdb.dot", "%s", buf); } showFlowGraph(s->def, stk, fname); } else { showFlowGraph(mb, stk, fname); } return MAL_SUCCEED; }
str MDBinspect(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { str modnme; str fcnnme; Symbol s = NULL; (void) cntxt; if (stk != 0) { modnme = *getArgReference_str(stk, p, 1); fcnnme = *getArgReference_str(stk, p, 2); } else { modnme = getArgDefault(mb, p, 1); fcnnme = getArgDefault(mb, p, 2); } s = findSymbol(cntxt->nspace, putName(modnme), putName(fcnnme)); if (s == NULL) throw(MAL, "mdb.inspect", RUNTIME_SIGNATURE_MISSING); return runMALDebugger(cntxt, s); }
str RUNinline(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { Symbol qc; str modnme = getVarConstant(mb, getArg(p, 1)).val.sval; str fcnnme = getVarConstant(mb, getArg(p, 2)).val.sval; (void) stk; (void) p; qc = findSymbol(cntxt ->nspace, getName(modnme), putName(fcnnme)); if (qc) MACROprocessor(cntxt, mb, qc); return MAL_SUCCEED; }
/* Every client record has a private module name 'user' * for keeping around non-shared functions */ Module userModule(void){ Module cur; cur = (Module) GDKzalloc(sizeof(ModuleRecord)); if (cur == NULL) return NULL; cur->name = putName("user"); cur->link = NULL; cur->space = NULL; cur->isAtomModule = FALSE; cur->space = (Symbol *) GDKzalloc(MAXSCOPE * sizeof(Symbol)); if (cur->space == NULL) { GDKfree(cur); return NULL; } return cur; }
int OPTmatpackImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { int v, i, j, limit, slimit; InstrPtr p,q; int actions = 0; InstrPtr *old; char *packIncrementRef = putName("packIncrement", 13); (void) pci; (void) cntxt; (void) stk; /* to fool compilers */ old= mb->stmt; limit= mb->stop; slimit = mb->ssize; if ( newMalBlkStmt(mb,mb->stop) < 0) return 0; for (i = 0; i < limit; i++) { p = old[i]; if( getModuleId(p) == matRef && getFunctionId(p) == packRef && isaBatType(getArgType(mb,p,1))) { q = newStmt(mb, matRef, packIncrementRef); v = getArg(q,0); setVarType(mb,v,getArgType(mb,p,1)); q = pushArgument(mb, q, getArg(p,1)); q = pushInt(mb,q, p->argc - p->retc); for ( j = 2; j < p->argc; j++) { q = newStmt(mb,matRef, packIncrementRef); q = pushArgument(mb, q, v); q = pushArgument(mb, q, getArg(p,j)); setVarType(mb,getArg(q,0),getVarType(mb,v)); v = getArg(q,0); } getArg(q,0) = getArg(p,0); freeInstruction(p); continue; } pushInstruction(mb,p); } for(; i<slimit; i++) if (old[i]) freeInstruction(old[i]); GDKfree(old); return actions; }
static void propagateNonTarget(MalBlkPtr mb, int pc) { int i; InstrPtr p; str scheduler = putName("scheduler", 9); for (; pc < mb->stop; pc++) { p = getInstrPtr(mb, pc); if (getModuleId(p) == scheduler) continue; for (i = 0; i < p->argc; i++) if (isVarDisabled(mb, getArg(p, i)) && p->token >= 0) p->token = -p->token; /* temporary NOOP */ if (p->token < 0) for (i = 0; i < p->retc; i++) setVarDisabled(mb, getArg(p, i)); } }
void KmlGenerator::putKmlHeader() { time_t t = time(0); std::tm *now = localtime(&t); startKml(); skipLine(); putComment("====================================================================================================================="); putComment("This file was generated automatically with real meteorological data and is part of the Ensimag visualization project."); putComment("====================================================================================================================="); skipLine(); startDocument("Root"); putName("Environemental contaminant viewer"); putDescription("PM10 particles"); putDate(*now, YYYY_MM_DD_hh_mm_ss); putAuthor("Jean-Baptiste Keck"); putAuthor("Alexandre Ribard"); skipLine(); putVisibility(true); putOpen(true); skipLine(); }
str QOToptimize(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { str modnme; str fcnnme; Symbol s; (void) stk; if (stk != 0) { modnme = *getArgReference_str(stk, pci, 1); fcnnme = *getArgReference_str(stk, pci, 2); } else { modnme = getArgDefault(mb, pci, 1); fcnnme = getArgDefault(mb, pci, 2); } s = findSymbol(cntxt->usermodule, putName(modnme), fcnnme); if (s == NULL) throw(MAL, "optimizer.optimize", SQLSTATE(HY002) SEMANTIC_OPERATION_MISSING); removeInstruction(mb, pci); addtoMalBlkHistory(s->def); return optimizeMALBlock(cntxt, s->def); }
/* * Module scope management * It will contain the symbol table of all globally accessible functions. */ Module globalModule(str nme) { Module cur; // Global modules are not named 'user' assert (strcmp(nme, "user")); #ifdef _DEBUG_MODULE_ fprintf(stderr,"#create new global module %s\n",nme); #endif nme = putName(nme); cur = (Module) GDKzalloc(sizeof(ModuleRecord)); if (cur == NULL) return NULL; cur->name = nme; cur->link = NULL; cur->isAtomModule = FALSE; cur->space = (Symbol *) GDKzalloc(MAXSCOPE * sizeof(Symbol)); if (cur->space == NULL) { GDKfree(cur); return NULL; } addModuleToIndex(cur); return cur; }
/* * The trace operation collects the events in the BATs * and creates a secondary result set upon termination * of the query. */ static void SQLsetTrace(backend *be, Client cntxt, bit onoff) { InstrPtr q, resultset; InstrPtr tbls, cols, types, clen, scale; MalBlkPtr mb = cntxt->curprg->def; int k; (void) be; if (onoff) { (void) newStmt(mb, "profiler", "start"); initTrace(); } else { (void) newStmt(mb, "profiler", "stop"); /* cook a new resultSet instruction */ resultset = newInstruction(mb,ASSIGNsymbol); setModuleId(resultset, sqlRef); setFunctionId(resultset, resultSetRef); getArg(resultset,0)= newTmpVariable(mb,TYPE_int); /* build table defs */ tbls = newStmt(mb,batRef, newRef); setVarType(mb, getArg(tbls,0), newBatType(TYPE_oid, TYPE_str)); tbls = pushType(mb, tbls, TYPE_oid); tbls = pushType(mb, tbls, TYPE_str); resultset= pushArgument(mb,resultset, getArg(tbls,0)); q= newStmt(mb,batRef,appendRef); q= pushArgument(mb,q,getArg(tbls,0)); q= pushStr(mb,q,".trace"); k= getArg(q,0); q= newStmt(mb,batRef,appendRef); q= pushArgument(mb,q,k); q= pushStr(mb,q,".trace"); /* build colum defs */ cols = newStmt(mb,batRef, newRef); setVarType(mb, getArg(cols,0), newBatType(TYPE_oid, TYPE_str)); cols = pushType(mb, cols, TYPE_oid); cols = pushType(mb, cols, TYPE_str); resultset= pushArgument(mb,resultset, getArg(cols,0)); q= newStmt(mb,batRef,appendRef); q= pushArgument(mb,q,getArg(cols,0)); q= pushStr(mb,q,"usec"); k= getArg(q,0); q= newStmt(mb,batRef,appendRef); q= pushArgument(mb,q, getArg(cols,0)); q= pushStr(mb,q,"statement"); /* build type defs */ types = newStmt(mb,batRef, newRef); setVarType(mb, getArg(types,0), newBatType(TYPE_oid, TYPE_str)); types = pushType(mb, types, TYPE_oid); types = pushType(mb, types, TYPE_str); resultset= pushArgument(mb,resultset, getArg(types,0)); q= newStmt(mb,batRef,appendRef); q= pushArgument(mb,q, getArg(types,0)); q= pushStr(mb,q,"bigint"); k= getArg(q,0); q= newStmt(mb,batRef,appendRef); q= pushArgument(mb,q, k); q= pushStr(mb,q,"clob"); /* build scale defs */ clen = newStmt(mb,batRef, newRef); setVarType(mb, getArg(clen,0), newBatType(TYPE_oid, TYPE_int)); clen = pushType(mb, clen, TYPE_oid); clen = pushType(mb, clen, TYPE_int); resultset= pushArgument(mb,resultset, getArg(clen,0)); q= newStmt(mb,batRef,appendRef); q= pushArgument(mb,q, getArg(clen,0)); q= pushInt(mb,q,64); k= getArg(q,0); q= newStmt(mb,batRef,appendRef); q= pushArgument(mb,q, k); q= pushInt(mb,q,0); /* build scale defs */ scale = newStmt(mb,batRef, newRef); setVarType(mb, getArg(scale,0), newBatType(TYPE_oid, TYPE_int)); scale = pushType(mb, scale, TYPE_oid); scale = pushType(mb, scale, TYPE_int); resultset= pushArgument(mb,resultset, getArg(scale,0)); q= newStmt(mb,batRef,appendRef); q= pushArgument(mb,q, getArg(scale,0)); q= pushInt(mb,q,0); k= getArg(q,0); q= newStmt(mb,batRef,appendRef); q= pushArgument(mb, q, k); q= pushInt(mb,q,0); /* add the ticks column */ q = newStmt(mb, profilerRef, "getTrace"); q = pushStr(mb, q, putName("usec",4)); resultset= pushArgument(mb,resultset, getArg(q,0)); /* add the stmt column */ q = newStmt(mb, profilerRef, "getTrace"); q = pushStr(mb, q, putName("stmt",4)); resultset= pushArgument(mb,resultset, getArg(q,0)); pushInstruction(mb,resultset); } }
str SQLparser(Client c) { bstream *in = c->fdin; stream *out = c->fdout; str msg = NULL; backend *be; mvc *m; int oldvtop, oldstop; int pstatus = 0; int err = 0, opt = 0; be = (backend *) c->sqlcontext; if (be == 0) { /* tell the client */ mnstr_printf(out, "!SQL state descriptor missing, aborting\n"); mnstr_flush(out); /* leave a message in the log */ fprintf(stderr, "SQL state descriptor missing, cannot handle client!\n"); /* stop here, instead of printing the exception below to the * client in an endless loop */ c->mode = FINISHCLIENT; throw(SQL, "SQLparser", "State descriptor missing"); } oldvtop = c->curprg->def->vtop; oldstop = c->curprg->def->stop; be->vtop = oldvtop; #ifdef _SQL_PARSER_DEBUG mnstr_printf(GDKout, "#SQL compilation \n"); printf("debugger? %d(%d)\n", (int) be->mvc->emode, (int) be->mvc->emod); #endif m = be->mvc; m->type = Q_PARSE; SQLtrans(m); pstatus = m->session->status; /* sqlparse needs sql allocator to be available. It can be NULL at * this point if this is a recursive call. */ if (!m->sa) m->sa = sa_create(); m->emode = m_normal; m->emod = mod_none; if (be->language == 'X') { int n = 0, v, off, len; if (strncmp(in->buf + in->pos, "export ", 7) == 0) n = sscanf(in->buf + in->pos + 7, "%d %d %d", &v, &off, &len); if (n == 2 || n == 3) { mvc_export_chunk(be, out, v, off, n == 3 ? len : m->reply_size); in->pos = in->len; /* HACK: should use parsed length */ return MAL_SUCCEED; } if (strncmp(in->buf + in->pos, "close ", 6) == 0) { res_table *t; v = (int) strtol(in->buf + in->pos + 6, NULL, 0); t = res_tables_find(m->results, v); if (t) m->results = res_tables_remove(m->results, t); in->pos = in->len; /* HACK: should use parsed length */ return MAL_SUCCEED; } if (strncmp(in->buf + in->pos, "release ", 8) == 0) { cq *q = NULL; v = (int) strtol(in->buf + in->pos + 8, NULL, 0); if ((q = qc_find(m->qc, v)) != NULL) qc_delete(m->qc, q); in->pos = in->len; /* HACK: should use parsed length */ return MAL_SUCCEED; } if (strncmp(in->buf + in->pos, "auto_commit ", 12) == 0) { int commit; v = (int) strtol(in->buf + in->pos + 12, NULL, 10); commit = (!m->session->auto_commit && v); m->session->auto_commit = (v) != 0; m->session->ac_on_commit = m->session->auto_commit; if (m->session->active) { if (commit && mvc_commit(m, 0, NULL) < 0) { mnstr_printf(out, "!COMMIT: commit failed while " "enabling auto_commit\n"); msg = createException(SQL, "SQLparser", "Xauto_commit (commit) failed"); } else if (!commit && mvc_rollback(m, 0, NULL) < 0) { RECYCLEdrop(0); mnstr_printf(out, "!COMMIT: rollback failed while " "disabling auto_commit\n"); msg = createException(SQL, "SQLparser", "Xauto_commit (rollback) failed"); } } in->pos = in->len; /* HACK: should use parsed length */ if (msg != NULL) goto finalize; return MAL_SUCCEED; } if (strncmp(in->buf + in->pos, "reply_size ", 11) == 0) { v = (int) strtol(in->buf + in->pos + 11, NULL, 10); if (v < -1) { msg = createException(SQL, "SQLparser", "reply_size cannot be negative"); goto finalize; } m->reply_size = v; in->pos = in->len; /* HACK: should use parsed length */ return MAL_SUCCEED; } if (strncmp(in->buf + in->pos, "sizeheader", 10) == 0) { v = (int) strtol(in->buf + in->pos + 10, NULL, 10); m->sizeheader = v != 0; in->pos = in->len; /* HACK: should use parsed length */ return MAL_SUCCEED; } if (strncmp(in->buf + in->pos, "quit", 4) == 0) { c->mode = FINISHCLIENT; return MAL_SUCCEED; } mnstr_printf(out, "!unrecognized X command: %s\n", in->buf + in->pos); msg = createException(SQL, "SQLparser", "unrecognized X command"); goto finalize; } if (be->language !='S') { mnstr_printf(out, "!unrecognized language prefix: %ci\n", be->language); msg = createException(SQL, "SQLparser", "unrecognized language prefix: %c", be->language); goto finalize; } if ((err = sqlparse(m)) || /* Only forget old errors on transaction boundaries */ (mvc_status(m) && m->type != Q_TRANS) || !m->sym) { if (!err &&m->scanner.started) /* repeat old errors, with a parsed query */ err = mvc_status(m); if (err) { msg = createException(PARSE, "SQLparser", "%s", m->errstr); handle_error(m, c->fdout, pstatus); } sqlcleanup(m, err); goto finalize; } assert(m->session->schema != NULL); /* * We have dealt with the first parsing step and advanced the input reader * to the next statement (if any). * Now is the time to also perform the semantic analysis, optimize and * produce code. */ be->q = NULL; if (m->emode == m_execute) { assert(m->sym->data.lval->h->type == type_int); be->q = qc_find(m->qc, m->sym->data.lval->h->data.i_val); if (!be->q) { err = -1; mnstr_printf(out, "!07003!EXEC: no prepared statement with id: %d\n", m->sym->data.lval->h->data.i_val); msg = createException(SQL, "PREPARE", "no prepared statement with id: %d", m->sym->data.lval->h->data.i_val); handle_error(m, c->fdout, pstatus); sqlcleanup(m, err); goto finalize; } else if (be->q->type != Q_PREPARE) { err = -1; mnstr_printf(out, "!07005!EXEC: given handle id is not for a " "prepared statement: %d\n", m->sym->data.lval->h->data.i_val); msg = createException(SQL, "PREPARE", "is not a prepared statement: %d", m->sym->data.lval->h->data.i_val); handle_error(m, c->fdout, pstatus); sqlcleanup(m, err); goto finalize; } m->emode = m_inplace; scanner_query_processed(&(m->scanner)); } else if (caching(m) && cachable(m, NULL) && m->emode != m_prepare && (be->q = qc_match(m->qc, m->sym, m->args, m->argc, m->scanner.key ^ m->session->schema->base.id)) != NULL) { // look for outdated plans if ( OPTmitosisPlanOverdue(c, be->q->name) ){ msg = SQLCacheRemove(c, be->q->name); qc_delete(be->mvc->qc, be->q); goto recompilequery; } if (m->emod & mod_debug) SQLsetDebugger(c, m, TRUE); if (m->emod & mod_trace) SQLsetTrace(be, c, TRUE); if (!(m->emod & (mod_explain | mod_debug | mod_trace | mod_dot))) m->emode = m_inplace; scanner_query_processed(&(m->scanner)); } else { sql_rel *r; stmt *s; recompilequery: r = sql_symbol2relation(m, m->sym); s = sql_relation2stmt(m, r); if (s == 0 || (err = mvc_status(m) && m->type != Q_TRANS)) { msg = createException(PARSE, "SQLparser", "%s", m->errstr); handle_error(m, c->fdout, pstatus); sqlcleanup(m, err); goto finalize; } assert(s); /* generate the MAL code */ if (m->emod & mod_trace) SQLsetTrace(be, c, TRUE); if (m->emod & mod_debug) SQLsetDebugger(c, m, TRUE); if (!caching(m) || !cachable(m, s)) { scanner_query_processed(&(m->scanner)); if (backend_callinline(be, c, s, 0) == 0) { opt = 1; } else { err = 1; } } else { /* generate a factory instantiation */ be->q = qc_insert(m->qc, m->sa, /* the allocator */ r, /* keep relational query */ m->sym, /* the sql symbol tree */ m->args, /* the argument list */ m->argc, m->scanner.key ^ m->session->schema->base.id, /* the statement hash key */ m->emode == m_prepare ? Q_PREPARE : m->type, /* the type of the statement */ sql_escape_str(QUERY(m->scanner))); scanner_query_processed(&(m->scanner)); be->q->code = (backend_code) backend_dumpproc(be, c, be->q, s); if (!be->q->code) err = 1; be->q->stk = 0; /* passed over to query cache, used during dumpproc */ m->sa = NULL; m->sym = NULL; /* register name in the namespace */ be->q->name = putName(be->q->name, strlen(be->q->name)); if (m->emode == m_normal && m->emod == mod_none) m->emode = m_inplace; } } if (err) m->session->status = -10; if (err == 0) { if (be->q) { if (m->emode == m_prepare) err = mvc_export_prepare(m, c->fdout, be->q, ""); else if (m->emode == m_inplace) { /* everything ready for a fast call */ } else { /* call procedure generation (only in cache mode) */ backend_call(be, c, be->q); } } /* In the final phase we add any debugging control */ if (m->emod & mod_trace) SQLsetTrace(be, c, FALSE); if (m->emod & mod_debug) SQLsetDebugger(c, m, FALSE); /* * During the execution of the query exceptions can be raised. * The default action is to print them out at the end of the * query block. */ pushEndInstruction(c->curprg->def); chkTypes(c->fdout, c->nspace, c->curprg->def, TRUE); /* resolve types */ if (opt) { MalBlkPtr mb = c->curprg->def; trimMalBlk(mb); chkProgram(c->fdout, c->nspace, mb); addOptimizers(c, mb, "default_pipe"); msg = optimizeMALBlock(c, mb); if (msg != MAL_SUCCEED) { sqlcleanup(m, err); goto finalize; } c->curprg->def = mb; } //printFunction(c->fdout, c->curprg->def, 0, LIST_MAL_ALL); /* we know more in this case than chkProgram(c->fdout, c->nspace, c->curprg->def); */ if (c->curprg->def->errors) { showErrors(c); /* restore the state */ MSresetInstructions(c->curprg->def, oldstop); freeVariables(c, c->curprg->def, c->glb, oldvtop); c->curprg->def->errors = 0; msg = createException(PARSE, "SQLparser", "Semantic errors"); } } finalize: if (msg) sqlcleanup(m, 0); return msg; }
/* * The generic solution to the multiplex operators is to translate * them to a MAL loop. * The call optimizer.multiplex(MOD,FCN,A1,...An) introduces the following code * structure: * * @verbatim * A1rev:=bat.reverse(A1); * resB:= bat.new(A1); * barrier (h,t):= iterator.new(A1); * $1:= algebra.fetch(A1,h); * $2:= A2; # in case of constant? * ... * cr:= MOD.FCN($1,...,$n); * y:=algebra.fetch(A1rev,h); * bat.insert(resB,y,cr); * redo (h,t):= iterator.next(A1); * end h; * @end verbatim * * The algorithm consists of two phases: phase one deals with * collecting the relevant information, phase two is the actual * code construction. */ static str OPTexpandMultiplex(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { int i = 2, resB, iter = 0, cr; int hvar, tvar; int x, y; str mod, fcn; int *alias; InstrPtr q; int ht, tt; (void) cntxt; (void) stk; ht = getHeadType(getArgType(mb, pci, 0)); if (ht != TYPE_oid) throw(MAL, "optimizer.multiplex", "Target head type is missing"); tt = getTailType(getArgType(mb, pci, 0)); if (tt== TYPE_any) throw(MAL, "optimizer.multiplex", "Target tail type is missing"); if (isAnyExpression(getArgType(mb, pci, 0))) throw(MAL, "optimizer.multiplex", "Target type is missing"); mod = VALget(&getVar(mb, getArg(pci, 1))->value); mod = putName(mod,strlen(mod)); fcn = VALget(&getVar(mb, getArg(pci, 2))->value); fcn = putName(fcn,strlen(fcn)); /* search the iterator bat */ for (i = 3; i < pci->argc; i++) if (isaBatType(getArgType(mb, pci, i))) { iter = getArg(pci, i); if (getHeadType(getVarType(mb,iter)) != TYPE_oid) throw(MAL, "optimizer.multiplex", "Iterator BAT is not OID-headed"); break; } if( i == pci->argc) throw(MAL, "optimizer.multiplex", "Iterator BAT type is missing"); OPTDEBUGmultiplex { mnstr_printf(cntxt->fdout,"#calling the optimize multiplex script routine\n"); printFunction(cntxt->fdout,mb, 0, LIST_MAL_ALL ); mnstr_printf(cntxt->fdout,"#multiplex against operator %d %s\n",iter, getTypeName(getVarType(mb,iter))); printInstruction(cntxt->fdout,mb, 0, pci,LIST_MAL_ALL); } /* * Beware, the operator constant (arg=1) is passed along as well, * because in the end we issue a recursive function call that should * find the actual arguments at the proper place of the callee. */ alias= (int*) GDKmalloc(sizeof(int) * pci->maxarg); if (alias == NULL) return NULL; /* x := bat.reverse(A1); */ x = newTmpVariable(mb, newBatType(getTailType(getVarType(mb,iter)), getHeadType(getVarType(mb,iter)))); q = newFcnCall(mb, batRef, reverseRef); getArg(q, 0) = x; q = pushArgument(mb, q, iter); /* resB := new(refBat) */ q = newFcnCall(mb, batRef, newRef); resB = getArg(q, 0); setVarType(mb, getArg(q, 0), newBatType(ht, tt)); q = pushType(mb, q, ht); q = pushType(mb, q, tt); /* barrier (h,r) := iterator.new(refBat); */ q = newFcnCall(mb, iteratorRef, newRef); q->barrier = BARRIERsymbol; hvar = newTmpVariable(mb, TYPE_any); getArg(q,0) = hvar; tvar = newTmpVariable(mb, TYPE_any); q= pushReturn(mb, q, tvar); (void) pushArgument(mb,q,iter); /* $1:= algebra.fetch(Ai,h) or constant */ alias[i] = tvar; for (i++; i < pci->argc; i++) if (isaBatType(getArgType(mb, pci, i))) { q = newFcnCall(mb, algebraRef, "fetch"); alias[i] = newTmpVariable(mb, getTailType(getArgType(mb, pci, i))); getArg(q, 0) = alias[i]; q= pushArgument(mb, q, getArg(pci, i)); (void) pushArgument(mb, q, hvar); } /* cr:= mod.CMD($1,...,$n); */ q = newFcnCall(mb, mod, fcn); cr = getArg(q, 0) = newTmpVariable(mb, TYPE_any); for (i = 3; i < pci->argc; i++) if (isaBatType(getArgType(mb, pci, i))) { q= pushArgument(mb, q, alias[i]); } else { q = pushArgument(mb, q, getArg(pci, i)); } /* y := algebra.fetch(x,h); */ y = newTmpVariable(mb, getHeadType(getVarType(mb,iter))); q = newFcnCall(mb, algebraRef, "fetch"); getArg(q, 0) = y; q = pushArgument(mb, q, x); q = pushArgument(mb, q, hvar); /* insert(resB,h,cr); not append(resB, cr); the head type (oid) may dynamically change */ q = newFcnCall(mb, batRef, insertRef); q= pushArgument(mb, q, resB); q= pushArgument(mb, q, y); (void) pushArgument(mb, q, cr); /* redo (h,r):= iterator.next(refBat); */ q = newFcnCall(mb, iteratorRef, nextRef); q->barrier = REDOsymbol; getArg(q,0) = hvar; q= pushReturn(mb, q, tvar); (void) pushArgument(mb,q,iter); q = newAssignment(mb); q->barrier = EXITsymbol; getArg(q,0) = hvar; (void) pushReturn(mb, q, tvar); q = newAssignment(mb); getArg(q, 0) = getArg(pci, 0); (void) pushArgument(mb, q, resB); GDKfree(alias); return MAL_SUCCEED; }
static void setAtomName(InstrPtr pci) { char buf[PATHLENGTH]; snprintf(buf, PATHLENGTH, "#%s", getFunctionId(pci)); setFunctionId(pci, putName(buf)); }
static void setAtomName(InstrPtr pci) { char buf[FILENAME_MAX]; snprintf(buf, FILENAME_MAX, "#%s", getFunctionId(pci)); setFunctionId(pci, putName(buf)); }
/* * The generic solution to the multiplex operators is to translate * them to a MAL loop. * The call optimizer.multiplex(MOD,FCN,A1,...An) introduces the following code * structure: * * resB:= bat.new(A1); * barrier (h,t1):= iterator.new(A1); * t2:= algebra.fetch(A2,h) * ... * cr:= MOD.FCN(t1,...,tn); * bat.append(resB,cr); * redo (h,t):= iterator.next(A1); * end h; * * The algorithm consists of two phases: phase one deals with * collecting the relevant information, phase two is the actual * code construction. */ static str OPTexpandMultiplex(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { int i = 2, iter = 0; int hvar, tvar; str mod, fcn; int *alias, *resB; InstrPtr q; int tt; int bat = (getModuleId(pci) == batmalRef) ; //if ( optimizerIsApplied(mb,"multiplex")) //return 0; (void) cntxt; (void) stk; for (i = 0; i < pci->retc; i++) { tt = getBatType(getArgType(mb, pci, i)); if (tt== TYPE_any) throw(MAL, "optimizer.multiplex", SQLSTATE(HY002) "Target tail type is missing"); if (isAnyExpression(getArgType(mb, pci, i))) throw(MAL, "optimizer.multiplex", SQLSTATE(HY002) "Target type is missing"); } mod = VALget(&getVar(mb, getArg(pci, pci->retc))->value); mod = putName(mod); fcn = VALget(&getVar(mb, getArg(pci, pci->retc+1))->value); fcn = putName(fcn); if(mod == NULL || fcn == NULL) throw(MAL, "optimizer.multiplex", SQLSTATE(HY001) MAL_MALLOC_FAIL); #ifndef NDEBUG fprintf(stderr,"#WARNING To speedup %s.%s a bulk operator implementation is needed\n#", mod,fcn); fprintInstruction(stderr, mb, stk, pci, LIST_MAL_DEBUG); #endif /* search the iterator bat */ for (i = pci->retc+2; i < pci->argc; i++) if (isaBatType(getArgType(mb, pci, i))) { iter = getArg(pci, i); break; } if( i == pci->argc) throw(MAL, "optimizer.multiplex", SQLSTATE(HY002) "Iterator BAT type is missing"); #ifdef DEBUG_OPT_MULTIPLEX { char *tpenme; fprintf(stderr,"#calling the optimize multiplex script routine\n"); fprintFunction(stderr,mb, 0, LIST_MAL_ALL ); tpenme = getTypeName(getVarType(mb,iter)); fprintf(stderr,"#multiplex against operator %d %s\n",iter, tpenme); GDKfree(tpenme); fprintInstruction(stderr,mb, 0, pci,LIST_MAL_ALL); } #endif /* * Beware, the operator constant (arg=1) is passed along as well, * because in the end we issue a recursive function call that should * find the actual arguments at the proper place of the callee. */ alias= (int*) GDKmalloc(sizeof(int) * pci->maxarg); resB = (int*) GDKmalloc(sizeof(int) * pci->retc); if (alias == NULL || resB == NULL) { GDKfree(alias); GDKfree(resB); return NULL; } /* resB := new(refBat) */ for (i = 0; i < pci->retc; i++) { q = newFcnCall(mb, batRef, newRef); resB[i] = getArg(q, 0); tt = getBatType(getArgType(mb, pci, i)); setVarType(mb, getArg(q, 0), newBatType(tt)); q = pushType(mb, q, tt); } /* barrier (h,r) := iterator.new(refBat); */ q = newFcnCall(mb, iteratorRef, newRef); q->barrier = BARRIERsymbol; hvar = newTmpVariable(mb, TYPE_any); getArg(q,0) = hvar; tvar = newTmpVariable(mb, TYPE_any); q= pushReturn(mb, q, tvar); (void) pushArgument(mb,q,iter); /* $1:= algebra.fetch(Ai,h) or constant */ for (i = pci->retc+2; i < pci->argc; i++) { if (getArg(pci, i) != iter && isaBatType(getArgType(mb, pci, i))) { q = newFcnCall(mb, algebraRef, "fetch"); alias[i] = newTmpVariable(mb, getBatType(getArgType(mb, pci, i))); getArg(q, 0) = alias[i]; q= pushArgument(mb, q, getArg(pci, i)); (void) pushArgument(mb, q, hvar); } } /* cr:= mod.CMD($1,...,$n); */ q = newFcnCall(mb, mod, fcn); for (i = 0; i < pci->retc; i++) { int nvar = 0; if (bat) { tt = getBatType(getArgType(mb, pci, i)); nvar = newTmpVariable(mb, newBatType(tt)); } else { nvar = newTmpVariable(mb, TYPE_any); } if (i) q = pushReturn(mb, q, nvar); else getArg(q, 0) = nvar; } for (i = pci->retc+2; i < pci->argc; i++) { if (getArg(pci, i) == iter) { q = pushArgument(mb, q, tvar); } else if (isaBatType(getArgType(mb, pci, i))) { q = pushArgument(mb, q, alias[i]); } else { q = pushArgument(mb, q, getArg(pci, i)); } } for (i = 0; i < pci->retc; i++) { InstrPtr a = newFcnCall(mb, batRef, appendRef); a = pushArgument(mb, a, resB[i]); (void) pushArgument(mb, a, getArg(q,i)); } /* redo (h,r):= iterator.next(refBat); */ q = newFcnCall(mb, iteratorRef, nextRef); q->barrier = REDOsymbol; getArg(q,0) = hvar; q= pushReturn(mb, q, tvar); (void) pushArgument(mb,q,iter); q = newAssignment(mb); q->barrier = EXITsymbol; getArg(q,0) = hvar; (void) pushReturn(mb, q, tvar); for (i = 0; i < pci->retc; i++) { q = newAssignment(mb); getArg(q, 0) = getArg(pci, i); (void) pushArgument(mb, q, resB[i]); } GDKfree(alias); GDKfree(resB); return MAL_SUCCEED; }