/* ** Generate the end of the WHERE loop. See comments on ** sqliteWhereBegin() for additional information. */ void sqliteWhereEnd(WhereInfo *pWInfo) { Vdbe *v = pWInfo->pParse->pVdbe; int i; WhereLevel *pLevel; SrcList *pTabList = pWInfo->pTabList; for(i=pTabList->nSrc-1; i>=0; i--) { pLevel = &pWInfo->a[i]; sqliteVdbeResolveLabel(v, pLevel->cont); if( pLevel->op!=OP_Noop ) { sqliteVdbeAddOp(v, pLevel->op, pLevel->p1, pLevel->p2); } sqliteVdbeResolveLabel(v, pLevel->brk); if( pLevel->inOp!=OP_Noop ) { sqliteVdbeAddOp(v, pLevel->inOp, pLevel->inP1, pLevel->inP2); } if( pLevel->iLeftJoin ) { int addr; addr = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iLeftJoin, 0); sqliteVdbeAddOp(v, OP_NotNull, 1, addr+4 + (pLevel->iCur>=0)); sqliteVdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0); if( pLevel->iCur>=0 ) { sqliteVdbeAddOp(v, OP_NullRow, pLevel->iCur, 0); } sqliteVdbeAddOp(v, OP_Goto, 0, pLevel->top); } } sqliteVdbeResolveLabel(v, pWInfo->iBreak); for(i=0; i<pTabList->nSrc; i++) { Table *pTab = pTabList->a[i].pTab; assert( pTab!=0 ); if( pTab->isTransient || pTab->pSelect ) continue; pLevel = &pWInfo->a[i]; sqliteVdbeAddOp(v, OP_Close, pTabList->a[i].iCursor, 0); if( pLevel->pIdx!=0 ) { sqliteVdbeAddOp(v, OP_Close, pLevel->iCur, 0); } } #if 0 /* Never reuse a cursor */ if( pWInfo->pParse->nTab==pWInfo->peakNTab ) { pWInfo->pParse->nTab = pWInfo->savedNTab; } #endif sqliteFree(pWInfo); return; }
/* ** Convert an ansi string to microsoft unicode, based on the ** current codepage settings for file apis. ** ** Space to hold the returned string is obtained ** from sqliteMalloc. */ static WCHAR *mbcsToUnicode(const char *zFilename){ int nByte; WCHAR *zMbcsFilename; int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR); zMbcsFilename = sqliteMalloc( nByte*sizeof(zMbcsFilename[0]) ); if( zMbcsFilename==0 ){ return 0; } nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte); if( nByte==0 ){ sqliteFree(zMbcsFilename); zMbcsFilename = 0; } return zMbcsFilename; }
/* ** Convert microsoft unicode to UTF-8. Space to hold the returned string is ** obtained from sqliteMalloc(). */ static char *unicodeToUtf8(const WCHAR *zWideFilename){ int nByte; char *zFilename; nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); zFilename = sqliteMalloc( nByte ); if( zFilename==0 ){ return 0; } nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, 0, 0); if( nByte == 0 ){ sqliteFree(zFilename); zFilename = 0; } return zFilename; }
/* ** Register a new collation sequence with the database handle db. */ int sqlite3_create_collation16( sqlite3* db, const char *zName, int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*) ){ int rc = SQLITE_OK; char *zName8; assert( !sqlite3MallocFailed() ); zName8 = sqlite3Utf16to8(zName, -1); if( zName8 ){ rc = createCollation(db, zName8, enc, pCtx, xCompare, 0); sqliteFree(zName8); } return sqlite3ApiExit(db, rc); }
/* ** Release any memory held by the Mem. This may leave the Mem in an ** inconsistent state, for example with (Mem.z==0) and ** (Mem.type==SQLITE_TEXT). */ void sqlite3VdbeMemRelease(Mem *p){ if( p->flags & (MEM_Dyn|MEM_Agg) ){ if( p->xDel ){ if( p->flags & MEM_Agg ){ sqlite3VdbeMemFinalize(p, *(FuncDef**)&p->i); assert( (p->flags & MEM_Agg)==0 ); sqlite3VdbeMemRelease(p); }else{ p->xDel((void *)p->z); } }else{ sqliteFree(p->z); } p->z = 0; p->xDel = 0; } }
static int sqliteCompileCall( Parse *pParse, Token *pName, ExprList *pEList ) { char *zName = 0; Vdbe *v = sqliteGetVdbe(pParse); Block *b = pParse->pCurrentBlock; Object * pObj = 0; sqlite *db = pParse->db; int i, nActual = 0; /* Check that the object exist & get its Object pointer*/ zName = sqliteStrNDup(pName->z, pName->n); sqliteDequote(zName); pObj = sqliteHashFind(&(db->aDb[0].objectHash), zName,pName->n+1); if( !pObj ){ sqliteErrorMsg(pParse, "object %T not found", pName); goto proc_cleanup; } if( pEList ) { nActual = pEList->nExpr; } if( pObj->nParam!=nActual ) { sqliteErrorMsg(pParse, "bad parameter count for object %T", pName); goto proc_cleanup; } for(i=0; i<nActual; i++) { Expr *pExpr = pEList->a[i].pExpr; if( sqliteExprProcResolve(pParse, b, pExpr) ){ goto proc_cleanup; } if( sqliteExprCheck(pParse, pExpr, 0, 0) ){ goto proc_cleanup; } sqliteExprCode(pParse, pExpr); } sqliteVdbeOp3(v, OP_Exec, nActual, 0, zName, P3_DYNAMIC); return 0; proc_cleanup: sqliteFree(zName); return 1; }
/* ** Convert microsoft unicode to multibyte character string, based on the ** user's Ansi codepage. ** ** Space to hold the returned string is obtained from ** sqliteMalloc(). */ static char *unicodeToMbcs(const WCHAR *zWideFilename){ int nByte; char *zFilename; int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); zFilename = sqliteMalloc( nByte ); if( zFilename==0 ){ return 0; } nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte, 0, 0); if( nByte == 0 ){ sqliteFree(zFilename); zFilename = 0; } return zFilename; }
/* ** Return TRUE if the named file exists. */ int sqlite3WinFileExists(const char *zFilename){ int exists = 0; void *zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return SQLITE_NOMEM; } if( isNT() ){ exists = GetFileAttributesW((WCHAR*)zConverted) != 0xffffffff; }else{ #if OS_WINCE return SQLITE_NOMEM; #else exists = GetFileAttributesA((char*)zConverted) != 0xffffffff; #endif } sqliteFree(zConverted); return exists; }
/* ** Append text to a dstr */ static void dstrAppend(struct dstr *p, const char *z, int divider){ int n = strlen(z); if( p->nUsed + n + 2 > p->nAlloc ){ char *zNew; p->nAlloc = p->nAlloc*2 + n + 200; zNew = sqliteRealloc(p->z, p->nAlloc); if( zNew==0 ){ sqliteFree(p->z); memset(p, 0, sizeof(*p)); return; } p->z = zNew; } if( divider && p->nUsed>0 ){ p->z[p->nUsed++] = divider; } memcpy(&p->z[p->nUsed], z, n+1); p->nUsed += n; }
/* ** This routine is called by the parser to process a DETACH statement: ** ** DETACH DATABASE dbname ** ** The pDbname argument is the name of the database in the DETACH statement. */ void sqlite3Detach(Parse *pParse, Token *pDbname){ int i; sqlite3 *db; Vdbe *v; Db *pDb = 0; char *zName; v = sqlite3GetVdbe(pParse); if( !v ) return; sqlite3VdbeAddOp(v, OP_Expire, 0, 0); sqlite3VdbeAddOp(v, OP_Halt, 0, 0); if( pParse->explain ) return; db = pParse->db; zName = sqlite3NameFromToken(pDbname); if( zName==0 ) return; for(i=0; i<db->nDb; i++){ pDb = &db->aDb[i]; if( pDb->pBt==0 ) continue; if( sqlite3StrICmp(pDb->zName, zName)==0 ) break; } if( i>=db->nDb ){ sqlite3ErrorMsg(pParse, "no such database: %z", zName); return; } if( i<2 ){ sqlite3ErrorMsg(pParse, "cannot detach database %z", zName); return; } sqliteFree(zName); if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "cannot DETACH database within transaction"); pParse->rc = SQLITE_ERROR; return; } #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){ return; } #endif /* SQLITE_OMIT_AUTHORIZATION */ sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; sqlite3ResetInternalSchema(db, 0); }
/* ** Generate the text of a WHERE expression which can be used to select all ** temporary triggers on table pTab from the sqlite_temp_master table. If ** table pTab has no temporary triggers, or is itself stored in the ** temporary database, NULL is returned. */ static char *whereTempTriggers(Parse *pParse, Table *pTab){ Trigger *pTrig; char *zWhere = 0; char *tmp = 0; if( pTab->iDb!=1 ){ for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){ if( pTrig->iDb==1 ){ if( !zWhere ){ zWhere = sqlite3MPrintf("name=%Q", pTrig->name); }else{ tmp = zWhere; zWhere = sqlite3MPrintf("%s OR name=%Q", zWhere, pTrig->name); sqliteFree(tmp); } } } } return zWhere; }
/* ** Attempt to open a new file for read-only access. ** ** On success, write the file handle into *id and return SQLITE_OK. ** ** On failure, return SQLITE_CANTOPEN. */ int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){ winFile f; HANDLE h; void *zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return SQLITE_NOMEM; } assert( *pId==0 ); if( isNT() ){ h = CreateFileW((WCHAR*)zConverted, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL ); }else{ #if OS_WINCE return SQLITE_NOMEM; #else h = CreateFileA((char*)zConverted, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL ); #endif } sqliteFree(zConverted); if( h==INVALID_HANDLE_VALUE ){ return SQLITE_CANTOPEN; } f.h = h; #if OS_WINCE f.zDeleteOnClose = 0; f.hMutex = NULL; #endif TRACE3("OPEN RO %d \"%s\"\n", h, zFilename); return allocateWinFile(&f, pId); }
/* ** This function is used to set the schema of a virtual table. It is only ** valid to call this function from within the xCreate() or xConnect() of a ** virtual table module. */ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ Parse sParse; int rc = SQLITE_OK; Table *pTab = db->pVTab; char *zErr = 0; if( !pTab ){ sqlite3Error(db, SQLITE_MISUSE, 0); return SQLITE_MISUSE; } assert(pTab->isVirtual && pTab->nCol==0 && pTab->aCol==0); memset(&sParse, 0, sizeof(Parse)); sParse.declareVtab = 1; sParse.db = db; if( SQLITE_OK == sqlite3RunParser(&sParse, zCreateTable, &zErr) && sParse.pNewTable && !sParse.pNewTable->pSelect && !sParse.pNewTable->isVirtual ){ pTab->aCol = sParse.pNewTable->aCol; pTab->nCol = sParse.pNewTable->nCol; sParse.pNewTable->nCol = 0; sParse.pNewTable->aCol = 0; db->pVTab = 0; } else { sqlite3Error(db, SQLITE_ERROR, zErr); sqliteFree(zErr); rc = SQLITE_ERROR; } sParse.declareVtab = 0; sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe); sqlite3DeleteTable(sParse.pNewTable); sParse.pNewTable = 0; assert( (rc&0xff)==rc ); return sqlite3ApiExit(db, rc); }
/* ** External API function used to create a new virtual-table module. */ int sqlite3_create_module( sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ const sqlite3_module *pModule, /* The definition of the module */ void *pAux /* Context pointer for xCreate/xConnect */ ){ int nName = strlen(zName); Module *pMod = (Module *)sqliteMallocRaw(sizeof(Module) + nName + 1); if( pMod ){ char *zCopy = (char *)(&pMod[1]); strcpy(zCopy, zName); pMod->zName = zCopy; pMod->pModule = pModule; pMod->pAux = pAux; pMod = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod); sqliteFree(pMod); sqlite3ResetInternalSchema(db, 0); } return sqlite3ApiExit(db, SQLITE_OK); }
int sqlite3_create_function16( sqlite3 *db, const void *zFunctionName, int nArg, int eTextRep, void *p, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ){ int rc; char *zFunc8; assert( !sqlite3MallocFailed() ); zFunc8 = sqlite3utf16to8(zFunctionName, -1); rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal); sqliteFree(zFunc8); return sqlite3ApiExit(db, rc); }
/* ** Invoke the 'collation needed' callback to request a collation sequence ** in the database text encoding of name zName, length nName. ** If the collation sequence */ static void callCollNeeded(sqlite3 *db, const char *zName, int nName){ assert( !db->xCollNeeded || !db->xCollNeeded16 ); if( nName<0 ) nName = strlen(zName); if( db->xCollNeeded ){ char *zExternal = sqliteStrNDup(zName, nName); if( !zExternal ) return; db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal); sqliteFree(zExternal); } #ifndef SQLITE_OMIT_UTF16 if( db->xCollNeeded16 ){ char const *zExternal; sqlite3_value *pTmp = sqlite3GetTransientValue(db); sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); if( !zExternal ) return; db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal); } #endif }
/* ** Change the value of the P3 operand for a specific instruction. ** This routine is useful when a large program is loaded from a ** static array using sqlite3VdbeAddOpList but we want to make a ** few minor changes to the program. ** ** If n>=0 then the P3 operand is dynamic, meaning that a copy of ** the string is made into memory obtained from sqliteMalloc(). ** A value of n==0 means copy bytes of zP3 up to and including the ** first null byte. If n>0 then copy n+1 bytes of zP3. ** ** If n==P3_STATIC it means that zP3 is a pointer to a constant static ** string and we can just copy the pointer. n==P3_POINTER means zP3 is ** a pointer to some object other than a string. n==P3_COLLSEQ and ** n==P3_KEYINFO mean that zP3 is a pointer to a CollSeq or KeyInfo ** structure. A copy is made of KeyInfo structures into memory obtained ** from sqliteMalloc. ** ** If addr<0 then change P3 on the most recently inserted instruction. */ void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){ Op *pOp; assert( p->magic==VDBE_MAGIC_INIT ); if( p==0 || p->aOp==0 ) return; if( addr<0 || addr>=p->nOp ){ addr = p->nOp - 1; if( addr<0 ) return; } pOp = &p->aOp[addr]; if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){ sqliteFree(pOp->p3); pOp->p3 = 0; } if( zP3==0 ){ pOp->p3 = 0; pOp->p3type = P3_NOTUSED; }else if( n==P3_KEYINFO ){ KeyInfo *pKeyInfo; int nField, nByte; nField = ((KeyInfo*)zP3)->nField; nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]); pKeyInfo = sqliteMallocRaw( nByte ); pOp->p3 = (char*)pKeyInfo; if( pKeyInfo ){ memcpy(pKeyInfo, zP3, nByte); pOp->p3type = P3_KEYINFO; }else{ pOp->p3type = P3_NOTUSED; } }else if( n==P3_KEYINFO_HANDOFF ){ pOp->p3 = (char*)zP3; pOp->p3type = P3_KEYINFO; }else if( n<0 ){ pOp->p3 = (char*)zP3; pOp->p3type = n; }else{ if( n==0 ) n = strlen(zP3); pOp->p3 = sqliteStrNDup(zP3, n); pOp->p3type = P3_DYNAMIC; } }
/* ** This routine is called by the parser to process a DETACH statement: ** ** DETACH DATABASE dbname ** ** The pDbname argument is the name of the database in the DETACH statement. */ void sqliteDetach(Parse *pParse, Token *pDbname){ int i; sqlite *db; Vdbe *v; Db *pDb; v = sqliteGetVdbe(pParse); sqliteVdbeAddOp(v, OP_Halt, 0, 0); if( pParse->explain ) return; db = pParse->db; for(i=0; i<db->nDb; i++){ pDb = &db->aDb[i]; if( pDb->pBt==0 || pDb->zName==0 ) continue; if( strlen(pDb->zName)!=pDbname->n ) continue; if( sqliteStrNICmp(pDb->zName, pDbname->z, pDbname->n)==0 ) break; } if( i>=db->nDb ){ sqliteErrorMsg(pParse, "no such database: %T", pDbname); return; } if( i<2 ){ sqliteErrorMsg(pParse, "cannot detach database %T", pDbname); return; } #ifndef SQLITE_OMIT_AUTHORIZATION if( sqliteAuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){ return; } #endif /* SQLITE_OMIT_AUTHORIZATION */ sqliteBtreeClose(pDb->pBt); pDb->pBt = 0; sqliteFree(pDb->zName); sqliteResetInternalSchema(db, i); if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux); db->nDb--; if( i<db->nDb ){ db->aDb[i] = db->aDb[db->nDb]; memset(&db->aDb[db->nDb], 0, sizeof(db->aDb[0])); sqliteResetInternalSchema(db, i); } }
/* ** Invoke a virtual table constructor (either xCreate or xConnect). The ** pointer to the function to invoke is passed as the fourth parameter ** to this procedure. */ static int vtabCallConstructor( sqlite3 *db, Table *pTab, Module *pMod, int (*xConstruct)(sqlite3*, void *, int, char **, sqlite3_vtab **), char **pzErr ){ int rc; int rc2; char **azArg = pTab->azModuleArg; int nArg = pTab->nModuleArg; char *zErr = sqlite3MPrintf("vtable constructor failed: %s", pTab->zName); assert( !db->pVTab ); assert( xConstruct ); db->pVTab = pTab; rc = sqlite3SafetyOff(db); assert( rc==SQLITE_OK ); rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab); rc2 = sqlite3SafetyOn(db); if( rc==SQLITE_OK && pTab->pVtab ){ pTab->pVtab->pModule = pMod->pModule; pTab->pVtab->nRef = 1; } if( SQLITE_OK!=rc ){ *pzErr = zErr; zErr = 0; } else if( db->pVTab ){ const char *zFormat = "vtable constructor did not declare schema: %s"; *pzErr = sqlite3MPrintf(zFormat, pTab->zName); rc = SQLITE_ERROR; } if( rc==SQLITE_OK ){ rc = rc2; } db->pVTab = 0; sqliteFree(zErr); return rc; }
/* * Delete table n from the supplied Rbtree. */ static int memRbtreeDropTable(Rbtree* tree, int n) { BtRbTree *pTree; assert( tree->eTransState != TRANS_NONE ); memRbtreeClearTable(tree, n); pTree = sqliteHashInsert(&tree->tblHash, 0, n, 0); assert(pTree); assert( pTree->pCursors==0 ); sqliteFree(pTree); if( tree->eTransState != TRANS_ROLLBACK ){ BtRollbackOp *pRollbackOp = sqliteMalloc(sizeof(BtRollbackOp)); if( pRollbackOp==0 ) return SQLITE_NOMEM; pRollbackOp->eOp = ROLLBACK_CREATE; pRollbackOp->iTab = n; btreeLogRollbackOp(tree, pRollbackOp); } return SQLITE_OK; }
/* ** Create a new symbolic label for an instruction that has yet to be ** coded. The symbolic label is really just a negative number. The ** label can be used as the P2 value of an operation. Later, when ** the label is resolved to a specific address, the VDBE will scan ** through its operation list and change all values of P2 which match ** the label into the resolved address. ** ** The VDBE knows that a P2 value is a label because labels are ** always negative and P2 values are suppose to be non-negative. ** Hence, a negative P2 value is a label that has yet to be resolved. */ int sqliteVdbeMakeLabel(Vdbe *p){ int i; i = p->nLabel++; assert( p->magic==VDBE_MAGIC_INIT ); if( i>=p->nLabelAlloc ){ int *aNew; p->nLabelAlloc = p->nLabelAlloc*2 + 10; aNew = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0])); if( aNew==0 ){ sqliteFree(p->aLabel); } p->aLabel = aNew; } if( p->aLabel==0 ){ p->nLabel = 0; p->nLabelAlloc = 0; return 0; } p->aLabel[i] = -1; return -1-i; }
/* ** Make sure the given Mem is \u0000 terminated. */ int sqlite3VdbeMemNulTerminate(Mem *pMem){ if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){ return SQLITE_OK; /* Nothing to do */ } if( pMem->flags & (MEM_Static|MEM_Ephem) ){ return sqlite3VdbeMemMakeWriteable(pMem); }else{ char *z = sqliteMalloc(pMem->n+2); if( !z ) return SQLITE_NOMEM; memcpy(z, pMem->z, pMem->n); z[pMem->n] = 0; z[pMem->n+1] = 0; if( pMem->xDel ){ pMem->xDel(pMem->z); }else{ sqliteFree(pMem->z); } pMem->xDel = 0; pMem->z = z; pMem->flags |= MEM_Term; } return SQLITE_OK; }
/* ** Locate and return an entry from the db.aCollSeq hash table. If the entry ** specified by zName and nName is not found and parameter 'create' is ** true, then create a new entry. Otherwise return NULL. ** ** Each pointer stored in the sqlite3.aCollSeq hash table contains an ** array of three CollSeq structures. The first is the collation sequence ** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be. ** ** Stored immediately after the three collation sequences is a copy of ** the collation sequence name. A pointer to this string is stored in ** each collation sequence structure. */ static CollSeq *findCollSeqEntry( sqlite3 *db, const char *zName, int nName, int create ){ CollSeq *pColl; if( nName<0 ) nName = strlen(zName); pColl = sqlite3HashFind(&db->aCollSeq, zName, nName); if( 0==pColl && create ){ pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 ); if( pColl ){ CollSeq *pDel = 0; pColl[0].zName = (char*)&pColl[3]; pColl[0].enc = SQLITE_UTF8; pColl[1].zName = (char*)&pColl[3]; pColl[1].enc = SQLITE_UTF16LE; pColl[2].zName = (char*)&pColl[3]; pColl[2].enc = SQLITE_UTF16BE; memcpy(pColl[0].zName, zName, nName); pColl[0].zName[nName] = 0; pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); /* If a malloc() failure occured in sqlite3HashInsert(), it will ** return the pColl pointer to be deleted (because it wasn't added ** to the hash table). */ assert( !pDel || (sqlite3MallocFailed() && pDel==pColl) ); if( pDel ){ sqliteFree(pDel); pColl = 0; } } } return pColl; }
/* ** Compile the UTF-16 encoded SQL statement zSql into a statement handle. */ static int sqlite3Prepare16( sqlite3 *db, /* Database handle. */ const void *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ int saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const void **pzTail /* OUT: End of parsed string */ ){ /* This function currently works by first transforming the UTF-16 ** encoded string to UTF-8, then invoking sqlite3_prepare(). The ** tricky bit is figuring out the pointer to return in *pzTail. */ char *zSql8; const char *zTail8 = 0; int rc = SQLITE_OK; if( sqlite3SafetyCheck(db) ){ return SQLITE_MISUSE; } zSql8 = sqlite3utf16to8(zSql, nBytes); if( zSql8 ){ rc = sqlite3Prepare(db, zSql8, -1, saveSqlFlag, ppStmt, &zTail8); } if( zTail8 && pzTail ){ /* If sqlite3_prepare returns a tail pointer, we calculate the ** equivalent pointer into the UTF-16 string by counting the unicode ** characters between zSql8 and zTail8, and then returning a pointer ** the same number of characters into the UTF-16 string. */ int chars_parsed = sqlite3utf8CharLen(zSql8, zTail8-zSql8); *pzTail = (u8 *)zSql + sqlite3utf16ByteLen(zSql, chars_parsed); } sqliteFree(zSql8); return sqlite3ApiExit(db, rc); }
/* ** Memory cell pMem contains the context of an aggregate function. ** This routine calls the finalize method for that function. The ** result of the aggregate is stored back into pMem. ** ** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK ** otherwise. */ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ int rc = SQLITE_OK; if( pFunc && pFunc->xFinalize ){ sqlite3_context ctx; assert( (pMem->flags & MEM_Null)!=0 || pFunc==*(FuncDef**)&pMem->i ); ctx.s.flags = MEM_Null; ctx.s.z = pMem->zShort; ctx.pMem = pMem; ctx.pFunc = pFunc; ctx.isError = 0; pFunc->xFinalize(&ctx); if( pMem->z && pMem->z!=pMem->zShort ){ sqliteFree( pMem->z ); } *pMem = ctx.s; if( pMem->flags & MEM_Short ){ pMem->z = pMem->zShort; } if( ctx.isError ){ rc = SQLITE_ERROR; } } return rc; }
/* ** Change the value of the P3 operand for a specific instruction. ** This routine is useful when a large program is loaded from a ** static array using sqliteVdbeAddOpList but we want to make a ** few minor changes to the program. ** ** If n>=0 then the P3 operand is dynamic, meaning that a copy of ** the string is made into memory obtained from sqliteMalloc(). ** A value of n==0 means copy bytes of zP3 up to and including the ** first null byte. If n>0 then copy n+1 bytes of zP3. ** ** If n==P3_STATIC it means that zP3 is a pointer to a constant static ** string and we can just copy the pointer. n==P3_POINTER means zP3 is ** a pointer to some object other than a string. ** ** If addr<0 then change P3 on the most recently inserted instruction. */ void sqliteVdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){ Op *pOp; assert( p->magic==VDBE_MAGIC_INIT ); if( p==0 || p->aOp==0 ) return; if( addr<0 || addr>=p->nOp ){ addr = p->nOp - 1; if( addr<0 ) return; } pOp = &p->aOp[addr]; if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){ sqliteFree(pOp->p3); pOp->p3 = 0; } if( zP3==0 ){ pOp->p3 = 0; pOp->p3type = P3_NOTUSED; }else if( n<0 ){ pOp->p3 = (char*)zP3; pOp->p3type = n; }else{ sqliteSetNString(&pOp->p3, zP3, n, 0); pOp->p3type = P3_DYNAMIC; } }
void sqliteBeginProc( Parse *pParse, /* The parse context of the statement */ int what, /* One of TK_PROCEDURE or TK_FUNCTION */ Token *pName /* The name of the object */ ){ Object *no; Block *pBlock = pParse->pCurrentBlock; char *zName = 0; /* Name of the object */ sqlite *db = pParse->db; /* Check that the object name does not already exist */ zName = sqliteStrNDup(pName->z, pName->n); sqliteDequote(zName); if( !pParse->explain && sqliteHashFind(&(db->aDb[0].objectHash), zName,pName->n+1) ){ sqliteErrorMsg(pParse, "object %T already exists", pName); goto object_cleanup; } /* Build the object */ no = (Object*)sqliteMalloc(sizeof(Object)); if( no==0 ) goto object_cleanup; no->name = zName; zName = 0; no->what = what; no->iDb = 0; no->nParam = pBlock->nVar; /* add param checks here */ pBlock->pObj = no; pBlock->params = 0; assert( pParse->pNewTrigger==0 ); pParse->pNewObject = no; return; object_cleanup: sqliteFree(zName); }
/* ** This is called by the parser when it sees a CREATE TRIGGER statement ** up to the point of the BEGIN before the trigger actions. A Trigger ** structure is generated based on the information available and stored ** in pParse->pNewTrigger. After the trigger actions have been parsed, the ** sqlite3FinishTrigger() function is called to complete the trigger ** construction process. */ void sqlite3BeginTrigger( Parse *pParse, /* The parse context of the CREATE TRIGGER statement */ Token *pName1, /* The name of the trigger */ Token *pName2, /* The name of the trigger */ int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */ int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */ IdList *pColumns, /* column list if this is an UPDATE OF trigger */ SrcList *pTableName,/* The name of the table/view the trigger applies to */ int foreach, /* One of TK_ROW or TK_STATEMENT */ Expr *pWhen, /* WHEN clause */ int isTemp /* True if the TEMPORARY keyword is present */ ){ Trigger *pTrigger; Table *pTab; char *zName = 0; /* Name of the trigger */ sqlite *db = pParse->db; int iDb; /* The database to store the trigger in */ Token *pName; /* The unqualified db name */ DbFixer sFix; if( isTemp ){ /* If TEMP was specified, then the trigger name may not be qualified. */ if( pName2 && pName2->n>0 ){ sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name"); goto trigger_cleanup; } iDb = 1; pName = pName1; }else{ /* Figure out the db that the the trigger will be created in */ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); if( iDb<0 ){ goto trigger_cleanup; } } /* If the trigger name was unqualified, and the table is a temp table, ** then set iDb to 1 to create the trigger in the temporary database. ** If sqlite3SrcListLookup() returns 0, indicating the table does not ** exist, the error is caught by the block below. */ if( !pTableName || sqlite3_malloc_failed ) goto trigger_cleanup; pTab = sqlite3SrcListLookup(pParse, pTableName); if( pName2->n==0 && pTab && pTab->iDb==1 ){ iDb = 1; } /* Ensure the table name matches database name and that the table exists */ if( sqlite3_malloc_failed ) goto trigger_cleanup; assert( pTableName->nSrc==1 ); if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && sqlite3FixSrcList(&sFix, pTableName) ){ goto trigger_cleanup; } pTab = sqlite3SrcListLookup(pParse, pTableName); if( !pTab ){ /* The table does not exist. */ goto trigger_cleanup; } /* Check that the trigger name is not reserved and that no trigger of the ** specified name exists */ zName = sqlite3NameFromToken(pName); if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto trigger_cleanup; } if( sqlite3HashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); goto trigger_cleanup; } /* Do not create a trigger on a system table */ if( (iDb!=1 && sqlite3StrICmp(pTab->zName, MASTER_NAME)==0) || (iDb==1 && sqlite3StrICmp(pTab->zName, TEMP_MASTER_NAME)==0) ){ sqlite3ErrorMsg(pParse, "cannot create trigger on system table"); pParse->nErr++; goto trigger_cleanup; } /* INSTEAD of triggers are only for views and views only support INSTEAD ** of triggers. */ if( pTab->pSelect && tr_tm!=TK_INSTEAD ){ sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0); goto trigger_cleanup; } if( !pTab->pSelect && tr_tm==TK_INSTEAD ){ sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF" " trigger on table: %S", pTableName, 0); goto trigger_cleanup; } #ifndef SQLITE_OMIT_AUTHORIZATION { int code = SQLITE_CREATE_TRIGGER; const char *zDb = db->aDb[pTab->iDb].zName; const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb; if( pTab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER; if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){ goto trigger_cleanup; } if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(pTab->iDb), 0, zDb)){ goto trigger_cleanup; } } #endif /* INSTEAD OF triggers can only appear on views and BEFORE triggers ** cannot appear on views. So we might as well translate every ** INSTEAD OF trigger into a BEFORE trigger. It simplifies code ** elsewhere. */ if (tr_tm == TK_INSTEAD){ tr_tm = TK_BEFORE; } /* Build the Trigger object */ pTrigger = (Trigger*)sqliteMalloc(sizeof(Trigger)); if( pTrigger==0 ) goto trigger_cleanup; pTrigger->name = zName; zName = 0; pTrigger->table = sqliteStrDup(pTableName->a[0].zName); if( sqlite3_malloc_failed ) goto trigger_cleanup; pTrigger->iDb = iDb; pTrigger->iTabDb = pTab->iDb; pTrigger->op = op; pTrigger->tr_tm = tr_tm; pTrigger->pWhen = sqlite3ExprDup(pWhen); pTrigger->pColumns = sqlite3IdListDup(pColumns); pTrigger->foreach = foreach; sqlite3TokenCopy(&pTrigger->nameToken,pName); assert( pParse->pNewTrigger==0 ); pParse->pNewTrigger = pTrigger; trigger_cleanup: sqliteFree(zName); sqlite3SrcListDelete(pTableName); sqlite3IdListDelete(pColumns); sqlite3ExprDelete(pWhen); }
/* ** This is called to code FOR EACH ROW triggers. ** ** When the code that this function generates is executed, the following ** must be true: ** ** 1. No cursors may be open in the main database. (But newIdx and oldIdx ** can be indices of cursors in temporary tables. See below.) ** ** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then ** a temporary vdbe cursor (index newIdx) must be open and pointing at ** a row containing values to be substituted for new.* expressions in the ** trigger program(s). ** ** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then ** a temporary vdbe cursor (index oldIdx) must be open and pointing at ** a row containing values to be substituted for old.* expressions in the ** trigger program(s). ** */ int sqlite3CodeRowTrigger( Parse *pParse, /* Parse context */ int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */ ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ int tr_tm, /* One of TK_BEFORE, TK_AFTER */ Table *pTab, /* The table to code triggers from */ int newIdx, /* The indice of the "new" row to access */ int oldIdx, /* The indice of the "old" row to access */ int orconf, /* ON CONFLICT policy */ int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ ){ Trigger * pTrigger; TriggerStack * pTriggerStack; assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE); assert(tr_tm == TK_BEFORE || tr_tm == TK_AFTER ); assert(newIdx != -1 || oldIdx != -1); pTrigger = pTab->pTrigger; while( pTrigger ){ int fire_this = 0; /* determine whether we should code this trigger */ if( pTrigger->op == op && pTrigger->tr_tm == tr_tm && pTrigger->foreach == TK_ROW ){ fire_this = 1; pTriggerStack = pParse->trigStack; while( pTriggerStack ){ if( pTriggerStack->pTrigger == pTrigger ){ fire_this = 0; } pTriggerStack = pTriggerStack->pNext; } if( op == TK_UPDATE && pTrigger->pColumns && !checkColumnOverLap(pTrigger->pColumns, pChanges) ){ fire_this = 0; } } if( fire_this && (pTriggerStack = sqliteMalloc(sizeof(TriggerStack)))!=0 ){ int endTrigger; SrcList dummyTablist; Expr * whenExpr; AuthContext sContext; dummyTablist.nSrc = 0; /* Push an entry on to the trigger stack */ pTriggerStack->pTrigger = pTrigger; pTriggerStack->newIdx = newIdx; pTriggerStack->oldIdx = oldIdx; pTriggerStack->pTab = pTab; pTriggerStack->pNext = pParse->trigStack; pTriggerStack->ignoreJump = ignoreJump; pParse->trigStack = pTriggerStack; sqlite3AuthContextPush(pParse, &sContext, pTrigger->name); /* code the WHEN clause */ endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe); whenExpr = sqlite3ExprDup(pTrigger->pWhen); if( sqlite3ExprResolveIds(pParse, &dummyTablist, 0, whenExpr) ){ pParse->trigStack = pParse->trigStack->pNext; sqliteFree(pTriggerStack); sqlite3ExprDelete(whenExpr); return 1; } sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1); sqlite3ExprDelete(whenExpr); sqlite3VdbeAddOp(pParse->pVdbe, OP_ContextPush, 0, 0); codeTriggerProgram(pParse, pTrigger->step_list, orconf); sqlite3VdbeAddOp(pParse->pVdbe, OP_ContextPop, 0, 0); /* Pop the entry off the trigger stack */ pParse->trigStack = pParse->trigStack->pNext; sqlite3AuthContextPop(&sContext); sqliteFree(pTriggerStack); sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger); } pTrigger = pTrigger->pNext; } return 0; }
/* ** Routines for testing the sqlite3_get_auxdata() and sqlite3_set_auxdata() ** interface. ** ** The test_auxdata() SQL function attempts to register each of its arguments ** as auxiliary data. If there are no prior registrations of aux data for ** that argument (meaning the argument is not a constant or this is its first ** call) then the result for that argument is 0. If there is a prior ** registration, the result for that argument is 1. The overall result ** is the individual argument results separated by spaces. */ static void free_test_auxdata(void *p) {sqliteFree(p);}