diff options
author | drh <drh@noemail.net> | 2015-12-01 21:23:07 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2015-12-01 21:23:07 +0000 |
commit | 41d2e66ef3de25a0d78a79bfbb781f305842c77b (patch) | |
tree | b55cca9e909ac260476b57faedd3e3e43fb48d88 /src | |
parent | 415afddaae95a60fea20b977b76eb6c86f902a40 (diff) | |
download | sqlite-41d2e66ef3de25a0d78a79bfbb781f305842c77b.tar.gz sqlite-41d2e66ef3de25a0d78a79bfbb781f305842c77b.zip |
Add the SQLITE_LIKE_DOESNT_MATCH_BLOBS compile-time option.
FossilOrigin-Name: 9e1d6d4c391ff90077f0d1cdeb567969fee9f747
Diffstat (limited to 'src')
-rw-r--r-- | src/ctime.c | 3 | ||||
-rw-r--r-- | src/func.c | 11 | ||||
-rw-r--r-- | src/test_config.c | 6 | ||||
-rw-r--r-- | src/vdbe.c | 2 | ||||
-rw-r--r-- | src/where.c | 2 | ||||
-rw-r--r-- | src/whereInt.h | 2 | ||||
-rw-r--r-- | src/wherecode.c | 14 |
7 files changed, 40 insertions, 0 deletions
diff --git a/src/ctime.c b/src/ctime.c index 17dd710bc..c3149ad91 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -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 diff --git a/src/func.c b/src/func.c index b134c1a7c..3fbd2b736 100644 --- a/src/func.c +++ b/src/func.c @@ -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]); diff --git a/src/test_config.c b/src/test_config.c index b84424bbd..a9ef182e0 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -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 diff --git a/src/vdbe.c b/src/vdbe.c index 66b507b28..f87fddafe 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -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; } diff --git a/src/where.c b/src/where.c index 30ad58e01..7d6866459 100644 --- a/src/where.c +++ b/src/where.c @@ -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 diff --git a/src/whereInt.h b/src/whereInt.h index 86164d8c1..63d2d71cb 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -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 */ diff --git a/src/wherecode.c b/src/wherecode.c index 87db0e0a2..bc72e0ac7 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -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); |