Store collation sequence names instead of pointers in sharable schema data structures. (CVS 2904)

FossilOrigin-Name: 0f0213be4d064b3d24e31ff93ec16f6862003d26
This commit is contained in:
danielk1977 2006-01-10 17:58:23 +00:00
parent d2d4a6b00d
commit b3bf556ef6
15 changed files with 196 additions and 143 deletions

View File

@ -1,5 +1,5 @@
C Updates\sto\sthe\sC-API\sdocumentation.\s\sChange\sthe\sparameter\stype\sof\nsqlite3_soft_heap_limit\sto\sinteger.\s(CVS\s2903)
D 2006-01-10T15:18:28
C Store\scollation\ssequence\snames\sinstead\sof\spointers\sin\ssharable\sschema\sdata\sstructures.\s(CVS\s2904)
D 2006-01-10T17:58:23
F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@ -31,22 +31,22 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.def c413e514217736884254739a105c8c942fdf0c2f
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
F src/alter.c d0dd079b9ef0d551ff4a4ce09ee270c07b307bbb
F src/analyze.c ed87abad3f6f60e1bd5308ed6ff6e0fa396db52b
F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a
F src/attach.c 8438a2808f89c01cfd472e676a27d771ac4405aa
F src/auth.c cdec356a5cd8b217c346f816c5912221537fe87f
F src/btree.c 874eaba6dec1660c7c917d5afc790f69de82cf2e
F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
F src/build.c 97997d435acfb9406f776f14931c16559bd534e5
F src/callback.c 1c2b78a210fda18cdd4d0b604ed41bf0e1f5125c
F src/build.c 59c4a6fc0e89590c7eec3154acb4cf6644674d7d
F src/callback.c 51fe813309f7cf69d3d19a2e7be2103130186efd
F src/complete.c df1681cef40dec33a286006981845f87b194e7a4
F src/date.c a927bdbb51296ac398d2f667086a7072c099e5ab
F src/delete.c 66199ba71a0f753033073b080baebb349157c960
F src/delete.c b242a0d9462d2b7054e38c5250bdbe94d6772a8e
F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
F src/expr.c 426717b11cf55cb538ccd3db8a3b22a0f956ce8d
F src/expr.c b90fa835a2216edd6808b4bb5da6bbf3b8ee29b9
F src/func.c e013c3b6c607c6a1654f5260eab59f5609a5ce4a
F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
F src/insert.c 16610475976dc9b25d231338e283dd4b4362a430
F src/insert.c 337785137430a012ff0f1c181d4a4d55d2a942d3
F src/legacy.c f651ccd3700f99fa05766ac53506bf9a0694761b
F src/main.c 3fe4b606db7d269d7a57c7b51ab3d9ff488e4b98
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
@ -62,15 +62,15 @@ F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c f84488fa616f1279761aaf06b0acc42af345d3a5
F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f
F src/parse.y 83df51fea35f68f7e07384d75dce83d1ed30434c
F src/pragma.c 05abacaa5a1817a44876d9dbb4790aa7c784427b
F src/prepare.c 41d9a8563e2b988932922c9f96a7bb1271932564
F src/pragma.c 711992e440ce78569322dd625d2cfe1cd696ccfb
F src/prepare.c 3283bb65b4b217a092c9cbf65014774e6c3a142d
F src/printf.c f47a2f4b5387cd2ebb12e9117a1a5d6bd9a2b812
F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
F src/select.c acfeda959fe07eac04950d945ac7ec0518ef4b7d
F src/select.c 579cfdd250c5598de7c867134f7d35a2099b1dcc
F src/server.c 42a2bd02eec5018098a96e08f7a923f4965a2b1d
F src/shell.c 66b073375efbdee19045e7e0cd38b85f9aff71da
F src/sqlite.h.in 821b93f918d126c54d9a91fc928434945655edc3
F src/sqliteInt.h f3fe5c8b7d3a7491d6f47f0605b7ed70f146c59f
F src/sqliteInt.h d7584dc5b8e15f1732a195ece9e93049ccde35fa
F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
F src/tclsqlite.c d650bea0248fc0a310ddc2cb94273a3a5021fddf
F src/test1.c 5f634ce9aa452dbcc362993c9612047df800216c
@ -83,7 +83,7 @@ F src/test7.c bfe36c62cae189509660acfeeb891ffb9da8ef0c
F src/test_async.c 9733deb7fefa18a3596e5234c1ef05b4685c6ad7
F src/tokenize.c 196486012c871cdcad6cc84a820cc988603f1b9d
F src/trigger.c 883b5f3b97137fbe417e3337c3fa20ac8e9c1ae5
F src/update.c e09da54cb8e042f89f4177f4ef879b594d8ab946
F src/update.c cd8ad5bb1a29f2056347481308fca4a59f2f4764
F src/utf.c b7bffac4260177ae7f83c01d025fe0f5ed70ce71
F src/util.c 5d5792d4a4dda20d70fdfb973ed8a5ed71fea98c
F src/vacuum.c f5a068096b22fad438bf1f1cf69ccb7f9e8cc7fb
@ -93,8 +93,8 @@ F src/vdbeInt.h 5451cf71f229e366ac543607c0a17f36e5737ea9
F src/vdbeapi.c 6d20e92de62b90ae27aeea3a7b18653734b0b1cb
F src/vdbeaux.c e4b8f492e41e3b8ecee8f66045e897dae92d1356
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
F src/vdbemem.c d712dfd80d58011db688fa8234c1821262a57cae
F src/where.c 18a7a16a5b050b2df6f8b03945313ec0f46dc30c
F src/vdbemem.c 2ada7cae76da9c840cd0d3c01d2b3987d97141c6
F src/where.c 4fecfccf8f35ec7b325d666f0cd2fb016a53da43
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
F test/all.test 90cf64bb655e3d474b0dda04e63ece03e36b0ce2
F test/alter.test b94b640063e725d062b2997bd2810ac39195c718
@ -340,7 +340,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
P 4f2ec95283f1ae0a28b2f9ce0afc5a7203de87fb
R 6f27b31eddededb37a4ce53e31f18e64
U drh
Z abf90018e50b865b136d9f985b2b2657
P bdd35e9fbb651fe7a1ed5042923c9529c3c5ab7c
R 86f043f12b95a158f3793bd5117e0f9d
U danielk1977
Z 598f1f083965de59648a9c0d25b3df80

View File

@ -1 +1 @@
bdd35e9fbb651fe7a1ed5042923c9529c3c5ab7c
0f0213be4d064b3d24e31ff93ec16f6862003d26

View File

@ -11,7 +11,7 @@
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
** @(#) $Id: analyze.c,v 1.15 2006/01/09 06:29:48 danielk1977 Exp $
** @(#) $Id: analyze.c,v 1.16 2006/01/10 17:58:23 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"
@ -114,13 +114,15 @@ static void analyzeOneTable(
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*)&pIdx->keyInfo, P3_KEYINFO);
(char *)pKey, P3_KEYINFO_HANDOFF);
nCol = pIdx->nColumn;
if( iMem+nCol*2>=pParse->nMem ){
pParse->nMem = iMem+nCol*2+1;

View File

@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
** $Id: build.c,v 1.374 2006/01/10 07:14:23 danielk1977 Exp $
** $Id: build.c,v 1.375 2006/01/10 17:58:23 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@ -468,6 +468,7 @@ static void sqliteResetColumnNames(Table *pTable){
sqliteFree(pCol->zName);
sqlite3ExprDelete(pCol->pDflt);
sqliteFree(pCol->zType);
sqliteFree(pCol->zColl);
}
sqliteFree(pTable->aCol);
}
@ -938,7 +939,6 @@ void sqlite3AddColumn(Parse *pParse, Token *pName){
** be called next to set pCol->affinity correctly.
*/
pCol->affinity = SQLITE_AFF_NONE;
pCol->pColl = pParse->db->pDfltColl;
p->nCol++;
}
@ -1167,41 +1167,26 @@ void sqlite3AddCheckConstraint(
*/
void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){
Table *p;
Index *pIdx;
CollSeq *pColl;
int i;
if( (p = pParse->pNewTable)==0 ) return;
i = p->nCol-1;
pColl = sqlite3LocateCollSeq(pParse, zType, nType);
p->aCol[i].pColl = pColl;
/* 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->keyInfo.aColl[0] = pColl;
}
}
/*
** Call sqlite3CheckCollSeq() for all collating sequences in an index,
** in order to verify that all the necessary collating sequences are
** loaded.
*/
int sqlite3CheckIndexCollSeq(Parse *pParse, Index *pIdx){
if( pIdx ){
int i;
for(i=0; i<pIdx->nColumn; i++){
if( sqlite3CheckCollSeq(pParse, pIdx->keyInfo.aColl[i]) ){
return SQLITE_ERROR;
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;
}
}
}
return SQLITE_OK;
}
/*
@ -1222,8 +1207,9 @@ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){
sqlite3 *db = pParse->db;
u8 enc = ENC(db);
u8 initbusy = db->init.busy;
CollSeq *pColl;
CollSeq *pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy);
pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy);
if( !initbusy && (!pColl || !pColl->xCmp) ){
pColl = sqlite3GetCollSeq(db, pColl, zName, nName);
if( !pColl ){
@ -2131,6 +2117,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
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
@ -2140,14 +2127,6 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
}
#endif
/* Ensure all the required collation sequences are available. This
** routine will invoke the collation-needed callback if necessary (and
** if one has been registered).
*/
if( sqlite3CheckIndexCollSeq(pParse, pIndex) ){
return;
}
/* Require a write-lock on the table to perform this operation */
sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
@ -2161,8 +2140,8 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
sqlite3VdbeAddOp(v, OP_Clear, tnum, iDb);
}
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum,
(char*)&pIndex->keyInfo, P3_KEYINFO);
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);
@ -2221,6 +2200,9 @@ void sqlite3CreateIndex(
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;
@ -2352,17 +2334,37 @@ void sqlite3CreateIndex(
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);
pIndex = sqliteMalloc( sizeof(Index) + nName + 2 + sizeof(int) +
(sizeof(int)*2 + sizeof(CollSeq*) + 1)*pList->nExpr );
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->keyInfo.aColl[pList->nExpr];
pIndex->aiRowEst = (unsigned*)&pIndex->aiColumn[pList->nExpr];
pIndex->zName = (char*)&pIndex->aiRowEst[pList->nExpr+1];
pIndex->keyInfo.aSortOrder = &pIndex->zName[nName+1];
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;
@ -2386,6 +2388,8 @@ void sqlite3CreateIndex(
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;
}
@ -2397,20 +2401,22 @@ void sqlite3CreateIndex(
pIndex->aiColumn[i] = j;
if( pListItem->pExpr ){
assert( pListItem->pExpr->pColl );
pIndex->keyInfo.aColl[i] = pListItem->pExpr->pColl;
zColl = zExtra;
strcpy(zExtra, pListItem->pExpr->pColl->zName);
zExtra += (strlen(zColl) + 1);
}else{
pIndex->keyInfo.aColl[i] = pTab->aCol[j].pColl;
zColl = pTab->aCol[j].zColl;
if( !zColl ){
zColl = db->pDfltColl->zName;
}
}
assert( pIndex->keyInfo.aColl[i] );
if( !db->init.busy &&
sqlite3CheckCollSeq(pParse, pIndex->keyInfo.aColl[i])
){
if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl, -1) ){
goto exit_create_index;
}
pIndex->azColl[i] = zColl;
requestedSortOrder = pListItem->sortOrder & sortOrderMask;
pIndex->keyInfo.aSortOrder[i] = requestedSortOrder;
pIndex->aSortOrder[i] = requestedSortOrder;
}
pIndex->keyInfo.nField = pList->nExpr;
sqlite3DefaultRowEst(pIndex);
if( pTab==pParse->pNewTable ){
@ -2436,9 +2442,11 @@ void sqlite3CreateIndex(
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->keyInfo.aColl[k]!=pIndex->keyInfo.aColl[k] ) break;
if( pIdx->keyInfo.aSortOrder[k]!=pIndex->keyInfo.aSortOrder[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 ){
@ -3054,12 +3062,13 @@ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
** true if it does and false if it does not.
*/
#ifndef SQLITE_OMIT_REINDEX
static int collationMatch(CollSeq *pColl, Index *pIndex){
int n = pIndex->keyInfo.nField;
CollSeq **pp = pIndex->keyInfo.aColl;
while( n-- ){
if( *pp==pColl ) return 1;
pp++;
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;
}
@ -3070,11 +3079,11 @@ static int collationMatch(CollSeq *pColl, Index *pIndex){
** If pColl==0 then recompute all indices of pTab.
*/
#ifndef SQLITE_OMIT_REINDEX
static void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){
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( pColl==0 || collationMatch(pColl,pIndex) ){
if( zColl==0 || collationMatch(zColl, pIndex) ){
int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
sqlite3BeginWriteOperation(pParse, 0, iDb);
sqlite3RefillIndex(pParse, pIndex, -1);
@ -3089,7 +3098,7 @@ static void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){
** all indices everywhere.
*/
#ifndef SQLITE_OMIT_REINDEX
static void reindexDatabases(Parse *pParse, CollSeq *pColl){
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 */
@ -3100,7 +3109,7 @@ static void reindexDatabases(Parse *pParse, CollSeq *pColl){
if( pDb==0 ) continue;
for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){
pTab = (Table*)sqliteHashData(k);
reindexTable(pParse, pTab, pColl);
reindexTable(pParse, pTab, zColl);
}
}
}
@ -3140,9 +3149,14 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
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 ){
reindexDatabases(pParse, pColl);
char *z = sqlite3StrNDup(pName1->z, pName1->n);
if( z ){
reindexDatabases(pParse, z);
sqliteFree(z);
}
return;
}
}
@ -3166,3 +3180,39 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
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;
}

View File

@ -13,7 +13,7 @@
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
** $Id: callback.c,v 1.9 2006/01/09 16:12:05 danielk1977 Exp $
** $Id: callback.c,v 1.10 2006/01/10 17:58:23 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -130,6 +130,7 @@ int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
pParse->nErr++;
return SQLITE_ERROR;
}
assert( p==pColl );
}
return SQLITE_OK;
}
@ -199,7 +200,12 @@ CollSeq *sqlite3FindCollSeq(
int nName,
int create
){
CollSeq *pColl = findCollSeqEntry(db, zName, nName, 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;

View File

@ -12,7 +12,7 @@
** 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.116 2006/01/09 06:29:48 danielk1977 Exp $
** $Id: delete.c,v 1.117 2006/01/10 17:58:23 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -236,13 +236,6 @@ void sqlite3DeleteFrom(
** the table and pick which records to delete.
*/
else{
/* Ensure all required collation sequences are available. */
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){
goto delete_from_cleanup;
}
}
/* Begin the database scan
*/
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);

View File

@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.246 2006/01/09 16:12:05 danielk1977 Exp $
** $Id: expr.c,v 1.247 2006/01/10 17:58:23 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@ -867,6 +867,7 @@ static int lookupName(
}
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;
@ -875,7 +876,7 @@ static int lookupName(
/* 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 = pTab->aCol[j].pColl;
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 */
@ -926,10 +927,11 @@ static int lookupName(
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 = pTab->aCol[j].pColl;
pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
pExpr->pTab = pTab;
break;
}

View File

@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.155 2006/01/09 06:29:48 danielk1977 Exp $
** $Id: insert.c,v 1.156 2006/01/10 17:58:23 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -275,13 +275,6 @@ void sqlite3Insert(
goto insert_cleanup;
}
/* Ensure all required collation sequences are available. */
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){
goto insert_cleanup;
}
}
/* Allocate a VDBE
*/
v = sqlite3GetVdbe(pParse);
@ -1108,11 +1101,11 @@ void sqlite3OpenTableAndIndices(
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*)&pIdx->keyInfo, P3_KEYINFO);
sqlite3VdbeOp3(v, op, i+base, pIdx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF);
}
if( pParse->nTab<=base+i ){
pParse->nTab = base+i;

View File

@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.111 2006/01/09 16:12:05 danielk1977 Exp $
** $Id: pragma.c,v 1.112 2006/01/10 17:58:23 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -670,7 +670,6 @@ void sqlite3Pragma(
sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0);
cnt++;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto pragma_out;
sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0);
cnt++;
}

View File

@ -13,7 +13,7 @@
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.17 2006/01/09 16:12:05 danielk1977 Exp $
** $Id: prepare.c,v 1.18 2006/01/10 17:58:23 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -262,7 +262,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
if( iDb==0 ){
/* If opening the main database, set ENC(db). */
ENC(db) = (u8)meta[4];
db->pDfltColl = sqlite3FindCollSeq(db, ENC(db), "BINARY", 6, 0);
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) ){

View File

@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.291 2006/01/09 16:12:05 danielk1977 Exp $
** $Id: select.c,v 1.292 2006/01/10 17:58:23 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -978,6 +978,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
char *zType;
char *zName;
char *zBasename;
CollSeq *pColl;
int cnt;
NameContext sNC;
@ -1030,9 +1031,9 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
zType = sqliteStrDup(columnType(&sNC, p));
pCol->zType = zType;
pCol->affinity = sqlite3ExprAffinity(p);
pCol->pColl = sqlite3ExprCollSeq(pParse, p);
if( !pCol->pColl ){
pCol->pColl = pParse->db->pDfltColl;
pColl = sqlite3ExprCollSeq(pParse, p);
if( pColl ){
pCol->zColl = sqlite3StrDup(pColl->zName);
}
}
pTab->iPKey = -1;
@ -2278,7 +2279,10 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
assert( pIdx->nColumn>=1 );
if( pIdx->aiColumn[0]==iCol && pIdx->keyInfo.aColl[0]==pColl ) break;
if( pIdx->aiColumn[0]==iCol &&
0==sqlite3StrICmp(pIdx->azColl[0], pColl->zName) ){
break;
}
}
if( pIdx==0 ) return 0;
}
@ -2321,11 +2325,12 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
** "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*)&pIdx->keyInfo, P3_KEYINFO);
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);

View File

@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.459 2006/01/10 15:18:28 drh Exp $
** @(#) $Id: sqliteInt.h,v 1.460 2006/01/10 17:58:23 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@ -584,7 +584,7 @@ struct Column {
char *zName; /* Name of this column */
Expr *pDflt; /* Default value of this column */
char *zType; /* Data type for this column */
CollSeq *pColl; /* Collating sequence. If NULL, use the default */
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 */
@ -600,7 +600,7 @@ struct Column {
** 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
** transalations, if any.
** 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.
@ -845,11 +845,11 @@ struct Index {
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) */
// u8 iDb; /* Index in sqlite.aDb[] of where this index is stored */
char *zColAff; /* String defining the affinity of each column */
Index *pNext; /* The next index associated with the same table */
Schema *pSchema;
KeyInfo keyInfo; /* Info on how to order keys. MUST BE LAST */
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 */
};
/*
@ -1736,6 +1736,7 @@ 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 *);

View File

@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.118 2006/01/09 16:12:05 danielk1977 Exp $
** $Id: update.c,v 1.119 2006/01/10 17:58:23 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -233,7 +233,6 @@ void sqlite3Update(
}
}
if( i<pIdx->nColumn ){
if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto update_cleanup;
apIdx[nIdx++] = pIdx;
aIdxUsed[j] = 1;
}else{
@ -378,9 +377,10 @@ void sqlite3Update(
}
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*)&pIdx->keyInfo, P3_KEYINFO);
(char*)pKey, P3_KEYINFO_HANDOFF);
assert( pParse->nTab>iCur+i+1 );
}
}

View File

@ -579,9 +579,9 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
assert( pMem1->enc==SQLITE_UTF8 ||
pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
/* This assert may fail if the collation sequence is deleted after this
** vdbe program is compiled. The documentation defines this as an
** undefined condition. A crash is usual result.
/* 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 );

View File

@ -16,7 +16,7 @@
** 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.192 2006/01/09 06:29:49 danielk1977 Exp $
** $Id: where.c,v 1.193 2006/01/10 17:58:23 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -450,7 +450,7 @@ static WhereTerm *findTerm(
}
for(k=0; k<pIdx->nColumn && pIdx->aiColumn[k]!=iColumn; k++){}
assert( k<pIdx->nColumn );
if( pColl!=pIdx->keyInfo.aColl[k] ) continue;
if( sqlite3StrICmp(pColl->zName, pIdx->azColl[k]) ) continue;
}
return pTerm;
}
@ -810,7 +810,8 @@ static int isSortingIndex(
}
pColl = sqlite3ExprCollSeq(pParse, pExpr);
if( !pColl ) pColl = db->pDfltColl;
if( pExpr->iColumn!=pIdx->aiColumn[i] || pColl!=pIdx->keyInfo.aColl[i] ){
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
@ -824,10 +825,10 @@ static int isSortingIndex(
return 0;
}
}
assert( pIdx->keyInfo.aSortOrder!=0 );
assert( pIdx->aSortOrder!=0 );
assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );
assert( pIdx->keyInfo.aSortOrder[i]==0 || pIdx->keyInfo.aSortOrder[i]==1 );
termSortOrder = pIdx->keyInfo.aSortOrder[i] ^ pTerm->sortOrder;
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
@ -1586,11 +1587,12 @@ WhereInfo *sqlite3WhereBegin(
}
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*)&pIx->keyInfo, P3_KEYINFO);
(char*)pKey, P3_KEYINFO_HANDOFF);
}
if( (pLevel->flags & WHERE_IDX_ONLY)!=0 ){
sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
@ -1747,7 +1749,7 @@ WhereInfo *sqlite3WhereBegin(
** index the operators are reversed.
*/
nNotNull = nEq + topLimit;
if( pIdx->keyInfo.aSortOrder[nEq]==SQLITE_SO_ASC ){
if( pIdx->aSortOrder[nEq]==SQLITE_SO_ASC ){
topOp = WO_LT|WO_LE;
btmOp = WO_GT|WO_GE;
}else{