Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Store collation sequence names instead of pointers in sharable schema data structures. (CVS 2904) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
0f0213be4d064b3d24e31ff93ec16f68 |
User & Date: | danielk1977 2006-01-10 17:58:23.000 |
Context
2006-01-10
| ||
18:08 | Typos in new documentation. (CVS 2905) (check-in: b5bedb2a9f user: danielk1977 tags: trunk) | |
17:58 | Store collation sequence names instead of pointers in sharable schema data structures. (CVS 2904) (check-in: 0f0213be4d user: danielk1977 tags: trunk) | |
15:18 | Updates to the C-API documentation. Change the parameter type of sqlite3_soft_heap_limit to integer. (CVS 2903) (check-in: bdd35e9fbb user: drh tags: trunk) | |
Changes
Changes to src/analyze.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2005 July 8 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code associated with the ANALYZE command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2005 July 8 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code associated with the ANALYZE command. ** ** @(#) $Id: analyze.c,v 1.16 2006/01/10 17:58:23 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" /* ** This routine generates code that opens the sqlite_stat1 table on cursor ** iStatCur. |
︙ | ︙ | |||
110 111 112 113 114 115 116 117 118 119 120 121 122 | #endif /* Establish a read-lock on the table at the shared-cache level. */ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); iIdxCur = pParse->nTab; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ /* Open a cursor to the index to be analyzed */ assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) ); sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); VdbeComment((v, "# %s", pIdx->zName)); sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, | > > | | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #endif /* Establish a read-lock on the table at the shared-cache level. */ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); iIdxCur = pParse->nTab; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); /* Open a cursor to the index to be analyzed */ assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) ); sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); VdbeComment((v, "# %s", pIdx->zName)); sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, (char *)pKey, P3_KEYINFO_HANDOFF); nCol = pIdx->nColumn; if( iMem+nCol*2>=pParse->nMem ){ pParse->nMem = iMem+nCol*2+1; } sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, nCol+1); /* Memory cells are used as follows: |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.375 2006/01/10 17:58:23 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. |
︙ | ︙ | |||
464 465 466 467 468 469 470 471 472 473 474 475 476 477 | Column *pCol; assert( pTable!=0 ); if( (pCol = pTable->aCol)!=0 ){ for(i=0; i<pTable->nCol; i++, pCol++){ sqliteFree(pCol->zName); sqlite3ExprDelete(pCol->pDflt); sqliteFree(pCol->zType); } sqliteFree(pTable->aCol); } pTable->aCol = 0; pTable->nCol = 0; } | > | 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | Column *pCol; assert( pTable!=0 ); if( (pCol = pTable->aCol)!=0 ){ for(i=0; i<pTable->nCol; i++, pCol++){ sqliteFree(pCol->zName); sqlite3ExprDelete(pCol->pDflt); sqliteFree(pCol->zType); sqliteFree(pCol->zColl); } sqliteFree(pTable->aCol); } pTable->aCol = 0; pTable->nCol = 0; } |
︙ | ︙ | |||
934 935 936 937 938 939 940 | pCol->zName = z; /* If there is no type specified, columns have the default affinity ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will ** be called next to set pCol->affinity correctly. */ pCol->affinity = SQLITE_AFF_NONE; | < | 935 936 937 938 939 940 941 942 943 944 945 946 947 948 | pCol->zName = z; /* If there is no type specified, columns have the default affinity ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will ** be called next to set pCol->affinity correctly. */ pCol->affinity = SQLITE_AFF_NONE; p->nCol++; } /* ** This routine is called by the parser while in the middle of ** parsing a CREATE TABLE statement. A "NOT NULL" constraint has ** been seen on a column. This routine sets the notNull flag on |
︙ | ︙ | |||
1163 1164 1165 1166 1167 1168 1169 | /* ** Set the collation function of the most recently parsed table column ** to the CollSeq given. */ void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){ Table *p; | < < | > | | | | | | | | | < < | < < < < < < < < < < < < > | | 1163 1164 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 | /* ** Set the collation function of the most recently parsed table column ** to the CollSeq given. */ void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){ Table *p; int i; if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; if( sqlite3LocateCollSeq(pParse, zType, nType) ){ Index *pIdx; p->aCol[i].zColl = sqlite3StrNDup(zType, nType); /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>", ** then an index may have been created on this column before the ** collation type was added. Correct this if it is the case. */ for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ assert( pIdx->nColumn==1 ); if( pIdx->aiColumn[0]==i ){ pIdx->azColl[0] = p->aCol[i].zColl; } } } } /* ** This function returns the collation sequence for database native text ** encoding identified by the string zName, length nName. ** ** If the requested collation sequence is not available, or not available ** in the database native encoding, the collation factory is invoked to ** request it. If the collation factory does not supply such a sequence, ** and the sequence is available in another text encoding, then that is ** returned instead. ** ** If no versions of the requested collations sequence are available, or ** another error occurs, NULL is returned and an error message written into ** pParse. */ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){ sqlite3 *db = pParse->db; u8 enc = ENC(db); u8 initbusy = db->init.busy; CollSeq *pColl; pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy); if( !initbusy && (!pColl || !pColl->xCmp) ){ pColl = sqlite3GetCollSeq(db, pColl, zName, nName); if( !pColl ){ if( nName<0 ){ nName = strlen(zName); } sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName); |
︙ | ︙ | |||
2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 | static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ Table *pTab = pIndex->pTable; /* The table that is indexed */ int iTab = pParse->nTab; /* Btree cursor used for pTab */ int iIdx = pParse->nTab+1; /* Btree cursor used for pIndex */ int addr1; /* Address of top of loop */ int tnum; /* Root page of index */ Vdbe *v; /* Generate code into this virtual machine */ int iDb = sqlite3SchemaToIndex(pParse->db, pIndex->pSchema); #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, pParse->db->aDb[iDb].zName ) ){ return; } #endif | > < < < < < < < < > | < | 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 | static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ Table *pTab = pIndex->pTable; /* The table that is indexed */ int iTab = pParse->nTab; /* Btree cursor used for pTab */ int iIdx = pParse->nTab+1; /* Btree cursor used for pIndex */ int addr1; /* Address of top of loop */ int tnum; /* Root page of index */ Vdbe *v; /* Generate code into this virtual machine */ KeyInfo *pKey; /* KeyInfo for index */ int iDb = sqlite3SchemaToIndex(pParse->db, pIndex->pSchema); #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, pParse->db->aDb[iDb].zName ) ){ return; } #endif /* Require a write-lock on the table to perform this operation */ sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); v = sqlite3GetVdbe(pParse); if( v==0 ) return; if( memRootPage>=0 ){ sqlite3VdbeAddOp(v, OP_MemLoad, memRootPage, 0); tnum = 0; }else{ tnum = pIndex->tnum; sqlite3VdbeAddOp(v, OP_Clear, tnum, iDb); } sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); pKey = sqlite3IndexKeyinfo(pParse, pIndex); sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum, (char *)pKey, P3_KEYINFO_HANDOFF); sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0); sqlite3GenerateIndexKey(v, pIndex, iTab); if( pIndex->onError!=OE_None ){ int curaddr = sqlite3VdbeCurrentAddr(v); int addr2 = curaddr+4; sqlite3VdbeChangeP2(v, curaddr-1, addr2); |
︙ | ︙ | |||
2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 | DbFixer sFix; /* For assigning database names to pTable */ int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */ sqlite3 *db = pParse->db; Db *pDb; /* The specific table containing the indexed database */ int iDb; /* Index of the database that is being written */ Token *pName = 0; /* Unqualified name of the index to create */ struct ExprList_item *pListItem; /* For looping over pList */ if( pParse->nErr || sqlite3ThreadData()->mallocFailed ){ goto exit_create_index; } /* ** Find the table that is to be indexed. Return early if not found. | > > > | 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 | DbFixer sFix; /* For assigning database names to pTable */ int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */ sqlite3 *db = pParse->db; Db *pDb; /* The specific table containing the indexed database */ int iDb; /* Index of the database that is being written */ Token *pName = 0; /* Unqualified name of the index to create */ struct ExprList_item *pListItem; /* For looping over pList */ int nCol; int nExtra = 0; char *zExtra; if( pParse->nErr || sqlite3ThreadData()->mallocFailed ){ goto exit_create_index; } /* ** Find the table that is to be indexed. Return early if not found. |
︙ | ︙ | |||
2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 | if( pList==0 ){ nullId.z = (u8*)pTab->aCol[pTab->nCol-1].zName; nullId.n = strlen((char*)nullId.z); pList = sqlite3ExprListAppend(0, 0, &nullId); if( pList==0 ) goto exit_create_index; pList->a[0].sortOrder = sortOrder; } /* ** Allocate the index structure. */ nName = strlen(zName); | > > > > > > > > > > > | > | > > > > > > | | > > | | | 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 | if( pList==0 ){ nullId.z = (u8*)pTab->aCol[pTab->nCol-1].zName; nullId.n = strlen((char*)nullId.z); pList = sqlite3ExprListAppend(0, 0, &nullId); if( pList==0 ) goto exit_create_index; pList->a[0].sortOrder = sortOrder; } /* Figure out how many bytes of space are required to store explicitly ** specified collation sequence names. */ for(i=0; i<pList->nExpr; i++){ Expr *pExpr = pList->a[i].pExpr; if( pExpr ){ nExtra += (1 + strlen(pExpr->pColl->zName)); } } /* ** Allocate the index structure. */ nName = strlen(zName); nCol = pList->nExpr; pIndex = sqliteMalloc( sizeof(Index) + /* Index structure */ sizeof(int)*nCol + /* Index.aiColumn */ sizeof(int)*(nCol+1) + /* Index.aiRowEst */ sizeof(char *)*nCol + /* Index.azColl */ sizeof(u8)*nCol + /* Index.aSortOrder */ nName + 1 + /* Index.zName */ nExtra /* Collation sequence names */ ); if( sqlite3ThreadData()->mallocFailed ) goto exit_create_index; pIndex->aiColumn = (int *)(&pIndex[1]); pIndex->aiRowEst = (int *)(&pIndex->aiColumn[nCol]); pIndex->azColl = (char **)(&pIndex->aiRowEst[nCol+1]); pIndex->aSortOrder = (u8 *)(&pIndex->azColl[nCol]); pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]); zExtra = (char *)(&pIndex->zName[nName+1]); strcpy(pIndex->zName, zName); pIndex->pTable = pTab; pIndex->nColumn = pList->nExpr; pIndex->onError = onError; pIndex->autoIndex = pName==0; pIndex->pSchema = db->aDb[iDb].pSchema; |
︙ | ︙ | |||
2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 | ** load the column indices into the Index structure. Report an error ** if any column is not found. */ for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){ const char *zColName = pListItem->zName; Column *pTabCol; int requestedSortOrder; for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){ if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; } if( j>=pTab->nCol ){ sqlite3ErrorMsg(pParse, "table %s has no column named %s", pTab->zName, zColName); goto exit_create_index; } pIndex->aiColumn[i] = j; if( pListItem->pExpr ){ assert( pListItem->pExpr->pColl ); | > > > | > | > > | < > | < < > | < | 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 | ** load the column indices into the Index structure. Report an error ** if any column is not found. */ for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){ const char *zColName = pListItem->zName; Column *pTabCol; int requestedSortOrder; char *zColl; /* Collation sequence */ for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){ if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; } if( j>=pTab->nCol ){ sqlite3ErrorMsg(pParse, "table %s has no column named %s", pTab->zName, zColName); goto exit_create_index; } pIndex->aiColumn[i] = j; if( pListItem->pExpr ){ assert( pListItem->pExpr->pColl ); zColl = zExtra; strcpy(zExtra, pListItem->pExpr->pColl->zName); zExtra += (strlen(zColl) + 1); }else{ zColl = pTab->aCol[j].zColl; if( !zColl ){ zColl = db->pDfltColl->zName; } } if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl, -1) ){ goto exit_create_index; } pIndex->azColl[i] = zColl; requestedSortOrder = pListItem->sortOrder & sortOrderMask; pIndex->aSortOrder[i] = requestedSortOrder; } sqlite3DefaultRowEst(pIndex); if( pTab==pParse->pNewTable ){ /* This routine has been called to create an automatic index as a ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or ** a PRIMARY KEY or UNIQUE clause following the column definitions. ** i.e. one of: |
︙ | ︙ | |||
2432 2433 2434 2435 2436 2437 2438 2439 | int k; assert( pIdx->onError!=OE_None ); assert( pIdx->autoIndex ); assert( pIndex->onError!=OE_None ); if( pIdx->nColumn!=pIndex->nColumn ) continue; for(k=0; k<pIdx->nColumn; k++){ if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break; | > > < | > | 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 | int k; assert( pIdx->onError!=OE_None ); assert( pIdx->autoIndex ); assert( pIndex->onError!=OE_None ); if( pIdx->nColumn!=pIndex->nColumn ) continue; for(k=0; k<pIdx->nColumn; k++){ const char *z1 = pIdx->azColl[k]; const char *z2 = pIndex->azColl[k]; if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break; if( pIdx->aSortOrder[k]!=pIndex->aSortOrder[k] ) break; if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break; } if( k==pIdx->nColumn ){ if( pIdx->onError!=pIndex->onError ){ /* This constraint creates the same index as a previous ** constraint specified somewhere in the CREATE TABLE statement. ** However the ON CONFLICT clauses are different. If both this ** constraint and the previous equivalent constraint have explicit |
︙ | ︙ | |||
3050 3051 3052 3053 3054 3055 3056 | } /* ** Check to see if pIndex uses the collating sequence pColl. Return ** true if it does and false if it does not. */ #ifndef SQLITE_OMIT_REINDEX | | > | | < > | < > | | | | | 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 | } /* ** Check to see if pIndex uses the collating sequence pColl. Return ** true if it does and false if it does not. */ #ifndef SQLITE_OMIT_REINDEX static int collationMatch(const char *zColl, Index *pIndex){ int i; for(i=0; i<pIndex->nColumn; i++){ const char *z = pIndex->azColl[i]; if( z==zColl || (z && zColl && 0==sqlite3StrICmp(z, zColl)) ){ return 1; } } return 0; } #endif /* ** Recompute all indices of pTab that use the collating sequence pColl. ** If pColl==0 then recompute all indices of pTab. */ #ifndef SQLITE_OMIT_REINDEX static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){ Index *pIndex; /* An index associated with pTab */ for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ if( zColl==0 || collationMatch(zColl, pIndex) ){ int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3RefillIndex(pParse, pIndex, -1); } } } #endif /* ** Recompute all indices of all tables in all databases where the ** indices use the collating sequence pColl. If pColl==0 then recompute ** all indices everywhere. */ #ifndef SQLITE_OMIT_REINDEX static void reindexDatabases(Parse *pParse, char const *zColl){ Db *pDb; /* A single database */ int iDb; /* The database index number */ sqlite3 *db = pParse->db; /* The database connection */ HashElem *k; /* For looping over tables in pDb */ Table *pTab; /* A table in the database */ for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){ if( pDb==0 ) continue; for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){ pTab = (Table*)sqliteHashData(k); reindexTable(pParse, pTab, zColl); } } } #endif /* ** Generate code for the REINDEX command. |
︙ | ︙ | |||
3136 3137 3138 3139 3140 3141 3142 3143 3144 | return; } if( pName1==0 || pName1->z==0 ){ reindexDatabases(pParse, 0); return; }else if( pName2==0 || pName2->z==0 ){ pColl = sqlite3FindCollSeq(db, ENC(db), (char*)pName1->z, pName1->n, 0); if( pColl ){ | > > > | > > | 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 | return; } if( pName1==0 || pName1->z==0 ){ reindexDatabases(pParse, 0); return; }else if( pName2==0 || pName2->z==0 ){ assert( pName1->z ); pColl = sqlite3FindCollSeq(db, ENC(db), (char*)pName1->z, pName1->n, 0); if( pColl ){ char *z = sqlite3StrNDup(pName1->z, pName1->n); if( z ){ reindexDatabases(pParse, z); sqliteFree(z); } return; } } iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); if( iDb<0 ) return; z = sqlite3NameFromToken(pObjName); zDb = db->aDb[iDb].zName; |
︙ | ︙ | |||
3162 3163 3164 3165 3166 3167 3168 | sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3RefillIndex(pParse, pIndex, -1); return; } sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); } #endif | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 | sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3RefillIndex(pParse, pIndex, -1); return; } sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); } #endif /* ** Return a dynamicly allocated KeyInfo structure that can be used ** with OP_OpenRead or OP_OpenWrite to access database index pIdx. ** ** If successful, a pointer to the new structure is returned. In this case ** the caller is responsible for calling sqliteFree() on the returned ** pointer. If an error occurs (out of memory or missing collation ** sequence), NULL is returned and the state of pParse updated to reflect ** the error. */ KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){ int i; int nCol = pIdx->nColumn; int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol; KeyInfo *pKey = (KeyInfo *)sqliteMalloc(nBytes); if( pKey ){ pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]); assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) ); for(i=0; i<nCol; i++){ char *zColl = pIdx->azColl[i]; assert( zColl ); pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl, -1); pKey->aSortOrder[i] = pIdx->aSortOrder[i]; } pKey->nField = nCol; } if( pParse->nErr ){ sqliteFree(pKey); pKey = 0; } return pKey; } |
Changes to src/callback.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. ** ** $Id: callback.c,v 1.10 2006/01/10 17:58:23 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Invoke the 'collation needed' callback to request a collation sequence ** in the database text encoding of name zName, length nName. |
︙ | ︙ | |||
126 127 128 129 130 131 132 133 134 135 136 137 138 139 | if( !p ){ if( pParse->nErr==0 ){ sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); } pParse->nErr++; return SQLITE_ERROR; } } return SQLITE_OK; } /* | > | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | if( !p ){ if( pParse->nErr==0 ){ sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); } pParse->nErr++; return SQLITE_ERROR; } assert( p==pColl ); } return SQLITE_OK; } /* |
︙ | ︙ | |||
195 196 197 198 199 200 201 | CollSeq *sqlite3FindCollSeq( sqlite3 *db, u8 enc, const char *zName, int nName, int create ){ | > > | > > > | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | CollSeq *sqlite3FindCollSeq( sqlite3 *db, u8 enc, const char *zName, int nName, int create ){ CollSeq *pColl; if( zName ){ pColl = findCollSeqEntry(db, zName, nName, create); }else{ pColl = db->pDfltColl; } assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE ); if( pColl ) pColl += enc-1; return pColl; } /* |
︙ | ︙ |
Changes to src/delete.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** ** $Id: delete.c,v 1.117 2006/01/10 17:58:23 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Look up every table that is named in pSrc. If any table is not found, ** add an error message to pParse->zErrMsg and return NULL. If all tables ** are found, return a pointer to the last table. |
︙ | ︙ | |||
232 233 234 235 236 237 238 | } } /* The usual case: There is a WHERE clause so we have to scan through ** the table and pick which records to delete. */ else{ | < < < < < < < | 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | } } /* The usual case: There is a WHERE clause so we have to scan through ** the table and pick which records to delete. */ else{ /* Begin the database scan */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0); if( pWInfo==0 ) goto delete_from_cleanup; /* Remember the rowid of every item to be deleted. */ |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.247 2006/01/10 17:58:23 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 | if( 0==(cntTab++) ){ pExpr->iTable = pItem->iCursor; pExpr->pSchema = pTab->pSchema; pMatch = pItem; } for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){ if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ IdList *pUsing; cnt++; pExpr->iTable = pItem->iCursor; pMatch = pItem; pExpr->pSchema = pTab->pSchema; /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ pExpr->iColumn = j==pTab->iPKey ? -1 : j; pExpr->affinity = pTab->aCol[j].affinity; | > | | 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 | if( 0==(cntTab++) ){ pExpr->iTable = pItem->iCursor; pExpr->pSchema = pTab->pSchema; pMatch = pItem; } for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){ if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ const char *zColl = pTab->aCol[j].zColl; IdList *pUsing; cnt++; pExpr->iTable = pItem->iCursor; pMatch = pItem; pExpr->pSchema = pTab->pSchema; /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ pExpr->iColumn = j==pTab->iPKey ? -1 : j; pExpr->affinity = pTab->aCol[j].affinity; pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0); if( pItem->jointype & JT_NATURAL ){ /* If this match occurred in the left table of a natural join, ** then skip the right table to avoid a duplicate match */ pItem++; i++; } if( (pUsing = pItem->pUsing)!=0 ){ |
︙ | ︙ | |||
922 923 924 925 926 927 928 929 930 931 | int j; Column *pCol = pTab->aCol; pExpr->pSchema = pTab->pSchema; cntTab++; for(j=0; j < pTab->nCol; j++, pCol++) { if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ cnt++; pExpr->iColumn = j==pTab->iPKey ? -1 : j; pExpr->affinity = pTab->aCol[j].affinity; | > | | 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 | int j; Column *pCol = pTab->aCol; pExpr->pSchema = pTab->pSchema; cntTab++; for(j=0; j < pTab->nCol; j++, pCol++) { if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ const char *zColl = pTab->aCol[j].zColl; cnt++; pExpr->iColumn = j==pTab->iPKey ? -1 : j; pExpr->affinity = pTab->aCol[j].affinity; pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0); pExpr->pTab = pTab; break; } } } } #endif /* !defined(SQLITE_OMIT_TRIGGER) */ |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** ** $Id: insert.c,v 1.156 2006/01/10 17:58:23 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Set P3 of the most recently inserted opcode to a column affinity ** string for index pIdx. A column affinity string has one character ** for each column in the table, according to the affinity of the column: |
︙ | ︙ | |||
271 272 273 274 275 276 277 | /* If pTab is really a view, make sure it has been initialized. */ if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){ goto insert_cleanup; } | < < < < < < < | 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | /* If pTab is really a view, make sure it has been initialized. */ if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){ goto insert_cleanup; } /* Allocate a VDBE */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto insert_cleanup; if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, iDb); |
︙ | ︙ | |||
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 | int i; int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); Index *pIdx; Vdbe *v = sqlite3GetVdbe(pParse); assert( v!=0 ); sqlite3OpenTable(pParse, base, iDb, pTab, op); for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ assert( pIdx->pSchema==pTab->pSchema ); sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); VdbeComment((v, "# %s", pIdx->zName)); | > | < | 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 | int i; int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); Index *pIdx; Vdbe *v = sqlite3GetVdbe(pParse); assert( v!=0 ); sqlite3OpenTable(pParse, base, iDb, pTab, op); for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); assert( pIdx->pSchema==pTab->pSchema ); sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); VdbeComment((v, "# %s", pIdx->zName)); sqlite3VdbeOp3(v, op, i+base, pIdx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF); } if( pParse->nTab<=base+i ){ pParse->nTab = base+i; } } |
Changes to src/pragma.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** ** $Id: pragma.c,v 1.112 2006/01/10 17:58:23 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* Ignore this whole file if pragmas are disabled */ |
︙ | ︙ | |||
666 667 668 669 670 671 672 | pTbls = &db->aDb[i].pSchema->tblHash; for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0); cnt++; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | < | 666 667 668 669 670 671 672 673 674 675 676 677 678 679 | pTbls = &db->aDb[i].pSchema->tblHash; for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0); cnt++; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0); cnt++; } } assert( cnt>0 ); sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i); sqlite3VdbeAddOp(v, OP_Dup, 0, 1); |
︙ | ︙ |
Changes to src/prepare.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** ** $Id: prepare.c,v 1.18 2006/01/10 17:58:23 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** Fill the InitData structure with an error message that indicates |
︙ | ︙ | |||
258 259 260 261 262 263 264 | ** For an attached db, it is an error if the encoding is not the same ** as sqlite3.enc. */ if( meta[4] ){ /* text encoding */ if( iDb==0 ){ /* If opening the main database, set ENC(db). */ ENC(db) = (u8)meta[4]; | | | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | ** For an attached db, it is an error if the encoding is not the same ** as sqlite3.enc. */ if( meta[4] ){ /* text encoding */ if( iDb==0 ){ /* If opening the main database, set ENC(db). */ ENC(db) = (u8)meta[4]; db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0); }else{ /* If opening an attached database, the encoding much match ENC(db) */ if( meta[4]!=ENC(db) ){ sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "attached databases must use the same" " text encoding as main database", (char*)0); return SQLITE_ERROR; |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** ** $Id: select.c,v 1.292 2006/01/10 17:58:23 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Allocate a new Select structure and return a pointer to that ** structure. |
︙ | ︙ | |||
974 975 976 977 978 979 980 981 982 983 984 985 986 987 | assert( pTab->nCol>0 ); pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol ); for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){ Expr *p, *pR; char *zType; char *zName; char *zBasename; int cnt; NameContext sNC; /* Get an appropriate name for the column */ p = pEList->a[i].pExpr; assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 ); | > | 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 | assert( pTab->nCol>0 ); pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol ); for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){ Expr *p, *pR; char *zType; char *zName; char *zBasename; CollSeq *pColl; int cnt; NameContext sNC; /* Get an appropriate name for the column */ p = pEList->a[i].pExpr; assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 ); |
︙ | ︙ | |||
1026 1027 1028 1029 1030 1031 1032 | ** column. */ memset(&sNC, 0, sizeof(sNC)); sNC.pSrcList = pSelect->pSrc; zType = sqliteStrDup(columnType(&sNC, p)); pCol->zType = zType; pCol->affinity = sqlite3ExprAffinity(p); | | | | | 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 | ** column. */ memset(&sNC, 0, sizeof(sNC)); sNC.pSrcList = pSelect->pSrc; zType = sqliteStrDup(columnType(&sNC, p)); pCol->zType = zType; pCol->affinity = sqlite3ExprAffinity(p); pColl = sqlite3ExprCollSeq(pParse, p); if( pColl ){ pCol->zColl = sqlite3StrDup(pColl->zName); } } pTab->iPKey = -1; return pTab; } /* |
︙ | ︙ | |||
2274 2275 2276 2277 2278 2279 2280 | */ if( iCol<0 ){ pIdx = 0; }else{ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ assert( pIdx->nColumn>=1 ); | | > > > | 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 | */ if( iCol<0 ){ pIdx = 0; }else{ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ assert( pIdx->nColumn>=1 ); if( pIdx->aiColumn[0]==iCol && 0==sqlite3StrICmp(pIdx->azColl[0], pColl->zName) ){ break; } } if( pIdx==0 ) return 0; } /* Identify column types if we will be using the callback. This ** step is skipped if the output is going to a table or a memory cell. ** The column names have already been generated in the calling function. |
︙ | ︙ | |||
2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 | /* Even though the cursor used to open the index here is closed ** as soon as a single value has been read from it, allocate it ** using (pParse->nTab++) to prevent the cursor id from being ** reused. This is important for statements of the form ** "INSERT INTO x SELECT max() FROM x". */ int iIdx; iIdx = pParse->nTab++; assert( pIdx->pSchema==pTab->pSchema ); sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); | > | | | 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 | /* Even though the cursor used to open the index here is closed ** as soon as a single value has been read from it, allocate it ** using (pParse->nTab++) to prevent the cursor id from being ** reused. This is important for statements of the form ** "INSERT INTO x SELECT max() FROM x". */ int iIdx; KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); iIdx = pParse->nTab++; assert( pIdx->pSchema==pTab->pSchema ); sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF); if( seekOp==OP_Rewind ){ sqlite3VdbeAddOp(v, OP_Null, 0, 0); sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0); seekOp = OP_MoveGt; } sqlite3VdbeAddOp(v, seekOp, iIdx, 0); sqlite3VdbeAddOp(v, OP_IdxRowid, iIdx, 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.460 2006/01/10 17:58:23 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Extra interface definitions for those who need them */ |
︙ | ︙ | |||
580 581 582 583 584 585 586 | ** information about each column of an SQL table is held in an instance ** of this structure. */ struct Column { char *zName; /* Name of this column */ Expr *pDflt; /* Default value of this column */ char *zType; /* Data type for this column */ | | | | 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 | ** information about each column of an SQL table is held in an instance ** of this structure. */ struct Column { char *zName; /* Name of this column */ Expr *pDflt; /* Default value of this column */ char *zType; /* Data type for this column */ char *zColl; /* Collating sequence. If NULL, use the default */ u8 notNull; /* True if there is a NOT NULL constraint */ u8 isPrimKey; /* True if this column is part of the PRIMARY KEY */ char affinity; /* One of the SQLITE_AFF_... values */ }; /* ** A "Collating Sequence" is defined by an instance of the following ** structure. Conceptually, a collating sequence consists of a name and ** a comparison routine that defines the order of that sequence. ** ** There may two seperate implementations of the collation function, one ** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that ** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine ** native byte order. When a collation sequence is invoked, SQLite selects ** the version that will require the least expensive encoding ** translations, if any. ** ** The CollSeq.pUser member variable is an extra parameter that passed in ** as the first argument to the UTF-8 comparison function, xCmp. ** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function, ** xCmp16. ** ** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the |
︙ | ︙ | |||
841 842 843 844 845 846 847 | int nColumn; /* Number of columns in the table used by this index */ int *aiColumn; /* Which columns are used by this index. 1st is 0 */ unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */ Table *pTable; /* The SQL table being indexed */ int tnum; /* Page containing root of this index in database file */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */ | < | > | | 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 | int nColumn; /* Number of columns in the table used by this index */ int *aiColumn; /* Which columns are used by this index. 1st is 0 */ unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */ Table *pTable; /* The SQL table being indexed */ int tnum; /* Page containing root of this index in database file */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */ char *zColAff; /* String defining the affinity of each column */ Index *pNext; /* The next index associated with the same table */ Schema *pSchema; /* Schema containing this index */ u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */ char **azColl; /* Array of collation sequence names for index */ }; /* ** Each token coming out of the lexer is an instance of ** this structure. Tokens are also used as part of an expression. ** ** Note if Token.z==0 then Token.dyn and Token.n are undefined and |
︙ | ︙ | |||
1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 | int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); ThreadData *sqlite3ThreadData(); void sqlite3AttachFunctions(sqlite3 *); void sqlite3MinimumFileFormat(Parse*, int, int); void sqlite3SchemaFree(void *); Schema *sqlite3SchemaGet(Btree *); int sqlite3SchemaToIndex(sqlite3 *db, Schema *); #ifndef SQLITE_OMIT_SHARED_CACHE void sqlite3TableLock(Parse *, int, int, u8, const char *); #else #define sqlite3TableLock(v,w,x,y,z) #endif | > | 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 | int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); ThreadData *sqlite3ThreadData(); void sqlite3AttachFunctions(sqlite3 *); void sqlite3MinimumFileFormat(Parse*, int, int); void sqlite3SchemaFree(void *); Schema *sqlite3SchemaGet(Btree *); int sqlite3SchemaToIndex(sqlite3 *db, Schema *); KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *); #ifndef SQLITE_OMIT_SHARED_CACHE void sqlite3TableLock(Parse *, int, int, u8, const char *); #else #define sqlite3TableLock(v,w,x,y,z) #endif |
︙ | ︙ |
Changes to src/update.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** ** $Id: update.c,v 1.119 2006/01/10 17:58:23 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The most recently coded instruction was an OP_Column to retrieve the ** i-th column of table pTab. This routine sets the P3 parameter of the ** OP_Column to the default value, if any. |
︙ | ︙ | |||
229 230 231 232 233 234 235 | i = 0; }else{ for(i=0; i<pIdx->nColumn; i++){ if( aXRef[pIdx->aiColumn[i]]>=0 ) break; } } if( i<pIdx->nColumn ){ | < | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | i = 0; }else{ for(i=0; i<pIdx->nColumn; i++){ if( aXRef[pIdx->aiColumn[i]]>=0 ) break; } } if( i<pIdx->nColumn ){ apIdx[nIdx++] = pIdx; aIdxUsed[j] = 1; }else{ aIdxUsed[j] = 0; } } |
︙ | ︙ | |||
374 375 376 377 378 379 380 381 382 | openAll = 1; break; } } } for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ if( openAll || aIdxUsed[i] ){ sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); sqlite3VdbeOp3(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, | > | | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 | openAll = 1; break; } } } for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ if( openAll || aIdxUsed[i] ){ KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); sqlite3VdbeOp3(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF); assert( pParse->nTab>iCur+i+1 ); } } /* Loop over every record that needs updating. We have to load ** the old data for each record to be updated because some columns ** might not change and we will need to copy the old value. |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
575 576 577 578 579 580 581 | return -1; } assert( pMem1->enc==pMem2->enc ); assert( pMem1->enc==SQLITE_UTF8 || pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE ); | | | | | 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 | return -1; } assert( pMem1->enc==pMem2->enc ); assert( pMem1->enc==SQLITE_UTF8 || pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE ); /* The collation sequence must be defined at this point, even if ** the user deletes the collation sequence after the vdbe program is ** compiled (this was not always the case). */ assert( !pColl || pColl->xCmp ); if( pColl ){ if( pMem1->enc==pColl->enc ){ return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); }else{ |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.193 2006/01/10 17:58:23 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
446 447 448 449 450 451 452 | } if( !pColl ){ pColl = pParse->db->pDfltColl; } } for(k=0; k<pIdx->nColumn && pIdx->aiColumn[k]!=iColumn; k++){} assert( k<pIdx->nColumn ); | | | 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | } if( !pColl ){ pColl = pParse->db->pDfltColl; } } for(k=0; k<pIdx->nColumn && pIdx->aiColumn[k]!=iColumn; k++){} assert( k<pIdx->nColumn ); if( sqlite3StrICmp(pColl->zName, pIdx->azColl[k]) ) continue; } return pTerm; } } return 0; } |
︙ | ︙ | |||
806 807 808 809 810 811 812 | if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){ /* Can not use an index sort on anything that is not a column in the ** left-most table of the FROM clause */ return 0; } pColl = sqlite3ExprCollSeq(pParse, pExpr); if( !pColl ) pColl = db->pDfltColl; | | > | | | | 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 | if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){ /* Can not use an index sort on anything that is not a column in the ** left-most table of the FROM clause */ return 0; } pColl = sqlite3ExprCollSeq(pParse, pExpr); if( !pColl ) pColl = db->pDfltColl; if( pExpr->iColumn!=pIdx->aiColumn[i] || sqlite3StrICmp(pColl->zName, pIdx->azColl[i]) ){ /* Term j of the ORDER BY clause does not match column i of the index */ if( i<nEqCol ){ /* If an index column that is constrained by == fails to match an ** ORDER BY term, that is OK. Just ignore that column of the index */ continue; }else{ /* If an index column fails to match and is not constrained by == ** then the index cannot satisfy the ORDER BY constraint. */ return 0; } } assert( pIdx->aSortOrder!=0 ); assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 ); assert( pIdx->aSortOrder[i]==0 || pIdx->aSortOrder[i]==1 ); termSortOrder = pIdx->aSortOrder[i] ^ pTerm->sortOrder; if( i>nEqCol ){ if( termSortOrder!=sortOrder ){ /* Indices can only be used if all ORDER BY terms past the ** equality constraints are all either DESC or ASC. */ return 0; } }else{ |
︙ | ︙ | |||
1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 | if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){ sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, OP_OpenRead); }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); } pLevel->iTabCur = pTabItem->iCursor; if( (pIx = pLevel->pIdx)!=0 ){ assert( pIx->pSchema==pTab->pSchema ); sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); VdbeComment((v, "# %s", pIx->zName)); sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum, | > | | 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 | if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){ sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, OP_OpenRead); }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); } pLevel->iTabCur = pTabItem->iCursor; if( (pIx = pLevel->pIdx)!=0 ){ KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx); assert( pIx->pSchema==pTab->pSchema ); sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); VdbeComment((v, "# %s", pIx->zName)); sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF); } if( (pLevel->flags & WHERE_IDX_ONLY)!=0 ){ sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1); } sqlite3CodeVerifySchema(pParse, iDb); } pWInfo->iTop = sqlite3VdbeCurrentAddr(v); |
︙ | ︙ | |||
1743 1744 1745 1746 1747 1748 1749 | /* Figure out what comparison operators to use for top and bottom ** search bounds. For an ascending index, the bottom bound is a > or >= ** operator and the top bound is a < or <= operator. For a descending ** index the operators are reversed. */ nNotNull = nEq + topLimit; | | | 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 | /* Figure out what comparison operators to use for top and bottom ** search bounds. For an ascending index, the bottom bound is a > or >= ** operator and the top bound is a < or <= operator. For a descending ** index the operators are reversed. */ nNotNull = nEq + topLimit; if( pIdx->aSortOrder[nEq]==SQLITE_SO_ASC ){ topOp = WO_LT|WO_LE; btmOp = WO_GT|WO_GE; }else{ topOp = WO_GT|WO_GE; btmOp = WO_LT|WO_LE; SWAP(int, topLimit, btmLimit); } |
︙ | ︙ |