Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Progress towards getting prepared statements and CREATE and DROP to play nicely together. Work is incomplete. Some tests are known to fail. (CVS 1864) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
49b991492496e104f5eca620a5d465a7 |
User & Date: | drh 2004-07-24 03:30:48.000 |
Context
2004-07-24
| ||
14:35 | Fix more problems with deferred execution of CREATE. Still need to do DROP. There is now a memory leak. (CVS 1865) (check-in: 6db3f122aa user: drh tags: trunk) | |
03:30 | Progress towards getting prepared statements and CREATE and DROP to play nicely together. Work is incomplete. Some tests are known to fail. (CVS 1864) (check-in: 49b9914924 user: drh tags: trunk) | |
2004-07-23
| ||
00:01 | First cut at a analysis tool for version 3.0 databases. (CVS 1862) (check-in: 7c7f698b2e user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.241 2004/07/24 03:30:48 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Check to see if the schema for the database needs |
︙ | ︙ | |||
227 228 229 230 231 232 233 | } } sqliteDeleteIndex(db, pIndex); } /* ** Erase all schema information from the in-memory hash tables of | | | | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | } } sqliteDeleteIndex(db, pIndex); } /* ** 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. */ |
︙ | ︙ | |||
1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 | sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0); } /* ** Measure the number of characters needed to output the given ** identifier. The number returned includes any quotes used ** but does not include the null terminator. */ static int identLength(const char *z){ int n; | > > > < | | | | | | > | | > | | | | | | | | | 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 | sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0); } /* ** Measure the number of characters needed to output the given ** identifier. The number returned includes any quotes used ** but does not include the null terminator. ** ** The estimate is conservative. It might be larger that what is ** really needed. */ static int identLength(const char *z){ int n; for(n=0; *z; n++, z++){ if( *z=='"' ){ n++; } } return n + 2; } /* ** Write an identifier onto the end of the given string. Add ** quote characters as needed. */ static void identPut(char *z, int *pIdx, char *zIdent){ int i, j, needQuote; i = *pIdx; for(j=0; zIdent[j]; j++){ if( !isalnum(zIdent[j]) && zIdent[j]!='_' ) break; } needQuote = zIdent[j]!=0 || isdigit(zIdent[0]) || sqlite3KeywordCode(zIdent, j)!=TK_ID; if( needQuote ) z[i++] = '"'; for(j=0; zIdent[j]; j++){ z[i++] = zIdent[j]; if( zIdent[j]=='"' ) z[i++] = '"'; } if( needQuote ) z[i++] = '"'; z[i] = 0; *pIdx = i; } /* ** Generate a CREATE TABLE statement appropriate for the given ** table. Memory to hold the text of the statement is obtained ** from sqliteMalloc() and must be freed by the calling function. */ static char *createTableStmt(Table *p){ int i, k, n; char *zStmt; char *zSep, *zSep2, *zEnd, *z; Column *pCol; n = 0; for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){ n += identLength(pCol->zName); z = pCol->zType; if( z ){ n += (strlen(z) + 1); } } n += identLength(p->zName); if( n<50 ){ zSep = ""; zSep2 = ","; zEnd = ")"; }else{ zSep = "\n "; zSep2 = ",\n "; zEnd = "\n)"; } n += 35 + 6*p->nCol; zStmt = sqliteMallocRaw( n ); if( zStmt==0 ) return 0; strcpy(zStmt, p->iDb==1 ? "CREATE TEMP TABLE " : "CREATE TABLE "); k = strlen(zStmt); identPut(zStmt, &k, p->zName); zStmt[k++] = '('; for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){ strcpy(&zStmt[k], zSep); k += strlen(&zStmt[k]); zSep = zSep2; identPut(zStmt, &k, pCol->zName); if( (z = pCol->zType)!=0 ){ zStmt[k++] = ' '; strcpy(&zStmt[k], z); k += strlen(z); } } strcpy(&zStmt[k], zEnd); return zStmt; } /* |
︙ | ︙ | |||
1301 1302 1303 1304 1305 1306 1307 | Vdbe *v; v = sqlite3GetVdbe(pParse); if( v==0 ) return; if( p->pSelect==0 ){ /* A regular table */ | | < | 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 | Vdbe *v; v = sqlite3GetVdbe(pParse); if( v==0 ) return; if( p->pSelect==0 ){ /* A regular table */ sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0); }else{ /* A view */ sqlite3VdbeAddOp(v, OP_Integer, 0, 0); } sqlite3VdbeAddOp(v, OP_Close, 0, 0); /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT ** statement to populate the new table. The root-page number for the ** new table is on the top of the vdbe stack. ** |
︙ | ︙ | |||
1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 | sqlite3VdbeChangeP3(v, -1, pParse->sNameToken.z, n); sqlite3VdbeAddOp(v, OP_Concat8, 2, 0); } sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); sqlite3ChangeCookie(db, v, p->iDb); sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3EndWriteOperation(pParse); } /* Add the table to the in-memory representation of the database. */ | > > | | 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 | sqlite3VdbeChangeP3(v, -1, pParse->sNameToken.z, n); sqlite3VdbeAddOp(v, OP_Concat8, 2, 0); } sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); sqlite3ChangeCookie(db, v, p->iDb); sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0, sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC); sqlite3EndWriteOperation(pParse); } /* Add the table to the in-memory representation of the database. */ if( db->init.busy && pParse->nErr==0 ){ Table *pOld; FKey *pFKey; pOld = sqlite3HashInsert(&db->aDb[p->iDb].tblHash, p->zName, strlen(p->zName)+1, p); if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ return; |
︙ | ︙ | |||
1561 1562 1563 1564 1565 1566 1567 | if( pTab->pSelect ){ sqliteViewResetColumnNames(pTab); } } DbClearProperty(db, idx, DB_UnresetViews); } | < < < < < < < < < < < < < < < < < < < < | 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 | if( pTab->pSelect ){ sqliteViewResetColumnNames(pTab); } } DbClearProperty(db, idx, DB_UnresetViews); } /* ** This routine is called to do the work of a DROP TABLE statement. ** pName is the name of the table to be dropped. */ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){ Table *pTab; Vdbe *v; |
︙ | ︙ | |||
2095 2096 2097 2098 2099 2100 2101 | } } } /* Link the new Index structure to its table and to the other ** in-memory database structures. */ | | < < < < < < | | > | 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 | } } } /* Link the new Index structure to its table and to the other ** in-memory database structures. */ if( db->init.busy ){ Index *p; p = sqlite3HashInsert(&db->aDb[pIndex->iDb].idxHash, pIndex->zName, strlen(pIndex->zName)+1, pIndex); if( p ){ assert( p==pIndex ); /* Malloc must have failed */ goto exit_create_index; } db->flags |= SQLITE_InternChanges; if( pTblName!=0 ){ pIndex->tnum = db->init.newTnum; } } /* If the db->init.busy is 0 then create the index on disk. This ** involves writing the index into the master table and filling in the ** index with the current table contents. ** ** The db->init.busy is 0 when the user first enters a CREATE INDEX |
︙ | ︙ | |||
2144 2145 2146 2147 2148 2149 2150 | sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3OpenMasterTable(v, iDb); } sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, "index", P3_STATIC); sqlite3VdbeOp3(v, OP_String8, 0, 0, pIndex->zName, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); | | < | 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 | sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3OpenMasterTable(v, iDb); } sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, "index", P3_STATIC); sqlite3VdbeOp3(v, OP_String8, 0, 0, pIndex->zName, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0); if( pTblName ){ sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); sqlite3VdbeOp3(v, OP_OpenWrite, 1, 0, (char*)&pIndex->keyInfo, P3_KEYINFO); } sqlite3VdbeAddOp(v, OP_String8, 0, 0); |
︙ | ︙ | |||
2181 2182 2183 2184 2185 2186 2187 | sqlite3GenerateIndexKey(v, pIndex, 2); sqlite3VdbeOp3(v, OP_IdxPut, 1, pIndex->onError!=OE_None, "indexed columns are not unique", P3_STATIC); sqlite3VdbeAddOp(v, OP_Next, 2, lbl1); sqlite3VdbeResolveLabel(v, lbl2); sqlite3VdbeAddOp(v, OP_Close, 2, 0); sqlite3VdbeAddOp(v, OP_Close, 1, 0); | < < > > > | | | | | | | | | | | | | > | 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 | sqlite3GenerateIndexKey(v, pIndex, 2); sqlite3VdbeOp3(v, OP_IdxPut, 1, pIndex->onError!=OE_None, "indexed columns are not unique", P3_STATIC); sqlite3VdbeAddOp(v, OP_Next, 2, lbl1); sqlite3VdbeResolveLabel(v, lbl2); sqlite3VdbeAddOp(v, OP_Close, 2, 0); sqlite3VdbeAddOp(v, OP_Close, 1, 0); sqlite3ChangeCookie(db, v, iDb); sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3EndWriteOperation(pParse); sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, sqlite3MPrintf("name='%q'", pIndex->zName), P3_DYNAMIC); } } /* When adding an index to the list of indices for a table, make ** sure all indices labeled OE_Replace come after all those labeled ** OE_Ignore. This is necessary for the correct operation of UPDATE ** and INSERT. */ if( db->init.busy || pTblName==0 ){ if( onError!=OE_Replace || pTab->pIndex==0 || pTab->pIndex->onError==OE_Replace){ pIndex->pNext = pTab->pIndex; pTab->pIndex = pIndex; }else{ Index *pOther = pTab->pIndex; while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){ pOther = pOther->pNext; } pIndex->pNext = pOther->pNext; pOther->pNext = pIndex; } pIndex = 0; } /* Clean up before exiting */ exit_create_index: if( pIndex ) sqliteFree(pIndex); sqlite3ExprListDelete(pList); sqlite3SrcListDelete(pTblName); sqliteFree(zName); |
︙ | ︙ | |||
2240 2241 2242 2243 2244 2245 2246 | goto exit_drop_index; } if( pIndex->autoIndex ){ sqlite3ErrorMsg(pParse, "index associated with UNIQUE " "or PRIMARY KEY constraint cannot be dropped", 0); goto exit_drop_index; } | < < < < < < < | 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 | goto exit_drop_index; } if( pIndex->autoIndex ){ sqlite3ErrorMsg(pParse, "index associated with UNIQUE " "or PRIMARY KEY constraint cannot be dropped", 0); goto exit_drop_index; } #ifndef SQLITE_OMIT_AUTHORIZATION { int code = SQLITE_DROP_INDEX; Table *pTab = pIndex->pTable; const char *zDb = db->aDb[pIndex->iDb].zName; const char *zTab = SCHEMA_TABLE(pIndex->iDb); if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ |
︙ | ︙ | |||
2268 2269 2270 2271 2272 2273 2274 | #endif /* Generate code to remove the index and from the master table */ v = sqlite3GetVdbe(pParse); if( v ){ static VdbeOpList dropIndex[] = { { OP_Rewind, 0, ADDR(9), 0}, | | | 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 | #endif /* Generate code to remove the index and from the master table */ v = sqlite3GetVdbe(pParse); if( v ){ static VdbeOpList dropIndex[] = { { OP_Rewind, 0, ADDR(9), 0}, { OP_String8, 0, 0, 0}, /* 1 */ { OP_MemStore, 1, 1, 0}, { OP_MemLoad, 1, 0, 0}, /* 3 */ { OP_Column, 0, 1, 0}, { OP_Eq, 0, ADDR(8), 0}, { OP_Next, 0, ADDR(3), 0}, { OP_Goto, 0, ADDR(9), 0}, { OP_Delete, 0, 0, 0}, /* 8 */ |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | < < < < < < < < < > < | | | | < > | | | | | < < < | < < < < | | | | | | | | | < | | | | | | | | | | | | | | | < | < < < | | | | | | | | | | | | < < < < < < < < | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.247 2004/07/24 03:30:48 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** The following constant value is used by the SQLITE_BIGENDIAN and ** SQLITE_LITTLEENDIAN macros. */ const int sqlite3one = 1; /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. */ static void corruptSchema(InitData *pData, const char *zExtra){ if( !sqlite3_malloc_failed ){ sqlite3SetString(pData->pzErrMsg, "malformed database schema", zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0); } } /* ** This is the callback routine for the code that initializes the ** database. See sqlite3Init() below for additional information. ** This routine is also called from the OP_ParseSchema opcode of the VDBE. ** ** Each callback contains the following information: ** ** argv[0] = name of thing being created ** argv[1] = root page number for table or index. NULL for trigger or view. ** argv[2] = SQL text for the CREATE statement. ** argv[3] = "1" for temporary files, "0" for main database, "2" or more ** for auxiliary database files. ** */ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){ InitData *pData = (InitData*)pInit; sqlite *db = pData->db; int iDb; assert( argc==4 ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[1]==0 || argv[3]==0 ){ corruptSchema(pData, 0); return 1; } iDb = atoi(argv[3]); assert( iDb>=0 && iDb<db->nDb ); if( argv[2] && argv[2][0] ){ /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. */ char *zErr; int rc; assert( db->init.busy ); db->init.iDb = iDb; db->init.newTnum = atoi(argv[1]); rc = sqlite3_exec(db, argv[2], 0, 0, &zErr); db->init.iDb = 0; if( SQLITE_OK!=rc ){ corruptSchema(pData, zErr); sqlite3_free(zErr); return rc; } }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE ** constraint for a CREATE TABLE. The index should have already ** been created when we processed the CREATE TABLE. All we have ** to do here is record the root page number for that index. */ Index *pIndex; pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName); if( pIndex==0 || pIndex->tnum!=0 ){ /* This can occur if there exists an index on a TEMP table which ** has the same name as another index on a permanent index. Since ** the permanent table is hidden by the TEMP table, we can also ** safely ignore the index on the permanent table. */ /* Do Nothing */; }else{ pIndex->tnum = atoi(argv[1]); } } return 0; } /* ** Attempt to read the database schema and initialize internal ** data structures for a single database file. The index of the ** database file is given by iDb. iDb==0 is used for the main ** database. iDb==1 should never be used. iDb>=2 is used for ** auxiliary databases. Return one of the SQLITE_ error codes to ** indicate success or failure. */ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){ int rc; BtCursor *curMain; int size; Table *pTab; char const *azArg[5]; char zDbNum[30]; int meta[10]; InitData initData; char const *zMasterSchema; char const *zMasterName; /* |
︙ | ︙ | |||
188 189 190 191 192 193 194 | }else{ zMasterSchema = master_schema; zMasterName = MASTER_NAME; } /* Construct the schema tables. */ sqlite3SafetyOff(db); | | | | < | | | | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | }else{ zMasterSchema = master_schema; zMasterName = MASTER_NAME; } /* Construct the schema tables. */ sqlite3SafetyOff(db); azArg[0] = zMasterName; azArg[1] = "1"; azArg[2] = zMasterSchema; sprintf(zDbNum, "%d", iDb); azArg[3] = zDbNum; azArg[4] = 0; initData.db = db; initData.pzErrMsg = pzErrMsg; rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0); if( rc!=SQLITE_OK ){ sqlite3SafetyOn(db); return rc; } pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); if( pTab ){ pTab->readOnly = 1; |
︙ | ︙ | |||
300 301 302 303 304 305 306 | /* Read the schema information out of the schema tables */ assert( db->init.busy ); if( rc==SQLITE_EMPTY ){ /* For an empty database, there is nothing to read */ rc = SQLITE_OK; }else{ | | | < | | > < > | 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | /* Read the schema information out of the schema tables */ assert( db->init.busy ); if( rc==SQLITE_EMPTY ){ /* For an empty database, there is nothing to read */ rc = SQLITE_OK; }else{ char *zSql; zSql = sqlite3MPrintf( "SELECT name, rootpage, sql, %s FROM '%q'.%s", zDbNum, db->aDb[iDb].zName, zMasterName); sqlite3SafetyOff(db); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); sqlite3SafetyOn(db); sqliteFree(zSql); sqlite3BtreeCloseCursor(curMain); } if( sqlite3_malloc_failed ){ sqlite3SetString(pzErrMsg, "out of memory", (char*)0); rc = SQLITE_NOMEM; sqlite3ResetInternalSchema(db, 0); } |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.309 2004/07/24 03:30:48 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ #include "config.h" #include "sqlite3.h" #include "hash.h" |
︙ | ︙ | |||
1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 | typedef struct DbFixer DbFixer; struct DbFixer { Parse *pParse; /* The parsing context. Error messages written here */ const char *zDb; /* Make sure all objects are contained in this database */ const char *zType; /* Type of the container - used for error messages */ const Token *pName; /* Name of the container - used for error messages */ }; /* * This global flag is set for performance testing of triggers. When it is set * SQLite will perform the overhead of building new and old trigger references * even when no triggers exist */ extern int sqlite3_always_code_trigger_setup; | > > > > > > > > > > | 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 | typedef struct DbFixer DbFixer; struct DbFixer { Parse *pParse; /* The parsing context. Error messages written here */ const char *zDb; /* Make sure all objects are contained in this database */ const char *zType; /* Type of the container - used for error messages */ const Token *pName; /* Name of the container - used for error messages */ }; /* ** A pointer to this structure is used to communicate information ** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback. */ typedef struct { sqlite *db; /* The database being initialized */ char **pzErrMsg; /* Error message stored here */ } InitData; /* * This global flag is set for performance testing of triggers. When it is set * SQLite will perform the overhead of building new and old trigger references * even when no triggers exist */ extern int sqlite3_always_code_trigger_setup; |
︙ | ︙ | |||
1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 | Expr *sqlite3Expr(int, Expr*, Expr*, Token*); void sqlite3ExprSpan(Expr*,Token*,Token*); Expr *sqlite3ExprFunction(ExprList*, Token*); void sqlite3ExprDelete(Expr*); ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*); void sqlite3ExprListDelete(ExprList*); int sqlite3Init(sqlite*, char**); void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); void sqlite3ResetInternalSchema(sqlite*, int); void sqlite3BeginParse(Parse*,int); void sqlite3RollbackInternalChanges(sqlite*); void sqlite3CommitInternalChanges(sqlite*); Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*); void sqlite3OpenMasterTable(Vdbe *v, int); | > | 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 | Expr *sqlite3Expr(int, Expr*, Expr*, Token*); void sqlite3ExprSpan(Expr*,Token*,Token*); Expr *sqlite3ExprFunction(ExprList*, Token*); void sqlite3ExprDelete(Expr*); ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*); void sqlite3ExprListDelete(ExprList*); int sqlite3Init(sqlite*, char**); int sqlite3InitCallback(void*, int, char**, char**); void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); void sqlite3ResetInternalSchema(sqlite*, int); void sqlite3BeginParse(Parse*,int); void sqlite3RollbackInternalChanges(sqlite*); void sqlite3CommitInternalChanges(sqlite*); Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*); void sqlite3OpenMasterTable(Vdbe *v, int); |
︙ | ︙ |
Changes to src/tokenize.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** ** $Id: tokenize.c,v 1.79 2004/07/24 03:30:48 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include <stdlib.h> /* |
︙ | ︙ | |||
427 428 429 430 431 432 433 434 435 436 437 438 439 440 | pParse->rc = SQLITE_OK; i = 0; pEngine = sqlite3ParserAlloc((void*(*)(int))malloc); if( pEngine==0 ){ sqlite3SetString(pzErrMsg, "out of memory", (char*)0); return 1; } pParse->sLastToken.dyn = 0; pParse->zTail = zSql; while( sqlite3_malloc_failed==0 && zSql[i]!=0 ){ assert( i>=0 ); pParse->sLastToken.z = &zSql[i]; assert( pParse->sLastToken.dyn==0 ); pParse->sLastToken.n = sqliteGetToken((unsigned char*)&zSql[i], &tokenType); | > > > > > | 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | pParse->rc = SQLITE_OK; i = 0; pEngine = sqlite3ParserAlloc((void*(*)(int))malloc); if( pEngine==0 ){ sqlite3SetString(pzErrMsg, "out of memory", (char*)0); return 1; } #ifndef NDEBUG if( sqlite3OsFileExists("vdbe_sqltrace") ){ printf("SQL To Compiler: [%s]\n", zSql); } #endif pParse->sLastToken.dyn = 0; pParse->zTail = zSql; while( sqlite3_malloc_failed==0 && zSql[i]!=0 ){ assert( i>=0 ); pParse->sLastToken.z = &zSql[i]; assert( pParse->sLastToken.dyn==0 ); pParse->sLastToken.n = sqliteGetToken((unsigned char*)&zSql[i], &tokenType); |
︙ | ︙ | |||
710 711 712 713 714 715 716 | zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8); if( zSql8 ){ rc = sqlite3_complete(zSql8); } sqlite3ValueFree(pVal); return rc; } | < | 715 716 717 718 719 720 721 | zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8); if( zSql8 ){ rc = sqlite3_complete(zSql8); } sqlite3ValueFree(pVal); return rc; } |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.404 2004/07/24 03:30:48 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
3666 3667 3668 3669 3670 3671 3672 | ** See also: Destroy */ case OP_Clear: { rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1); break; } | | < < < < < | | | | > | < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 | ** See also: Destroy */ case OP_Clear: { rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1); break; } /* Opcode: CreateTable P1 * * ** ** Allocate a new table in the main database file if P2==0 or in the ** auxiliary database file if P2==1. Push the page number ** for the root page of the new table onto the stack. ** ** The difference between a table and an index is this: A table must ** have a 4-byte integer key and can have arbitrary data. An index ** has an arbitrary key but no data. ** ** See also: CreateIndex */ /* Opcode: CreateIndex P1 * * ** ** Allocate a new index in the main database file if P2==0 or in the ** auxiliary database file if P2==1. Push the page number of the ** root page of the new index onto the stack. ** ** See documentation on OP_CreateTable for additional information. */ case OP_CreateIndex: case OP_CreateTable: { int pgno; int flags; Db *pDb; assert( pOp->p1>=0 && pOp->p1<db->nDb ); pDb = &db->aDb[pOp->p1]; assert( pDb->pBt!=0 ); if( pOp->opcode==OP_CreateTable ){ /* flags = BTREE_INTKEY; */ flags = BTREE_LEAFDATA|BTREE_INTKEY; }else{ flags = BTREE_ZERODATA; } rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags); pTos++; if( rc==SQLITE_OK ){ pTos->i = pgno; pTos->flags = MEM_Int; }else{ pTos->flags = MEM_Null; } break; } /* Opcode: ParseSchema P1 * P3 ** ** Read and parse all entries from the SQLITE_MASTER table of database P1 ** that match the WHERE clause P3. ** ** This opcode invokes the parser to create a new virtual machine, ** then runs the new virtual machine. It is thus a reentrant opcode. */ case OP_ParseSchema: { char *zSql; int iDb = pOp->p1; const char *zMaster; InitData initData; assert( iDb>=0 && iDb<db->nDb ); zMaster = iDb==1 ? TEMP_MASTER_NAME : MASTER_NAME; initData.db = db; initData.pzErrMsg = &p->zErrMsg; zSql = sqlite3MPrintf( "SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s", pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3); sqlite3SafetyOff(db); assert( db->init.busy==0 ); db->init.busy = 1; rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); db->init.busy = 0; sqlite3SafetyOn(db); sqliteFree(zSql); break; } /* Opcode: IntegrityCk * P2 * ** ** Do an analysis of the currently open database. Push onto the ** stack the text of an error message describing any problems. ** If there are no errors, push a "ok" onto the stack. ** |
︙ | ︙ |
Changes to test/misc4.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for miscellanous features that were # left out of other test files. # | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for miscellanous features that were # left out of other test files. # # $Id: misc4.test,v 1.4 2004/07/24 03:30:49 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Prepare a statement that will create a temporary table. Then do # a rollback. Then try to execute the prepared statement. # |
︙ | ︙ | |||
49 50 51 52 53 54 55 56 57 | execsql {DROP TABLE t2} sqlite3_reset $stmt sqlite3_step $stmt } {SQLITE_ERROR} do_test misc4-1.3 { sqlite3_finalize $stmt } {SQLITE_SCHEMA} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | execsql {DROP TABLE t2} sqlite3_reset $stmt sqlite3_step $stmt } {SQLITE_ERROR} do_test misc4-1.3 { sqlite3_finalize $stmt } {SQLITE_SCHEMA} # Prepare but do not execute various CREATE statements. Then before # those statements are executed, try to use the tables, indices, views, # are triggers that were created. # if 0 { do_test misc4-2.1 { set stmt [sqlite3_prepare $DB {CREATE TABLE t3(x);} -1 TAIL] catchsql { pragma vdbe_trace=on; INSERT INTO t3 VALUES(1); } } {1 {no such table: t3}} do_test misc4-2.2 { sqlite3_step $stmt } SQLITE_DONE do_test misc4-2.3 { sqlite3_finalize $stmt } SQLITE_OK do_test misc4-2.4 { catchsql { INSERT INTO t3 VALUES(1); } } {0 {}} } finish_test |
Changes to test/table.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 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 implements regression tests for SQLite library. The # focus of this file is testing the CREATE TABLE statement. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 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 implements regression tests for SQLite library. The # focus of this file is testing the CREATE TABLE statement. # # $Id: table.test,v 1.29 2004/07/24 03:30:49 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create a basic table and verify it is added to sqlite_master # do_test table-1.1 { |
︙ | ︙ | |||
312 313 314 315 316 317 318 | } } {desc a asc b explain 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all} do_test table-8.1.1 { execsql { SELECT sql FROM sqlite_master WHERE name='t2'; } } {{CREATE TABLE t2( | | | | | | | | | | | | | | | | | | 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | } } {desc a asc b explain 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all} do_test table-8.1.1 { execsql { SELECT sql FROM sqlite_master WHERE name='t2'; } } {{CREATE TABLE t2( "desc" text, "asc" text, "explain" int, "14_vac" boolean, fuzzy_dog_12 varchar(10), "begin" blob, "end" clob )}} do_test table-8.2 { execsql { CREATE TABLE "t3""xyz"(a,b,c); INSERT INTO [t3"xyz] VALUES(1,2,3); SELECT * FROM [t3"xyz]; } } {1 2 3} do_test table-8.3 { execsql2 { CREATE TABLE [t4"abc] AS SELECT count(*) as cnt, max(b+c) FROM [t3"xyz]; SELECT * FROM [t4"abc]; } } {cnt 1 max(b+c) 5} # Update for v3: The declaration type of anything except a column is now a # NULL pointer, so the created table has no column types. (Changed result # from {{CREATE TABLE 't4"abc'(cnt NUMERIC,"max(b+c)" NUMERIC)}}). do_test table-8.3.1 { execsql { SELECT sql FROM sqlite_master WHERE name='t4"abc' } } {{CREATE TABLE "t4""abc"(cnt,"max(b+c)")}} do_test table-8.4 { execsql2 { CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3"xyz]; SELECT * FROM t5; } } {y'all 1} do_test table-8.5 { db close sqlite3 db test.db execsql2 { SELECT * FROM [t4"abc]; } } {cnt 1 max(b+c) 5} do_test table-8.6 { execsql2 { SELECT * FROM t2; } } {desc a asc b explain 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all} |
︙ | ︙ | |||
516 517 518 519 520 521 522 | do_test table-12.2 { execsql { SELECT sql FROM sqlite_master WHERE tbl_name = 't8' } } {{CREATE TABLE t8(b number(5,10),h,i integer,j BLOB)}} finish_test | < < | 516 517 518 519 520 521 522 | do_test table-12.2 { execsql { SELECT sql FROM sqlite_master WHERE tbl_name = 't8' } } {{CREATE TABLE t8(b number(5,10),h,i integer,j BLOB)}} finish_test |