⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 build.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 5 页
字号:
/*** 2001 September 15**** The author disclaims copyright to this source code.  In place of** a legal notice, here is a blessing:****    May you do good and not evil.**    May you find forgiveness for yourself and forgive others.**    May you share freely, never taking more than you give.***************************************************************************** This file contains C code routines that are called by the SQLite parser** when syntax rules are reduced.  The routines in this file handle the** following kinds of SQL syntax:****     CREATE TABLE**     DROP TABLE**     CREATE INDEX**     DROP INDEX**     creating ID lists**     BEGIN TRANSACTION**     COMMIT**     ROLLBACK**** $Id: build.c,v 1.433 2007/07/02 19:31:27 drh Exp $*/#include "sqliteInt.h"#include <ctype.h>/*** This routine is called when a new SQL statement is beginning to** be parsed.  Initialize the pParse structure as needed.*/void sqlite3BeginParse(Parse *pParse, int explainFlag){  pParse->explain = explainFlag;  pParse->nVar = 0;}#ifndef SQLITE_OMIT_SHARED_CACHE/*** The TableLock structure is only used by the sqlite3TableLock() and** codeTableLocks() functions.*/struct TableLock {  int iDb;             /* The database containing the table to be locked */  int iTab;            /* The root page of the table to be locked */  u8 isWriteLock;      /* True for write lock.  False for a read lock */  const char *zName;   /* Name of the table */};/*** Record the fact that we want to lock a table at run-time.  **** The table to be locked has root page iTab and is found in database iDb.** A read or a write lock can be taken depending on isWritelock.**** This routine just records the fact that the lock is desired.  The** code to make the lock occur is generated by a later call to** codeTableLocks() which occurs during sqlite3FinishCoding().*/void sqlite3TableLock(  Parse *pParse,     /* Parsing context */  int iDb,           /* Index of the database containing the table to lock */  int iTab,          /* Root page number of the table to be locked */  u8 isWriteLock,    /* True for a write lock */  const char *zName  /* Name of the table to be locked */){  int i;  int nBytes;  TableLock *p;  if( 0==sqlite3ThreadDataReadOnly()->useSharedData || iDb<0 ){    return;  }  for(i=0; i<pParse->nTableLock; i++){    p = &pParse->aTableLock[i];    if( p->iDb==iDb && p->iTab==iTab ){      p->isWriteLock = (p->isWriteLock || isWriteLock);      return;    }  }  nBytes = sizeof(TableLock) * (pParse->nTableLock+1);  pParse->aTableLock = sqliteReallocOrFree(pParse->aTableLock, nBytes);  if( pParse->aTableLock ){    p = &pParse->aTableLock[pParse->nTableLock++];    p->iDb = iDb;    p->iTab = iTab;    p->isWriteLock = isWriteLock;    p->zName = zName;  }}/*** Code an OP_TableLock instruction for each table locked by the** statement (configured by calls to sqlite3TableLock()).*/static void codeTableLocks(Parse *pParse){  int i;  Vdbe *pVdbe;   assert( sqlite3ThreadDataReadOnly()->useSharedData || pParse->nTableLock==0 );  if( 0==(pVdbe = sqlite3GetVdbe(pParse)) ){    return;  }  for(i=0; i<pParse->nTableLock; i++){    TableLock *p = &pParse->aTableLock[i];    int p1 = p->iDb;    if( p->isWriteLock ){      p1 = -1*(p1+1);    }    sqlite3VdbeOp3(pVdbe, OP_TableLock, p1, p->iTab, p->zName, P3_STATIC);  }}#else  #define codeTableLocks(x)#endif/*** This routine is called after a single SQL statement has been** parsed and a VDBE program to execute that statement has been** prepared.  This routine puts the finishing touches on the** VDBE program and resets the pParse structure for the next** parse.**** Note that if an error occurred, it might be the case that** no VDBE code was generated.*/void sqlite3FinishCoding(Parse *pParse){  sqlite3 *db;  Vdbe *v;  if( sqlite3MallocFailed() ) return;  if( pParse->nested ) return;  if( !pParse->pVdbe ){    if( pParse->rc==SQLITE_OK && pParse->nErr ){      pParse->rc = SQLITE_ERROR;      return;    }  }  /* Begin by generating some termination code at the end of the  ** vdbe program  */  db = pParse->db;  v = sqlite3GetVdbe(pParse);  if( v ){    sqlite3VdbeAddOp(v, OP_Halt, 0, 0);    /* The cookie mask contains one bit for each database file open.    ** (Bit 0 is for main, bit 1 is for temp, and so forth.)  Bits are    ** set for each database that is used.  Generate code to start a    ** transaction on each used database and to verify the schema cookie    ** on each used database.    */    if( pParse->cookieGoto>0 ){      u32 mask;      int iDb;      sqlite3VdbeJumpHere(v, pParse->cookieGoto-1);      for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){        if( (mask & pParse->cookieMask)==0 ) continue;        sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0);        sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);      }#ifndef SQLITE_OMIT_VIRTUALTABLE      if( pParse->pVirtualLock ){        char *vtab = (char *)pParse->pVirtualLock->pVtab;        sqlite3VdbeOp3(v, OP_VBegin, 0, 0, vtab, P3_VTAB);      }#endif      /* Once all the cookies have been verified and transactions opened,       ** obtain the required table-locks. This is a no-op unless the       ** shared-cache feature is enabled.      */      codeTableLocks(pParse);      sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto);    }#ifndef SQLITE_OMIT_TRACE    /* Add a No-op that contains the complete text of the compiled SQL    ** statement as its P3 argument.  This does not change the functionality    ** of the program.     **    ** This is used to implement sqlite3_trace().    */    sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql);#endif /* SQLITE_OMIT_TRACE */  }  /* Get the VDBE program ready for execution  */  if( v && pParse->nErr==0 && !sqlite3MallocFailed() ){#ifdef SQLITE_DEBUG    FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;    sqlite3VdbeTrace(v, trace);#endif    sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3,                         pParse->nTab+3, pParse->explain);    pParse->rc = SQLITE_DONE;    pParse->colNamesSet = 0;  }else if( pParse->rc==SQLITE_OK ){    pParse->rc = SQLITE_ERROR;  }  pParse->nTab = 0;  pParse->nMem = 0;  pParse->nSet = 0;  pParse->nVar = 0;  pParse->cookieMask = 0;  pParse->cookieGoto = 0;}/*** Run the parser and code generator recursively in order to generate** code for the SQL statement given onto the end of the pParse context** currently under construction.  When the parser is run recursively** this way, the final OP_Halt is not appended and other initialization** and finalization steps are omitted because those are handling by the** outermost parser.**** Not everything is nestable.  This facility is designed to permit** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER.  Use** care if you decide to try to use this routine for some other purposes.*/void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){  va_list ap;  char *zSql;# define SAVE_SZ  (sizeof(Parse) - offsetof(Parse,nVar))  char saveBuf[SAVE_SZ];  if( pParse->nErr ) return;  assert( pParse->nested<10 );  /* Nesting should only be of limited depth */  va_start(ap, zFormat);  zSql = sqlite3VMPrintf(zFormat, ap);  va_end(ap);  if( zSql==0 ){    return;   /* A malloc must have failed */  }  pParse->nested++;  memcpy(saveBuf, &pParse->nVar, SAVE_SZ);  memset(&pParse->nVar, 0, SAVE_SZ);  sqlite3RunParser(pParse, zSql, 0);  sqliteFree(zSql);  memcpy(&pParse->nVar, saveBuf, SAVE_SZ);  pParse->nested--;}/*** Locate the in-memory structure that describes a particular database** table given the name of that table and (optionally) the name of the** database containing the table.  Return NULL if not found.**** If zDatabase is 0, all databases are searched for the table and the** first matching table is returned.  (No checking for duplicate table** names is done.)  The search order is TEMP first, then MAIN, then any** auxiliary databases added using the ATTACH command.**** See also sqlite3LocateTable().*/Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){  Table *p = 0;  int i;  assert( zName!=0 );  for(i=OMIT_TEMPDB; i<db->nDb; i++){    int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */    if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;    p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, strlen(zName)+1);    if( p ) break;  }  return p;}/*** Locate the in-memory structure that describes a particular database** table given the name of that table and (optionally) the name of the** database containing the table.  Return NULL if not found.  Also leave an** error message in pParse->zErrMsg.**** The difference between this routine and sqlite3FindTable() is that this** routine leaves an error message in pParse->zErrMsg where** sqlite3FindTable() does not.*/Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){  Table *p;  /* Read the database schema. If an error occurs, leave an error message  ** and code in pParse and return NULL. */  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){    return 0;  }  p = sqlite3FindTable(pParse->db, zName, zDbase);  if( p==0 ){    if( zDbase ){      sqlite3ErrorMsg(pParse, "no such table: %s.%s", zDbase, zName);    }else{      sqlite3ErrorMsg(pParse, "no such table: %s", zName);    }    pParse->checkSchema = 1;  }  return p;}/*** Locate the in-memory structure that describes ** a particular index given the name of that index** and the name of the database that contains the index.** Return NULL if not found.**** If zDatabase is 0, all databases are searched for the** table and the first matching index is returned.  (No checking** for duplicate index names is done.)  The search order is** TEMP first, then MAIN, then any auxiliary databases added** using the ATTACH command.*/Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){  Index *p = 0;  int i;  for(i=OMIT_TEMPDB; i<db->nDb; i++){    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */    Schema *pSchema = db->aDb[j].pSchema;    if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;    assert( pSchema || (j==1 && !db->aDb[1].pBt) );    if( pSchema ){      p = sqlite3HashFind(&pSchema->idxHash, zName, strlen(zName)+1);    }    if( p ) break;  }  return p;}/*** Reclaim the memory used by an index*/static void freeIndex(Index *p){  sqliteFree(p->zColAff);  sqliteFree(p);}/*** Remove the given index from the index hash table, and free** its memory structures.**** The index is removed from the database hash tables but** it is not unlinked from the Table that it indexes.** Unlinking from the Table must be done by the calling function.*/static void sqliteDeleteIndex(Index *p){  Index *pOld;  const char *zName = p->zName;  pOld = sqlite3HashInsert(&p->pSchema->idxHash, zName, strlen( zName)+1, 0);  assert( pOld==0 || pOld==p );  freeIndex(p);}/*** For the index called zIdxName which is found in the database iDb,** unlike that index from its Table then remove the index from** the index hash table and free all memory structures associated** with the index.*/void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){  Index *pIndex;  int len;  Hash *pHash = &db->aDb[iDb].pSchema->idxHash;  len = strlen(zIdxName);  pIndex = sqlite3HashInsert(pHash, zIdxName, len+1, 0);  if( pIndex ){    if( pIndex->pTable->pIndex==pIndex ){      pIndex->pTable->pIndex = pIndex->pNext;    }else{      Index *p;      for(p=pIndex->pTable->pIndex; p && p->pNext!=pIndex; p=p->pNext){}      if( p && p->pNext==pIndex ){        p->pNext = pIndex->pNext;      }    }    freeIndex(pIndex);  }  db->flags |= SQLITE_InternChanges;}/*** Erase all schema information from the in-memory hash tables of** a single database.  This routine is called to reclaim memory** before the database closes.  It is also called during a rollback** if there were schema changes during the transaction or if a** schema-cookie mismatch occurs.**** If iDb<=0 then reset the internal schema tables for all database** files.  If iDb>=2 then reset the internal schema for only the** single file indicated.*/void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){  int i, j;  assert( iDb>=0 && iDb<db->nDb );  for(i=iDb; i<db->nDb; i++){    Db *pDb = &db->aDb[i];    if( pDb->pSchema ){      sqlite3SchemaFree(pDb->pSchema);    }    if( iDb>0 ) return;  }  assert( iDb==0 );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -