mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
MFH: Upgraded SQLite 2 library in ext/sqlite to 2.8.16
This commit is contained in:
parent
caa9702a5a
commit
7f293b91b4
18 changed files with 271 additions and 189 deletions
1
NEWS
1
NEWS
|
@ -5,6 +5,7 @@ PHP NEWS
|
||||||
classes. (Dmitry, Michael Wallner)
|
classes. (Dmitry, Michael Wallner)
|
||||||
- Added "new_link" parameter to mssql_connect(). Bug #34369. (Frank)
|
- Added "new_link" parameter to mssql_connect(). Bug #34369. (Frank)
|
||||||
- Upgraded bundled SQLite library for PDO:SQLite to 3.2.5 (Ilia)
|
- Upgraded bundled SQLite library for PDO:SQLite to 3.2.5 (Ilia)
|
||||||
|
- Upgraded SQLite 2 library in ext/sqlite to 2.8.16 (Ilia)
|
||||||
- Upgraded PCRE library to version 6.2. (Andrei)
|
- Upgraded PCRE library to version 6.2. (Andrei)
|
||||||
- Upgraded bundled libraries in Windows distribution. (Edin)
|
- Upgraded bundled libraries in Windows distribution. (Edin)
|
||||||
. zlib 1.2.3
|
. zlib 1.2.3
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
2.8.14
|
2.8.16
|
||||||
|
|
|
@ -259,17 +259,16 @@ static void rightRotate(BtRbTree *pTree, BtRbNode *pX)
|
||||||
* concatenation of orig and val is returned. The original orig is deleted
|
* concatenation of orig and val is returned. The original orig is deleted
|
||||||
* (using sqliteFree()).
|
* (using sqliteFree()).
|
||||||
*/
|
*/
|
||||||
static char *append_val(char * orig, char const * val)
|
static char *append_val(char * orig, char const * val){
|
||||||
{
|
char *z;
|
||||||
if( !orig ){
|
if( !orig ){
|
||||||
return sqliteStrDup( val );
|
z = sqliteStrDup( val );
|
||||||
} else{
|
} else{
|
||||||
char * ret = 0;
|
z = 0;
|
||||||
sqliteSetString(&ret, orig, val, (char*)0);
|
sqliteSetString(&z, orig, val, (char*)0);
|
||||||
sqliteFree( orig );
|
sqliteFree( orig );
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
assert(0);
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -723,13 +722,13 @@ static int memRbtreeCursor(
|
||||||
pCur = *ppCur = sqliteMalloc(sizeof(RbtCursor));
|
pCur = *ppCur = sqliteMalloc(sizeof(RbtCursor));
|
||||||
if( sqlite_malloc_failed ) return SQLITE_NOMEM;
|
if( sqlite_malloc_failed ) return SQLITE_NOMEM;
|
||||||
pCur->pTree = sqliteHashFind(&tree->tblHash, 0, iTable);
|
pCur->pTree = sqliteHashFind(&tree->tblHash, 0, iTable);
|
||||||
|
assert( pCur->pTree );
|
||||||
pCur->pRbtree = tree;
|
pCur->pRbtree = tree;
|
||||||
pCur->iTree = iTable;
|
pCur->iTree = iTable;
|
||||||
pCur->pOps = &sqliteRbtreeCursorOps;
|
pCur->pOps = &sqliteRbtreeCursorOps;
|
||||||
pCur->wrFlag = wrFlag;
|
pCur->wrFlag = wrFlag;
|
||||||
pCur->pShared = pCur->pTree->pCursors;
|
pCur->pShared = pCur->pTree->pCursors;
|
||||||
pCur->pTree->pCursors = pCur;
|
pCur->pTree->pCursors = pCur;
|
||||||
|
|
||||||
|
|
||||||
assert( (*ppCur)->pTree );
|
assert( (*ppCur)->pTree );
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
|
@ -1178,12 +1177,11 @@ static int memRbtreeKey(RbtCursor* pCur, int offset, int amt, char *zBuf)
|
||||||
if( !pCur->pNode ) return 0;
|
if( !pCur->pNode ) return 0;
|
||||||
if( !pCur->pNode->pKey || ((amt + offset) <= pCur->pNode->nKey) ){
|
if( !pCur->pNode->pKey || ((amt + offset) <= pCur->pNode->nKey) ){
|
||||||
memcpy(zBuf, ((char*)pCur->pNode->pKey)+offset, amt);
|
memcpy(zBuf, ((char*)pCur->pNode->pKey)+offset, amt);
|
||||||
return amt;
|
|
||||||
}else{
|
}else{
|
||||||
memcpy(zBuf, ((char*)pCur->pNode->pKey)+offset, pCur->pNode->nKey-offset);
|
memcpy(zBuf, ((char*)pCur->pNode->pKey)+offset, pCur->pNode->nKey-offset);
|
||||||
return pCur->pNode->nKey-offset;
|
amt = pCur->pNode->nKey-offset;
|
||||||
}
|
}
|
||||||
assert(0);
|
return amt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int memRbtreeDataSize(RbtCursor* pCur, int *pSize)
|
static int memRbtreeDataSize(RbtCursor* pCur, int *pSize)
|
||||||
|
@ -1201,12 +1199,11 @@ static int memRbtreeData(RbtCursor *pCur, int offset, int amt, char *zBuf)
|
||||||
if( !pCur->pNode ) return 0;
|
if( !pCur->pNode ) return 0;
|
||||||
if( (amt + offset) <= pCur->pNode->nData ){
|
if( (amt + offset) <= pCur->pNode->nData ){
|
||||||
memcpy(zBuf, ((char*)pCur->pNode->pData)+offset, amt);
|
memcpy(zBuf, ((char*)pCur->pNode->pData)+offset, amt);
|
||||||
return amt;
|
|
||||||
}else{
|
}else{
|
||||||
memcpy(zBuf, ((char*)pCur->pNode->pData)+offset ,pCur->pNode->nData-offset);
|
memcpy(zBuf, ((char*)pCur->pNode->pData)+offset ,pCur->pNode->nData-offset);
|
||||||
return pCur->pNode->nData-offset;
|
amt = pCur->pNode->nData-offset;
|
||||||
}
|
}
|
||||||
assert(0);
|
return amt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int memRbtreeCloseCursor(RbtCursor* pCur)
|
static int memRbtreeCloseCursor(RbtCursor* pCur)
|
||||||
|
@ -1421,13 +1418,12 @@ static int memRbtreeCursorDump(RbtCursor* pCur, int* aRes)
|
||||||
assert(!"Cannot call sqliteRbtreeCursorDump");
|
assert(!"Cannot call sqliteRbtreeCursorDump");
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct Pager *memRbtreePager(Rbtree* tree)
|
static struct Pager *memRbtreePager(Rbtree* tree)
|
||||||
{
|
{
|
||||||
assert(!"Cannot call sqliteRbtreePager");
|
return 0;
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the full pathname of the underlying database file.
|
** Return the full pathname of the underlying database file.
|
||||||
|
@ -1463,10 +1459,9 @@ static BtOps sqliteRbtreeOps = {
|
||||||
(char*(*)(Btree*,int*,int)) memRbtreeIntegrityCheck,
|
(char*(*)(Btree*,int*,int)) memRbtreeIntegrityCheck,
|
||||||
(const char*(*)(Btree*)) memRbtreeGetFilename,
|
(const char*(*)(Btree*)) memRbtreeGetFilename,
|
||||||
(int(*)(Btree*,Btree*)) memRbtreeCopyFile,
|
(int(*)(Btree*,Btree*)) memRbtreeCopyFile,
|
||||||
|
(struct Pager*(*)(Btree*)) memRbtreePager,
|
||||||
#ifdef SQLITE_TEST
|
#ifdef SQLITE_TEST
|
||||||
(int(*)(Btree*,int,int)) memRbtreePageDump,
|
(int(*)(Btree*,int,int)) memRbtreePageDump,
|
||||||
(struct Pager*(*)(Btree*)) memRbtreePager
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1537,7 +1537,7 @@ void sqliteCreateIndex(
|
||||||
if( pName && !db->init.busy ){
|
if( pName && !db->init.busy ){
|
||||||
Index *pISameName; /* Another index with the same name */
|
Index *pISameName; /* Another index with the same name */
|
||||||
Table *pTSameName; /* A table with same name as the index */
|
Table *pTSameName; /* A table with same name as the index */
|
||||||
zName = sqliteStrNDup(pName->z, pName->n);
|
zName = sqliteTableNameFromToken(pName);
|
||||||
if( zName==0 ) goto exit_create_index;
|
if( zName==0 ) goto exit_create_index;
|
||||||
if( (pISameName = sqliteFindIndex(db, zName, 0))!=0 ){
|
if( (pISameName = sqliteFindIndex(db, zName, 0))!=0 ){
|
||||||
sqliteErrorMsg(pParse, "index %s already exists", zName);
|
sqliteErrorMsg(pParse, "index %s already exists", zName);
|
||||||
|
@ -1557,7 +1557,7 @@ void sqliteCreateIndex(
|
||||||
sqliteSetString(&zName, "(", pTab->zName, " autoindex ", zBuf, (char*)0);
|
sqliteSetString(&zName, "(", pTab->zName, " autoindex ", zBuf, (char*)0);
|
||||||
if( zName==0 ) goto exit_create_index;
|
if( zName==0 ) goto exit_create_index;
|
||||||
}else{
|
}else{
|
||||||
zName = sqliteStrNDup(pName->z, pName->n);
|
zName = sqliteTableNameFromToken(pName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for authorization to create an index.
|
/* Check for authorization to create an index.
|
||||||
|
|
|
@ -800,18 +800,20 @@ static void strftimeFunc(sqlite_func *context, int argc, const char **argv){
|
||||||
case 'H': sprintf(&z[j],"%02d",x.h); j+=2; break;
|
case 'H': sprintf(&z[j],"%02d",x.h); j+=2; break;
|
||||||
case 'W': /* Fall thru */
|
case 'W': /* Fall thru */
|
||||||
case 'j': {
|
case 'j': {
|
||||||
int n;
|
int n; /* Number of days since 1st day of year */
|
||||||
DateTime y = x;
|
DateTime y = x;
|
||||||
y.validJD = 0;
|
y.validJD = 0;
|
||||||
y.M = 1;
|
y.M = 1;
|
||||||
y.D = 1;
|
y.D = 1;
|
||||||
computeJD(&y);
|
computeJD(&y);
|
||||||
n = x.rJD - y.rJD + 1;
|
n = x.rJD - y.rJD;
|
||||||
if( zFmt[i]=='W' ){
|
if( zFmt[i]=='W' ){
|
||||||
sprintf(&z[j],"%02d",(n+6)/7);
|
int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */
|
||||||
|
wd = ((int)(x.rJD+0.5)) % 7;
|
||||||
|
sprintf(&z[j],"%02d",(n+7-wd)/7);
|
||||||
j += 2;
|
j += 2;
|
||||||
}else{
|
}else{
|
||||||
sprintf(&z[j],"%03d",n);
|
sprintf(&z[j],"%03d",n+1);
|
||||||
j += 3;
|
j += 3;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -847,19 +849,18 @@ static void strftimeFunc(sqlite_func *context, int argc, const char **argv){
|
||||||
** external linkage.
|
** external linkage.
|
||||||
*/
|
*/
|
||||||
void sqliteRegisterDateTimeFunctions(sqlite *db){
|
void sqliteRegisterDateTimeFunctions(sqlite *db){
|
||||||
|
#ifndef SQLITE_OMIT_DATETIME_FUNCS
|
||||||
static struct {
|
static struct {
|
||||||
char *zName;
|
char *zName;
|
||||||
int nArg;
|
int nArg;
|
||||||
int dataType;
|
int dataType;
|
||||||
void (*xFunc)(sqlite_func*,int,const char**);
|
void (*xFunc)(sqlite_func*,int,const char**);
|
||||||
} aFuncs[] = {
|
} aFuncs[] = {
|
||||||
#ifndef SQLITE_OMIT_DATETIME_FUNCS
|
|
||||||
{ "julianday", -1, SQLITE_NUMERIC, juliandayFunc },
|
{ "julianday", -1, SQLITE_NUMERIC, juliandayFunc },
|
||||||
{ "date", -1, SQLITE_TEXT, dateFunc },
|
{ "date", -1, SQLITE_TEXT, dateFunc },
|
||||||
{ "time", -1, SQLITE_TEXT, timeFunc },
|
{ "time", -1, SQLITE_TEXT, timeFunc },
|
||||||
{ "datetime", -1, SQLITE_TEXT, datetimeFunc },
|
{ "datetime", -1, SQLITE_TEXT, datetimeFunc },
|
||||||
{ "strftime", -1, SQLITE_TEXT, strftimeFunc },
|
{ "strftime", -1, SQLITE_TEXT, strftimeFunc },
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -870,4 +871,5 @@ void sqliteRegisterDateTimeFunctions(sqlite *db){
|
||||||
sqlite_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);
|
sqlite_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@ Expr *sqliteExprDup(Expr *p){
|
||||||
if( pNew==0 ) return 0;
|
if( pNew==0 ) return 0;
|
||||||
memcpy(pNew, p, sizeof(*pNew));
|
memcpy(pNew, p, sizeof(*pNew));
|
||||||
if( p->token.z!=0 ){
|
if( p->token.z!=0 ){
|
||||||
pNew->token.z = sqliteStrDup(p->token.z);
|
pNew->token.z = sqliteStrNDup(p->token.z, p->token.n);
|
||||||
pNew->token.dyn = 1;
|
pNew->token.dyn = 1;
|
||||||
}else{
|
}else{
|
||||||
assert( pNew->token.z==0 );
|
assert( pNew->token.z==0 );
|
||||||
|
@ -155,7 +155,10 @@ ExprList *sqliteExprListDup(ExprList *p){
|
||||||
if( pNew==0 ) return 0;
|
if( pNew==0 ) return 0;
|
||||||
pNew->nExpr = pNew->nAlloc = p->nExpr;
|
pNew->nExpr = pNew->nAlloc = p->nExpr;
|
||||||
pNew->a = pItem = sqliteMalloc( p->nExpr*sizeof(p->a[0]) );
|
pNew->a = pItem = sqliteMalloc( p->nExpr*sizeof(p->a[0]) );
|
||||||
if( pItem==0 ) return 0; /* Leaks memory after a malloc failure */
|
if( pItem==0 ){
|
||||||
|
sqliteFree(pNew);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
for(i=0; i<p->nExpr; i++, pItem++){
|
for(i=0; i<p->nExpr; i++, pItem++){
|
||||||
Expr *pNewExpr, *pOldExpr;
|
Expr *pNewExpr, *pOldExpr;
|
||||||
pItem->pExpr = pNewExpr = sqliteExprDup(pOldExpr = p->a[i].pExpr);
|
pItem->pExpr = pNewExpr = sqliteExprDup(pOldExpr = p->a[i].pExpr);
|
||||||
|
|
|
@ -157,20 +157,20 @@ static void roundFunc(sqlite_func *context, int argc, const char **argv){
|
||||||
** Implementation of the upper() and lower() SQL functions.
|
** Implementation of the upper() and lower() SQL functions.
|
||||||
*/
|
*/
|
||||||
static void upperFunc(sqlite_func *context, int argc, const char **argv){
|
static void upperFunc(sqlite_func *context, int argc, const char **argv){
|
||||||
char *z;
|
unsigned char *z;
|
||||||
int i;
|
int i;
|
||||||
if( argc<1 || argv[0]==0 ) return;
|
if( argc<1 || argv[0]==0 ) return;
|
||||||
z = sqlite_set_result_string(context, argv[0], -1);
|
z = (unsigned char*)sqlite_set_result_string(context, argv[0], -1);
|
||||||
if( z==0 ) return;
|
if( z==0 ) return;
|
||||||
for(i=0; z[i]; i++){
|
for(i=0; z[i]; i++){
|
||||||
if( islower(z[i]) ) z[i] = toupper(z[i]);
|
if( islower(z[i]) ) z[i] = toupper(z[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void lowerFunc(sqlite_func *context, int argc, const char **argv){
|
static void lowerFunc(sqlite_func *context, int argc, const char **argv){
|
||||||
char *z;
|
unsigned char *z;
|
||||||
int i;
|
int i;
|
||||||
if( argc<1 || argv[0]==0 ) return;
|
if( argc<1 || argv[0]==0 ) return;
|
||||||
z = sqlite_set_result_string(context, argv[0], -1);
|
z = (unsigned char*)sqlite_set_result_string(context, argv[0], -1);
|
||||||
if( z==0 ) return;
|
if( z==0 ) return;
|
||||||
for(i=0; z[i]; i++){
|
for(i=0; z[i]; i++){
|
||||||
if( isupper(z[i]) ) z[i] = tolower(z[i]);
|
if( isupper(z[i]) ) z[i] = tolower(z[i]);
|
||||||
|
@ -517,26 +517,28 @@ static void minmaxStep(sqlite_func *context, int argc, const char **argv){
|
||||||
int mask; /* 0 for min() or 0xffffffff for max() */
|
int mask; /* 0 for min() or 0xffffffff for max() */
|
||||||
|
|
||||||
assert( argc==2 );
|
assert( argc==2 );
|
||||||
|
if( argv[0]==0 ) return; /* Ignore NULL values */
|
||||||
if( argv[1][0]=='n' ){
|
if( argv[1][0]=='n' ){
|
||||||
xCompare = sqliteCompare;
|
xCompare = sqliteCompare;
|
||||||
}else{
|
}else{
|
||||||
xCompare = strcmp;
|
xCompare = strcmp;
|
||||||
}
|
}
|
||||||
mask = (int)sqlite_user_data(context);
|
mask = (int)sqlite_user_data(context);
|
||||||
|
assert( mask==0 || mask==-1 );
|
||||||
p = sqlite_aggregate_context(context, sizeof(*p));
|
p = sqlite_aggregate_context(context, sizeof(*p));
|
||||||
if( p==0 || argc<1 || argv[0]==0 ) return;
|
if( p==0 || argc<1 ) return;
|
||||||
if( p->z==0 || (xCompare(argv[0],p->z)^mask)<0 ){
|
if( p->z==0 || (xCompare(argv[0],p->z)^mask)<0 ){
|
||||||
int len;
|
int len;
|
||||||
if( !p->zBuf[0] ){
|
if( p->zBuf[0] ){
|
||||||
sqliteFree(p->z);
|
sqliteFree(p->z);
|
||||||
}
|
}
|
||||||
len = strlen(argv[0]);
|
len = strlen(argv[0]);
|
||||||
if( len < sizeof(p->zBuf)-1 ){
|
if( len < sizeof(p->zBuf)-1 ){
|
||||||
p->z = &p->zBuf[1];
|
p->z = &p->zBuf[1];
|
||||||
p->zBuf[0] = 1;
|
p->zBuf[0] = 0;
|
||||||
}else{
|
}else{
|
||||||
p->z = sqliteMalloc( len+1 );
|
p->z = sqliteMalloc( len+1 );
|
||||||
p->zBuf[0] = 0;
|
p->zBuf[0] = 1;
|
||||||
if( p->z==0 ) return;
|
if( p->z==0 ) return;
|
||||||
}
|
}
|
||||||
strcpy(p->z, argv[0]);
|
strcpy(p->z, argv[0]);
|
||||||
|
@ -545,10 +547,10 @@ static void minmaxStep(sqlite_func *context, int argc, const char **argv){
|
||||||
static void minMaxFinalize(sqlite_func *context){
|
static void minMaxFinalize(sqlite_func *context){
|
||||||
MinMaxCtx *p;
|
MinMaxCtx *p;
|
||||||
p = sqlite_aggregate_context(context, sizeof(*p));
|
p = sqlite_aggregate_context(context, sizeof(*p));
|
||||||
if( p && p->z ){
|
if( p && p->z && p->zBuf[0]<2 ){
|
||||||
sqlite_set_result_string(context, p->z, strlen(p->z));
|
sqlite_set_result_string(context, p->z, strlen(p->z));
|
||||||
}
|
}
|
||||||
if( p && !p->zBuf[0] ){
|
if( p && p->zBuf[0] ){
|
||||||
sqliteFree(p->z);
|
sqliteFree(p->z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -621,7 +623,12 @@ void sqliteRegisterBuiltinFunctions(sqlite *db){
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
|
for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
|
||||||
void *pArg = aFuncs[i].argType==2 ? (void*)(-1) : db;
|
void *pArg;
|
||||||
|
switch( aFuncs[i].argType ){
|
||||||
|
case 0: pArg = 0; break;
|
||||||
|
case 1: pArg = db; break;
|
||||||
|
case 2: pArg = (void*)(-1); break;
|
||||||
|
}
|
||||||
sqlite_create_function(db, aFuncs[i].zName,
|
sqlite_create_function(db, aFuncs[i].zName,
|
||||||
aFuncs[i].nArg, aFuncs[i].xFunc, pArg);
|
aFuncs[i].nArg, aFuncs[i].xFunc, pArg);
|
||||||
if( aFuncs[i].xFunc ){
|
if( aFuncs[i].xFunc ){
|
||||||
|
@ -629,7 +636,12 @@ void sqliteRegisterBuiltinFunctions(sqlite *db){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
|
for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
|
||||||
void *pArg = aAggs[i].argType==2 ? (void*)(-1) : db;
|
void *pArg;
|
||||||
|
switch( aAggs[i].argType ){
|
||||||
|
case 0: pArg = 0; break;
|
||||||
|
case 1: pArg = db; break;
|
||||||
|
case 2: pArg = (void*)(-1); break;
|
||||||
|
}
|
||||||
sqlite_create_aggregate(db, aAggs[i].zName,
|
sqlite_create_aggregate(db, aAggs[i].zName,
|
||||||
aAggs[i].nArg, aAggs[i].xStep, aAggs[i].xFinalize, pArg);
|
aAggs[i].nArg, aAggs[i].xStep, aAggs[i].xFinalize, pArg);
|
||||||
sqlite_function_type(db, aAggs[i].zName, aAggs[i].dataType);
|
sqlite_function_type(db, aAggs[i].zName, aAggs[i].dataType);
|
||||||
|
|
|
@ -189,10 +189,13 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||||
BtCursor *curMain;
|
BtCursor *curMain;
|
||||||
int size;
|
int size;
|
||||||
Table *pTab;
|
Table *pTab;
|
||||||
char *azArg[6];
|
char const *azArg[6];
|
||||||
char zDbNum[30];
|
char zDbNum[30];
|
||||||
int meta[SQLITE_N_BTREE_META];
|
int meta[SQLITE_N_BTREE_META];
|
||||||
InitData initData;
|
InitData initData;
|
||||||
|
char const *zMasterSchema;
|
||||||
|
char const *zMasterName;
|
||||||
|
char *zSql = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The master database table has a structure like this
|
** The master database table has a structure like this
|
||||||
|
@ -216,62 +219,38 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||||
")"
|
")"
|
||||||
;
|
;
|
||||||
|
|
||||||
/* The following SQL will read the schema from the master tables.
|
assert( iDb>=0 && iDb<db->nDb );
|
||||||
** The first version works with SQLite file formats 2 or greater.
|
|
||||||
** The second version is for format 1 files.
|
/* zMasterSchema and zInitScript are set to point at the master schema
|
||||||
**
|
** and initialisation script appropriate for the database being
|
||||||
** Beginning with file format 2, the rowid for new table entries
|
** initialised. zMasterName is the name of the master table.
|
||||||
** (including entries in sqlite_master) is an increasing integer.
|
|
||||||
** So for file format 2 and later, we can play back sqlite_master
|
|
||||||
** and all the CREATE statements will appear in the right order.
|
|
||||||
** But with file format 1, table entries were random and so we
|
|
||||||
** have to make sure the CREATE TABLEs occur before their corresponding
|
|
||||||
** CREATE INDEXs. (We don't have to deal with CREATE VIEW or
|
|
||||||
** CREATE TRIGGER in file format 1 because those constructs did
|
|
||||||
** not exist then.)
|
|
||||||
*/
|
*/
|
||||||
static char init_script[] =
|
if( iDb==1 ){
|
||||||
"SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
|
zMasterSchema = temp_master_schema;
|
||||||
"UNION ALL "
|
zMasterName = TEMP_MASTER_NAME;
|
||||||
"SELECT type, name, rootpage, sql, 0 FROM sqlite_master";
|
}else{
|
||||||
static char older_init_script[] =
|
zMasterSchema = master_schema;
|
||||||
"SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
|
zMasterName = MASTER_NAME;
|
||||||
"UNION ALL "
|
}
|
||||||
"SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
|
|
||||||
"WHERE type='table' "
|
|
||||||
"UNION ALL "
|
|
||||||
"SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
|
|
||||||
"WHERE type='index'";
|
|
||||||
|
|
||||||
|
/* Construct the schema table.
|
||||||
assert( iDb>=0 && iDb!=1 && iDb<db->nDb );
|
|
||||||
|
|
||||||
/* Construct the schema tables: sqlite_master and sqlite_temp_master
|
|
||||||
*/
|
*/
|
||||||
sqliteSafetyOff(db);
|
sqliteSafetyOff(db);
|
||||||
azArg[0] = "table";
|
azArg[0] = "table";
|
||||||
azArg[1] = MASTER_NAME;
|
azArg[1] = zMasterName;
|
||||||
azArg[2] = "2";
|
azArg[2] = "2";
|
||||||
azArg[3] = master_schema;
|
azArg[3] = zMasterSchema;
|
||||||
sprintf(zDbNum, "%d", iDb);
|
sprintf(zDbNum, "%d", iDb);
|
||||||
azArg[4] = zDbNum;
|
azArg[4] = zDbNum;
|
||||||
azArg[5] = 0;
|
azArg[5] = 0;
|
||||||
initData.db = db;
|
initData.db = db;
|
||||||
initData.pzErrMsg = pzErrMsg;
|
initData.pzErrMsg = pzErrMsg;
|
||||||
sqliteInitCallback(&initData, 5, azArg, 0);
|
sqliteInitCallback(&initData, 5, (char **)azArg, 0);
|
||||||
pTab = sqliteFindTable(db, MASTER_NAME, "main");
|
pTab = sqliteFindTable(db, zMasterName, db->aDb[iDb].zName);
|
||||||
if( pTab ){
|
if( pTab ){
|
||||||
pTab->readOnly = 1;
|
pTab->readOnly = 1;
|
||||||
}
|
}else{
|
||||||
if( iDb==0 ){
|
return SQLITE_NOMEM;
|
||||||
azArg[1] = TEMP_MASTER_NAME;
|
|
||||||
azArg[3] = temp_master_schema;
|
|
||||||
azArg[4] = "1";
|
|
||||||
sqliteInitCallback(&initData, 5, azArg, 0);
|
|
||||||
pTab = sqliteFindTable(db, TEMP_MASTER_NAME, "temp");
|
|
||||||
if( pTab ){
|
|
||||||
pTab->readOnly = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sqliteSafetyOn(db);
|
sqliteSafetyOn(db);
|
||||||
|
|
||||||
|
@ -320,7 +299,7 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||||
sqliteSetString(pzErrMsg, "unsupported file format", (char*)0);
|
sqliteSetString(pzErrMsg, "unsupported file format", (char*)0);
|
||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
}else if( db->file_format!=meta[2] || db->file_format<4 ){
|
}else if( iDb!=1 && (db->file_format!=meta[2] || db->file_format<4) ){
|
||||||
assert( db->file_format>=4 );
|
assert( db->file_format>=4 );
|
||||||
if( meta[2]==0 ){
|
if( meta[2]==0 ){
|
||||||
sqliteSetString(pzErrMsg, "cannot attach empty database: ",
|
sqliteSetString(pzErrMsg, "cannot attach empty database: ",
|
||||||
|
@ -340,18 +319,35 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||||
*/
|
*/
|
||||||
assert( db->init.busy );
|
assert( db->init.busy );
|
||||||
sqliteSafetyOff(db);
|
sqliteSafetyOff(db);
|
||||||
if( iDb==0 ){
|
|
||||||
rc = sqlite_exec(db,
|
/* The following SQL will read the schema from the master tables.
|
||||||
db->file_format>=2 ? init_script : older_init_script,
|
** The first version works with SQLite file formats 2 or greater.
|
||||||
sqliteInitCallback, &initData, 0);
|
** The second version is for format 1 files.
|
||||||
}else{
|
**
|
||||||
char *zSql = 0;
|
** Beginning with file format 2, the rowid for new table entries
|
||||||
|
** (including entries in sqlite_master) is an increasing integer.
|
||||||
|
** So for file format 2 and later, we can play back sqlite_master
|
||||||
|
** and all the CREATE statements will appear in the right order.
|
||||||
|
** But with file format 1, table entries were random and so we
|
||||||
|
** have to make sure the CREATE TABLEs occur before their corresponding
|
||||||
|
** CREATE INDEXs. (We don't have to deal with CREATE VIEW or
|
||||||
|
** CREATE TRIGGER in file format 1 because those constructs did
|
||||||
|
** not exist then.)
|
||||||
|
*/
|
||||||
|
if( db->file_format>=2 ){
|
||||||
sqliteSetString(&zSql,
|
sqliteSetString(&zSql,
|
||||||
"SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
|
"SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
|
||||||
db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
|
db->aDb[iDb].zName, "\".", zMasterName, (char*)0);
|
||||||
rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
|
}else{
|
||||||
sqliteFree(zSql);
|
sqliteSetString(&zSql,
|
||||||
|
"SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
|
||||||
|
db->aDb[iDb].zName, "\".", zMasterName,
|
||||||
|
" WHERE type IN ('table', 'index')"
|
||||||
|
" ORDER BY CASE type WHEN 'table' THEN 0 ELSE 1 END", (char*)0);
|
||||||
}
|
}
|
||||||
|
rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
|
||||||
|
|
||||||
|
sqliteFree(zSql);
|
||||||
sqliteSafetyOn(db);
|
sqliteSafetyOn(db);
|
||||||
sqliteBtreeCloseCursor(curMain);
|
sqliteBtreeCloseCursor(curMain);
|
||||||
if( sqlite_malloc_failed ){
|
if( sqlite_malloc_failed ){
|
||||||
|
@ -361,9 +357,6 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
DbSetProperty(db, iDb, DB_SchemaLoaded);
|
DbSetProperty(db, iDb, DB_SchemaLoaded);
|
||||||
if( iDb==0 ){
|
|
||||||
DbSetProperty(db, 1, DB_SchemaLoaded);
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
sqliteResetInternalSchema(db, iDb);
|
sqliteResetInternalSchema(db, iDb);
|
||||||
}
|
}
|
||||||
|
@ -391,13 +384,24 @@ int sqliteInit(sqlite *db, char **pzErrMsg){
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
db->init.busy = 1;
|
db->init.busy = 1;
|
||||||
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
|
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
|
||||||
if( DbHasProperty(db, i, DB_SchemaLoaded) ) continue;
|
if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
|
||||||
assert( i!=1 ); /* Should have been initialized together with 0 */
|
|
||||||
rc = sqliteInitOne(db, i, pzErrMsg);
|
rc = sqliteInitOne(db, i, pzErrMsg);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
sqliteResetInternalSchema(db, i);
|
sqliteResetInternalSchema(db, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Once all the other databases have been initialised, load the schema
|
||||||
|
** for the TEMP database. This is loaded last, as the TEMP database
|
||||||
|
** schema may contain references to objects in other databases.
|
||||||
|
*/
|
||||||
|
if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
|
||||||
|
rc = sqliteInitOne(db, 1, pzErrMsg);
|
||||||
|
if( rc ){
|
||||||
|
sqliteResetInternalSchema(db, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
db->init.busy = 0;
|
db->init.busy = 0;
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
db->flags |= SQLITE_Initialized;
|
db->flags |= SQLITE_Initialized;
|
||||||
|
|
|
@ -830,7 +830,7 @@ int sqliteOsTempFileName(char *zBuf){
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
"0123456789";
|
"0123456789";
|
||||||
int i, j;
|
int i, j;
|
||||||
char *zDir;
|
const char *zDir;
|
||||||
char zTempPath[SQLITE_TEMPNAME_SIZE];
|
char zTempPath[SQLITE_TEMPNAME_SIZE];
|
||||||
if( sqlite_temp_directory==0 ){
|
if( sqlite_temp_directory==0 ){
|
||||||
GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);
|
GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);
|
||||||
|
@ -1116,6 +1116,10 @@ int sqliteOsSeek(OsFile *id, off_t offset){
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SQLITE_NOSYNC
|
||||||
|
# define fsync(X) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Make sure all writes to a particular file are committed to disk.
|
** Make sure all writes to a particular file are committed to disk.
|
||||||
**
|
**
|
||||||
|
|
|
@ -227,6 +227,7 @@ static int vxprintf(
|
||||||
int nsd; /* Number of significant digits returned */
|
int nsd; /* Number of significant digits returned */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
func(arg,"",0);
|
||||||
count = length = 0;
|
count = length = 0;
|
||||||
bufpt = 0;
|
bufpt = 0;
|
||||||
for(; (c=(*fmt))!=0; ++fmt){
|
for(; (c=(*fmt))!=0; ++fmt){
|
||||||
|
@ -673,9 +674,11 @@ static void mout(void *arg, const char *zNewText, int nNewChar){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( pM->zText && nNewChar>0 ){
|
if( pM->zText ){
|
||||||
memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
|
if( nNewChar>0 ){
|
||||||
pM->nChar += nNewChar;
|
memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
|
||||||
|
pM->nChar += nNewChar;
|
||||||
|
}
|
||||||
pM->zText[pM->nChar] = 0;
|
pM->zText[pM->nChar] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,6 +364,30 @@ void sqliteAddKeyType(Vdbe *v, ExprList *pEList){
|
||||||
sqliteVdbeChangeP3(v, -1, zType, P3_DYNAMIC);
|
sqliteVdbeChangeP3(v, -1, zType, P3_DYNAMIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Add code to implement the OFFSET and LIMIT
|
||||||
|
*/
|
||||||
|
static void codeLimiter(
|
||||||
|
Vdbe *v, /* Generate code into this VM */
|
||||||
|
Select *p, /* The SELECT statement being coded */
|
||||||
|
int iContinue, /* Jump here to skip the current record */
|
||||||
|
int iBreak, /* Jump here to end the loop */
|
||||||
|
int nPop /* Number of times to pop stack when jumping */
|
||||||
|
){
|
||||||
|
if( p->iOffset>=0 ){
|
||||||
|
int addr = sqliteVdbeCurrentAddr(v) + 2;
|
||||||
|
if( nPop>0 ) addr++;
|
||||||
|
sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr);
|
||||||
|
if( nPop>0 ){
|
||||||
|
sqliteVdbeAddOp(v, OP_Pop, nPop, 0);
|
||||||
|
}
|
||||||
|
sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
|
||||||
|
}
|
||||||
|
if( p->iLimit>=0 ){
|
||||||
|
sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This routine generates the code for the inside of the inner loop
|
** This routine generates the code for the inside of the inner loop
|
||||||
** of a SELECT.
|
** of a SELECT.
|
||||||
|
@ -388,6 +412,7 @@ static int selectInnerLoop(
|
||||||
){
|
){
|
||||||
Vdbe *v = pParse->pVdbe;
|
Vdbe *v = pParse->pVdbe;
|
||||||
int i;
|
int i;
|
||||||
|
int hasDistinct; /* True if the DISTINCT keyword is present */
|
||||||
|
|
||||||
if( v==0 ) return 0;
|
if( v==0 ) return 0;
|
||||||
assert( pEList!=0 );
|
assert( pEList!=0 );
|
||||||
|
@ -395,15 +420,9 @@ static int selectInnerLoop(
|
||||||
/* If there was a LIMIT clause on the SELECT statement, then do the check
|
/* If there was a LIMIT clause on the SELECT statement, then do the check
|
||||||
** to see if this row should be output.
|
** to see if this row should be output.
|
||||||
*/
|
*/
|
||||||
if( pOrderBy==0 ){
|
hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
|
||||||
if( p->iOffset>=0 ){
|
if( pOrderBy==0 && !hasDistinct ){
|
||||||
int addr = sqliteVdbeCurrentAddr(v);
|
codeLimiter(v, p, iContinue, iBreak, 0);
|
||||||
sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr+2);
|
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
|
|
||||||
}
|
|
||||||
if( p->iLimit>=0 ){
|
|
||||||
sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pull the requested columns.
|
/* Pull the requested columns.
|
||||||
|
@ -423,7 +442,7 @@ static int selectInnerLoop(
|
||||||
** and this row has been seen before, then do not make this row
|
** and this row has been seen before, then do not make this row
|
||||||
** part of the result.
|
** part of the result.
|
||||||
*/
|
*/
|
||||||
if( distinct>=0 && pEList && pEList->nExpr>0 ){
|
if( hasDistinct ){
|
||||||
#if NULL_ALWAYS_DISTINCT
|
#if NULL_ALWAYS_DISTINCT
|
||||||
sqliteVdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqliteVdbeCurrentAddr(v)+7);
|
sqliteVdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqliteVdbeCurrentAddr(v)+7);
|
||||||
#endif
|
#endif
|
||||||
|
@ -434,6 +453,9 @@ static int selectInnerLoop(
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
|
sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_PutStrKey, distinct, 0);
|
sqliteVdbeAddOp(v, OP_PutStrKey, distinct, 0);
|
||||||
|
if( pOrderBy==0 ){
|
||||||
|
codeLimiter(v, p, iContinue, iBreak, nColumn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( eDest ){
|
switch( eDest ){
|
||||||
|
@ -570,14 +592,7 @@ static void generateSortTail(
|
||||||
if( eDest==SRT_Sorter ) return;
|
if( eDest==SRT_Sorter ) return;
|
||||||
sqliteVdbeAddOp(v, OP_Sort, 0, 0);
|
sqliteVdbeAddOp(v, OP_Sort, 0, 0);
|
||||||
addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end1);
|
addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end1);
|
||||||
if( p->iOffset>=0 ){
|
codeLimiter(v, p, addr, end2, 1);
|
||||||
sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr+4);
|
|
||||||
sqliteVdbeAddOp(v, OP_Pop, 1, 0);
|
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
|
|
||||||
}
|
|
||||||
if( p->iLimit>=0 ){
|
|
||||||
sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, end2);
|
|
||||||
}
|
|
||||||
switch( eDest ){
|
switch( eDest ){
|
||||||
case SRT_Callback: {
|
case SRT_Callback: {
|
||||||
sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0);
|
sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0);
|
||||||
|
@ -810,8 +825,9 @@ Table *sqliteResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
|
||||||
}else{
|
}else{
|
||||||
char zBuf[30];
|
char zBuf[30];
|
||||||
sprintf(zBuf, "column%d", i+1);
|
sprintf(zBuf, "column%d", i+1);
|
||||||
pTab->aCol[i].zName = sqliteStrDup(zBuf);
|
aCol[i].zName = sqliteStrDup(zBuf);
|
||||||
}
|
}
|
||||||
|
sqliteDequote(aCol[i].zName);
|
||||||
}
|
}
|
||||||
pTab->iPKey = -1;
|
pTab->iPKey = -1;
|
||||||
return pTab;
|
return pTab;
|
||||||
|
@ -943,11 +959,11 @@ static int fillInColumnList(Parse *pParse, Select *p){
|
||||||
/* This expression is a "*" or a "TABLE.*" and needs to be
|
/* This expression is a "*" or a "TABLE.*" and needs to be
|
||||||
** expanded. */
|
** expanded. */
|
||||||
int tableSeen = 0; /* Set to 1 when TABLE matches */
|
int tableSeen = 0; /* Set to 1 when TABLE matches */
|
||||||
Token *pName; /* text of name of TABLE */
|
char *zTName; /* text of name of TABLE */
|
||||||
if( pE->op==TK_DOT && pE->pLeft ){
|
if( pE->op==TK_DOT && pE->pLeft ){
|
||||||
pName = &pE->pLeft->token;
|
zTName = sqliteTableNameFromToken(&pE->pLeft->token);
|
||||||
}else{
|
}else{
|
||||||
pName = 0;
|
zTName = 0;
|
||||||
}
|
}
|
||||||
for(i=0; i<pTabList->nSrc; i++){
|
for(i=0; i<pTabList->nSrc; i++){
|
||||||
Table *pTab = pTabList->a[i].pTab;
|
Table *pTab = pTabList->a[i].pTab;
|
||||||
|
@ -955,9 +971,8 @@ static int fillInColumnList(Parse *pParse, Select *p){
|
||||||
if( zTabName==0 || zTabName[0]==0 ){
|
if( zTabName==0 || zTabName[0]==0 ){
|
||||||
zTabName = pTab->zName;
|
zTabName = pTab->zName;
|
||||||
}
|
}
|
||||||
if( pName && (zTabName==0 || zTabName[0]==0 ||
|
if( zTName && (zTabName==0 || zTabName[0]==0 ||
|
||||||
sqliteStrNICmp(pName->z, zTabName, pName->n)!=0 ||
|
sqliteStrICmp(zTName, zTabName)!=0) ){
|
||||||
zTabName[pName->n]!=0) ){
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tableSeen = 1;
|
tableSeen = 1;
|
||||||
|
@ -1002,13 +1017,14 @@ static int fillInColumnList(Parse *pParse, Select *p){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( !tableSeen ){
|
if( !tableSeen ){
|
||||||
if( pName ){
|
if( zTName ){
|
||||||
sqliteErrorMsg(pParse, "no such table: %T", pName);
|
sqliteErrorMsg(pParse, "no such table: %s", zTName);
|
||||||
}else{
|
}else{
|
||||||
sqliteErrorMsg(pParse, "no tables specified");
|
sqliteErrorMsg(pParse, "no tables specified");
|
||||||
}
|
}
|
||||||
rc = 1;
|
rc = 1;
|
||||||
}
|
}
|
||||||
|
sqliteFree(zTName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqliteExprListDelete(pEList);
|
sqliteExprListDelete(pEList);
|
||||||
|
@ -1916,6 +1932,12 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
|
||||||
}else{
|
}else{
|
||||||
sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
|
sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
|
||||||
sqliteVdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum, pIdx->zName, P3_STATIC);
|
sqliteVdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum, pIdx->zName, P3_STATIC);
|
||||||
|
if( seekOp==OP_Rewind ){
|
||||||
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
|
sqliteVdbeAddOp(v, OP_MakeKey, 1, 0);
|
||||||
|
sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
|
||||||
|
seekOp = OP_MoveTo;
|
||||||
|
}
|
||||||
sqliteVdbeAddOp(v, seekOp, base+1, 0);
|
sqliteVdbeAddOp(v, seekOp, base+1, 0);
|
||||||
sqliteVdbeAddOp(v, OP_IdxRecno, base+1, 0);
|
sqliteVdbeAddOp(v, OP_IdxRecno, base+1, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Close, base+1, 0);
|
sqliteVdbeAddOp(v, OP_Close, base+1, 0);
|
||||||
|
|
|
@ -28,7 +28,11 @@ extern "C" {
|
||||||
/*
|
/*
|
||||||
** The version of the SQLite library.
|
** The version of the SQLite library.
|
||||||
*/
|
*/
|
||||||
#define SQLITE_VERSION "--VERS--"
|
#ifdef SQLITE_VERSION
|
||||||
|
# undef SQLITE_VERSION
|
||||||
|
#else
|
||||||
|
# define SQLITE_VERSION "--VERS--"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The version string is also compiled into the library so that a program
|
** The version string is also compiled into the library so that a program
|
||||||
|
@ -479,9 +483,23 @@ int sqlite_function_type(
|
||||||
int datatype /* The datatype for this function */
|
int datatype /* The datatype for this function */
|
||||||
);
|
);
|
||||||
#define SQLITE_NUMERIC (-1)
|
#define SQLITE_NUMERIC (-1)
|
||||||
#define SQLITE_TEXT (-2)
|
/* #define SQLITE_TEXT (-2) // See below */
|
||||||
#define SQLITE_ARGS (-3)
|
#define SQLITE_ARGS (-3)
|
||||||
|
|
||||||
|
/*
|
||||||
|
** SQLite version 3 defines SQLITE_TEXT differently. To allow both
|
||||||
|
** version 2 and version 3 to be included, undefine them both if a
|
||||||
|
** conflict is seen. Define SQLITE2_TEXT to be the version 2 value.
|
||||||
|
*/
|
||||||
|
#ifdef SQLITE_TEXT
|
||||||
|
# undef SQLITE_TEXT
|
||||||
|
#else
|
||||||
|
# define SQLITE_TEXT (-2)
|
||||||
|
#endif
|
||||||
|
#define SQLITE2_TEXT (-2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The user function implementations call one of the following four routines
|
** The user function implementations call one of the following four routines
|
||||||
** in order to return their results. The first parameter to each of these
|
** in order to return their results. The first parameter to each of these
|
||||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
||||||
/*
|
/*
|
||||||
** The version of the SQLite library.
|
** The version of the SQLite library.
|
||||||
*/
|
*/
|
||||||
#define SQLITE_VERSION "2.8.11"
|
#define SQLITE_VERSION "2.8.16"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The version string is also compiled into the library so that a program
|
** The version string is also compiled into the library so that a program
|
||||||
|
|
|
@ -102,6 +102,9 @@
|
||||||
#ifndef UINT16_TYPE
|
#ifndef UINT16_TYPE
|
||||||
# define UINT16_TYPE unsigned short int
|
# define UINT16_TYPE unsigned short int
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef INT16_TYPE
|
||||||
|
# define INT16_TYPE short int
|
||||||
|
#endif
|
||||||
#ifndef UINT8_TYPE
|
#ifndef UINT8_TYPE
|
||||||
# define UINT8_TYPE unsigned char
|
# define UINT8_TYPE unsigned char
|
||||||
#endif
|
#endif
|
||||||
|
@ -117,6 +120,7 @@
|
||||||
#endif
|
#endif
|
||||||
typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
|
typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
|
||||||
typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
|
typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
|
||||||
|
typedef INT16_TYPE i16; /* 2-byte signed integer */
|
||||||
typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
|
typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
|
||||||
typedef UINT8_TYPE i8; /* 1-byte signed integer */
|
typedef UINT8_TYPE i8; /* 1-byte signed integer */
|
||||||
typedef INTPTR_TYPE ptr; /* Big enough to hold a pointer */
|
typedef INTPTR_TYPE ptr; /* Big enough to hold a pointer */
|
||||||
|
@ -762,8 +766,8 @@ struct IdList {
|
||||||
** now be identified by a database name, a dot, then the table name: ID.ID.
|
** now be identified by a database name, a dot, then the table name: ID.ID.
|
||||||
*/
|
*/
|
||||||
struct SrcList {
|
struct SrcList {
|
||||||
u16 nSrc; /* Number of tables or subqueries in the FROM clause */
|
i16 nSrc; /* Number of tables or subqueries in the FROM clause */
|
||||||
u16 nAlloc; /* Number of entries allocated in a[] below */
|
i16 nAlloc; /* Number of entries allocated in a[] below */
|
||||||
struct SrcList_item {
|
struct SrcList_item {
|
||||||
char *zDatabase; /* Name of database holding this table */
|
char *zDatabase; /* Name of database holding this table */
|
||||||
char *zName; /* Name of the table */
|
char *zName; /* Name of the table */
|
||||||
|
|
|
@ -504,14 +504,14 @@ int sqliteStrICmp(const char *zLeft, const char *zRight){
|
||||||
a = (unsigned char *)zLeft;
|
a = (unsigned char *)zLeft;
|
||||||
b = (unsigned char *)zRight;
|
b = (unsigned char *)zRight;
|
||||||
while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
|
while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
|
||||||
return *a - *b;
|
return UpperToLower[*a] - UpperToLower[*b];
|
||||||
}
|
}
|
||||||
int sqliteStrNICmp(const char *zLeft, const char *zRight, int N){
|
int sqliteStrNICmp(const char *zLeft, const char *zRight, int N){
|
||||||
register unsigned char *a, *b;
|
register unsigned char *a, *b;
|
||||||
a = (unsigned char *)zLeft;
|
a = (unsigned char *)zLeft;
|
||||||
b = (unsigned char *)zRight;
|
b = (unsigned char *)zRight;
|
||||||
while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
|
while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
|
||||||
return N<0 ? 0 : *a - *b;
|
return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -163,24 +163,6 @@ static int vacuumCallback1(void *pArg, int argc, char **argv, char **NotUsed){
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** This callback is used to transfer PRAGMA settings from one database
|
|
||||||
** to the other. The value in argv[0] should be passed to a pragma
|
|
||||||
** identified by ((vacuumStruct*)pArg)->zPragma.
|
|
||||||
*/
|
|
||||||
static int vacuumCallback3(void *pArg, int argc, char **argv, char **NotUsed){
|
|
||||||
vacuumStruct *p = (vacuumStruct*)pArg;
|
|
||||||
char zBuf[200];
|
|
||||||
assert( argc==1 );
|
|
||||||
if( argv==0 ) return 0;
|
|
||||||
assert( argv[0]!=0 );
|
|
||||||
assert( strlen(p->zPragma)<100 );
|
|
||||||
assert( strlen(argv[0])<30 );
|
|
||||||
sprintf(zBuf,"PRAGMA %s=%s;", p->zPragma, argv[0]);
|
|
||||||
p->rc = execsql(p->pzErrMsg, p->dbNew, zBuf);
|
|
||||||
return p->rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Generate a random name of 20 character in length.
|
** Generate a random name of 20 character in length.
|
||||||
*/
|
*/
|
||||||
|
@ -226,14 +208,6 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
|
||||||
char *zErrMsg; /* Error message */
|
char *zErrMsg; /* Error message */
|
||||||
vacuumStruct sVac; /* Information passed to callbacks */
|
vacuumStruct sVac; /* Information passed to callbacks */
|
||||||
|
|
||||||
/* These are all of the pragmas that need to be transferred over
|
|
||||||
** to the new database */
|
|
||||||
static const char *zPragma[] = {
|
|
||||||
"default_synchronous",
|
|
||||||
"default_cache_size",
|
|
||||||
/* "default_temp_store", */
|
|
||||||
};
|
|
||||||
|
|
||||||
if( db->flags & SQLITE_InTrans ){
|
if( db->flags & SQLITE_InTrans ){
|
||||||
sqliteSetString(pzErrMsg, "cannot VACUUM from within a transaction",
|
sqliteSetString(pzErrMsg, "cannot VACUUM from within a transaction",
|
||||||
(char*)0);
|
(char*)0);
|
||||||
|
@ -283,13 +257,6 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
|
||||||
sVac.dbOld = db;
|
sVac.dbOld = db;
|
||||||
sVac.dbNew = dbNew;
|
sVac.dbNew = dbNew;
|
||||||
sVac.pzErrMsg = pzErrMsg;
|
sVac.pzErrMsg = pzErrMsg;
|
||||||
for(i=0; rc==SQLITE_OK && i<sizeof(zPragma)/sizeof(zPragma[0]); i++){
|
|
||||||
char zBuf[200];
|
|
||||||
assert( strlen(zPragma[i])<100 );
|
|
||||||
sprintf(zBuf, "PRAGMA %s;", zPragma[i]);
|
|
||||||
sVac.zPragma = zPragma[i];
|
|
||||||
rc = sqlite_exec(db, zBuf, vacuumCallback3, &sVac, &zErrMsg);
|
|
||||||
}
|
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = sqlite_exec(db,
|
rc = sqlite_exec(db,
|
||||||
"SELECT type, name, sql FROM sqlite_master "
|
"SELECT type, name, sql FROM sqlite_master "
|
||||||
|
@ -299,6 +266,17 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
|
||||||
"WHERE sql NOT NULL AND type=='view'",
|
"WHERE sql NOT NULL AND type=='view'",
|
||||||
vacuumCallback1, &sVac, &zErrMsg);
|
vacuumCallback1, &sVac, &zErrMsg);
|
||||||
}
|
}
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
int meta1[SQLITE_N_BTREE_META];
|
||||||
|
int meta2[SQLITE_N_BTREE_META];
|
||||||
|
sqliteBtreeGetMeta(db->aDb[0].pBt, meta1);
|
||||||
|
sqliteBtreeGetMeta(dbNew->aDb[0].pBt, meta2);
|
||||||
|
meta2[1] = meta1[1]+1;
|
||||||
|
meta2[3] = meta1[3];
|
||||||
|
meta2[4] = meta1[4];
|
||||||
|
meta2[6] = meta1[6];
|
||||||
|
rc = sqliteBtreeUpdateMeta(dbNew->aDb[0].pBt, meta2);
|
||||||
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = sqliteBtreeCopyFile(db->aDb[0].pBt, dbNew->aDb[0].pBt);
|
rc = sqliteBtreeCopyFile(db->aDb[0].pBt, dbNew->aDb[0].pBt);
|
||||||
sqlite_exec(db, "COMMIT", 0, 0, 0);
|
sqlite_exec(db, "COMMIT", 0, 0, 0);
|
||||||
|
|
|
@ -4545,6 +4545,10 @@ case OP_AggGet: {
|
||||||
pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
|
pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
|
||||||
pTos->flags |= MEM_Ephem;
|
pTos->flags |= MEM_Ephem;
|
||||||
}
|
}
|
||||||
|
if( pTos->flags & MEM_AggCtx ){
|
||||||
|
Release(pTos);
|
||||||
|
pTos->flags = MEM_Null;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4695,8 +4699,9 @@ case OP_SetNext: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
assert( pSet->prev );
|
if( pSet->prev ){
|
||||||
pSet->prev = sqliteHashNext(pSet->prev);
|
pSet->prev = sqliteHashNext(pSet->prev);
|
||||||
|
}
|
||||||
if( pSet->prev==0 ){
|
if( pSet->prev==0 ){
|
||||||
break;
|
break;
|
||||||
}else{
|
}else{
|
||||||
|
|
|
@ -46,7 +46,7 @@ struct ExprInfo {
|
||||||
typedef struct ExprMaskSet ExprMaskSet;
|
typedef struct ExprMaskSet ExprMaskSet;
|
||||||
struct ExprMaskSet {
|
struct ExprMaskSet {
|
||||||
int n; /* Number of assigned cursor values */
|
int n; /* Number of assigned cursor values */
|
||||||
int ix[32]; /* Cursor assigned to each bit */
|
int ix[31]; /* Cursor assigned to each bit */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -123,7 +123,9 @@ static int exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){
|
||||||
unsigned int mask = 0;
|
unsigned int mask = 0;
|
||||||
if( p==0 ) return 0;
|
if( p==0 ) return 0;
|
||||||
if( p->op==TK_COLUMN ){
|
if( p->op==TK_COLUMN ){
|
||||||
return getMask(pMaskSet, p->iTable);
|
mask = getMask(pMaskSet, p->iTable);
|
||||||
|
if( mask==0 ) mask = -1;
|
||||||
|
return mask;
|
||||||
}
|
}
|
||||||
if( p->pRight ){
|
if( p->pRight ){
|
||||||
mask = exprTableUsage(pMaskSet, p->pRight);
|
mask = exprTableUsage(pMaskSet, p->pRight);
|
||||||
|
@ -269,6 +271,35 @@ static Index *findSortingIndex(
|
||||||
return pMatch;
|
return pMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Disable a term in the WHERE clause. Except, do not disable the term
|
||||||
|
** if it controls a LEFT OUTER JOIN and it did not originate in the ON
|
||||||
|
** or USING clause of that join.
|
||||||
|
**
|
||||||
|
** Consider the term t2.z='ok' in the following queries:
|
||||||
|
**
|
||||||
|
** (1) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
|
||||||
|
** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
|
||||||
|
** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
|
||||||
|
**
|
||||||
|
** The t2.z='ok' is disabled in the in (2) because it did not originate
|
||||||
|
** in the ON clause. The term is disabled in (3) because it is not part
|
||||||
|
** of a LEFT OUTER JOIN. In (1), the term is not disabled.
|
||||||
|
**
|
||||||
|
** Disabling a term causes that term to not be tested in the inner loop
|
||||||
|
** of the join. Disabling is an optimization. We would get the correct
|
||||||
|
** results if nothing were ever disabled, but joins might run a little
|
||||||
|
** slower. The trick is to disable as much as we can without disabling
|
||||||
|
** too much. If we disabled in (1), we'd get the wrong answer.
|
||||||
|
** See ticket #813.
|
||||||
|
*/
|
||||||
|
static void disableTerm(WhereLevel *pLevel, Expr **ppExpr){
|
||||||
|
Expr *pExpr = *ppExpr;
|
||||||
|
if( pLevel->iLeftJoin==0 || ExprHasProperty(pExpr, EP_FromJoin) ){
|
||||||
|
*ppExpr = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Generate the beginning of the loop used for WHERE clause processing.
|
** Generate the beginning of the loop used for WHERE clause processing.
|
||||||
** The return value is a pointer to an (opaque) structure that contains
|
** The return value is a pointer to an (opaque) structure that contains
|
||||||
|
@ -736,7 +767,7 @@ WhereInfo *sqliteWhereBegin(
|
||||||
}else{
|
}else{
|
||||||
sqliteExprCode(pParse, aExpr[k].p->pLeft);
|
sqliteExprCode(pParse, aExpr[k].p->pLeft);
|
||||||
}
|
}
|
||||||
aExpr[k].p = 0;
|
disableTerm(pLevel, &aExpr[k].p);
|
||||||
cont = pLevel->cont = sqliteVdbeMakeLabel(v);
|
cont = pLevel->cont = sqliteVdbeMakeLabel(v);
|
||||||
sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk);
|
sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk);
|
||||||
haveKey = 0;
|
haveKey = 0;
|
||||||
|
@ -760,7 +791,7 @@ WhereInfo *sqliteWhereBegin(
|
||||||
){
|
){
|
||||||
if( pX->op==TK_EQ ){
|
if( pX->op==TK_EQ ){
|
||||||
sqliteExprCode(pParse, pX->pRight);
|
sqliteExprCode(pParse, pX->pRight);
|
||||||
aExpr[k].p = 0;
|
disableTerm(pLevel, &aExpr[k].p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( pX->op==TK_IN && nColumn==1 ){
|
if( pX->op==TK_IN && nColumn==1 ){
|
||||||
|
@ -777,7 +808,7 @@ WhereInfo *sqliteWhereBegin(
|
||||||
pLevel->inOp = OP_Next;
|
pLevel->inOp = OP_Next;
|
||||||
pLevel->inP1 = pX->iTable;
|
pLevel->inP1 = pX->iTable;
|
||||||
}
|
}
|
||||||
aExpr[k].p = 0;
|
disableTerm(pLevel, &aExpr[k].p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -787,7 +818,7 @@ WhereInfo *sqliteWhereBegin(
|
||||||
&& aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
|
&& aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
|
||||||
){
|
){
|
||||||
sqliteExprCode(pParse, aExpr[k].p->pLeft);
|
sqliteExprCode(pParse, aExpr[k].p->pLeft);
|
||||||
aExpr[k].p = 0;
|
disableTerm(pLevel, &aExpr[k].p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -854,7 +885,7 @@ WhereInfo *sqliteWhereBegin(
|
||||||
sqliteVdbeAddOp(v, OP_ForceInt,
|
sqliteVdbeAddOp(v, OP_ForceInt,
|
||||||
aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT, brk);
|
aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT, brk);
|
||||||
sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk);
|
sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk);
|
||||||
aExpr[k].p = 0;
|
disableTerm(pLevel, &aExpr[k].p);
|
||||||
}else{
|
}else{
|
||||||
sqliteVdbeAddOp(v, OP_Rewind, iCur, brk);
|
sqliteVdbeAddOp(v, OP_Rewind, iCur, brk);
|
||||||
}
|
}
|
||||||
|
@ -876,7 +907,7 @@ WhereInfo *sqliteWhereBegin(
|
||||||
}else{
|
}else{
|
||||||
testOp = OP_Gt;
|
testOp = OP_Gt;
|
||||||
}
|
}
|
||||||
aExpr[k].p = 0;
|
disableTerm(pLevel, &aExpr[k].p);
|
||||||
}
|
}
|
||||||
start = sqliteVdbeCurrentAddr(v);
|
start = sqliteVdbeCurrentAddr(v);
|
||||||
pLevel->op = OP_Next;
|
pLevel->op = OP_Next;
|
||||||
|
@ -931,7 +962,7 @@ WhereInfo *sqliteWhereBegin(
|
||||||
&& aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j]
|
&& aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j]
|
||||||
){
|
){
|
||||||
sqliteExprCode(pParse, aExpr[k].p->pRight);
|
sqliteExprCode(pParse, aExpr[k].p->pRight);
|
||||||
aExpr[k].p = 0;
|
disableTerm(pLevel, &aExpr[k].p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( aExpr[k].idxRight==iCur
|
if( aExpr[k].idxRight==iCur
|
||||||
|
@ -940,7 +971,7 @@ WhereInfo *sqliteWhereBegin(
|
||||||
&& aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
|
&& aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
|
||||||
){
|
){
|
||||||
sqliteExprCode(pParse, aExpr[k].p->pLeft);
|
sqliteExprCode(pParse, aExpr[k].p->pLeft);
|
||||||
aExpr[k].p = 0;
|
disableTerm(pLevel, &aExpr[k].p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -977,7 +1008,7 @@ WhereInfo *sqliteWhereBegin(
|
||||||
){
|
){
|
||||||
sqliteExprCode(pParse, pExpr->pRight);
|
sqliteExprCode(pParse, pExpr->pRight);
|
||||||
leFlag = pExpr->op==TK_LE;
|
leFlag = pExpr->op==TK_LE;
|
||||||
aExpr[k].p = 0;
|
disableTerm(pLevel, &aExpr[k].p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( aExpr[k].idxRight==iCur
|
if( aExpr[k].idxRight==iCur
|
||||||
|
@ -987,7 +1018,7 @@ WhereInfo *sqliteWhereBegin(
|
||||||
){
|
){
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
leFlag = pExpr->op==TK_GE;
|
leFlag = pExpr->op==TK_GE;
|
||||||
aExpr[k].p = 0;
|
disableTerm(pLevel, &aExpr[k].p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1036,7 +1067,7 @@ WhereInfo *sqliteWhereBegin(
|
||||||
){
|
){
|
||||||
sqliteExprCode(pParse, pExpr->pRight);
|
sqliteExprCode(pParse, pExpr->pRight);
|
||||||
geFlag = pExpr->op==TK_GE;
|
geFlag = pExpr->op==TK_GE;
|
||||||
aExpr[k].p = 0;
|
disableTerm(pLevel, &aExpr[k].p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( aExpr[k].idxRight==iCur
|
if( aExpr[k].idxRight==iCur
|
||||||
|
@ -1046,7 +1077,7 @@ WhereInfo *sqliteWhereBegin(
|
||||||
){
|
){
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
geFlag = pExpr->op==TK_LE;
|
geFlag = pExpr->op==TK_LE;
|
||||||
aExpr[k].p = 0;
|
disableTerm(pLevel, &aExpr[k].p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue