| ︙ | | | ︙ | |
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
** the text of this file. Search for "Begin file sqlite3.h" to find the start
** of the embedded sqlite3.h header file.) Additional code files may be needed
** if you want a wrapper to interface SQLite with your choice of programming
** language. The code for the "sqlite3" command-line shell is also in a
** separate file. This file contains only code for the core SQLite library.
**
** The content in this amalgamation comes from Fossil check-in
** 7bf49e2c54c9f6f336416f01c0e76aaf70f1.
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
#ifndef SQLITE_PRIVATE
# define SQLITE_PRIVATE static
#endif
/************** Begin file sqliteInt.h ***************************************/
|
|
|
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
** the text of this file. Search for "Begin file sqlite3.h" to find the start
** of the embedded sqlite3.h header file.) Additional code files may be needed
** if you want a wrapper to interface SQLite with your choice of programming
** language. The code for the "sqlite3" command-line shell is also in a
** separate file. This file contains only code for the core SQLite library.
**
** The content in this amalgamation comes from Fossil check-in
** 69ec714b2d698acf9e37635256c01b233ce3.
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
#ifndef SQLITE_PRIVATE
# define SQLITE_PRIVATE static
#endif
/************** Begin file sqliteInt.h ***************************************/
|
| ︙ | | | ︙ | |
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
|
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.46.0"
#define SQLITE_VERSION_NUMBER 3046000
#define SQLITE_SOURCE_ID "2024-04-04 14:26:42 7bf49e2c54c9f6f336416f01c0e76aaf70f1e2f3fd612232e5a33ae5dabe0900"
/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
|
|
|
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
|
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.46.0"
#define SQLITE_VERSION_NUMBER 3046000
#define SQLITE_SOURCE_ID "2024-04-08 11:50:07 69ec714b2d698acf9e37635256c01b233ce32f22e8323e226441d5ddd948a940"
/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
|
| ︙ | | | ︙ | |
17830
17831
17832
17833
17834
17835
17836
17837
17838
17839
17840
17841
17842
17843
17844
|
#define SQLITE_OrderByIdxJoin 0x00000040 /* ORDER BY of joins via index */
#define SQLITE_Transitive 0x00000080 /* Transitive constraints */
#define SQLITE_OmitNoopJoin 0x00000100 /* Omit unused tables in joins */
#define SQLITE_CountOfView 0x00000200 /* The count-of-view optimization */
#define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */
#define SQLITE_Stat4 0x00000800 /* Use STAT4 data */
/* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */
#define SQLITE_PushDown 0x00001000 /* The push-down optimization */
#define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */
#define SQLITE_SkipScan 0x00004000 /* Skip-scans */
#define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */
#define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */
#define SQLITE_SeekScan 0x00020000 /* The OP_SeekScan optimization */
#define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */
/* TH3 expects this value ^^^^^^^^^^ to be 0x40000. Coordinate any change */
|
|
|
17830
17831
17832
17833
17834
17835
17836
17837
17838
17839
17840
17841
17842
17843
17844
|
#define SQLITE_OrderByIdxJoin 0x00000040 /* ORDER BY of joins via index */
#define SQLITE_Transitive 0x00000080 /* Transitive constraints */
#define SQLITE_OmitNoopJoin 0x00000100 /* Omit unused tables in joins */
#define SQLITE_CountOfView 0x00000200 /* The count-of-view optimization */
#define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */
#define SQLITE_Stat4 0x00000800 /* Use STAT4 data */
/* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */
#define SQLITE_PushDown 0x00001000 /* WHERE-clause push-down opt */
#define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */
#define SQLITE_SkipScan 0x00004000 /* Skip-scans */
#define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */
#define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */
#define SQLITE_SeekScan 0x00020000 /* The OP_SeekScan optimization */
#define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */
/* TH3 expects this value ^^^^^^^^^^ to be 0x40000. Coordinate any change */
|
| ︙ | | | ︙ | |
19504
19505
19506
19507
19508
19509
19510
19511
19512
19513
19514
19515
19516
19517
19518
19519
19520
19521
19522
|
#define SF_IncludeHidden 0x0020000 /* Include hidden columns in output */
#define SF_ComplexResult 0x0040000 /* Result contains subquery or function */
#define SF_WhereBegin 0x0080000 /* Really a WhereBegin() call. Debug Only */
#define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */
#define SF_View 0x0200000 /* SELECT statement is a view */
#define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */
#define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */
#define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */
#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */
#define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
#define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */
/* True if S exists and has SF_NestedFrom */
#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0)
/*
** The results of a SELECT can be distributed in several ways, as defined
** by one of the following macros. The "SRT" prefix means "SELECT Result
|
|
>
|
19504
19505
19506
19507
19508
19509
19510
19511
19512
19513
19514
19515
19516
19517
19518
19519
19520
19521
19522
19523
|
#define SF_IncludeHidden 0x0020000 /* Include hidden columns in output */
#define SF_ComplexResult 0x0040000 /* Result contains subquery or function */
#define SF_WhereBegin 0x0080000 /* Really a WhereBegin() call. Debug Only */
#define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */
#define SF_View 0x0200000 /* SELECT statement is a view */
#define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */
#define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */
#define SF_PushDown 0x1000000 /* Modified by WHERE-clause push-down opt */
#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */
#define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
#define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */
#define SF_Correlated 0x20000000 /* True if references the outer context */
/* True if S exists and has SF_NestedFrom */
#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0)
/*
** The results of a SELECT can be distributed in several ways, as defined
** by one of the following macros. The "SRT" prefix means "SELECT Result
|
| ︙ | | | ︙ | |
21005
21006
21007
21008
21009
21010
21011
21012
21013
21014
21015
21016
21017
21018
21019
21020
|
SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char*);
SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*);
SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse*,Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int);
SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*);
#endif
SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
|
<
|
|
21006
21007
21008
21009
21010
21011
21012
21013
21014
21015
21016
21017
21018
21019
21020
|
SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char*);
SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*);
SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse*,Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*);
#endif
SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
|
| ︙ | | | ︙ | |
107282
107283
107284
107285
107286
107287
107288
107289
107290
107291
107292
107293
107294
107295
|
&& cntTab>=1
&& pMatch
&& (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
&& sqlite3IsRowid(zCol)
&& ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom)
){
cnt = cntTab;
if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1;
pExpr->affExpr = SQLITE_AFF_INTEGER;
}
/*
** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z
** might refer to an result-set alias. This happens, for example, when
|
>
>
>
>
>
|
107282
107283
107284
107285
107286
107287
107288
107289
107290
107291
107292
107293
107294
107295
107296
107297
107298
107299
107300
|
&& cntTab>=1
&& pMatch
&& (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
&& sqlite3IsRowid(zCol)
&& ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom)
){
cnt = cntTab;
#if SQLITE_ALLOW_ROWID_IN_VIEW+0==2
if( pMatch->pTab!=0 && IsView(pMatch->pTab) ){
eNewExprOp = TK_NULL;
}
#endif
if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1;
pExpr->affExpr = SQLITE_AFF_INTEGER;
}
/*
** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z
** might refer to an result-set alias. This happens, for example, when
|
| ︙ | | | ︙ | |
107999
108000
108001
108002
108003
108004
108005
108006
108007
108008
108009
108010
108011
108012
108013
108014
108015
108016
108017
108018
108019
108020
|
testcase( pExpr->op==TK_IN );
if( ExprUseXSelect(pExpr) ){
int nRef = pNC->nRef;
testcase( pNC->ncFlags & NC_IsCheck );
testcase( pNC->ncFlags & NC_PartIdx );
testcase( pNC->ncFlags & NC_IdxExpr );
testcase( pNC->ncFlags & NC_GenCol );
if( pNC->ncFlags & NC_SelfRef ){
notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr);
}else{
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
}
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
ExprSetProperty(pExpr, EP_VarSelect);
}
pNC->ncFlags |= NC_Subquery;
}
break;
}
case TK_VARIABLE: {
testcase( pNC->ncFlags & NC_IsCheck );
|
>
>
|
108004
108005
108006
108007
108008
108009
108010
108011
108012
108013
108014
108015
108016
108017
108018
108019
108020
108021
108022
108023
108024
108025
108026
108027
|
testcase( pExpr->op==TK_IN );
if( ExprUseXSelect(pExpr) ){
int nRef = pNC->nRef;
testcase( pNC->ncFlags & NC_IsCheck );
testcase( pNC->ncFlags & NC_PartIdx );
testcase( pNC->ncFlags & NC_IdxExpr );
testcase( pNC->ncFlags & NC_GenCol );
assert( pExpr->x.pSelect );
if( pNC->ncFlags & NC_SelfRef ){
notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr);
}else{
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
}
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
ExprSetProperty(pExpr, EP_VarSelect);
pExpr->x.pSelect->selFlags |= SF_Correlated;
}
pNC->ncFlags |= NC_Subquery;
}
break;
}
case TK_VARIABLE: {
testcase( pNC->ncFlags & NC_IsCheck );
|
| ︙ | | | ︙ | |
111423
111424
111425
111426
111427
111428
111429
111430
111431
111432
111433
111434
111435
111436
111437
111438
111439
111440
111441
111442
111443
111444
111445
111446
111447
111448
111449
111450
111451
111452
111453
111454
111455
111456
111457
111458
111459
111460
111461
111462
111463
111464
111465
111466
111467
111468
111469
111470
111471
111472
111473
111474
111475
111476
111477
111478
111479
111480
111481
111482
111483
111484
111485
111486
111487
111488
111489
111490
111491
111492
111493
111494
111495
111496
111497
111498
111499
111500
111501
111502
111503
111504
111505
111506
111507
111508
111509
111510
111511
|
/* no break */ deliberate_fall_through
default:
testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail() disallows */
testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail() disallows */
return WRC_Continue;
}
}
static int exprIsConst(Parse *pParse, Expr *p, int initFlag, int iCur){
Walker w;
w.eCode = initFlag;
w.pParse = pParse;
w.xExprCallback = exprNodeIsConstant;
w.xSelectCallback = sqlite3SelectWalkFail;
#ifdef SQLITE_DEBUG
w.xSelectCallback2 = sqlite3SelectWalkAssert2;
#endif
w.u.iCur = iCur;
sqlite3WalkExpr(&w, p);
return w.eCode;
}
/*
** Walk an expression tree. Return non-zero if the expression is constant
** and 0 if it involves variables or function calls.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
**
** The pParse parameter may be NULL. But if it is NULL, there is no way
** to determine if function calls are constant or not, and hence all
** function calls will be considered to be non-constant. If pParse is
** not NULL, then a function call might be constant, depending on the
** function and on its parameters.
*/
SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse *pParse, Expr *p){
return exprIsConst(pParse, p, 1, 0);
}
/*
** Walk an expression tree. Return non-zero if
**
** (1) the expression is constant, and
** (2) the expression does originate in the ON or USING clause
** of a LEFT JOIN, and
** (3) the expression does not contain any EP_FixedCol TK_COLUMN
** operands created by the constant propagation optimization.
**
** When this routine returns true, it indicates that the expression
** can be added to the pParse->pConstExpr list and evaluated once when
** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce().
*/
static int sqlite3ExprIsConstantNotJoin(Parse *pParse, Expr *p){
return exprIsConst(pParse, p, 2, 0);
}
/*
** Walk an expression tree. Return non-zero if the expression is constant
** for any single row of the table with cursor iCur. In other words, the
** expression must not refer to any non-deterministic function nor any
** table other than iCur.
*/
SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
return exprIsConst(0, p, 3, iCur);
}
/*
** Check pExpr to see if it is an constraint on the single data source
** pSrc = &pSrcList->a[iSrc]. In other words, check to see if pExpr
** constrains pSrc but does not depend on any other tables or data
** sources anywhere else in the query. Return true (non-zero) if pExpr
** is a constraint on pSrc only.
**
** This is an optimization. False negatives will perhaps cause slower
** queries, but false positives will yield incorrect answers. So when in
** doubt, return 0.
**
** To be an single-source constraint, the following must be true:
**
** (1) pExpr cannot refer to any table other than pSrc->iCursor.
**
** (2) pExpr cannot use subqueries or non-deterministic functions.
**
** (3) pSrc cannot be part of the left operand for a RIGHT JOIN.
** (Is there some way to relax this constraint?)
**
** (4) If pSrc is the right operand of a LEFT JOIN, then...
** (4a) pExpr must come from an ON clause..
** (4b) and specifically the ON clause associated with the LEFT JOIN.
|
|
<
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
|
111430
111431
111432
111433
111434
111435
111436
111437
111438
111439
111440
111441
111442
111443
111444
111445
111446
111447
111448
111449
111450
111451
111452
111453
111454
111455
111456
111457
111458
111459
111460
111461
111462
111463
111464
111465
111466
111467
111468
111469
111470
111471
111472
111473
111474
111475
111476
111477
111478
111479
111480
111481
111482
111483
111484
111485
111486
111487
111488
111489
111490
111491
111492
111493
111494
111495
111496
111497
111498
111499
111500
111501
111502
111503
111504
111505
111506
111507
111508
111509
111510
111511
111512
111513
111514
111515
111516
111517
111518
111519
111520
111521
111522
111523
111524
111525
111526
111527
111528
111529
111530
111531
111532
111533
111534
111535
111536
111537
111538
111539
111540
111541
111542
111543
111544
111545
111546
111547
111548
111549
111550
111551
111552
111553
|
/* no break */ deliberate_fall_through
default:
testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail() disallows */
testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail() disallows */
return WRC_Continue;
}
}
static int exprIsConst(Parse *pParse, Expr *p, int initFlag){
Walker w;
w.eCode = initFlag;
w.pParse = pParse;
w.xExprCallback = exprNodeIsConstant;
w.xSelectCallback = sqlite3SelectWalkFail;
#ifdef SQLITE_DEBUG
w.xSelectCallback2 = sqlite3SelectWalkAssert2;
#endif
sqlite3WalkExpr(&w, p);
return w.eCode;
}
/*
** Walk an expression tree. Return non-zero if the expression is constant
** and 0 if it involves variables or function calls.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
**
** The pParse parameter may be NULL. But if it is NULL, there is no way
** to determine if function calls are constant or not, and hence all
** function calls will be considered to be non-constant. If pParse is
** not NULL, then a function call might be constant, depending on the
** function and on its parameters.
*/
SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse *pParse, Expr *p){
return exprIsConst(pParse, p, 1);
}
/*
** Walk an expression tree. Return non-zero if
**
** (1) the expression is constant, and
** (2) the expression does originate in the ON or USING clause
** of a LEFT JOIN, and
** (3) the expression does not contain any EP_FixedCol TK_COLUMN
** operands created by the constant propagation optimization.
**
** When this routine returns true, it indicates that the expression
** can be added to the pParse->pConstExpr list and evaluated once when
** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce().
*/
static int sqlite3ExprIsConstantNotJoin(Parse *pParse, Expr *p){
return exprIsConst(pParse, p, 2);
}
/*
** This routine examines sub-SELECT statements as an expression is being
** walked as part of sqlite3ExprIsTableConstant(). Sub-SELECTs are considered
** constant as long as they are uncorrelated - meaning that they do not
** contain any terms from outer contexts.
*/
static int exprSelectWalkTableConstant(Walker *pWalker, Select *pSelect){
assert( pSelect!=0 );
assert( pWalker->eCode==3 || pWalker->eCode==0 );
if( (pSelect->selFlags & SF_Correlated)!=0 ){
pWalker->eCode = 0;
return WRC_Abort;
}
return WRC_Prune;
}
/*
** Walk an expression tree. Return non-zero if the expression is constant
** for any single row of the table with cursor iCur. In other words, the
** expression must not refer to any non-deterministic function nor any
** table other than iCur.
**
** Consider uncorrelated subqueries to be constants if the bAllowSubq
** parameter is true.
*/
static int sqlite3ExprIsTableConstant(Expr *p, int iCur, int bAllowSubq){
Walker w;
w.eCode = 3;
w.pParse = 0;
w.xExprCallback = exprNodeIsConstant;
if( bAllowSubq ){
w.xSelectCallback = exprSelectWalkTableConstant;
}else{
w.xSelectCallback = sqlite3SelectWalkFail;
#ifdef SQLITE_DEBUG
w.xSelectCallback2 = sqlite3SelectWalkAssert2;
#endif
}
w.u.iCur = iCur;
sqlite3WalkExpr(&w, p);
return w.eCode;
}
/*
** Check pExpr to see if it is an constraint on the single data source
** pSrc = &pSrcList->a[iSrc]. In other words, check to see if pExpr
** constrains pSrc but does not depend on any other tables or data
** sources anywhere else in the query. Return true (non-zero) if pExpr
** is a constraint on pSrc only.
**
** This is an optimization. False negatives will perhaps cause slower
** queries, but false positives will yield incorrect answers. So when in
** doubt, return 0.
**
** To be an single-source constraint, the following must be true:
**
** (1) pExpr cannot refer to any table other than pSrc->iCursor.
**
** (2a) pExpr cannot use subqueries unless the bAllowSubq parameter is
** true and the subquery is non-correlated
**
** (2b) pExpr cannot use non-deterministic functions.
**
** (3) pSrc cannot be part of the left operand for a RIGHT JOIN.
** (Is there some way to relax this constraint?)
**
** (4) If pSrc is the right operand of a LEFT JOIN, then...
** (4a) pExpr must come from an ON clause..
** (4b) and specifically the ON clause associated with the LEFT JOIN.
|
| ︙ | | | ︙ | |
111526
111527
111528
111529
111530
111531
111532
111533
111534
111535
111536
111537
111538
111539
111540
|
** from the left side of a RIGHT JOIN over to the right side,
** which leads to incorrect answers. See also restriction (9)
** on push-down.
*/
SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(
Expr *pExpr, /* The constraint */
const SrcList *pSrcList, /* Complete FROM clause */
int iSrc /* Which element of pSrcList to use */
){
const SrcItem *pSrc = &pSrcList->a[iSrc];
if( pSrc->fg.jointype & JT_LTORJ ){
return 0; /* rule (3) */
}
if( pSrc->fg.jointype & JT_LEFT ){
if( !ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (4a) */
|
|
>
|
111568
111569
111570
111571
111572
111573
111574
111575
111576
111577
111578
111579
111580
111581
111582
111583
|
** from the left side of a RIGHT JOIN over to the right side,
** which leads to incorrect answers. See also restriction (9)
** on push-down.
*/
SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(
Expr *pExpr, /* The constraint */
const SrcList *pSrcList, /* Complete FROM clause */
int iSrc, /* Which element of pSrcList to use */
int bAllowSubq /* Allow non-correlated subqueries */
){
const SrcItem *pSrc = &pSrcList->a[iSrc];
if( pSrc->fg.jointype & JT_LTORJ ){
return 0; /* rule (3) */
}
if( pSrc->fg.jointype & JT_LEFT ){
if( !ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (4a) */
|
| ︙ | | | ︙ | |
111551
111552
111553
111554
111555
111556
111557
111558
111559
111560
111561
111562
111563
111564
111565
|
if( (pSrcList->a[jj].fg.jointype & JT_LTORJ)!=0 ){
return 0; /* restriction (6) */
}
break;
}
}
}
return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */
}
/*
** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy().
*/
static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
|
>
|
|
111594
111595
111596
111597
111598
111599
111600
111601
111602
111603
111604
111605
111606
111607
111608
111609
|
if( (pSrcList->a[jj].fg.jointype & JT_LTORJ)!=0 ){
return 0; /* restriction (6) */
}
break;
}
}
}
/* Rules (1), (2a), and (2b) handled by the following: */
return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor, bAllowSubq);
}
/*
** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy().
*/
static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
|
| ︙ | | | ︙ | |
111636
111637
111638
111639
111640
111641
111642
111643
111644
111645
111646
111647
111648
111649
111650
|
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
assert( isInit==0 || isInit==1 );
return exprIsConst(0, p, 4+isInit, 0);
}
#ifdef SQLITE_ENABLE_CURSOR_HINTS
/*
** Walk an expression tree. Return 1 if the expression contains a
** subquery of some kind. Return 0 if there are no subqueries.
*/
|
|
|
111680
111681
111682
111683
111684
111685
111686
111687
111688
111689
111690
111691
111692
111693
111694
|
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
assert( isInit==0 || isInit==1 );
return exprIsConst(0, p, 4+isInit);
}
#ifdef SQLITE_ENABLE_CURSOR_HINTS
/*
** Walk an expression tree. Return 1 if the expression contains a
** subquery of some kind. Return 0 if there are no subqueries.
*/
|
| ︙ | | | ︙ | |
113954
113955
113956
113957
113958
113959
113960
113961
113962
113963
113964
113965
113966
113967
113968
113969
|
exprCodeBetween(pParse, pExpr, target, 0, 0);
return target;
}
case TK_COLLATE: {
if( !ExprHasProperty(pExpr, EP_Collate) ){
/* A TK_COLLATE Expr node without the EP_Collate tag is a so-called
** "SOFT-COLLATE" that is added to constraints that are pushed down
** from outer queries into sub-queries by the push-down optimization.
** Clear subtypes as subtypes may not cross a subquery boundary.
*/
assert( pExpr->pLeft );
sqlite3ExprCode(pParse, pExpr->pLeft, target);
sqlite3VdbeAddOp1(v, OP_ClrSubtype, target);
return target;
}else{
pExpr = pExpr->pLeft;
|
|
|
>
|
113998
113999
114000
114001
114002
114003
114004
114005
114006
114007
114008
114009
114010
114011
114012
114013
114014
|
exprCodeBetween(pParse, pExpr, target, 0, 0);
return target;
}
case TK_COLLATE: {
if( !ExprHasProperty(pExpr, EP_Collate) ){
/* A TK_COLLATE Expr node without the EP_Collate tag is a so-called
** "SOFT-COLLATE" that is added to constraints that are pushed down
** from outer queries into sub-queries by the WHERE-clause push-down
** optimization. Clear subtypes as subtypes may not cross a subquery
** boundary.
*/
assert( pExpr->pLeft );
sqlite3ExprCode(pParse, pExpr->pLeft, target);
sqlite3VdbeAddOp1(v, OP_ClrSubtype, target);
return target;
}else{
pExpr = pExpr->pLeft;
|
| ︙ | | | ︙ | |
147802
147803
147804
147805
147806
147807
147808
147809
147810
147811
147812
147813
147814
147815
|
** Transformed into:
**
** SELECT * FROM (SELECT a AS x, c-d AS y FROM t1 WHERE a=5 AND c-d=10)
** WHERE x=5 AND y=10;
**
** The hope is that the terms added to the inner query will make it more
** efficient.
**
** Do not attempt this optimization if:
**
** (1) (** This restriction was removed on 2017-09-29. We used to
** disallow this optimization for aggregate subqueries, but now
** it is allowed by putting the extra terms on the HAVING clause.
** The added HAVING clause is pointless if the subquery lacks
|
>
>
>
>
>
>
>
>
>
>
>
>
|
147847
147848
147849
147850
147851
147852
147853
147854
147855
147856
147857
147858
147859
147860
147861
147862
147863
147864
147865
147866
147867
147868
147869
147870
147871
147872
|
** Transformed into:
**
** SELECT * FROM (SELECT a AS x, c-d AS y FROM t1 WHERE a=5 AND c-d=10)
** WHERE x=5 AND y=10;
**
** The hope is that the terms added to the inner query will make it more
** efficient.
**
** NAME AMBIGUITY
**
** This optimization is called the "WHERE-clause push-down optimization".
**
** Do not confuse this optimization with another unrelated optimization
** with a similar name: The "MySQL push-down optimization" causes WHERE
** clause terms that can be evaluated using only the index and without
** reference to the table are run first, so that if they are false,
** unnecessary table seeks are avoided.
**
** RULES
**
** Do not attempt this optimization if:
**
** (1) (** This restriction was removed on 2017-09-29. We used to
** disallow this optimization for aggregate subqueries, but now
** it is allowed by putting the extra terms on the HAVING clause.
** The added HAVING clause is pointless if the subquery lacks
|
| ︙ | | | ︙ | |
147868
147869
147870
147871
147872
147873
147874
147875
147876
147877
147878
147879
147880
147881
147882
147883
147884
147885
|
** of a join (either an INNER or an OUTER join), and
**
** (9b) The subquery is to the right of the ON/USING clause
**
** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING
** clause and the subquery.
**
** Without this restriction, the push-down optimization might move
** the ON/USING filter expression from the left side of a RIGHT JOIN
** over to the right side, which leads to incorrect answers. See
** also restriction (6) in sqlite3ExprIsSingleTableConstraint().
**
** (10) The inner query is not the right-hand table of a RIGHT JOIN.
**
** (11) The subquery is not a VALUES clause
**
** (12) The WHERE clause is not "rowid ISNULL" or the equivalent. This
** case only comes up if SQLite is compiled using
|
|
|
|
|
|
147925
147926
147927
147928
147929
147930
147931
147932
147933
147934
147935
147936
147937
147938
147939
147940
147941
147942
|
** of a join (either an INNER or an OUTER join), and
**
** (9b) The subquery is to the right of the ON/USING clause
**
** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING
** clause and the subquery.
**
** Without this restriction, the WHERE-clause push-down optimization
** might move the ON/USING filter expression from the left side of a
** RIGHT JOIN over to the right side, which leads to incorrect answers.
** See also restriction (6) in sqlite3ExprIsSingleTableConstraint().
**
** (10) The inner query is not the right-hand table of a RIGHT JOIN.
**
** (11) The subquery is not a VALUES clause
**
** (12) The WHERE clause is not "rowid ISNULL" or the equivalent. This
** case only comes up if SQLite is compiled using
|
| ︙ | | | ︙ | |
148003
148004
148005
148006
148007
148008
148009
148010
148011
148012
148013
148014
148015
148016
148017
|
&& pLeft->iColumn < 0
){
return 0; /* Restriction (12) */
}
}
#endif
if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){
nChng++;
pSubq->selFlags |= SF_PushDown;
while( pSubq ){
SubstContext x;
pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
unsetJoinExpr(pNew, -1, 1);
x.pParse = pParse;
|
|
|
148060
148061
148062
148063
148064
148065
148066
148067
148068
148069
148070
148071
148072
148073
148074
|
&& pLeft->iColumn < 0
){
return 0; /* Restriction (12) */
}
}
#endif
if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc, 1) ){
nChng++;
pSubq->selFlags |= SF_PushDown;
while( pSubq ){
SubstContext x;
pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
unsetJoinExpr(pNew, -1, 1);
x.pParse = pParse;
|
| ︙ | | | ︙ | |
150432
150433
150434
150435
150436
150437
150438
150439
150440
150441
150442
150443
150444
150445
150446
|
TREETRACE(0x4000,pParse,p,
("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
sqlite3TreeViewSelect(0, p, 0);
}
#endif
assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 );
}else{
TREETRACE(0x4000,pParse,p,("Push-down not possible\n"));
}
/* Convert unused result columns of the subquery into simple NULL
** expressions, to avoid unneeded searching and computation.
*/
if( OptimizationEnabled(db, SQLITE_NullUnusedCols)
&& disableUnusedSubqueryResultColumns(pItem)
|
|
|
150489
150490
150491
150492
150493
150494
150495
150496
150497
150498
150499
150500
150501
150502
150503
|
TREETRACE(0x4000,pParse,p,
("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
sqlite3TreeViewSelect(0, p, 0);
}
#endif
assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 );
}else{
TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n"));
}
/* Convert unused result columns of the subquery into simple NULL
** expressions, to avoid unneeded searching and computation.
*/
if( OptimizationEnabled(db, SQLITE_NullUnusedCols)
&& disableUnusedSubqueryResultColumns(pItem)
|
| ︙ | | | ︙ | |
153963
153964
153965
153966
153967
153968
153969
153970
153971
153972
153973
153974
153975
153976
|
testcase( oldmask!=0xffffffff && i==31 );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, k);
}
}
if( chngRowid==0 && pPk==0 ){
sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
}
}
/* Populate the array of registers beginning at regNew with the new
** row data. This array is used to check constants, create the new
** table and index records, and as the values for any new.* references
|
>
>
>
|
154020
154021
154022
154023
154024
154025
154026
154027
154028
154029
154030
154031
154032
154033
154034
154035
154036
|
testcase( oldmask!=0xffffffff && i==31 );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, k);
}
}
if( chngRowid==0 && pPk==0 ){
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
if( isView ) sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid);
#endif
sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
}
}
/* Populate the array of registers beginning at regNew with the new
** row data. This array is used to check constants, create the new
** table and index records, and as the values for any new.* references
|
| ︙ | | | ︙ | |
159648
159649
159650
159651
159652
159653
159654
159655
159656
159657
159658
159659
159660
159661
|
**
** iLoop==1: Code only expressions that are entirely covered by pIdx.
** iLoop==2: Code remaining expressions that do not contain correlated
** sub-queries.
** iLoop==3: Code all remaining expressions.
**
** An effort is made to skip unnecessary iterations of the loop.
*/
iLoop = (pIdx ? 1 : 2);
do{
int iNext = 0; /* Next value for iLoop */
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
Expr *pE;
int skipLikeAddr = 0;
|
>
>
>
>
>
>
|
159708
159709
159710
159711
159712
159713
159714
159715
159716
159717
159718
159719
159720
159721
159722
159723
159724
159725
159726
159727
|
**
** iLoop==1: Code only expressions that are entirely covered by pIdx.
** iLoop==2: Code remaining expressions that do not contain correlated
** sub-queries.
** iLoop==3: Code all remaining expressions.
**
** An effort is made to skip unnecessary iterations of the loop.
**
** This optimization of causing simple query restrictions to occur before
** more complex one is call the "push-down" optimization in MySQL. Here
** in SQLite, the name is "MySQL push-down", since there is also another
** totally unrelated optimization called "WHERE-clause push-down".
** Sometimes the qualifier is omitted, resulting in an ambiguity, so beware.
*/
iLoop = (pIdx ? 1 : 2);
do{
int iNext = 0; /* Next value for iLoop */
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
Expr *pE;
int skipLikeAddr = 0;
|
| ︙ | | | ︙ | |
162781
162782
162783
162784
162785
162786
162787
162788
162789
162790
162791
162792
162793
162794
162795
|
idxCols = 0;
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
Expr *pExpr = pTerm->pExpr;
/* Make the automatic index a partial index if there are terms in the
** WHERE clause (or the ON clause of a LEFT join) that constrain which
** rows of the target table (pSrc) that can be used. */
if( (pTerm->wtFlags & TERM_VIRTUAL)==0
&& sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom)
){
pPartial = sqlite3ExprAnd(pParse, pPartial,
sqlite3ExprDup(pParse->db, pExpr, 0));
}
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
int iCol;
Bitmask cMask;
|
|
|
162847
162848
162849
162850
162851
162852
162853
162854
162855
162856
162857
162858
162859
162860
162861
|
idxCols = 0;
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
Expr *pExpr = pTerm->pExpr;
/* Make the automatic index a partial index if there are terms in the
** WHERE clause (or the ON clause of a LEFT join) that constrain which
** rows of the target table (pSrc) that can be used. */
if( (pTerm->wtFlags & TERM_VIRTUAL)==0
&& sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom, 0)
){
pPartial = sqlite3ExprAnd(pParse, pPartial,
sqlite3ExprDup(pParse->db, pExpr, 0));
}
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
int iCol;
Bitmask cMask;
|
| ︙ | | | ︙ | |
163050
163051
163052
163053
163054
163055
163056
163057
163058
163059
163060
163061
163062
163063
163064
|
sqlite3VdbeAddOp2(v, OP_Blob, (int)sz, pLevel->regFilter);
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
pWCEnd = &pWInfo->sWC.a[pWInfo->sWC.nTerm];
for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){
Expr *pExpr = pTerm->pExpr;
if( (pTerm->wtFlags & TERM_VIRTUAL)==0
&& sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc)
){
sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
}
}
if( pLoop->wsFlags & WHERE_IPK ){
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, r1);
|
|
|
163116
163117
163118
163119
163120
163121
163122
163123
163124
163125
163126
163127
163128
163129
163130
|
sqlite3VdbeAddOp2(v, OP_Blob, (int)sz, pLevel->regFilter);
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
pWCEnd = &pWInfo->sWC.a[pWInfo->sWC.nTerm];
for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){
Expr *pExpr = pTerm->pExpr;
if( (pTerm->wtFlags & TERM_VIRTUAL)==0
&& sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc, 0)
){
sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
}
}
if( pLoop->wsFlags & WHERE_IPK ){
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, r1);
|
| ︙ | | | ︙ | |
167787
167788
167789
167790
167791
167792
167793
167794
167795
167796
167797
167798
167799
167800
167801
167802
167803
167804
167805
167806
167807
167808
167809
167810
|
IndexedExpr *p;
Table *pTab;
assert( pIdx->bHasExpr );
pTab = pIdx->pTable;
for(i=0; i<pIdx->nColumn; i++){
Expr *pExpr;
int j = pIdx->aiColumn[i];
int bMaybeNullRow;
if( j==XN_EXPR ){
pExpr = pIdx->aColExpr->a[i].pExpr;
testcase( pTabItem->fg.jointype & JT_LEFT );
testcase( pTabItem->fg.jointype & JT_RIGHT );
testcase( pTabItem->fg.jointype & JT_LTORJ );
bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0;
}else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){
pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]);
bMaybeNullRow = 0;
}else{
continue;
}
if( sqlite3ExprIsConstant(0,pExpr) ) continue;
if( pExpr->op==TK_FUNCTION ){
/* Functions that might set a subtype should not be replaced by the
** value taken from an expression index since the index omits the
|
<
<
<
<
<
<
|
167853
167854
167855
167856
167857
167858
167859
167860
167861
167862
167863
167864
167865
167866
167867
167868
167869
167870
|
IndexedExpr *p;
Table *pTab;
assert( pIdx->bHasExpr );
pTab = pIdx->pTable;
for(i=0; i<pIdx->nColumn; i++){
Expr *pExpr;
int j = pIdx->aiColumn[i];
if( j==XN_EXPR ){
pExpr = pIdx->aColExpr->a[i].pExpr;
}else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){
pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]);
}else{
continue;
}
if( sqlite3ExprIsConstant(0,pExpr) ) continue;
if( pExpr->op==TK_FUNCTION ){
/* Functions that might set a subtype should not be replaced by the
** value taken from an expression index since the index omits the
|
| ︙ | | | ︙ | |
167828
167829
167830
167831
167832
167833
167834
167835
167836
167837
167838
167839
167840
167841
167842
|
if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(pExpr);
}
#endif
p->pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
p->iDataCur = pTabItem->iCursor;
p->iIdxCur = iIdxCur;
p->iIdxCol = i;
p->bMaybeNullRow = bMaybeNullRow;
if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){
p->aff = pIdx->zColAff[i];
}
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
p->zIdxName = pIdx->zName;
#endif
pParse->pIdxEpr = p;
|
|
|
167888
167889
167890
167891
167892
167893
167894
167895
167896
167897
167898
167899
167900
167901
167902
|
if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(pExpr);
}
#endif
p->pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
p->iDataCur = pTabItem->iCursor;
p->iIdxCur = iIdxCur;
p->iIdxCol = i;
p->bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0;
if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){
p->aff = pIdx->zColAff[i];
}
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
p->zIdxName = pIdx->zName;
#endif
pParse->pIdxEpr = p;
|
| ︙ | | | ︙ | |
216751
216752
216753
216754
216755
216756
216757
216758
216759
216760
216761
216762
216763
216764
216765
|
{ "PRIMARY", UCOL_PRIMARY },
{ "SECONDARY", UCOL_SECONDARY },
{ "TERTIARY", UCOL_TERTIARY },
{ "DEFAULT", UCOL_DEFAULT_STRENGTH },
{ "QUARTERNARY", UCOL_QUATERNARY },
{ "IDENTICAL", UCOL_IDENTICAL },
};
int i;
for(i=0; i<sizeof(aStrength)/sizeof(aStrength[0]); i++){
if( sqlite3_stricmp(zOption,aStrength[i].zName)==0 ){
ucol_setStrength(pUCollator, aStrength[i].val);
break;
}
}
if( i>=sizeof(aStrength)/sizeof(aStrength[0]) ){
|
|
|
216811
216812
216813
216814
216815
216816
216817
216818
216819
216820
216821
216822
216823
216824
216825
|
{ "PRIMARY", UCOL_PRIMARY },
{ "SECONDARY", UCOL_SECONDARY },
{ "TERTIARY", UCOL_TERTIARY },
{ "DEFAULT", UCOL_DEFAULT_STRENGTH },
{ "QUARTERNARY", UCOL_QUATERNARY },
{ "IDENTICAL", UCOL_IDENTICAL },
};
unsigned int i;
for(i=0; i<sizeof(aStrength)/sizeof(aStrength[0]); i++){
if( sqlite3_stricmp(zOption,aStrength[i].zName)==0 ){
ucol_setStrength(pUCollator, aStrength[i].val);
break;
}
}
if( i>=sizeof(aStrength)/sizeof(aStrength[0]) ){
|
| ︙ | | | ︙ | |
252094
252095
252096
252097
252098
252099
252100
252101
252102
252103
252104
252105
252106
252107
252108
|
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2024-04-04 14:26:42 7bf49e2c54c9f6f336416f01c0e76aaf70f1e2f3fd612232e5a33ae5dabe0900", -1, SQLITE_TRANSIENT);
}
/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int fts5ShadowName(const char *zName){
|
|
|
252154
252155
252156
252157
252158
252159
252160
252161
252162
252163
252164
252165
252166
252167
252168
|
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2024-04-08 11:50:07 69ec714b2d698acf9e37635256c01b233ce32f22e8323e226441d5ddd948a940", -1, SQLITE_TRANSIENT);
}
/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int fts5ShadowName(const char *zName){
|
| ︙ | | | ︙ | |