コード例 #1
0
    /*
** Locate or create an AutoincInfo structure associated with table pTab
** which is in database iDb.  Return the register number for the register
** that holds the maximum rowid.
**
** There is at most one AutoincInfo structure per table even if the
** same table is autoincremented multiple times due to inserts within
** triggers.  A new AutoincInfo structure is created if this is the
** first use of table pTab.  On 2nd and subsequent uses, the original
** AutoincInfo structure is used.
**
** Three memory locations are allocated:
**
**   (1)  Register to hold the name of the pTab table.
**   (2)  Register to hold the maximum ROWID of pTab.
**   (3)  Register to hold the rowid in sqlite_sequence of pTab
**
** The 2nd register is the one that is returned.  That is all the
** insert routine needs to know about.
*/
    static int autoIncBegin(
    Parse pParse,      /* Parsing context */
    int iDb,            /* Index of the database holding pTab */
    Table pTab         /* The table we are writing to */
    )
    {
      int memId = 0;      /* Register holding maximum rowid */
      if ( ( pTab.tabFlags & TF_Autoincrement ) != 0 )
      {
        Parse pToplevel = sqlite3ParseToplevel( pParse );
        AutoincInfo pInfo;

        pInfo = pToplevel.pAinc;
        while ( pInfo != null && pInfo.pTab != pTab )
        {
          pInfo = pInfo.pNext;
        }
        if ( pInfo == null )
        {
          pInfo = new AutoincInfo();//sqlite3DbMallocRaw(pParse.db, sizeof(*pInfo));
          //if( pInfo==0 ) return 0;
          pInfo.pNext = pToplevel.pAinc;
          pToplevel.pAinc = pInfo;
          pInfo.pTab = pTab;
          pInfo.iDb = iDb;
          pToplevel.nMem++;                  /* Register to hold name of table */
          pInfo.regCtr = ++pToplevel.nMem;  /* Max rowid register */
          pToplevel.nMem++;                  /* Rowid in sqlite_sequence */
        }
        memId = pInfo.regCtr;
      }
      return memId;
    }
コード例 #2
0
        /*
        ** Run the parser on the given SQL string.  The parser structure is
        ** passed in.  An SQLITE_ status code is returned.  If an error occurs
        ** then an and attempt is made to write an error message into
        ** memory obtained from sqlite3_malloc() and to make pzErrMsg point to that
        ** error message.
        */
        static int sqlite3RunParser(Parse pParse, string zSql, ref string pzErrMsg)
        {
            int      nErr = 0;             /* Number of errors encountered */
            int      i;                    /* Loop counter */
            yyParser pEngine;              /* The LEMON-generated LALR(1) parser */
            int      tokenType       = 0;  /* type of the next token */
            int      lastTokenParsed = -1; /* type of the previous token */
            byte     enableLookaside;      /* Saved value of db->lookaside.bEnabled */
            sqlite3  db = pParse.db;       /* The database connection */
            int      mxSqlLen;             /* Max length of an SQL string */


            mxSqlLen = db.aLimit[SQLITE_LIMIT_SQL_LENGTH];
            if (db.activeVdbeCnt == 0)
            {
                db.u1.isInterrupted = false;
            }
            pParse.rc    = SQLITE_OK;
            pParse.zTail = new StringBuilder(zSql);
            i            = 0;
            Debug.Assert(pzErrMsg != null);
            pEngine = sqlite3ParserAlloc();//sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc);
            if (pEngine == null)
            {
////        db.mallocFailed = 1;
                return(SQLITE_NOMEM);
            }
            Debug.Assert(pParse.pNewTable == null);
            Debug.Assert(pParse.pNewTrigger == null);
            Debug.Assert(pParse.nVar == 0);
            Debug.Assert(pParse.nVarExpr == 0);
            Debug.Assert(pParse.nVarExprAlloc == 0);
            Debug.Assert(pParse.apVarExpr == null);
            enableLookaside = db.lookaside.bEnabled;
            if (db.lookaside.pStart != 0)
            {
                db.lookaside.bEnabled = 1;
            }
            while (/*  0 == db.mallocFailed && */ i < zSql.Length)
            {
                Debug.Assert(i >= 0);
                //pParse->sLastToken.z = &zSql[i];
                pParse.sLastToken.n = sqlite3GetToken(zSql, i, ref tokenType);
                pParse.sLastToken.z = zSql.Substring(i);
                i += pParse.sLastToken.n;
                if (i > mxSqlLen)
                {
                    pParse.rc = SQLITE_TOOBIG;
                    break;
                }
                switch (tokenType)
                {
                case TK_SPACE:
                {
                    if (db.u1.isInterrupted)
                    {
                        sqlite3ErrorMsg(pParse, "interrupt");
                        pParse.rc = SQLITE_INTERRUPT;
                        goto abort_parse;
                    }
                    break;
                }

                case TK_ILLEGAL:
                {
                    //sqlite3DbFree( db, ref pzErrMsg );
                    pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
                                              (object)pParse.sLastToken);
                    nErr++;
                    goto abort_parse;
                }

                case TK_SEMI:
                {
                    //pParse.zTail = new StringBuilder(zSql.Substring( i,zSql.Length-i ));
                    /* Fall thru into the default case */
                    goto default;
                }

                default:
                {
                    sqlite3Parser(pEngine, tokenType, pParse.sLastToken, pParse);
                    lastTokenParsed = tokenType;
                    if (pParse.rc != SQLITE_OK)
                    {
                        goto abort_parse;
                    }
                    break;
                }
                }
            }
abort_parse:
            pParse.zTail = new StringBuilder(zSql.Length <= i ? "" : zSql.Substring(i, zSql.Length - i));
            if (zSql.Length >= i && nErr == 0 && pParse.rc == SQLITE_OK)
            {
                if (lastTokenParsed != TK_SEMI)
                {
                    sqlite3Parser(pEngine, TK_SEMI, pParse.sLastToken, pParse);
                }
                sqlite3Parser(pEngine, 0, pParse.sLastToken, pParse);
            }
#if YYTRACKMAXSTACKDEPTH
            sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
                             sqlite3ParserStackPeak(pEngine)
                             );
#endif //* YYDEBUG */
            sqlite3ParserFree(pEngine, null);//sqlite3_free );
            db.lookaside.bEnabled = enableLookaside;
            //if ( db.mallocFailed != 0 )
            //{
            //  pParse.rc = SQLITE_NOMEM;
            //}
            if (pParse.rc != SQLITE_OK && pParse.rc != SQLITE_DONE && pParse.zErrMsg == "")
            {
                sqlite3SetString(ref pParse.zErrMsg, db, sqlite3ErrStr(pParse.rc));
            }
            //assert( pzErrMsg!=0 );
            if (pParse.zErrMsg != null)
            {
                pzErrMsg       = pParse.zErrMsg;
                pParse.zErrMsg = "";
                nErr++;
            }
            if (pParse.pVdbe != null && pParse.nErr > 0 && pParse.nested == 0)
            {
                sqlite3VdbeDelete(ref pParse.pVdbe);
                pParse.pVdbe = null;
            }
#if !SQLITE_OMIT_SHARED_CACHE
            if (pParse.nested == 0)
            {
//sqlite3DbFree( db, ref pParse.aTableLock );
                pParse.aTableLock = null;
                pParse.nTableLock = 0;
            }
#endif
#if !SQLITE_OMIT_VIRTUALTABLE
//sqlite3DbFree(db,pParse.apVtabLock);
#endif
            if (!IN_DECLARE_VTAB)
            {
                /* If the pParse.declareVtab flag is set, do not delete any table
                ** structure built up in pParse.pNewTable. The calling code (see vtab.c)
                ** will take responsibility for freeing the Table structure.
                */
                sqlite3DeleteTable(ref pParse.pNewTable);
            }

#if !SQLITE_OMIT_TRIGGER
            sqlite3DeleteTrigger(db, ref pParse.pNewTrigger);
#endif
            //sqlite3DbFree( db, ref pParse.apVarExpr );
            //sqlite3DbFree( db, ref pParse.aAlias );
            while (pParse.pAinc != null)
            {
                AutoincInfo p = pParse.pAinc;
                pParse.pAinc = p.pNext;
                //sqlite3DbFree( db, ref p );
            }
            while (pParse.pZombieTab != null)
            {
                Table p = pParse.pZombieTab;
                pParse.pZombieTab = p.pNextZombie;
                sqlite3DeleteTable(ref p);
            }
            if (nErr > 0 && pParse.rc == SQLITE_OK)
            {
                pParse.rc = SQLITE_ERROR;
            }
            return(nErr);
        }
コード例 #3
0
        public int RunParser(string sql, ref string errMsg)
        {
            Debug.Assert(errMsg != null);
            Debug.Assert(NewTable == null);
            Debug.Assert(NewTrigger == null);
            Debug.Assert(VarsSeen == 0);
            Debug.Assert(Vars.length == 0);
            Debug.Assert(Vars.data == null);
            Context ctx          = Ctx;                               // The database connection
            int     maxSqlLength = ctx.Limits[(int)LIMIT.SQL_LENGTH]; // Max length of an SQL string

            if (ctx.ActiveVdbeCnt == 0)
            {
                ctx.u1.IsInterrupted = false;
            }
            RC   = RC.OK;
            Tail = new StringBuilder(sql);
            yyParser engine = Parser_Alloc(); // The LEMON-generated LALR(1) parser

            if (engine == null)
            {
                ctx.MallocFailed = true;
                return((int)RC.NOMEM);
            }
            bool enableLookaside = ctx.Lookaside.Enabled; // Saved value of db->lookaside.bEnabled

            if (ctx.Lookaside.Start != 0)
            {
                ctx.Lookaside.Enabled = true;
            }
            int errs            = 0;      // Number of errors encountered
            TK  tokenType       = 0;      // type of the next token
            TK  lastTokenParsed = 0;      // type of the previous token
            int i = 0;

            while (/*  !ctx.MallocFailed && */ i < sql.Length)
            {
                Debug.Assert(i >= 0);
                LastToken.data   = sql.Substring(i);
                LastToken.length = (uint)GetToken(sql, i, ref tokenType);
                i += (int)LastToken.length;
                if (i > maxSqlLength)
                {
                    RC = RC.TOOBIG;
                    break;
                }
                switch (tokenType)
                {
                case TK.SPACE:
                {
                    if (ctx.u1.IsInterrupted)
                    {
                        ErrorMsg("interrupt");
                        RC = RC.INTERRUPT;
                        goto abort_parse;
                    }
                    break;
                }

                case TK.ILLEGAL:
                {
                    C._tagfree(ctx, ref errMsg);
                    errMsg = SysEx.Mprintf(ctx, "unrecognized token: \"%T\"", (object)LastToken);
                    errs++;
                    goto abort_parse;
                }

                case TK.SEMI:
                {
                    //Tail = new StringBuilder(sql.Substring(i, sql.Length - i));
                    goto default;
                }

                default:
                {
                    Parser(engine, tokenType, LastToken, this);
                    lastTokenParsed = tokenType;
                    if (RC != RC.OK)
                    {
                        goto abort_parse;
                    }
                    break;
                }
                }
            }
abort_parse:
            Tail = new StringBuilder(sql.Length <= i ? string.Empty : sql.Substring(i, sql.Length - i));
            if (sql.Length >= i && errs == 0 && RC == RC.OK)
            {
                if (lastTokenParsed != TK.SEMI)
                {
                    Parser(engine, TK.SEMI, LastToken, this);
                }
                Parser(engine, 0, LastToken, this);
            }
#if YYTRACKMAXSTACKDEPTH
            sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK, sqlite3ParserStackPeak(engine));
#endif
            Parser_Free(engine, null);
            ctx.Lookaside.Enabled = enableLookaside;
            //if (ctx.MallocFailed)
            //    RC = RC.NOMEM;
            if (RC != RC.OK && RC != RC.DONE && string.IsNullOrEmpty(ErrMsg))
            {
                SetString(ref ErrMsg, ctx, ErrStr(RC));
            }
            if (ErrMsg != null)
            {
                errMsg = ErrMsg;
                SysEx.LOG(RC, "%s", errMsg);
                ErrMsg = string.Empty;
                errs++;
            }
            if (V != null && Errs > 0 && Nested == 0)
            {
                Vdbe.Delete(ref V);
                V = null;
            }
#if !OMIT_SHARED_CACHE
            if (Nested == 0)
            {
                C._tagfree(ctx, ref TableLocks.data);
                TableLocks.data   = null;
                TableLocks.length = 0;
            }
#endif
#if !OMIT_VIRTUALTABLE
            VTableLocks.data = null;
#endif
            if (!E.INDECLARE_VTABLE(this))
            {
                // If the pParse.declareVtab flag is set, do not delete any table structure built up in pParse.pNewTable. The calling code (see vtab.c)
                // will take responsibility for freeing the Table structure.
                DeleteTable(ctx, ref NewTable);
            }

#if !OMIT_TRIGGER
            DeleteTrigger(ctx, ref NewTrigger);
#endif
            //for (i = Vars.length - 1; i >= 0; i--)
            //    C._tagfree(ctx, ref Vars.data[i]);
            C._tagfree(ctx, ref Vars.data);
            C._tagfree(ctx, ref Alias.data);
            while (Ainc != null)
            {
                AutoincInfo p = Ainc;
                Ainc = p.Next;
                C._tagfree(ctx, ref p);
            }
            while (ZombieTab != null)
            {
                Table p = ZombieTab;
                ZombieTab = p.NextZombie;
                DeleteTable(ctx, ref p);
            }
            if (errs > 0 && RC == RC.OK)
            {
                RC = RC.ERROR;
            }
            return(errs);
        }