mirror of
https://github.com/sqlite/sqlite.git
synced 2025-10-31 18:11:01 +03:00
Code simplifications and size reductions. (CVS 1983)
FossilOrigin-Name: cb631a135da92fd689ee40a8b7e2695a510eb765
This commit is contained in:
20
manifest
20
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Size\soptimizations\sin\svdbeapi.c.\s(CVS\s1982)
|
C Code\ssimplifications\sand\ssize\sreductions.\s(CVS\s1983)
|
||||||
D 2004-09-24T23:59:12
|
D 2004-09-25T13:12:15
|
||||||
F Makefile.in abdeb5bd9d017822691884935c320037c33f6ee6
|
F Makefile.in abdeb5bd9d017822691884935c320037c33f6ee6
|
||||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@@ -33,7 +33,7 @@ F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029
|
|||||||
F src/build.c c5ecf114af4ebc2963a03142b6bd6f2284ee35fc
|
F src/build.c c5ecf114af4ebc2963a03142b6bd6f2284ee35fc
|
||||||
F src/date.c eb8d5fa1a6d5cfc09031c8852d10ff742a94b15b
|
F src/date.c eb8d5fa1a6d5cfc09031c8852d10ff742a94b15b
|
||||||
F src/delete.c d862b383a9abc0b79f4588783c2619fe52d74ea7
|
F src/delete.c d862b383a9abc0b79f4588783c2619fe52d74ea7
|
||||||
F src/expr.c 16ccea21ffb60f32ce2a9dd56d6d2c2cfdb0f1c6
|
F src/expr.c f255c5c56c0371cb2955cbc2733621051e4f79f8
|
||||||
F src/func.c 1fbc5256639586573fd0e70814d6dcd8bc10afc1
|
F src/func.c 1fbc5256639586573fd0e70814d6dcd8bc10afc1
|
||||||
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
|
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
|
||||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||||
@@ -53,14 +53,14 @@ F src/os_win.c 9e2887825b1a32f0ceb1b73b93ffe29a112cd86f
|
|||||||
F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44
|
F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44
|
||||||
F src/pager.c 705a61117f05d7dd031762408f9a279834e88c3a
|
F src/pager.c 705a61117f05d7dd031762408f9a279834e88c3a
|
||||||
F src/pager.h 67739fe649f33be55dba522ca8a9cc4e42d14f71
|
F src/pager.h 67739fe649f33be55dba522ca8a9cc4e42d14f71
|
||||||
F src/parse.y 9389af67bd49b8e5c9d2968b3315a30565b4a200
|
F src/parse.y 93edda0f1e9b25bee7cdfb5bf624ae85f8e9e5c9
|
||||||
F src/pragma.c 5fb6647fda4c95edb08447a505e6c98c041e5b31
|
F src/pragma.c 5fb6647fda4c95edb08447a505e6c98c041e5b31
|
||||||
F src/printf.c 40770e1f553612d13dfc86d236086e69baa62fe1
|
F src/printf.c 40770e1f553612d13dfc86d236086e69baa62fe1
|
||||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
||||||
F src/select.c 13a4e6d0ca2bce8be60e26a499060524fef2e28c
|
F src/select.c 97c5f11b2b456dc6113454e592dbf03dc46e2b9d
|
||||||
F src/shell.c 0856973c2b94e22664bc43f398ba3fc22d5e080c
|
F src/shell.c 0856973c2b94e22664bc43f398ba3fc22d5e080c
|
||||||
F src/sqlite.h.in e29a526593b806f148017ed8bada760ada84cf2f
|
F src/sqlite.h.in e29a526593b806f148017ed8bada760ada84cf2f
|
||||||
F src/sqliteInt.h a7d334b2aca08de0c1cace3eebfabc129279c26f
|
F src/sqliteInt.h 581437ae245e5b8294bfc20c9a06a16bb6b3d281
|
||||||
F src/table.c 8168c6e824009f8485bff79fc60ea8fea6829b10
|
F src/table.c 8168c6e824009f8485bff79fc60ea8fea6829b10
|
||||||
F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008
|
F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008
|
||||||
F src/test1.c 1305825c29575ee55a1c8b98a191669fd78b6287
|
F src/test1.c 1305825c29575ee55a1c8b98a191669fd78b6287
|
||||||
@@ -80,7 +80,7 @@ F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b
|
|||||||
F src/vdbeapi.c 81ab9e84c55f5762f552904e6e5d309269b02017
|
F src/vdbeapi.c 81ab9e84c55f5762f552904e6e5d309269b02017
|
||||||
F src/vdbeaux.c dc3848209aee05b32636a9c1dd913a56ef8dac79
|
F src/vdbeaux.c dc3848209aee05b32636a9c1dd913a56ef8dac79
|
||||||
F src/vdbemem.c ef9ac7d32acfe4bce5c5b408b1294c8d9e0cdb56
|
F src/vdbemem.c ef9ac7d32acfe4bce5c5b408b1294c8d9e0cdb56
|
||||||
F src/where.c 5d573333c07f259c8d3b8423d82ba774b78b63a9
|
F src/where.c 04d3ee039d8e66c520e3b6bd5103dc3b8c3eb76b
|
||||||
F test/all.test 929bfa932b55e75c96fe2203f7650ba451c1862c
|
F test/all.test 929bfa932b55e75c96fe2203f7650ba451c1862c
|
||||||
F test/attach.test feb2ce54e78688df4c84553416d5aec3b2a0112e
|
F test/attach.test feb2ce54e78688df4c84553416d5aec3b2a0112e
|
||||||
F test/attach2.test 32ca2c1a5a347a7404219a11f9f84739a63d2582
|
F test/attach2.test 32ca2c1a5a347a7404219a11f9f84739a63d2582
|
||||||
@@ -247,7 +247,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
|
|||||||
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
||||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||||
P 8154d545e8ae3d22490b49ce4f327605883accaa
|
P b2f3d4bb8e24212d3cef7615c24da13f29c1440c
|
||||||
R 508b9be36c846738b3d04606ced87a41
|
R 7b7549a8227df9a562548ecaa05d3fba
|
||||||
U drh
|
U drh
|
||||||
Z da75a2e59bfb74cfb329258a940d48f5
|
Z e21d66c92b9e14b190cf7982b2d07af5
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
b2f3d4bb8e24212d3cef7615c24da13f29c1440c
|
cb631a135da92fd689ee40a8b7e2695a510eb765
|
||||||
27
src/expr.c
27
src/expr.c
@@ -12,24 +12,11 @@
|
|||||||
** This file contains routines used for analyzing expressions and
|
** This file contains routines used for analyzing expressions and
|
||||||
** for generating VDBE code that evaluates expressions in SQLite.
|
** for generating VDBE code that evaluates expressions in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: expr.c,v 1.164 2004/09/24 12:24:07 drh Exp $
|
** $Id: expr.c,v 1.165 2004/09/25 13:12:15 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
char const *sqlite3AffinityString(char affinity){
|
|
||||||
switch( affinity ){
|
|
||||||
case SQLITE_AFF_INTEGER: return "i";
|
|
||||||
case SQLITE_AFF_NUMERIC: return "n";
|
|
||||||
case SQLITE_AFF_TEXT: return "t";
|
|
||||||
case SQLITE_AFF_NONE: return "o";
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the 'affinity' of the expression pExpr if any.
|
** Return the 'affinity' of the expression pExpr if any.
|
||||||
**
|
**
|
||||||
@@ -184,7 +171,7 @@ static int codeCompare(
|
|||||||
){
|
){
|
||||||
int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull);
|
int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull);
|
||||||
CollSeq *p3 = binaryCompareCollSeq(pParse, pLeft, pRight);
|
CollSeq *p3 = binaryCompareCollSeq(pParse, pLeft, pRight);
|
||||||
return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (void *)p3, P3_COLLSEQ);
|
return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (void*)p3, P3_COLLSEQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -970,11 +957,9 @@ int sqlite3ExprResolveIds(
|
|||||||
** a column, use numeric affinity.
|
** a column, use numeric affinity.
|
||||||
*/
|
*/
|
||||||
int i;
|
int i;
|
||||||
char const *affStr;
|
|
||||||
if( !affinity ){
|
if( !affinity ){
|
||||||
affinity = SQLITE_AFF_NUMERIC;
|
affinity = SQLITE_AFF_NUMERIC;
|
||||||
}
|
}
|
||||||
affStr = sqlite3AffinityString(affinity);
|
|
||||||
keyInfo.aColl[0] = pExpr->pLeft->pColl;
|
keyInfo.aColl[0] = pExpr->pLeft->pColl;
|
||||||
|
|
||||||
/* Loop through each expression in <exprlist>. */
|
/* Loop through each expression in <exprlist>. */
|
||||||
@@ -993,7 +978,7 @@ int sqlite3ExprResolveIds(
|
|||||||
|
|
||||||
/* Evaluate the expression and insert it into the temp table */
|
/* Evaluate the expression and insert it into the temp table */
|
||||||
sqlite3ExprCode(pParse, pE2);
|
sqlite3ExprCode(pParse, pE2);
|
||||||
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, affStr, P3_STATIC);
|
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutStrKey, pExpr->iTable, 0);
|
sqlite3VdbeAddOp(v, OP_PutStrKey, pExpr->iTable, 0);
|
||||||
}
|
}
|
||||||
@@ -1374,13 +1359,13 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
}
|
}
|
||||||
case TK_IN: {
|
case TK_IN: {
|
||||||
int addr;
|
int addr;
|
||||||
char const *affStr;
|
char affinity;
|
||||||
|
|
||||||
/* Figure out the affinity to use to create a key from the results
|
/* Figure out the affinity to use to create a key from the results
|
||||||
** of the expression. affinityStr stores a static string suitable for
|
** of the expression. affinityStr stores a static string suitable for
|
||||||
** P3 of OP_MakeRecord.
|
** P3 of OP_MakeRecord.
|
||||||
*/
|
*/
|
||||||
affStr = sqlite3AffinityString(comparisonAffinity(pExpr));
|
affinity = comparisonAffinity(pExpr);
|
||||||
|
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
|
||||||
|
|
||||||
@@ -1393,7 +1378,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
|
sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7);
|
sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7);
|
||||||
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, affStr, P3_STATIC); /* addr + 4 */
|
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); /* addr + 4 */
|
||||||
sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7);
|
sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7);
|
||||||
sqlite3VdbeAddOp(v, OP_AddImm, -1, 0); /* addr + 6 */
|
sqlite3VdbeAddOp(v, OP_AddImm, -1, 0); /* addr + 6 */
|
||||||
|
|
||||||
|
|||||||
@@ -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.136 2004/09/07 16:19:54 drh Exp $
|
** @(#) $Id: parse.y,v 1.137 2004/09/25 13:12:16 drh Exp $
|
||||||
*/
|
*/
|
||||||
%token_prefix TK_
|
%token_prefix TK_
|
||||||
%token_type {Token}
|
%token_type {Token}
|
||||||
@@ -140,7 +140,7 @@ id(A) ::= ID(X). {A = X;}
|
|||||||
%left OR.
|
%left OR.
|
||||||
%left AND.
|
%left AND.
|
||||||
%right NOT.
|
%right NOT.
|
||||||
%left EQ NE ISNULL NOTNULL IS LIKE GLOB BETWEEN IN.
|
%left ISNULL NOTNULL IS LIKE GLOB BETWEEN IN NE EQ.
|
||||||
%left GT GE LT LE.
|
%left GT GE LT LE.
|
||||||
%left BITAND BITOR LSHIFT RSHIFT.
|
%left BITAND BITOR LSHIFT RSHIFT.
|
||||||
%left PLUS MINUS.
|
%left PLUS MINUS.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** to handle SELECT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: select.c,v 1.209 2004/09/19 02:15:26 drh Exp $
|
** $Id: select.c,v 1.210 2004/09/25 13:12:16 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -483,8 +483,7 @@ static int selectInnerLoop(
|
|||||||
char const *affStr;
|
char const *affStr;
|
||||||
char aff = (iParm>>16)&0xFF;
|
char aff = (iParm>>16)&0xFF;
|
||||||
aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff);
|
aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff);
|
||||||
affStr = sqlite3AffinityString(aff);
|
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &aff, 1);
|
||||||
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, affStr, P3_STATIC);
|
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
|
sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.322 2004/09/19 02:15:26 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.323 2004/09/25 13:12:16 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -1372,7 +1372,6 @@ char sqlite3AffinityType(const char *, int);
|
|||||||
void sqlite3IndexAffinityStr(Vdbe *, Index *);
|
void sqlite3IndexAffinityStr(Vdbe *, Index *);
|
||||||
void sqlite3TableAffinityStr(Vdbe *, Table *);
|
void sqlite3TableAffinityStr(Vdbe *, Table *);
|
||||||
char sqlite3CompareAffinity(Expr *pExpr, char aff2);
|
char sqlite3CompareAffinity(Expr *pExpr, char aff2);
|
||||||
char const *sqlite3AffinityString(char affinity);
|
|
||||||
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
|
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
|
||||||
char sqlite3ExprAffinity(Expr *pExpr);
|
char sqlite3ExprAffinity(Expr *pExpr);
|
||||||
int sqlite3atoi64(const char*, i64*);
|
int sqlite3atoi64(const char*, i64*);
|
||||||
|
|||||||
178
src/where.c
178
src/where.c
@@ -12,7 +12,7 @@
|
|||||||
** This module contains C code that generates VDBE code used to process
|
** This module contains C code that generates VDBE code used to process
|
||||||
** the WHERE clause of SQL statements.
|
** the WHERE clause of SQL statements.
|
||||||
**
|
**
|
||||||
** $Id: where.c,v 1.114 2004/09/19 02:15:26 drh Exp $
|
** $Id: where.c,v 1.115 2004/09/25 13:12:16 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -357,6 +357,52 @@ static void disableTerm(WhereLevel *pLevel, Expr **ppExpr){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Generate code that builds a probe for an index. Details:
|
||||||
|
**
|
||||||
|
** * Check the top nColumn entries on the stack. If any
|
||||||
|
** of those entries are NULL, jump immediately to brk,
|
||||||
|
** which is the loop exit, since no index entry will match
|
||||||
|
** if any part of the key is NULL.
|
||||||
|
**
|
||||||
|
** * Construct a probe entry from the top nColumn entries in
|
||||||
|
** the stack with affinities appropriate for index pIdx.
|
||||||
|
*/
|
||||||
|
static void buildIndexProbe(Vdbe *v, int nColumn, int brk, Index *pIdx){
|
||||||
|
sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
|
||||||
|
sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
|
||||||
|
sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
|
||||||
|
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||||
|
sqlite3IndexAffinityStr(v, pIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Generate code for an equality term of the WHERE clause. An equality
|
||||||
|
** term can be either X=expr or X IN (...). pTerm is the X.
|
||||||
|
*/
|
||||||
|
static void codeEqualityTerm(
|
||||||
|
Parse *pParse, /* The parsing context */
|
||||||
|
ExprInfo *pTerm, /* The term of the WHERE clause to be coded */
|
||||||
|
int brk, /* Jump here to abandon the loop */
|
||||||
|
WhereLevel *pLevel /* When level of the FROM clause we are working on */
|
||||||
|
){
|
||||||
|
Expr *pX = pTerm->p;
|
||||||
|
if( pX->op!=TK_IN ){
|
||||||
|
assert( pX->op==TK_EQ );
|
||||||
|
sqlite3ExprCode(pParse, pX->pRight);
|
||||||
|
}else{
|
||||||
|
int iTab = pX->iTable;
|
||||||
|
Vdbe *v = pParse->pVdbe;
|
||||||
|
sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk);
|
||||||
|
sqlite3VdbeAddOp(v, OP_KeyAsData, iTab, 1);
|
||||||
|
pLevel->inP2 = sqlite3VdbeAddOp(v, OP_IdxColumn, iTab, 0);
|
||||||
|
pLevel->inOp = OP_Next;
|
||||||
|
pLevel->inP1 = iTab;
|
||||||
|
}
|
||||||
|
disableTerm(pLevel, &pTerm->p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** 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
|
||||||
@@ -539,6 +585,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
loopMask = 0;
|
loopMask = 0;
|
||||||
for(i=0; i<pTabList->nSrc && i<ARRAYSIZE(iDirectEq); i++){
|
for(i=0; i<pTabList->nSrc && i<ARRAYSIZE(iDirectEq); i++){
|
||||||
int j;
|
int j;
|
||||||
|
WhereLevel *pLevel = &pWInfo->a[i];
|
||||||
int iCur = pTabList->a[i].iCursor; /* The cursor for this table */
|
int iCur = pTabList->a[i].iCursor; /* The cursor for this table */
|
||||||
int mask = getMask(&maskSet, iCur); /* Cursor mask for this table */
|
int mask = getMask(&maskSet, iCur); /* Cursor mask for this table */
|
||||||
Table *pTab = pTabList->a[i].pTab;
|
Table *pTab = pTabList->a[i].pTab;
|
||||||
@@ -554,7 +601,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
**
|
**
|
||||||
** (Added:) Treat ROWID IN expr like ROWID=expr.
|
** (Added:) Treat ROWID IN expr like ROWID=expr.
|
||||||
*/
|
*/
|
||||||
pWInfo->a[i].iCur = -1;
|
pLevel->iCur = -1;
|
||||||
iDirectEq[i] = -1;
|
iDirectEq[i] = -1;
|
||||||
iDirectLt[i] = -1;
|
iDirectLt[i] = -1;
|
||||||
iDirectGt[i] = -1;
|
iDirectGt[i] = -1;
|
||||||
@@ -574,7 +621,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
}
|
}
|
||||||
if( iDirectEq[i]>=0 ){
|
if( iDirectEq[i]>=0 ){
|
||||||
loopMask |= mask;
|
loopMask |= mask;
|
||||||
pWInfo->a[i].pIdx = 0;
|
pLevel->pIdx = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,8 +659,8 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
|
|
||||||
if( pIdx->nColumn>32 ) continue; /* Ignore indices too many columns */
|
if( pIdx->nColumn>32 ) continue; /* Ignore indices too many columns */
|
||||||
for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){
|
for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){
|
||||||
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pTerm->p->pLeft);
|
|
||||||
Expr *pX = pTerm->p;
|
Expr *pX = pTerm->p;
|
||||||
|
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pX->pLeft);
|
||||||
if( !pColl && pX->pRight ){
|
if( !pColl && pX->pRight ){
|
||||||
pColl = sqlite3ExprCollSeq(pParse, pX->pRight);
|
pColl = sqlite3ExprCollSeq(pParse, pX->pRight);
|
||||||
}
|
}
|
||||||
@@ -679,12 +726,12 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
bestScore = score;
|
bestScore = score;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pWInfo->a[i].pIdx = pBestIdx;
|
pLevel->pIdx = pBestIdx;
|
||||||
pWInfo->a[i].score = bestScore;
|
pLevel->score = bestScore;
|
||||||
pWInfo->a[i].bRev = 0;
|
pLevel->bRev = 0;
|
||||||
loopMask |= mask;
|
loopMask |= mask;
|
||||||
if( pBestIdx ){
|
if( pBestIdx ){
|
||||||
pWInfo->a[i].iCur = pParse->nTab++;
|
pLevel->iCur = pParse->nTab++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,31 +813,18 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
|
|
||||||
pIdx = pLevel->pIdx;
|
pIdx = pLevel->pIdx;
|
||||||
pLevel->inOp = OP_Noop;
|
pLevel->inOp = OP_Noop;
|
||||||
if( i<ARRAYSIZE(iDirectEq) && iDirectEq[i]>=0 ){
|
if( i<ARRAYSIZE(iDirectEq) && (k = iDirectEq[i])>=0 ){
|
||||||
/* Case 1: We can directly reference a single row using an
|
/* Case 1: We can directly reference a single row using an
|
||||||
** equality comparison against the ROWID field. Or
|
** equality comparison against the ROWID field. Or
|
||||||
** we reference multiple rows using a "rowid IN (...)"
|
** we reference multiple rows using a "rowid IN (...)"
|
||||||
** construct.
|
** construct.
|
||||||
*/
|
*/
|
||||||
Expr *pX;
|
|
||||||
k = iDirectEq[i];
|
|
||||||
assert( k<nExpr );
|
assert( k<nExpr );
|
||||||
pTerm = &aExpr[k];
|
pTerm = &aExpr[k];
|
||||||
assert( pTerm->p!=0 );
|
assert( pTerm->p!=0 );
|
||||||
assert( pTerm->idxLeft==iCur || pTerm->idxRight==iCur );
|
|
||||||
brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
|
|
||||||
pX = pTerm->p;
|
|
||||||
assert( pTerm->idxLeft==iCur );
|
assert( pTerm->idxLeft==iCur );
|
||||||
if( pX->op!=TK_IN ){
|
brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
|
||||||
sqlite3ExprCode(pParse, pTerm->p->pRight);
|
codeEqualityTerm(pParse, pTerm, brk, pLevel);
|
||||||
}else{
|
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, pX->iTable, brk);
|
|
||||||
sqlite3VdbeAddOp(v, OP_KeyAsData, pX->iTable, 1);
|
|
||||||
pLevel->inP2 = sqlite3VdbeAddOp(v, OP_IdxColumn, pX->iTable, 0);
|
|
||||||
pLevel->inOp = OP_Next;
|
|
||||||
pLevel->inP1 = pX->iTable;
|
|
||||||
}
|
|
||||||
disableTerm(pLevel, &pTerm->p);
|
|
||||||
cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
|
cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
|
||||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 1, brk);
|
sqlite3VdbeAddOp(v, OP_MustBeInt, 1, brk);
|
||||||
haveKey = 0;
|
haveKey = 0;
|
||||||
@@ -816,40 +850,16 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
&& pX->pLeft->iColumn==pIdx->aiColumn[j]
|
&& pX->pLeft->iColumn==pIdx->aiColumn[j]
|
||||||
){
|
){
|
||||||
char idxaff = pIdx->pTable->aCol[pX->pLeft->iColumn].affinity;
|
char idxaff = pIdx->pTable->aCol[pX->pLeft->iColumn].affinity;
|
||||||
if( sqlite3IndexAffinityOk(pTerm->p, idxaff) ){
|
if( sqlite3IndexAffinityOk(pX, idxaff) ){
|
||||||
if( pX->op==TK_EQ ){
|
codeEqualityTerm(pParse, pTerm, brk, pLevel);
|
||||||
sqlite3ExprCode(pParse, pX->pRight);
|
break;
|
||||||
disableTerm(pLevel, &pTerm->p);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert( pX->op==TK_IN && nColumn==1 );
|
|
||||||
if( pX->op==TK_IN && nColumn==1 ){
|
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, pX->iTable, brk);
|
|
||||||
sqlite3VdbeAddOp(v, OP_KeyAsData, pX->iTable, 1);
|
|
||||||
pLevel->inP2 = sqlite3VdbeAddOp(v, OP_IdxColumn, pX->iTable, 0);
|
|
||||||
pLevel->inOp = OP_Next;
|
|
||||||
pLevel->inP1 = pX->iTable;
|
|
||||||
disableTerm(pLevel, &pTerm->p);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pLevel->iMem = pParse->nMem++;
|
pLevel->iMem = pParse->nMem++;
|
||||||
cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
|
cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
|
||||||
|
buildIndexProbe(v, nColumn, brk, pIdx);
|
||||||
/* At this point, the top nColumn elements of the stack are the
|
|
||||||
** values of columns in the index we are using. Check to see if
|
|
||||||
** any of these values are NULL. If they are, they will not match any
|
|
||||||
** index entries, so skip immediately to the next iteration of the loop */
|
|
||||||
sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
|
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
|
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
|
|
||||||
|
|
||||||
/* Generate an index key from the top nColumn elements of the stack */
|
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
|
||||||
sqlite3IndexAffinityStr(v, pIdx);
|
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
|
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
|
||||||
|
|
||||||
/* Generate code (1) to move to the first matching element of the table.
|
/* Generate code (1) to move to the first matching element of the table.
|
||||||
@@ -890,30 +900,32 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
|
brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
|
||||||
cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
|
cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
|
||||||
if( iDirectGt[i]>=0 ){
|
if( iDirectGt[i]>=0 ){
|
||||||
|
Expr *pX;
|
||||||
k = iDirectGt[i];
|
k = iDirectGt[i];
|
||||||
assert( k<nExpr );
|
assert( k<nExpr );
|
||||||
pTerm = &aExpr[k];
|
pTerm = &aExpr[k];
|
||||||
assert( pTerm->p!=0 );
|
pX = pTerm->p;
|
||||||
|
assert( pX!=0 );
|
||||||
assert( pTerm->idxLeft==iCur );
|
assert( pTerm->idxLeft==iCur );
|
||||||
sqlite3ExprCode(pParse, pTerm->p->pRight);
|
sqlite3ExprCode(pParse, pX->pRight);
|
||||||
sqlite3VdbeAddOp(v, OP_ForceInt,
|
sqlite3VdbeAddOp(v, OP_ForceInt, pX->op==TK_LT || pX->op==TK_GT, brk);
|
||||||
pTerm->p->op==TK_LT || pTerm->p->op==TK_GT, brk);
|
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, brk);
|
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, brk);
|
||||||
disableTerm(pLevel, &pTerm->p);
|
disableTerm(pLevel, &pTerm->p);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, iCur, brk);
|
sqlite3VdbeAddOp(v, OP_Rewind, iCur, brk);
|
||||||
}
|
}
|
||||||
if( iDirectLt[i]>=0 ){
|
if( iDirectLt[i]>=0 ){
|
||||||
|
Expr *pX;
|
||||||
k = iDirectLt[i];
|
k = iDirectLt[i];
|
||||||
assert( k<nExpr );
|
assert( k<nExpr );
|
||||||
pTerm = &aExpr[k];
|
pTerm = &aExpr[k];
|
||||||
assert( pTerm->p!=0 );
|
pX = pTerm->p;
|
||||||
|
assert( pX!=0 );
|
||||||
assert( pTerm->idxLeft==iCur );
|
assert( pTerm->idxLeft==iCur );
|
||||||
sqlite3ExprCode(pParse, pTerm->p->pRight);
|
sqlite3ExprCode(pParse, pX->pRight);
|
||||||
/* sqlite3VdbeAddOp(v, OP_MustBeInt, 0, sqlite3VdbeCurrentAddr(v)+1); */
|
|
||||||
pLevel->iMem = pParse->nMem++;
|
pLevel->iMem = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
||||||
if( pTerm->p->op==TK_LT || pTerm->p->op==TK_GT ){
|
if( pX->op==TK_LT || pX->op==TK_GT ){
|
||||||
testOp = OP_Ge;
|
testOp = OP_Ge;
|
||||||
}else{
|
}else{
|
||||||
testOp = OP_Gt;
|
testOp = OP_Gt;
|
||||||
@@ -965,14 +977,16 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
/* Evaluate the equality constraints
|
/* Evaluate the equality constraints
|
||||||
*/
|
*/
|
||||||
for(j=0; j<nEqColumn; j++){
|
for(j=0; j<nEqColumn; j++){
|
||||||
|
int iIdxCol = pIdx->aiColumn[j];
|
||||||
for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
|
for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
|
||||||
if( pTerm->p==0 ) continue;
|
Expr *pX = pTerm->p;
|
||||||
|
if( pX==0 ) continue;
|
||||||
if( pTerm->idxLeft==iCur
|
if( pTerm->idxLeft==iCur
|
||||||
&& pTerm->p->op==TK_EQ
|
&& pX->op==TK_EQ
|
||||||
&& (pTerm->prereqRight & loopMask)==pTerm->prereqRight
|
&& (pTerm->prereqRight & loopMask)==pTerm->prereqRight
|
||||||
&& pTerm->p->pLeft->iColumn==pIdx->aiColumn[j]
|
&& pX->pLeft->iColumn==iIdxCol
|
||||||
){
|
){
|
||||||
sqlite3ExprCode(pParse, pTerm->p->pRight);
|
sqlite3ExprCode(pParse, pX->pRight);
|
||||||
disableTerm(pLevel, &pTerm->p);
|
disableTerm(pLevel, &pTerm->p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1001,15 +1015,15 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
*/
|
*/
|
||||||
if( (score & 1)!=0 ){
|
if( (score & 1)!=0 ){
|
||||||
for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
|
for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
|
||||||
Expr *pExpr = pTerm->p;
|
Expr *pX = pTerm->p;
|
||||||
if( pExpr==0 ) continue;
|
if( pX==0 ) continue;
|
||||||
if( pTerm->idxLeft==iCur
|
if( pTerm->idxLeft==iCur
|
||||||
&& (pExpr->op==TK_LT || pExpr->op==TK_LE)
|
&& (pX->op==TK_LT || pX->op==TK_LE)
|
||||||
&& (pTerm->prereqRight & loopMask)==pTerm->prereqRight
|
&& (pTerm->prereqRight & loopMask)==pTerm->prereqRight
|
||||||
&& pExpr->pLeft->iColumn==pIdx->aiColumn[j]
|
&& pX->pLeft->iColumn==pIdx->aiColumn[j]
|
||||||
){
|
){
|
||||||
sqlite3ExprCode(pParse, pExpr->pRight);
|
sqlite3ExprCode(pParse, pX->pRight);
|
||||||
leFlag = pExpr->op==TK_LE;
|
leFlag = pX->op==TK_LE;
|
||||||
disableTerm(pLevel, &pTerm->p);
|
disableTerm(pLevel, &pTerm->p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1022,11 +1036,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
if( testOp!=OP_Noop ){
|
if( testOp!=OP_Noop ){
|
||||||
int nCol = nEqColumn + (score & 1);
|
int nCol = nEqColumn + (score & 1);
|
||||||
pLevel->iMem = pParse->nMem++;
|
pLevel->iMem = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_NotNull, -nCol, sqlite3VdbeCurrentAddr(v)+3);
|
buildIndexProbe(v, nCol, brk, pIdx);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, nCol, 0);
|
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
|
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, nCol, 0);
|
|
||||||
sqlite3IndexAffinityStr(v, pIdx);
|
|
||||||
if( pLevel->bRev ){
|
if( pLevel->bRev ){
|
||||||
int op = leFlag ? OP_MoveLe : OP_MoveLt;
|
int op = leFlag ? OP_MoveLe : OP_MoveLt;
|
||||||
sqlite3VdbeAddOp(v, op, pLevel->iCur, brk);
|
sqlite3VdbeAddOp(v, op, pLevel->iCur, brk);
|
||||||
@@ -1048,15 +1058,15 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
*/
|
*/
|
||||||
if( (score & 2)!=0 ){
|
if( (score & 2)!=0 ){
|
||||||
for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
|
for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
|
||||||
Expr *pExpr = pTerm->p;
|
Expr *pX = pTerm->p;
|
||||||
if( pExpr==0 ) continue;
|
if( pX==0 ) continue;
|
||||||
if( pTerm->idxLeft==iCur
|
if( pTerm->idxLeft==iCur
|
||||||
&& (pExpr->op==TK_GT || pExpr->op==TK_GE)
|
&& (pX->op==TK_GT || pX->op==TK_GE)
|
||||||
&& (pTerm->prereqRight & loopMask)==pTerm->prereqRight
|
&& (pTerm->prereqRight & loopMask)==pTerm->prereqRight
|
||||||
&& pExpr->pLeft->iColumn==pIdx->aiColumn[j]
|
&& pX->pLeft->iColumn==pIdx->aiColumn[j]
|
||||||
){
|
){
|
||||||
sqlite3ExprCode(pParse, pExpr->pRight);
|
sqlite3ExprCode(pParse, pX->pRight);
|
||||||
geFlag = pExpr->op==TK_GE;
|
geFlag = pX->op==TK_GE;
|
||||||
disableTerm(pLevel, &pTerm->p);
|
disableTerm(pLevel, &pTerm->p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1066,11 +1076,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
}
|
}
|
||||||
if( nEqColumn>0 || (score&2)!=0 ){
|
if( nEqColumn>0 || (score&2)!=0 ){
|
||||||
int nCol = nEqColumn + ((score&2)!=0);
|
int nCol = nEqColumn + ((score&2)!=0);
|
||||||
sqlite3VdbeAddOp(v, OP_NotNull, -nCol, sqlite3VdbeCurrentAddr(v)+3);
|
buildIndexProbe(v, nCol, brk, pIdx);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, nCol, 0);
|
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
|
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, nCol, 0);
|
|
||||||
sqlite3IndexAffinityStr(v, pIdx);
|
|
||||||
if( pLevel->bRev ){
|
if( pLevel->bRev ){
|
||||||
pLevel->iMem = pParse->nMem++;
|
pLevel->iMem = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user