Index: src/alter.c ================================================================== --- src/alter.c +++ src/alter.c @@ -502,11 +502,11 @@ ** for which the renamed table is the parent table. */ if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){ sqlite3NestedParse(pParse, "UPDATE \"%w\".%s SET " "sql = sqlite_rename_parent(sql, %Q, %Q) " - "WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere); + "WHERE %s;", zDb, MASTER_NAME, zTabName, zName, zWhere); sqlite3DbFree(db, zWhere); } } #endif @@ -526,11 +526,11 @@ "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " "'sqlite_autoindex_' || %Q || substr(name,%d+18) " "ELSE name END " "WHERE tbl_name=%Q COLLATE nocase AND " "(type='table' OR type='index' OR type='trigger');", - zDb, SCHEMA_TABLE(iDb), zName, zName, zName, + zDb, MASTER_NAME, zName, zName, zName, #ifndef SQLITE_OMIT_TRIGGER zName, #endif zName, nTabName, zTabName ); @@ -687,11 +687,11 @@ db->flags |= SQLITE_PreferBuiltin; sqlite3NestedParse(pParse, "UPDATE \"%w\".%s SET " "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " "WHERE type = 'table' AND name = %Q", - zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1, + zDb, MASTER_NAME, pNew->addColOffset, zCol, pNew->addColOffset+1, zTab ); sqlite3DbFree(db, zCol); db->flags = savedDbFlags; } Index: src/build.c ================================================================== --- src/build.c +++ src/build.c @@ -28,14 +28,14 @@ /* ** 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 */ + 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 *zLockName; /* Name of the table */ }; /* ** Record the fact that we want to lock a table at run-time. ** @@ -75,11 +75,11 @@ if( pToplevel->aTableLock ){ p = &pToplevel->aTableLock[pToplevel->nTableLock++]; p->iDb = iDb; p->iTab = iTab; p->isWriteLock = isWriteLock; - p->zName = zName; + p->zLockName = zName; }else{ pToplevel->nTableLock = 0; sqlite3OomFault(pToplevel->db); } } @@ -97,11 +97,11 @@ for(i=0; inTableLock; i++){ TableLock *p = &pParse->aTableLock[i]; int p1 = p->iDb; sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock, - p->zName, P4_STATIC); + p->zLockName, P4_STATIC); } } #else #define codeTableLocks(x) #endif @@ -306,19 +306,26 @@ ** exists */ if( db->auth.authLevelnDb; i++){ - int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ - assert( sqlite3SchemaMutexHeld(db, j, 0) ); - p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); - if( p ) break; - } - } - return p; + while(1){ + for(i=OMIT_TEMPDB; inDb; i++){ + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); + if( p ) return p; + } + } + /* Not found. If the name we were looking for was temp.sqlite_master + ** then change the name to sqlite_temp_master and try again. */ + if( sqlite3StrICmp(zName, MASTER_NAME)!=0 ) break; + if( sqlite3_stricmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break; + zName = TEMP_MASTER_NAME; + } + return 0; } /* ** Locate the in-memory structure that describes a particular database ** table given the name of that table and (optionally) the name of the @@ -350,10 +357,13 @@ if( sqlite3FindDbName(pParse->db, zDbase)<1 ){ /* If zName is the not the name of a table in the schema created using ** CREATE, then check to see if it is the name of an virtual table that ** can be an eponymous virtual table. */ Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName); + if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ + pMod = sqlite3PragmaVtabRegister(pParse->db, zName); + } if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ return pMod->pEpoTab; } } #endif @@ -686,11 +696,11 @@ ** Open the sqlite_master table stored in database number iDb for ** writing. The table is opened using cursor 0. */ void sqlite3OpenMasterTable(Parse *p, int iDb){ Vdbe *v = sqlite3GetVdbe(p); - sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb)); + sqlite3TableLock(p, iDb, MASTER_ROOT, 1, MASTER_NAME); sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5); if( p->nTab==0 ){ p->nTab = 1; } } @@ -1989,11 +1999,11 @@ */ sqlite3NestedParse(pParse, "UPDATE %Q.%s " "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q " "WHERE rowid=#%d", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), + db->aDb[iDb].zDbSName, MASTER_NAME, zType, p->zName, p->zName, pParse->regRoot, zStmt, @@ -2326,11 +2336,11 @@ ** is in register NNN. See grammar rules associated with the TK_REGISTER ** token for additional information. */ sqlite3NestedParse(pParse, "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d", - pParse->db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), iTable, r1, r1); + pParse->db->aDb[iDb].zDbSName, MASTER_NAME, iTable, r1, r1); #endif sqlite3ReleaseTempReg(pParse, r1); } /* @@ -2469,11 +2479,11 @@ ** created in the temp database that refers to a table in another ** database. */ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", - pDb->zDbSName, SCHEMA_TABLE(iDb), pTab->zName); + pDb->zDbSName, MASTER_NAME, pTab->zName); if( !isView && !IsVirtual(pTab) ){ destroyTable(pParse, pTab); } /* Remove the table entry from SQLite's internal schema and modify @@ -3361,11 +3371,11 @@ /* Add an entry in sqlite_master for this index */ sqlite3NestedParse(pParse, "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), + db->aDb[iDb].zDbSName, MASTER_NAME, pIndex->zName, pTab->zName, iMem, zStmt ); @@ -3513,11 +3523,11 @@ v = sqlite3GetVdbe(pParse); if( v ){ sqlite3BeginWriteOperation(pParse, 1, iDb); sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE name=%Q AND type='index'", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pIndex->zName + db->aDb[iDb].zDbSName, MASTER_NAME, pIndex->zName ); sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); sqlite3ChangeCookie(pParse, iDb); destroyRootPage(pParse, pIndex->tnum, iDb); sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); @@ -3656,11 +3666,11 @@ assert( iStart<=pSrc->nSrc ); /* Allocate additional space if needed */ if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){ SrcList *pNew; - int nAlloc = pSrc->nSrc+nExtra; + int nAlloc = pSrc->nSrc*2+nExtra; int nGot; pNew = sqlite3DbRealloc(db, pSrc, sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) ); if( pNew==0 ){ assert( db->mallocFailed ); Index: src/pragma.c ================================================================== --- src/pragma.c +++ src/pragma.c @@ -164,12 +164,12 @@ /* ** Set result column names for a pragma. */ static void setPragmaResultColumnNames( - Vdbe *v, /* The query under construction */ - const struct sPragmaNames *pPragma /* The pragma */ + Vdbe *v, /* The query under construction */ + const PragmaName *pPragma /* The pragma */ ){ u8 n = pPragma->nPragCName; sqlite3VdbeSetNumCols(v, n==0 ? 1 : n); if( n==0 ){ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, pPragma->zName, SQLITE_STATIC); @@ -272,10 +272,30 @@ assert( eMode>=0 && eMode<=ArraySize(azModeName) ); if( eMode==ArraySize(azModeName) ) return 0; return azModeName[eMode]; } + +/* +** Locate a pragma in the aPragmaName[] array. +*/ +static const PragmaName *pragmaLocate(const char *zName){ + int upr, lwr, mid, rc; + lwr = 0; + upr = ArraySize(aPragmaName)-1; + while( lwr<=upr ){ + mid = (lwr+upr)/2; + rc = sqlite3_stricmp(zName, aPragmaName[mid].zName); + if( rc==0 ) break; + if( rc<0 ){ + upr = mid - 1; + }else{ + lwr = mid + 1; + } + } + return lwr>upr ? 0 : &aPragmaName[mid]; +} /* ** Process a pragma statement. ** ** Pragmas are of this form: @@ -301,16 +321,15 @@ char *zRight = 0; /* Nul-terminated UTF-8 string , or NULL */ const char *zDb = 0; /* The database name */ Token *pId; /* Pointer to token */ char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ int iDb; /* Database index for */ - int lwr, upr, mid = 0; /* Binary search bounds */ int rc; /* return value form SQLITE_FCNTL_PRAGMA */ sqlite3 *db = pParse->db; /* The database connection */ Db *pDb; /* The specific database being pragmaed */ Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ - const struct sPragmaNames *pPragma; + const PragmaName *pPragma; /* The pragma */ if( v==0 ) return; sqlite3VdbeRunOnlyOnce(v); pParse->nMem = 2; @@ -378,24 +397,12 @@ pParse->rc = rc; goto pragma_out; } /* Locate the pragma in the lookup table */ - lwr = 0; - upr = ArraySize(aPragmaNames)-1; - while( lwr<=upr ){ - mid = (lwr+upr)/2; - rc = sqlite3_stricmp(zLeft, aPragmaNames[mid].zName); - if( rc==0 ) break; - if( rc<0 ){ - upr = mid - 1; - }else{ - lwr = mid + 1; - } - } - if( lwr>upr ) goto pragma_out; - pPragma = &aPragmaNames[mid]; + pPragma = pragmaLocate(zLeft); + if( pPragma==0 ) goto pragma_out; /* Make sure the database schema is loaded if the pragma requires that */ if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){ if( sqlite3ReadSchema(pParse) ) goto pragma_out; } @@ -1948,7 +1955,309 @@ pragma_out: sqlite3DbFree(db, zLeft); sqlite3DbFree(db, zRight); } +#ifndef SQLITE_OMIT_VIRTUALTABLE +/***************************************************************************** +** Implementation of an eponymous virtual table that runs a pragma. +** +*/ +typedef struct PragmaVtab PragmaVtab; +typedef struct PragmaVtabCursor PragmaVtabCursor; +struct PragmaVtab { + sqlite3_vtab base; /* Base class. Must be first */ + sqlite3 *db; /* The database connection to which it belongs */ + const PragmaName *pName; /* Name of the pragma */ + u8 nHidden; /* Number of hidden columns */ + u8 iHidden; /* Index of the first hidden column */ +}; +struct PragmaVtabCursor { + sqlite3_vtab_cursor base; /* Base class. Must be first */ + sqlite3_stmt *pPragma; /* The pragma statement to run */ + sqlite_int64 iRowid; /* Current rowid */ + char *azArg[2]; /* Value of the argument and schema */ +}; + +/* +** Pragma virtual table module xConnect method. +*/ +static int pragmaVtabConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + const PragmaName *pPragma = (const PragmaName*)pAux; + PragmaVtab *pTab = 0; + int rc; + int i, j; + char cSep = '('; + StrAccum acc; + char zBuf[200]; + + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x"); + for(i=0, j=pPragma->iPragCName; inPragCName; i++, j++){ + sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]); + cSep = ','; + } + if( i==0 ){ + sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName); + cSep = ','; + i++; + } + j = 0; + if( pPragma->mPragFlg & PragFlg_Result1 ){ + sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN"); + j++; + } + if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){ + sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN"); + j++; + } + sqlite3StrAccumAppend(&acc, ")", 1); + sqlite3StrAccumFinish(&acc); + assert( strlen(zBuf) < sizeof(zBuf)-1 ); + rc = sqlite3_declare_vtab(db, zBuf); + if( rc==SQLITE_OK ){ + pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab)); + if( pTab==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pTab, 0, sizeof(PragmaVtab)); + pTab->pName = pPragma; + pTab->db = db; + pTab->iHidden = i; + pTab->nHidden = j; + } + }else{ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } + + *ppVtab = (sqlite3_vtab*)pTab; + return rc; +} + +/* +** Pragma virtual table module xDisconnect method. +*/ +static int pragmaVtabDisconnect(sqlite3_vtab *pVtab){ + PragmaVtab *pTab = (PragmaVtab*)pVtab; + sqlite3_free(pTab); + return SQLITE_OK; +} + +/* Figure out the best index to use to search a pragma virtual table. +** +** There are not really any index choices. But we want to encourage the +** query planner to give == constraints on as many hidden parameters as +** possible, and especially on the first hidden parameter. So return a +** high cost if hidden parameters are unconstrained. +*/ +static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + PragmaVtab *pTab = (PragmaVtab*)tab; + const struct sqlite3_index_constraint *pConstraint; + int i, j; + int seen[2]; + + pIdxInfo->estimatedCost = (double)1; + if( pTab->nHidden==0 ){ return SQLITE_OK; } + pConstraint = pIdxInfo->aConstraint; + seen[0] = 0; + seen[1] = 0; + for(i=0; inConstraint; i++, pConstraint++){ + if( pConstraint->usable==0 ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + if( pConstraint->iColumn < pTab->iHidden ) continue; + j = pConstraint->iColumn - pTab->iHidden; + assert( j < 2 ); + seen[j] = i+1; + } + if( seen[0]==0 ){ + pIdxInfo->estimatedCost = (double)2147483647; + pIdxInfo->estimatedRows = 2147483647; + return SQLITE_OK; + } + j = seen[0]-1; + pIdxInfo->aConstraintUsage[j].argvIndex = 1; + pIdxInfo->aConstraintUsage[j].omit = 1; + if( seen[1]==0 ) return SQLITE_OK; + pIdxInfo->estimatedCost = (double)20; + pIdxInfo->estimatedRows = 20; + j = seen[1]-1; + pIdxInfo->aConstraintUsage[j].argvIndex = 2; + pIdxInfo->aConstraintUsage[j].omit = 1; + return SQLITE_OK; +} + +/* Create a new cursor for the pragma virtual table */ +static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){ + PragmaVtabCursor *pCsr; + pCsr = (PragmaVtabCursor*)sqlite3_malloc(sizeof(*pCsr)); + if( pCsr==0 ) return SQLITE_NOMEM; + memset(pCsr, 0, sizeof(PragmaVtabCursor)); + pCsr->base.pVtab = pVtab; + *ppCursor = &pCsr->base; + return SQLITE_OK; +} + +/* Clear all content from pragma virtual table cursor. */ +static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){ + int i; + sqlite3_finalize(pCsr->pPragma); + pCsr->pPragma = 0; + for(i=0; iazArg); i++){ + sqlite3_free(pCsr->azArg[i]); + pCsr->azArg[i] = 0; + } +} + +/* Close a pragma virtual table cursor */ +static int pragmaVtabClose(sqlite3_vtab_cursor *cur){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)cur; + pragmaVtabCursorClear(pCsr); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* Advance the pragma virtual table cursor to the next row */ +static int pragmaVtabNext(sqlite3_vtab_cursor *pVtabCursor){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + int rc = SQLITE_OK; + + /* Increment the xRowid value */ + pCsr->iRowid++; + assert( pCsr->pPragma ); + if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){ + rc = sqlite3_finalize(pCsr->pPragma); + pCsr->pPragma = 0; + pragmaVtabCursorClear(pCsr); + } + return rc; +} + +/* +** Pragma virtual table module xFilter method. +*/ +static int pragmaVtabFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); + int rc; + int i, j; + StrAccum acc; + char *zSql; + + pragmaVtabCursorClear(pCsr); + j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1; + for(i=0; iazArg) ); + pCsr->azArg[j] = sqlite3_mprintf("%s", sqlite3_value_text(argv[i])); + if( pCsr->azArg[j]==0 ){ + return SQLITE_NOMEM; + } + } + sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]); + sqlite3StrAccumAppendAll(&acc, "PRAGMA "); + if( pCsr->azArg[1] ){ + sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]); + } + sqlite3StrAccumAppendAll(&acc, pTab->pName->zName); + if( pCsr->azArg[0] ){ + sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]); + } + zSql = sqlite3StrAccumFinish(&acc); + if( zSql==0 ) return SQLITE_NOMEM; + rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0); + sqlite3_free(zSql); + if( rc!=SQLITE_OK ){ + pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db)); + return rc; + } + return pragmaVtabNext(pVtabCursor); +} + +/* +** Pragma virtual table module xEof method. +*/ +static int pragmaVtabEof(sqlite3_vtab_cursor *pVtabCursor){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + return (pCsr->pPragma==0); +} + +/* The xColumn method simply returns the corresponding column from +** the PRAGMA. +*/ +static int pragmaVtabColumn( + sqlite3_vtab_cursor *pVtabCursor, + sqlite3_context *ctx, + int i +){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); + if( iiHidden ){ + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i)); + }else{ + sqlite3_result_text(ctx, pCsr->azArg[i-pTab->iHidden],-1,SQLITE_TRANSIENT); + } + return SQLITE_OK; +} + +/* +** Pragma virtual table module xRowid method. +*/ +static int pragmaVtabRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + *p = pCsr->iRowid; + return SQLITE_OK; +} + +/* The pragma virtual table object */ +static const sqlite3_module pragmaVtabModule = { + 0, /* iVersion */ + 0, /* xCreate - create a table */ + pragmaVtabConnect, /* xConnect - connect to an existing table */ + pragmaVtabBestIndex, /* xBestIndex - Determine search strategy */ + pragmaVtabDisconnect, /* xDisconnect - Disconnect from a table */ + 0, /* xDestroy - Drop a table */ + pragmaVtabOpen, /* xOpen - open a cursor */ + pragmaVtabClose, /* xClose - close a cursor */ + pragmaVtabFilter, /* xFilter - configure scan constraints */ + pragmaVtabNext, /* xNext - advance a cursor */ + pragmaVtabEof, /* xEof */ + pragmaVtabColumn, /* xColumn - read data */ + pragmaVtabRowid, /* xRowid - read data */ + 0, /* xUpdate - write data */ + 0, /* xBegin - begin transaction */ + 0, /* xSync - sync transaction */ + 0, /* xCommit - commit transaction */ + 0, /* xRollback - rollback transaction */ + 0, /* xFindFunction - function overloading */ + 0, /* xRename - rename the table */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ +}; + +/* +** Check to see if zTabName is really the name of a pragma. If it is, +** then register an eponymous virtual table for that pragma and return +** a pointer to the Module object for the new virtual table. +*/ +Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){ + const PragmaName *pName; + assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 ); + pName = pragmaLocate(zName+7); + if( pName==0 ) return 0; + if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0; + assert( sqlite3HashFind(&db->aModule, zName)==0 ); + return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0); +} + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ #endif /* SQLITE_OMIT_PRAGMA */ Index: src/pragma.h ================================================================== --- src/pragma.h +++ src/pragma.h @@ -112,18 +112,19 @@ /* 46 */ "database", /* Used by: lock_status */ /* 47 */ "status", }; /* Definitions of all built-in pragmas */ -static const struct sPragmaNames { +typedef struct PragmaName { const char *const zName; /* Name of pragma */ u8 ePragTyp; /* PragTyp_XXX value */ u8 mPragFlg; /* Zero or more PragFlg_XXX values */ u8 iPragCName; /* Start of column names in pragCName[] */ u8 nPragCName; /* Num of col names. 0 means use pragma name */ u32 iArg; /* Extra argument */ -} aPragmaNames[] = { +} PragmaName; +static const PragmaName aPragmaName[] = { #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) {/* zName: */ "activate_extensions", /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, /* ePragFlg: */ 0, /* ColNames: */ 0, 0, Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -3561,10 +3561,13 @@ void sqlite3ExprListDelete(sqlite3*, ExprList*); u32 sqlite3ExprListFlags(const ExprList*); int sqlite3Init(sqlite3*, char**); int sqlite3InitCallback(void*, int, char**, char**); void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); +#ifndef SQLITE_OMIT_VIRTUALTABLE +Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName); +#endif void sqlite3ResetAllSchemasOfConnection(sqlite3*); void sqlite3ResetOneSchema(sqlite3*,int); void sqlite3CollapseDatabaseArray(sqlite3*); void sqlite3CommitInternalChanges(sqlite3*); void sqlite3DeleteColumnNames(sqlite3*,Table*); @@ -4075,10 +4078,17 @@ void sqlite3VtabUnlock(VTable *); void sqlite3VtabUnlockList(sqlite3*); int sqlite3VtabSavepoint(sqlite3 *, int, int); void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*); VTable *sqlite3GetVTable(sqlite3*, Table*); + Module *sqlite3VtabCreateModule( + sqlite3*, + const char*, + const sqlite3_module*, + void*, + void(*)(void*) + ); # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) #endif int sqlite3VtabEponymousTableInit(Parse*,Module*); void sqlite3VtabEponymousTableClear(sqlite3*,Module*); void sqlite3VtabMakeWritable(Parse*,Table*); Index: src/trigger.c ================================================================== --- src/trigger.c +++ src/trigger.c @@ -306,11 +306,11 @@ if( v==0 ) goto triggerfinish_cleanup; sqlite3BeginWriteOperation(pParse, 0, iDb); z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); sqlite3NestedParse(pParse, "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), zName, + db->aDb[iDb].zDbSName, MASTER_NAME, zName, pTrig->table, z); sqlite3DbFree(db, z); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddParseSchemaOp(v, iDb, sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName)); @@ -557,11 +557,11 @@ */ assert( pTable!=0 ); if( (v = sqlite3GetVdbe(pParse))!=0 ){ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pTrigger->zName + db->aDb[iDb].zDbSName, MASTER_NAME, pTrigger->zName ); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); } } Index: src/vdbe.c ================================================================== --- src/vdbe.c +++ src/vdbe.c @@ -5477,11 +5477,11 @@ iDb = pOp->p1; assert( iDb>=0 && iDbnDb ); assert( DbHasProperty(db, iDb, DB_SchemaLoaded) ); /* Used to be a conditional */ { - zMaster = SCHEMA_TABLE(iDb); + zMaster = MASTER_NAME; initData.db = db; initData.iDb = pOp->p1; initData.pzErrMsg = &p->zErrMsg; zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", Index: src/vtab.c ================================================================== --- src/vtab.c +++ src/vtab.c @@ -25,10 +25,45 @@ VTable *pVTable; /* The virtual table being constructed */ Table *pTab; /* The Table object to which the virtual table belongs */ VtabCtx *pPrior; /* Parent context (if any) */ int bDeclared; /* True after sqlite3_declare_vtab() is called */ }; + +/* +** Construct and install a Module object for a virtual table. When this +** routine is called, it is guaranteed that all appropriate locks are held +** and the module is not already part of the connection. +*/ +Module *sqlite3VtabCreateModule( + 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 */ + void (*xDestroy)(void *) /* Module destructor function */ +){ + Module *pMod; + int nName = sqlite3Strlen30(zName); + pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1); + if( pMod ){ + Module *pDel; + char *zCopy = (char *)(&pMod[1]); + memcpy(zCopy, zName, nName+1); + pMod->zName = zCopy; + pMod->pModule = pModule; + pMod->pAux = pAux; + pMod->xDestroy = xDestroy; + pMod->pEpoTab = 0; + pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); + assert( pDel==0 || pDel==pMod ); + if( pDel ){ + sqlite3OomFault(db); + sqlite3DbFree(db, pDel); + pMod = 0; + } + } + return pMod; +} /* ** The actual function that does the work of creating a new module. ** This function implements the sqlite3_create_module() and ** sqlite3_create_module_v2() interfaces. @@ -39,39 +74,19 @@ const sqlite3_module *pModule, /* The definition of the module */ void *pAux, /* Context pointer for xCreate/xConnect */ void (*xDestroy)(void *) /* Module destructor function */ ){ int rc = SQLITE_OK; - int nName; sqlite3_mutex_enter(db->mutex); - nName = sqlite3Strlen30(zName); if( sqlite3HashFind(&db->aModule, zName) ){ rc = SQLITE_MISUSE_BKPT; }else{ - Module *pMod; - pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1); - if( pMod ){ - Module *pDel; - char *zCopy = (char *)(&pMod[1]); - memcpy(zCopy, zName, nName+1); - pMod->zName = zCopy; - pMod->pModule = pModule; - pMod->pAux = pAux; - pMod->xDestroy = xDestroy; - pMod->pEpoTab = 0; - pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); - assert( pDel==0 || pDel==pMod ); - if( pDel ){ - sqlite3OomFault(db); - sqlite3DbFree(db, pDel); - } - } + (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy); } rc = sqlite3ApiExit(db, rc); if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); - sqlite3_mutex_leave(db->mutex); return rc; } @@ -406,11 +421,11 @@ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3NestedParse(pParse, "UPDATE %Q.%s " "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " "WHERE rowid=#%d", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), + db->aDb[iDb].zDbSName, MASTER_NAME, pTab->zName, pTab->zName, zStmt, pParse->regRowid ); Index: test/alter.test ================================================================== --- test/alter.test +++ test/alter.test @@ -75,11 +75,11 @@ FROM sqlite_master WHERE NAME!='objlist'; }] ifcapable tempdb { execsql { INSERT INTO objlist SELECT type, name, tbl_name - FROM sqlite_temp_master WHERE NAME!='objlist'; + FROM temp.sqlite_master WHERE NAME!='objlist'; } } execsql { SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name; @@ -151,11 +151,11 @@ set DB [sqlite3_connection_pointer db] execsql { CREATE TEMP TABLE objlist(type, name, tbl_name); INSERT INTO objlist SELECT type, name, tbl_name FROM sqlite_master; INSERT INTO objlist - SELECT type, name, tbl_name FROM sqlite_temp_master + SELECT type, name, tbl_name FROM temp.sqlite_master WHERE NAME!='objlist'; SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name; } } [list \ @@ -522,11 +522,11 @@ } } {} ifcapable tempdb { do_test alter-3.3.8 { execsql { - SELECT * FROM sqlite_temp_master WHERE type = 'trigger'; + SELECT * FROM temp.sqlite_master WHERE type = 'trigger'; } } {} } } ;# ifcapable trigger Index: test/alter4.test ================================================================== --- test/alter4.test +++ test/alter4.test @@ -42,29 +42,49 @@ do_test alter4-1.1 { execsql { CREATE TEMP TABLE abc(a, b, c); SELECT sql FROM sqlite_temp_master; } +} {{CREATE TABLE abc(a, b, c)}} +do_test alter4-1.1b { + execsql { + SELECT sql FROM temp.sqlite_master; + } } {{CREATE TABLE abc(a, b, c)}} do_test alter4-1.2 { execsql {ALTER TABLE abc ADD d INTEGER;} execsql { SELECT sql FROM sqlite_temp_master; + } +} {{CREATE TABLE abc(a, b, c, d INTEGER)}} +do_test alter4-1.2b { + execsql { + SELECT sql FROM temp.sqlite_master; } } {{CREATE TABLE abc(a, b, c, d INTEGER)}} do_test alter4-1.3 { execsql {ALTER TABLE abc ADD e} execsql { SELECT sql FROM sqlite_temp_master; + } +} {{CREATE TABLE abc(a, b, c, d INTEGER, e)}} +do_test alter4-1.3b { + execsql { + SELECT sql FROM temp.sqlite_master; } } {{CREATE TABLE abc(a, b, c, d INTEGER, e)}} do_test alter4-1.4 { execsql { CREATE TABLE temp.t1(a, b); ALTER TABLE t1 ADD c; SELECT sql FROM sqlite_temp_master WHERE tbl_name = 't1'; } +} {{CREATE TABLE t1(a, b, c)}} +do_test alter4-1.4b { + execsql { + SELECT sql FROM temp.sqlite_master WHERE tbl_name = 't1'; + } } {{CREATE TABLE t1(a, b, c)}} do_test alter4-1.5 { execsql { ALTER TABLE t1 ADD d CHECK (a>d); SELECT sql FROM sqlite_temp_master WHERE tbl_name = 't1'; Index: test/attach.test ================================================================== --- test/attach.test +++ test/attach.test @@ -191,11 +191,11 @@ db_list db } {0 main 2 db2 3 db3 4 db4 5 db6 6 db7 7 db8 8 db9 9 db10 10 db11} } ;# ifcapable schema_pragmas integrity_check attach-1.20.3 ifcapable tempdb { - execsql {select * from sqlite_temp_master} + execsql {select * from temp.sqlite_master} } do_test attach-1.21 { catchsql { ATTACH 'test.db' as db12; } Index: test/attach3.test ================================================================== --- test/attach3.test +++ test/attach3.test @@ -205,11 +205,11 @@ CREATE TABLE main.t4(a, b, c); CREATE TABLE aux.t4(a, b, c); CREATE TEMP TRIGGER tst_trigger BEFORE INSERT ON aux.t4 BEGIN SELECT 'hello world'; END; - SELECT count(*) FROM sqlite_temp_master; + SELECT count(*) FROM temp.sqlite_master; } } {1} do_test attach3-9.1 { execsql { DROP TABLE main.t4; @@ -217,11 +217,11 @@ } } {1} do_test attach3-9.2 { execsql { DROP TABLE aux.t4; - SELECT count(*) FROM sqlite_temp_master; + SELECT count(*) FROM temp.sqlite_master; } } {0} } } ;# endif trigger Index: test/auth.test ================================================================== --- test/auth.test +++ test/auth.test @@ -89,11 +89,11 @@ return SQLITE_OK } catchsql {CREATE TEMP TABLE t1(a,b,c)} } {1 {not authorized}} do_test auth-1.6 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {} do_test auth-1.7.1 { proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] @@ -146,11 +146,11 @@ return SQLITE_OK } catchsql {CREATE TEMP TABLE t1(a,b,c)} } {0 {}} do_test auth-1.14 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {} do_test auth-1.15 { proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] @@ -559,11 +559,11 @@ return SQLITE_OK } catchsql {DROP TABLE t1} } {0 {}} do_test auth-1.78 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} } # Test cases auth-1.79 to auth-1.124 test creating and dropping views. # Omit these if the library was compiled with views omitted. @@ -630,11 +630,11 @@ } {0 {}} do_test auth-1.89 { set ::authargs } {v1 {} temp {}} do_test auth-1.90 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} } do_test auth-1.91 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -777,11 +777,11 @@ CREATE TEMP VIEW v1 AS SELECT a+1,b+1 FROM t1; DROP VIEW v1 } } {1 {not authorized}} do_test auth-1.113 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 v1} do_test auth-1.114 { proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_VIEW"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] @@ -821,11 +821,11 @@ } {0 {}} do_test auth-1.120 { set ::authargs } {v1 {} temp {}} do_test auth-1.121 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 v1} do_test auth-1.122 { proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_VIEW"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] @@ -978,11 +978,11 @@ } {1 {not authorized}} do_test auth-1.139 { set ::authargs } {r1 t1 temp {}} do_test auth-1.140 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} do_test auth-1.141 { proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_temp_master"} { return SQLITE_DENY @@ -1014,11 +1014,11 @@ } {0 {}} do_test auth-1.144 { set ::authargs } {r1 t1 temp {}} do_test auth-1.145 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} do_test auth-1.146 { proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_temp_master"} { return SQLITE_IGNORE @@ -1050,11 +1050,11 @@ } {0 {}} do_test auth-1.149 { set ::authargs } {r1 t1 temp {}} do_test auth-1.150 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 r1} do_test auth-1.151 { proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_master"} { @@ -1140,11 +1140,11 @@ return SQLITE_OK } catchsql {DROP TRIGGER r1} } {1 {not authorized}} do_test auth-1.165 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 r1} do_test auth-1.166 { proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] @@ -1168,11 +1168,11 @@ return SQLITE_OK } catchsql {DROP TRIGGER r1} } {0 {}} do_test auth-1.170 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 r1} do_test auth-1.171 { proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] @@ -1200,11 +1200,11 @@ } {0 {}} do_test auth-1.175 { set ::authargs } {r1 t1 temp {}} do_test auth-1.176 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} } ;# ifcapable trigger do_test auth-1.177 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -1304,11 +1304,11 @@ return SQLITE_OK } catchsql {CREATE INDEX i1 ON t1(b)} } {1 {not authorized}} do_test auth-1.194 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} do_test auth-1.195 { proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] @@ -1348,11 +1348,11 @@ } {0 {}} do_test auth-1.201 { set ::authargs } {i1 t1 temp {}} do_test auth-1.202 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 i1} } do_test auth-1.203 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -1464,11 +1464,11 @@ return SQLITE_OK } catchsql {DROP INDEX i1} } {0 {}} do_test auth-1.222 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 i1} do_test auth-1.223 { proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] @@ -1480,11 +1480,11 @@ } {0 {}} do_test auth-1.224 { set ::authargs } {i1 t1 temp {}} do_test auth-1.225 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 i1} do_test auth-1.226 { proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] @@ -1496,11 +1496,11 @@ } {0 {}} do_test auth-1.227 { set ::authargs } {i1 t1 temp {}} do_test auth-1.228 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} } do_test auth-1.229 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -1763,11 +1763,11 @@ catchsql { ALTER TABLE t1x RENAME TO t1 } } {0 {}} do_test auth-1.267 { - execsql {SELECT name FROM sqlite_temp_master WHERE type='table'} + execsql {SELECT name FROM temp.sqlite_master WHERE type='table'} } {t1x} do_test auth-1.268 { set authargs } {temp t1x {} {}} do_test auth-1.269 { @@ -2068,11 +2068,11 @@ catchsql { ALTER TABLE t5 ADD COLUMN new_col_3 } } {1 {not authorized}} do_test auth-1.307 { - set x [execsql {SELECT sql FROM sqlite_temp_master WHERE type='t5'}] + set x [execsql {SELECT sql FROM temp.sqlite_master WHERE type='t5'}] regexp new_col_3 $x } {0} do_test auth-1.308 { set authargs @@ -2371,11 +2371,11 @@ } } do_test auth-5.2 { execsql { SELECT name FROM ( - SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) + SELECT * FROM sqlite_master UNION ALL SELECT * FROM temp.sqlite_master) WHERE type='table' ORDER BY name } } "sqlite_stat1 ${stat4}t1 t2 t3 t4" } Index: test/auth3.test ================================================================== --- test/auth3.test +++ test/auth3.test @@ -120,9 +120,9 @@ do_execsql_test auth3-3.0 { CREATE TEMPORARY TABLE TempTable ( key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, value TEXT NOT NULL ON CONFLICT FAIL); ALTER TABLE TempTable RENAME TO DoNotRead; - SELECT name FROM sqlite_temp_master; + SELECT name FROM temp.sqlite_master; } {DoNotRead sqlite_autoindex_DoNotRead_1} finish_test Index: test/autoinc.test ================================================================== --- test/autoinc.test +++ test/autoinc.test @@ -342,11 +342,11 @@ # ifcapable tempdb { do_test autoinc-4.1 { execsql { SELECT 1, name FROM sqlite_master WHERE type='table'; - SELECT 2, name FROM sqlite_temp_master WHERE type='table'; + SELECT 2, name FROM temp.sqlite_master WHERE type='table'; } } {1 sqlite_sequence} do_test autoinc-4.2 { execsql { CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y); Index: test/bestindex3.test ================================================================== --- test/bestindex3.test +++ test/bestindex3.test @@ -170,6 +170,5 @@ do_execsql_test 3.1 { CREATE VIRTUAL TABLE t3 USING tcl('vvv_command') } do_execsql_test 3.2 { CREATE VIRTUAL TABLE t4 USING tcl('yyy_command') } finish_test - Index: test/bestindex4.test ================================================================== --- test/bestindex4.test +++ test/bestindex4.test @@ -116,6 +116,5 @@ } } finish_test - Index: test/e_dropview.test ================================================================== --- test/e_dropview.test +++ test/e_dropview.test @@ -43,11 +43,11 @@ proc list_all_views {{db db}} { set res [list] $db eval { PRAGMA database_list } { set tbl "$name.sqlite_master" - if {$name == "temp"} { set tbl sqlite_temp_master } + if {$name == "temp"} { set tbl temp.sqlite_master } set sql "SELECT '$name.' || name FROM $tbl WHERE type = 'view'" lappend res {*}[$db eval $sql] } set res Index: test/fkey2.test ================================================================== --- test/fkey2.test +++ test/fkey2.test @@ -1060,11 +1060,11 @@ do_test fkey2-14.1tmp.6 { execsql { PRAGMA foreign_keys = off; ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1; PRAGMA foreign_keys = on; - SELECT sql FROM sqlite_temp_master WHERE name='t2'; + SELECT sql FROM temp.sqlite_master WHERE name='t2'; } } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} do_test fkey2-14.2tmp.1.1 { test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3 @@ -1091,11 +1091,11 @@ {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)} \ {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \ ] do_test fkey2-14.2tmp.2.2 { execsql { ALTER TABLE t1 RENAME TO t4 } - execsql { SELECT sql FROM sqlite_temp_master WHERE type = 'table'} + execsql { SELECT sql FROM temp.sqlite_master WHERE type = 'table'} } [list \ {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")} \ {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)} \ {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \ ] Index: test/incrblob4.test ================================================================== --- test/incrblob4.test +++ test/incrblob4.test @@ -105,6 +105,5 @@ sqlite3_extended_errcode db } {SQLITE_LOCKED} close $blob finish_test - Index: test/intarray.test ================================================================== --- test/intarray.test +++ test/intarray.test @@ -40,11 +40,11 @@ set ia1 [sqlite3_intarray_create db ia1] set ia2 [sqlite3_intarray_create db ia2] set ia3 [sqlite3_intarray_create db ia3] set ia4 [sqlite3_intarray_create db ia4] db eval { - SELECT type, name FROM sqlite_temp_master + SELECT type, name FROM temp.sqlite_master ORDER BY name } } {table ia1 table ia2 table ia3 table ia4} do_test intarray-1.2 { Index: test/interrupt.test ================================================================== --- test/interrupt.test +++ test/interrupt.test @@ -126,11 +126,11 @@ INSERT INTO t2 SELECT * FROM t1; } } {1 interrupted} do_test interrupt-3.$i.3 { execsql { - SELECT name FROM sqlite_temp_master; + SELECT name FROM temp.sqlite_master; } } {} do_test interrupt-3.$i.4 { catchsql { ROLLBACK @@ -137,11 +137,11 @@ } } {1 {cannot rollback - no transaction is active}} do_test interrupt-3.$i.5 { catchsql {SELECT name FROM sqlite_temp_master}; execsql { - SELECT name FROM sqlite_temp_master; + SELECT name FROM temp.sqlite_master; } } {} } } Index: test/regexp2.test ================================================================== --- test/regexp2.test +++ test/regexp2.test @@ -120,6 +120,5 @@ SELECT * FROM t6; } {eab dea} finish_test - Index: test/rowvalue.test ================================================================== --- test/rowvalue.test +++ test/rowvalue.test @@ -315,7 +315,5 @@ do_catchsql_test 14.2.$tn $sql [list 1 $err] } finish_test - - Index: test/rowvalue9.test ================================================================== --- test/rowvalue9.test +++ test/rowvalue9.test @@ -297,6 +297,5 @@ ); } { 1 4 1 5 } finish_test - Index: test/rowvaluefault.test ================================================================== --- test/rowvaluefault.test +++ test/rowvaluefault.test @@ -67,6 +67,5 @@ } -test { faultsim_test_result {0 {2 3}} } finish_test - Index: test/schema4.test ================================================================== --- test/schema4.test +++ test/schema4.test @@ -147,11 +147,11 @@ CREATE TEMP TABLE x1(x); INSERT INTO x1 VALUES(123); } {} do_execsql_test schema4-2.8 { - select sql from sqlite_temp_master WHERE type='table'; + select sql from temp.sqlite_master WHERE type='table'; } {{CREATE TABLE x1(x)}} do_execsql_test schema4-2.7 { ALTER TABLE tbl RENAME TO tbl2 } {} do_execsql_test schema4-2.9 { Index: test/snapshot2.test ================================================================== --- test/snapshot2.test +++ test/snapshot2.test @@ -196,7 +196,5 @@ } list [catch { sqlite3_snapshot_recover db aux } msg] $msg } {1 SQLITE_ERROR} finish_test - - Index: test/tempdb2.test ================================================================== --- test/tempdb2.test +++ test/tempdb2.test @@ -72,6 +72,5 @@ do_execsql_test 1.4 { SELECT b=int2str(2) FROM t1 } {1 1 1} finish_test - Index: test/temptrigger.test ================================================================== --- test/temptrigger.test +++ test/temptrigger.test @@ -234,11 +234,11 @@ execsql { DROP TABLE t1 } db2 } {} do_execsql_test 5.2 { SELECT * FROM sqlite_master; - SELECT * FROM sqlite_temp_master; + SELECT * FROM temp.sqlite_master; } { trigger tr1 t1 0 {CREATE TRIGGER tr1 BEFORE INSERT ON t1 BEGIN SELECT 1,2,3; END} } db2 close Index: test/tkt3630.test ================================================================== --- test/tkt3630.test +++ test/tkt3630.test @@ -21,11 +21,11 @@ source $testdir/tester.tcl do_test tkt3630-1 { db eval { CREATE TEMP TABLE temp1(a,b,c); - SELECT * FROM sqlite_temp_master WHERE sql GLOB '*TEMP*'; + SELECT * FROM temp.sqlite_master WHERE sql GLOB '*TEMP*'; } } {} do_test tkt3630-2 { db eval { CREATE TABLE main1(a,b,c); @@ -37,11 +37,11 @@ ifcapable altertable { do_test tkt3630-3 { db eval { ALTER TABLE temp2 ADD COLUMN d; ALTER TABLE temp2 RENAME TO temp2rn; - SELECT name FROM sqlite_temp_master WHERE name LIKE 'temp2%'; + SELECT name FROM temp.sqlite_master WHERE name LIKE 'temp2%'; } } {temp2rn} } finish_test Index: test/tkt3810.test ================================================================== --- test/tkt3810.test +++ test/tkt3810.test @@ -60,11 +60,11 @@ # Trigger still exists in the sqlite_temp_master table, but now it is # an orphan. # do_test tkt3810-4 { - execsql {SELECT name FROM sqlite_temp_master ORDER BY name} + execsql {SELECT name FROM temp.sqlite_master ORDER BY name} } {r1} # Because it is an orphan, it cannot be dropped. # do_test tkt3810-5 { Index: test/without_rowid3.test ================================================================== --- test/without_rowid3.test +++ test/without_rowid3.test @@ -1029,11 +1029,11 @@ do_test without_rowid3-14.1tmp.6 { execsql { PRAGMA foreign_keys = off; ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1; PRAGMA foreign_keys = on; - SELECT sql FROM sqlite_temp_master WHERE name='t2'; + SELECT sql FROM temp.sqlite_master WHERE name='t2'; } } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} do_test without_rowid3-14.2tmp.1.1 { test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3 @@ -1062,11 +1062,11 @@ WITHOUT rowid} \ {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \ ] do_test without_rowid3-14.2tmp.2.2 { execsql { ALTER TABLE t1 RENAME TO t4 } - execsql { SELECT sql FROM sqlite_temp_master WHERE type = 'table'} + execsql { SELECT sql FROM temp.sqlite_master WHERE type = 'table'} } [list \ {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \ {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2) WITHOUT rowid} \ {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \ Index: tool/mkpragmatab.tcl ================================================================== --- tool/mkpragmatab.tcl +++ tool/mkpragmatab.tcl @@ -493,19 +493,20 @@ puts $fd "\175;" # Generate the lookup table # puts $fd "\n/* Definitions of all built-in pragmas */" -puts $fd "static const struct sPragmaNames \173" +puts $fd "typedef struct PragmaName \173" puts $fd " const char *const zName; /* Name of pragma */" puts $fd " u8 ePragTyp; /* PragTyp_XXX value */" puts $fd " u8 mPragFlg; /* Zero or more PragFlg_XXX values */" puts $fd { u8 iPragCName; /* Start of column names in pragCName[] */} puts $fd " u8 nPragCName; \ /* Num of col names. 0 means use pragma name */" puts $fd " u32 iArg; /* Extra argument */" -puts $fd "\175 aPragmaNames\[\] = \173" +puts $fd "\175 PragmaName;" +puts $fd "static const PragmaName aPragmaName\[\] = \173" set current_if {} set spacer [format { %26s } {}] foreach name $allnames { foreach {type arg if flag cx} $allbyname($name) break