Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add tests and minor fixes to the xFindFunction method of virtual tables. (CVS 3323) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
3c4233e074cb016e2422b2e8f867c992 |
User & Date: | drh 2006-07-08 18:09:15.000 |
Context
2006-07-08
| ||
18:35 | For infix functions (LIKE, GLOB, REGEXP, and MATCH) treat the left operand as the first argument for the purposes of virtual table function overloading, even though the left operand is really the the second argument. (CVS 3324) (check-in: 6e98373ca1 user: drh tags: trunk) | |
18:09 | Add tests and minor fixes to the xFindFunction method of virtual tables. (CVS 3323) (check-in: 3c4233e074 user: drh tags: trunk) | |
17:06 | Allow virtual table implementations to overload function that use a column of the virtual table as their first argument. Untested. (CVS 3322) (check-in: 12cc7af4b6 user: drh tags: trunk) | |
Changes
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.187 2006/07/08 18:09:15 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
1562 1563 1564 1565 1566 1567 1568 | int (*xRowid)(sqlite3_vtab_cursor*, sqlite_int64 *pRowid); int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite_int64 *); int (*xBegin)(sqlite3_vtab *pVTab); int (*xSync)(sqlite3_vtab *pVTab); int (*xCommit)(sqlite3_vtab *pVTab); int (*xRollback)(sqlite3_vtab *pVTab); int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, | | | | 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 | int (*xRowid)(sqlite3_vtab_cursor*, sqlite_int64 *pRowid); int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite_int64 *); int (*xBegin)(sqlite3_vtab *pVTab); int (*xSync)(sqlite3_vtab *pVTab); int (*xCommit)(sqlite3_vtab *pVTab); int (*xRollback)(sqlite3_vtab *pVTab); int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), void **ppArg); }; /* ** The sqlite3_index_info structure and its substructures is used to ** pass information into and receive the reply from the xBestIndex ** method of an sqlite3_module. The fields under **Inputs** are the ** inputs to xBestIndex and are read-only. xBestIndex inserts its |
︙ | ︙ |
Changes to src/test8.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test8.c,v 1.40 2006/07/08 18:09:15 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
891 892 893 894 895 896 897 898 899 900 901 902 903 904 | } static int echoCommit(sqlite3_vtab *tab){ return echoTransactionCall(tab, "xCommit"); } static int echoRollback(sqlite3_vtab *tab){ return echoTransactionCall(tab, "xRollback"); } /* ** A virtual table module that merely "echos" the contents of another ** table (like an SQL VIEW). */ static sqlite3_module echoModule = { 0, /* iVersion */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 | } static int echoCommit(sqlite3_vtab *tab){ return echoTransactionCall(tab, "xCommit"); } static int echoRollback(sqlite3_vtab *tab){ return echoTransactionCall(tab, "xRollback"); } /* ** Implementation of "GLOB" function on the echo module. Pass ** all arguments to the ::echo_glob_overload procedure of TCL ** and return the result of that procedure as a string. */ static void overloadedGlobFunction( sqlite3_context *pContext, int nArg, sqlite3_value **apArg ){ Tcl_Interp *interp = sqlite3_user_data(pContext); Tcl_DString str; int i; int rc; Tcl_DStringInit(&str); Tcl_DStringAppendElement(&str, "::echo_glob_overload"); for(i=0; i<nArg; i++){ Tcl_DStringAppendElement(&str, (char*)sqlite3_value_text(apArg[i])); } rc = Tcl_Eval(interp, Tcl_DStringValue(&str)); Tcl_DStringFree(&str); if( rc ){ sqlite3_result_error(pContext, Tcl_GetStringResult(interp), -1); }else{ sqlite3_result_text(pContext, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT); } Tcl_ResetResult(interp); } /* ** This is the xFindFunction implementation for the echo module. ** SQLite calls this routine when the first argument of a function ** is a column of an echo virtual table. This routine can optionally ** override the implementation of that function. It will choose to ** do so if the function is named "glob", and a TCL command named ** ::echo_glob_overload exists. */ static int echoFindFunction( sqlite3_vtab *vtab, int nArg, const char *zFuncName, void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), void **ppArg ){ echo_vtab *pVtab = (echo_vtab *)vtab; Tcl_Interp *interp = pVtab->interp; Tcl_CmdInfo info; if( strcmp(zFuncName,"glob")!=0 ){ return 0; } if( Tcl_GetCommandInfo(interp, "::echo_glob_overload", &info)==0 ){ return 0; } *pxFunc = overloadedGlobFunction; *ppArg = interp; return 1; } /* ** A virtual table module that merely "echos" the contents of another ** table (like an SQL VIEW). */ static sqlite3_module echoModule = { 0, /* iVersion */ |
︙ | ︙ | |||
915 916 917 918 919 920 921 | echoColumn, /* xColumn - read data */ echoRowid, /* xRowid - read data */ echoUpdate, /* xUpdate - write data */ echoBegin, /* xBegin - begin transaction */ echoSync, /* xSync - sync transaction */ echoCommit, /* xCommit - commit transaction */ echoRollback, /* xRollback - rollback transaction */ | | | 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 | echoColumn, /* xColumn - read data */ echoRowid, /* xRowid - read data */ echoUpdate, /* xUpdate - write data */ echoBegin, /* xBegin - begin transaction */ echoSync, /* xSync - sync transaction */ echoCommit, /* xCommit - commit transaction */ echoRollback, /* xRollback - rollback transaction */ echoFindFunction, /* xFindFunction - function overloading */ }; /* ** Decode a pointer to an sqlite3 object. */ static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){ *ppDb = (sqlite3*)sqlite3TextToPtr(zA); |
︙ | ︙ |
Changes to src/vtab.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2006 June 10 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to help implement virtual tables. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2006 June 10 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to help implement virtual tables. ** ** $Id: vtab.c,v 1.27 2006/07/08 18:09:15 drh Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" /* ** External API function used to create a new virtual-table module. */ |
︙ | ︙ | |||
590 591 592 593 594 595 596 | FuncDef *pDef, /* Function to possibly overload */ int nArg, /* Number of arguments to the function */ Expr *pExpr /* First argument to the function */ ){ Table *pTab; sqlite3_vtab *pVtab; sqlite3_module *pMod; | | < | < | 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 | FuncDef *pDef, /* Function to possibly overload */ int nArg, /* Number of arguments to the function */ Expr *pExpr /* First argument to the function */ ){ Table *pTab; sqlite3_vtab *pVtab; sqlite3_module *pMod; void (*xFunc)(sqlite3_context*,int,sqlite3_value**); void *pArg; int rc; FuncDef *pNew; /* Check to see the left operand is a column in a virtual table */ if( pExpr==0 ) return pDef; if( pExpr->op!=TK_COLUMN ) return pDef; pTab = pExpr->pTab; if( pTab==0 ) return pDef; if( !pTab->isVirtual ) return pDef; pVtab = pTab->pVtab; assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); pMod = pVtab->pModule; if( pMod->xFindFunction==0 ) return pDef; /* Call the xFuncFunction method on the virtual table implementation ** to see if the implementation wants to overload this function */ if( pMod->xFindFunction(pVtab, nArg, pDef->zName, &xFunc, &pArg)==0 ){ return pDef; } /* Create a new ephemeral function definition for the overloaded ** function */ pNew = sqliteMalloc( sizeof(*pNew) + strlen(pDef->zName) ); if( pNew==0 ){ return pDef; } *pNew = *pDef; strcpy(pNew->zName, pDef->zName); pNew->xFunc = xFunc; pNew->pUserData = pArg; pNew->flags |= SQLITE_FUNC_EPHEM; return pNew; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
Changes to test/vtab1.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2006 June 10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is creating and dropping virtual tables. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2006 June 10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is creating and dropping virtual tables. # # $Id: vtab1.test,v 1.34 2006/07/08 18:09:15 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !vtab||!schema_pragmas { finish_test return |
︙ | ︙ | |||
829 830 831 832 833 834 835 | } set echo_module } [list \ xBestIndex {SELECT rowid, * FROM 'r'} \ xFilter {SELECT rowid, * FROM 'r'} \ ] | | > | > > > > > > > > > > > > > > > > > > > > > > > | 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 | } set echo_module } [list \ xBestIndex {SELECT rowid, * FROM 'r'} \ xFilter {SELECT rowid, * FROM 'r'} \ ] # Testing the xFindFunction interface # do_test vtab1.11-1 { execsql { INSERT INTO r(a,b,c) VALUES(1,'?',99); INSERT INTO r(a,b,c) VALUES(2,3,99); SELECT a GLOB b FROM e } } {1 0} proc ::echo_glob_overload {a b} { return [list $b $a] } do_test vtab1.11-2 { execsql { SELECT a like b FROM e } } {0 0} do_test vtab1.11-3 { execsql { SELECT a glob b FROM e } } {{1 ?} {2 3}} finish_test |