aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/printf.c8
-rw-r--r--src/sqliteInt.h2
-rw-r--r--src/where.c9
-rw-r--r--src/whereInt.h3
-rw-r--r--src/whereexpr.c35
5 files changed, 41 insertions, 16 deletions
diff --git a/src/printf.c b/src/printf.c
index 8cb5a43c5..669ca26b0 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -416,6 +416,14 @@ void sqlite3_str_vappendf(
}
prefix = 0;
}
+
+#if WHERETRACE_ENABLED
+ if( xtype==etPOINTER && sqlite3WhereTrace & 0x100000 ) longvalue = 0;
+#endif
+#if TREETRACE_ENABLED
+ if( xtype==etPOINTER && sqlite3TreeTrace & 0x100000 ) longvalue = 0;
+#endif
+
if( longvalue==0 ) flag_alternateform = 0;
if( flag_zeropad && precision<width-(prefix!=0) ){
precision = width-(prefix!=0);
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index e28e338c4..88272920c 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -1153,6 +1153,7 @@ extern u32 sqlite3TreeTrace;
** 0x00020000 Transform DISTINCT into GROUP BY
** 0x00040000 SELECT tree dump after all code has been generated
** 0x00080000 NOT NULL strength reduction
+** 0x00100000 Pointers are all shown as zero
*/
/*
@@ -1197,6 +1198,7 @@ extern u32 sqlite3WhereTrace;
** 0x00020000 Show WHERE terms returned from whereScanNext()
** 0x00040000 Solver overview messages
** 0x00080000 Star-query heuristic
+** 0x00100000 Pointers are all shown as zero
*/
diff --git a/src/where.c b/src/where.c
index 9561a75ea..11e24a8d3 100644
--- a/src/where.c
+++ b/src/where.c
@@ -426,11 +426,11 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
pScan->pWC = pWC;
pScan->k = k+1;
#ifdef WHERETRACE_ENABLED
- if( sqlite3WhereTrace & 0x20000 ){
+ if( (sqlite3WhereTrace & 0x20000)!=0 && pScan->nEquiv>1 ){
int ii;
- sqlite3DebugPrintf("SCAN-TERM %p: nEquiv=%d",
- pTerm, pScan->nEquiv);
- for(ii=0; ii<pScan->nEquiv; ii++){
+ sqlite3DebugPrintf("EQUIVALENT TO {%d:%d} (due to TERM-%d):",
+ pScan->aiCur[0], pScan->aiColumn[0], pTerm->iTerm);
+ for(ii=1; ii<pScan->nEquiv; ii++){
sqlite3DebugPrintf(" {%d:%d}",
pScan->aiCur[ii], pScan->aiColumn[ii]);
}
@@ -2385,6 +2385,7 @@ void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){
}else{
sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor);
}
+ iTerm = pTerm->iTerm = MAX(iTerm,pTerm->iTerm);
sqlite3DebugPrintf(
"TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x",
iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags);
diff --git a/src/whereInt.h b/src/whereInt.h
index 40a720ab9..3a9353e07 100644
--- a/src/whereInt.h
+++ b/src/whereInt.h
@@ -280,6 +280,9 @@ struct WhereTerm {
u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
int iParent; /* Disable pWC->a[iParent] when this term disabled */
int leftCursor; /* Cursor number of X in "X <op> <expr>" */
+#ifdef SQLITE_DEBUG
+ int iTerm; /* Which WhereTerm is this, for debug purposes */
+#endif
union {
struct {
int leftColumn; /* Column number of X in "X <op> <expr>" */
diff --git a/src/whereexpr.c b/src/whereexpr.c
index 4a24dadd2..6dcbd0167 100644
--- a/src/whereexpr.c
+++ b/src/whereexpr.c
@@ -931,30 +931,38 @@ static void exprAnalyzeOrTerm(
** 1. The SQLITE_Transitive optimization must be enabled
** 2. Must be either an == or an IS operator
** 3. Not originating in the ON clause of an OUTER JOIN
-** 4. The affinities of A and B must be compatible
-** 5a. Both operands use the same collating sequence OR
-** 5b. The overall collating sequence is BINARY
+** 4. The operator is not IS or else the query does not contain RIGHT JOIN
+** 5. The affinities of A and B must be compatible
+** 6a. Both operands use the same collating sequence OR
+** 6b. The overall collating sequence is BINARY
** If this routine returns TRUE, that means that the RHS can be substituted
** for the LHS anyplace else in the WHERE clause where the LHS column occurs.
** This is an optimization. No harm comes from returning 0. But if 1 is
** returned when it should not be, then incorrect answers might result.
*/
-static int termIsEquivalence(Parse *pParse, Expr *pExpr){
+static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){
char aff1, aff2;
CollSeq *pColl;
- if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;
- if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;
- if( ExprHasProperty(pExpr, EP_OuterON) ) return 0;
+ if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */
+ if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */
+ if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */
+ if( pExpr->op==TK_IS && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
+ return 0; /* (4) */
+ }
aff1 = sqlite3ExprAffinity(pExpr->pLeft);
aff2 = sqlite3ExprAffinity(pExpr->pRight);
if( aff1!=aff2
&& (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2))
){
- return 0;
+ return 0; /* (5) */
}
pColl = sqlite3ExprCompareCollSeq(pParse, pExpr);
- if( sqlite3IsBinary(pColl) ) return 1;
- return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight);
+ if( !sqlite3IsBinary(pColl)
+ && !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight)
+ ){
+ return 0; /* (6) */
+ }
+ return 1;
}
/*
@@ -1112,6 +1120,9 @@ static void exprAnalyze(
}
assert( pWC->nTerm > idxTerm );
pTerm = &pWC->a[idxTerm];
+#ifdef SQLITE_DEBUG
+ pTerm->iTerm = idxTerm;
+#endif
pMaskSet = &pWInfo->sMaskSet;
pExpr = pTerm->pExpr;
assert( pExpr!=0 ); /* Because malloc() has not failed */
@@ -1219,8 +1230,8 @@ static void exprAnalyze(
if( op==TK_IS ) pNew->wtFlags |= TERM_IS;
pTerm = &pWC->a[idxTerm];
pTerm->wtFlags |= TERM_COPIED;
-
- if( termIsEquivalence(pParse, pDup) ){
+ assert( pWInfo->pTabList!=0 );
+ if( termIsEquivalence(pParse, pDup, pWInfo->pTabList) ){
pTerm->eOperator |= WO_EQUIV;
eExtraOp = WO_EQUIV;
}