1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-16 23:02:26 +03:00

Add the SQLITE_LIKE_DOESNT_MATCH_BLOBS compile-time option.

FossilOrigin-Name: 9e1d6d4c391ff90077f0d1cdeb567969fee9f747
This commit is contained in:
drh
2015-12-01 21:23:07 +00:00
parent 415afddaae
commit 41d2e66ef3
14 changed files with 121 additions and 46 deletions

View File

@@ -158,6 +158,9 @@ static const char * const azCompileOpt[] = {
#ifdef SQLITE_INT64_TYPE
"INT64_TYPE",
#endif
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
"LIKE_DOESNT_MATCH_BLOBS",
#endif
#if SQLITE_LOCK_TRACE
"LOCK_TRACE",
#endif

View File

@@ -802,6 +802,17 @@ static void likeFunc(
int nPat;
sqlite3 *db = sqlite3_context_db_handle(context);
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( sqlite3_value_type(argv[0])==SQLITE_BLOB
|| sqlite3_value_type(argv[1])==SQLITE_BLOB
){
#ifdef SQLITE_TEST
sqlite3_like_count++;
#endif
sqlite3_result_int(context, 0);
return;
}
#endif
zB = sqlite3_value_text(argv[0]);
zA = sqlite3_value_text(argv[1]);

View File

@@ -185,6 +185,12 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "json1", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
Tcl_SetVar2(interp, "sqlite_options", "like_match_blobs", "0", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "like_match_blobs", "1", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_OMIT_ATTACH
Tcl_SetVar2(interp, "sqlite_options", "attach", "0", TCL_GLOBAL_ONLY);
#else

View File

@@ -1088,6 +1088,7 @@ case OP_String: { /* out2 */
pOut->n = pOp->p1;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( pOp->p5 ){
assert( pOp->p3>0 );
assert( pOp->p3<=(p->nMem-p->nCursor) );
@@ -1095,6 +1096,7 @@ case OP_String: { /* out2 */
assert( pIn3->flags & MEM_Int );
if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term;
}
#endif
break;
}

View File

@@ -4492,6 +4492,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeJumpHere(v, pLevel->addrSkip);
sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
}
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( pLevel->addrLikeRep ){
int op;
if( sqlite3VdbeGetOp(v, pLevel->addrLikeRep-1)->p1 ){
@@ -4502,6 +4503,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeAddOp2(v, op, pLevel->iLikeRepCntr, pLevel->addrLikeRep);
VdbeCoverage(v);
}
#endif
if( pLevel->iLeftJoin ){
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0

View File

@@ -69,8 +69,10 @@ struct WhereLevel {
int addrCont; /* Jump here to continue with the next loop cycle */
int addrFirst; /* First instruction of interior of the loop */
int addrBody; /* Beginning of the body of this loop */
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
int iLikeRepCntr; /* LIKE range processing counter register */
int addrLikeRep; /* LIKE range processing address */
#endif
u8 iFrom; /* Which entry in the FROM clause */
u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
int p1, p2; /* Operands of the opcode used to ends the loop */

View File

@@ -561,6 +561,7 @@ static int codeAllEqualityTerms(
return regBase;
}
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
/*
** If the most recently coded instruction is a constant range contraint
** that originated from the LIKE optimization, then change the P3 to be
@@ -572,6 +573,10 @@ static int codeAllEqualityTerms(
** The OP_String opcodes on the second pass convert the upper and lower
** bound string contants to blobs. This routine makes the necessary changes
** to the OP_String opcodes for that to happen.
**
** Except, of course, if SQLITE_LIKE_DOESNT_MATCH_BLOBS is defined, then
** only the one pass through the string space is required, so this routine
** becomes a no-op.
*/
static void whereLikeOptimizationStringFixup(
Vdbe *v, /* prepared statement under construction */
@@ -589,6 +594,9 @@ static void whereLikeOptimizationStringFixup(
pOp->p5 = 1;
}
}
#else
# define whereLikeOptimizationStringFixup(A,B,C)
#endif
#ifdef SQLITE_ENABLE_CURSOR_HINTS
/*
@@ -1075,6 +1083,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
pRangeEnd = pLoop->aLTerm[j++];
nExtraReg = 1;
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){
assert( pRangeStart!=0 ); /* LIKE opt constraints */
assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */
@@ -1087,6 +1096,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
VdbeComment((v, "LIKE loop counter"));
pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v);
}
#endif
if( pRangeStart==0
&& (j = pIdx->aiColumn[nEq])>=0
&& pIdx->pTable->aCol[j].notNull==0
@@ -1590,9 +1600,13 @@ Bitmask sqlite3WhereCodeOneLoopStart(
continue;
}
if( pTerm->wtFlags & TERM_LIKECOND ){
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
continue;
#else
assert( pLevel->iLikeRepCntr>0 );
skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfNot, pLevel->iLikeRepCntr);
VdbeCoverage(v);
#endif
}
sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);