@@ -5989,6 +5989,58 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful(
5989
5989
}
5990
5990
}
5991
5991
5992
+ /*
5993
+ ** Expression Node callback for sqlite3ExprCanReturnSubtype().
5994
+ **
5995
+ ** Only a function call is able to return a subtype. So if the node
5996
+ ** is not a function call, return WRC_Prune immediately.
5997
+ **
5998
+ ** A function call is able to return a subtype if it has the
5999
+ ** SQLITE_RESULT_SUBTYPE property.
6000
+ **
6001
+ ** Assume that every function is able to pass-through a subtype from
6002
+ ** one of its argument (using sqlite3_result_value()). Most functions
6003
+ ** are not this way, but we don't have a mechanism to distinguish those
6004
+ ** that are from those that are not, so assume they all work this way.
6005
+ ** That means that if one of its arguments is another function and that
6006
+ ** other function is able to return a subtype, then this function is
6007
+ ** able to return a subtype.
6008
+ */
6009
+ static int exprNodeCanReturnSubtype (Walker * pWalker , Expr * pExpr ){
6010
+ int n ;
6011
+ FuncDef * pDef ;
6012
+ sqlite3 * db ;
6013
+ if ( pExpr -> op != TK_FUNCTION ){
6014
+ return WRC_Prune ;
6015
+ }
6016
+ assert ( ExprUseXList (pExpr ) );
6017
+ db = pWalker -> pParse -> db ;
6018
+ n = pExpr -> x .pList ? pExpr -> x .pList -> nExpr : 0 ;
6019
+ pDef = sqlite3FindFunction (db , pExpr -> u .zToken , n , ENC (db ), 0 );
6020
+ if ( pDef == 0 || (pDef -> funcFlags & SQLITE_RESULT_SUBTYPE )!= 0 ){
6021
+ pWalker -> eCode = 1 ;
6022
+ return WRC_Prune ;
6023
+ }
6024
+ return WRC_Continue ;
6025
+ }
6026
+
6027
+ /*
6028
+ ** Return TRUE if expression pExpr is able to return a subtype.
6029
+ **
6030
+ ** A TRUE return does not guarantee that a subtype will be returned.
6031
+ ** It only indicates that a subtype return is possible. False positives
6032
+ ** are acceptable as they only disable an optimization. False negatives,
6033
+ ** on the other hand, can lead to incorrect answers.
6034
+ */
6035
+ static int sqlite3ExprCanReturnSubtype (Parse * pParse , Expr * pExpr ){
6036
+ Walker w ;
6037
+ memset (& w , 0 , sizeof (w ));
6038
+ w .pParse = pParse ;
6039
+ w .xExprCallback = exprNodeCanReturnSubtype ;
6040
+ sqlite3WalkExpr (& w , pExpr );
6041
+ return w .eCode ;
6042
+ }
6043
+
5992
6044
/*
5993
6045
** The index pIdx is used by a query and contains one or more expressions.
5994
6046
** In other words pIdx is an index on an expression. iIdxCur is the cursor
@@ -6022,19 +6074,11 @@ static SQLITE_NOINLINE void whereAddIndexedExpr(
6022
6074
continue ;
6023
6075
}
6024
6076
if ( sqlite3ExprIsConstant (0 ,pExpr ) ) continue ;
6025
- if ( pExpr -> op == TK_FUNCTION ){
6077
+ if ( pExpr -> op == TK_FUNCTION && sqlite3ExprCanReturnSubtype ( pParse , pExpr ) ){
6026
6078
/* Functions that might set a subtype should not be replaced by the
6027
6079
** value taken from an expression index since the index omits the
6028
6080
** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */
6029
- int n ;
6030
- FuncDef * pDef ;
6031
- sqlite3 * db = pParse -> db ;
6032
- assert ( ExprUseXList (pExpr ) );
6033
- n = pExpr -> x .pList ? pExpr -> x .pList -> nExpr : 0 ;
6034
- pDef = sqlite3FindFunction (db , pExpr -> u .zToken , n , ENC (db ), 0 );
6035
- if ( pDef == 0 || (pDef -> funcFlags & SQLITE_RESULT_SUBTYPE )!= 0 ){
6036
- continue ;
6037
- }
6081
+ continue ;
6038
6082
}
6039
6083
p = sqlite3DbMallocRaw (pParse -> db , sizeof (IndexedExpr ));
6040
6084
if ( p == 0 ) break ;
0 commit comments