OLD | NEW |
1 /* | 1 /* |
2 ** 2006 June 10 | 2 ** 2006 June 10 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 rc = SQLITE_NOMEM; | 199 rc = SQLITE_NOMEM; |
200 goto out; | 200 goto out; |
201 } | 201 } |
202 | 202 |
203 /* Copy the column names into the allocated space and set up the | 203 /* Copy the column names into the allocated space and set up the |
204 ** pointers in the aCol[] array. | 204 ** pointers in the aCol[] array. |
205 */ | 205 */ |
206 zSpace = (char *)(&aCol[nCol]); | 206 zSpace = (char *)(&aCol[nCol]); |
207 for(ii=0; ii<nCol; ii++){ | 207 for(ii=0; ii<nCol; ii++){ |
208 aCol[ii] = zSpace; | 208 aCol[ii] = zSpace; |
209 zSpace += sprintf(zSpace, "%s", sqlite3_column_name(pStmt, ii)); | 209 sqlite3_snprintf(nBytes, zSpace, "%s", sqlite3_column_name(pStmt,ii)); |
210 zSpace++; | 210 zSpace += (int)strlen(zSpace) + 1; |
211 } | 211 } |
212 assert( (zSpace-nBytes)==(char *)aCol ); | 212 assert( (zSpace-nBytes)==(char *)aCol ); |
213 } | 213 } |
214 | 214 |
215 *paCol = aCol; | 215 *paCol = aCol; |
216 *pnCol = nCol; | 216 *pnCol = nCol; |
217 | 217 |
218 out: | 218 out: |
219 sqlite3_finalize(pStmt); | 219 sqlite3_finalize(pStmt); |
220 return rc; | 220 return rc; |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 /* | 641 /* |
642 ** Compute a simple hash of the null terminated string zString. | 642 ** Compute a simple hash of the null terminated string zString. |
643 ** | 643 ** |
644 ** This module uses only sqlite3_index_info.idxStr, not | 644 ** This module uses only sqlite3_index_info.idxStr, not |
645 ** sqlite3_index_info.idxNum. So to test idxNum, when idxStr is set | 645 ** sqlite3_index_info.idxNum. So to test idxNum, when idxStr is set |
646 ** in echoBestIndex(), idxNum is set to the corresponding hash value. | 646 ** in echoBestIndex(), idxNum is set to the corresponding hash value. |
647 ** In echoFilter(), code assert()s that the supplied idxNum value is | 647 ** In echoFilter(), code assert()s that the supplied idxNum value is |
648 ** indeed the hash of the supplied idxStr. | 648 ** indeed the hash of the supplied idxStr. |
649 */ | 649 */ |
650 static int hashString(const char *zString){ | 650 static int hashString(const char *zString){ |
651 int val = 0; | 651 u32 val = 0; |
652 int ii; | 652 int ii; |
653 for(ii=0; zString[ii]; ii++){ | 653 for(ii=0; zString[ii]; ii++){ |
654 val = (val << 3) + (int)zString[ii]; | 654 val = (val << 3) + (int)zString[ii]; |
655 } | 655 } |
656 return val; | 656 return (int)(val&0x7fffffff); |
657 } | 657 } |
658 | 658 |
659 /* | 659 /* |
660 ** Echo virtual table module xFilter method. | 660 ** Echo virtual table module xFilter method. |
661 */ | 661 */ |
662 static int echoFilter( | 662 static int echoFilter( |
663 sqlite3_vtab_cursor *pVtabCursor, | 663 sqlite3_vtab_cursor *pVtabCursor, |
664 int idxNum, const char *idxStr, | 664 int idxNum, const char *idxStr, |
665 int argc, sqlite3_value **argv | 665 int argc, sqlite3_value **argv |
666 ){ | 666 ){ |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 *pRc = SQLITE_NOMEM; | 739 *pRc = SQLITE_NOMEM; |
740 } | 740 } |
741 } | 741 } |
742 *pzStr = zIn; | 742 *pzStr = zIn; |
743 if( doFree ){ | 743 if( doFree ){ |
744 sqlite3_free(zAppend); | 744 sqlite3_free(zAppend); |
745 } | 745 } |
746 } | 746 } |
747 | 747 |
748 /* | 748 /* |
| 749 ** This function returns a pointer to an sqlite3_malloc()ed buffer |
| 750 ** containing the select-list (the thing between keywords SELECT and FROM) |
| 751 ** to query the underlying real table with for the scan described by |
| 752 ** argument pIdxInfo. |
| 753 ** |
| 754 ** If the current SQLite version is earlier than 3.10.0, this is just "*" |
| 755 ** (select all columns). Or, for version 3.10.0 and greater, the list of |
| 756 ** columns identified by the pIdxInfo->colUsed mask. |
| 757 */ |
| 758 static char *echoSelectList(echo_vtab *pTab, sqlite3_index_info *pIdxInfo){ |
| 759 char *zRet = 0; |
| 760 if( sqlite3_libversion_number()<3010000 ){ |
| 761 zRet = sqlite3_mprintf(", *"); |
| 762 }else{ |
| 763 int i; |
| 764 for(i=0; i<pTab->nCol; i++){ |
| 765 if( pIdxInfo->colUsed & ((sqlite3_uint64)1 << (i>=63 ? 63 : i)) ){ |
| 766 zRet = sqlite3_mprintf("%z, %s", zRet, pTab->aCol[i]); |
| 767 }else{ |
| 768 zRet = sqlite3_mprintf("%z, NULL", zRet); |
| 769 } |
| 770 if( !zRet ) break; |
| 771 } |
| 772 } |
| 773 return zRet; |
| 774 } |
| 775 |
| 776 /* |
749 ** The echo module implements the subset of query constraints and sort | 777 ** The echo module implements the subset of query constraints and sort |
750 ** orders that may take advantage of SQLite indices on the underlying | 778 ** orders that may take advantage of SQLite indices on the underlying |
751 ** real table. For example, if the real table is declared as: | 779 ** real table. For example, if the real table is declared as: |
752 ** | 780 ** |
753 ** CREATE TABLE real(a, b, c); | 781 ** CREATE TABLE real(a, b, c); |
754 ** CREATE INDEX real_index ON real(b); | 782 ** CREATE INDEX real_index ON real(b); |
755 ** | 783 ** |
756 ** then the echo module handles WHERE or ORDER BY clauses that refer | 784 ** then the echo module handles WHERE or ORDER BY clauses that refer |
757 ** to the column "b", but not "a" or "c". If a multi-column index is | 785 ** to the column "b", but not "a" or "c". If a multi-column index is |
758 ** present, only its left most column is considered. | 786 ** present, only its left most column is considered. |
759 ** | 787 ** |
760 ** This xBestIndex method encodes the proposed search strategy as | 788 ** This xBestIndex method encodes the proposed search strategy as |
761 ** an SQL query on the real table underlying the virtual echo module | 789 ** an SQL query on the real table underlying the virtual echo module |
762 ** table and stores the query in sqlite3_index_info.idxStr. The SQL | 790 ** table and stores the query in sqlite3_index_info.idxStr. The SQL |
763 ** statement is of the form: | 791 ** statement is of the form: |
764 ** | 792 ** |
765 ** SELECT rowid, * FROM <real-table> ?<where-clause>? ?<order-by-clause>? | 793 ** SELECT rowid, * FROM <real-table> ?<where-clause>? ?<order-by-clause>? |
766 ** | 794 ** |
767 ** where the <where-clause> and <order-by-clause> are determined | 795 ** where the <where-clause> and <order-by-clause> are determined |
768 ** by the contents of the structure pointed to by the pIdxInfo argument. | 796 ** by the contents of the structure pointed to by the pIdxInfo argument. |
769 */ | 797 */ |
770 static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ | 798 static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ |
771 int ii; | 799 int ii; |
772 char *zQuery = 0; | 800 char *zQuery = 0; |
| 801 char *zCol = 0; |
773 char *zNew; | 802 char *zNew; |
774 int nArg = 0; | 803 int nArg = 0; |
775 const char *zSep = "WHERE"; | 804 const char *zSep = "WHERE"; |
776 echo_vtab *pVtab = (echo_vtab *)tab; | 805 echo_vtab *pVtab = (echo_vtab *)tab; |
777 sqlite3_stmt *pStmt = 0; | 806 sqlite3_stmt *pStmt = 0; |
778 Tcl_Interp *interp = pVtab->interp; | 807 Tcl_Interp *interp = pVtab->interp; |
779 | 808 |
780 int nRow; | 809 int nRow = 0; |
781 int useIdx = 0; | 810 int useIdx = 0; |
782 int rc = SQLITE_OK; | 811 int rc = SQLITE_OK; |
783 int useCost = 0; | 812 int useCost = 0; |
784 double cost; | 813 double cost = 0; |
785 int isIgnoreUsable = 0; | 814 int isIgnoreUsable = 0; |
786 if( Tcl_GetVar(interp, "echo_module_ignore_usable", TCL_GLOBAL_ONLY) ){ | 815 if( Tcl_GetVar(interp, "echo_module_ignore_usable", TCL_GLOBAL_ONLY) ){ |
787 isIgnoreUsable = 1; | 816 isIgnoreUsable = 1; |
788 } | 817 } |
789 | 818 |
790 if( simulateVtabError(pVtab, "xBestIndex") ){ | 819 if( simulateVtabError(pVtab, "xBestIndex") ){ |
791 return SQLITE_ERROR; | 820 return SQLITE_ERROR; |
792 } | 821 } |
793 | 822 |
794 /* Determine the number of rows in the table and store this value in local | 823 /* Determine the number of rows in the table and store this value in local |
(...skipping 15 matching lines...) Expand all Loading... |
810 return rc; | 839 return rc; |
811 } | 840 } |
812 sqlite3_step(pStmt); | 841 sqlite3_step(pStmt); |
813 nRow = sqlite3_column_int(pStmt, 0); | 842 nRow = sqlite3_column_int(pStmt, 0); |
814 rc = sqlite3_finalize(pStmt); | 843 rc = sqlite3_finalize(pStmt); |
815 if( rc!=SQLITE_OK ){ | 844 if( rc!=SQLITE_OK ){ |
816 return rc; | 845 return rc; |
817 } | 846 } |
818 } | 847 } |
819 | 848 |
820 zQuery = sqlite3_mprintf("SELECT rowid, * FROM %Q", pVtab->zTableName); | 849 zCol = echoSelectList(pVtab, pIdxInfo); |
821 if( !zQuery ){ | 850 if( !zCol ) return SQLITE_NOMEM; |
822 return SQLITE_NOMEM; | 851 zQuery = sqlite3_mprintf("SELECT rowid%z FROM %Q", zCol, pVtab->zTableName); |
823 } | 852 if( !zQuery ) return SQLITE_NOMEM; |
| 853 |
824 for(ii=0; ii<pIdxInfo->nConstraint; ii++){ | 854 for(ii=0; ii<pIdxInfo->nConstraint; ii++){ |
825 const struct sqlite3_index_constraint *pConstraint; | 855 const struct sqlite3_index_constraint *pConstraint; |
826 struct sqlite3_index_constraint_usage *pUsage; | 856 struct sqlite3_index_constraint_usage *pUsage; |
827 int iCol; | 857 int iCol; |
828 | 858 |
829 pConstraint = &pIdxInfo->aConstraint[ii]; | 859 pConstraint = &pIdxInfo->aConstraint[ii]; |
830 pUsage = &pIdxInfo->aConstraintUsage[ii]; | 860 pUsage = &pIdxInfo->aConstraintUsage[ii]; |
831 | 861 |
832 if( !isIgnoreUsable && !pConstraint->usable ) continue; | 862 if( !isIgnoreUsable && !pConstraint->usable ) continue; |
833 | 863 |
834 iCol = pConstraint->iColumn; | 864 iCol = pConstraint->iColumn; |
835 if( iCol<0 || pVtab->aIndex[iCol] ){ | 865 if( iCol<0 || pVtab->aIndex[iCol] ){ |
836 char *zCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid"; | 866 char *zNewCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid"; |
837 char *zOp = 0; | 867 char *zOp = 0; |
838 useIdx = 1; | 868 useIdx = 1; |
839 switch( pConstraint->op ){ | 869 switch( pConstraint->op ){ |
840 case SQLITE_INDEX_CONSTRAINT_EQ: | 870 case SQLITE_INDEX_CONSTRAINT_EQ: |
841 zOp = "="; break; | 871 zOp = "="; break; |
842 case SQLITE_INDEX_CONSTRAINT_LT: | 872 case SQLITE_INDEX_CONSTRAINT_LT: |
843 zOp = "<"; break; | 873 zOp = "<"; break; |
844 case SQLITE_INDEX_CONSTRAINT_GT: | 874 case SQLITE_INDEX_CONSTRAINT_GT: |
845 zOp = ">"; break; | 875 zOp = ">"; break; |
846 case SQLITE_INDEX_CONSTRAINT_LE: | 876 case SQLITE_INDEX_CONSTRAINT_LE: |
847 zOp = "<="; break; | 877 zOp = "<="; break; |
848 case SQLITE_INDEX_CONSTRAINT_GE: | 878 case SQLITE_INDEX_CONSTRAINT_GE: |
849 zOp = ">="; break; | 879 zOp = ">="; break; |
850 case SQLITE_INDEX_CONSTRAINT_MATCH: | 880 case SQLITE_INDEX_CONSTRAINT_MATCH: |
| 881 /* Purposely translate the MATCH operator into a LIKE, which |
| 882 ** will be used by the next block of code to construct a new |
| 883 ** query. It should also be noted here that the next block |
| 884 ** of code requires the first letter of this operator to be |
| 885 ** in upper-case to trigger the special MATCH handling (i.e. |
| 886 ** wrapping the bound parameter with literal '%'s). |
| 887 */ |
851 zOp = "LIKE"; break; | 888 zOp = "LIKE"; break; |
| 889 case SQLITE_INDEX_CONSTRAINT_LIKE: |
| 890 zOp = "like"; break; |
| 891 case SQLITE_INDEX_CONSTRAINT_GLOB: |
| 892 zOp = "glob"; break; |
| 893 case SQLITE_INDEX_CONSTRAINT_REGEXP: |
| 894 zOp = "regexp"; break; |
852 } | 895 } |
853 if( zOp[0]=='L' ){ | 896 if( zOp[0]=='L' ){ |
854 zNew = sqlite3_mprintf(" %s %s LIKE (SELECT '%%'||?||'%%')", | 897 zNew = sqlite3_mprintf(" %s %s LIKE (SELECT '%%'||?||'%%')", |
855 zSep, zCol); | 898 zSep, zNewCol); |
856 } else { | 899 } else { |
857 zNew = sqlite3_mprintf(" %s %s %s ?", zSep, zCol, zOp); | 900 zNew = sqlite3_mprintf(" %s %s %s ?", zSep, zNewCol, zOp); |
858 } | 901 } |
859 string_concat(&zQuery, zNew, 1, &rc); | 902 string_concat(&zQuery, zNew, 1, &rc); |
860 | 903 |
861 zSep = "AND"; | 904 zSep = "AND"; |
862 pUsage->argvIndex = ++nArg; | 905 pUsage->argvIndex = ++nArg; |
863 pUsage->omit = 1; | 906 pUsage->omit = 1; |
864 } | 907 } |
865 } | 908 } |
866 | 909 |
867 /* If there is only one term in the ORDER BY clause, and it is | 910 /* If there is only one term in the ORDER BY clause, and it is |
868 ** on a column that this virtual table has an index for, then consume | 911 ** on a column that this virtual table has an index for, then consume |
869 ** the ORDER BY clause. | 912 ** the ORDER BY clause. |
870 */ | 913 */ |
871 if( pIdxInfo->nOrderBy==1 && ( | 914 if( pIdxInfo->nOrderBy==1 && ( |
872 pIdxInfo->aOrderBy->iColumn<0 || | 915 pIdxInfo->aOrderBy->iColumn<0 || |
873 pVtab->aIndex[pIdxInfo->aOrderBy->iColumn]) ){ | 916 pVtab->aIndex[pIdxInfo->aOrderBy->iColumn]) ){ |
874 int iCol = pIdxInfo->aOrderBy->iColumn; | 917 int iCol = pIdxInfo->aOrderBy->iColumn; |
875 char *zCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid"; | 918 char *zNewCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid"; |
876 char *zDir = pIdxInfo->aOrderBy->desc?"DESC":"ASC"; | 919 char *zDir = pIdxInfo->aOrderBy->desc?"DESC":"ASC"; |
877 zNew = sqlite3_mprintf(" ORDER BY %s %s", zCol, zDir); | 920 zNew = sqlite3_mprintf(" ORDER BY %s %s", zNewCol, zDir); |
878 string_concat(&zQuery, zNew, 1, &rc); | 921 string_concat(&zQuery, zNew, 1, &rc); |
879 pIdxInfo->orderByConsumed = 1; | 922 pIdxInfo->orderByConsumed = 1; |
880 } | 923 } |
881 | 924 |
882 appendToEchoModule(pVtab->interp, "xBestIndex");; | 925 appendToEchoModule(pVtab->interp, "xBestIndex");; |
883 appendToEchoModule(pVtab->interp, zQuery); | 926 appendToEchoModule(pVtab->interp, zQuery); |
884 | 927 |
885 if( !zQuery ){ | 928 if( !zQuery ){ |
886 return rc; | 929 return rc; |
887 } | 930 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 int echoUpdate( | 963 int echoUpdate( |
921 sqlite3_vtab *tab, | 964 sqlite3_vtab *tab, |
922 int nData, | 965 int nData, |
923 sqlite3_value **apData, | 966 sqlite3_value **apData, |
924 sqlite_int64 *pRowid | 967 sqlite_int64 *pRowid |
925 ){ | 968 ){ |
926 echo_vtab *pVtab = (echo_vtab *)tab; | 969 echo_vtab *pVtab = (echo_vtab *)tab; |
927 sqlite3 *db = pVtab->db; | 970 sqlite3 *db = pVtab->db; |
928 int rc = SQLITE_OK; | 971 int rc = SQLITE_OK; |
929 | 972 |
930 sqlite3_stmt *pStmt; | 973 sqlite3_stmt *pStmt = 0; |
931 char *z = 0; /* SQL statement to execute */ | 974 char *z = 0; /* SQL statement to execute */ |
932 int bindArgZero = 0; /* True to bind apData[0] to sql var no. nData */ | 975 int bindArgZero = 0; /* True to bind apData[0] to sql var no. nData */ |
933 int bindArgOne = 0; /* True to bind apData[1] to sql var no. 1 */ | 976 int bindArgOne = 0; /* True to bind apData[1] to sql var no. 1 */ |
934 int i; /* Counter variable used by for loops */ | 977 int i; /* Counter variable used by for loops */ |
935 | 978 |
936 assert( nData==pVtab->nCol+2 || nData==1 ); | 979 assert( nData==pVtab->nCol+2 || nData==1 ); |
937 | 980 |
938 /* Ticket #3083 - make sure we always start a transaction prior to | 981 /* Ticket #3083 - make sure we always start a transaction prior to |
939 ** making any changes to a virtual table */ | 982 ** making any changes to a virtual table */ |
940 assert( pVtab->inTransaction ); | 983 assert( pVtab->inTransaction ); |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1387 { "sqlite3_declare_vtab", declare_vtab, 0 }, | 1430 { "sqlite3_declare_vtab", declare_vtab, 0 }, |
1388 }; | 1431 }; |
1389 int i; | 1432 int i; |
1390 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ | 1433 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ |
1391 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, | 1434 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, |
1392 aObjCmd[i].xProc, aObjCmd[i].clientData, 0); | 1435 aObjCmd[i].xProc, aObjCmd[i].clientData, 0); |
1393 } | 1436 } |
1394 #endif | 1437 #endif |
1395 return TCL_OK; | 1438 return TCL_OK; |
1396 } | 1439 } |
OLD | NEW |