Changeset: 4a19ab69ab83 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=4a19ab69ab83
Modified Files:
        monetdb5/mal/mal_client.c
        monetdb5/mal/mal_import.c
        monetdb5/mal/mal_instruction.c
        monetdb5/mal/mal_parser.c
        monetdb5/mal/mal_session.c
        monetdb5/modules/atoms/inet.c
        monetdb5/modules/mal/Tests/partition.stable.out
        monetdb5/modules/mal/bbp.mal
        monetdb5/modules/mal/mal_mapi.mal
Branch: malparsing
Log Message:

Various minor issues
- mal_client, defense against self destruction
- mal_import, share the user space amongst 'child' clients
- mal_parser, more specific error messages
- mal_session, stream handling


diffs (truncated from 447 to 300 lines):

diff --git a/monetdb5/mal/mal_client.c b/monetdb5/mal/mal_client.c
--- a/monetdb5/mal/mal_client.c
+++ b/monetdb5/mal/mal_client.c
@@ -109,7 +109,8 @@ void
 MCpopClientInput(Client c)
 {
        ClientInput *x = c->bak;
-       if (c->fdin) {
+
+       if (c->fdin && c->fdin != x->fdin) {
                /* missing protection against closing stdin stream */
                bstream_destroy(c->fdin);
        }
diff --git a/monetdb5/mal/mal_import.c b/monetdb5/mal/mal_import.c
--- a/monetdb5/mal/mal_import.c
+++ b/monetdb5/mal/mal_import.c
@@ -136,7 +136,6 @@ evalFile(Client cntxt, str fname, int li
                        GDKfree(c->prompt);
                        c->prompt= NULL;
                        c->promptlength = 0;
-                       c->blkmode = 1; // collect all statements
                        msg = defaultScenario(c);
                        if( msg == MAL_SUCCEED){ 
                                (void) MSinitClientPrg(c, "user", "main");  /* 
create new context */
@@ -201,7 +200,8 @@ compileString(Client cntxt, str s)
        c = MCinitClient((oid)0,0,0);
        c->fdin = bstream_create(buffer_rastream(b, "compileString"), b->len);
        strncpy(c->fdin->buf,s,len);
-       c->curmodule = c->usermodule = userModule();
+       // use namespace of caller to keep the block around
+       c->curmodule = c->usermodule = cntxt->usermodule;
        GDKfree(c->prompt);
        c->prompt= NULL;
        c->promptlength = 0;
@@ -218,6 +218,7 @@ compileString(Client cntxt, str s)
                pushEndInstruction(c->curprg->def);
                chkProgram(c->usermodule, c->curprg->def);
        }
+       c->curmodule = c->usermodule = 0;
        c->fdout = 0;
        cntxt->curprg = c->curprg;
        c->curprg = 0;
@@ -232,9 +233,12 @@ callString(Client cntxt, str s)
        str msg = MAL_SUCCEED;
 
        c = MCinitClient((oid)0,cntxt->fdin,cntxt->fdout);
+       // use namespace of caller to leave the block around
+       c->curmodule = c->usermodule = cntxt->usermodule;
        msg = compileString(c,s);
        if( msg == MAL_SUCCEED)
                runMAL(c, c->curprg->def,0,0);
+       c->curmodule = c->usermodule = 0;
        c->fdin= 0;
        c->fdout = 0;
        MCcloseClient(c);
diff --git a/monetdb5/mal/mal_instruction.c b/monetdb5/mal/mal_instruction.c
--- a/monetdb5/mal/mal_instruction.c
+++ b/monetdb5/mal/mal_instruction.c
@@ -837,6 +837,9 @@ trimMalVariables_(MalBlkPtr mb, MalStkPt
 
        /* build the alias table */
        for (i = 0; i < mb->vtop; i++) {
+#ifdef DEBUG_REDUCE
+               fprintf(stderr,"used %s %d\n", getVarName(mb,i), 
isVarUsed(mb,i));
+#endif
                if ( isVarUsed(mb,i) == 0) {
                        if (glb && isVarConstant(mb, i))
                                VALclear(&glb->stk[i]);
@@ -869,8 +872,12 @@ trimMalVariables_(MalBlkPtr mb, MalStkPt
        if (cnt < mb->vtop) {
                for (i = 0; i < mb->stop; i++) {
                        q = getInstrPtr(mb, i);
-                       for (j = 0; j < q->argc; j++)
+                       for (j = 0; j < q->argc; j++){
+#ifdef DEBUG_REDUCE
+                               fprintf(stderr, "map %d->%d\n", getArg(q,j), 
alias[getArg(q,j)]);
+#endif
                                getArg(q, j) = alias[getArg(q, j)];
+                               }
                }
        }
        /* rename the temporary variable */
@@ -893,13 +900,16 @@ trimMalVariables(MalBlkPtr mb, MalStkPtr
        int i, j;
        InstrPtr q;
 
-       /* reset the use bit */
+       /* reset the use bit for all non-signature arguments */
        for (i = 0; i < mb->vtop; i++) 
                clrVarUsed(mb,i);
+       /* the return variable is also 'used' */
+       i = findVariable(mb, getFunctionId(mb->stmt[0]));
+       assert(i >=0);
+       setVarUsed(mb,i);
        /* build the use table */
        for (i = 0; i < mb->stop; i++) {
                q = getInstrPtr(mb, i);
-
                for (j = 0; j < q->argc; j++)
                        setVarUsed(mb,getArg(q,j));
        }
diff --git a/monetdb5/mal/mal_parser.c b/monetdb5/mal/mal_parser.c
--- a/monetdb5/mal/mal_parser.c
+++ b/monetdb5/mal/mal_parser.c
@@ -1154,7 +1154,7 @@ parseCommandPattern(Client cntxt, int ki
                int i;
                i = idLength(cntxt);
                if (i == 0) {
-                       parseError(cntxt, "<identifier> expected\n");
+                       parseError(cntxt, "address <identifier> expected\n");
                        return 0;
                }
                cntxt->blkmode = 0;
@@ -1208,7 +1208,7 @@ parseFunction(Client cntxt, int kind)
                InstrPtr curInstr = getInstrPtr(cntxt->curprg->def, 0);
                i = idLength(cntxt);
                if (i == 0) {
-                       parseError(cntxt, "<identifier> expected\n");
+                       parseError(cntxt, "address <identifier> expected\n");
                        return 0;
                }
                nme = idCopy(cntxt, i);
@@ -1256,7 +1256,7 @@ parseEnd(Client cntxt)
                        strncmp(cntxt->lineptr, getFunctionId(sig), l) == 0) || 
l == 0) {} else {
                        advance(cntxt, l);
                        parseError(cntxt, "non matching end label\n");
-                       return 0;
+                       return 1;
                }
                advance(cntxt, l);
                pushEndInstruction(cntxt->curprg->def);
@@ -1265,7 +1265,8 @@ parseEnd(Client cntxt)
                        insertSymbol(cntxt->usermodule, cntxt->curprg);
                else
                        insertSymbol(getModule(getModuleId(sig)), 
cntxt->curprg);
-        chkProgram(cntxt->usermodule, cntxt->curprg->def);
+               if( cntxt->curprg->def->errors == MAL_SUCCEED)
+                       chkProgram(cntxt->usermodule, cntxt->curprg->def);
         if (cntxt->backup) {
                        cntxt->backup->def->errors = 
GDKstrdup(cntxt->curprg->def->errors);
             cntxt->curprg = cntxt->backup;
@@ -1344,7 +1345,7 @@ parseStatement(Client cntxt, int cntrl)
                while (*cntxt->lineptr != ')' && *cntxt->lineptr) {
                        l = idLength(cntxt);
                        if (l == 0 ) {
-                               parseError(cntxt, "<identifier> expected\n");
+                               parseError(cntxt, "left-hand-side <identifier> 
expected\n");
                                goto part3;
                        }
                        GETvariable;
@@ -1384,12 +1385,12 @@ parseStatement(Client cntxt, int cntrl)
                                curInstr->argv[0] = getBarrierEnvelop(curBlk);
                                pushInstruction(curBlk, curInstr);
                                if (*cntxt->lineptr != ';')
-                                       parseError(cntxt, "<identifier> 
expected\n");
+                                       parseError(cntxt, "<identifier> 
expected in control statement\n");
                                return;
                        }
                        getArg(curInstr, 0) = newTmpVariable(curBlk, TYPE_any);
                        pushInstruction(curBlk, curInstr);
-                       parseError(cntxt, "<identifier> expected\n");
+                       parseError(cntxt, "simple left-hand-side <identifier> 
expected\n");
                        return;
                }
                /* Check if we are dealing with module.fcn call*/
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
@@ -20,7 +20,7 @@
 #include "mal_private.h"
 #include <gdk.h>       /* for opendir and friends */
 
-/* #define _DEBUG_SESSION_*/
+/*#define _DEBUG_SESSION_*/
 #ifdef HAVE_EMBEDDED
 // FIXME:
 //#include "mal_init_inline.h"
@@ -63,7 +63,7 @@ malBootstrap(void)
        }
        pushEndInstruction(c->curprg->def);
        chkProgram(c->usermodule, c->curprg->def);
-       if (c->curprg->def->errors != MAL_SUCCEED ) {
+       if ( (msg= c->curprg->def->errors) != MAL_SUCCEED ) {
                mnstr_printf(c->fdout,"!%s%s",msg, (msg[strlen(msg)-1] == '\n'? 
"":"\n"));
                mnstr_flush(c->fdout);
                if( GDKerrbuf && GDKerrbuf[0]){
@@ -116,19 +116,20 @@ MSresetClientPrg(Client cntxt, str mod, 
        p->argc = 1;
        p->argv[0] = 0;
 
-       strcpy(getVarName(mb,0), nme);
-    setRowCnt(mb,0,0);
-       if( strcmp(mod,"user") == 0 && strcmp(nme,"main")==0)
-               setVarType(mb, 0, TYPE_void);
-    clrVarFixed(mb, 0);
-    clrVarUsed(mb, 0);
-    clrVarInit(mb, 0);
-    clrVarDisabled(mb, 0);
-    clrVarUDFtype(mb, 0);
-    clrVarConstant(mb, 0);
-    clrVarCleanup(mb, 0);
+#ifdef _DEBUG_SESSION_
+       fprintf(stderr,"reset sym %s %s to %s, id %d\n", 
+               cntxt->curprg->name, getFunctionId(p), nme, 
findVariable(mb,nme) );
+       fprintf(stderr,"vtop %d\n", mb->vtop);
+       if( mb->vtop)
+       fprintf(stderr,"first var %s\n", mb->var[0].id);
+#endif
+
        setModuleId(p, mod);
        setFunctionId(p, nme);
+       if( findVariable(mb,nme) < 0)
+               p->argv[0] = newVariable(mb, nme, strlen(nme), TYPE_void);
+
+       setVarType(mb, findVariable(mb, nme), TYPE_void);
        /* remove any MAL history */
        if (mb->history) {
                freeMalBlk(mb->history);
@@ -145,18 +146,19 @@ str
 MSinitClientPrg(Client cntxt, str mod, str nme)
 {
        if (cntxt->curprg  && idcmp(nme, cntxt->curprg->name) == 0)
-               return MSresetClientPrg(cntxt, mod,nme);
+               return MSresetClientPrg(cntxt, putName(mod), putName(nme));
        cntxt->curprg = newFunction(putName(mod), putName(nme), FUNCTIONsymbol);
+       if( strcmp(mod,"user")==0 && strcmp(nme,"main")==0)
+               setVarType(cntxt->curprg->def, 
findVariable(cntxt->curprg->def,"main"), TYPE_void);
        if( cntxt->curprg == 0)
                throw(MAL, "initClientPrg", MAL_MALLOC_FAIL);
        
-       if( strcmp(mod,"user") == 0 && strcmp(nme,"main")==0)
-               setVarType(cntxt->curprg->def, 0, TYPE_void);
        if (cntxt->glb == NULL )
                cntxt->glb = newGlobalStack(MAXGLOBALS + 
cntxt->curprg->def->vsize);
        if( cntxt->glb == NULL)
                throw(MAL,"initClientPrg", MAL_MALLOC_FAIL);
        assert(cntxt->curprg->def != NULL);
+       assert(cntxt->curprg->def->vtop >0);
        return MAL_SUCCEED;
 }
 
@@ -410,8 +412,12 @@ MSresetVariables(Client cntxt, MalBlkPtr
 {
        int i;
 
-       for (i = 0; i < start && start < mb->vtop; i++)
-               setVarUsed(mb,i);
+#ifdef _DEBUG_SESSION_
+       fprintf(stderr,"resetVarables %d  vtop %d errors %s\n", start, 
mb->vtop,mb->errors);
+#endif
+       if( start <= mb->vtop)
+               for (i = 0; i < start ; i++)
+                       setVarUsed(mb,i);
        if (mb->errors == MAL_SUCCEED)
                for (i = start; i < mb->vtop; i++) {
                        if (isVarUsed(mb,i) || !isTmpVar(mb,i)){
@@ -428,8 +434,14 @@ MSresetVariables(Client cntxt, MalBlkPtr
                        }
                }
 
+#ifdef _DEBUG_SESSION_
+       fprintf(stderr,"resetVar %s %d\n", getFunctionId(mb->stmt[0]), 
mb->var[mb->stmt[0]->argv[0]].used);
+#endif
        if (mb->errors == MAL_SUCCEED)
                trimMalVariables_(mb, glb);
+#ifdef _DEBUG_SESSION_
+       fprintf(stderr,"after trim %s %d\n", getFunctionId(mb->stmt[0]), 
mb->vtop);
+#endif
 }
 
 /*
@@ -589,20 +601,31 @@ MALreader(Client c)
                                        mnstr_write(c->fdout, c->prompt, 
strlen(c->prompt), 1);
                                mnstr_flush(c->fdout);
                        }
-                       if((nr = bstream_next(c->fdin)) < 0 || (!blocked && 
c->fdin->eof)){
+                       nr = bstream_next(c->fdin);
+                       if(nr < 0 || (!blocked && c->fdin->eof)){
+               alternative:
                                if (c->bak){
 #ifdef _DEBUG_SESSION_
-                                       fprintf(stderr,"Pop the input 
stream\n");
+                                       fprintf(stderr,"Pop the input stream 
for client %d\n", c->idx);
 #endif
                                        MCpopClientInput(c);
                                } else{
+                                       // if we have unprocessed data we 
should return and await its consumption
+                                       if(c->line && *c->line){
+                                               return MAL_SUCCEED;
+                                       }
                                        MT_lock_set(&mal_contextLock);
                                        c->mode = FINISHCLIENT;
                                        MT_lock_unset(&mal_contextLock);
                                }
                                return MAL_SUCCEED;
                        }
-                       if (!nr)
+                       if (!nr && blocked ){
+                               nr = bstream_next(c->fdin); // check for eof 
+                               if (c->fdin->eof)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to