]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Experimental change that allows overloaded functions to be analyzed by vtab-func-constraint
authordrh <drh@noemail.net>
Sat, 26 May 2018 18:03:48 +0000 (18:03 +0000)
committerdrh <drh@noemail.net>
Sat, 26 May 2018 18:03:48 +0000 (18:03 +0000)
the xBestIndex method and used by the xFilter method of a virtual table.

FossilOrigin-Name: a353b1d7ee6c5989ba1b98a3990c9a4c2ff39ae66572fd1200606e8ef585e5fa

manifest
manifest.uuid
src/expr.c
src/sqlite.h.in
src/whereexpr.c

index 1867640d1db11c2cbec7920a2b9194f73e908f4d..b86958ab3efd929917878ee6895f491c214d30b9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Store\sapplication-defined\sfunction\snames\sas\slower-case\sto\savoid\sthe\sneed\nfor\scase\sconversions\sbefore\scalling\sxFindFunction\son\svirtual\stables.\nAvoid\susing\slookaside\sto\sstore\sthe\sdestructors\sfor\sapplication\sdefined\nfunctions,\sas\slookaside\sshould\sbe\sreserved\sfor\stransient\sallocations.
-D 2018-05-26T16:00:26.368
+C Experimental\schange\sthat\sallows\soverloaded\sfunctions\sto\sbe\sanalyzed\sby\nthe\sxBestIndex\smethod\sand\sused\sby\sthe\sxFilter\smethod\sof\sa\svirtual\stable.
+D 2018-05-26T18:03:48.120
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da
@@ -446,7 +446,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
 F src/dbpage.c 8db4c97f630e7d83f884ea75caf1ffd0988c160e9d530194d93721c80821e0f6
 F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91
 F src/delete.c 4c8c7604277a2041647f96b78f4b9a47858e9217e4fb333d35e7b5ab32c5b57f
-F src/expr.c af4a81a385277510bfc56df87c25d76fc365f98c33bc8797c4a8d84b88e31013
+F src/expr.c 81b3925fb84e226d230eb59d8ef8d680b22a121410934545ba026027d5fe03df
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331
 F src/func.c e2e3c02621a528a472933fd4733a5da635676f1461be73293f6e9f62f18d4eaa
@@ -496,7 +496,7 @@ F src/resolve.c 6415381a0e9d22c0e7cba33ca4a53f81474190862f5d4838190f5eb5b0b47bc9
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
 F src/select.c a35d462ee7a3c0856ad7a9d9c8921fbf3d91d911a8f39ad9d61302eb43b24a71
 F src/shell.c.in 51c100206f4b7f86cd9affd80b764825e0edc36ca0190c442e4ca7994611bfe2
-F src/sqlite.h.in db327b5de56909e060da241ff89cc3726eadf98e9eb17386fc831bbce80e0820
+F src/sqlite.h.in 9823d4fee4b4d56d210a2f603c255af3c984c3cacb14a841d35c5bb27707055b
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7
 F src/sqliteInt.h d2bd297dba08f2390a91c31ff775e0964e9663df5b2910a569fe6f830b8b2beb
@@ -581,7 +581,7 @@ F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f
 F src/where.c 60ec752fcbe9f9e0271ac60548d159a540a1ee47a4f9fedc85e88a3d0e392dd1
 F src/whereInt.h cbae2bcd37cfebdb7812a8b188cdb19634ced2b9346470d1c270556b0c33ea53
 F src/wherecode.c 728c7f70731430ccdac807a79969873e1af6968bf1c4745dff3f9dd35f636cc8
-F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a
+F src/whereexpr.c a6994e3a616f33e885becc2d6a4377ce5aea92b6e2dff96de3a8dd986ed3113f
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1729,7 +1729,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 27b4fa5dd0defc6ddaf5d8cde6a1e1162b70d99bfdc69c1d2290621a6d23ed91
-R d728fa434c4672bbeedeb70c9aae9549
+P 777189ce88799f93f393fd14fd716111c85bcdcb23690fd561f78ea2bd2ce5da
+R 287ad6e657f697576be6591ee557b37e
+T *branch * vtab-func-constraint
+T *sym-vtab-func-constraint *
+T -sym-trunk *
 U drh
-Z 593bd01a2c2330ddb0f8d8891bce9a51
+Z 1dcaa168f6b87a9c36f55e4d22ec80f8
index 2496e832588cdd40143ca334be754370ff1aac67..bf9a43fb0df6789721274e3ed5dede1ea690bd48 100644 (file)
@@ -1 +1 @@
-777189ce88799f93f393fd14fd716111c85bcdcb23690fd561f78ea2bd2ce5da
\ No newline at end of file
+a353b1d7ee6c5989ba1b98a3990c9a4c2ff39ae66572fd1200606e8ef585e5fa
\ No newline at end of file
index 6aff83a256a494fc57e53dc0370b285d14fa32bb..a45f38f9c7b560374020055c7120111d2d591b3b 100644 (file)
@@ -3903,7 +3903,7 @@ expr_code_doover:
       ** "glob(B,A).  We want to use the A in "A glob B" to test
       ** for function overloading.  But we use the B term in "glob(B,A)".
       */
-      if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){
+      if( nFarg>=2 && ExprHasProperty(pExpr, EP_InfixFunc) ){
         pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr);
       }else if( nFarg>0 ){
         pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
index 64e929a89ee26557ff333712d5a6b745a27b07c6..979b9746997c5100b9ac468472e7787e79bbd30d 100644 (file)
@@ -6323,6 +6323,7 @@ struct sqlite3_index_info {
 #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
 #define SQLITE_INDEX_CONSTRAINT_ISNULL    71
 #define SQLITE_INDEX_CONSTRAINT_IS        72
+#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
 
 /*
 ** CAPI3REF: Register A Virtual Table Implementation
index 29750080a1259377e59fa3702a542c0d06ec3263..b177a7d9957bdb29a0af1f7a9677a4979a93e288 100644 (file)
@@ -338,6 +338,7 @@ static int isLikeOrGlob(
 ** If the expression matches none of the patterns above, return 0.
 */
 static int isAuxiliaryVtabOperator(
+  sqlite3 *db,                    /* Parsing context */
   Expr *pExpr,                    /* Test this expression */
   unsigned char *peOp2,           /* OUT: 0 for MATCH, or else an op2 value */
   Expr **ppLeft,                  /* Column expression to left of MATCH/op2 */
@@ -361,16 +362,54 @@ static int isAuxiliaryVtabOperator(
     if( pList==0 || pList->nExpr!=2 ){
       return 0;
     }
+
+    /* Built-in operators MATCH, GLOB, LIKE, and REGEXP attach to a
+    ** virtual table on their second argument, which is the same as
+    ** the left-hand side operand in their in-fix form.
+    **
+    **       vtab_column MATCH expression
+    **       MATCH(expression,vtab_column)
+    */
     pCol = pList->a[1].pExpr;
-    if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){
-      return 0;
+    if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+      for(i=0; i<ArraySize(aOp); i++){
+        if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
+          *peOp2 = aOp[i].eOp2;
+          *ppRight = pList->a[0].pExpr;
+          *ppLeft = pCol;
+          return 1;
+        }
+      }
     }
-    for(i=0; i<ArraySize(aOp); i++){
-      if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
-        *peOp2 = aOp[i].eOp2;
-        *ppRight = pList->a[0].pExpr;
-        *ppLeft = pCol;
-        return 1;
+
+    /* We can also match against the first column of overloaded
+    ** functions where xFindFunction returns a value of at least
+    ** SQLITE_INDEX_CONSTRAINT_FUNCTION.
+    **
+    **      OVERLOADED(vtab_column,expression)
+    **
+    ** Historically, xFindFunction expected to see lower-case function
+    ** names.  But for this use case, xFindFunction is expected to deal
+    ** with function names in an arbitrary case.
+    */
+    pCol = pList->a[0].pExpr;
+    if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+      sqlite3_vtab *pVtab;
+      sqlite3_module *pMod;
+      void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
+      void *pNotUsed;
+      pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab;
+      assert( pVtab!=0 );
+      assert( pVtab->pModule!=0 );
+      pMod = (sqlite3_module *)pVtab->pModule;
+      if( pMod->xFindFunction!=0 ){
+        i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
+        if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
+          *peOp2 = i;
+          *ppRight = pList->a[1].pExpr;
+          *ppLeft = pCol;
+          return 1;
+        }
       }
     }
   }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
@@ -1230,7 +1269,7 @@ static void exprAnalyze(
   */
   if( pWC->op==TK_AND ){
     Expr *pRight = 0, *pLeft = 0;
-    int res = isAuxiliaryVtabOperator(pExpr, &eOp2, &pLeft, &pRight);
+    int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight);
     while( res-- > 0 ){
       int idxNew;
       WhereTerm *pNewTerm;