-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
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
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
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
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
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
-bdd35e9fbb651fe7a1ed5042923c9529c3c5ab7c
\ No newline at end of file
+0f0213be4d064b3d24e31ff93ec16f6862003d26
\ No newline at end of file
*************************************************************************
** 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"
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;
** 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>
sqliteFree(pCol->zName);
sqlite3ExprDelete(pCol->pDflt);
sqliteFree(pCol->zType);
+ sqliteFree(pCol->zColl);
}
sqliteFree(pTable->aCol);
}
** be called next to set pCol->affinity correctly.
*/
pCol->affinity = SQLITE_AFF_NONE;
- pCol->pColl = pParse->db->pDfltColl;
p->nCol++;
}
*/
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;
}
/*
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 ){
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
}
#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);
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);
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;
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;
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;
}
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 ){
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 ){
** 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;
}
** 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);
** 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 */
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);
}
}
}
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;
}
}
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;
+}
+
** 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"
pParse->nErr++;
return SQLITE_ERROR;
}
+ assert( p==pColl );
}
return SQLITE_OK;
}
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;
** 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"
** 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);
** 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>
}
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;
/* 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 */
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;
}
** 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"
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);
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;
*************************************************************************
** 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"
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++;
}
** 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"
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) ){
** 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"
char *zType;
char *zName;
char *zBasename;
+ CollSeq *pColl;
int cnt;
NameContext sNC;
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;
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;
}
** "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);
*************************************************************************
** 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_
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 */
** 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.
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 */
};
/*
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 *);
** 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"
}
}
if( i<pIdx->nColumn ){
- if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto update_cleanup;
apIdx[nIdx++] = pIdx;
aIdxUsed[j] = 1;
}else{
}
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 );
}
}
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 );
** 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"
}
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;
}
}
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
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
}
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);
** 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{