mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-08 03:22:21 +03:00
Initial infrastructure for recognizing DESC indices and being able to read
and write older databases that specify DESC indices but do not really use them. Nothing is close to working yet. (CVS 2822) FossilOrigin-Name: cd110aa225b09591064405dd8952b3df37278c52
This commit is contained in:
24
manifest
24
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Fix\sthe\sutf8\sto\sutf16\sconversion\sroutine\sfor\sshort\sstrings.\s\sBug\nintroduced\sby\scheck-in\s(2817).\s(CVS\s2821)
|
C Initial\sinfrastructure\sfor\srecognizing\sDESC\sindices\sand\sbeing\sable\sto\sread\r\nand\swrite\solder\sdatabases\sthat\sspecify\sDESC\sindices\sbut\sdo\snot\sreally\suse\r\nthem.\s\sNothing\sis\sclose\sto\sworking\syet.\s(CVS\s2822)
|
||||||
D 2005-12-15T22:34:01
|
D 2005-12-16T01:06:17
|
||||||
F Makefile.in e3c6b3a38d734d41574c04f2fc90d18de2b87102
|
F Makefile.in e3c6b3a38d734d41574c04f2fc90d18de2b87102
|
||||||
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
|
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -30,13 +30,13 @@ F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
|
|||||||
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
||||||
F sqlite3.def c413e514217736884254739a105c8c942fdf0c2f
|
F sqlite3.def c413e514217736884254739a105c8c942fdf0c2f
|
||||||
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
|
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
|
||||||
F src/alter.c 26e590618fe6a316c74626dbea6529c7315172e9
|
F src/alter.c 7bc737c689044fa00ff2f445139c61f5c9ee0ad8
|
||||||
F src/analyze.c ea42005eed52c382fcc7ef66969e7f1858597633
|
F src/analyze.c ea42005eed52c382fcc7ef66969e7f1858597633
|
||||||
F src/attach.c ee70131f128d31a9c6dcb8824e8471c91b18601a
|
F src/attach.c ee70131f128d31a9c6dcb8824e8471c91b18601a
|
||||||
F src/auth.c 31e2304bef67f44d635655f44234387ea7d21454
|
F src/auth.c 31e2304bef67f44d635655f44234387ea7d21454
|
||||||
F src/btree.c de0fc1a0f6a4631001ffb6070d1b7588cdebcbc5
|
F src/btree.c de0fc1a0f6a4631001ffb6070d1b7588cdebcbc5
|
||||||
F src/btree.h 1ed561263ca0e335bc3e81d761c9d5ff8c22f61e
|
F src/btree.h 1ed561263ca0e335bc3e81d761c9d5ff8c22f61e
|
||||||
F src/build.c 306dde3134acd8f1c9f3821d81c3cb598af91280
|
F src/build.c 178a5c36365b5ec89a4a29a74186583f503c10fa
|
||||||
F src/callback.c 62066afd516f220575e81b1a1239ab92a2eae252
|
F src/callback.c 62066afd516f220575e81b1a1239ab92a2eae252
|
||||||
F src/complete.c df1681cef40dec33a286006981845f87b194e7a4
|
F src/complete.c df1681cef40dec33a286006981845f87b194e7a4
|
||||||
F src/date.c bb079317bff6a2b78aba5c0d2ddae5f6f03acfb7
|
F src/date.c bb079317bff6a2b78aba5c0d2ddae5f6f03acfb7
|
||||||
@@ -61,15 +61,15 @@ F src/os_win.c 9feb97f49b93d451f8ef7c5dd388e05a44647dc6
|
|||||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||||
F src/pager.c 49f63a54b57164a70df0b1539141003fd27856c6
|
F src/pager.c 49f63a54b57164a70df0b1539141003fd27856c6
|
||||||
F src/pager.h e7b41ce8e7b5f629d456708b7ad9a8c8ede37140
|
F src/pager.h e7b41ce8e7b5f629d456708b7ad9a8c8ede37140
|
||||||
F src/parse.y d0b1f9a4d508bf043cdbc7079aa26dff7d358651
|
F src/parse.y 142a4b347c82217332e2d3dfa317ff2b7ac32f9c
|
||||||
F src/pragma.c 8883b4d34796efa315bdd0ec1b03f580ef1575b9
|
F src/pragma.c 8883b4d34796efa315bdd0ec1b03f580ef1575b9
|
||||||
F src/prepare.c ca4d58a46e74412dba1fcfaeeaa89b01e64f1a8b
|
F src/prepare.c 1417a396efe55e2767f9f97f694d21b8cac2f4d6
|
||||||
F src/printf.c f47a2f4b5387cd2ebb12e9117a1a5d6bd9a2b812
|
F src/printf.c f47a2f4b5387cd2ebb12e9117a1a5d6bd9a2b812
|
||||||
F src/random.c ff5e9a8cad790e2a51cd4d2e7737dc8540e09d1d
|
F src/random.c ff5e9a8cad790e2a51cd4d2e7737dc8540e09d1d
|
||||||
F src/select.c 2292b065bc6be61e01aad39a2e1b93e332fb7e57
|
F src/select.c 2292b065bc6be61e01aad39a2e1b93e332fb7e57
|
||||||
F src/shell.c 4872acee1d2a826c73c914961e469e563204b7f9
|
F src/shell.c 4872acee1d2a826c73c914961e469e563204b7f9
|
||||||
F src/sqlite.h.in 31ab5ef5268c7f1ee909151a0fc45c659290ec15
|
F src/sqlite.h.in 31ab5ef5268c7f1ee909151a0fc45c659290ec15
|
||||||
F src/sqliteInt.h 927c7fbc25d105c89aa90dc148c68c0b33051048
|
F src/sqliteInt.h 853a868ee69e841b9eba078f359932cddd3cf264
|
||||||
F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
|
F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
|
||||||
F src/tclsqlite.c c2303e1b1e6602b8cfef4dad00e4d76a47868c5e
|
F src/tclsqlite.c c2303e1b1e6602b8cfef4dad00e4d76a47868c5e
|
||||||
F src/test1.c d6924b182773b2ad3b22e435e4d3bfd5a846da9e
|
F src/test1.c d6924b182773b2ad3b22e435e4d3bfd5a846da9e
|
||||||
@@ -88,7 +88,7 @@ F src/vdbe.c a9acffc91d3e06af24dc1dcf5bf7d5e77460b1c5
|
|||||||
F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
|
F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
|
||||||
F src/vdbeInt.h 7b8b8c5dcb203243e4a9a4414c9e488473f67741
|
F src/vdbeInt.h 7b8b8c5dcb203243e4a9a4414c9e488473f67741
|
||||||
F src/vdbeapi.c b270b680cbc5d20b5a1abfdb08339667985df94e
|
F src/vdbeapi.c b270b680cbc5d20b5a1abfdb08339667985df94e
|
||||||
F src/vdbeaux.c f714ee9e91f1e47d4b6ae83798e0b263ffe224cc
|
F src/vdbeaux.c 722736cd433f06942bc5c7b7915e6561be0b400c
|
||||||
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
||||||
F src/vdbemem.c deba8d6e3727643924b210a8c531a496c2b8d386
|
F src/vdbemem.c deba8d6e3727643924b210a8c531a496c2b8d386
|
||||||
F src/where.c 269569f380ddc018518f67765fe2f0d3c8760e28
|
F src/where.c 269569f380ddc018518f67765fe2f0d3c8760e28
|
||||||
@@ -125,7 +125,7 @@ F test/btree7.test a6d3b842db22af97dd14b989e90a2fd96066b72f
|
|||||||
F test/btree8.test fadc112bcbd6a0c622d34c813fc8a648eacf8804
|
F test/btree8.test fadc112bcbd6a0c622d34c813fc8a648eacf8804
|
||||||
F test/busy.test 0271c854738e23ad76e10d4096a698e5af29d211
|
F test/busy.test 0271c854738e23ad76e10d4096a698e5af29d211
|
||||||
F test/capi2.test f897209386fb21cfdc9267595e0c667ebaca9164
|
F test/capi2.test f897209386fb21cfdc9267595e0c667ebaca9164
|
||||||
F test/capi3.test fc8e573467049add3bfaf81f53827e8ff153cf8f
|
F test/capi3.test af46034e00e225eaef780930204a4f885bd40fa0
|
||||||
F test/capi3b.test 5b6a66f9f295f79f443b5d3f33187fa5ef6cf336
|
F test/capi3b.test 5b6a66f9f295f79f443b5d3f33187fa5ef6cf336
|
||||||
F test/cast.test 2543165ced4249c89ce5f0352222df503a98b9e5
|
F test/cast.test 2543165ced4249c89ce5f0352222df503a98b9e5
|
||||||
F test/check.test 8154b8ac0c56c34088168b8d87eee713fba2b31b
|
F test/check.test 8154b8ac0c56c34088168b8d87eee713fba2b31b
|
||||||
@@ -327,7 +327,7 @@ F www/tclsqlite.tcl ddcf912ea48695603c8ed7efb29f0812ef8d1b49
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
||||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||||
P 36229018817eebfbfca7a66d2285e4faf7b39845
|
P 4fba2db38e0693be52ca7251e4958bd836607f05
|
||||||
R db348b533dcaa66ab84d8527c31842a7
|
R cf0e0e36b0268dddfac27efc891f1d3b
|
||||||
U drh
|
U drh
|
||||||
Z 04cd55b34392e021d53876472bf23ee4
|
Z e31baf15a60fd5885441bd2ca28e4cd9
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
4fba2db38e0693be52ca7251e4958bd836607f05
|
cd110aa225b09591064405dd8952b3df37278c52
|
||||||
29
src/alter.c
29
src/alter.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that used to generate VDBE code
|
** This file contains C code routines that used to generate VDBE code
|
||||||
** that implements the ALTER TABLE command.
|
** that implements the ALTER TABLE command.
|
||||||
**
|
**
|
||||||
** $Id: alter.c,v 1.11 2005/12/09 20:02:05 drh Exp $
|
** $Id: alter.c,v 1.12 2005/12/16 01:06:17 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -462,21 +462,28 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
|
|||||||
** format to 2. If the default value of the new column is not NULL,
|
** format to 2. If the default value of the new column is not NULL,
|
||||||
** the file format becomes 3.
|
** the file format becomes 3.
|
||||||
*/
|
*/
|
||||||
if( (v=sqlite3GetVdbe(pParse))!=0 ){
|
sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);
|
||||||
int f = (pDflt?3:2);
|
|
||||||
|
|
||||||
/* Only set the file format to $f if it is currently less than $f. */
|
|
||||||
sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);
|
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, f, 0);
|
|
||||||
sqlite3VdbeAddOp(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3);
|
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, f, 0);
|
|
||||||
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reload the schema of the modified table. */
|
/* Reload the schema of the modified table. */
|
||||||
reloadTableSchema(pParse, pTab, pTab->zName);
|
reloadTableSchema(pParse, pTab, pTab->zName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Generate code to make sure the file format number is at least minFormat.
|
||||||
|
** The generated code will increase the file format number if necessary.
|
||||||
|
*/
|
||||||
|
void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
|
||||||
|
Vdbe *v;
|
||||||
|
v = sqlite3GetVdbe(pParse);
|
||||||
|
if( v ){
|
||||||
|
sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);
|
||||||
|
sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0);
|
||||||
|
sqlite3VdbeAddOp(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3);
|
||||||
|
sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0);
|
||||||
|
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This function is called by the parser after the table-name in
|
** This function is called by the parser after the table-name in
|
||||||
|
|||||||
88
src/build.c
88
src/build.c
@@ -22,7 +22,7 @@
|
|||||||
** COMMIT
|
** COMMIT
|
||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.357 2005/12/09 20:02:05 drh Exp $
|
** $Id: build.c,v 1.358 2005/12/16 01:06:17 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -764,7 +764,7 @@ void sqlite3StartTable(
|
|||||||
sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); /* file_format */
|
sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); /* file_format */
|
||||||
lbl = sqlite3VdbeMakeLabel(v);
|
lbl = sqlite3VdbeMakeLabel(v);
|
||||||
sqlite3VdbeAddOp(v, OP_If, 0, lbl);
|
sqlite3VdbeAddOp(v, OP_If, 0, lbl);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, db->file_format, 0);
|
sqlite3VdbeAddOp(v, OP_Integer, 1, 0); /* file format defaults to 1 */
|
||||||
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
|
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0);
|
sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
|
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
|
||||||
@@ -1010,7 +1010,8 @@ void sqlite3AddPrimaryKey(
|
|||||||
Parse *pParse, /* Parsing context */
|
Parse *pParse, /* Parsing context */
|
||||||
ExprList *pList, /* List of field names to be indexed */
|
ExprList *pList, /* List of field names to be indexed */
|
||||||
int onError, /* What to do with a uniqueness conflict */
|
int onError, /* What to do with a uniqueness conflict */
|
||||||
int autoInc /* True if the AUTOINCREMENT keyword is present */
|
int autoInc, /* True if the AUTOINCREMENT keyword is present */
|
||||||
|
int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */
|
||||||
){
|
){
|
||||||
Table *pTab = pParse->pNewTable;
|
Table *pTab = pParse->pNewTable;
|
||||||
char *zType = 0;
|
char *zType = 0;
|
||||||
@@ -1041,7 +1042,8 @@ void sqlite3AddPrimaryKey(
|
|||||||
if( iCol>=0 && iCol<pTab->nCol ){
|
if( iCol>=0 && iCol<pTab->nCol ){
|
||||||
zType = pTab->aCol[iCol].zType;
|
zType = pTab->aCol[iCol].zType;
|
||||||
}
|
}
|
||||||
if( zType && sqlite3StrICmp(zType, "INTEGER")==0 ){
|
if( zType && sqlite3StrICmp(zType, "INTEGER")==0
|
||||||
|
&& sortOrder==SQLITE_SO_ASC ){
|
||||||
pTab->iPKey = iCol;
|
pTab->iPKey = iCol;
|
||||||
pTab->keyConf = onError;
|
pTab->keyConf = onError;
|
||||||
pTab->autoInc = autoInc;
|
pTab->autoInc = autoInc;
|
||||||
@@ -1051,7 +1053,7 @@ void sqlite3AddPrimaryKey(
|
|||||||
"INTEGER PRIMARY KEY");
|
"INTEGER PRIMARY KEY");
|
||||||
#endif
|
#endif
|
||||||
}else{
|
}else{
|
||||||
sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0);
|
sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder);
|
||||||
pList = 0;
|
pList = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2094,18 +2096,24 @@ void sqlite3CreateIndex(
|
|||||||
ExprList *pList, /* A list of columns to be indexed */
|
ExprList *pList, /* A list of columns to be indexed */
|
||||||
int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
|
int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
|
||||||
Token *pStart, /* The CREATE token that begins a CREATE TABLE statement */
|
Token *pStart, /* The CREATE token that begins a CREATE TABLE statement */
|
||||||
Token *pEnd /* The ")" that closes the CREATE INDEX statement */
|
Token *pEnd, /* The ")" that closes the CREATE INDEX statement */
|
||||||
|
int sortOrder /* Sort order of primary key when pList==NULL */
|
||||||
){
|
){
|
||||||
Table *pTab = 0; /* Table to be indexed */
|
Table *pTab = 0; /* Table to be indexed */
|
||||||
Index *pIndex = 0; /* The index to be created */
|
Index *pIndex = 0; /* The index to be created */
|
||||||
char *zName = 0;
|
char *zName = 0; /* Name of the index */
|
||||||
|
int nName; /* Number of characters in zName */
|
||||||
int i, j;
|
int i, j;
|
||||||
Token nullId; /* Fake token for an empty ID list */
|
Token nullId; /* Fake token for an empty ID list */
|
||||||
DbFixer sFix; /* For assigning database names to pTable */
|
DbFixer sFix; /* For assigning database names to pTable */
|
||||||
|
int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */
|
||||||
|
int descSeen = 0; /* Changes to true if a DESC is seen */
|
||||||
sqlite3 *db = pParse->db;
|
sqlite3 *db = pParse->db;
|
||||||
|
Db *pDb; /* The specific table containing the indexed database */
|
||||||
int iDb; /* Index of the database that is being written */
|
int iDb; /* Index of the database that is being written */
|
||||||
Token *pName = 0; /* Unqualified name of the index to create */
|
Token *pName = 0; /* Unqualified name of the index to create */
|
||||||
|
struct ExprList_item *pListItem; /* For looping over pList */
|
||||||
|
CollSeq *pCollSeq; /* Collating sequence for one index column */
|
||||||
|
|
||||||
if( pParse->nErr || sqlite3Tsd()->mallocFailed ) goto exit_create_index;
|
if( pParse->nErr || sqlite3Tsd()->mallocFailed ) goto exit_create_index;
|
||||||
|
|
||||||
@@ -2148,6 +2156,7 @@ void sqlite3CreateIndex(
|
|||||||
pTab = pParse->pNewTable;
|
pTab = pParse->pNewTable;
|
||||||
iDb = pTab->iDb;
|
iDb = pTab->iDb;
|
||||||
}
|
}
|
||||||
|
pDb = &db->aDb[iDb];
|
||||||
|
|
||||||
if( pTab==0 || pParse->nErr ) goto exit_create_index;
|
if( pTab==0 || pParse->nErr ) goto exit_create_index;
|
||||||
if( pTab->readOnly ){
|
if( pTab->readOnly ){
|
||||||
@@ -2183,7 +2192,7 @@ void sqlite3CreateIndex(
|
|||||||
}
|
}
|
||||||
if( !db->init.busy ){
|
if( !db->init.busy ){
|
||||||
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
|
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
|
||||||
if( sqlite3FindIndex(db, zName, db->aDb[iDb].zName)!=0 ){
|
if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
|
||||||
sqlite3ErrorMsg(pParse, "index %s already exists", zName);
|
sqlite3ErrorMsg(pParse, "index %s already exists", zName);
|
||||||
goto exit_create_index;
|
goto exit_create_index;
|
||||||
}
|
}
|
||||||
@@ -2207,7 +2216,7 @@ void sqlite3CreateIndex(
|
|||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
{
|
{
|
||||||
const char *zDb = db->aDb[iDb].zName;
|
const char *zDb = pDb->zName;
|
||||||
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
|
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
|
||||||
goto exit_create_index;
|
goto exit_create_index;
|
||||||
}
|
}
|
||||||
@@ -2228,17 +2237,20 @@ void sqlite3CreateIndex(
|
|||||||
nullId.n = strlen((char*)nullId.z);
|
nullId.n = strlen((char*)nullId.z);
|
||||||
pList = sqlite3ExprListAppend(0, 0, &nullId);
|
pList = sqlite3ExprListAppend(0, 0, &nullId);
|
||||||
if( pList==0 ) goto exit_create_index;
|
if( pList==0 ) goto exit_create_index;
|
||||||
|
pList->a[0].sortOrder = sortOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Allocate the index structure.
|
** Allocate the index structure.
|
||||||
*/
|
*/
|
||||||
pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 + sizeof(int) +
|
nName = strlen(zName);
|
||||||
(sizeof(int)*2 + sizeof(CollSeq*))*pList->nExpr );
|
pIndex = sqliteMalloc( sizeof(Index) + nName + 2 + sizeof(int) +
|
||||||
|
(sizeof(int)*2 + sizeof(CollSeq*) + 1)*pList->nExpr );
|
||||||
if( sqlite3Tsd()->mallocFailed ) goto exit_create_index;
|
if( sqlite3Tsd()->mallocFailed ) goto exit_create_index;
|
||||||
pIndex->aiColumn = (int*)&pIndex->keyInfo.aColl[pList->nExpr];
|
pIndex->aiColumn = (int*)&pIndex->keyInfo.aColl[pList->nExpr];
|
||||||
pIndex->aiRowEst = (unsigned*)&pIndex->aiColumn[pList->nExpr];
|
pIndex->aiRowEst = (unsigned*)&pIndex->aiColumn[pList->nExpr];
|
||||||
pIndex->zName = (char*)&pIndex->aiRowEst[pList->nExpr+1];
|
pIndex->zName = (char*)&pIndex->aiRowEst[pList->nExpr+1];
|
||||||
|
pIndex->keyInfo.aSortOrder = &pIndex->zName[nName+1];
|
||||||
strcpy(pIndex->zName, zName);
|
strcpy(pIndex->zName, zName);
|
||||||
pIndex->pTable = pTab;
|
pIndex->pTable = pTab;
|
||||||
pIndex->nColumn = pList->nExpr;
|
pIndex->nColumn = pList->nExpr;
|
||||||
@@ -2246,23 +2258,38 @@ void sqlite3CreateIndex(
|
|||||||
pIndex->autoIndex = pName==0;
|
pIndex->autoIndex = pName==0;
|
||||||
pIndex->iDb = iDb;
|
pIndex->iDb = iDb;
|
||||||
|
|
||||||
|
/* Check to see if we should honor DESC requests on index columns
|
||||||
|
*/
|
||||||
|
if( pDb->file_format>=4 || (pDb->descIndex && db->init.busy) ){
|
||||||
|
#if 0
|
||||||
|
sortOrderMask = -1; /* Honor DESC */
|
||||||
|
#else
|
||||||
|
sortOrderMask = 0;
|
||||||
|
#endif
|
||||||
|
}else{
|
||||||
|
sortOrderMask = 0; /* Ignore DESC */
|
||||||
|
}
|
||||||
|
|
||||||
/* Scan the names of the columns of the table to be indexed and
|
/* Scan the names of the columns of the table to be indexed and
|
||||||
** load the column indices into the Index structure. Report an error
|
** load the column indices into the Index structure. Report an error
|
||||||
** if any column is not found.
|
** if any column is not found.
|
||||||
*/
|
*/
|
||||||
for(i=0; i<pList->nExpr; i++){
|
for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
|
||||||
for(j=0; j<pTab->nCol; j++){
|
const char *zColName = pListItem->zName;
|
||||||
if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[j].zName)==0 ) break;
|
Column *pTabCol;
|
||||||
|
int sortOrder;
|
||||||
|
for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
|
||||||
|
if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
|
||||||
}
|
}
|
||||||
if( j>=pTab->nCol ){
|
if( j>=pTab->nCol ){
|
||||||
sqlite3ErrorMsg(pParse, "table %s has no column named %s",
|
sqlite3ErrorMsg(pParse, "table %s has no column named %s",
|
||||||
pTab->zName, pList->a[i].zName);
|
pTab->zName, zColName);
|
||||||
goto exit_create_index;
|
goto exit_create_index;
|
||||||
}
|
}
|
||||||
pIndex->aiColumn[i] = j;
|
pIndex->aiColumn[i] = j;
|
||||||
if( pList->a[i].pExpr ){
|
if( pListItem->pExpr ){
|
||||||
assert( pList->a[i].pExpr->pColl );
|
assert( pListItem->pExpr->pColl );
|
||||||
pIndex->keyInfo.aColl[i] = pList->a[i].pExpr->pColl;
|
pIndex->keyInfo.aColl[i] = pListItem->pExpr->pColl;
|
||||||
}else{
|
}else{
|
||||||
pIndex->keyInfo.aColl[i] = pTab->aCol[j].pColl;
|
pIndex->keyInfo.aColl[i] = pTab->aCol[j].pColl;
|
||||||
}
|
}
|
||||||
@@ -2272,6 +2299,11 @@ void sqlite3CreateIndex(
|
|||||||
){
|
){
|
||||||
goto exit_create_index;
|
goto exit_create_index;
|
||||||
}
|
}
|
||||||
|
sortOrder = pListItem->sortOrder;
|
||||||
|
pDb->descIndex |= sortOrder;
|
||||||
|
sortOrder &= sortOrderMask;
|
||||||
|
pIndex->keyInfo.aSortOrder[i] = sortOrder;
|
||||||
|
descSeen |= sortOrder;
|
||||||
}
|
}
|
||||||
pIndex->keyInfo.nField = pList->nExpr;
|
pIndex->keyInfo.nField = pList->nExpr;
|
||||||
sqlite3DefaultRowEst(pIndex);
|
sqlite3DefaultRowEst(pIndex);
|
||||||
@@ -2301,6 +2333,7 @@ void sqlite3CreateIndex(
|
|||||||
for(k=0; k<pIdx->nColumn; k++){
|
for(k=0; k<pIdx->nColumn; k++){
|
||||||
if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
|
if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
|
||||||
if( pIdx->keyInfo.aColl[k]!=pIndex->keyInfo.aColl[k] ) break;
|
if( pIdx->keyInfo.aColl[k]!=pIndex->keyInfo.aColl[k] ) break;
|
||||||
|
if( pIdx->keyInfo.aSortOrder[k]!=pIndex->keyInfo.aSortOrder[k] ) break;
|
||||||
}
|
}
|
||||||
if( k==pIdx->nColumn ){
|
if( k==pIdx->nColumn ){
|
||||||
if( pIdx->onError!=pIndex->onError ){
|
if( pIdx->onError!=pIndex->onError ){
|
||||||
@@ -2364,6 +2397,11 @@ void sqlite3CreateIndex(
|
|||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v==0 ) goto exit_create_index;
|
if( v==0 ) goto exit_create_index;
|
||||||
|
|
||||||
|
/* Make sure the file_format is at least 4 if we have DESC indices. */
|
||||||
|
if( descSeen ){
|
||||||
|
sqlite3MinimumFileFormat(pParse, iDb, 4);
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the rootpage for the index
|
/* Create the rootpage for the index
|
||||||
*/
|
*/
|
||||||
sqlite3BeginWriteOperation(pParse, 1, iDb);
|
sqlite3BeginWriteOperation(pParse, 1, iDb);
|
||||||
|
|||||||
21
src/parse.y
21
src/parse.y
@@ -14,7 +14,7 @@
|
|||||||
** the parser. Lemon will also generate a header file containing
|
** the parser. Lemon will also generate a header file containing
|
||||||
** numeric codes for all of the tokens.
|
** numeric codes for all of the tokens.
|
||||||
**
|
**
|
||||||
** @(#) $Id: parse.y,v 1.187 2005/12/09 20:02:05 drh Exp $
|
** @(#) $Id: parse.y,v 1.188 2005/12/16 01:06:17 drh Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// All token codes are small integers with #defines that begin with "TK_"
|
// All token codes are small integers with #defines that begin with "TK_"
|
||||||
@@ -257,9 +257,9 @@ carg ::= DEFAULT id(X). {
|
|||||||
//
|
//
|
||||||
ccons ::= NULL onconf.
|
ccons ::= NULL onconf.
|
||||||
ccons ::= NOT NULL onconf(R). {sqlite3AddNotNull(pParse, R);}
|
ccons ::= NOT NULL onconf(R). {sqlite3AddNotNull(pParse, R);}
|
||||||
ccons ::= PRIMARY KEY sortorder onconf(R) autoinc(I).
|
ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I).
|
||||||
{sqlite3AddPrimaryKey(pParse,0,R,I);}
|
{sqlite3AddPrimaryKey(pParse,0,R,I,Z);}
|
||||||
ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0);}
|
ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0);}
|
||||||
ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X);}
|
ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X);}
|
||||||
ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
|
ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
|
||||||
{sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
|
{sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
|
||||||
@@ -307,9 +307,9 @@ conslist ::= conslist tcons.
|
|||||||
conslist ::= tcons.
|
conslist ::= tcons.
|
||||||
tcons ::= CONSTRAINT nm.
|
tcons ::= CONSTRAINT nm.
|
||||||
tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R).
|
tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R).
|
||||||
{sqlite3AddPrimaryKey(pParse,X,R,I);}
|
{sqlite3AddPrimaryKey(pParse,X,R,I,0);}
|
||||||
tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
|
tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
|
||||||
{sqlite3CreateIndex(pParse,0,0,0,X,R,0,0);}
|
{sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0);}
|
||||||
tcons ::= CHECK LP expr(E) RP onconf. {sqlite3AddCheckConstraint(pParse,E);}
|
tcons ::= CHECK LP expr(E) RP onconf. {sqlite3AddCheckConstraint(pParse,E);}
|
||||||
tcons ::= FOREIGN KEY LP idxlist(FA) RP
|
tcons ::= FOREIGN KEY LP idxlist(FA) RP
|
||||||
REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). {
|
REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). {
|
||||||
@@ -834,7 +834,8 @@ cmd ::= CREATE(S) uniqueflag(U) INDEX nm(X) dbnm(D)
|
|||||||
ON nm(Y) LP idxlist(Z) RP(E) onconf(R). {
|
ON nm(Y) LP idxlist(Z) RP(E) onconf(R). {
|
||||||
if( U!=OE_None ) U = R;
|
if( U!=OE_None ) U = R;
|
||||||
if( U==OE_Default) U = OE_Abort;
|
if( U==OE_Default) U = OE_Abort;
|
||||||
sqlite3CreateIndex(pParse, &X, &D, sqlite3SrcListAppend(0,&Y,0),Z,U, &S, &E);
|
sqlite3CreateIndex(pParse, &X, &D, sqlite3SrcListAppend(0,&Y,0), Z, U,
|
||||||
|
&S, &E, SQLITE_SO_ASC);
|
||||||
}
|
}
|
||||||
|
|
||||||
%type uniqueflag {int}
|
%type uniqueflag {int}
|
||||||
@@ -849,21 +850,23 @@ uniqueflag(A) ::= . {A = OE_None;}
|
|||||||
|
|
||||||
idxlist_opt(A) ::= . {A = 0;}
|
idxlist_opt(A) ::= . {A = 0;}
|
||||||
idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;}
|
idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;}
|
||||||
idxlist(A) ::= idxlist(X) COMMA idxitem(Y) collate(C) sortorder. {
|
idxlist(A) ::= idxlist(X) COMMA idxitem(Y) collate(C) sortorder(Z). {
|
||||||
Expr *p = 0;
|
Expr *p = 0;
|
||||||
if( C.n>0 ){
|
if( C.n>0 ){
|
||||||
p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
|
p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
|
||||||
if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)C.z, C.n);
|
if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)C.z, C.n);
|
||||||
}
|
}
|
||||||
A = sqlite3ExprListAppend(X, p, &Y);
|
A = sqlite3ExprListAppend(X, p, &Y);
|
||||||
|
if( A ) A->a[A->nExpr-1].sortOrder = Z;
|
||||||
}
|
}
|
||||||
idxlist(A) ::= idxitem(Y) collate(C) sortorder. {
|
idxlist(A) ::= idxitem(Y) collate(C) sortorder(Z). {
|
||||||
Expr *p = 0;
|
Expr *p = 0;
|
||||||
if( C.n>0 ){
|
if( C.n>0 ){
|
||||||
p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
|
p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
|
||||||
if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)C.z, C.n);
|
if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)C.z, C.n);
|
||||||
}
|
}
|
||||||
A = sqlite3ExprListAppend(0, p, &Y);
|
A = sqlite3ExprListAppend(0, p, &Y);
|
||||||
|
if( A ) A->a[A->nExpr-1].sortOrder = Z;
|
||||||
}
|
}
|
||||||
idxitem(A) ::= nm(X). {A = X;}
|
idxitem(A) ::= nm(X). {A = X;}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
** interface, and routines that contribute to loading the database schema
|
** interface, and routines that contribute to loading the database schema
|
||||||
** from disk.
|
** from disk.
|
||||||
**
|
**
|
||||||
** $Id: prepare.c,v 1.9 2005/12/15 03:04:11 drh Exp $
|
** $Id: prepare.c,v 1.10 2005/12/16 01:06:17 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -115,6 +115,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
BtCursor *curMain;
|
BtCursor *curMain;
|
||||||
int size;
|
int size;
|
||||||
Table *pTab;
|
Table *pTab;
|
||||||
|
Db *pDb;
|
||||||
char const *azArg[5];
|
char const *azArg[5];
|
||||||
char zDbNum[30];
|
char zDbNum[30];
|
||||||
int meta[10];
|
int meta[10];
|
||||||
@@ -184,11 +185,12 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
|
|
||||||
/* Create a cursor to hold the database open
|
/* Create a cursor to hold the database open
|
||||||
*/
|
*/
|
||||||
if( db->aDb[iDb].pBt==0 ){
|
pDb = &db->aDb[iDb];
|
||||||
|
if( pDb->pBt==0 ){
|
||||||
if( !OMIT_TEMPDB && iDb==1 ) DbSetProperty(db, 1, DB_SchemaLoaded);
|
if( !OMIT_TEMPDB && iDb==1 ) DbSetProperty(db, 1, DB_SchemaLoaded);
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain);
|
rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, 0, &curMain);
|
||||||
if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
|
if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
|
||||||
sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
|
sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -214,7 +216,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
int i;
|
int i;
|
||||||
for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){
|
for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){
|
||||||
rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, i+1, (u32 *)&meta[i]);
|
rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
|
||||||
}
|
}
|
||||||
if( rc ){
|
if( rc ){
|
||||||
sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
|
sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
|
||||||
@@ -224,7 +226,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
}else{
|
}else{
|
||||||
memset(meta, 0, sizeof(meta));
|
memset(meta, 0, sizeof(meta));
|
||||||
}
|
}
|
||||||
db->aDb[iDb].schema_cookie = meta[0];
|
pDb->schema_cookie = meta[0];
|
||||||
|
|
||||||
/* If opening a non-empty database, check the text encoding. For the
|
/* If opening a non-empty database, check the text encoding. For the
|
||||||
** main database, set sqlite3.enc to the encoding of the main database.
|
** main database, set sqlite3.enc to the encoding of the main database.
|
||||||
@@ -249,39 +251,25 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
|
|
||||||
size = meta[2];
|
size = meta[2];
|
||||||
if( size==0 ){ size = MAX_PAGES; }
|
if( size==0 ){ size = MAX_PAGES; }
|
||||||
db->aDb[iDb].cache_size = size;
|
pDb->cache_size = size;
|
||||||
|
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
|
||||||
if( iDb==0 ){
|
|
||||||
db->file_format = meta[1];
|
|
||||||
if( db->file_format==0 ){
|
|
||||||
/* This happens if the database was initially empty */
|
|
||||||
db->file_format = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( db->file_format==2 || db->file_format==3 ){
|
|
||||||
/* File format 2 is treated exactly as file format 1. New
|
|
||||||
** databases are created with file format 1.
|
|
||||||
*/
|
|
||||||
db->file_format = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** file_format==1 Version 3.0.0.
|
** file_format==1 Version 3.0.0.
|
||||||
** file_format==2 Version 3.1.3.
|
** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN
|
||||||
** file_format==3 Version 3.1.4.
|
** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults
|
||||||
**
|
** file_format==4 Version 3.3.0. // DESC indices
|
||||||
** Version 3.0 can only use files with file_format==1. Version 3.1.3
|
|
||||||
** can read and write files with file_format==1 or file_format==2.
|
|
||||||
** Version 3.1.4 can read and write file formats 1, 2 and 3.
|
|
||||||
*/
|
*/
|
||||||
if( meta[1]>3 ){
|
pDb->file_format = meta[1];
|
||||||
|
if( pDb->file_format==0 ){
|
||||||
|
pDb->file_format = 1;
|
||||||
|
}
|
||||||
|
if( pDb->file_format>4 ){
|
||||||
sqlite3BtreeCloseCursor(curMain);
|
sqlite3BtreeCloseCursor(curMain);
|
||||||
sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
|
sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
|
||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);
|
|
||||||
|
|
||||||
/* Read the schema information out of the schema tables
|
/* Read the schema information out of the schema tables
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.437 2005/12/15 15:22:09 danielk1977 Exp $
|
** @(#) $Id: sqliteInt.h,v 1.438 2005/12/16 01:06:17 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -356,6 +356,8 @@ struct Db {
|
|||||||
u16 flags; /* Flags associated with this database */
|
u16 flags; /* Flags associated with this database */
|
||||||
u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */
|
u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */
|
||||||
u8 safety_level; /* How aggressive at synching data to disk */
|
u8 safety_level; /* How aggressive at synching data to disk */
|
||||||
|
u8 file_format; /* Schema format version for this file */
|
||||||
|
u8 descIndex; /* True if any index uses the DESC attribute */
|
||||||
int cache_size; /* Number of pages to use in the cache */
|
int cache_size; /* Number of pages to use in the cache */
|
||||||
Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */
|
Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */
|
||||||
void *pAux; /* Auxiliary data. Usually NULL */
|
void *pAux; /* Auxiliary data. Usually NULL */
|
||||||
@@ -419,7 +421,6 @@ struct sqlite3 {
|
|||||||
int errCode; /* Most recent error code (SQLITE_*) */
|
int errCode; /* Most recent error code (SQLITE_*) */
|
||||||
u8 enc; /* Text encoding for this database. */
|
u8 enc; /* Text encoding for this database. */
|
||||||
u8 autoCommit; /* The auto-commit flag. */
|
u8 autoCommit; /* The auto-commit flag. */
|
||||||
u8 file_format; /* What file format version is this database? */
|
|
||||||
u8 temp_store; /* 1: file 2: memory 0: default */
|
u8 temp_store; /* 1: file 2: memory 0: default */
|
||||||
int nTable; /* Number of tables in the database */
|
int nTable; /* Number of tables in the database */
|
||||||
CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
|
CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
|
||||||
@@ -1467,7 +1468,7 @@ void sqlite3OpenMasterTable(Vdbe *v, int);
|
|||||||
void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int);
|
void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int);
|
||||||
void sqlite3AddColumn(Parse*,Token*);
|
void sqlite3AddColumn(Parse*,Token*);
|
||||||
void sqlite3AddNotNull(Parse*, int);
|
void sqlite3AddNotNull(Parse*, int);
|
||||||
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int);
|
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
|
||||||
void sqlite3AddCheckConstraint(Parse*, Expr*);
|
void sqlite3AddCheckConstraint(Parse*, Expr*);
|
||||||
void sqlite3AddColumnType(Parse*,Token*);
|
void sqlite3AddColumnType(Parse*,Token*);
|
||||||
void sqlite3AddDefaultValue(Parse*,Expr*);
|
void sqlite3AddDefaultValue(Parse*,Expr*);
|
||||||
@@ -1493,7 +1494,7 @@ void sqlite3SrcListAssignCursors(Parse*, SrcList*);
|
|||||||
void sqlite3IdListDelete(IdList*);
|
void sqlite3IdListDelete(IdList*);
|
||||||
void sqlite3SrcListDelete(SrcList*);
|
void sqlite3SrcListDelete(SrcList*);
|
||||||
void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
|
void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
|
||||||
Token*);
|
Token*, int);
|
||||||
void sqlite3DropIndex(Parse*, SrcList*);
|
void sqlite3DropIndex(Parse*, SrcList*);
|
||||||
void sqlite3AddKeyType(Vdbe*, ExprList*);
|
void sqlite3AddKeyType(Vdbe*, ExprList*);
|
||||||
void sqlite3AddIdxKeyType(Vdbe*, Index*);
|
void sqlite3AddIdxKeyType(Vdbe*, Index*);
|
||||||
@@ -1676,6 +1677,7 @@ void sqlite3RegisterLikeFunctions(sqlite3*, int);
|
|||||||
int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
|
int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
|
||||||
SqliteTsd *sqlite3Tsd();
|
SqliteTsd *sqlite3Tsd();
|
||||||
void sqlite3AttachFunctions(sqlite3 *);
|
void sqlite3AttachFunctions(sqlite3 *);
|
||||||
|
void sqlite3MinimumFileFormat(Parse*, int, int);
|
||||||
|
|
||||||
void sqlite3MallocClearFailed();
|
void sqlite3MallocClearFailed();
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
|
|||||||
@@ -435,16 +435,18 @@ void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
|
|||||||
KeyInfo *pKeyInfo;
|
KeyInfo *pKeyInfo;
|
||||||
int nField, nByte;
|
int nField, nByte;
|
||||||
|
|
||||||
/* KeyInfo structures that include an KeyInfo.aSortOrder are always
|
|
||||||
** sent in using P3_KEYINFO_HANDOFF. The KeyInfo.aSortOrder array
|
|
||||||
** is not duplicated when P3_KEYINFO is used. */
|
|
||||||
/* assert( pKeyInfo->aSortOrder==0 ); */
|
|
||||||
nField = ((KeyInfo*)zP3)->nField;
|
nField = ((KeyInfo*)zP3)->nField;
|
||||||
nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]);
|
nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
|
||||||
pKeyInfo = sqliteMallocRaw( nByte );
|
pKeyInfo = sqliteMallocRaw( nByte );
|
||||||
pOp->p3 = (char*)pKeyInfo;
|
pOp->p3 = (char*)pKeyInfo;
|
||||||
if( pKeyInfo ){
|
if( pKeyInfo ){
|
||||||
|
char *aSortOrder;
|
||||||
memcpy(pKeyInfo, zP3, nByte);
|
memcpy(pKeyInfo, zP3, nByte);
|
||||||
|
aSortOrder = pKeyInfo->aSortOrder;
|
||||||
|
if( aSortOrder ){
|
||||||
|
pKeyInfo->aSortOrder = (char*)&pKeyInfo->aColl[nField];
|
||||||
|
memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
|
||||||
|
}
|
||||||
pOp->p3type = P3_KEYINFO;
|
pOp->p3type = P3_KEYINFO;
|
||||||
}else{
|
}else{
|
||||||
pOp->p3type = P3_NOTUSED;
|
pOp->p3type = P3_NOTUSED;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this script testing the callback-free C/C++ API.
|
# focus of this script testing the callback-free C/C++ API.
|
||||||
#
|
#
|
||||||
# $Id: capi3.test,v 1.34 2005/08/11 02:10:19 drh Exp $
|
# $Id: capi3.test,v 1.35 2005/12/16 01:06:18 drh Exp $
|
||||||
#
|
#
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
@@ -490,7 +490,7 @@ if {![sqlite3 -has-codec]} {
|
|||||||
set ::bt [btree_open test.db 10 0]
|
set ::bt [btree_open test.db 10 0]
|
||||||
btree_begin_transaction $::bt
|
btree_begin_transaction $::bt
|
||||||
set meta [btree_get_meta $::bt]
|
set meta [btree_get_meta $::bt]
|
||||||
lset meta 2 4
|
lset meta 2 5
|
||||||
eval [concat btree_update_meta $::bt [lrange $meta 0 end]]
|
eval [concat btree_update_meta $::bt [lrange $meta 0 end]]
|
||||||
btree_commit $::bt
|
btree_commit $::bt
|
||||||
btree_close $::bt
|
btree_close $::bt
|
||||||
|
|||||||
Reference in New Issue
Block a user