Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge latest trunk changes with this branch. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | wal2 |
Files: | files | file ages | folders |
SHA3-256: |
d218d815f89cb1368fdb5e3f774b7ada |
User & Date: | dan 2017-10-09 19:50:09.728 |
Context
2017-10-10
| ||
20:11 | Add new extension "bgckpt" in ext/misc/bgckpt.c. For experimenting with running wal2 mode checkpoints in a background thread. (check-in: 6395544230 user: dan tags: wal2) | |
2017-10-09
| ||
19:50 | Merge latest trunk changes with this branch. (check-in: d218d815f8 user: dan tags: wal2) | |
19:49 | Add a header comment to wal.c describing the differences between wal and wal2 mode. (check-in: 9c80cd202f user: dan tags: wal2) | |
2017-10-08
| ||
02:22 | Fix harmless compiler warnings in FTS5 seen with MSVC. (check-in: 5594a121bf user: mistachkin tags: trunk) | |
Changes
Changes to ext/fts5/fts5_vocab.c.
︙ | ︙ | |||
679 680 681 682 683 684 685 | assert( iCol==1 || iCol==2 ); if( iCol==1 ){ iVal = pCsr->aDoc[0]; }else{ iVal = pCsr->aCnt[0]; } }else{ | < | | 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 | assert( iCol==1 || iCol==2 ); if( iCol==1 ){ iVal = pCsr->aDoc[0]; }else{ iVal = pCsr->aCnt[0]; } }else{ assert( eType==FTS5_VOCAB_INSTANCE ); switch( iCol ){ case 1: sqlite3_result_int64(pCtx, pCsr->pIter->iRowid); break; case 2: { int ii = -1; if( eDetail==FTS5_DETAIL_FULL ){ ii = FTS5_POS2COLUMN(pCsr->iInstPos); }else if( eDetail==FTS5_DETAIL_COLUMNS ){ ii = (int)pCsr->iInstPos; } if( ii>=0 && ii<pCsr->pConfig->nCol ){ const char *z = pCsr->pConfig->azCol[ii]; sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC); } break; } |
︙ | ︙ |
Changes to src/test_func.c.
︙ | ︙ | |||
786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 | abuse_err: Tcl_AppendResult(interp, "sqlite3_create_function abused test failed", (char*)0); return TCL_ERROR; } /* ** Register commands with the TCL interpreter. */ int Sqlitetest_func_Init(Tcl_Interp *interp){ static struct { char *zName; Tcl_ObjCmdProc *xProc; } aObjCmd[] = { { "autoinstall_test_functions", autoinstall_test_funcs }, { "abuse_create_function", abuse_create_function }, }; int i; extern int Md5_Register(sqlite3 *, char **, const sqlite3_api_routines *); for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0); } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 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 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 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 | abuse_err: Tcl_AppendResult(interp, "sqlite3_create_function abused test failed", (char*)0); return TCL_ERROR; } /* ** SQLite user defined function to use with matchinfo() to calculate the ** relevancy of an FTS match. The value returned is the relevancy score ** (a real value greater than or equal to zero). A larger value indicates ** a more relevant document. ** ** The overall relevancy returned is the sum of the relevancies of each ** column value in the FTS table. The relevancy of a column value is the ** sum of the following for each reportable phrase in the FTS query: ** ** (<hit count> / <global hit count>) * <column weight> ** ** where <hit count> is the number of instances of the phrase in the ** column value of the current row and <global hit count> is the number ** of instances of the phrase in the same column of all rows in the FTS ** table. The <column weight> is a weighting factor assigned to each ** column by the caller (see below). ** ** The first argument to this function must be the return value of the FTS ** matchinfo() function. Following this must be one argument for each column ** of the FTS table containing a numeric weight factor for the corresponding ** column. Example: ** ** CREATE VIRTUAL TABLE documents USING fts3(title, content) ** ** The following query returns the docids of documents that match the full-text ** query <query> sorted from most to least relevant. When calculating ** relevance, query term instances in the 'title' column are given twice the ** weighting of those in the 'content' column. ** ** SELECT docid FROM documents ** WHERE documents MATCH <query> ** ORDER BY rank(matchinfo(documents), 1.0, 0.5) DESC */ static void rankfunc(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){ int *aMatchinfo; /* Return value of matchinfo() */ int nMatchinfo; /* Number of elements in aMatchinfo[] */ int nCol = 0; /* Number of columns in the table */ int nPhrase = 0; /* Number of phrases in the query */ int iPhrase; /* Current phrase */ double score = 0.0; /* Value to return */ assert( sizeof(int)==4 ); /* Check that the number of arguments passed to this function is correct. ** If not, jump to wrong_number_args. Set aMatchinfo to point to the array ** of unsigned integer values returned by FTS function matchinfo. Set ** nPhrase to contain the number of reportable phrases in the users full-text ** query, and nCol to the number of columns in the table. Then check that the ** size of the matchinfo blob is as expected. Return an error if it is not. */ if( nVal<1 ) goto wrong_number_args; aMatchinfo = (int*)sqlite3_value_blob(apVal[0]); nMatchinfo = sqlite3_value_bytes(apVal[0]) / sizeof(int); if( nMatchinfo>=2 ){ nPhrase = aMatchinfo[0]; nCol = aMatchinfo[1]; } if( nMatchinfo!=(2+3*nCol*nPhrase) ){ sqlite3_result_error(pCtx, "invalid matchinfo blob passed to function rank()", -1); return; } if( nVal!=(1+nCol) ) goto wrong_number_args; /* Iterate through each phrase in the users query. */ for(iPhrase=0; iPhrase<nPhrase; iPhrase++){ int iCol; /* Current column */ /* Now iterate through each column in the users query. For each column, ** increment the relevancy score by: ** ** (<hit count> / <global hit count>) * <column weight> ** ** aPhraseinfo[] points to the start of the data for phrase iPhrase. So ** the hit count and global hit counts for each column are found in ** aPhraseinfo[iCol*3] and aPhraseinfo[iCol*3+1], respectively. */ int *aPhraseinfo = &aMatchinfo[2 + iPhrase*nCol*3]; for(iCol=0; iCol<nCol; iCol++){ int nHitCount = aPhraseinfo[3*iCol]; int nGlobalHitCount = aPhraseinfo[3*iCol+1]; double weight = sqlite3_value_double(apVal[iCol+1]); if( nHitCount>0 ){ score += ((double)nHitCount / (double)nGlobalHitCount) * weight; } } } sqlite3_result_double(pCtx, score); return; /* Jump here if the wrong number of arguments are passed to this function */ wrong_number_args: sqlite3_result_error(pCtx, "wrong number of arguments to function rank()", -1); } static int SQLITE_TCLAPI install_fts3_rank_function( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**); sqlite3 *db; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; sqlite3_create_function(db, "rank", -1, SQLITE_UTF8, 0, rankfunc, 0, 0); return TCL_OK; } /* ** Register commands with the TCL interpreter. */ int Sqlitetest_func_Init(Tcl_Interp *interp){ static struct { char *zName; Tcl_ObjCmdProc *xProc; } aObjCmd[] = { { "autoinstall_test_functions", autoinstall_test_funcs }, { "abuse_create_function", abuse_create_function }, { "install_fts3_rank_function", install_fts3_rank_function }, }; int i; extern int Md5_Register(sqlite3 *, char **, const sqlite3_api_routines *); for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0); } |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 | ** again. ** ** To look at it another way, this routine resets the state of the ** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to ** VDBE_MAGIC_INIT. */ int sqlite3VdbeReset(Vdbe *p){ sqlite3 *db; db = p->db; /* If the VM did not run to completion or if it encountered an ** error, then it might not have been halted properly. So halt ** it now. */ | > > > > | 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 | ** again. ** ** To look at it another way, this routine resets the state of the ** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to ** VDBE_MAGIC_INIT. */ int sqlite3VdbeReset(Vdbe *p){ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) int i; #endif sqlite3 *db; db = p->db; /* If the VM did not run to completion or if it encountered an ** error, then it might not have been halted properly. So halt ** it now. */ |
︙ | ︙ | |||
2895 2896 2897 2898 2899 2900 2901 | } /* Reset register contents and reclaim error message memory. */ #ifdef SQLITE_DEBUG /* Execute assert() statements to ensure that the Vdbe.apCsr[] and ** Vdbe.aMem[] arrays have already been cleaned up. */ | < < | 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 | } /* Reset register contents and reclaim error message memory. */ #ifdef SQLITE_DEBUG /* Execute assert() statements to ensure that the Vdbe.apCsr[] and ** Vdbe.aMem[] arrays have already been cleaned up. */ if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 ); if( p->aMem ){ for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); } #endif sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; p->pResultSet = 0; /* Save profiling information from this VDBE run. */ #ifdef VDBE_PROFILE { FILE *out = fopen("vdbe_profile.out", "a"); if( out ){ fprintf(out, "---- "); for(i=0; i<p->nOp; i++){ fprintf(out, "%02x", p->aOp[i].opcode); } fprintf(out, "\n"); if( p->zSql ){ char c, pc = 0; |
︙ | ︙ |
Added test/fts3rank.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | # 2017 October 7 # # 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 script is testing the FTS3 module. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix fts3expr5 # If SQLITE_ENABLE_FTS3 is defined, omit this file. ifcapable !fts3 { finish_test return } install_fts3_rank_function db do_execsql_test 1.0 { CREATE VIRTUAL TABLE t1 USING fts3(a, b); INSERT INTO t1 VALUES('one two', 'one'); INSERT INTO t1 VALUES('one two', 'three'); INSERT INTO t1 VALUES('one two', 'two'); } do_execsql_test 1.1 { SELECT * FROM t1 WHERE t1 MATCH 'one' ORDER BY rank(matchinfo(t1), 1.0, 1.0) DESC, rowid } { {one two} one {one two} three {one two} two } do_execsql_test 1.2 { SELECT * FROM t1 WHERE t1 MATCH 'two' ORDER BY rank(matchinfo(t1), 1.0, 1.0) DESC, rowid } { {one two} two {one two} one {one two} three } do_catchsql_test 1.3 { SELECT * FROM t1 ORDER BY rank(matchinfo(t1), 1.0, 1.0) DESC, rowid } {1 {invalid matchinfo blob passed to function rank()}} do_catchsql_test 1.4 { SELECT * FROM t1 ORDER BY rank(x'0000000000000000') DESC, rowid } {0 {{one two} one {one two} three {one two} two}} do_catchsql_test 1.5 { SELECT * FROM t1 ORDER BY rank(x'0100000001000000') DESC, rowid } {1 {invalid matchinfo blob passed to function rank()}} finish_test |