void ParseComment (FILE* file,char type,Comment* doc){
     char* line=NULL;
     StringList bloc=NULL;
     int end=0;
     if(doc==NULL)doc=newComment();
     if(doc==NULL)exit(EXIT_FAILURE);
     switch(type){
                  case '/':
                       line=GetLine(file);
                        ParseLine(file,doc);
                        free(line);
                        break;
                  case '*':
                       bloc=newStringList();
                       while(end==0){
                                     char* tmp=GetLine(file);
                                     int length=strlen(tmp);
                                     if(strstr(tmp,"*/")!=NULL)end=1;
                                     addtoStringList(bloc,tmp);
                                     }
                       StringCell* tmp;
                       int i;
                       for(tmp=bloc.first, i=1;i<=bloc.size;i++, tmp=tmp->suivant){
                                           ParseLine(tmp->string,doc);
                                           }
                       freeStringList(bloc);
                       break;
                  default:
                          break;
                  }
     
     }
/** \brief Funcion para crear un nuevo comentario
 * \param listaUsuarios: arraylist donde se guardan los usuarios
 * \param listaComentarios: arraylist donde se guardan los comentarios
 */
void nuevoComentario(ArrayList *listaUsuarios,ArrayList *listaComentarios)
{
    char nickAux[51];
    char passAux[51];
    char commentAux[250];
    User *usuario;
    EComments *comentario;
    int i,id;

    printf("Ingrese su nick: ");

    gets(nickAux);
    fflush(stdin);
    printf("Ingrese su pass: "******"Ingrese su comentario: ");
            gets(commentAux);
            fflush(stdin);

            id=listaComentarios->size;
            comentario=newComment(commentAux, usuario->id,id);
            if(listaComentarios->size > 0)
                listaComentarios->push(listaComentarios,0,comentario);
            else
                listaComentarios->add(listaComentarios,comentario);

        }
    }
}
Beispiel #3
0
short SlkToken::get(void)
{
  if (NULL == mSource || NULL == mErrorAndStringBuffer) {
    return END_OF_SLK_INPUT_;
  }

  for (;;) {
    if (*mIterator == '\0') {
      if (isCanFinish()) {
        newToken();
        endTokenWithEof();
        return END_OF_SLK_INPUT_;
      } else {
        if (!mIterator.Load()) {
          newToken();
          endTokenWithEof();
          return END_OF_SLK_INPUT_;
        }
      }
    }

    int isSkip = TRUE;
    //跳过注释与白空格
    for (; isSkip && *mIterator != '\0';) {
      isSkip = FALSE;
      for (; isWhiteSpace(*mIterator); ++mIterator) {
        if (*mIterator == '\n') {
          ++mLineNumber;
          if (mCommentNum <= 0) {
            mCommentOnNewLine = TRUE;
          }
        }
        isSkip = TRUE;
      }
      //#引导的单行注释
      if (*mIterator == '#') {
        newComment();
        for (; *mIterator != '\0' && *mIterator != '\n'; ++mIterator) {
          if (*mIterator != '\r')
            pushCommentChar(*mIterator);
        }
        endComment();
        isSkip = TRUE;
      }
      //C++风格的单行注释与多行注释
      if (*mIterator == '/' && (*(mIterator + 1) == '/' || *(mIterator + 1) == '*')) {
        newComment();
        pushCommentChar(*mIterator);
        ++mIterator;
        if (*mIterator == '/') {
          pushCommentChar(*mIterator);
          ++mIterator;
          for (; *mIterator != '\0' && *mIterator != '\n'; ++mIterator) {
            if (*mIterator != '\r')
              pushCommentChar(*mIterator);
          }
          isSkip = TRUE;
        } else if (*mIterator == '*') {
          pushCommentChar(*mIterator);
          ++mIterator;
          for (;;) {
            if (*mIterator != '\0') {
              if (*mIterator == '\n') {
                pushCommentChar(*mIterator);
                ++mLineNumber;
              } else if (*mIterator == '*' && *(mIterator + 1) == '/') {
                pushCommentChar(*mIterator);
                ++mIterator;
                pushCommentChar(*mIterator);
                ++mIterator;
                break;
              } else if (*mIterator != '\r') {
                pushCommentChar(*mIterator);
              }
            } else {
              if (mIterator.Load()) {
                continue;
              } else {
                endComment();
                newToken();
                endTokenWithEof();
                return END_OF_SLK_INPUT_;
              }
            }
            ++mIterator;
          }
          isSkip = TRUE;
        }
        endComment();
      }
    }
    if (*mIterator != '\0')
      break;
  }

  newToken();
  if (isCanFinish())
    setCanFinish(FALSE);

  if (*mIterator == '{' && *(mIterator + 1) == ':') {
    ++mIterator;
    ++mIterator;
    int line = mLineNumber;
    //搜索脚本结束 :}
    for (; *mIterator != '\0';) {
      while (*mIterator != '\0' && *mIterator != ':') {
        if (*mIterator == '\n')++mLineNumber;

        pushTokenChar(*mIterator);

        ++mIterator;
      }
      if (*mIterator == '\0')
        break;
      IScriptSource::Iterator next = mIterator + 1;
      if (*next == '}') {
        ++mIterator;
        ++mIterator;
        break;
      } else {
        pushTokenChar(*mIterator);

        ++mIterator;
      }
    }
    if (*mIterator == '\0') {
      char* pInfo = mErrorAndStringBuffer->NewErrorInfo();
      if (pInfo)
        tsnprintf(pInfo, MAX_ERROR_INFO_CAPACITY, "[line %d ]:ExternScript can't finish!", line);
    }
    endToken();
    if (myhavelinefeed(mCurToken)){
      removeFirstAndLastEmptyLine();
    }
    return SCRIPT_CONTENT_;
  } else if (isOperator(*mIterator)) {//操作符
    getOperatorToken();
    return getOperatorTokenValue();
  } else if (*mIterator == '.' && 0 == myisdigit(*(mIterator + 1), FALSE)) {
    char c = *mIterator;
    ++mIterator;

    pushTokenChar(c);
    endToken();
    return DOT_;
  } else if (*mIterator == '(') {
    ++mIterator;
    pushTokenChar('(');
    endToken();
    return LPAREN_;
  } else if (*mIterator == ')') {
    ++mIterator;
    pushTokenChar(')');
    endToken();
    return RPAREN_;
  } else if (*mIterator == '[') {
    ++mIterator;
    pushTokenChar('[');
    endToken();
    return LBRACK_;
  } else if (*mIterator == ']') {
    ++mIterator;
    pushTokenChar(']');
    endToken();
    return RBRACK_;
  } else if (*mIterator == '{') {
    ++mIterator;
    pushTokenChar('{');
    endToken();
    return LBRACE_;
  } else if (*mIterator == '}') {
    ++mIterator;
    pushTokenChar('}');
    endToken();
    return RBRACE_;
  } else if (*mIterator == ',') {
    ++mIterator;
    pushTokenChar(',');
    endToken();
    return COMMA_;
  } else if (*mIterator == ';') {
    ++mIterator;
    pushTokenChar(';');
    endToken();
    return SEMI_;
  } else {//关键字、标识符或常数
    if (*mIterator == '"' || *mIterator == '\'') {//引号括起来的名称或关键字
      int line = mLineNumber;
      char c = *mIterator;
      for (++mIterator; *mIterator != '\0' && *mIterator != c;) {
        if (*mIterator == '\n')++mLineNumber;
        if (*mIterator == '\\') {
          //pushTokenChar(*mIterator);
          ++mIterator;
        }

        pushTokenChar(*mIterator);
        ++mIterator;

        if (*mIterator == '\0') {
          if (mIterator.Load()) {
            continue;
          } else {
            char* pInfo = mErrorAndStringBuffer->NewErrorInfo();
            if (pInfo)
              tsnprintf(pInfo, MAX_ERROR_INFO_CAPACITY, "[line %d ]:String can't finish!", line);
            endTokenWithEof();
            return END_OF_SLK_INPUT_;
          }
        }
      }
      if (*mIterator != '\0') {
        ++mIterator;
      } else {
        char* pInfo = mErrorAndStringBuffer->NewErrorInfo();
        if (pInfo)
          tsnprintf(pInfo, MAX_ERROR_INFO_CAPACITY, "[line %d ]:String can't finish!", line);
      }
      endToken();
      if (myhavelinefeed(mCurToken)){
        removeFirstAndLastEmptyLine();
      }
      return STRING_;
    } else {
      int isNum = TRUE;
      int isHex = FALSE;
      if (*mIterator == '0' && *(mIterator + 1) == 'x') {
        isHex = TRUE;
        pushTokenChar(*mIterator);
        ++mIterator;
        pushTokenChar(*mIterator);
        ++mIterator;
      }
      for (; !isSpecialChar(*mIterator); ++mIterator) {
        if (*mIterator == '#')
          break;
        else if (*mIterator == '/') {
          IScriptSource::Iterator next = mIterator + 1;
          if (*next != '\0' && (*next == '/' || *next == '*')) {
            break;
          }
        } else if (*mIterator == '.') {
          if (!isNum) {
            break;
          } else {
            IScriptSource::Iterator next = mIterator + 1;
            if (0 == myisdigit(*next, isHex)) {
              break;
            }
          }
        } else if (0 == myisdigit(*mIterator, isHex)) {
          isNum = FALSE;
        }

        pushTokenChar(*mIterator);
      }
      endToken();
      if (isNum) {
        return NUMBER_;
      } else {
        int token = handleStringOrScriptDelimiter();
        if (token)
          return token;
        return IDENTIFIER_;
      }
    }
  }
}
Beispiel #4
0
str
OPTevaluateImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	InstrPtr p;
	int i, k, limit, *alias = 0, barrier;
	MalStkPtr env = NULL;
	int profiler;
	int debugstate = cntxt->itrace, actions = 0, constantblock = 0;
	int *assigned = 0, use; 
	char buf[256];
	lng usec = GDKusec();
	str msg = MAL_SUCCEED;

	(void)stk;
	(void)pci;

	if ( mb->inlineProp )
		return MAL_SUCCEED;

	cntxt->itrace = 0;

#ifdef DEBUG_OPT_EVALUATE
	fprintf(stderr, "Constant expression optimizer started\n");
#endif

	assigned = (int*) GDKzalloc(sizeof(int) * mb->vtop);
	if (assigned == NULL)
		throw(MAL,"optimzier.evaluate", SQLSTATE(HY001) MAL_MALLOC_FAIL);

	alias = (int*)GDKzalloc(mb->vsize * sizeof(int) * 2); /* we introduce more */
	if (alias == NULL){
		GDKfree(assigned);
		throw(MAL,"optimzier.evaluate", SQLSTATE(HY001) MAL_MALLOC_FAIL);
	}

	// arguments are implicitly assigned by context
	p = getInstrPtr(mb, 0);
	for ( k =p->retc;  k < p->argc; k++)
		assigned[getArg(p,k)]++;
	limit = mb->stop;
	for (i = 1; i < limit; i++) {
		p = getInstrPtr(mb, i);
		// The double count emerging from a barrier exit is ignored.
		if (! blockExit(p) || (blockExit(p) && p->retc != p->argc))
		for ( k =0;  k < p->retc; k++)
		if ( p->retc != p->argc || p->token != ASSIGNsymbol )
			assigned[getArg(p,k)]++;
	}

	for (i = 1; i < limit && cntxt->mode != FINISHCLIENT; i++) {
		p = getInstrPtr(mb, i);
		// to avoid management of duplicate assignments over multiple blocks
		// we limit ourselves to evaluation of the first assignment only.
		use = assigned[getArg(p,0)] == 1 && !(p->argc == p->retc && blockExit(p));
		for (k = p->retc; k < p->argc; k++)
			if (alias[getArg(p, k)])
				getArg(p, k) = alias[getArg(p, k)];
#ifdef DEBUG_OPT_EVALUATE
		fprintInstruction(stderr , mb, 0, p, LIST_MAL_ALL);
#endif
		/* be aware that you only assign once to a variable */
		if (use && p->retc == 1 && OPTallConstant(cntxt, mb, p) && !isUnsafeFunction(p)) {
			barrier = p->barrier;
			p->barrier = 0;
			profiler = malProfileMode;	/* we don't trace it */
			malProfileMode = 0;
			if ( env == NULL) {
				env = prepareMALstack(mb,  2 * mb->vsize);
				if (!env) {
					msg = createException(MAL,"optimizer.evaluate", SQLSTATE(HY001) MAL_MALLOC_FAIL);
					goto wrapup;
				}
				env->keepAlive = TRUE;
			}
			msg = reenterMAL(cntxt, mb, i, i + 1, env);
			malProfileMode= profiler;
			p->barrier = barrier;
#ifdef DEBUG_OPT_EVALUATE
			fprintf(stderr, "#retc var %s\n", getVarName(mb, getArg(p, 0)));
			fprintf(stderr, "#result:%s\n", msg == MAL_SUCCEED ? "ok" : msg);
#endif
			if (msg == MAL_SUCCEED) {
				int nvar;
				ValRecord cst;

				actions++;
				cst.vtype = 0;
				VALcopy(&cst, &env->stk[getArg(p, 0)]);
				/* You may not overwrite constants.  They may be used by
				 * other instructions */
				nvar = getArg(p, 1) = defConstant(mb, getArgType(mb, p, 0), &cst);
				if (nvar >= env->stktop) {
					VALcopy(&env->stk[getArg(p, 1)], &getVarConstant(mb, getArg(p, 1)));
					env->stktop = getArg(p, 1) + 1;
				}
				alias[getArg(p, 0)] = getArg(p, 1);
				p->argc = 2;
				p->token = ASSIGNsymbol;
				clrFunction(p);
				p->barrier = barrier;
				/* freeze the type */
				setVarFixed(mb,getArg(p,1));
				setVarUDFtype(mb,getArg(p,1));
#ifdef DEBUG_OPT_EVALUATE
				{str tpename;
				fprintf(stderr, "Evaluated new constant=%d -> %d:%s\n",
					getArg(p, 0), getArg(p, 1), tpename = getTypeName(getArgType(mb, p, 1)));
				GDKfree(tpename);
				}
#endif
			} else {
				/* if there is an error, we should postpone message handling,
					as the actual error (eg. division by zero ) may not happen) */
#ifdef DEBUG_OPT_EVALUATE
				fprintf(stderr, "Evaluated %s\n", msg);
#endif
				freeException(msg);
				msg= MAL_SUCCEED;
				mb->errors = 0;
			}
		}
		constantblock +=  blockStart(p) && OPTallConstant(cntxt, mb, p);	/* default */
	}
	// produces errors in SQL when enabled
	if ( constantblock)
		msg = OPTremoveUnusedBlocks(cntxt, mb);
	cntxt->itrace = debugstate;

    /* Defense line against incorrect plans */
	/* Plan is unaffected */
	chkTypes(cntxt->usermodule, mb, FALSE);
	chkFlow(mb);
	chkDeclarations(mb);
    
    /* keep all actions taken as a post block comment */
	usec = GDKusec()- usec;
    snprintf(buf,256,"%-20s actions=%2d time=" LLFMT " usec","evaluate",actions,usec);
    newComment(mb,buf);
	if( actions >= 0)
		addtoMalBlkHistory(mb);

wrapup:
	if ( env) freeStack(env);
	if(assigned) GDKfree(assigned);
	if(alias)	GDKfree(alias);
	return msg;
}
Beispiel #5
0
CommentNode* BaseCompiler::addComment(const char* str) {
  CommentNode* node = newComment(str);
  if (node == NULL)
    return NULL;
  return static_cast<CommentNode*>(addNode(node));
}
Beispiel #6
0
str
OPTvolcanoImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	int i, limit;
	int mvcvar = -1;
	int count=0;
	InstrPtr p,q, *old = mb->stmt;
	char buf[256];
	lng usec = GDKusec();
	str msg = MAL_SUCCEED;

	(void) pci;
	(void) cntxt;
	(void) stk;		/* to fool compilers */

    if ( mb->inlineProp )
        return MAL_SUCCEED;

    limit= mb->stop;
    if ( newMalBlkStmt(mb, mb->ssize + 20) < 0)
		throw(MAL,"optimizer.volcano", SQLSTATE(HY001) MAL_MALLOC_FAIL);

	for (i = 0; i < limit; i++) {
		p = old[i];

		pushInstruction(mb,p);
		if( getModuleId(p) == sqlRef && getFunctionId(p)== mvcRef ){
			mvcvar = getArg(p,0);
			continue;
		}

		if( count < MAXdelays && getModuleId(p) == algebraRef ){
			if( getFunctionId(p) == selectRef ||
				getFunctionId(p) == thetaselectRef ||
				getFunctionId(p) == likeselectRef ||
				getFunctionId(p) == joinRef
			){
				q= newInstruction(0,languageRef,blockRef);
				setDestVar(q, newTmpVariable(mb,TYPE_any));
				q =  pushArgument(mb,q,mvcvar);
				q =  pushArgument(mb,q,getArg(p,0));
				mvcvar=  getArg(q,0);
				pushInstruction(mb,q);
				count++;
			}
			continue;
		}
		if( count < MAXdelays && getModuleId(p) == groupRef ){
			if( getFunctionId(p) == subgroupdoneRef || getFunctionId(p) == groupdoneRef ){
				q= newInstruction(0,languageRef,blockRef);
				setDestVar(q, newTmpVariable(mb,TYPE_any));
				q =  pushArgument(mb,q,mvcvar);
				q =  pushArgument(mb,q,getArg(p,0));
				mvcvar=  getArg(q,0);
				pushInstruction(mb,q);
				count++;
			}
		}
		if( getModuleId(p) == sqlRef){
			if ( getFunctionId(p) == bindRef ||
				getFunctionId(p) == bindidxRef || 
				getFunctionId(p)== tidRef ||
				getFunctionId(p)== appendRef ||
				getFunctionId(p)== updateRef ||
				getFunctionId(p)== deleteRef
			){
				setArg(p,p->retc,mvcvar);
			}
		}
	} 
	GDKfree(old);

    /* Defense line against incorrect plans */
    if( count){
        chkTypes(cntxt->usermodule, mb, FALSE);
        chkFlow(mb);
        chkDeclarations(mb);
    }
    /* keep all actions taken as a post block comment */
	usec = GDKusec()- usec;
    snprintf(buf,256,"%-20s actions=%2d time=" LLFMT " usec","volcano",count,usec);
    newComment(mb,buf);
	if( count >= 0)
		addtoMalBlkHistory(mb);

	return msg;
}
Beispiel #7
0
str
OPTmultiplexImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	InstrPtr *old = 0, p;
	int i, limit, slimit, actions= 0;
	str msg= MAL_SUCCEED;
	char buf[256];
	lng usec = GDKusec();

	(void) stk;
	(void) pci;

	old = mb->stmt;
	limit = mb->stop;
	slimit = mb->ssize;
	if ( newMalBlkStmt(mb, mb->ssize) < 0 )
		throw(MAL,"optimizer.mergetable", SQLSTATE(HY001) MAL_MALLOC_FAIL);

	for (i = 0; i < limit; i++) {
		p = old[i];
		if (msg == MAL_SUCCEED && isMultiplex(p)) { 
			if ( MANIFOLDtypecheck(cntxt,mb,p,0) != NULL){
				setFunctionId(p, manifoldRef);
				p->typechk = TYPE_UNKNOWN;
				pushInstruction(mb, p);
				actions++;
				continue;
			}
			msg = OPTexpandMultiplex(cntxt, mb, stk, p);
			if( msg== MAL_SUCCEED){
				freeInstruction(p);
				old[i]=0;
				actions++;
				continue;
			} 

			pushInstruction(mb, p);
			actions++;
		} else if( old[i])
			pushInstruction(mb, p);
	}
	for(;i<slimit; i++)
		if( old[i])
			freeInstruction(old[i]);
	GDKfree(old);

    /* Defense line against incorrect plans */
    if( msg == MAL_SUCCEED &&  actions > 0){
        chkTypes(cntxt->usermodule, mb, FALSE);
        chkFlow(mb);
        chkDeclarations(mb);
    }
    /* keep all actions taken as a post block comment */
	usec = GDKusec()- usec;
    snprintf(buf,256,"%-20s actions=%2d time=" LLFMT " usec","multiplex",actions, usec);
    newComment(mb,buf);
	if( actions >= 0)
		addtoMalBlkHistory(mb);

	return msg;
}
Beispiel #8
0
str 
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;
	char buf[256];
	lng usec = GDKusec();
	str msg = MAL_SUCCEED;

	(void) pci;
	(void) cntxt;
	(void) stk;		/* to fool compilers */
	old= mb->stmt;
	limit= mb->stop;
	slimit = mb->ssize;
	if ( newMalBlkStmt(mb,mb->stop) < 0)
		throw(MAL,"optimizer.json", SQLSTATE(HY001) MAL_MALLOC_FAIL);
	for (i = 0; i < limit; i++) {
		p = old[i];
		if( getModuleId(p) == sqlRef  && getFunctionId(p) == affectedRowsRef) {
			q = newInstruction(0, 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);
			setDestVar(q, newTmpVariable(mb, TYPE_str));
			pushInstruction(mb,p);
			q = newInstruction(0, NULL, NULL);
			q->barrier = RETURNsymbol;
			getArg(q,0)= getArg(p,0);
			pushArgument(mb,q,j);
			pushInstruction(mb,q);
			actions++;
			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);
			actions++;
			continue;
		}
		pushInstruction(mb,p);
	} 
	for(; i<slimit; i++)
		if (old[i]) 
			freeInstruction(old[i]);
	GDKfree(old);
    /* Defense line against incorrect plans */
    if( actions > 0){
        chkTypes(cntxt->usermodule, mb, FALSE);
        chkFlow(mb);
        chkDeclarations(mb);
    }
    /* keep all actions taken as a post block comment */
	usec = GDKusec()- usec;
    snprintf(buf,256,"%-20s actions=%2d time=" LLFMT " usec","json",actions, usec);
    newComment(mb,buf);
	if( actions >= 0)
		addtoMalBlkHistory(mb);

	return msg;
}
Beispiel #9
0
str 
OPTgeneratorImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	InstrPtr p,q, *old, *series;
	int i, k, limit, slimit, actions=0;
	str m;
	str bteRef = getName("bte");
	str shtRef = getName("sht");
	str intRef = getName("int");
	str lngRef = getName("lng");
	str fltRef = getName("flt");
	str dblRef = getName("dbl");
	char buf[256];
	lng usec= GDKusec();

	(void) cntxt;
	(void) stk;
	(void) pci;

	series = (InstrPtr*) GDKzalloc(sizeof(InstrPtr) * mb->vtop);
	if(series == NULL)
		throw(MAL,"optimizer.generator", SQLSTATE(HY001) MAL_MALLOC_FAIL);
	old = mb->stmt;
	limit = mb->stop;
	slimit = mb->ssize;

	// check applicability first
	for( i=0; i < limit; i++){
		p = old[i];
		if ( getModuleId(p) == generatorRef && getFunctionId(p) == seriesRef)
			break;
	}
	if (i == limit) {
		GDKfree(series);
		return 0;
	}
	
	if (newMalBlkStmt(mb, mb->ssize) < 0) {
		GDKfree(series);
		throw(MAL,"optimizer.generator", SQLSTATE(HY001) MAL_MALLOC_FAIL);
	}

	for( i=0; i < limit; i++){
		p = old[i];
		if (p->token == ENDsymbol){
			pushInstruction(mb,p); 
			break;
		}
		if ( getModuleId(p) == generatorRef && getFunctionId(p) == seriesRef){
			series[getArg(p,0)] = p;
			setModuleId(p, generatorRef);
			setFunctionId(p, parametersRef);
			typeChecker(cntxt->usermodule, mb, p, TRUE);
			pushInstruction(mb,p); 
		} else if ( getModuleId(p) == algebraRef && getFunctionId(p) == selectRef && series[getArg(p,1)]){
			errorCheck(p,algebraRef,getArg(p,1));
		} else if ( getModuleId(p) == algebraRef && getFunctionId(p) == thetaselectRef && series[getArg(p,1)]){
			errorCheck(p,algebraRef,getArg(p,1));
		} else if ( getModuleId(p) == algebraRef && getFunctionId(p) == projectionRef && series[getArg(p,2)]){
			errorCheck(p,algebraRef,getArg(p,2));
		} else if ( getModuleId(p) == sqlRef && getFunctionId(p) ==  putName("exportValue") && isaBatType(getArgType(mb,p,0)) ){
			// interface expects scalar type only, not expressable in MAL signature
			mb->errors=createException(MAL, "generate_series", SQLSTATE(42000) "internal error, generate_series is a table producing function");
		}else if ( getModuleId(p) == batcalcRef && getFunctionId(p) == bteRef && series[getArg(p,1)] && p->argc == 2 ){
			casting(bte);
		} else if ( getModuleId(p) == batcalcRef && getFunctionId(p) == shtRef && series[getArg(p,1)] && p->argc == 2 ){
			casting(sht);
		} else if ( getModuleId(p) == batcalcRef && getFunctionId(p) == intRef && series[getArg(p,1)] && p->argc == 2 ){
			casting(int);
		} else if ( getModuleId(p) == batcalcRef && getFunctionId(p) == lngRef && series[getArg(p,1)] && p->argc == 2 ){
			casting(lng);
		} else if ( getModuleId(p) == batcalcRef && getFunctionId(p) == fltRef && series[getArg(p,1)] && p->argc == 2 ){
			casting(flt);
		} else if ( getModuleId(p) == batcalcRef && getFunctionId(p) == dblRef && series[getArg(p,1)] && p->argc == 2 ){
			casting(dbl);
		} else if ( getModuleId(p) == languageRef && getFunctionId(p) == passRef )
			pushInstruction(mb,p);
		else {
			// check for use without conversion
			for(k = p->retc; k < p->argc; k++)
			if( series[getArg(p,k)]){
				m = getModuleId(p);
				setModuleId(p, generatorRef);
				typeChecker(cntxt->usermodule, mb, p, TRUE);
				if(p->typechk == TYPE_UNKNOWN){
					setModuleId(p,m);
					typeChecker(cntxt->usermodule, mb, p, TRUE);
					setModuleId(series[getArg(p,k)], generatorRef);
					setFunctionId(series[getArg(p,k)], seriesRef);
					typeChecker(cntxt->usermodule, mb, series[getArg(p,k)], TRUE);
				}
			}
			pushInstruction(mb,p);
		}
	}
	for (i++; i < limit; i++)
        	pushInstruction(mb, old[i]);
	for (; i < slimit; i++)
		if (old[i])
        		freeInstruction(old[i]);
    	GDKfree(old);
    	GDKfree(series);

#ifdef VLT_DEBUG
	fprintFunction(stderr,mb,0,LIST_MAL_ALL);
#endif

    /* Defense line against incorrect plans */
	/* all new/modified statements are already checked */
	//chkTypes(cntxt->usermodule, mb, FALSE);
	//chkFlow(mb);
	//chkDeclarations(mb);
    /* keep all actions taken as a post block comment */
	usec = GDKusec()- usec;
    snprintf(buf,256,"%-20s actions=%2d time=" LLFMT " usec","generator",actions, usec);
    newComment(mb,buf);
	if( actions >= 0)
		addtoMalBlkHistory(mb);

	return MAL_SUCCEED;
}
Beispiel #10
0
str
OPToltpImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{	int i, limit, slimit, updates=0;
	InstrPtr p, q, lcks;
	int actions = 0;
	InstrPtr *old;
	lng usec = GDKusec();
	OLTPlocks wlocks, rlocks;
	char buf[256];
	str msg = MAL_SUCCEED;

	(void) pci;
	(void) cntxt;
	(void) stk;		/* to fool compilers */

	old= mb->stmt;
	limit= mb->stop;
	slimit = mb->ssize;
	
	// We use a fake collection of objects to speed up the checking later.
	OLTPclear(wlocks);
	OLTPclear(rlocks);

	for (i = 0; i < limit; i++) {
		p = old[i];
		if( getModuleId(p) == sqlRef && getFunctionId(p) == bindRef)
			addLock(cntxt,rlocks, mb, p, p->retc + 1, p->retc + 2);
		else
		if( getModuleId(p) == sqlRef && getFunctionId(p) == bindidxRef)
			addLock(cntxt,rlocks, mb, p, p->retc + 1, p->retc + 2);
		else
		if( getModuleId(p) == sqlRef && getFunctionId(p) == appendRef ){
			addLock(cntxt,wlocks, mb, p, p->retc + 1, p->retc + 2);
			updates++;
		} else
		if( getModuleId(p) == sqlRef && getFunctionId(p) == updateRef ){
			addLock(cntxt,wlocks, mb, p, p->retc + 1, p->retc + 2);
			updates++;
		} else
		if( getModuleId(p) == sqlRef && getFunctionId(p) == deleteRef ){
			addLock(cntxt,wlocks, mb, p, p->retc + 1, p->retc + 2);
			updates++;
		} else
		if( getModuleId(p) == sqlcatalogRef ){
			addLock(cntxt,wlocks, mb, p, 0,0);
			updates++;
		}
	}
	
	if( updates == 0)
		return 0;

	// Get a free instruction, don't get it from mb
	lcks= newInstruction(0, oltpRef,lockRef);
	getArg(lcks,0)= newTmpVariable(mb, TYPE_void);

	for( i = 0; i< MAXOLTPLOCKS; i++)
	if( wlocks[i])
		lcks = pushInt(mb, lcks, i);
	else 
	if( rlocks[i])
		lcks = pushInt(mb, lcks, -i);

	if( lcks->argc == 1 ){
		freeInstruction(lcks);
		return MAL_SUCCEED;
	}

	// Now optimize the code
	if ( newMalBlkStmt(mb,mb->ssize + 6) < 0) {
		freeInstruction(lcks);
		return 0;
	}
	pushInstruction(mb,old[0]);
	pushInstruction(mb,lcks);
	for (i = 1; i < limit; i++) {
		p = old[i];
		if( p->token == ENDsymbol){
			// unlock all if there is an error
			q= newCatchStmt(mb,"MALexception");
			q= newExitStmt(mb,"MALexception");
			q= newCatchStmt(mb,"SQLexception");
			q= newExitStmt(mb,"SQLexception");
			q= copyInstruction(lcks);
			if( q == NULL){
				for(; i<slimit; i++)
					if( old[i])
						freeInstruction(old[i]);
				GDKfree(old);
				throw(MAL,"optimizer.oltp", SQLSTATE(HY001) MAL_MALLOC_FAIL);
			}
			setFunctionId(q, releaseRef);
			pushInstruction(mb,q);
		}
		pushInstruction(mb,p);
	} 
	for(; i<slimit; i++)
		if( old[i])
			freeInstruction(old[i]);
	GDKfree(old);

    /* Defense line against incorrect plans */
	chkTypes(cntxt->usermodule, mb, FALSE);
	//chkFlow(mb);
	//chkDeclarations(mb);
    /* keep all actions taken as a post block comment */
	usec = GDKusec()- usec;
    snprintf(buf,256,"%-20s actions=%2d time=" LLFMT " usec","oltp",actions, usec);
    newComment(mb,buf);
	if( actions >= 0)
		addtoMalBlkHistory(mb);
	return msg;
}