Example #1
0
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;
}
Example #2
0
/*
 * 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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
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;
}
Example #7
0
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;
}
Example #8
0
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;
}
Example #9
0
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);
}
Example #10
0
/*
 * 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;
}
Example #11
0
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;
}
Example #12
0
/*
 * 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;
}
Example #14
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;
}
Example #15
0
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);
}
Example #16
0
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;
}
Example #17
0
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);
}
Example #18
0
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;
}
Example #19
0
/* 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;
}
Example #20
0
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;
}
Example #21
0
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();
    }
Example #23
0
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);
}
Example #24
0
/*
 * 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;
}
Example #25
0
/*
 * 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);
	}
}
Example #26
0
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;
}
Example #27
0
/*
 * 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;
}
Example #28
0
static void setAtomName(InstrPtr pci)
{
	char buf[PATHLENGTH];
	snprintf(buf, PATHLENGTH, "#%s", getFunctionId(pci));
	setFunctionId(pci, putName(buf));
}
Example #29
0
static void setAtomName(InstrPtr pci)
{
	char buf[FILENAME_MAX];
	snprintf(buf, FILENAME_MAX, "#%s", getFunctionId(pci));
	setFunctionId(pci, putName(buf));
}
Example #30
0
/*
 * 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;
}