/* * The SQL block is stored in the client input buffer, from which it * can be parsed by the SQL parser. The client structure contains * a small table of bounded tables. This should be reset before we * parse a new statement sequence. * Before we parse the sql statement, we look for any variable settings * for specific commands. * The most important one is to prepare code to be handled by the debugger. * The current analysis is simple and fulfills our short-term needs. * A future version may analyze the parameter settings in more detail. */ static void SQLsetDebugger(Client c, mvc *m, int onoff) { if (m == 0 || !(m->emod & mod_debug)) return; c->itrace = 'n'; if (onoff) { newStmt(c->curprg->def, "mdb", "start"); c->debugOptimizer = TRUE; c->curprg->def->keephistory = TRUE; } else { newStmt(c->curprg->def, "mdb", "stop"); c->debugOptimizer = FALSE; c->curprg->def->keephistory = FALSE; } }
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; }
int OPTjsonImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { int i, j, limit, slimit; int bu = 0, br = 0, bj = 0; str nme; InstrPtr p,q; int actions = 0; InstrPtr *old; (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) == sqlRef && getFunctionId(p) == affectedRowsRef) { q = newStmt(mb, jsonRef, resultSetRef); q = pushArgument(mb, q, bu); q = pushArgument(mb, q, br); q = pushArgument(mb, q, bj); j = getArg(q,0); p= getInstrPtr(mb,0); setVarType(mb,getArg(p,0),TYPE_str); q = newReturnStmt(mb); getArg(q,0)= getArg(p,0); pushArgument(mb,q,j); continue; } if( getModuleId(p) == sqlRef && getFunctionId(p) == rsColumnRef) { nme = getVarConstant(mb,getArg(p,4)).val.sval; if (strcmp(nme,"uuid")==0) bu = getArg(p,7); if (strcmp(nme,"lng")==0) br = getArg(p,7); if (strcmp(nme,"json")==0) bj = getArg(p,7); freeInstruction(p); continue; } pushInstruction(mb,p); } for(; i<slimit; i++) if (old[i]) freeInstruction(old[i]); GDKfree(old); return actions; }
/* * 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); } }
int OPTquerylogImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { int i, limit, slimit; InstrPtr p = 0, *old= mb->stmt, q,r; int argc, io, user,nice,sys,idle,iowait,load, arg, start,finish, name; int xtime=0, rtime = 0, tuples=0; InstrPtr defineQuery = NULL; // query log needed? if ( !QLOGisset() ) return 0; (void) pci; (void) stk; /* to fool compilers */ (void) cntxt; /* gather information */ for (i = 1; i < mb->stop; i++) { p = getInstrPtr(mb,i); if ( getModuleId(p) && idcmp(getModuleId(p), "querylog") == 0 && idcmp(getFunctionId(p),"define")==0){ defineQuery= p; getVarConstant(mb,getArg(p,3)).val.lval = GDKusec()-getVarConstant(mb,getArg(p,3)).val.lval ; } } if ( defineQuery == NULL) /* nothing to do */ return 0; limit= mb->stop; slimit= mb->ssize; if ( newMalBlkStmt(mb, mb->ssize) < 0) return 0; pushInstruction(mb, old[0]); /* run the querylog.define operation */ defineQuery = copyInstruction(defineQuery); setFunctionId(defineQuery, insertRef); getArg(defineQuery,0) = newTmpVariable(mb,TYPE_any); defineQuery->token = ASSIGNsymbol; setModuleId(defineQuery,querylogRef); /* collect the initial statistics */ q = newStmt(mb, "clients", "getUsername"); name= getArg(q,0)= newVariable(mb,GDKstrdup("name"),TYPE_str); defineQuery = pushArgument(mb,defineQuery,name); q = newStmt(mb, "mtime", "current_timestamp"); start= getArg(q,0)= newVariable(mb,GDKstrdup("start"),TYPE_timestamp); defineQuery = pushArgument(mb,defineQuery,start); pushInstruction(mb, defineQuery); q = newStmt1(mb, sqlRef, "argRecord"); for ( argc=1; argc < old[0]->argc; argc++) q = pushArgument(mb, q, getArg(old[0],argc)); arg= getArg(q,0)= newVariable(mb,GDKstrdup("args"),TYPE_str); q = newStmt(mb, "alarm", "usec"); xtime = getArg(q,0)= newVariable(mb,GDKstrdup("xtime"),TYPE_lng); user = newVariable(mb,GDKstrdup("user"),TYPE_lng); nice = newVariable(mb,GDKstrdup("nice"),TYPE_lng); sys = newVariable(mb,GDKstrdup("sys"),TYPE_lng); idle = newVariable(mb,GDKstrdup("idle"),TYPE_lng); iowait = newVariable(mb,GDKstrdup("iowait"),TYPE_lng); q = newStmt(mb, "profiler", "cpustats"); q->retc= q->argc =0; q = pushReturn(mb,q,user); q = pushReturn(mb,q,nice); q = pushReturn(mb,q,sys); q = pushReturn(mb,q,idle); q = pushReturn(mb,q,iowait); q = newAssignment(mb); tuples= getArg(q,0) = newVariable(mb,GDKstrdup("tuples"),TYPE_wrd); (void) pushWrd(mb,q,1); for (i = 1; i < limit; i++) { p = old[i]; if (getModuleId(p)==sqlRef && (idcmp(getFunctionId(p),"exportValue")==0 || idcmp(getFunctionId(p),"exportResult")==0 ) ) { q = newStmt(mb, "alarm", "usec"); r = newStmt1(mb, calcRef, "-"); r = pushArgument(mb, r, getArg(q,0)); r = pushArgument(mb, r, xtime); getArg(r,0)=xtime; q = newStmt(mb, "alarm", "usec"); rtime= getArg(q,0)= newVariable(mb,GDKstrdup("rtime"),TYPE_lng); pushInstruction(mb,p); continue; } if ( getModuleId(p) == sqlRef && idcmp(getFunctionId(p),"resultSet")==0 && isaBatType(getVarType(mb,getArg(p,3)))){ q = newStmt(mb, "aggr", "count"); getArg(q,0) = tuples; (void) pushArgument(mb,q, getArg(p,3)); pushInstruction(mb,p); continue; } if ( p->token== ENDsymbol || p->barrier == RETURNsymbol || p->barrier == YIELDsymbol){ if ( rtime == 0){ q = newStmt(mb, "alarm", "usec"); r = newStmt1(mb, calcRef, "-"); r = pushArgument(mb, r, getArg(q,0)); r = pushArgument(mb, r, xtime); getArg(r,0)=xtime; q = newStmt(mb, "alarm", "usec"); rtime= getArg(q,0)= newVariable(mb,GDKstrdup("rtime"),TYPE_lng); } q = newStmt(mb, "alarm", "usec"); r = newStmt1(mb, calcRef, "-"); r = pushArgument(mb, r, getArg(q,0)); r = pushArgument(mb, r, rtime); getArg(r,0)=rtime; /* * Post execution statistics gathering */ q = newStmt(mb, "mtime", "current_timestamp"); finish= getArg(q,0)= newVariable(mb,GDKstrdup("finish"),TYPE_any); q = newStmt(mb, "profiler", "cpuload"); load = newVariable(mb,GDKstrdup("load"),TYPE_int); getArg(q,0)= load; io = newVariable(mb,GDKstrdup("io"),TYPE_int); q= pushReturn(mb,q,io); q = pushArgument(mb,q,user); q = pushArgument(mb,q,nice); q = pushArgument(mb,q,sys); q = pushArgument(mb,q,idle); q = pushArgument(mb,q,iowait); q = newStmt(mb, querylogRef, "call"); q = pushArgument(mb, q, start); q = pushArgument(mb, q, finish); q = pushArgument(mb, q, arg); q = pushArgument(mb, q, tuples); q = pushArgument(mb, q, xtime); q = pushArgument(mb, q, rtime); q = pushArgument(mb, q, load); q = pushArgument(mb, q, io); pushInstruction(mb,p); continue; } pushInstruction(mb,p); if (p->barrier == YIELDsymbol){ /* the factory yield may return */ q = newStmt(mb, "mtime", "current_timestamp"); start= getArg(q,0)= newVariable(mb,GDKstrdup("start"),TYPE_any); q = newStmt1(mb, sqlRef, "argRecord"); for ( argc=1; argc < old[0]->argc; argc++) q = pushArgument(mb, q, getArg(old[0],argc)); arg= getArg(q,0)= newVariable(mb,GDKstrdup("args"),TYPE_str); q = newAssignment(mb); q = pushLng(mb,q,0); q = newAssignment(mb); q = pushWrd(mb,q,0); tuples= getArg(q,0)= newVariable(mb,GDKstrdup("tuples"),TYPE_wrd); newFcnCall(mb,"profiler","setMemoryFlag"); q->argc--; pushWrd(mb,q,1); q = newStmt(mb, "alarm", "usec"); xtime = getArg(q,0)= newVariable(mb,GDKstrdup("xtime"),TYPE_lng); } } for( ; i<slimit; i++) if(old[i]) freeInstruction(old[i]); GDKfree(old); return 1; }