aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2020-01-08 13:08:52 +0000
committerdrh <drh@noemail.net>2020-01-08 13:08:52 +0000
commit19ca76af384cfbc05740f1a5e5f570127b5cec8e (patch)
treeb47dd8e2e2b5153e928d2e43ed0d9fb78e1b60e0 /src
parent2b1c2aad9f45a21e04d3420152779386b6cf7d33 (diff)
parent87969b2a1190584c09f8676e3a17c2acaa99227c (diff)
downloadsqlite-19ca76af384cfbc05740f1a5e5f570127b5cec8e.tar.gz
sqlite-19ca76af384cfbc05740f1a5e5f570127b5cec8e.zip
Merge recent changes from trunk.
FossilOrigin-Name: 5962921fceaf2ec645379a5f1d18e2c2c13abbf92cf64606caee69f45a21c500
Diffstat (limited to 'src')
-rw-r--r--src/btree.c4
-rw-r--r--src/select.c50
-rw-r--r--src/sqlite.h.in11
-rw-r--r--src/util.c1
-rw-r--r--src/vdbe.c2
5 files changed, 38 insertions, 30 deletions
diff --git a/src/btree.c b/src/btree.c
index 552fc6a32..8b229ed5e 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -2138,11 +2138,11 @@ static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){
*/
static Pgno btreePagecount(BtShared *pBt){
assert( (pBt->nPage & 0x80000000)==0 || CORRUPT_DB );
- return pBt->nPage & 0x7fffffff;
+ return pBt->nPage;
}
u32 sqlite3BtreeLastPage(Btree *p){
assert( sqlite3BtreeHoldsMutex(p) );
- return btreePagecount(p->pBt);
+ return btreePagecount(p->pBt) & 0x7fffffff;
}
/*
diff --git a/src/select.c b/src/select.c
index d6cd7c25e..34c476ff7 100644
--- a/src/select.c
+++ b/src/select.c
@@ -4146,15 +4146,28 @@ struct WhereConst {
/*
** Add a new entry to the pConst object. Except, do not add duplicate
-** pColumn entires.
+** pColumn entires. Also, do not add if doing so would not be appropriate.
+**
+** The caller guarantees the pColumn is a column and pValue is a constant.
+** This routine has to do some additional checks before completing the
+** insert.
*/
static void constInsert(
- WhereConst *pConst, /* The WhereConst into which we are inserting */
- Expr *pColumn, /* The COLUMN part of the constraint */
- Expr *pValue /* The VALUE part of the constraint */
+ WhereConst *pConst, /* The WhereConst into which we are inserting */
+ Expr *pColumn, /* The COLUMN part of the constraint */
+ Expr *pValue, /* The VALUE part of the constraint */
+ Expr *pExpr /* Overall expression: COLUMN=VALUE or VALUE=COLUMN */
){
int i;
assert( pColumn->op==TK_COLUMN );
+ assert( sqlite3ExprIsConstant(pValue) );
+
+ if( !ExprHasProperty(pValue, EP_FixedCol) && sqlite3ExprAffinity(pValue)!=0 ){
+ return;
+ }
+ if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){
+ return;
+ }
/* 2018-10-25 ticket [cf5ed20f]
** Make sure the same pColumn is not inserted more than once */
@@ -4174,7 +4187,9 @@ static void constInsert(
if( pConst->apExpr==0 ){
pConst->nConst = 0;
}else{
- if( ExprHasProperty(pValue, EP_FixedCol) ) pValue = pValue->pLeft;
+ if( ExprHasProperty(pValue, EP_FixedCol) ){
+ pValue = pValue->pLeft;
+ }
pConst->apExpr[pConst->nConst*2-2] = pColumn;
pConst->apExpr[pConst->nConst*2-1] = pValue;
}
@@ -4200,19 +4215,11 @@ static void findConstInWhere(WhereConst *pConst, Expr *pExpr){
pLeft = pExpr->pLeft;
assert( pRight!=0 );
assert( pLeft!=0 );
- if( pRight->op==TK_COLUMN
- && !ExprHasProperty(pRight, EP_FixedCol)
- && sqlite3ExprIsConstant(pLeft)
- && sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr))
- ){
- constInsert(pConst, pRight, pLeft);
- }else
- if( pLeft->op==TK_COLUMN
- && !ExprHasProperty(pLeft, EP_FixedCol)
- && sqlite3ExprIsConstant(pRight)
- && sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr))
- ){
- constInsert(pConst, pLeft, pRight);
+ if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pLeft) ){
+ constInsert(pConst,pRight,pLeft,pExpr);
+ }
+ if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pRight) ){
+ constInsert(pConst,pLeft,pRight,pExpr);
}
}
@@ -4248,10 +4255,9 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
** The WHERE-clause constant propagation optimization.
**
** If the WHERE clause contains terms of the form COLUMN=CONSTANT or
-** CONSTANT=COLUMN that must be tree (in other words, if the terms top-level
-** AND-connected terms that are not part of a ON clause from a LEFT JOIN)
-** then throughout the query replace all other occurrences of COLUMN
-** with CONSTANT within the WHERE clause.
+** CONSTANT=COLUMN that are top-level AND-connected terms that are not
+** part of a ON clause from a LEFT JOIN, then throughout the query
+** replace all other occurrences of COLUMN with CONSTANT.
**
** For example, the query:
**
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index cb572a329..48aedf438 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -5587,7 +5587,7 @@ void sqlite3_result_subtype(sqlite3_context*,unsigned int);
** <li> [SQLITE_UTF16_ALIGNED].
** </ul>)^
** ^The eTextRep argument determines the encoding of strings passed
-** to the collating function callback, xCallback.
+** to the collating function callback, xCompare.
** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
** force strings to be UTF16 with native byte order.
** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
@@ -5596,18 +5596,19 @@ void sqlite3_result_subtype(sqlite3_context*,unsigned int);
** ^The fourth argument, pArg, is an application data pointer that is passed
** through as the first argument to the collating function callback.
**
-** ^The fifth argument, xCallback, is a pointer to the collating function.
+** ^The fifth argument, xCompare, is a pointer to the collating function.
** ^Multiple collating functions can be registered using the same name but
** with different eTextRep parameters and SQLite will use whichever
** function requires the least amount of data transformation.
-** ^If the xCallback argument is NULL then the collating function is
+** ^If the xCompare argument is NULL then the collating function is
** deleted. ^When all collating functions having the same name are deleted,
** that collation is no longer usable.
**
** ^The collating function callback is invoked with a copy of the pArg
** application data pointer and with two strings in the encoding specified
-** by the eTextRep argument. The collating function must return an
-** integer that is negative, zero, or positive
+** by the eTextRep argument. The two integer parameters to the collating
+** function callback are the length of the two strings, in bytes. The collating
+** function must return an integer that is negative, zero, or positive
** if the first string is less than, equal to, or greater than the second,
** respectively. A collating function must always return the same answer
** given the same inputs. If two or more collating functions are registered
diff --git a/src/util.c b/src/util.c
index f7a993a76..88ac6d39f 100644
--- a/src/util.c
+++ b/src/util.c
@@ -411,6 +411,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
}else{
int i;
incr = 2;
+ length &= ~1;
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
testcase( enc==SQLITE_UTF16LE );
testcase( enc==SQLITE_UTF16BE );
diff --git a/src/vdbe.c b/src/vdbe.c
index 06a6d3230..14c83bd1f 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -499,7 +499,7 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){
}else{
c = 's';
}
- sqlite3_str_appendf(pStr, "%cx", c);
+ sqlite3_str_appendf(pStr, "%cx[", c);
for(i=0; i<25 && i<pMem->n; i++){
sqlite3_str_appendf(pStr, "%02X", ((int)pMem->z[i] & 0xFF));
}