Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Update the built-in SQLite to 3.11.0 beta 1. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
56283544079cf6e79b1c17762c090e14 |
User & Date: | drh 2016-02-09 15:09:24.211 |
Context
2016-02-09
| ||
20:16 | Update the built-in SQLite to include the latest changes, and especially the new auto-explain mode in the command-line shell. ... (check-in: e00968a5 user: drh tags: trunk) | |
15:09 | Update the built-in SQLite to 3.11.0 beta 1. ... (check-in: 56283544 user: drh tags: trunk) | |
14:12 | json: added a few assertions and changed a few chars to ints to avoid potential signedness problems on ARM. ... (check-in: 5c0dc2d3 user: stephan tags: trunk) | |
Changes
Changes to src/sqlite3.c.
︙ | ︙ | |||
119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #define SQLITE_ENABLE_LOCKING_STYLE 0 #define HAVE_UTIME 1 #else /* This is not VxWorks. */ #define OS_VXWORKS 0 #define HAVE_FCHOWN 1 #define HAVE_READLINK 1 #endif /* defined(_WRS_KERNEL) */ /************** End of vxworks.h *********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ /* ** These #defines should enable >2GB file support on POSIX if the | > | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | #define SQLITE_ENABLE_LOCKING_STYLE 0 #define HAVE_UTIME 1 #else /* This is not VxWorks. */ #define OS_VXWORKS 0 #define HAVE_FCHOWN 1 #define HAVE_READLINK 1 #define HAVE_LSTAT 1 #endif /* defined(_WRS_KERNEL) */ /************** End of vxworks.h *********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ /* ** These #defines should enable >2GB file support on POSIX if the |
︙ | ︙ | |||
325 326 327 328 329 330 331 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.11.0" #define SQLITE_VERSION_NUMBER 3011000 | | | 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.11.0" #define SQLITE_VERSION_NUMBER 3011000 #define SQLITE_SOURCE_ID "2016-02-09 02:12:20 ca72be8618e5d466d6f35819ca8bbd2b84269959" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ | |||
5909 5910 5911 5912 5913 5914 5915 | ** sqlite3_libversion_number() returns a value greater than or equal to ** 3009000. */ struct sqlite3_index_info { /* Inputs */ int nConstraint; /* Number of entries in aConstraint */ struct sqlite3_index_constraint { | | | 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 | ** sqlite3_libversion_number() returns a value greater than or equal to ** 3009000. */ struct sqlite3_index_info { /* Inputs */ int nConstraint; /* Number of entries in aConstraint */ struct sqlite3_index_constraint { int iColumn; /* Column constrained. -1 for ROWID */ unsigned char op; /* Constraint operator */ unsigned char usable; /* True if this constraint is usable */ int iTermOffset; /* Used internally - xBestIndex should ignore */ } *aConstraint; /* Table of WHERE clause constraints */ int nOrderBy; /* Number of terms in the ORDER BY clause */ struct sqlite3_index_orderby { int iColumn; /* Column number */ |
︙ | ︙ | |||
10466 10467 10468 10469 10470 10471 10472 | #define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */ #define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */ /* ** Flags passed as the third argument to sqlite3BtreeCursor(). ** ** For read-only cursors the wrFlag argument is always zero. For read-write | | | | > > > > > > > > > > | 10467 10468 10469 10470 10471 10472 10473 10474 10475 10476 10477 10478 10479 10480 10481 10482 10483 10484 10485 10486 10487 10488 10489 10490 10491 10492 10493 10494 10495 10496 10497 10498 | #define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */ #define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */ /* ** Flags passed as the third argument to sqlite3BtreeCursor(). ** ** For read-only cursors the wrFlag argument is always zero. For read-write ** cursors it may be set to either (BTREE_WRCSR|BTREE_FORDELETE) or just ** (BTREE_WRCSR). If the BTREE_FORDELETE bit is set, then the cursor will ** only be used by SQLite for the following: ** ** * to seek to and then delete specific entries, and/or ** ** * to read values that will be used to create keys that other ** BTREE_FORDELETE cursors will seek to and delete. ** ** The BTREE_FORDELETE flag is an optimization hint. It is not used by ** by this, the native b-tree engine of SQLite, but it is available to ** alternative storage engines that might be substituted in place of this ** b-tree system. For alternative storage engines in which a delete of ** the main table row automatically deletes corresponding index rows, ** the FORDELETE flag hint allows those alternative storage engines to ** skip a lot of work. Namely: FORDELETE cursors may treat all SEEK ** and DELETE operations as no-ops, and any READ operation against a ** FORDELETE cursor may return a null row: 0x01 0x00. */ #define BTREE_WRCSR 0x00000004 /* read-write cursor */ #define BTREE_FORDELETE 0x00000008 /* Cursor is for seek/delete only */ SQLITE_PRIVATE int sqlite3BtreeCursor( Btree*, /* BTree containing table to open */ int iTable, /* Index of root page */ |
︙ | ︙ | |||
10502 10503 10504 10505 10506 10507 10508 | UnpackedRecord *pUnKey, i64 intKey, int bias, int *pRes ); SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*); SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*); | | > > > > > | 10513 10514 10515 10516 10517 10518 10519 10520 10521 10522 10523 10524 10525 10526 10527 10528 10529 10530 10531 10532 | UnpackedRecord *pUnKey, i64 intKey, int bias, int *pRes ); SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*); SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*); SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags); /* Allowed flags for the 2nd argument to sqlite3BtreeDelete() */ #define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ #define BTREE_AUXDELETE 0x04 /* not the primary delete operation */ SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, const void *pData, int nData, int nZero, int bias, int seekResult); SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes); SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes); SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int *pRes); SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*); |
︙ | ︙ | |||
10760 10761 10762 10763 10764 10765 10766 | ** The makefile scans the vdbe.c source file and creates the "opcodes.h" ** header file that defines a number for each opcode used by the VDBE. */ /************** Include opcodes.h in the middle of vdbe.h ********************/ /************** Begin file opcodes.h *****************************************/ /* Automatically generated. Do not edit */ /* See the tool/mkopcodeh.tcl script for details */ | | | | | | | | | | | | | | | | | | | > < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > < < | > > | | < < | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | > < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | 10776 10777 10778 10779 10780 10781 10782 10783 10784 10785 10786 10787 10788 10789 10790 10791 10792 10793 10794 10795 10796 10797 10798 10799 10800 10801 10802 10803 10804 10805 10806 10807 10808 10809 10810 10811 10812 10813 10814 10815 10816 10817 10818 10819 10820 10821 10822 10823 10824 10825 10826 10827 10828 10829 10830 10831 10832 10833 10834 10835 10836 10837 10838 10839 10840 10841 10842 10843 10844 10845 10846 10847 10848 10849 10850 10851 10852 10853 10854 10855 10856 10857 10858 10859 10860 10861 10862 10863 10864 10865 10866 10867 10868 10869 10870 10871 10872 10873 10874 10875 10876 10877 10878 10879 10880 10881 10882 10883 10884 10885 10886 10887 10888 10889 10890 10891 10892 10893 10894 10895 10896 10897 10898 10899 10900 10901 10902 10903 10904 10905 10906 10907 10908 10909 10910 10911 10912 10913 10914 10915 10916 10917 10918 10919 10920 10921 10922 10923 10924 10925 10926 10927 10928 10929 10930 10931 10932 10933 10934 10935 10936 10937 10938 10939 10940 10941 10942 10943 10944 10945 10946 10947 10948 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 10959 10960 10961 10962 10963 10964 10965 10966 10967 10968 10969 10970 10971 10972 10973 10974 10975 10976 10977 10978 10979 10980 10981 10982 10983 10984 10985 10986 10987 10988 10989 10990 10991 10992 10993 10994 10995 10996 10997 10998 10999 11000 11001 11002 11003 11004 | ** The makefile scans the vdbe.c source file and creates the "opcodes.h" ** header file that defines a number for each opcode used by the VDBE. */ /************** Include opcodes.h in the middle of vdbe.h ********************/ /************** Begin file opcodes.h *****************************************/ /* Automatically generated. Do not edit */ /* See the tool/mkopcodeh.tcl script for details */ #define OP_Savepoint 0 #define OP_AutoCommit 1 #define OP_Transaction 2 #define OP_SorterNext 3 #define OP_PrevIfOpen 4 #define OP_NextIfOpen 5 #define OP_Prev 6 #define OP_Next 7 #define OP_Checkpoint 8 #define OP_JournalMode 9 #define OP_Vacuum 10 #define OP_VFilter 11 /* synopsis: iplan=r[P3] zplan='P4' */ #define OP_VUpdate 12 /* synopsis: data=r[P3@P2] */ #define OP_Goto 13 #define OP_Gosub 14 #define OP_Return 15 #define OP_InitCoroutine 16 #define OP_EndCoroutine 17 #define OP_Yield 18 #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ #define OP_HaltIfNull 20 /* synopsis: if r[P3]=null halt */ #define OP_Halt 21 #define OP_Integer 22 /* synopsis: r[P2]=P1 */ #define OP_Int64 23 /* synopsis: r[P2]=P4 */ #define OP_String 24 /* synopsis: r[P2]='P4' (len=P1) */ #define OP_Null 25 /* synopsis: r[P2..P3]=NULL */ #define OP_SoftNull 26 /* synopsis: r[P1]=NULL */ #define OP_Blob 27 /* synopsis: r[P2]=P4 (len=P1) */ #define OP_Variable 28 /* synopsis: r[P2]=parameter(P1,P4) */ #define OP_Move 29 /* synopsis: r[P2@P3]=r[P1@P3] */ #define OP_Copy 30 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ #define OP_SCopy 31 /* synopsis: r[P2]=r[P1] */ #define OP_IntCopy 32 /* synopsis: r[P2]=r[P1] */ #define OP_ResultRow 33 /* synopsis: output=r[P1@P2] */ #define OP_CollSeq 34 #define OP_Function0 35 /* synopsis: r[P3]=func(r[P2@P5]) */ #define OP_Function 36 /* synopsis: r[P3]=func(r[P2@P5]) */ #define OP_AddImm 37 /* synopsis: r[P1]=r[P1]+P2 */ #define OP_MustBeInt 38 #define OP_RealAffinity 39 #define OP_Cast 40 /* synopsis: affinity(r[P1]) */ #define OP_Permutation 41 #define OP_Compare 42 /* synopsis: r[P1@P3] <-> r[P2@P3] */ #define OP_Jump 43 #define OP_Once 44 #define OP_If 45 #define OP_IfNot 46 #define OP_Column 47 /* synopsis: r[P3]=PX */ #define OP_Affinity 48 /* synopsis: affinity(r[P1@P2]) */ #define OP_MakeRecord 49 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ #define OP_Count 50 /* synopsis: r[P2]=count() */ #define OP_ReadCookie 51 #define OP_SetCookie 52 #define OP_ReopenIdx 53 /* synopsis: root=P2 iDb=P3 */ #define OP_OpenRead 54 /* synopsis: root=P2 iDb=P3 */ #define OP_OpenWrite 55 /* synopsis: root=P2 iDb=P3 */ #define OP_OpenAutoindex 56 /* synopsis: nColumn=P2 */ #define OP_OpenEphemeral 57 /* synopsis: nColumn=P2 */ #define OP_SorterOpen 58 #define OP_SequenceTest 59 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ #define OP_OpenPseudo 60 /* synopsis: P3 columns in r[P2] */ #define OP_Close 61 #define OP_ColumnsUsed 62 #define OP_SeekLT 63 /* synopsis: key=r[P3@P4] */ #define OP_SeekLE 64 /* synopsis: key=r[P3@P4] */ #define OP_SeekGE 65 /* synopsis: key=r[P3@P4] */ #define OP_SeekGT 66 /* synopsis: key=r[P3@P4] */ #define OP_NoConflict 67 /* synopsis: key=r[P3@P4] */ #define OP_NotFound 68 /* synopsis: key=r[P3@P4] */ #define OP_Found 69 /* synopsis: key=r[P3@P4] */ #define OP_NotExists 70 /* synopsis: intkey=r[P3] */ #define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ #define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ #define OP_Sequence 73 /* synopsis: r[P2]=cursor[P1].ctr++ */ #define OP_NewRowid 74 /* synopsis: r[P2]=rowid */ #define OP_Insert 75 /* synopsis: intkey=r[P3] data=r[P2] */ #define OP_IsNull 76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ #define OP_NotNull 77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ #define OP_Ne 78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */ #define OP_Eq 79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */ #define OP_Gt 80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */ #define OP_Le 81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */ #define OP_Lt 82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */ #define OP_Ge 83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */ #define OP_InsertInt 84 /* synopsis: intkey=P3 data=r[P2] */ #define OP_BitAnd 85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ #define OP_BitOr 86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ #define OP_ShiftLeft 87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ #define OP_ShiftRight 88 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ #define OP_Add 89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ #define OP_Subtract 90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ #define OP_Multiply 91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ #define OP_Divide 92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ #define OP_Remainder 93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ #define OP_Concat 94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ #define OP_Delete 95 #define OP_BitNot 96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ #define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */ #define OP_ResetCount 98 #define OP_SorterCompare 99 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ #define OP_SorterData 100 /* synopsis: r[P2]=data */ #define OP_RowKey 101 /* synopsis: r[P2]=key */ #define OP_RowData 102 /* synopsis: r[P2]=data */ #define OP_Rowid 103 /* synopsis: r[P2]=rowid */ #define OP_NullRow 104 #define OP_Last 105 #define OP_SorterSort 106 #define OP_Sort 107 #define OP_Rewind 108 #define OP_SorterInsert 109 #define OP_IdxInsert 110 /* synopsis: key=r[P2] */ #define OP_IdxDelete 111 /* synopsis: key=r[P2@P3] */ #define OP_Seek 112 /* synopsis: Move P3 to P1.rowid */ #define OP_IdxRowid 113 /* synopsis: r[P2]=rowid */ #define OP_IdxLE 114 /* synopsis: key=r[P3@P4] */ #define OP_IdxGT 115 /* synopsis: key=r[P3@P4] */ #define OP_IdxLT 116 /* synopsis: key=r[P3@P4] */ #define OP_IdxGE 117 /* synopsis: key=r[P3@P4] */ #define OP_Destroy 118 #define OP_Clear 119 #define OP_ResetSorter 120 #define OP_CreateIndex 121 /* synopsis: r[P2]=root iDb=P1 */ #define OP_CreateTable 122 /* synopsis: r[P2]=root iDb=P1 */ #define OP_ParseSchema 123 #define OP_LoadAnalysis 124 #define OP_DropTable 125 #define OP_DropIndex 126 #define OP_DropTrigger 127 #define OP_IntegrityCk 128 #define OP_RowSetAdd 129 /* synopsis: rowset(P1)=r[P2] */ #define OP_RowSetRead 130 /* synopsis: r[P3]=rowset(P1) */ #define OP_RowSetTest 131 /* synopsis: if r[P3] in rowset(P1) goto P2 */ #define OP_Program 132 #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ #define OP_Param 134 #define OP_FkCounter 135 /* synopsis: fkctr[P1]+=P2 */ #define OP_FkIfZero 136 /* synopsis: if fkctr[P1]==0 goto P2 */ #define OP_MemMax 137 /* synopsis: r[P1]=max(r[P1],r[P2]) */ #define OP_IfPos 138 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ #define OP_OffsetLimit 139 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ #define OP_IfNotZero 140 /* synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2 */ #define OP_DecrJumpZero 141 /* synopsis: if (--r[P1])==0 goto P2 */ #define OP_JumpZeroIncr 142 /* synopsis: if (r[P1]++)==0 ) goto P2 */ #define OP_AggStep0 143 /* synopsis: accum=r[P3] step(r[P2@P5]) */ #define OP_AggStep 144 /* synopsis: accum=r[P3] step(r[P2@P5]) */ #define OP_AggFinal 145 /* synopsis: accum=r[P1] N=P2 */ #define OP_IncrVacuum 146 #define OP_Expire 147 #define OP_TableLock 148 /* synopsis: iDb=P1 root=P2 write=P3 */ #define OP_VBegin 149 #define OP_VCreate 150 #define OP_VDestroy 151 #define OP_VOpen 152 #define OP_VColumn 153 /* synopsis: r[P3]=vcolumn(P2) */ #define OP_VNext 154 #define OP_VRename 155 #define OP_Pagecount 156 #define OP_MaxPgcnt 157 #define OP_Init 158 /* synopsis: Start at P2 */ #define OP_CursorHint 159 #define OP_Noop 160 #define OP_Explain 161 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c ** are encoded into bitvectors as follows: */ #define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */ #define OPFLG_IN1 0x02 /* in1: P1 is an input */ #define OPFLG_IN2 0x04 /* in2: P2 is an input */ #define OPFLG_IN3 0x08 /* in3: P3 is an input */ #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ #define OPFLG_INITIALIZER {\ /* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,\ /* 8 */ 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x02,\ /* 16 */ 0x01, 0x02, 0x03, 0x12, 0x08, 0x00, 0x10, 0x10,\ /* 24 */ 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,\ /* 32 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02,\ /* 40 */ 0x02, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x00,\ /* 48 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,\ /* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,\ /* 64 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x26,\ /* 72 */ 0x26, 0x10, 0x10, 0x00, 0x03, 0x03, 0x0b, 0x0b,\ /* 80 */ 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x26, 0x26, 0x26,\ /* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00,\ /* 96 */ 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ /* 104 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x00,\ /* 112 */ 0x00, 0x10, 0x01, 0x01, 0x01, 0x01, 0x10, 0x00,\ /* 120 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 128 */ 0x00, 0x06, 0x23, 0x0b, 0x01, 0x10, 0x10, 0x00,\ /* 136 */ 0x01, 0x04, 0x03, 0x1a, 0x03, 0x03, 0x03, 0x00,\ /* 144 */ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 152 */ 0x00, 0x00, 0x01, 0x00, 0x10, 0x10, 0x01, 0x00,\ /* 160 */ 0x00, 0x00,} /************** End of opcodes.h *********************************************/ /************** Continuing where we left off in vdbe.h ***********************/ /* ** Prototypes for the VDBE interface. See comments on the implementation ** for a description of what each of these routines does. */ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse*); SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int); SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int); SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int); SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe*,int); SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe*,int,const char*); SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...); SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe*,int); #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N); #else # define sqlite3VdbeVerifyNoMallocRequired(A,B) #endif SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno); SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); |
︙ | ︙ | |||
11197 11198 11199 11200 11201 11202 11203 | /* ** Flags for sqlite3PagerSetFlags() */ #define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */ #define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */ #define PAGER_SYNCHRONOUS_FULL 0x03 /* PRAGMA synchronous=FULL */ | > | | | | | | 11214 11215 11216 11217 11218 11219 11220 11221 11222 11223 11224 11225 11226 11227 11228 11229 11230 11231 11232 11233 | /* ** Flags for sqlite3PagerSetFlags() */ #define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */ #define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */ #define PAGER_SYNCHRONOUS_FULL 0x03 /* PRAGMA synchronous=FULL */ #define PAGER_SYNCHRONOUS_EXTRA 0x04 /* PRAGMA synchronous=EXTRA */ #define PAGER_SYNCHRONOUS_MASK 0x07 /* Mask for four values above */ #define PAGER_FULLFSYNC 0x08 /* PRAGMA fullfsync=ON */ #define PAGER_CKPT_FULLFSYNC 0x10 /* PRAGMA checkpoint_fullfsync=ON */ #define PAGER_CACHESPILL 0x20 /* PRAGMA cache_spill=ON */ #define PAGER_FLAGS_MASK 0x38 /* All above except SYNCHRONOUS */ /* ** The remainder of this file contains the declarations of the functions ** that make up the Pager sub-system API. See source code comments for ** a detailed description of each routine. */ |
︙ | ︙ | |||
11961 11962 11963 11964 11965 11966 11967 11968 | ** with a particular database connection. Hence, schema information cannot ** be stored in lookaside because in shared cache mode the schema information ** is shared by multiple database connections. Therefore, while parsing ** schema information, the Lookaside.bEnabled flag is cleared so that ** lookaside allocations are not used to construct the schema objects. */ struct Lookaside { u16 sz; /* Size of each buffer in bytes */ | > < | 11979 11980 11981 11982 11983 11984 11985 11986 11987 11988 11989 11990 11991 11992 11993 11994 | ** with a particular database connection. Hence, schema information cannot ** be stored in lookaside because in shared cache mode the schema information ** is shared by multiple database connections. Therefore, while parsing ** schema information, the Lookaside.bEnabled flag is cleared so that ** lookaside allocations are not used to construct the schema objects. */ struct Lookaside { u32 bDisable; /* Only operate the lookaside when zero */ u16 sz; /* Size of each buffer in bytes */ u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ int nOut; /* Number of buffers currently checked out */ int mxOut; /* Highwater mark for nOut */ int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ LookasideSlot *pFree; /* List of available buffers */ void *pStart; /* First byte of available memory space */ void *pEnd; /* First byte past end of available space */ |
︙ | ︙ | |||
12045 12046 12047 12048 12049 12050 12051 12052 12053 12054 12055 12056 12057 12058 | int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ u16 dbOptFlags; /* Flags to enable/disable optimizations */ u8 enc; /* Text encoding */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ u8 dfltLockMode; /* Default locking-mode for attached dbs */ signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ u8 suppressErr; /* Do not issue error messages if true */ u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ int nextPagesize; /* Pagesize after VACUUM if >0 */ u32 magic; /* Magic number for detect library misuse */ | > | 12063 12064 12065 12066 12067 12068 12069 12070 12071 12072 12073 12074 12075 12076 12077 | int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ u16 dbOptFlags; /* Flags to enable/disable optimizations */ u8 enc; /* Text encoding */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ u8 bBenignMalloc; /* Do not require OOMs if true */ u8 dfltLockMode; /* Default locking-mode for attached dbs */ signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ u8 suppressErr; /* Do not issue error messages if true */ u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ int nextPagesize; /* Pagesize after VACUUM if >0 */ u32 magic; /* Magic number for detect library misuse */ |
︙ | ︙ | |||
12153 12154 12155 12156 12157 12158 12159 | #define ENC(db) ((db)->enc) /* ** Possible values for the sqlite3.flags. */ #define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ #define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */ | > | | | < | 12172 12173 12174 12175 12176 12177 12178 12179 12180 12181 12182 12183 12184 12185 12186 12187 12188 12189 | #define ENC(db) ((db)->enc) /* ** Possible values for the sqlite3.flags. */ #define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ #define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */ #define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */ #define SQLITE_FullFSync 0x00000008 /* Use full fsync on the backend */ #define SQLITE_CkptFullFSync 0x00000010 /* Use full fsync for checkpoint */ #define SQLITE_CacheSpill 0x00000020 /* OK to spill pager cache */ #define SQLITE_ShortColNames 0x00000040 /* Show short columns names */ #define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */ /* DELETE, or UPDATE and return */ /* the count using a callback. */ #define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ /* result set is empty */ #define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */ |
︙ | ︙ | |||
13508 13509 13510 13511 13512 13513 13514 | }; /* ** During code generation of statements that do inserts into AUTOINCREMENT ** tables, the following information is attached to the Table.u.autoInc.p ** pointer of each autoincrement table to record some side information that ** the code generator needs. We have to keep per-table autoincrement | | | 13527 13528 13529 13530 13531 13532 13533 13534 13535 13536 13537 13538 13539 13540 13541 | }; /* ** During code generation of statements that do inserts into AUTOINCREMENT ** tables, the following information is attached to the Table.u.autoInc.p ** pointer of each autoincrement table to record some side information that ** the code generator needs. We have to keep per-table autoincrement ** information in case inserts are done within triggers. Triggers do not ** normally coordinate their activities, but we do need to coordinate the ** loading and saving of autoincrement information. */ struct AutoincInfo { AutoincInfo *pNext; /* Next info block in a list of them all */ Table *pTab; /* Table this info block refers to */ int iDb; /* Index in sqlite3.aDb[] of database holding pTab */ |
︙ | ︙ | |||
13600 13601 13602 13603 13604 13605 13606 13607 13608 13609 13610 13611 13612 13613 | u8 checkSchema; /* Causes schema cookie check after an error */ u8 nested; /* Number of nested calls to the parser/code generator */ u8 nTempReg; /* Number of temporary registers in aTempReg[] */ u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ u8 mayAbort; /* True if statement may throw an ABORT exception */ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ u8 okConstFactor; /* OK to factor out constants */ int aTempReg[8]; /* Holding area for temporary registers */ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ | > | 13619 13620 13621 13622 13623 13624 13625 13626 13627 13628 13629 13630 13631 13632 13633 | u8 checkSchema; /* Causes schema cookie check after an error */ u8 nested; /* Number of nested calls to the parser/code generator */ u8 nTempReg; /* Number of temporary registers in aTempReg[] */ u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ u8 mayAbort; /* True if statement may throw an ABORT exception */ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ u8 okConstFactor; /* OK to factor out constants */ u8 disableLookaside; /* Number of times lookaside has been disabled */ int aTempReg[8]; /* Holding area for temporary registers */ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ |
︙ | ︙ | |||
13714 13715 13716 13717 13718 13719 13720 | const char *zAuthContext; /* Put saved Parse.zAuthContext here */ Parse *pParse; /* The Parse structure */ }; /* ** Bitfield flags for P5 value in various opcodes. */ | | > | > > | 13734 13735 13736 13737 13738 13739 13740 13741 13742 13743 13744 13745 13746 13747 13748 13749 13750 13751 13752 13753 13754 13755 13756 13757 13758 13759 13760 13761 13762 13763 | const char *zAuthContext; /* Put saved Parse.zAuthContext here */ Parse *pParse; /* The Parse structure */ }; /* ** Bitfield flags for P5 value in various opcodes. */ #define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */ /* Also used in P2 (not P5) of OP_Delete */ #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */ #define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */ #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ #define OPFLAG_APPEND 0x08 /* This is likely to be an append */ #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ #define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */ #define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */ #define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */ #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ #define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete: keep cursor position */ #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ /* * Each trigger present in the database schema is stored as an instance of * struct Trigger. * * Pointers to instances of struct Trigger are stored in two ways. * 1. In the "trigHash" hash table (part of the sqlite3* that represents the |
︙ | ︙ | |||
13845 13846 13847 13848 13849 13850 13851 | sqlite3 *db; /* Optional database for lookaside. Can be NULL */ char *zBase; /* A base allocation. Not from malloc. */ char *zText; /* The string collected so far */ u32 nChar; /* Length of the string so far */ u32 nAlloc; /* Amount of space allocated in zText */ u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */ | | > > > > > > | 13868 13869 13870 13871 13872 13873 13874 13875 13876 13877 13878 13879 13880 13881 13882 13883 13884 13885 13886 13887 13888 13889 13890 13891 | sqlite3 *db; /* Optional database for lookaside. Can be NULL */ char *zBase; /* A base allocation. Not from malloc. */ char *zText; /* The string collected so far */ u32 nChar; /* Length of the string so far */ u32 nAlloc; /* Amount of space allocated in zText */ u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */ u8 printfFlags; /* SQLITE_PRINTF flags below */ }; #define STRACCUM_NOMEM 1 #define STRACCUM_TOOBIG 2 #define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */ #define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */ #define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */ #define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) /* ** A pointer to this structure is used to communicate information ** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback. */ typedef struct { sqlite3 *db; /* The database being initialized */ |
︙ | ︙ | |||
14083 14084 14085 14086 14087 14088 14089 14090 14091 14092 14093 14094 14095 14096 | SQLITE_PRIVATE int sqlite3MallocInit(void); SQLITE_PRIVATE void sqlite3MallocEnd(void); SQLITE_PRIVATE void *sqlite3Malloc(u64); SQLITE_PRIVATE void *sqlite3MallocZero(u64); SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, u64); SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, u64); SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*); SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64); SQLITE_PRIVATE void *sqlite3Realloc(void*, u64); SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*); SQLITE_PRIVATE int sqlite3MallocSize(void*); | > | 14112 14113 14114 14115 14116 14117 14118 14119 14120 14121 14122 14123 14124 14125 14126 | SQLITE_PRIVATE int sqlite3MallocInit(void); SQLITE_PRIVATE void sqlite3MallocEnd(void); SQLITE_PRIVATE void *sqlite3Malloc(u64); SQLITE_PRIVATE void *sqlite3MallocZero(u64); SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, u64); SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, u64); SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3*, u64); SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*); SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64); SQLITE_PRIVATE void *sqlite3Realloc(void*, u64); SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*); SQLITE_PRIVATE int sqlite3MallocSize(void*); |
︙ | ︙ | |||
14165 14166 14167 14168 14169 14170 14171 | */ struct PrintfArguments { int nArg; /* Total number of arguments */ int nUsed; /* Number of arguments used so far */ sqlite3_value **apArg; /* The argument values */ }; | < < | | > | 14195 14196 14197 14198 14199 14200 14201 14202 14203 14204 14205 14206 14207 14208 14209 14210 14211 14212 14213 14214 14215 14216 14217 14218 14219 14220 14221 14222 14223 14224 14225 14226 14227 14228 14229 14230 14231 | */ struct PrintfArguments { int nArg; /* Total number of arguments */ int nUsed; /* Number of arguments used so far */ sqlite3_value **apArg; /* The argument values */ }; SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, const char*, va_list); SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, const char*, ...); SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...); #endif #if defined(SQLITE_TEST) SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*); #endif #if defined(SQLITE_DEBUG) SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); #endif SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); SQLITE_PRIVATE int sqlite3Dequote(char*); SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*); SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int); SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **); SQLITE_PRIVATE void sqlite3FinishCoding(Parse*); SQLITE_PRIVATE int sqlite3GetTempReg(Parse*); SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int); SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int); SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int); |
︙ | ︙ | |||
14636 14637 14638 14639 14640 14641 14642 14643 14644 14645 14646 14647 14648 14649 | SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*); #endif SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*), FuncDestructor *pDestructor ); SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int); SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*); SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char); | > > | 14665 14666 14667 14668 14669 14670 14671 14672 14673 14674 14675 14676 14677 14678 14679 14680 | SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*); #endif SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*), FuncDestructor *pDestructor ); SQLITE_PRIVATE void sqlite3OomFault(sqlite3*); SQLITE_PRIVATE void sqlite3OomClear(sqlite3*); SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int); SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*); SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char); |
︙ | ︙ | |||
15732 15733 15734 15735 15736 15737 15738 15739 15740 15741 15742 15743 15744 15745 15746 15747 15748 15749 15750 15751 15752 15753 15754 15755 15756 15757 15758 15759 15760 15761 15762 15763 15764 15765 15766 15767 15768 15769 15770 15771 | ** * A b-tree cursor ** - In the main database or in an ephemeral database ** - On either an index or a table ** * A sorter ** * A virtual table ** * A one-row "pseudotable" stored in a single register */ struct VdbeCursor { u8 eCurType; /* One of the CURTYPE_* values above */ i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ u8 nullRow; /* True if pointing to a row with no data */ u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ u8 isTable; /* True for rowid tables. False for indexes */ #ifdef SQLITE_DEBUG u8 seekOp; /* Most recent seek operation on this cursor */ #endif Bool isEphemeral:1; /* True for an ephemeral table */ Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ Pgno pgnoRoot; /* Root page of the open btree cursor */ i16 nField; /* Number of fields in the header */ u16 nHdrParsed; /* Number of header fields parsed so far */ union { BtCursor *pCursor; /* CURTYPE_BTREE. Btree cursor */ sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */ VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ } uc; Btree *pBt; /* Separate file holding temporary table */ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ int seekResult; /* Result of previous sqlite3BtreeMoveto() */ i64 seqCount; /* Sequence counter */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ #ifdef SQLITE_ENABLE_COLUMN_USED_MASK u64 maskUsed; /* Mask of columns used by this cursor */ #endif /* Cached information about the header for the data record that the ** cursor is currently pointing to. Only valid if cacheStatus matches ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of | > > > > | 15763 15764 15765 15766 15767 15768 15769 15770 15771 15772 15773 15774 15775 15776 15777 15778 15779 15780 15781 15782 15783 15784 15785 15786 15787 15788 15789 15790 15791 15792 15793 15794 15795 15796 15797 15798 15799 15800 15801 15802 15803 15804 15805 15806 | ** * A b-tree cursor ** - In the main database or in an ephemeral database ** - On either an index or a table ** * A sorter ** * A virtual table ** * A one-row "pseudotable" stored in a single register */ typedef struct VdbeCursor VdbeCursor; struct VdbeCursor { u8 eCurType; /* One of the CURTYPE_* values above */ i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ u8 nullRow; /* True if pointing to a row with no data */ u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ u8 isTable; /* True for rowid tables. False for indexes */ #ifdef SQLITE_DEBUG u8 seekOp; /* Most recent seek operation on this cursor */ u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */ #endif Bool isEphemeral:1; /* True for an ephemeral table */ Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ Pgno pgnoRoot; /* Root page of the open btree cursor */ i16 nField; /* Number of fields in the header */ u16 nHdrParsed; /* Number of header fields parsed so far */ union { BtCursor *pCursor; /* CURTYPE_BTREE. Btree cursor */ sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */ VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ } uc; Btree *pBt; /* Separate file holding temporary table */ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ int seekResult; /* Result of previous sqlite3BtreeMoveto() */ i64 seqCount; /* Sequence counter */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ int *aAltMap; /* Mapping from table to index column numbers */ #ifdef SQLITE_ENABLE_COLUMN_USED_MASK u64 maskUsed; /* Mask of columns used by this cursor */ #endif /* Cached information about the header for the data record that the ** cursor is currently pointing to. Only valid if cacheStatus matches ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of |
︙ | ︙ | |||
15782 15783 15784 15785 15786 15787 15788 | const u8 *aRow; /* Data for the current row, if all on one page */ u32 *aOffset; /* Pointer to aType[nField] */ u32 aType[1]; /* Type values for all entries in the record */ /* 2*nField extra array elements allocated for aType[], beyond the one ** static element declared in the structure. nField total array slots for ** aType[] and nField+1 array slots for aOffset[] */ }; | < | 15817 15818 15819 15820 15821 15822 15823 15824 15825 15826 15827 15828 15829 15830 | const u8 *aRow; /* Data for the current row, if all on one page */ u32 *aOffset; /* Pointer to aType[nField] */ u32 aType[1]; /* Type values for all entries in the record */ /* 2*nField extra array elements allocated for aType[], beyond the one ** static element declared in the structure. nField total array slots for ** aType[] and nField+1 array slots for aOffset[] */ }; /* ** When a sub-program is executed (OP_Program), a structure of this type ** is allocated to store the current value of the program counter, as ** well as the current memory cell array and various other frame specific ** values stored in the Vdbe struct. When the sub-program is finished, ** these values are copied back to the Vdbe from the VdbeFrame structure, |
︙ | ︙ | |||
15893 15894 15895 15896 15897 15898 15899 | #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_AffMask 0x001f /* Mask of affinity bits */ #define MEM_RowSet 0x0020 /* Value is a RowSet object */ #define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ #define MEM_Undefined 0x0080 /* Value is undefined */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ | | > > > > > > > | 15927 15928 15929 15930 15931 15932 15933 15934 15935 15936 15937 15938 15939 15940 15941 15942 15943 15944 15945 15946 15947 15948 15949 15950 15951 15952 15953 15954 15955 15956 15957 15958 15959 15960 15961 15962 15963 15964 15965 | #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_AffMask 0x001f /* Mask of affinity bits */ #define MEM_RowSet 0x0020 /* Value is a RowSet object */ #define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ #define MEM_Undefined 0x0080 /* Value is undefined */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ #define MEM_TypeMask 0x81ff /* Mask of type bits */ /* Whenever Mem contains a valid string or blob representation, one of ** the following flags must be set to determine the memory management ** policy for Mem.z. The MEM_Term flag tells us whether or not the ** string is \000 or \u0000 terminated */ #define MEM_Term 0x0200 /* String rep is nul terminated */ #define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */ #define MEM_Static 0x0800 /* Mem.z points to a static string */ #define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */ #define MEM_Agg 0x2000 /* Mem.z points to an agg function context */ #define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */ #define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */ #ifdef SQLITE_OMIT_INCRBLOB #undef MEM_Zero #define MEM_Zero 0x0000 #endif /* Return TRUE if Mem X contains dynamically allocated content - anything ** that needs to be deallocated to avoid a leak. */ #define VdbeMemDynamic(X) \ (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) /* ** Clear any existing type flags from a Mem and replace them with f */ #define MemSetTypeFlag(p, f) \ ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f) |
︙ | ︙ | |||
16081 16082 16083 16084 16085 16086 16087 | /* ** Function prototypes */ SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...); SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); | | | 16122 16123 16124 16125 16126 16127 16128 16129 16130 16131 16132 16133 16134 16135 16136 | /* ** Function prototypes */ SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...); SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, int*); SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*); #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*); #endif SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8); SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int, u32*); |
︙ | ︙ | |||
16127 16128 16129 16130 16131 16132 16133 | SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8); SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); | < < | 16168 16169 16170 16171 16172 16173 16174 16175 16176 16177 16178 16179 16180 16181 | SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8); SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); SQLITE_PRIVATE const char *sqlite3OpcodeName(int); SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n); SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); |
︙ | ︙ | |||
17490 17491 17492 17493 17494 17495 17496 | testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ); if( n<sizeof(zBuf) ){ z = zBuf; }else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){ sqlite3_result_error_toobig(context); return; }else{ | | | 17529 17530 17531 17532 17533 17534 17535 17536 17537 17538 17539 17540 17541 17542 17543 | testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ); if( n<sizeof(zBuf) ){ z = zBuf; }else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){ sqlite3_result_error_toobig(context); return; }else{ z = sqlite3DbMallocRawNN(db, (int)n); if( z==0 ){ sqlite3_result_error_nomem(context); return; } } computeJD(&x); computeYMD_HMS(&x); |
︙ | ︙ | |||
20079 20080 20081 20082 20083 20084 20085 20086 20087 20088 | #endif mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize; while( ALWAYS(iLogsize<LOGMAX) ){ int iBuddy; if( (iBlock>>iLogsize) & 1 ){ iBuddy = iBlock - size; }else{ iBuddy = iBlock + size; } | > > < < | 20118 20119 20120 20121 20122 20123 20124 20125 20126 20127 20128 20129 20130 20131 20132 20133 20134 20135 20136 | #endif mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize; while( ALWAYS(iLogsize<LOGMAX) ){ int iBuddy; if( (iBlock>>iLogsize) & 1 ){ iBuddy = iBlock - size; assert( iBuddy>=0 ); }else{ iBuddy = iBlock + size; if( iBuddy>=mem5.nBlock ) break; } if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break; memsys5Unlink(iBuddy, iLogsize); iLogsize++; if( iBuddy<iBlock ){ mem5.aCtrl[iBuddy] = CTRL_FREE | iLogsize; mem5.aCtrl[iBlock] = 0; iBlock = iBuddy; |
︙ | ︙ | |||
22384 22385 22386 22387 22388 22389 22390 | } /* ** Allocate and zero memory. If the allocation fails, make ** the mallocFailed flag in the connection pointer. */ SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, u64 n){ | > > | < | > | > > > > > > > > > > > > | 22423 22424 22425 22426 22427 22428 22429 22430 22431 22432 22433 22434 22435 22436 22437 22438 22439 22440 22441 22442 22443 22444 22445 22446 22447 22448 22449 22450 22451 22452 22453 22454 | } /* ** Allocate and zero memory. If the allocation fails, make ** the mallocFailed flag in the connection pointer. */ SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, u64 n){ void *p; testcase( db==0 ); p = sqlite3DbMallocRaw(db, n); if( p ) memset(p, 0, (size_t)n); return p; } /* Finish the work of sqlite3DbMallocRawNN for the unusual and ** slower case when the allocation cannot be fulfilled using lookaside. */ static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){ void *p; assert( db!=0 ); p = sqlite3Malloc(n); if( !p ) sqlite3OomFault(db); sqlite3MemdebugSetType(p, (db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); return p; } /* ** Allocate memory, either lookaside (if possible) or heap. ** If the allocation fails, set the mallocFailed flag in ** the connection pointer. |
︙ | ︙ | |||
22409 22410 22411 22412 22413 22414 22415 22416 | ** ** int *a = (int*)sqlite3DbMallocRaw(db, 100); ** int *b = (int*)sqlite3DbMallocRaw(db, 200); ** if( b ) a[10] = 9; ** ** In other words, if a subsequent malloc (ex: "b") worked, it is assumed ** that all prior mallocs (ex: "a") worked too. */ | > > > < > > | < > > > > < | | > | < | > | | | | | | | | | | | | | > > | < > > > | < < < < | > | < < < > > > > > > > | < < < < < < | | | | 22462 22463 22464 22465 22466 22467 22468 22469 22470 22471 22472 22473 22474 22475 22476 22477 22478 22479 22480 22481 22482 22483 22484 22485 22486 22487 22488 22489 22490 22491 22492 22493 22494 22495 22496 22497 22498 22499 22500 22501 22502 22503 22504 22505 22506 22507 22508 22509 22510 22511 22512 22513 22514 22515 22516 22517 22518 22519 22520 22521 22522 22523 22524 22525 22526 22527 22528 22529 22530 22531 22532 22533 22534 22535 22536 22537 22538 22539 22540 22541 22542 22543 22544 22545 22546 22547 22548 22549 22550 22551 22552 22553 22554 22555 22556 | ** ** int *a = (int*)sqlite3DbMallocRaw(db, 100); ** int *b = (int*)sqlite3DbMallocRaw(db, 200); ** if( b ) a[10] = 9; ** ** In other words, if a subsequent malloc (ex: "b") worked, it is assumed ** that all prior mallocs (ex: "a") worked too. ** ** The sqlite3MallocRawNN() variant guarantees that the "db" parameter is ** not a NULL pointer. */ SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ void *p; if( db ) return sqlite3DbMallocRawNN(db, n); p = sqlite3Malloc(n); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); return p; } SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){ #ifndef SQLITE_OMIT_LOOKASIDE LookasideSlot *pBuf; assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); assert( db->pnBytesFreed==0 ); if( db->lookaside.bDisable==0 ){ assert( db->mallocFailed==0 ); if( n>db->lookaside.sz ){ db->lookaside.anStat[1]++; }else if( (pBuf = db->lookaside.pFree)==0 ){ db->lookaside.anStat[2]++; }else{ db->lookaside.pFree = pBuf->pNext; db->lookaside.nOut++; db->lookaside.anStat[0]++; if( db->lookaside.nOut>db->lookaside.mxOut ){ db->lookaside.mxOut = db->lookaside.nOut; } return (void*)pBuf; } }else if( db->mallocFailed ){ return 0; } #else assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); assert( db->pnBytesFreed==0 ); if( db->mallocFailed ){ return 0; } #endif return dbMallocRawFinish(db, n); } /* Forward declaration */ static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n); /* ** Resize the block of memory pointed to by p to n bytes. If the ** resize fails, set the mallocFailed flag in the connection object. */ SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ assert( db!=0 ); if( p==0 ) return sqlite3DbMallocRawNN(db, n); assert( sqlite3_mutex_held(db->mutex) ); if( isLookaside(db,p) && n<=db->lookaside.sz ) return p; return dbReallocFinish(db, p, n); } static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){ void *pNew = 0; assert( db!=0 ); assert( p!=0 ); if( db->mallocFailed==0 ){ if( isLookaside(db, p) ){ pNew = sqlite3DbMallocRawNN(db, n); if( pNew ){ memcpy(pNew, p, db->lookaside.sz); sqlite3DbFree(db, p); } }else{ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); pNew = sqlite3_realloc64(p, n); if( !pNew ){ sqlite3OomFault(db); } sqlite3MemdebugSetType(pNew, (db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); } } return pNew; } /* ** Attempt to reallocate p. If the reallocation fails, then free p |
︙ | ︙ | |||
22525 22526 22527 22528 22529 22530 22531 22532 22533 22534 22535 | if( zNew ){ memcpy(zNew, z, n); } return zNew; } SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){ char *zNew; if( z==0 ){ return 0; } assert( (n&0x7fffffff)==n ); | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 22584 22585 22586 22587 22588 22589 22590 22591 22592 22593 22594 22595 22596 22597 22598 22599 22600 22601 22602 22603 22604 22605 22606 22607 22608 22609 22610 22611 22612 22613 22614 22615 22616 22617 22618 22619 22620 22621 22622 22623 22624 22625 22626 22627 22628 22629 22630 22631 22632 22633 22634 22635 22636 22637 22638 22639 22640 22641 22642 22643 22644 22645 22646 22647 22648 22649 22650 22651 22652 22653 22654 22655 | if( zNew ){ memcpy(zNew, z, n); } return zNew; } SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){ char *zNew; assert( db!=0 ); if( z==0 ){ return 0; } assert( (n&0x7fffffff)==n ); zNew = sqlite3DbMallocRawNN(db, n+1); if( zNew ){ memcpy(zNew, z, (size_t)n); zNew[n] = 0; } return zNew; } /* ** Free any prior content in *pz and replace it with a copy of zNew. */ SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){ sqlite3DbFree(db, *pz); *pz = sqlite3DbStrDup(db, zNew); } /* ** Call this routine to record the fact that an OOM (out-of-memory) error ** has happened. This routine will set db->mallocFailed, and also ** temporarily disable the lookaside memory allocator and interrupt ** any running VDBEs. */ SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){ if( db->mallocFailed==0 && db->bBenignMalloc==0 ){ db->mallocFailed = 1; if( db->nVdbeExec>0 ){ db->u1.isInterrupted = 1; } db->lookaside.bDisable++; } } /* ** This routine reactivates the memory allocator and clears the ** db->mallocFailed flag as necessary. ** ** The memory allocator is not restarted if there are running ** VDBEs. */ SQLITE_PRIVATE void sqlite3OomClear(sqlite3 *db){ if( db->mallocFailed && db->nVdbeExec==0 ){ db->mallocFailed = 0; db->u1.isInterrupted = 0; assert( db->lookaside.bDisable>0 ); db->lookaside.bDisable--; } } /* ** Take actions at the end of an API call to indicate an OOM error */ static SQLITE_NOINLINE int apiOomError(sqlite3 *db){ sqlite3OomClear(db); sqlite3Error(db, SQLITE_NOMEM); return SQLITE_NOMEM; } /* ** This function must be called before exiting any API function (i.e. ** returning control to the user) that has called sqlite3_malloc or |
︙ | ︙ | |||
22754 22755 22756 22757 22758 22759 22760 | #define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */ /* ** Render a string given by "fmt" into the StrAccum object. */ SQLITE_PRIVATE void sqlite3VXPrintf( StrAccum *pAccum, /* Accumulate results here */ | < | 22846 22847 22848 22849 22850 22851 22852 22853 22854 22855 22856 22857 22858 22859 | #define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */ /* ** Render a string given by "fmt" into the StrAccum object. */ SQLITE_PRIVATE void sqlite3VXPrintf( StrAccum *pAccum, /* Accumulate results here */ const char *fmt, /* Format string */ va_list ap /* arguments */ ){ int c; /* Next character in the format string */ char *bufpt; /* Pointer to the conversion buffer */ int precision; /* Precision of the current field */ int length; /* Length of the field */ |
︙ | ︙ | |||
22794 22795 22796 22797 22798 22799 22800 | etByte flag_dp; /* True if decimal point should be shown */ etByte flag_rtz; /* True if trailing zeros should be removed */ #endif PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ char buf[etBUFSIZE]; /* Conversion buffer */ bufpt = 0; | | | | | 22885 22886 22887 22888 22889 22890 22891 22892 22893 22894 22895 22896 22897 22898 22899 22900 22901 22902 22903 | etByte flag_dp; /* True if decimal point should be shown */ etByte flag_rtz; /* True if trailing zeros should be removed */ #endif PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ char buf[etBUFSIZE]; /* Conversion buffer */ bufpt = 0; if( pAccum->printfFlags ){ if( (bArgList = (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){ pArgList = va_arg(ap, PrintfArguments*); } useIntern = pAccum->printfFlags & SQLITE_PRINTF_INTERNAL; }else{ bArgList = useIntern = 0; } for(; (c=(*fmt))!=0; ++fmt){ if( c!='%' ){ bufpt = (char *)fmt; #if HAVE_STRCHRNUL |
︙ | ︙ | |||
23349 23350 23351 23352 23353 23354 23355 | return 0; } if( p->mxAlloc==0 ){ N = p->nAlloc - p->nChar - 1; setStrAccumError(p, STRACCUM_TOOBIG); return N; }else{ | | | | | | | | 23440 23441 23442 23443 23444 23445 23446 23447 23448 23449 23450 23451 23452 23453 23454 23455 23456 23457 23458 23459 23460 23461 23462 23463 23464 23465 23466 23467 23468 23469 23470 23471 23472 23473 23474 23475 23476 23477 23478 23479 23480 23481 23482 23483 23484 23485 23486 23487 23488 23489 23490 23491 23492 23493 23494 23495 23496 23497 23498 23499 23500 23501 23502 23503 23504 23505 23506 23507 23508 23509 23510 23511 23512 23513 23514 23515 23516 | return 0; } if( p->mxAlloc==0 ){ N = p->nAlloc - p->nChar - 1; setStrAccumError(p, STRACCUM_TOOBIG); return N; }else{ char *zOld = isMalloced(p) ? p->zText : 0; i64 szNew = p->nChar; assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); szNew += N + 1; if( szNew+p->nChar<=p->mxAlloc ){ /* Force exponential buffer size growth as long as it does not overflow, ** to avoid having to call this routine too often */ szNew += p->nChar; } if( szNew > p->mxAlloc ){ sqlite3StrAccumReset(p); setStrAccumError(p, STRACCUM_TOOBIG); return 0; }else{ p->nAlloc = (int)szNew; } if( p->db ){ zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); }else{ zNew = sqlite3_realloc64(zOld, p->nAlloc); } if( zNew ){ assert( p->zText!=0 || p->nChar==0 ); if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); p->zText = zNew; p->nAlloc = sqlite3DbMallocSize(p->db, zNew); p->printfFlags |= SQLITE_PRINTF_MALLOCED; }else{ sqlite3StrAccumReset(p); setStrAccumError(p, STRACCUM_NOMEM); return 0; } } return N; } /* ** Append N copies of character c to the given string buffer. */ SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){ testcase( p->nChar + (i64)N > 0x7fffffff ); if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ return; } assert( (p->zText==p->zBase)==!isMalloced(p) ); while( (N--)>0 ) p->zText[p->nChar++] = c; } /* ** The StrAccum "p" is not large enough to accept N new bytes of z[]. ** So enlarge if first, then do the append. ** ** This is a helper routine to sqlite3StrAccumAppend() that does special-case ** work (enlarging the buffer) using tail recursion, so that the ** sqlite3StrAccumAppend() routine can use fast calling semantics. */ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ N = sqlite3StrAccumEnlarge(p, N); if( N>0 ){ memcpy(&p->zText[p->nChar], z, N); p->nChar += N; } assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); } /* ** Append N bytes of text from z to the StrAccum object. Increase the ** size of the memory allocation for StrAccum if necessary. */ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ |
︙ | ︙ | |||
23447 23448 23449 23450 23451 23452 23453 | /* ** Finish off a string by making sure it is zero-terminated. ** Return a pointer to the resulting string. Return a NULL ** pointer if any kind of error was encountered. */ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ if( p->zText ){ | | | | | | | | 23538 23539 23540 23541 23542 23543 23544 23545 23546 23547 23548 23549 23550 23551 23552 23553 23554 23555 23556 23557 23558 23559 23560 23561 23562 23563 23564 23565 23566 23567 23568 23569 23570 23571 23572 23573 23574 | /* ** Finish off a string by making sure it is zero-terminated. ** Return a pointer to the resulting string. Return a NULL ** pointer if any kind of error was encountered. */ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ if( p->zText ){ assert( (p->zText==p->zBase)==!isMalloced(p) ); p->zText[p->nChar] = 0; if( p->mxAlloc>0 && !isMalloced(p) ){ p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); if( p->zText ){ memcpy(p->zText, p->zBase, p->nChar+1); p->printfFlags |= SQLITE_PRINTF_MALLOCED; }else{ setStrAccumError(p, STRACCUM_NOMEM); } } } return p->zText; } /* ** Reset an StrAccum string. Reclaim all malloced memory. */ SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){ assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); if( isMalloced(p) ){ sqlite3DbFree(p->db, p->zText); p->printfFlags &= ~SQLITE_PRINTF_MALLOCED; } p->zText = 0; } /* ** Initialize a string accumulator. ** |
︙ | ︙ | |||
23495 23496 23497 23498 23499 23500 23501 | SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ p->zText = p->zBase = zBase; p->db = db; p->nChar = 0; p->nAlloc = n; p->mxAlloc = mx; p->accError = 0; | | > | | | 23586 23587 23588 23589 23590 23591 23592 23593 23594 23595 23596 23597 23598 23599 23600 23601 23602 23603 23604 23605 23606 23607 23608 23609 23610 23611 23612 23613 23614 23615 23616 23617 23618 | SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ p->zText = p->zBase = zBase; p->db = db; p->nChar = 0; p->nAlloc = n; p->mxAlloc = mx; p->accError = 0; p->printfFlags = 0; } /* ** Print into memory obtained from sqliteMalloc(). Use the internal ** %-conversion extensions. */ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ char *z; char zBase[SQLITE_PRINT_BUF_SIZE]; StrAccum acc; assert( db!=0 ); sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase), db->aLimit[SQLITE_LIMIT_LENGTH]); acc.printfFlags = SQLITE_PRINTF_INTERNAL; sqlite3VXPrintf(&acc, zFormat, ap); z = sqlite3StrAccumFinish(&acc); if( acc.accError==STRACCUM_NOMEM ){ sqlite3OomFault(db); } return z; } /* ** Print into memory obtained from sqliteMalloc(). Use the internal ** %-conversion extensions. |
︙ | ︙ | |||
23549 23550 23551 23552 23553 23554 23555 | return 0; } #endif #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); | | | 23641 23642 23643 23644 23645 23646 23647 23648 23649 23650 23651 23652 23653 23654 23655 | return 0; } #endif #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); sqlite3VXPrintf(&acc, zFormat, ap); z = sqlite3StrAccumFinish(&acc); return z; } /* ** Print into memory obtained from sqlite3_malloc()(). Omit the internal ** %-conversion extensions. |
︙ | ︙ | |||
23594 23595 23596 23597 23598 23599 23600 | if( zBuf==0 || zFormat==0 ) { (void)SQLITE_MISUSE_BKPT; if( zBuf ) zBuf[0] = 0; return zBuf; } #endif sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); | | | 23686 23687 23688 23689 23690 23691 23692 23693 23694 23695 23696 23697 23698 23699 23700 | if( zBuf==0 || zFormat==0 ) { (void)SQLITE_MISUSE_BKPT; if( zBuf ) zBuf[0] = 0; return zBuf; } #endif sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); sqlite3VXPrintf(&acc, zFormat, ap); return sqlite3StrAccumFinish(&acc); } SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ char *z; va_list ap; va_start(ap,zFormat); z = sqlite3_vsnprintf(n, zBuf, zFormat, ap); |
︙ | ︙ | |||
23625 23626 23627 23628 23629 23630 23631 | ** memory mutex is held do not use these mechanisms. */ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ StrAccum acc; /* String accumulator */ char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); | | | 23717 23718 23719 23720 23721 23722 23723 23724 23725 23726 23727 23728 23729 23730 23731 | ** memory mutex is held do not use these mechanisms. */ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ StrAccum acc; /* String accumulator */ char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); sqlite3VXPrintf(&acc, zFormat, ap); sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, sqlite3StrAccumFinish(&acc)); } /* ** Format and write a message to the log if logging is enabled. */ |
︙ | ︙ | |||
23654 23655 23656 23657 23658 23659 23660 | */ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){ va_list ap; StrAccum acc; char zBuf[500]; sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); va_start(ap,zFormat); | | | | | 23746 23747 23748 23749 23750 23751 23752 23753 23754 23755 23756 23757 23758 23759 23760 23761 23762 23763 23764 23765 23766 23767 23768 23769 23770 23771 23772 23773 23774 23775 23776 | */ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){ va_list ap; StrAccum acc; char zBuf[500]; sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); va_start(ap,zFormat); sqlite3VXPrintf(&acc, zFormat, ap); va_end(ap); sqlite3StrAccumFinish(&acc); fprintf(stdout,"%s", zBuf); fflush(stdout); } #endif /* ** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument ** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats. */ SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){ va_list ap; va_start(ap,zFormat); sqlite3VXPrintf(p, zFormat, ap); va_end(ap); } /************** End of printf.c **********************************************/ /************** Begin file treeview.c ****************************************/ /* ** 2015-06-08 |
︙ | ︙ | |||
23741 23742 23743 23744 23745 23746 23747 | if( p ){ for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){ sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4); } sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); } va_start(ap, zFormat); | | | 23833 23834 23835 23836 23837 23838 23839 23840 23841 23842 23843 23844 23845 23846 23847 | if( p ){ for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){ sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4); } sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); } va_start(ap, zFormat); sqlite3VXPrintf(&acc, zFormat, ap); va_end(ap); if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1); sqlite3StrAccumFinish(&acc); fprintf(stdout,"%s", zBuf); fflush(stdout); } |
︙ | ︙ | |||
23776 23777 23778 23779 23780 23781 23782 | if( pWith->nCte>0 ){ pView = sqlite3TreeViewPush(pView, 1); for(i=0; i<pWith->nCte; i++){ StrAccum x; char zLine[1000]; const struct Cte *pCte = &pWith->a[i]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); | | | | | | 23868 23869 23870 23871 23872 23873 23874 23875 23876 23877 23878 23879 23880 23881 23882 23883 23884 23885 23886 23887 23888 23889 23890 23891 23892 | if( pWith->nCte>0 ){ pView = sqlite3TreeViewPush(pView, 1); for(i=0; i<pWith->nCte; i++){ StrAccum x; char zLine[1000]; const struct Cte *pCte = &pWith->a[i]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); sqlite3XPrintf(&x, "%s", pCte->zName); if( pCte->pCols && pCte->pCols->nExpr>0 ){ char cSep = '('; int j; for(j=0; j<pCte->pCols->nExpr; j++){ sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName); cSep = ','; } sqlite3XPrintf(&x, ")"); } sqlite3XPrintf(&x, " AS"); sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1); sqlite3TreeViewSelect(pView, pCte->pSelect, 0); sqlite3TreeViewPop(pView); } sqlite3TreeViewPop(pView); } |
︙ | ︙ | |||
23837 23838 23839 23840 23841 23842 23843 | pView = sqlite3TreeViewPush(pView, (n--)>0); sqlite3TreeViewLine(pView, "FROM"); for(i=0; i<p->pSrc->nSrc; i++){ struct SrcList_item *pItem = &p->pSrc->a[i]; StrAccum x; char zLine[100]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); | | | | | | | | 23929 23930 23931 23932 23933 23934 23935 23936 23937 23938 23939 23940 23941 23942 23943 23944 23945 23946 23947 23948 23949 23950 23951 23952 23953 23954 23955 23956 | pView = sqlite3TreeViewPush(pView, (n--)>0); sqlite3TreeViewLine(pView, "FROM"); for(i=0; i<p->pSrc->nSrc; i++){ struct SrcList_item *pItem = &p->pSrc->a[i]; StrAccum x; char zLine[100]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor); if( pItem->zDatabase ){ sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName); }else if( pItem->zName ){ sqlite3XPrintf(&x, " %s", pItem->zName); } if( pItem->pTab ){ sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName); } if( pItem->zAlias ){ sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias); } if( pItem->fg.jointype & JT_LEFT ){ sqlite3XPrintf(&x, " LEFT-JOIN"); } sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1); if( pItem->pSelect ){ sqlite3TreeViewSelect(pView, pItem->pSelect, 0); } if( pItem->fg.isTabFunc ){ |
︙ | ︙ | |||
24897 24898 24899 24900 24901 24902 24903 | pMem->n = (int)(z - zOut); } *z = 0; assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len ); c = pMem->flags; sqlite3VdbeMemRelease(pMem); | | | 24989 24990 24991 24992 24993 24994 24995 24996 24997 24998 24999 25000 25001 25002 25003 | pMem->n = (int)(z - zOut); } *z = 0; assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len ); c = pMem->flags; sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Str|MEM_Term|(c&(MEM_AffMask|MEM_Subtype)); pMem->enc = desiredEnc; pMem->z = (char*)zOut; pMem->zMalloc = pMem->z; pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->z); translate_out: #if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) |
︙ | ︙ | |||
25347 25348 25349 25350 25351 25352 25353 25354 25355 25356 25357 25358 25359 25360 | }else{ z[j++] = z[i]; } } z[j] = 0; return j; } /* Convenient short-hand */ #define UpperToLower sqlite3UpperToLower /* ** Some systems have stricmp(). Others have strcasecmp(). Because ** there is no consistency, we will define our own. | > > > > > > > > | 25439 25440 25441 25442 25443 25444 25445 25446 25447 25448 25449 25450 25451 25452 25453 25454 25455 25456 25457 25458 25459 25460 | }else{ z[j++] = z[i]; } } z[j] = 0; return j; } /* ** Generate a Token object from a string */ SQLITE_PRIVATE void sqlite3TokenInit(Token *p, char *z){ p->z = z; p->n = sqlite3Strlen30(z); } /* Convenient short-hand */ #define UpperToLower sqlite3UpperToLower /* ** Some systems have stricmp(). Others have strcasecmp(). Because ** there is no consistency, we will define our own. |
︙ | ︙ | |||
26256 26257 26258 26259 26260 26261 26262 | ** binary value has been obtained from malloc and must be freed by ** the calling routine. */ SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ char *zBlob; int i; | | | 26356 26357 26358 26359 26360 26361 26362 26363 26364 26365 26366 26367 26368 26369 26370 | ** binary value has been obtained from malloc and must be freed by ** the calling routine. */ SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ char *zBlob; int i; zBlob = (char *)sqlite3DbMallocRawNN(db, n/2 + 1); n--; if( zBlob ){ for(i=0; i<n; i+=2){ zBlob[i/2] = (sqlite3HexToInt(z[i])<<4) | sqlite3HexToInt(z[i+1]); } zBlob[i/2] = 0; } |
︙ | ︙ | |||
26794 26795 26796 26797 26798 26799 26800 | || defined(SQLITE_DEBUG) #if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG) # define OpHelp(X) "\0" X #else # define OpHelp(X) #endif SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | | | | | | | | | | | | | | | | | | | | > < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | > > < < | > > | | < < | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | > < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 26894 26895 26896 26897 26898 26899 26900 26901 26902 26903 26904 26905 26906 26907 26908 26909 26910 26911 26912 26913 26914 26915 26916 26917 26918 26919 26920 26921 26922 26923 26924 26925 26926 26927 26928 26929 26930 26931 26932 26933 26934 26935 26936 26937 26938 26939 26940 26941 26942 26943 26944 26945 26946 26947 26948 26949 26950 26951 26952 26953 26954 26955 26956 26957 26958 26959 26960 26961 26962 26963 26964 26965 26966 26967 26968 26969 26970 26971 26972 26973 26974 26975 26976 26977 26978 26979 26980 26981 26982 26983 26984 26985 26986 26987 26988 26989 26990 26991 26992 26993 26994 26995 26996 26997 26998 26999 27000 27001 27002 27003 27004 27005 27006 27007 27008 27009 27010 27011 27012 27013 27014 27015 27016 27017 27018 27019 27020 27021 27022 27023 27024 27025 27026 27027 27028 27029 27030 27031 27032 27033 27034 27035 27036 27037 27038 27039 27040 27041 27042 27043 27044 27045 27046 27047 27048 27049 27050 27051 27052 27053 27054 27055 27056 27057 27058 27059 27060 27061 27062 27063 27064 27065 27066 27067 27068 27069 27070 | || defined(SQLITE_DEBUG) #if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG) # define OpHelp(X) "\0" X #else # define OpHelp(X) #endif SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ static const char *const azName[] = { /* 0 */ "Savepoint" OpHelp(""), /* 1 */ "AutoCommit" OpHelp(""), /* 2 */ "Transaction" OpHelp(""), /* 3 */ "SorterNext" OpHelp(""), /* 4 */ "PrevIfOpen" OpHelp(""), /* 5 */ "NextIfOpen" OpHelp(""), /* 6 */ "Prev" OpHelp(""), /* 7 */ "Next" OpHelp(""), /* 8 */ "Checkpoint" OpHelp(""), /* 9 */ "JournalMode" OpHelp(""), /* 10 */ "Vacuum" OpHelp(""), /* 11 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), /* 12 */ "VUpdate" OpHelp("data=r[P3@P2]"), /* 13 */ "Goto" OpHelp(""), /* 14 */ "Gosub" OpHelp(""), /* 15 */ "Return" OpHelp(""), /* 16 */ "InitCoroutine" OpHelp(""), /* 17 */ "EndCoroutine" OpHelp(""), /* 18 */ "Yield" OpHelp(""), /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), /* 20 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), /* 21 */ "Halt" OpHelp(""), /* 22 */ "Integer" OpHelp("r[P2]=P1"), /* 23 */ "Int64" OpHelp("r[P2]=P4"), /* 24 */ "String" OpHelp("r[P2]='P4' (len=P1)"), /* 25 */ "Null" OpHelp("r[P2..P3]=NULL"), /* 26 */ "SoftNull" OpHelp("r[P1]=NULL"), /* 27 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), /* 28 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), /* 29 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), /* 30 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), /* 31 */ "SCopy" OpHelp("r[P2]=r[P1]"), /* 32 */ "IntCopy" OpHelp("r[P2]=r[P1]"), /* 33 */ "ResultRow" OpHelp("output=r[P1@P2]"), /* 34 */ "CollSeq" OpHelp(""), /* 35 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"), /* 36 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"), /* 37 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), /* 38 */ "MustBeInt" OpHelp(""), /* 39 */ "RealAffinity" OpHelp(""), /* 40 */ "Cast" OpHelp("affinity(r[P1])"), /* 41 */ "Permutation" OpHelp(""), /* 42 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), /* 43 */ "Jump" OpHelp(""), /* 44 */ "Once" OpHelp(""), /* 45 */ "If" OpHelp(""), /* 46 */ "IfNot" OpHelp(""), /* 47 */ "Column" OpHelp("r[P3]=PX"), /* 48 */ "Affinity" OpHelp("affinity(r[P1@P2])"), /* 49 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), /* 50 */ "Count" OpHelp("r[P2]=count()"), /* 51 */ "ReadCookie" OpHelp(""), /* 52 */ "SetCookie" OpHelp(""), /* 53 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), /* 54 */ "OpenRead" OpHelp("root=P2 iDb=P3"), /* 55 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), /* 56 */ "OpenAutoindex" OpHelp("nColumn=P2"), /* 57 */ "OpenEphemeral" OpHelp("nColumn=P2"), /* 58 */ "SorterOpen" OpHelp(""), /* 59 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), /* 60 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), /* 61 */ "Close" OpHelp(""), /* 62 */ "ColumnsUsed" OpHelp(""), /* 63 */ "SeekLT" OpHelp("key=r[P3@P4]"), /* 64 */ "SeekLE" OpHelp("key=r[P3@P4]"), /* 65 */ "SeekGE" OpHelp("key=r[P3@P4]"), /* 66 */ "SeekGT" OpHelp("key=r[P3@P4]"), /* 67 */ "NoConflict" OpHelp("key=r[P3@P4]"), /* 68 */ "NotFound" OpHelp("key=r[P3@P4]"), /* 69 */ "Found" OpHelp("key=r[P3@P4]"), /* 70 */ "NotExists" OpHelp("intkey=r[P3]"), /* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), /* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), /* 73 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), /* 74 */ "NewRowid" OpHelp("r[P2]=rowid"), /* 75 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), /* 76 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), /* 77 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), /* 78 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"), /* 79 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"), /* 80 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"), /* 81 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"), /* 82 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"), /* 83 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"), /* 84 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), /* 85 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), /* 86 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), /* 87 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), /* 88 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), /* 89 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), /* 90 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), /* 91 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), /* 92 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), /* 93 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), /* 94 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), /* 95 */ "Delete" OpHelp(""), /* 96 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), /* 97 */ "String8" OpHelp("r[P2]='P4'"), /* 98 */ "ResetCount" OpHelp(""), /* 99 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), /* 100 */ "SorterData" OpHelp("r[P2]=data"), /* 101 */ "RowKey" OpHelp("r[P2]=key"), /* 102 */ "RowData" OpHelp("r[P2]=data"), /* 103 */ "Rowid" OpHelp("r[P2]=rowid"), /* 104 */ "NullRow" OpHelp(""), /* 105 */ "Last" OpHelp(""), /* 106 */ "SorterSort" OpHelp(""), /* 107 */ "Sort" OpHelp(""), /* 108 */ "Rewind" OpHelp(""), /* 109 */ "SorterInsert" OpHelp(""), /* 110 */ "IdxInsert" OpHelp("key=r[P2]"), /* 111 */ "IdxDelete" OpHelp("key=r[P2@P3]"), /* 112 */ "Seek" OpHelp("Move P3 to P1.rowid"), /* 113 */ "IdxRowid" OpHelp("r[P2]=rowid"), /* 114 */ "IdxLE" OpHelp("key=r[P3@P4]"), /* 115 */ "IdxGT" OpHelp("key=r[P3@P4]"), /* 116 */ "IdxLT" OpHelp("key=r[P3@P4]"), /* 117 */ "IdxGE" OpHelp("key=r[P3@P4]"), /* 118 */ "Destroy" OpHelp(""), /* 119 */ "Clear" OpHelp(""), /* 120 */ "ResetSorter" OpHelp(""), /* 121 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), /* 122 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), /* 123 */ "ParseSchema" OpHelp(""), /* 124 */ "LoadAnalysis" OpHelp(""), /* 125 */ "DropTable" OpHelp(""), /* 126 */ "DropIndex" OpHelp(""), /* 127 */ "DropTrigger" OpHelp(""), /* 128 */ "IntegrityCk" OpHelp(""), /* 129 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), /* 130 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), /* 131 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), /* 132 */ "Program" OpHelp(""), /* 133 */ "Real" OpHelp("r[P2]=P4"), /* 134 */ "Param" OpHelp(""), /* 135 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), /* 136 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), /* 137 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), /* 138 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), /* 139 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), /* 140 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]-=P3, goto P2"), /* 141 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), /* 142 */ "JumpZeroIncr" OpHelp("if (r[P1]++)==0 ) goto P2"), /* 143 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"), /* 144 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), /* 145 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), /* 146 */ "IncrVacuum" OpHelp(""), /* 147 */ "Expire" OpHelp(""), /* 148 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), /* 149 */ "VBegin" OpHelp(""), /* 150 */ "VCreate" OpHelp(""), /* 151 */ "VDestroy" OpHelp(""), /* 152 */ "VOpen" OpHelp(""), /* 153 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), /* 154 */ "VNext" OpHelp(""), /* 155 */ "VRename" OpHelp(""), /* 156 */ "Pagecount" OpHelp(""), /* 157 */ "MaxPgcnt" OpHelp(""), /* 158 */ "Init" OpHelp("Start at P2"), /* 159 */ "CursorHint" OpHelp(""), /* 160 */ "Noop" OpHelp(""), /* 161 */ "Explain" OpHelp(""), }; return azName[i]; } #endif /************** End of opcodes.c *********************************************/ /************** Begin file os_unix.c *****************************************/ |
︙ | ︙ | |||
27115 27116 27117 27118 27119 27120 27121 27122 27123 27124 27125 27126 27127 27128 | #endif /* ** Maximum supported path-length. */ #define MAX_PATHNAME 512 /* Always cast the getpid() return type for compatibility with ** kernel modules in VxWorks. */ #define osGetpid(X) (pid_t)getpid() /* ** Only set the lastErrno if the error code is a real error and not ** a normal expected return code of SQLITE_BUSY or SQLITE_OK | > > > > > | 27215 27216 27217 27218 27219 27220 27221 27222 27223 27224 27225 27226 27227 27228 27229 27230 27231 27232 27233 | #endif /* ** Maximum supported path-length. */ #define MAX_PATHNAME 512 /* ** Maximum supported symbolic links */ #define SQLITE_MAX_SYMLINKS 100 /* Always cast the getpid() return type for compatibility with ** kernel modules in VxWorks. */ #define osGetpid(X) (pid_t)getpid() /* ** Only set the lastErrno if the error code is a real error and not ** a normal expected return code of SQLITE_BUSY or SQLITE_OK |
︙ | ︙ | |||
27639 27640 27641 27642 27643 27644 27645 27646 27647 27648 27649 27650 27651 27652 | #if defined(HAVE_READLINK) { "readlink", (sqlite3_syscall_ptr)readlink, 0 }, #else { "readlink", (sqlite3_syscall_ptr)0, 0 }, #endif #define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent) }; /* End of the overrideable system calls */ /* ** On some systems, calls to fchown() will trigger a message in a security ** log if they come from non-root processes. So avoid calling fchown() if | > > > > > > | 27744 27745 27746 27747 27748 27749 27750 27751 27752 27753 27754 27755 27756 27757 27758 27759 27760 27761 27762 27763 | #if defined(HAVE_READLINK) { "readlink", (sqlite3_syscall_ptr)readlink, 0 }, #else { "readlink", (sqlite3_syscall_ptr)0, 0 }, #endif #define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent) #if defined(HAVE_LSTAT) { "lstat", (sqlite3_syscall_ptr)lstat, 0 }, #else { "lstat", (sqlite3_syscall_ptr)0, 0 }, #endif #define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) }; /* End of the overrideable system calls */ /* ** On some systems, calls to fchown() will trigger a message in a security ** log if they come from non-root processes. So avoid calling fchown() if |
︙ | ︙ | |||
33040 33041 33042 33043 33044 33045 33046 | return rc; } #ifndef SQLITE_DISABLE_DIRSYNC if( (dirSync & 1)!=0 ){ int fd; rc = osOpenDirectory(zPath, &fd); if( rc==SQLITE_OK ){ | < < < | < < | 33151 33152 33153 33154 33155 33156 33157 33158 33159 33160 33161 33162 33163 33164 33165 | return rc; } #ifndef SQLITE_DISABLE_DIRSYNC if( (dirSync & 1)!=0 ){ int fd; rc = osOpenDirectory(zPath, &fd); if( rc==SQLITE_OK ){ if( full_fsync(fd,0,0) ){ rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); } robust_close(0, fd, __LINE__); }else{ assert( rc==SQLITE_CANTOPEN ); rc = SQLITE_OK; } |
︙ | ︙ | |||
33091 33092 33093 33094 33095 33096 33097 33098 33099 33100 33101 33102 33103 33104 33105 33106 33107 33108 33109 33110 33111 33112 33113 33114 33115 33116 33117 33118 33119 33120 33121 33122 | *pResOut = (0==osStat(zPath, &buf) && buf.st_size>0); }else{ *pResOut = osAccess(zPath, W_OK|R_OK)==0; } return SQLITE_OK; } /* ** Turn a relative pathname into a full pathname. The relative path ** is stored as a nul-terminated string in the buffer pointed to by ** zPath. ** ** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes ** (in this case, MAX_PATHNAME bytes). The full-path is written to ** this buffer before returning. */ static int unixFullPathname( sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zPath, /* Possibly relative input path */ int nOut, /* Size of output buffer in bytes */ char *zOut /* Output buffer */ ){ int nByte; /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. This function could fail if, for example, the ** current working directory has been unlinked. */ SimulateIOError( return SQLITE_ERROR ); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < | | < < < | > | | | | < < | | | | > > > > > > | | | < < | < < < < < < < < < < < | > | | | > | > > | > > > > | > > | < > | | | < > | > > > > | > | 33197 33198 33199 33200 33201 33202 33203 33204 33205 33206 33207 33208 33209 33210 33211 33212 33213 33214 33215 33216 33217 33218 33219 33220 33221 33222 33223 33224 33225 33226 33227 33228 33229 33230 33231 33232 33233 33234 33235 33236 33237 33238 33239 33240 33241 33242 33243 33244 33245 33246 33247 33248 33249 33250 33251 33252 33253 33254 33255 33256 33257 33258 33259 33260 33261 33262 33263 33264 33265 33266 33267 33268 33269 33270 33271 33272 33273 33274 33275 33276 33277 33278 33279 33280 33281 33282 33283 33284 33285 33286 33287 33288 33289 33290 33291 33292 33293 33294 33295 33296 33297 33298 33299 33300 33301 33302 33303 33304 33305 33306 33307 33308 33309 33310 33311 33312 33313 33314 33315 33316 33317 33318 33319 33320 33321 33322 33323 33324 33325 33326 33327 | *pResOut = (0==osStat(zPath, &buf) && buf.st_size>0); }else{ *pResOut = osAccess(zPath, W_OK|R_OK)==0; } return SQLITE_OK; } /* ** */ static int mkFullPathname( const char *zPath, /* Input path */ char *zOut, /* Output buffer */ int nOut /* Allocated size of buffer zOut */ ){ int nPath = sqlite3Strlen30(zPath); int iOff = 0; if( zPath[0]!='/' ){ if( osGetcwd(zOut, nOut-2)==0 ){ return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); } iOff = sqlite3Strlen30(zOut); zOut[iOff++] = '/'; } if( (iOff+nPath+1)>nOut ){ /* SQLite assumes that xFullPathname() nul-terminates the output buffer ** even if it returns an error. */ zOut[iOff] = '\0'; return SQLITE_CANTOPEN_BKPT; } sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); return SQLITE_OK; } /* ** Turn a relative pathname into a full pathname. The relative path ** is stored as a nul-terminated string in the buffer pointed to by ** zPath. ** ** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes ** (in this case, MAX_PATHNAME bytes). The full-path is written to ** this buffer before returning. */ static int unixFullPathname( sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zPath, /* Possibly relative input path */ int nOut, /* Size of output buffer in bytes */ char *zOut /* Output buffer */ ){ #if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT) return mkFullPathname(zPath, zOut, nOut); #else int rc = SQLITE_OK; int nByte; int nLink = 1; /* Number of symbolic links followed so far */ const char *zIn = zPath; /* Input path for each iteration of loop */ char *zDel = 0; assert( pVfs->mxPathname==MAX_PATHNAME ); UNUSED_PARAMETER(pVfs); /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. This function could fail if, for example, the ** current working directory has been unlinked. */ SimulateIOError( return SQLITE_ERROR ); do { /* Call stat() on path zIn. Set bLink to true if the path is a symbolic ** link, or false otherwise. */ int bLink = 0; struct stat buf; if( osLstat(zIn, &buf)!=0 ){ if( errno!=ENOENT ){ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn); } }else{ bLink = S_ISLNK(buf.st_mode); } if( bLink ){ if( zDel==0 ){ zDel = sqlite3_malloc(nOut); if( zDel==0 ) rc = SQLITE_NOMEM; }else if( ++nLink>SQLITE_MAX_SYMLINKS ){ rc = SQLITE_CANTOPEN_BKPT; } if( rc==SQLITE_OK ){ nByte = osReadlink(zIn, zDel, nOut-1); if( nByte<0 ){ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn); }else{ if( zDel[0]!='/' ){ int n; for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); if( nByte+n+1>nOut ){ rc = SQLITE_CANTOPEN_BKPT; }else{ memmove(&zDel[n], zDel, nByte+1); memcpy(zDel, zIn, n); nByte += n; } } zDel[nByte] = '\0'; } } zIn = zDel; } assert( rc!=SQLITE_OK || zIn!=zOut || zIn[0]=='/' ); if( rc==SQLITE_OK && zIn!=zOut ){ rc = mkFullPathname(zIn, zOut, nOut); } if( bLink==0 ) break; zIn = zOut; }while( rc==SQLITE_OK ); sqlite3_free(zDel); return rc; #endif /* HAVE_READLINK && HAVE_LSTAT */ } #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Interfaces for opening a shared library, finding entry points ** within the shared library, and closing the shared library. |
︙ | ︙ | |||
33351 33352 33353 33354 33355 33356 33357 | *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; } #endif UNUSED_PARAMETER(NotUsed); return rc; } | | | | 33495 33496 33497 33498 33499 33500 33501 33502 33503 33504 33505 33506 33507 33508 33509 33510 33511 33512 33513 33514 33515 33516 33517 33518 33519 33520 33521 33522 33523 33524 33525 33526 33527 | *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; } #endif UNUSED_PARAMETER(NotUsed); return rc; } #ifndef SQLITE_OMIT_DEPRECATED /* ** Find the current time (in Universal Coordinated Time). Write the ** current time and date as a Julian Day number into *prNow and ** return 0. Return 1 if the time and date cannot be found. */ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ sqlite3_int64 i = 0; int rc; UNUSED_PARAMETER(NotUsed); rc = unixCurrentTimeInt64(0, &i); *prNow = i/86400000.0; return rc; } #else # define unixCurrentTime 0 #endif #ifndef SQLITE_OMIT_DEPRECATED /* ** We added the xGetLastError() method with the intention of providing ** better low-level error messages when operating-system problems come up ** during SQLite operation. But so far, none of that has been implemented ** in the core. So this routine is never called. For now, it is merely ** a place-holder. */ |
︙ | ︙ | |||
34051 34052 34053 34054 34055 34056 34057 | MAXPATHLEN); }else{ strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN); } writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); robust_ftruncate(conchFile->h, writeSize); rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); | | | 34195 34196 34197 34198 34199 34200 34201 34202 34203 34204 34205 34206 34207 34208 34209 | MAXPATHLEN); }else{ strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN); } writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); robust_ftruncate(conchFile->h, writeSize); rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); full_fsync(conchFile->h,0,0); /* If we created a new conch file (not just updated the contents of a ** valid conch file), try to match the permissions of the database */ if( rc==SQLITE_OK && createConch ){ struct stat buf; int err = osFstat(pFile->h, &buf); if( err==0 ){ |
︙ | ︙ | |||
34668 34669 34670 34671 34672 34673 34674 | UNIXVFS("unix-proxy", proxyIoFinder ), #endif }; unsigned int i; /* Loop counter */ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ | | | 34812 34813 34814 34815 34816 34817 34818 34819 34820 34821 34822 34823 34824 34825 34826 | UNIXVFS("unix-proxy", proxyIoFinder ), #endif }; unsigned int i; /* Loop counter */ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ assert( ArraySize(aSyscall)==28 ); /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ sqlite3_vfs_register(&aVfs[i], i==0); } return SQLITE_OK; } |
︙ | ︙ | |||
34968 34969 34970 34971 34972 34973 34974 34975 34976 34977 34978 34979 34980 34981 34982 34983 34984 34985 34986 34987 34988 34989 34990 34991 34992 34993 | # define NTDDI_WIN8 0x06020000 #endif #ifndef NTDDI_WINBLUE # define NTDDI_WINBLUE 0x06030000 #endif /* ** Check to see if the GetVersionEx[AW] functions are deprecated on the ** target system. GetVersionEx was first deprecated in Win8.1. */ #ifndef SQLITE_WIN32_GETVERSIONEX # if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE # define SQLITE_WIN32_GETVERSIONEX 0 /* GetVersionEx() is deprecated */ # else # define SQLITE_WIN32_GETVERSIONEX 1 /* GetVersionEx() is current */ # endif #endif /* ** This constant should already be defined (in the "WinDef.h" SDK file). */ #ifndef MAX_PATH # define MAX_PATH (260) #endif | > > > > > > > > > > > > > > > > > | 35112 35113 35114 35115 35116 35117 35118 35119 35120 35121 35122 35123 35124 35125 35126 35127 35128 35129 35130 35131 35132 35133 35134 35135 35136 35137 35138 35139 35140 35141 35142 35143 35144 35145 35146 35147 35148 35149 35150 35151 35152 35153 35154 | # define NTDDI_WIN8 0x06020000 #endif #ifndef NTDDI_WINBLUE # define NTDDI_WINBLUE 0x06030000 #endif #ifndef NTDDI_WINTHRESHOLD # define NTDDI_WINTHRESHOLD 0x06040000 #endif /* ** Check to see if the GetVersionEx[AW] functions are deprecated on the ** target system. GetVersionEx was first deprecated in Win8.1. */ #ifndef SQLITE_WIN32_GETVERSIONEX # if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE # define SQLITE_WIN32_GETVERSIONEX 0 /* GetVersionEx() is deprecated */ # else # define SQLITE_WIN32_GETVERSIONEX 1 /* GetVersionEx() is current */ # endif #endif /* ** Check to see if the CreateFileMappingA function is supported on the ** target system. It is unavailable when using "mincore.lib" on Win10. ** When compiling for Windows 10, always assume "mincore.lib" is in use. */ #ifndef SQLITE_WIN32_CREATEFILEMAPPINGA # if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINTHRESHOLD # define SQLITE_WIN32_CREATEFILEMAPPINGA 0 # else # define SQLITE_WIN32_CREATEFILEMAPPINGA 1 # endif #endif /* ** This constant should already be defined (in the "WinDef.h" SDK file). */ #ifndef MAX_PATH # define MAX_PATH (260) #endif |
︙ | ︙ | |||
35386 35387 35388 35389 35390 35391 35392 | #else { "CreateFileW", (SYSCALL)0, 0 }, #endif #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) | | | > | 35547 35548 35549 35550 35551 35552 35553 35554 35555 35556 35557 35558 35559 35560 35561 35562 35563 | #else { "CreateFileW", (SYSCALL)0, 0 }, #endif #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \ (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) && \ SQLITE_WIN32_CREATEFILEMAPPINGA { "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 }, #else { "CreateFileMappingA", (SYSCALL)0, 0 }, #endif #define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent) |
︙ | ︙ | |||
35617 35618 35619 35620 35621 35622 35623 | { "GetTickCount", (SYSCALL)GetTickCount, 0 }, #else { "GetTickCount", (SYSCALL)0, 0 }, #endif #define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) | | < | | 35779 35780 35781 35782 35783 35784 35785 35786 35787 35788 35789 35790 35791 35792 35793 35794 35795 35796 35797 35798 35799 35800 35801 35802 35803 | { "GetTickCount", (SYSCALL)GetTickCount, 0 }, #else { "GetTickCount", (SYSCALL)0, 0 }, #endif #define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) #if defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_GETVERSIONEX { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, #else { "GetVersionExA", (SYSCALL)0, 0 }, #endif #define osGetVersionExA ((BOOL(WINAPI*)( \ LPOSVERSIONINFOA))aSyscall[34].pCurrent) #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ SQLITE_WIN32_GETVERSIONEX { "GetVersionExW", (SYSCALL)GetVersionExW, 0 }, #else { "GetVersionExW", (SYSCALL)0, 0 }, #endif #define osGetVersionExW ((BOOL(WINAPI*)( \ LPOSVERSIONINFOW))aSyscall[35].pCurrent) |
︙ | ︙ | |||
36239 36240 36241 36242 36243 36244 36245 | ** the LockFileEx() API. But we can still statically link against that ** API as long as we don't call it when running Win95/98/ME. A call to ** this routine is used to determine if the host is Win95/98/ME or ** WinNT/2K/XP so that we will know whether or not we can safely call ** the LockFileEx() API. */ | | | | 36400 36401 36402 36403 36404 36405 36406 36407 36408 36409 36410 36411 36412 36413 36414 36415 36416 36417 36418 36419 36420 36421 36422 36423 36424 36425 36426 36427 36428 36429 36430 36431 36432 36433 36434 36435 | ** the LockFileEx() API. But we can still statically link against that ** API as long as we don't call it when running Win95/98/ME. A call to ** this routine is used to determine if the host is Win95/98/ME or ** WinNT/2K/XP so that we will know whether or not we can safely call ** the LockFileEx() API. */ #if !SQLITE_WIN32_GETVERSIONEX # define osIsNT() (1) #elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) # define osIsNT() (1) #elif !defined(SQLITE_WIN32_HAS_WIDE) # define osIsNT() (0) #else # define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) #endif /* ** This function determines if the machine is running a version of Windows ** based on the NT kernel. */ SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void){ #if SQLITE_OS_WINRT /* ** NOTE: The WinRT sub-platform is always assumed to be based on the NT ** kernel. */ return 1; #elif SQLITE_WIN32_GETVERSIONEX if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ #if defined(SQLITE_WIN32_HAS_ANSI) OSVERSIONINFOA sInfo; sInfo.dwOSVersionInfoSize = sizeof(sInfo); osGetVersionExA(&sInfo); osInterlockedCompareExchange(&sqlite3_os_type, (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); |
︙ | ︙ | |||
38844 38845 38846 38847 38848 38849 38850 | hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, NULL, PAGE_READWRITE, nByte, NULL ); #elif defined(SQLITE_WIN32_HAS_WIDE) hMap = osCreateFileMappingW(pShmNode->hFile.h, NULL, PAGE_READWRITE, 0, nByte, NULL ); | | | 39005 39006 39007 39008 39009 39010 39011 39012 39013 39014 39015 39016 39017 39018 39019 | hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, NULL, PAGE_READWRITE, nByte, NULL ); #elif defined(SQLITE_WIN32_HAS_WIDE) hMap = osCreateFileMappingW(pShmNode->hFile.h, NULL, PAGE_READWRITE, 0, nByte, NULL ); #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA hMap = osCreateFileMappingA(pShmNode->hFile.h, NULL, PAGE_READWRITE, 0, nByte, NULL ); #endif OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", osGetCurrentProcessId(), pShmNode->nRegion, nByte, hMap ? "ok" : "failed")); |
︙ | ︙ | |||
39000 39001 39002 39003 39004 39005 39006 | #endif #if SQLITE_OS_WINRT pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL); #elif defined(SQLITE_WIN32_HAS_WIDE) pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, (DWORD)((nMap>>32) & 0xffffffff), (DWORD)(nMap & 0xffffffff), NULL); | | | 39161 39162 39163 39164 39165 39166 39167 39168 39169 39170 39171 39172 39173 39174 39175 | #endif #if SQLITE_OS_WINRT pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL); #elif defined(SQLITE_WIN32_HAS_WIDE) pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, (DWORD)((nMap>>32) & 0xffffffff), (DWORD)(nMap & 0xffffffff), NULL); #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect, (DWORD)((nMap>>32) & 0xffffffff), (DWORD)(nMap & 0xffffffff), NULL); #endif if( pFd->hMap==NULL ){ pFd->lastErrno = osGetLastError(); rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
︙ | ︙ | |||
43064 43065 43066 43067 43068 43069 43070 | ** In an OOM situation, the RowSet.db->mallocFailed flag is set and this ** routine returns NULL. */ static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ assert( p!=0 ); if( p->nFresh==0 ){ struct RowSetChunk *pNew; | | | 43225 43226 43227 43228 43229 43230 43231 43232 43233 43234 43235 43236 43237 43238 43239 | ** In an OOM situation, the RowSet.db->mallocFailed flag is set and this ** routine returns NULL. */ static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ assert( p!=0 ); if( p->nFresh==0 ){ struct RowSetChunk *pNew; pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew)); if( pNew==0 ){ return 0; } pNew->pNextChunk = p->pChunk; p->pChunk = pNew; p->pFresh = pNew->aEntry; p->nFresh = ROWSET_ENTRY_PER_CHUNK; |
︙ | ︙ | |||
43971 43972 43973 43974 43975 43976 43977 43978 43979 43980 43981 43982 43983 43984 | /* ** The maximum allowed sector size. 64KiB. If the xSectorsize() method ** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. ** This could conceivably cause corruption following a power failure on ** such a system. This is currently an undocumented limit. */ #define MAX_SECTOR_SIZE 0x10000 /* ** An instance of the following structure is allocated for each active ** savepoint and statement transaction in the system. All such structures ** are stored in the Pager.aSavepoint[] array, which is allocated and ** resized using sqlite3Realloc(). ** | > > > > > > > > > > > > > > | 44132 44133 44134 44135 44136 44137 44138 44139 44140 44141 44142 44143 44144 44145 44146 44147 44148 44149 44150 44151 44152 44153 44154 44155 44156 44157 44158 44159 | /* ** The maximum allowed sector size. 64KiB. If the xSectorsize() method ** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. ** This could conceivably cause corruption following a power failure on ** such a system. This is currently an undocumented limit. */ #define MAX_SECTOR_SIZE 0x10000 /* ** If the option SQLITE_EXTRA_DURABLE option is set at compile-time, then ** SQLite will do extra fsync() operations when synchronous==FULL to help ** ensure that transactions are durable across a power failure. Most ** applications are happy as long as transactions are consistent across ** a power failure, and are perfectly willing to lose the last transaction ** in exchange for the extra performance of avoiding directory syncs. ** And so the default SQLITE_EXTRA_DURABLE setting is off. */ #ifndef SQLITE_EXTRA_DURABLE # define SQLITE_EXTRA_DURABLE 0 #endif /* ** An instance of the following structure is allocated for each active ** savepoint and statement transaction in the system. All such structures ** are stored in the Pager.aSavepoint[] array, which is allocated and ** resized using sqlite3Realloc(). ** |
︙ | ︙ | |||
44167 44168 44169 44170 44171 44172 44173 44174 44175 44176 44177 44178 44179 44180 | struct Pager { sqlite3_vfs *pVfs; /* OS functions to use for IO */ u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ u8 useJournal; /* Use a rollback journal on this file */ u8 noSync; /* Do not sync the journal if true */ u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ u8 tempFile; /* zFilename is a temporary or immutable file */ u8 noLock; /* Do not lock (except in WAL mode) */ u8 readOnly; /* True for a read-only database */ u8 memDb; /* True to inhibit all file I/O */ | > | 44342 44343 44344 44345 44346 44347 44348 44349 44350 44351 44352 44353 44354 44355 44356 | struct Pager { sqlite3_vfs *pVfs; /* OS functions to use for IO */ u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ u8 useJournal; /* Use a rollback journal on this file */ u8 noSync; /* Do not sync the journal if true */ u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 extraSync; /* sync directory after journal delete */ u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ u8 tempFile; /* zFilename is a temporary or immutable file */ u8 noLock; /* Do not lock (except in WAL mode) */ u8 readOnly; /* True for a read-only database */ u8 memDb; /* True to inhibit all file I/O */ |
︙ | ︙ | |||
45527 45528 45529 45530 45531 45532 45533 | int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd)); assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE || pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->journalMode==PAGER_JOURNALMODE_WAL ); sqlite3OsClose(pPager->jfd); if( bDelete ){ | | | 45703 45704 45705 45706 45707 45708 45709 45710 45711 45712 45713 45714 45715 45716 45717 | int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd)); assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE || pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->journalMode==PAGER_JOURNALMODE_WAL ); sqlite3OsClose(pPager->jfd); if( bDelete ){ rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, pPager->extraSync); } } } #ifdef SQLITE_CHECK_PAGES sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){ |
︙ | ︙ | |||
47033 47034 47035 47036 47037 47038 47039 | */ #ifndef SQLITE_OMIT_PAGER_PRAGMAS SQLITE_PRIVATE void sqlite3PagerSetFlags( Pager *pPager, /* The pager to set safety level for */ unsigned pgFlags /* Various flags */ ){ unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK; | | | | > > > > > > | 47209 47210 47211 47212 47213 47214 47215 47216 47217 47218 47219 47220 47221 47222 47223 47224 47225 47226 47227 47228 47229 47230 47231 | */ #ifndef SQLITE_OMIT_PAGER_PRAGMAS SQLITE_PRIVATE void sqlite3PagerSetFlags( Pager *pPager, /* The pager to set safety level for */ unsigned pgFlags /* Various flags */ ){ unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK; if( pPager->tempFile ){ pPager->noSync = 1; pPager->fullSync = 0; pPager->extraSync = 0; }else{ pPager->noSync = level==PAGER_SYNCHRONOUS_OFF ?1:0; pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0; pPager->extraSync = level==PAGER_SYNCHRONOUS_EXTRA ?1:0; } if( pPager->noSync ){ pPager->syncFlags = 0; pPager->ckptSyncFlags = 0; }else if( pgFlags & PAGER_FULLFSYNC ){ pPager->syncFlags = SQLITE_SYNC_FULL; pPager->ckptSyncFlags = SQLITE_SYNC_FULL; }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){ |
︙ | ︙ | |||
48340 48341 48342 48343 48344 48345 48346 48347 48348 48349 48350 48351 48352 48353 48354 48355 48356 48357 48358 | pPager->changeCountDone = pPager->tempFile; pPager->memDb = (u8)memDb; pPager->readOnly = (u8)readOnly; assert( useJournal || pPager->tempFile ); pPager->noSync = pPager->tempFile; if( pPager->noSync ){ assert( pPager->fullSync==0 ); assert( pPager->syncFlags==0 ); assert( pPager->walSyncFlags==0 ); assert( pPager->ckptSyncFlags==0 ); }else{ pPager->fullSync = 1; pPager->syncFlags = SQLITE_SYNC_NORMAL; pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS; pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; } /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ | > > > > > > | 48522 48523 48524 48525 48526 48527 48528 48529 48530 48531 48532 48533 48534 48535 48536 48537 48538 48539 48540 48541 48542 48543 48544 48545 48546 | pPager->changeCountDone = pPager->tempFile; pPager->memDb = (u8)memDb; pPager->readOnly = (u8)readOnly; assert( useJournal || pPager->tempFile ); pPager->noSync = pPager->tempFile; if( pPager->noSync ){ assert( pPager->fullSync==0 ); assert( pPager->extraSync==0 ); assert( pPager->syncFlags==0 ); assert( pPager->walSyncFlags==0 ); assert( pPager->ckptSyncFlags==0 ); }else{ pPager->fullSync = 1; #if SQLITE_EXTRA_DURABLE pPager->extraSync = 1; #else pPager->extraSync = 0; #endif pPager->syncFlags = SQLITE_SYNC_NORMAL; pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS; pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; } /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ |
︙ | ︙ | |||
57678 57679 57680 57681 57682 57683 57684 | MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) pBt->nRef = 1; MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);) if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){ pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST); if( pBt->mutex==0 ){ rc = SQLITE_NOMEM; | < | 57866 57867 57868 57869 57870 57871 57872 57873 57874 57875 57876 57877 57878 57879 | MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) pBt->nRef = 1; MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);) if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){ pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST); if( pBt->mutex==0 ){ rc = SQLITE_NOMEM; goto btree_open_out; } } sqlite3_mutex_enter(mutexShared); pBt->pNext = GLOBAL(BtShared*,sqlite3SharedCacheList); GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt; sqlite3_mutex_leave(mutexShared); |
︙ | ︙ | |||
59389 59390 59391 59392 59393 59394 59395 | /* ** Create a new cursor for the BTree whose root is on the page ** iTable. If a read-only cursor is requested, it is assumed that ** the caller already has at least a read-only transaction open ** on the database already. If a write-cursor is requested, then ** the caller is assumed to have an open write transaction. ** | | | | | | | > > > > > > > > > > | 59576 59577 59578 59579 59580 59581 59582 59583 59584 59585 59586 59587 59588 59589 59590 59591 59592 59593 59594 59595 59596 59597 59598 59599 59600 59601 59602 59603 59604 59605 59606 59607 59608 59609 59610 59611 59612 59613 59614 59615 59616 | /* ** Create a new cursor for the BTree whose root is on the page ** iTable. If a read-only cursor is requested, it is assumed that ** the caller already has at least a read-only transaction open ** on the database already. If a write-cursor is requested, then ** the caller is assumed to have an open write transaction. ** ** If the BTREE_WRCSR bit of wrFlag is clear, then the cursor can only ** be used for reading. If the BTREE_WRCSR bit is set, then the cursor ** can be used for reading or for writing if other conditions for writing ** are also met. These are the conditions that must be met in order ** for writing to be allowed: ** ** 1: The cursor must have been opened with wrFlag containing BTREE_WRCSR ** ** 2: Other database connections that share the same pager cache ** but which are not in the READ_UNCOMMITTED state may not have ** cursors open with wrFlag==0 on the same table. Otherwise ** the changes made by this write cursor would be visible to ** the read cursors in the other database connection. ** ** 3: The database must be writable (not on read-only media) ** ** 4: There must be an active transaction. ** ** The BTREE_FORDELETE bit of wrFlag may optionally be set if BTREE_WRCSR ** is set. If FORDELETE is set, that is a hint to the implementation that ** this cursor will only be used to seek to and delete entries of an index ** as part of a larger DELETE statement. The FORDELETE hint is not used by ** this implementation. But in a hypothetical alternative storage engine ** in which index entries are automatically deleted when corresponding table ** rows are deleted, the FORDELETE flag is a hint that all SEEK and DELETE ** operations on this cursor can be no-ops and all READ operations can ** return a null row (2-bytes: 0x01 0x00). ** ** No checking is done to make sure that page iTable really is the ** root page of a b-tree. If it is not, then the cursor acquired ** will not work correctly. ** ** It is assumed that the sqlite3BtreeCursorZero() has been called ** on pCur to initialize the memory space prior to invoking this routine. |
︙ | ︙ | |||
61479 61480 61481 61482 61483 61484 61485 | ** Use a call to btreeParseCellPtr() to verify that the values above ** were computed correctly. */ #if SQLITE_DEBUG { CellInfo info; pPage->xParseCell(pPage, pCell, &info); | | | 61676 61677 61678 61679 61680 61681 61682 61683 61684 61685 61686 61687 61688 61689 61690 | ** Use a call to btreeParseCellPtr() to verify that the values above ** were computed correctly. */ #if SQLITE_DEBUG { CellInfo info; pPage->xParseCell(pPage, pCell, &info); assert( nHeader==(int)(info.pPayload - pCell) ); assert( info.nKey==nKey ); assert( *pnSize == info.nSize ); assert( spaceLeft == info.nLocal ); } #endif /* Write the payload into the local Cell and any extra into overflow pages */ |
︙ | ︙ | |||
63138 63139 63140 63141 63142 63143 63144 | */ static int balance(BtCursor *pCur){ int rc = SQLITE_OK; const int nMin = pCur->pBt->usableSize * 2 / 3; u8 aBalanceQuickSpace[13]; u8 *pFree = 0; | | | > | | 63335 63336 63337 63338 63339 63340 63341 63342 63343 63344 63345 63346 63347 63348 63349 63350 63351 63352 63353 63354 63355 63356 63357 63358 63359 63360 63361 63362 63363 63364 | */ static int balance(BtCursor *pCur){ int rc = SQLITE_OK; const int nMin = pCur->pBt->usableSize * 2 / 3; u8 aBalanceQuickSpace[13]; u8 *pFree = 0; VVA_ONLY( int balance_quick_called = 0 ); VVA_ONLY( int balance_deeper_called = 0 ); do { int iPage = pCur->iPage; MemPage *pPage = pCur->apPage[iPage]; if( iPage==0 ){ if( pPage->nOverflow ){ /* The root page of the b-tree is overfull. In this case call the ** balance_deeper() function to create a new child for the root-page ** and copy the current contents of the root-page to it. The ** next iteration of the do-loop will balance the child page. */ assert( balance_deeper_called==0 ); VVA_ONLY( balance_deeper_called++ ); rc = balance_deeper(pPage, &pCur->apPage[1]); if( rc==SQLITE_OK ){ pCur->iPage = 1; pCur->aiIdx[0] = 0; pCur->aiIdx[1] = 0; assert( pCur->apPage[1]->nOverflow ); } |
︙ | ︙ | |||
63191 63192 63193 63194 63195 63196 63197 | ** buffer. ** ** The purpose of the following assert() is to check that only a ** single call to balance_quick() is made for each call to this ** function. If this were not verified, a subtle bug involving reuse ** of the aBalanceQuickSpace[] might sneak in. */ | > | | 63389 63390 63391 63392 63393 63394 63395 63396 63397 63398 63399 63400 63401 63402 63403 63404 | ** buffer. ** ** The purpose of the following assert() is to check that only a ** single call to balance_quick() is made for each call to this ** function. If this were not verified, a subtle bug involving reuse ** of the aBalanceQuickSpace[] might sneak in. */ assert( balance_quick_called==0 ); VVA_ONLY( balance_quick_called++ ); rc = balance_quick(pParent, pPage, aBalanceQuickSpace); }else #endif { /* In this case, call balance_nonroot() to redistribute cells ** between pPage and up to 2 of its sibling pages. This involves ** modifying the contents of pParent, which may cause pParent to |
︙ | ︙ | |||
63422 63423 63424 63425 63426 63427 63428 | end_insert: return rc; } /* ** Delete the entry that the cursor is pointing to. ** | | | > | | | > > > > > > > | > > | 63621 63622 63623 63624 63625 63626 63627 63628 63629 63630 63631 63632 63633 63634 63635 63636 63637 63638 63639 63640 63641 63642 63643 63644 63645 63646 63647 63648 63649 63650 63651 63652 63653 63654 63655 63656 63657 63658 63659 63660 63661 63662 63663 63664 63665 63666 63667 63668 63669 | end_insert: return rc; } /* ** Delete the entry that the cursor is pointing to. ** ** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then ** the cursor is left pointing at an arbitrary location after the delete. ** But if that bit is set, then the cursor is left in a state such that ** the next call to BtreeNext() or BtreePrev() moves it to the same row ** as it would have been on if the call to BtreeDelete() had been omitted. ** ** The BTREE_AUXDELETE bit of flags indicates that is one of several deletes ** associated with a single table entry and its indexes. Only one of those ** deletes is considered the "primary" delete. The primary delete occurs ** on a cursor that is not a BTREE_FORDELETE cursor. All but one delete ** operation on non-FORDELETE cursors is tagged with the AUXDELETE flag. ** The BTREE_AUXDELETE bit is a hint that is not used by this implementation, ** but which might be used by alternative storage engines. */ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ Btree *p = pCur->pBtree; BtShared *pBt = p->pBt; int rc; /* Return code */ MemPage *pPage; /* Page to delete cell from */ unsigned char *pCell; /* Pointer to cell to delete */ int iCellIdx; /* Index of cell to delete */ int iCellDepth; /* Depth of node containing pCell */ u16 szCell; /* Size of the cell being deleted */ int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */ u8 bPreserve = flags & BTREE_SAVEPOSITION; /* Keep cursor valid */ assert( cursorOwnsBtShared(pCur) ); assert( pBt->inTransaction==TRANS_WRITE ); assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); assert( pCur->curFlags & BTCF_WriteFlag ); assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); assert( !hasReadConflicts(p, pCur->pgnoRoot) ); assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell ); assert( pCur->eState==CURSOR_VALID ); assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); iCellDepth = pCur->iPage; iCellIdx = pCur->aiIdx[iCellDepth]; pPage = pCur->apPage[iCellDepth]; pCell = findCell(pPage, iCellIdx); /* If the page containing the entry to delete is not a leaf page, move |
︙ | ︙ | |||
63559 63560 63561 63562 63563 63564 63565 | } rc = balance(pCur); } if( rc==SQLITE_OK ){ if( bSkipnext ){ assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) ); | | | 63768 63769 63770 63771 63772 63773 63774 63775 63776 63777 63778 63779 63780 63781 63782 | } rc = balance(pCur); } if( rc==SQLITE_OK ){ if( bSkipnext ){ assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) ); assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB ); assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell ); pCur->eState = CURSOR_SKIPNEXT; if( iCellIdx>=pPage->nCell ){ pCur->skipNext = -1; pCur->aiIdx[iCellDepth] = pPage->nCell-1; }else{ pCur->skipNext = 1; |
︙ | ︙ | |||
64145 64146 64147 64148 64149 64150 64151 | pCheck->mxErr--; pCheck->nErr++; va_start(ap, zFormat); if( pCheck->errMsg.nChar ){ sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1); } if( pCheck->zPfx ){ | | | | 64354 64355 64356 64357 64358 64359 64360 64361 64362 64363 64364 64365 64366 64367 64368 64369 64370 | pCheck->mxErr--; pCheck->nErr++; va_start(ap, zFormat); if( pCheck->errMsg.nChar ){ sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1); } if( pCheck->zPfx ){ sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); } sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap); va_end(ap); if( pCheck->errMsg.accError==STRACCUM_NOMEM ){ pCheck->mallocFailed = 1; } } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ |
︙ | ︙ | |||
64648 64649 64650 64651 64652 64653 64654 | BtShared *pBt = p->pBt; int savedDbFlags = pBt->db->flags; char zErr[100]; VVA_ONLY( int nRef ); sqlite3BtreeEnter(p); assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); | | > > | 64857 64858 64859 64860 64861 64862 64863 64864 64865 64866 64867 64868 64869 64870 64871 64872 64873 64874 64875 64876 64877 64878 64879 64880 64881 64882 64883 64884 64885 | BtShared *pBt = p->pBt; int savedDbFlags = pBt->db->flags; char zErr[100]; VVA_ONLY( int nRef ); sqlite3BtreeEnter(p); assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) ); assert( nRef>=0 ); sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = btreePagecount(sCheck.pBt); sCheck.mxErr = mxErr; sCheck.nErr = 0; sCheck.mallocFailed = 0; sCheck.zPfx = 0; sCheck.v1 = 0; sCheck.v2 = 0; sCheck.aPgRef = 0; sCheck.heap = 0; sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; if( sCheck.nPage==0 ){ goto integrity_ck_cleanup; } sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); if( !sCheck.aPgRef ){ sCheck.mallocFailed = 1; |
︙ | ︙ | |||
65937 65938 65939 65940 65941 65942 65943 65944 65945 65946 65947 65948 65949 65950 | ** pMem->z into the new allocation. pMem must be either a string or ** blob if bPreserve is true. If bPreserve is false, any prior content ** in pMem->z is discarded. */ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ assert( sqlite3VdbeCheckMemInvariants(pMem) ); assert( (pMem->flags&MEM_RowSet)==0 ); /* If the bPreserve flag is set to true, then the memory cell must already ** contain a valid string or blob value. */ assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); testcase( bPreserve && pMem->z==0 ); assert( pMem->szMalloc==0 | > | 66148 66149 66150 66151 66152 66153 66154 66155 66156 66157 66158 66159 66160 66161 66162 | ** pMem->z into the new allocation. pMem must be either a string or ** blob if bPreserve is true. If bPreserve is false, any prior content ** in pMem->z is discarded. */ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ assert( sqlite3VdbeCheckMemInvariants(pMem) ); assert( (pMem->flags&MEM_RowSet)==0 ); testcase( pMem->db==0 ); /* If the bPreserve flag is set to true, then the memory cell must already ** contain a valid string or blob value. */ assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); testcase( bPreserve && pMem->z==0 ); assert( pMem->szMalloc==0 |
︙ | ︙ | |||
66540 66541 66542 66543 66544 66545 66546 | ** empty boolean index. */ SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){ sqlite3 *db = pMem->db; assert( db!=0 ); assert( (pMem->flags & MEM_RowSet)==0 ); sqlite3VdbeMemRelease(pMem); | | | 66752 66753 66754 66755 66756 66757 66758 66759 66760 66761 66762 66763 66764 66765 66766 | ** empty boolean index. */ SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){ sqlite3 *db = pMem->db; assert( db!=0 ); assert( (pMem->flags & MEM_RowSet)==0 ); sqlite3VdbeMemRelease(pMem); pMem->zMalloc = sqlite3DbMallocRawNN(db, 64); if( db->mallocFailed ){ pMem->flags = MEM_Null; pMem->szMalloc = 0; }else{ assert( pMem->zMalloc ); pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc); pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc); |
︙ | ︙ | |||
67202 67203 67204 67205 67206 67207 67208 | } #endif *ppVal = pVal; return rc; no_mem: | | | 67414 67415 67416 67417 67418 67419 67420 67421 67422 67423 67424 67425 67426 67427 67428 | } #endif *ppVal = pVal; return rc; no_mem: sqlite3OomFault(db); sqlite3DbFree(db, zVal); assert( *ppVal==0 ); #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 if( pCtx==0 ) sqlite3ValueFree(pVal); #else assert( pCtx==0 ); sqlite3ValueFree(pVal); #endif |
︙ | ︙ | |||
67261 67262 67263 67264 67265 67266 67267 | UNUSED_PARAMETER( argc ); iSerial = sqlite3VdbeSerialType(argv[0], file_format, &nVal); nSerial = sqlite3VarintLen(iSerial); db = sqlite3_context_db_handle(context); nRet = 1 + nSerial + nVal; | | | 67473 67474 67475 67476 67477 67478 67479 67480 67481 67482 67483 67484 67485 67486 67487 | UNUSED_PARAMETER( argc ); iSerial = sqlite3VdbeSerialType(argv[0], file_format, &nVal); nSerial = sqlite3VarintLen(iSerial); db = sqlite3_context_db_handle(context); nRet = 1 + nSerial + nVal; aRet = sqlite3DbMallocRawNN(db, nRet); if( aRet==0 ){ sqlite3_result_error_nomem(context); }else{ aRet[0] = nSerial+1; putVarint32(&aRet[1], iSerial); sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial); sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT); |
︙ | ︙ | |||
67713 67714 67715 67716 67717 67718 67719 | } SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ int i; VdbeOp *pOp; i = p->nOp; assert( p->magic==VDBE_MAGIC_INIT ); | | | 67925 67926 67927 67928 67929 67930 67931 67932 67933 67934 67935 67936 67937 67938 67939 | } SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ int i; VdbeOp *pOp; i = p->nOp; assert( p->magic==VDBE_MAGIC_INIT ); assert( op>=0 && op<0xff ); if( p->pParse->nOpAlloc<=i ){ return growOp3(p, op, p1, p2, p3); } p->nOp++; pOp = &p->aOp[i]; pOp->opcode = (u8)op; pOp->p5 = 0; |
︙ | ︙ | |||
67831 67832 67833 67834 67835 67836 67837 | int op, /* The new opcode */ int p1, /* The P1 operand */ int p2, /* The P2 operand */ int p3, /* The P3 operand */ const u8 *zP4, /* The P4 operand */ int p4type /* P4 operand type */ ){ | | | 68043 68044 68045 68046 68047 68048 68049 68050 68051 68052 68053 68054 68055 68056 68057 | int op, /* The new opcode */ int p1, /* The P1 operand */ int p2, /* The P2 operand */ int p3, /* The P3 operand */ const u8 *zP4, /* The P4 operand */ int p4type /* P4 operand type */ ){ char *p4copy = sqlite3DbMallocRawNN(sqlite3VdbeDb(p), 8); if( p4copy ) memcpy(p4copy, zP4, 8); return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type); } /* ** Add an OP_ParseSchema opcode. This routine is broken out from ** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees |
︙ | ︙ | |||
67865 67866 67867 67868 67869 67870 67871 67872 67873 67874 67875 67876 67877 67878 | int p3, /* The P3 operand */ int p4 /* The P4 operand as an integer */ ){ int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); sqlite3VdbeChangeP4(p, addr, SQLITE_INT_TO_PTR(p4), P4_INT32); return addr; } /* ** Create a new symbolic label for an instruction that has yet to be ** coded. The symbolic label is really just a negative number. The ** label can be used as the P2 value of an operation. Later, when ** the label is resolved to a specific address, the VDBE will scan ** through its operation list and change all values of P2 which match | > > > > > > > > > > > > > > > | 68077 68078 68079 68080 68081 68082 68083 68084 68085 68086 68087 68088 68089 68090 68091 68092 68093 68094 68095 68096 68097 68098 68099 68100 68101 68102 68103 68104 68105 | int p3, /* The P3 operand */ int p4 /* The P4 operand as an integer */ ){ int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); sqlite3VdbeChangeP4(p, addr, SQLITE_INT_TO_PTR(p4), P4_INT32); return addr; } /* Insert the end of a co-routine */ SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); /* Clear the temporary register cache, thereby ensuring that each ** co-routine has its own independent set of registers, because co-routines ** might expect their registers to be preserved across an OP_Yield, and ** that could cause problems if two or more co-routines are using the same ** temporary register. */ v->pParse->nTempReg = 0; v->pParse->nRangeReg = 0; } /* ** Create a new symbolic label for an instruction that has yet to be ** coded. The symbolic label is really just a negative number. The ** label can be used as the P2 value of an operation. Later, when ** the label is resolved to a specific address, the VDBE will scan ** through its operation list and change all values of P2 which match |
︙ | ︙ | |||
68076 68077 68078 68079 68080 68081 68082 | Parse *pParse = p->pParse; int *aLabel = pParse->aLabel; p->readOnly = 1; p->bIsReader = 0; for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ u8 opcode = pOp->opcode; | | | 68303 68304 68305 68306 68307 68308 68309 68310 68311 68312 68313 68314 68315 68316 68317 | Parse *pParse = p->pParse; int *aLabel = pParse->aLabel; p->readOnly = 1; p->bIsReader = 0; for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ u8 opcode = pOp->opcode; /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing ** cases from this switch! */ switch( opcode ){ case OP_Transaction: { if( pOp->p2!=0 ) p->readOnly = 0; /* fall thru */ } case OP_AutoCommit: |
︙ | ︙ | |||
68188 68189 68190 68191 68192 68193 68194 68195 68196 68197 68198 68199 68200 68201 68202 68203 68204 68205 68206 68207 68208 68209 68210 68211 68212 68213 68214 68215 68216 68217 68218 68219 68220 68221 | p->aOp = 0; return aOp; } /* ** Add a whole list of operations to the operation stack. Return a ** pointer to the first operation inserted. */ SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList( Vdbe *p, /* Add opcodes to the prepared statement */ int nOp, /* Number of opcodes to add */ VdbeOpList const *aOp, /* The opcodes to be added */ int iLineno /* Source-file line number of first opcode */ ){ int i; VdbeOp *pOut, *pFirst; assert( nOp>0 ); assert( p->magic==VDBE_MAGIC_INIT ); if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){ return 0; } pFirst = pOut = &p->aOp[p->nOp]; for(i=0; i<nOp; i++, aOp++, pOut++){ pOut->opcode = aOp->opcode; pOut->p1 = aOp->p1; pOut->p2 = aOp->p2; assert( aOp->p2>=0 ); pOut->p3 = aOp->p3; pOut->p4type = P4_NOTUSED; pOut->p4.p = 0; pOut->p5 = 0; #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS pOut->zComment = 0; #endif | > > > > > > | 68415 68416 68417 68418 68419 68420 68421 68422 68423 68424 68425 68426 68427 68428 68429 68430 68431 68432 68433 68434 68435 68436 68437 68438 68439 68440 68441 68442 68443 68444 68445 68446 68447 68448 68449 68450 68451 68452 68453 68454 | p->aOp = 0; return aOp; } /* ** Add a whole list of operations to the operation stack. Return a ** pointer to the first operation inserted. ** ** Non-zero P2 arguments to jump instructions are automatically adjusted ** so that the jump target is relative to the first operation inserted. */ SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList( Vdbe *p, /* Add opcodes to the prepared statement */ int nOp, /* Number of opcodes to add */ VdbeOpList const *aOp, /* The opcodes to be added */ int iLineno /* Source-file line number of first opcode */ ){ int i; VdbeOp *pOut, *pFirst; assert( nOp>0 ); assert( p->magic==VDBE_MAGIC_INIT ); if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){ return 0; } pFirst = pOut = &p->aOp[p->nOp]; for(i=0; i<nOp; i++, aOp++, pOut++){ pOut->opcode = aOp->opcode; pOut->p1 = aOp->p1; pOut->p2 = aOp->p2; assert( aOp->p2>=0 ); if( (sqlite3OpcodeProperty[aOp->opcode] & OPFLG_JUMP)!=0 && aOp->p2>0 ){ pOut->p2 += p->nOp; } pOut->p3 = aOp->p3; pOut->p4type = P4_NOTUSED; pOut->p4.p = 0; pOut->p5 = 0; #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS pOut->zComment = 0; #endif |
︙ | ︙ | |||
68659 68660 68661 68662 68663 68664 68665 | #endif /* SQLITE_DEBUG */ #if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) /* ** Translate the P4.pExpr value for an OP_CursorHint opcode into text ** that can be displayed in the P4 column of EXPLAIN output. */ | | < | | | | | | | 68892 68893 68894 68895 68896 68897 68898 68899 68900 68901 68902 68903 68904 68905 68906 68907 68908 68909 68910 68911 68912 68913 68914 68915 68916 68917 68918 68919 68920 68921 68922 68923 68924 68925 68926 | #endif /* SQLITE_DEBUG */ #if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) /* ** Translate the P4.pExpr value for an OP_CursorHint opcode into text ** that can be displayed in the P4 column of EXPLAIN output. */ static void displayP4Expr(StrAccum *p, Expr *pExpr){ const char *zOp = 0; switch( pExpr->op ){ case TK_STRING: sqlite3XPrintf(p, "%Q", pExpr->u.zToken); break; case TK_INTEGER: sqlite3XPrintf(p, "%d", pExpr->u.iValue); break; case TK_NULL: sqlite3XPrintf(p, "NULL"); break; case TK_REGISTER: { sqlite3XPrintf(p, "r[%d]", pExpr->iTable); break; } case TK_COLUMN: { if( pExpr->iColumn<0 ){ sqlite3XPrintf(p, "rowid"); }else{ sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn); } break; } case TK_LT: zOp = "LT"; break; case TK_LE: zOp = "LE"; break; case TK_GT: zOp = "GT"; break; case TK_GE: zOp = "GE"; break; |
︙ | ︙ | |||
68712 68713 68714 68715 68716 68717 68718 | case TK_UPLUS: zOp = "PLUS"; break; case TK_BITNOT: zOp = "BITNOT"; break; case TK_NOT: zOp = "NOT"; break; case TK_ISNULL: zOp = "ISNULL"; break; case TK_NOTNULL: zOp = "NOTNULL"; break; default: | | | < | | < > | | < > > | | < | < < | < < < < < < < < | < | < < < < < < > | | | | | | | | | | | > > > > > | > > > | > | 68944 68945 68946 68947 68948 68949 68950 68951 68952 68953 68954 68955 68956 68957 68958 68959 68960 68961 68962 68963 68964 68965 68966 68967 68968 68969 68970 68971 68972 68973 68974 68975 68976 68977 68978 68979 68980 68981 68982 68983 68984 68985 68986 68987 68988 68989 68990 68991 68992 68993 68994 68995 68996 68997 68998 68999 69000 69001 69002 69003 69004 69005 69006 69007 69008 69009 69010 69011 69012 69013 69014 69015 69016 69017 69018 69019 69020 69021 69022 69023 69024 69025 69026 69027 69028 69029 69030 69031 69032 69033 69034 69035 69036 69037 69038 69039 69040 69041 69042 69043 69044 69045 69046 69047 69048 69049 69050 69051 69052 69053 69054 69055 69056 69057 69058 69059 69060 69061 69062 69063 69064 69065 69066 69067 69068 69069 69070 69071 69072 69073 69074 69075 69076 69077 69078 69079 69080 69081 69082 69083 69084 69085 69086 | case TK_UPLUS: zOp = "PLUS"; break; case TK_BITNOT: zOp = "BITNOT"; break; case TK_NOT: zOp = "NOT"; break; case TK_ISNULL: zOp = "ISNULL"; break; case TK_NOTNULL: zOp = "NOTNULL"; break; default: sqlite3XPrintf(p, "%s", "expr"); break; } if( zOp ){ sqlite3XPrintf(p, "%s(", zOp); displayP4Expr(p, pExpr->pLeft); if( pExpr->pRight ){ sqlite3StrAccumAppend(p, ",", 1); displayP4Expr(p, pExpr->pRight); } sqlite3StrAccumAppend(p, ")", 1); } } #endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */ #if VDBE_DISPLAY_P4 /* ** Compute a string that describes the P4 parameter for an opcode. ** Use zTemp for any required temporary buffer space. */ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ char *zP4 = zTemp; StrAccum x; assert( nTemp>=20 ); sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0); switch( pOp->p4type ){ case P4_KEYINFO: { int j; KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; assert( pKeyInfo->aSortOrder!=0 ); sqlite3XPrintf(&x, "k(%d", pKeyInfo->nField); for(j=0; j<pKeyInfo->nField; j++){ CollSeq *pColl = pKeyInfo->aColl[j]; const char *zColl = pColl ? pColl->zName : ""; if( strcmp(zColl, "BINARY")==0 ) zColl = "B"; sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl); } sqlite3StrAccumAppend(&x, ")", 1); break; } #ifdef SQLITE_ENABLE_CURSOR_HINTS case P4_EXPR: { displayP4Expr(&x, pOp->p4.pExpr); break; } #endif case P4_COLLSEQ: { CollSeq *pColl = pOp->p4.pColl; sqlite3XPrintf(&x, "(%.20s)", pColl->zName); break; } case P4_FUNCDEF: { FuncDef *pDef = pOp->p4.pFunc; sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg); break; } #ifdef SQLITE_DEBUG case P4_FUNCCTX: { FuncDef *pDef = pOp->p4.pCtx->pFunc; sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg); break; } #endif case P4_INT64: { sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64); break; } case P4_INT32: { sqlite3XPrintf(&x, "%d", pOp->p4.i); break; } case P4_REAL: { sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal); break; } case P4_MEM: { Mem *pMem = pOp->p4.pMem; if( pMem->flags & MEM_Str ){ zP4 = pMem->z; }else if( pMem->flags & MEM_Int ){ sqlite3XPrintf(&x, "%lld", pMem->u.i); }else if( pMem->flags & MEM_Real ){ sqlite3XPrintf(&x, "%.16g", pMem->u.r); }else if( pMem->flags & MEM_Null ){ zP4 = "NULL"; }else{ assert( pMem->flags & MEM_Blob ); zP4 = "(blob)"; } break; } #ifndef SQLITE_OMIT_VIRTUALTABLE case P4_VTAB: { sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab; sqlite3XPrintf(&x, "vtab:%p", pVtab); break; } #endif case P4_INTARRAY: { int i; int *ai = pOp->p4.ai; int n = ai[0]; /* The first element of an INTARRAY is always the ** count of the number of elements to follow */ for(i=1; i<n; i++){ sqlite3XPrintf(&x, ",%d", ai[i]); } zTemp[0] = '['; sqlite3StrAccumAppend(&x, "]", 1); break; } case P4_SUBPROGRAM: { sqlite3XPrintf(&x, "program"); break; } case P4_ADVANCE: { zTemp[0] = 0; break; } default: { zP4 = pOp->p4.z; if( zP4==0 ){ zP4 = zTemp; zTemp[0] = 0; } } } sqlite3StrAccumFinish(&x); assert( zP4!=0 ); return zP4; } #endif /* VDBE_DISPLAY_P4 */ /* ** Declare to the Vdbe that the BTree object at db->aDb[i] is used. |
︙ | ︙ | |||
68968 68969 68970 68971 68972 68973 68974 | /* ** Release an array of N Mem elements */ static void releaseMemArray(Mem *p, int N){ if( p && N ){ Mem *pEnd = &p[N]; sqlite3 *db = p->db; | < | 69192 69193 69194 69195 69196 69197 69198 69199 69200 69201 69202 69203 69204 69205 | /* ** Release an array of N Mem elements */ static void releaseMemArray(Mem *p, int N){ if( p && N ){ Mem *pEnd = &p[N]; sqlite3 *db = p->db; if( db->pnBytesFreed ){ do{ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); }while( (++p)<pEnd ); return; } do{ |
︙ | ︙ | |||
69004 69005 69006 69007 69008 69009 69010 | }else if( p->szMalloc ){ sqlite3DbFree(db, p->zMalloc); p->szMalloc = 0; } p->flags = MEM_Undefined; }while( (++p)<pEnd ); | < | 69227 69228 69229 69230 69231 69232 69233 69234 69235 69236 69237 69238 69239 69240 | }else if( p->szMalloc ){ sqlite3DbFree(db, p->zMalloc); p->szMalloc = 0; } p->flags = MEM_Undefined; }while( (++p)<pEnd ); } } /* ** Delete a VdbeFrame object and its contents. VdbeFrame objects are ** allocated by the OP_Program opcode in sqlite3VdbeExec(). */ |
︙ | ︙ | |||
69065 69066 69067 69068 69069 69070 69071 | */ releaseMemArray(pMem, 8); p->pResultSet = 0; if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or ** sqlite3_column_text16() failed. */ | | | 69287 69288 69289 69290 69291 69292 69293 69294 69295 69296 69297 69298 69299 69300 69301 | */ releaseMemArray(pMem, 8); p->pResultSet = 0; if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or ** sqlite3_column_text16() failed. */ sqlite3OomFault(db); return SQLITE_ERROR; } /* When the number of output rows reaches nRow, that means the ** listing has finished and sqlite3_step() should return SQLITE_DONE. ** nRow is the sum of the number of rows in the main program, plus ** the sum of the number of rows in all trigger subprograms encountered |
︙ | ︙ | |||
69263 69264 69265 69266 69267 69268 69269 | } z[j] = 0; sqlite3IoTrace("SQL %s\n", z); } } #endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */ | > > > | > > > > > | > > | > > < | | < < | < < | < > | < < < < < | | < > | | | | | | 69485 69486 69487 69488 69489 69490 69491 69492 69493 69494 69495 69496 69497 69498 69499 69500 69501 69502 69503 69504 69505 69506 69507 69508 69509 69510 69511 69512 69513 69514 69515 69516 69517 69518 69519 69520 69521 69522 69523 69524 69525 69526 69527 69528 69529 69530 69531 69532 69533 69534 69535 | } z[j] = 0; sqlite3IoTrace("SQL %s\n", z); } } #endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */ /* An instance of this object describes bulk memory available for use ** by subcomponents of a prepared statement. Space is allocated out ** of a ReusableSpace object by the allocSpace() routine below. */ struct ReusableSpace { u8 *pSpace; /* Available memory */ int nFree; /* Bytes of available memory */ int nNeeded; /* Total bytes that could not be allocated */ }; /* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf ** from the ReusableSpace object. Return a pointer to the allocated ** memory on success. If insufficient memory is available in the ** ReusableSpace object, increase the ReusableSpace.nNeeded ** value by the amount needed and return NULL. ** ** If pBuf is not initially NULL, that means that the memory has already ** been allocated by a prior call to this routine, so just return a copy ** of pBuf and leave ReusableSpace unchanged. ** ** This allocator is employed to repurpose unused slots at the end of the ** opcode array of prepared state for other memory needs of the prepared ** statement. */ static void *allocSpace( struct ReusableSpace *p, /* Bulk memory available for allocation */ void *pBuf, /* Pointer to a prior allocation */ int nByte /* Bytes of memory needed */ ){ assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) ); if( pBuf==0 ){ nByte = ROUND8(nByte); if( nByte <= p->nFree ){ p->nFree -= nByte; pBuf = &p->pSpace[p->nFree]; }else{ p->nNeeded += nByte; } } assert( EIGHT_BYTE_ALIGNMENT(pBuf) ); return pBuf; } /* |
︙ | ︙ | |||
69330 69331 69332 69333 69334 69335 69336 | for(i=1; i<p->nMem; i++){ assert( p->aMem[i].db==p->db ); } #endif p->pc = -1; p->rc = SQLITE_OK; p->errorAction = OE_Abort; | < | 69554 69555 69556 69557 69558 69559 69560 69561 69562 69563 69564 69565 69566 69567 | for(i=1; i<p->nMem; i++){ assert( p->aMem[i].db==p->db ); } #endif p->pc = -1; p->rc = SQLITE_OK; p->errorAction = OE_Abort; p->nChange = 0; p->cacheCtr = 1; p->minWriteFileFormat = 255; p->iStatement = 0; p->nFkConstraint = 0; #ifdef VDBE_PROFILE for(i=0; i<p->nOp; i++){ |
︙ | ︙ | |||
69373 69374 69375 69376 69377 69378 69379 | sqlite3 *db; /* The database connection */ int nVar; /* Number of parameters */ int nMem; /* Number of VM memory registers */ int nCursor; /* Number of cursors required */ int nArg; /* Number of arguments in subprograms */ int nOnce; /* Number of OP_Once instructions */ int n; /* Loop counter */ | | < < | | | < < | | | | | | | | | | | | | | | | | | < | | | | < < | | | 69596 69597 69598 69599 69600 69601 69602 69603 69604 69605 69606 69607 69608 69609 69610 69611 69612 69613 69614 69615 69616 69617 69618 69619 69620 69621 69622 69623 69624 69625 69626 69627 69628 69629 69630 69631 69632 69633 69634 69635 69636 69637 69638 69639 69640 69641 69642 69643 69644 69645 69646 69647 69648 69649 69650 69651 69652 69653 69654 69655 69656 69657 69658 69659 69660 69661 69662 69663 69664 69665 69666 69667 69668 69669 69670 69671 69672 69673 69674 69675 69676 69677 69678 69679 69680 69681 | sqlite3 *db; /* The database connection */ int nVar; /* Number of parameters */ int nMem; /* Number of VM memory registers */ int nCursor; /* Number of cursors required */ int nArg; /* Number of arguments in subprograms */ int nOnce; /* Number of OP_Once instructions */ int n; /* Loop counter */ struct ReusableSpace x; /* Reusable bulk memory */ assert( p!=0 ); assert( p->nOp>0 ); assert( pParse!=0 ); assert( p->magic==VDBE_MAGIC_INIT ); assert( pParse==p->pParse ); db = p->db; assert( db->mallocFailed==0 ); nVar = pParse->nVar; nMem = pParse->nMem; nCursor = pParse->nTab; nArg = pParse->nMaxArg; nOnce = pParse->nOnce; if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */ /* For each cursor required, also allocate a memory cell. Memory ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by ** the vdbe program. Instead they are used to allocate memory for ** VdbeCursor/BtCursor structures. The blob of memory associated with ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) ** stores the blob of memory associated with cursor 1, etc. ** ** See also: allocateCursor(). */ nMem += nCursor; /* Figure out how much reusable memory is available at the end of the ** opcode array. This extra memory will be reallocated for other elements ** of the prepared statement. */ n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */ x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */ assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) ); x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */ assert( x.nFree>=0 ); if( x.nFree>0 ){ memset(x.pSpace, 0, x.nFree); assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) ); } resolveP2Values(p, &nArg); p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); if( pParse->explain && nMem<10 ){ nMem = 10; } p->expired = 0; /* Memory for registers, parameters, cursor, etc, is allocated in one or two ** passes. On the first pass, we try to reuse unused memory at the ** end of the opcode array. If we are unable to satisfy all memory ** requirements by reusing the opcode array tail, then the second ** pass will fill in the remainder using a fresh memory allocation. ** ** This two-pass approach that reuses as much memory as possible from ** the leftover memory at the end of the opcode array. This can significantly ** reduce the amount of memory held by a prepared statement. */ do { x.nNeeded = 0; p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem)); p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); p->aOnceFlag = allocSpace(&x, p->aOnceFlag, nOnce); #ifdef SQLITE_ENABLE_STMT_SCANSTATUS p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64)); #endif if( x.nNeeded==0 ) break; x.pSpace = p->pFree = sqlite3DbMallocZero(db, x.nNeeded); x.nFree = x.nNeeded; }while( !db->mallocFailed ); p->nCursor = nCursor; p->nOnceFlag = nOnce; if( p->aVar ){ p->nVar = (ynVar)nVar; for(n=0; n<nVar; n++){ p->aVar[n].flags = MEM_Null; |
︙ | ︙ | |||
70064 70065 70066 70067 70068 70069 70070 | ** SQLITE_INTERRUPT ** ** Then the internal cache might have been left in an inconsistent ** state. We need to rollback the statement transaction, if there is ** one, or the complete transaction if there is no statement transaction. */ | | | 70280 70281 70282 70283 70284 70285 70286 70287 70288 70289 70290 70291 70292 70293 70294 | ** SQLITE_INTERRUPT ** ** Then the internal cache might have been left in an inconsistent ** state. We need to rollback the statement transaction, if there is ** one, or the complete transaction if there is no statement transaction. */ if( db->mallocFailed ){ p->rc = SQLITE_NOMEM; } if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag); closeAllCursors(p); if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_OK; } |
︙ | ︙ | |||
70225 70226 70227 70228 70229 70230 70231 | if( p->bIsReader ) db->nVdbeRead--; assert( db->nVdbeActive>=db->nVdbeRead ); assert( db->nVdbeRead>=db->nVdbeWrite ); assert( db->nVdbeWrite>=0 ); } p->magic = VDBE_MAGIC_HALT; checkActiveVdbeCnt(db); | | | 70441 70442 70443 70444 70445 70446 70447 70448 70449 70450 70451 70452 70453 70454 70455 | if( p->bIsReader ) db->nVdbeRead--; assert( db->nVdbeActive>=db->nVdbeRead ); assert( db->nVdbeRead>=db->nVdbeWrite ); assert( db->nVdbeWrite>=0 ); } p->magic = VDBE_MAGIC_HALT; checkActiveVdbeCnt(db); if( db->mallocFailed ){ p->rc = SQLITE_NOMEM; } /* If the auto-commit flag is set to true, then any locks that were held ** by connection db have now been released. Call sqlite3ConnectionUnlocked() ** to invoke any required unlock-notify callbacks. */ |
︙ | ︙ | |||
70262 70263 70264 70265 70266 70267 70268 | ** This function does not clear the VDBE error code or message, just ** copies them to the database handle. */ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){ sqlite3 *db = p->db; int rc = p->rc; if( p->zErrMsg ){ | | | | 70478 70479 70480 70481 70482 70483 70484 70485 70486 70487 70488 70489 70490 70491 70492 70493 70494 70495 70496 70497 | ** This function does not clear the VDBE error code or message, just ** copies them to the database handle. */ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){ sqlite3 *db = p->db; int rc = p->rc; if( p->zErrMsg ){ db->bBenignMalloc++; sqlite3BeginBenignMalloc(); if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db); sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); sqlite3EndBenignMalloc(); db->bBenignMalloc--; db->errCode = rc; }else{ sqlite3Error(db, rc); } return rc; } |
︙ | ︙ | |||
70556 70557 70558 70559 70560 70561 70562 | ** MoveTo now. If no move is pending, check to see if the row has been ** deleted out from under the cursor and if it has, mark the row as ** a NULL row. ** ** If the cursor is already pointing to the correct row and that row has ** not been deleted out from under the cursor, then this routine is a no-op. */ | | > > > > > > > | 70772 70773 70774 70775 70776 70777 70778 70779 70780 70781 70782 70783 70784 70785 70786 70787 70788 70789 70790 70791 70792 70793 70794 70795 | ** MoveTo now. If no move is pending, check to see if the row has been ** deleted out from under the cursor and if it has, mark the row as ** a NULL row. ** ** If the cursor is already pointing to the correct row and that row has ** not been deleted out from under the cursor, then this routine is a no-op. */ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ VdbeCursor *p = *pp; if( p->eCurType==CURTYPE_BTREE ){ if( p->deferredMoveto ){ int iMap; if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){ *pp = p->pAltCursor; *piCol = iMap - 1; return SQLITE_OK; } return handleDeferredMoveto(p); } if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ return handleMovedCursor(p); } } return SQLITE_OK; |
︙ | ︙ | |||
72189 72190 72191 72192 72193 72194 72195 | SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value *pVal){ return (int)sqlite3VdbeIntValue((Mem*)pVal); } SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value *pVal){ return sqlite3VdbeIntValue((Mem*)pVal); } SQLITE_API unsigned int SQLITE_STDCALL sqlite3_value_subtype(sqlite3_value *pVal){ | | > | 72412 72413 72414 72415 72416 72417 72418 72419 72420 72421 72422 72423 72424 72425 72426 72427 | SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value *pVal){ return (int)sqlite3VdbeIntValue((Mem*)pVal); } SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value *pVal){ return sqlite3VdbeIntValue((Mem*)pVal); } SQLITE_API unsigned int SQLITE_STDCALL sqlite3_value_subtype(sqlite3_value *pVal){ Mem *pMem = (Mem*)pVal; return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0); } SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value *pVal){ return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); } #ifndef SQLITE_OMIT_UTF16 SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value* pVal){ return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); |
︙ | ︙ | |||
72370 72371 72372 72373 72374 72375 72376 | sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); } SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); } SQLITE_API void SQLITE_STDCALL sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ | > | | > | 72594 72595 72596 72597 72598 72599 72600 72601 72602 72603 72604 72605 72606 72607 72608 72609 72610 72611 | sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); } SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); } SQLITE_API void SQLITE_STDCALL sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); pOut->eSubtype = eSubtype & 0xff; pOut->flags |= MEM_Subtype; } SQLITE_API void SQLITE_STDCALL sqlite3_result_text( sqlite3_context *pCtx, const char *z, int n, void (*xDel)(void *) ){ |
︙ | ︙ | |||
72471 72472 72473 72474 72475 72476 72477 | /* An SQLITE_NOMEM error. */ SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); pCtx->isError = SQLITE_NOMEM; pCtx->fErrorOrAux = 1; | | | 72697 72698 72699 72700 72701 72702 72703 72704 72705 72706 72707 72708 72709 72710 72711 | /* An SQLITE_NOMEM error. */ SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); pCtx->isError = SQLITE_NOMEM; pCtx->fErrorOrAux = 1; sqlite3OomFault(pCtx->pOut->db); } /* ** This function is called after a transaction has been committed. It ** invokes callbacks registered with sqlite3_wal_hook() as required. */ static int doWalCallbacks(sqlite3 *db){ |
︙ | ︙ | |||
73099 73100 73101 73102 73103 73104 73105 | sqlite3_mutex_enter(db->mutex); assert( db->mallocFailed==0 ); ret = xFunc(&p->aColName[N]); /* A malloc may have failed inside of the xFunc() call. If this ** is the case, clear the mallocFailed flag and return NULL. */ if( db->mallocFailed ){ | | | 73325 73326 73327 73328 73329 73330 73331 73332 73333 73334 73335 73336 73337 73338 73339 | sqlite3_mutex_enter(db->mutex); assert( db->mallocFailed==0 ); ret = xFunc(&p->aColName[N]); /* A malloc may have failed inside of the xFunc() call. If this ** is the case, clear the mallocFailed flag and return NULL. */ if( db->mallocFailed ){ sqlite3OomClear(db); ret = 0; } sqlite3_mutex_leave(db->mutex); } return ret; } |
︙ | ︙ | |||
73800 73801 73802 73803 73804 73805 73806 | zRawSql += nToken; nextIndex = idx + 1; assert( idx>0 && idx<=p->nVar ); pVar = &p->aVar[idx-1]; if( pVar->flags & MEM_Null ){ sqlite3StrAccumAppend(&out, "NULL", 4); }else if( pVar->flags & MEM_Int ){ | | | | | | | | | 74026 74027 74028 74029 74030 74031 74032 74033 74034 74035 74036 74037 74038 74039 74040 74041 74042 74043 74044 74045 74046 74047 74048 74049 74050 74051 74052 74053 74054 74055 74056 74057 74058 74059 74060 74061 74062 74063 74064 74065 74066 74067 74068 74069 74070 74071 74072 74073 74074 74075 74076 74077 74078 74079 74080 74081 74082 74083 74084 74085 74086 74087 74088 | zRawSql += nToken; nextIndex = idx + 1; assert( idx>0 && idx<=p->nVar ); pVar = &p->aVar[idx-1]; if( pVar->flags & MEM_Null ){ sqlite3StrAccumAppend(&out, "NULL", 4); }else if( pVar->flags & MEM_Int ){ sqlite3XPrintf(&out, "%lld", pVar->u.i); }else if( pVar->flags & MEM_Real ){ sqlite3XPrintf(&out, "%!.15g", pVar->u.r); }else if( pVar->flags & MEM_Str ){ int nOut; /* Number of bytes of the string text to include in output */ #ifndef SQLITE_OMIT_UTF16 u8 enc = ENC(db); Mem utf8; if( enc!=SQLITE_UTF8 ){ memset(&utf8, 0, sizeof(utf8)); utf8.db = db; sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8); pVar = &utf8; } #endif nOut = pVar->n; #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOut>SQLITE_TRACE_SIZE_LIMIT ){ nOut = SQLITE_TRACE_SIZE_LIMIT; while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } } #endif sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z); #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOut<pVar->n ){ sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); } #endif #ifndef SQLITE_OMIT_UTF16 if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); #endif }else if( pVar->flags & MEM_Zero ){ sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero); }else{ int nOut; /* Number of bytes of the blob to include in output */ assert( pVar->flags & MEM_Blob ); sqlite3StrAccumAppend(&out, "x'", 2); nOut = pVar->n; #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; #endif for(i=0; i<nOut; i++){ sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff); } sqlite3StrAccumAppend(&out, "'", 1); #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOut<pVar->n ){ sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); } #endif } } } return sqlite3StrAccumFinish(&out); } |
︙ | ︙ | |||
74334 74335 74336 74337 74338 74339 74340 74341 74342 74343 74344 74345 74346 74347 | }else if( p->flags & MEM_RowSet ){ printf(" (rowset)"); }else{ char zBuf[200]; sqlite3VdbeMemPrettyPrint(p, zBuf); printf(" %s", zBuf); } } static void registerTrace(int iReg, Mem *p){ printf("REG[%d] = ", iReg); memTracePrint(p); printf("\n"); } #endif | > | 74560 74561 74562 74563 74564 74565 74566 74567 74568 74569 74570 74571 74572 74573 74574 | }else if( p->flags & MEM_RowSet ){ printf(" (rowset)"); }else{ char zBuf[200]; sqlite3VdbeMemPrettyPrint(p, zBuf); printf(" %s", zBuf); } if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype); } static void registerTrace(int iReg, Mem *p){ printf("REG[%d] = ", iReg); memTracePrint(p); printf("\n"); } #endif |
︙ | ︙ | |||
74504 74505 74506 74507 74508 74509 74510 74511 74512 74513 74514 74515 74516 74517 | Vdbe *p /* The VDBE */ ){ Op *aOp = p->aOp; /* Copy of p->aOp */ Op *pOp = aOp; /* Current operation */ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) Op *pOrigOp; /* Value of pOp at the top of the loop */ #endif int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ u8 encoding = ENC(db); /* The database encoding */ int iCompare = 0; /* Result of last OP_Compare operation */ unsigned nVmStep = 0; /* Number of virtual machine steps */ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK | > > > | 74731 74732 74733 74734 74735 74736 74737 74738 74739 74740 74741 74742 74743 74744 74745 74746 74747 | Vdbe *p /* The VDBE */ ){ Op *aOp = p->aOp; /* Copy of p->aOp */ Op *pOp = aOp; /* Current operation */ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) Op *pOrigOp; /* Value of pOp at the top of the loop */ #endif #ifdef SQLITE_DEBUG int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */ #endif int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ u8 encoding = ENC(db); /* The database encoding */ int iCompare = 0; /* Result of last OP_Compare operation */ unsigned nVmStep = 0; /* Number of virtual machine steps */ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
︙ | ︙ | |||
74577 74578 74579 74580 74581 74582 74583 | } if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n"); } sqlite3EndBenignMalloc(); #endif for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){ assert( pOp>=aOp && pOp<&aOp[p->nOp]); | < | 74807 74808 74809 74810 74811 74812 74813 74814 74815 74816 74817 74818 74819 74820 | } if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n"); } sqlite3EndBenignMalloc(); #endif for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){ assert( pOp>=aOp && pOp<&aOp[p->nOp]); #ifdef VDBE_PROFILE start = sqlite3Hwtime(); #endif nVmStep++; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS if( p->anExec ) p->anExec[(int)(pOp-aOp)]++; #endif |
︙ | ︙ | |||
75575 75576 75577 75578 75579 75580 75581 | sqlite3_context *pCtx; assert( pOp->p4type==P4_FUNCDEF ); n = pOp->p5; assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); | | | 75804 75805 75806 75807 75808 75809 75810 75811 75812 75813 75814 75815 75816 75817 75818 | sqlite3_context *pCtx; assert( pOp->p4type==P4_FUNCDEF ); n = pOp->p5; assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); if( pCtx==0 ) goto no_mem; pCtx->pOut = 0; pCtx->pFunc = pOp->p4.pFunc; pCtx->iOp = (int)(pOp - aOp); pCtx->pVdbe = p; pCtx->argc = n; pOp->p4type = P4_FUNCCTX; |
︙ | ︙ | |||
76019 76020 76021 76022 76023 76024 76025 76026 76027 76028 76029 | ** ** Set the permutation used by the OP_Compare operator to be the array ** of integers in P4. ** ** The permutation is only valid until the next OP_Compare that has ** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should ** occur immediately prior to the OP_Compare. */ case OP_Permutation: { assert( pOp->p4type==P4_INTARRAY ); assert( pOp->p4.ai ); | > > > | | 76248 76249 76250 76251 76252 76253 76254 76255 76256 76257 76258 76259 76260 76261 76262 76263 76264 76265 76266 76267 76268 76269 | ** ** Set the permutation used by the OP_Compare operator to be the array ** of integers in P4. ** ** The permutation is only valid until the next OP_Compare that has ** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should ** occur immediately prior to the OP_Compare. ** ** The first integer in the P4 integer array is the length of the array ** and does not become part of the permutation. */ case OP_Permutation: { assert( pOp->p4type==P4_INTARRAY ); assert( pOp->p4.ai ); aPermute = pOp->p4.ai + 1; break; } /* Opcode: Compare P1 P2 P3 P4 P5 ** Synopsis: r[P1@P3] <-> r[P2@P3] ** ** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this |
︙ | ︙ | |||
76328 76329 76330 76331 76332 76333 76334 76335 76336 76337 76338 76339 | const u8 *zEndHdr; /* Pointer to first byte after the header */ u32 offset; /* Offset into the data */ u64 offset64; /* 64-bit offset */ u32 avail; /* Number of bytes of available data */ u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ p2 = pOp->p2; assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | > > > > > < < < | 76560 76561 76562 76563 76564 76565 76566 76567 76568 76569 76570 76571 76572 76573 76574 76575 76576 76577 76578 76579 76580 76581 76582 76583 76584 76585 76586 76587 76588 76589 76590 76591 | const u8 *zEndHdr; /* Pointer to first byte after the header */ u32 offset; /* Offset into the data */ u64 offset64; /* 64-bit offset */ u32 avail; /* Number of bytes of available data */ u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ pC = p->apCsr[pOp->p1]; p2 = pOp->p2; /* If the cursor cache is stale, bring it up-to-date */ rc = sqlite3VdbeCursorMoveto(&pC, &p2); assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pC!=0 ); assert( p2<pC->nField ); aOffset = pC->aOffset; assert( pC->eCurType!=CURTYPE_VTAB ); assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); assert( pC->eCurType!=CURTYPE_SORTER ); pCrsr = pC->uc.pCursor; if( rc ) goto abort_due_to_error; if( pC->cacheStatus!=p->cacheCtr ){ if( pC->nullRow ){ if( pC->eCurType==CURTYPE_PSEUDO ){ assert( pC->uc.pseudoTableReg>0 ); pReg = &aMem[pC->uc.pseudoTableReg]; assert( pReg->flags & MEM_Blob ); |
︙ | ︙ | |||
76814 76815 76816 76817 76818 76819 76820 | assert( db->autoCommit==0 || db->nVTrans==0 ); rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, db->nStatement+db->nSavepoint); if( rc!=SQLITE_OK ) goto abort_due_to_error; #endif /* Create a new savepoint structure. */ | | | 77048 77049 77050 77051 77052 77053 77054 77055 77056 77057 77058 77059 77060 77061 77062 | assert( db->autoCommit==0 || db->nVTrans==0 ); rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, db->nStatement+db->nSavepoint); if( rc!=SQLITE_OK ) goto abort_due_to_error; #endif /* Create a new savepoint structure. */ pNew = sqlite3DbMallocRawNN(db, sizeof(Savepoint)+nName+1); if( pNew ){ pNew->zName = (char *)&pNew[1]; memcpy(pNew->zName, zName, nName+1); /* If there is no open transaction, then mark this as a special ** "transaction savepoint". */ if( db->autoCommit ){ |
︙ | ︙ | |||
76951 76952 76953 76954 76955 76956 76957 | ** there are active writing VMs or active VMs that use shared cache. ** ** This instruction causes the VM to halt. */ case OP_AutoCommit: { int desiredAutoCommit; int iRollback; | < < < < < < < < < | > > > > > > > > | 77185 77186 77187 77188 77189 77190 77191 77192 77193 77194 77195 77196 77197 77198 77199 77200 77201 77202 77203 77204 77205 77206 77207 77208 77209 77210 77211 77212 77213 77214 77215 77216 77217 77218 77219 | ** there are active writing VMs or active VMs that use shared cache. ** ** This instruction causes the VM to halt. */ case OP_AutoCommit: { int desiredAutoCommit; int iRollback; desiredAutoCommit = pOp->p1; iRollback = pOp->p2; assert( desiredAutoCommit==1 || desiredAutoCommit==0 ); assert( desiredAutoCommit==1 || iRollback==0 ); assert( db->nVdbeActive>0 ); /* At least this one VM is active */ assert( p->bIsReader ); if( desiredAutoCommit!=db->autoCommit ){ if( iRollback ){ assert( desiredAutoCommit==1 ); sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); db->autoCommit = 1; }else if( desiredAutoCommit && db->nVdbeWrite>0 ){ /* If this instruction implements a COMMIT and other VMs are writing ** return an error indicating that the other VMs must complete first. */ sqlite3VdbeError(p, "cannot commit transaction - " "SQL statements in progress"); rc = SQLITE_BUSY; break; }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ goto vdbe_return; }else{ db->autoCommit = (u8)desiredAutoCommit; } if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ p->pc = (int)(pOp - aOp); |
︙ | ︙ | |||
77157 77158 77159 77160 77161 77162 77163 | pOut = out2Prerelease(p, pOp); pOut->u.i = iMeta; break; } /* Opcode: SetCookie P1 P2 P3 * * ** | | | | | < < | | | | 77390 77391 77392 77393 77394 77395 77396 77397 77398 77399 77400 77401 77402 77403 77404 77405 77406 77407 77408 77409 77410 77411 77412 77413 77414 77415 77416 77417 77418 77419 77420 77421 77422 77423 77424 77425 77426 77427 77428 77429 | pOut = out2Prerelease(p, pOp); pOut->u.i = iMeta; break; } /* Opcode: SetCookie P1 P2 P3 * * ** ** Write the integer value P3 into cookie number P2 of database P1. ** P2==1 is the schema version. P2==2 is the database format. ** P2==3 is the recommended pager cache ** size, and so forth. P1==0 is the main database file and P1==1 is the ** database file used to store temporary tables. ** ** A transaction must be started before executing this opcode. */ case OP_SetCookie: { Db *pDb; assert( pOp->p2<SQLITE_N_BTREE_META ); assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( DbMaskTest(p->btreeMask, pOp->p1) ); assert( p->readOnly==0 ); pDb = &db->aDb[pOp->p1]; assert( pDb->pBt!=0 ); assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); /* See note about index shifting on OP_ReadCookie */ rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3); if( pOp->p2==BTREE_SCHEMA_VERSION ){ /* When the schema cookie changes, record the new cookie internally */ pDb->pSchema->schema_cookie = pOp->p3; db->flags |= SQLITE_InternChanges; }else if( pOp->p2==BTREE_FILE_FORMAT ){ /* Record changes in the file format */ pDb->pSchema->file_format = pOp->p3; } if( pOp->p1==1 ){ /* Invalidate all prepared statements whenever the TEMP database ** schema is changed. Ticket #1644 */ sqlite3ExpirePreparedStatements(db); p->expired = 0; } |
︙ | ︙ | |||
77344 77345 77346 77347 77348 77349 77350 77351 77352 77353 77354 77355 77356 77357 | assert( nField>=0 ); testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ pCur = allocateCursor(p, pOp->p1, nField, iDb, CURTYPE_BTREE); if( pCur==0 ) goto no_mem; pCur->nullRow = 1; pCur->isOrdered = 1; pCur->pgnoRoot = p2; rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor); pCur->pKeyInfo = pKeyInfo; /* Set the VdbeCursor.isTable variable. Previous versions of ** SQLite used to check if the root-page flags were sane at this point ** and report database corruption if they were not, but this check has ** since moved into the btree layer. */ pCur->isTable = pOp->p4type!=P4_KEYINFO; | > > > | 77575 77576 77577 77578 77579 77580 77581 77582 77583 77584 77585 77586 77587 77588 77589 77590 77591 | assert( nField>=0 ); testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ pCur = allocateCursor(p, pOp->p1, nField, iDb, CURTYPE_BTREE); if( pCur==0 ) goto no_mem; pCur->nullRow = 1; pCur->isOrdered = 1; pCur->pgnoRoot = p2; #ifdef SQLITE_DEBUG pCur->wrFlag = wrFlag; #endif rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor); pCur->pKeyInfo = pKeyInfo; /* Set the VdbeCursor.isTable variable. Previous versions of ** SQLite used to check if the root-page flags were sane at this point ** and report database corruption if they were not, but this check has ** since moved into the btree layer. */ pCur->isTable = pOp->p4type!=P4_KEYINFO; |
︙ | ︙ | |||
77797 77798 77799 77800 77801 77802 77803 | goto jump_to_p2; }else if( eqOnly ){ assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT ); pOp++; /* Skip the OP_IdxLt or OP_IdxGT that follows */ } break; } | < < < < < < < < < < < < < < < < < < < < < < < < < < | 78031 78032 78033 78034 78035 78036 78037 78038 78039 78040 78041 78042 78043 78044 | goto jump_to_p2; }else if( eqOnly ){ assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT ); pOp++; /* Skip the OP_IdxLt or OP_IdxGT that follows */ } break; } /* Opcode: Found P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** ** If P4==0 then register P3 holds a blob constructed by MakeRecord. If ** P4>0 then register P3 is the first of P4 registers that form an unpacked |
︙ | ︙ | |||
78293 78294 78295 78296 78297 78298 78299 | break; } /* Opcode: Delete P1 P2 * P4 P5 ** ** Delete the record at which the P1 cursor is currently pointing. ** | > | | | | > | > > > > > > | | | 78501 78502 78503 78504 78505 78506 78507 78508 78509 78510 78511 78512 78513 78514 78515 78516 78517 78518 78519 78520 78521 78522 78523 78524 78525 78526 78527 78528 78529 78530 | break; } /* Opcode: Delete P1 P2 * P4 P5 ** ** Delete the record at which the P1 cursor is currently pointing. ** ** If the OPFLAG_SAVEPOSITION bit of the P5 parameter is set, then ** the cursor will be left pointing at either the next or the previous ** record in the table. If it is left pointing at the next record, then ** the next Next instruction will be a no-op. As a result, in this case ** it is ok to delete a record from within a Next loop. If ** OPFLAG_SAVEPOSITION bit of P5 is clear, then the cursor will be ** left in an undefined state. ** ** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this ** delete one of several associated with deleting a table row and all its ** associated index entries. Exactly one of those deletes is the "primary" ** delete. The others are all on OPFLAG_FORDELETE cursors or else are ** marked with the AUXDELETE flag. ** ** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row ** change count is incremented (otherwise not). ** ** P1 must not be pseudo-table. It has to be a real table with ** multiple rows. ** ** If P4 is not NULL, then it is the name of the table that P1 is ** pointing to. The update hook will be invoked, if it exists. ** If P4 is not NULL then the P1 cursor must have been positioned |
︙ | ︙ | |||
78336 78337 78338 78339 78340 78341 78342 | ** is being deleted */ if( pOp->p4.z && pC->isTable && pOp->p5==0 ){ i64 iKey = 0; sqlite3BtreeKeySize(pC->uc.pCursor, &iKey); assert( pC->movetoTarget==iKey ); } #endif | | > > > > > > > > > > > > > > > > > > > | 78552 78553 78554 78555 78556 78557 78558 78559 78560 78561 78562 78563 78564 78565 78566 78567 78568 78569 78570 78571 78572 78573 78574 78575 78576 78577 78578 78579 78580 78581 78582 78583 78584 78585 | ** is being deleted */ if( pOp->p4.z && pC->isTable && pOp->p5==0 ){ i64 iKey = 0; sqlite3BtreeKeySize(pC->uc.pCursor, &iKey); assert( pC->movetoTarget==iKey ); } #endif /* Only flags that can be set are SAVEPOISTION and AUXDELETE */ assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 ); assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION ); assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE ); #ifdef SQLITE_DEBUG if( p->pFrame==0 ){ if( pC->isEphemeral==0 && (pOp->p5 & OPFLAG_AUXDELETE)==0 && (pC->wrFlag & OPFLAG_FORDELETE)==0 ){ nExtraDelete++; } if( pOp->p2 & OPFLAG_NCHANGE ){ nExtraDelete--; } } #endif rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && hasUpdateCallback ){ db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget); |
︙ | ︙ | |||
78881 78882 78883 78884 78885 78886 78887 | pCrsr = pC->uc.pCursor; assert( pCrsr!=0 ); assert( pOp->p5==0 ); r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p3; r.default_rc = 0; r.aMem = &aMem[pOp->p2]; | < < < | > > > > > > > > > > > > > > > > > > > > | | | < < | < > > > > > | | < < | > > > > > > > > > > > > > > > | | > > > > | 79116 79117 79118 79119 79120 79121 79122 79123 79124 79125 79126 79127 79128 79129 79130 79131 79132 79133 79134 79135 79136 79137 79138 79139 79140 79141 79142 79143 79144 79145 79146 79147 79148 79149 79150 79151 79152 79153 79154 79155 79156 79157 79158 79159 79160 79161 79162 79163 79164 79165 79166 79167 79168 79169 79170 79171 79172 79173 79174 79175 79176 79177 79178 79179 79180 79181 79182 79183 79184 79185 79186 79187 79188 79189 79190 79191 79192 79193 79194 79195 79196 79197 79198 79199 79200 79201 79202 79203 79204 79205 79206 79207 79208 79209 79210 79211 79212 79213 79214 79215 79216 79217 | pCrsr = pC->uc.pCursor; assert( pCrsr!=0 ); assert( pOp->p5==0 ); r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p3; r.default_rc = 0; r.aMem = &aMem[pOp->p2]; rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); if( rc==SQLITE_OK && res==0 ){ rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); } assert( pC->deferredMoveto==0 ); pC->cacheStatus = CACHE_STALE; break; } /* Opcode: Seek P1 * P3 P4 * ** Synopsis: Move P3 to P1.rowid ** ** P1 is an open index cursor and P3 is a cursor on the corresponding ** table. This opcode does a deferred seek of the P3 table cursor ** to the row that corresponds to the current row of P1. ** ** This is a deferred seek. Nothing actually happens until ** the cursor is used to read a record. That way, if no reads ** occur, no unnecessary I/O happens. ** ** P4 may be an array of integers (type P4_INTARRAY) containing ** one entry for each column in the P3 table. If array entry a(i) ** is non-zero, then reading column a(i)-1 from cursor P3 is ** equivalent to performing the deferred seek and then reading column i ** from P1. This information is stored in P3 and used to redirect ** reads against P3 over to P1, thus possibly avoiding the need to ** seek and read cursor P3. */ /* Opcode: IdxRowid P1 P2 * * * ** Synopsis: r[P2]=rowid ** ** Write into register P2 an integer which is the last entry in the record at ** the end of the index key pointed to by cursor P1. This integer should be ** the rowid of the table entry to which this index entry points. ** ** See also: Rowid, MakeRecord. */ case OP_Seek: case OP_IdxRowid: { /* out2 */ VdbeCursor *pC; /* The P1 index cursor */ VdbeCursor *pTabCur; /* The P2 table cursor (OP_Seek only) */ i64 rowid; /* Rowid that P1 current points to */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->uc.pCursor!=0 ); assert( pC->isTable==0 ); assert( pC->deferredMoveto==0 ); assert( !pC->nullRow || pOp->opcode==OP_IdxRowid ); /* The IdxRowid and Seek opcodes are combined because of the commonality ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */ rc = sqlite3VdbeCursorRestore(pC); /* sqlite3VbeCursorRestore() can only fail if the record has been deleted ** out from under the cursor. That will never happens for an IdxRowid ** or Seek opcode */ if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; if( !pC->nullRow ){ rowid = 0; /* Not needed. Only used to silence a warning. */ rc = sqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } if( pOp->opcode==OP_Seek ){ assert( pOp->p3>=0 && pOp->p3<p->nCursor ); pTabCur = p->apCsr[pOp->p3]; assert( pTabCur!=0 ); assert( pTabCur->eCurType==CURTYPE_BTREE ); assert( pTabCur->uc.pCursor!=0 ); assert( pTabCur->isTable ); pTabCur->nullRow = 0; pTabCur->movetoTarget = rowid; pTabCur->deferredMoveto = 1; assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); pTabCur->aAltMap = pOp->p4.ai; pTabCur->pAltCursor = pC; }else{ pOut = out2Prerelease(p, pOp); pOut->u.i = rowid; pOut->flags = MEM_Int; } }else{ assert( pOp->opcode==OP_IdxRowid ); sqlite3VdbeMemSetNull(&aMem[pOp->p2]); } break; } /* Opcode: IdxGE P1 P2 P3 P4 P5 ** Synopsis: key=r[P3@P4] ** |
︙ | ︙ | |||
79327 79328 79329 79330 79331 79332 79333 | int nErr; /* Number of errors reported */ char *z; /* Text of the error report */ Mem *pnErr; /* Register keeping track of errors remaining */ assert( p->bIsReader ); nRoot = pOp->p2; assert( nRoot>0 ); | | | 79598 79599 79600 79601 79602 79603 79604 79605 79606 79607 79608 79609 79610 79611 79612 | int nErr; /* Number of errors reported */ char *z; /* Text of the error report */ Mem *pnErr; /* Register keeping track of errors remaining */ assert( p->bIsReader ); nRoot = pOp->p2; assert( nRoot>0 ); aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(nRoot+1) ); if( aRoot==0 ) goto no_mem; assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); pnErr = &aMem[pOp->p3]; assert( (pnErr->flags & MEM_Int)!=0 ); assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); pIn1 = &aMem[pOp->p1]; for(j=0; j<nRoot; j++){ |
︙ | ︙ | |||
79709 79710 79711 79712 79713 79714 79715 | if( pIn1->u.i>0 ){ pIn1->u.i -= pOp->p3; goto jump_to_p2; } break; } | | | | > > > | > > > | > > > > > | < | | > > | < | 79980 79981 79982 79983 79984 79985 79986 79987 79988 79989 79990 79991 79992 79993 79994 79995 79996 79997 79998 79999 80000 80001 80002 80003 80004 80005 80006 80007 80008 80009 80010 80011 80012 80013 80014 80015 80016 80017 80018 | if( pIn1->u.i>0 ){ pIn1->u.i -= pOp->p3; goto jump_to_p2; } break; } /* Opcode: OffsetLimit P1 P2 P3 * * ** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) ** ** This opcode performs a commonly used computation associated with ** LIMIT and OFFSET process. r[P1] holds the limit counter. r[P3] ** holds the offset counter. The opcode computes the combined value ** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2] ** value computed is the total number of rows that will need to be ** visited in order to complete the query. ** ** If r[P3] is zero or negative, that means there is no OFFSET ** and r[P2] is set to be the value of the LIMIT, r[P1]. ** ** if r[P1] is zero or negative, that means there is no LIMIT ** and r[P2] is set to -1. ** ** Otherwise, r[P2] is set to the sum of r[P1] and r[P3]. */ case OP_OffsetLimit: { /* in1, out2, in3 */ pIn1 = &aMem[pOp->p1]; pIn3 = &aMem[pOp->p3]; pOut = out2Prerelease(p, pOp); assert( pIn1->flags & MEM_Int ); assert( pIn3->flags & MEM_Int ); pOut->u.i = pIn1->u.i<=0 ? -1 : pIn1->u.i+(pIn3->u.i>0?pIn3->u.i:0); break; } /* Opcode: IfNotZero P1 P2 P3 * * ** Synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2 ** ** Register P1 must contain an integer. If the content of register P1 is |
︙ | ︙ | |||
79813 79814 79815 79816 79817 79818 79819 | sqlite3_context *pCtx; assert( pOp->p4type==P4_FUNCDEF ); n = pOp->p5; assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); | | | 80095 80096 80097 80098 80099 80100 80101 80102 80103 80104 80105 80106 80107 80108 80109 | sqlite3_context *pCtx; assert( pOp->p4type==P4_FUNCDEF ); n = pOp->p5; assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); if( pCtx==0 ) goto no_mem; pCtx->pMem = 0; pCtx->pFunc = pOp->p4.pFunc; pCtx->iOp = (int)(pOp - aOp); pCtx->pVdbe = p; pCtx->argc = n; pOp->p4type = P4_FUNCCTX; |
︙ | ︙ | |||
80680 80681 80682 80683 80684 80685 80686 | vdbe_error_halt: assert( rc ); p->rc = rc; testcase( sqlite3GlobalConfig.xLog!=0 ); sqlite3_log(rc, "statement aborts at %d: [%s] %s", (int)(pOp - aOp), p->zSql, p->zErrMsg); sqlite3VdbeHalt(p); | | > > > | | | 80962 80963 80964 80965 80966 80967 80968 80969 80970 80971 80972 80973 80974 80975 80976 80977 80978 80979 80980 80981 80982 80983 80984 80985 80986 80987 80988 80989 80990 80991 80992 80993 80994 80995 80996 80997 80998 80999 81000 81001 81002 81003 81004 81005 81006 81007 81008 81009 81010 81011 81012 81013 81014 81015 81016 81017 81018 81019 81020 81021 81022 81023 81024 81025 81026 81027 | vdbe_error_halt: assert( rc ); p->rc = rc; testcase( sqlite3GlobalConfig.xLog!=0 ); sqlite3_log(rc, "statement aborts at %d: [%s] %s", (int)(pOp - aOp), p->zSql, p->zErrMsg); sqlite3VdbeHalt(p); if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); rc = SQLITE_ERROR; if( resetSchemaOnFault>0 ){ sqlite3ResetOneSchema(db, resetSchemaOnFault-1); } /* This is the only way out of this procedure. We have to ** release the mutexes on btrees that were acquired at the ** top. */ vdbe_return: db->lastRowid = lastRowid; testcase( nVmStep>0 ); p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; sqlite3VdbeLeave(p); assert( rc!=SQLITE_OK || nExtraDelete==0 || sqlite3_strlike("DELETE%",p->zSql,0)!=0 ); return rc; /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH ** is encountered. */ too_big: sqlite3VdbeError(p, "string or blob too big"); rc = SQLITE_TOOBIG; goto vdbe_error_halt; /* Jump to here if a malloc() fails. */ no_mem: sqlite3OomFault(db); sqlite3VdbeError(p, "out of memory"); rc = SQLITE_NOMEM; goto vdbe_error_halt; /* Jump to here for any other kind of fatal error. The "rc" variable ** should hold the error number. */ abort_due_to_error: assert( p->zErrMsg==0 ); if( db->mallocFailed ) rc = SQLITE_NOMEM; if( rc!=SQLITE_IOERR_NOMEM ){ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); } goto vdbe_error_halt; /* Jump to here if the sqlite3_interrupt() API sets the interrupt ** flag. */ abort_due_to_interrupt: assert( db->u1.isInterrupted ); rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_INTERRUPT; p->rc = rc; sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); goto vdbe_error_halt; } /************** End of vdbe.c ************************************************/ |
︙ | ︙ | |||
80988 80989 80990 80991 80992 80993 80994 | ** uses it to implement the blob_read(), blob_write() and ** blob_bytes() functions. ** ** The sqlite3_blob_close() function finalizes the vdbe program, ** which closes the b-tree cursor and (possibly) commits the ** transaction. */ | | < < | | | | | | | | | | 81273 81274 81275 81276 81277 81278 81279 81280 81281 81282 81283 81284 81285 81286 81287 81288 81289 81290 81291 81292 81293 81294 81295 81296 81297 | ** uses it to implement the blob_read(), blob_write() and ** blob_bytes() functions. ** ** The sqlite3_blob_close() function finalizes the vdbe program, ** which closes the b-tree cursor and (possibly) commits the ** transaction. */ static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList openBlob[] = { {OP_TableLock, 0, 0, 0}, /* 0: Acquire a read or write lock */ {OP_OpenRead, 0, 0, 0}, /* 1: Open a cursor */ {OP_Variable, 1, 1, 0}, /* 2: Move ?1 into reg[1] */ {OP_NotExists, 0, 7, 1}, /* 3: Seek the cursor */ {OP_Column, 0, 0, 1}, /* 4 */ {OP_ResultRow, 1, 0, 0}, /* 5 */ {OP_Goto, 0, 2, 0}, /* 6 */ {OP_Close, 0, 0, 0}, /* 7 */ {OP_Halt, 0, 0, 0}, /* 8 */ }; Vdbe *v = (Vdbe *)pBlob->pStmt; int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); VdbeOp *aOp; sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, flags, pTab->pSchema->schema_cookie, |
︙ | ︙ | |||
83042 83043 83044 83045 83046 83047 83048 83049 83050 83051 83052 83053 83054 83055 | } if( pSorter->list.aMemory ){ int nMin = pSorter->iMemory + nReq; if( nMin>pSorter->nMemory ){ u8 *aNew; int nNew = pSorter->nMemory * 2; while( nNew < nMin ) nNew = nNew*2; if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize; if( nNew < nMin ) nNew = nMin; aNew = sqlite3Realloc(pSorter->list.aMemory, nNew); if( !aNew ) return SQLITE_NOMEM; | > | < < > | > | 83325 83326 83327 83328 83329 83330 83331 83332 83333 83334 83335 83336 83337 83338 83339 83340 83341 83342 83343 83344 83345 83346 83347 83348 83349 83350 83351 83352 83353 83354 83355 83356 | } if( pSorter->list.aMemory ){ int nMin = pSorter->iMemory + nReq; if( nMin>pSorter->nMemory ){ u8 *aNew; int iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory; int nNew = pSorter->nMemory * 2; while( nNew < nMin ) nNew = nNew*2; if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize; if( nNew < nMin ) nNew = nMin; aNew = sqlite3Realloc(pSorter->list.aMemory, nNew); if( !aNew ) return SQLITE_NOMEM; pSorter->list.pList = (SorterRecord*)&aNew[iListOff]; pSorter->list.aMemory = aNew; pSorter->nMemory = nNew; } pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory]; pSorter->iMemory += ROUND8(nReq); if( pSorter->list.pList ){ pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory); } }else{ pNew = (SorterRecord *)sqlite3Malloc(nReq); if( pNew==0 ){ return SQLITE_NOMEM; } pNew->u.pNext = pSorter->list.pList; } |
︙ | ︙ | |||
86228 86229 86230 86231 86232 86233 86234 | } } return pExpr; } SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){ Token s; assert( zC!=0 ); | < | | 86512 86513 86514 86515 86516 86517 86518 86519 86520 86521 86522 86523 86524 86525 86526 | } } return pExpr; } SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){ Token s; assert( zC!=0 ); sqlite3TokenInit(&s, (char*)zC); return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); } /* ** Skip over any TK_COLLATE operators and any unlikely() ** or likelihood() function at the root of an expression. */ |
︙ | ︙ | |||
86597 86598 86599 86600 86601 86602 86603 86604 86605 86606 86607 86608 86609 86610 | const Token *pToken, /* Token argument. Might be NULL */ int dequote /* True to dequote */ ){ Expr *pNew; int nExtra = 0; int iValue = 0; if( pToken ){ if( op!=TK_INTEGER || pToken->z==0 || sqlite3GetInt32(pToken->z, &iValue)==0 ){ nExtra = pToken->n+1; assert( iValue>=0 ); } } | > | | 86880 86881 86882 86883 86884 86885 86886 86887 86888 86889 86890 86891 86892 86893 86894 86895 86896 86897 86898 86899 86900 86901 86902 | const Token *pToken, /* Token argument. Might be NULL */ int dequote /* True to dequote */ ){ Expr *pNew; int nExtra = 0; int iValue = 0; assert( db!=0 ); if( pToken ){ if( op!=TK_INTEGER || pToken->z==0 || sqlite3GetInt32(pToken->z, &iValue)==0 ){ nExtra = pToken->n+1; assert( iValue>=0 ); } } pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra); if( pNew ){ memset(pNew, 0, sizeof(Expr)); pNew->op = (u8)op; pNew->iAgg = -1; if( pToken ){ if( nExtra==0 ){ pNew->flags |= EP_IntValue; |
︙ | ︙ | |||
86843 86844 86845 86846 86847 86848 86849 | } if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar); } if( x>0 ){ if( x>pParse->nzVar ){ char **a; a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); | | > > > | 87127 87128 87129 87130 87131 87132 87133 87134 87135 87136 87137 87138 87139 87140 87141 87142 87143 87144 | } if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar); } if( x>0 ){ if( x>pParse->nzVar ){ char **a; a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); if( a==0 ){ assert( db->mallocFailed ); /* Error reported through mallocFailed */ return; } pParse->azVar = a; memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); pParse->nzVar = x; } if( z[0]!='?' || pParse->azVar[x-1]==0 ){ sqlite3DbFree(db, pParse->azVar[x-1]); pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); |
︙ | ︙ | |||
86998 86999 87000 87001 87002 87003 87004 87005 87006 87007 87008 87009 87010 87011 87012 87013 87014 87015 87016 | ** (if applicable), and the copies of the p->pLeft and p->pRight expressions, ** if any. Before returning, *pzBuffer is set to the first byte past the ** portion of the buffer copied into by this function. */ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ Expr *pNew = 0; /* Value to return */ assert( flags==0 || flags==EXPRDUP_REDUCE ); if( p ){ const int isReduced = (flags&EXPRDUP_REDUCE); u8 *zAlloc; u32 staticFlag = 0; assert( pzBuffer==0 || isReduced ); /* Figure out where to write the new Expr structure. */ if( pzBuffer ){ zAlloc = *pzBuffer; staticFlag = EP_Static; }else{ | > | | 87285 87286 87287 87288 87289 87290 87291 87292 87293 87294 87295 87296 87297 87298 87299 87300 87301 87302 87303 87304 87305 87306 87307 87308 87309 87310 87311 87312 | ** (if applicable), and the copies of the p->pLeft and p->pRight expressions, ** if any. Before returning, *pzBuffer is set to the first byte past the ** portion of the buffer copied into by this function. */ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ Expr *pNew = 0; /* Value to return */ assert( flags==0 || flags==EXPRDUP_REDUCE ); assert( db!=0 ); if( p ){ const int isReduced = (flags&EXPRDUP_REDUCE); u8 *zAlloc; u32 staticFlag = 0; assert( pzBuffer==0 || isReduced ); /* Figure out where to write the new Expr structure. */ if( pzBuffer ){ zAlloc = *pzBuffer; staticFlag = EP_Static; }else{ zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, flags)); } pNew = (Expr *)zAlloc; if( pNew ){ /* Set nNewSize to the size allocated for the structure pointed to ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed |
︙ | ︙ | |||
87133 87134 87135 87136 87137 87138 87139 87140 | assert( flags==0 || flags==EXPRDUP_REDUCE ); return exprDup(db, p, flags, 0); } SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ ExprList *pNew; struct ExprList_item *pItem, *pOldItem; int i; if( p==0 ) return 0; | > | | | 87421 87422 87423 87424 87425 87426 87427 87428 87429 87430 87431 87432 87433 87434 87435 87436 87437 87438 87439 87440 87441 | assert( flags==0 || flags==EXPRDUP_REDUCE ); return exprDup(db, p, flags, 0); } SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ ExprList *pNew; struct ExprList_item *pItem, *pOldItem; int i; assert( db!=0 ); if( p==0 ) return 0; pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->nExpr = i = p->nExpr; if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; i<p->nExpr; i+=i){} pNew->a = pItem = sqlite3DbMallocRawNN(db, i*sizeof(p->a[0]) ); if( pItem==0 ){ sqlite3DbFree(db, pNew); return 0; } pOldItem = p->a; for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){ Expr *pOldExpr = pOldItem->pExpr; |
︙ | ︙ | |||
87169 87170 87171 87172 87173 87174 87175 87176 87177 | */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ || !defined(SQLITE_OMIT_SUBQUERY) SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ SrcList *pNew; int i; int nByte; if( p==0 ) return 0; nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); | > | | 87458 87459 87460 87461 87462 87463 87464 87465 87466 87467 87468 87469 87470 87471 87472 87473 87474 87475 | */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ || !defined(SQLITE_OMIT_SUBQUERY) SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ SrcList *pNew; int i; int nByte; assert( db!=0 ); if( p==0 ) return 0; nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); pNew = sqlite3DbMallocRawNN(db, nByte ); if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; i<p->nSrc; i++){ struct SrcList_item *pNewItem = &pNew->a[i]; struct SrcList_item *pOldItem = &p->a[i]; Table *pTab; pNewItem->pSchema = pOldItem->pSchema; |
︙ | ︙ | |||
87208 87209 87210 87211 87212 87213 87214 87215 | pNewItem->colUsed = pOldItem->colUsed; } return pNew; } SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ IdList *pNew; int i; if( p==0 ) return 0; | > | | > | | 87498 87499 87500 87501 87502 87503 87504 87505 87506 87507 87508 87509 87510 87511 87512 87513 87514 87515 87516 87517 87518 87519 87520 87521 87522 87523 87524 87525 87526 87527 87528 87529 87530 87531 87532 87533 87534 87535 87536 87537 | pNewItem->colUsed = pOldItem->colUsed; } return pNew; } SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ IdList *pNew; int i; assert( db!=0 ); if( p==0 ) return 0; pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->nId = p->nId; pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) ); if( pNew->a==0 ){ sqlite3DbFree(db, pNew); return 0; } /* Note that because the size of the allocation for p->a[] is not ** necessarily a power of two, sqlite3IdListAppend() may not be called ** on the duplicate created by this function. */ for(i=0; i<p->nId; i++){ struct IdList_item *pNewItem = &pNew->a[i]; struct IdList_item *pOldItem = &p->a[i]; pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->idx = pOldItem->idx; } return pNew; } SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ Select *pNew, *pPrior; assert( db!=0 ); if( p==0 ) return 0; pNew = sqlite3DbMallocRawNN(db, sizeof(*p) ); if( pNew==0 ) return 0; pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags); pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags); pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags); pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags); pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); |
︙ | ︙ | |||
87277 87278 87279 87280 87281 87282 87283 87284 | */ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend( Parse *pParse, /* Parsing context */ ExprList *pList, /* List to which to append. Might be NULL */ Expr *pExpr /* Expression to be appended. Might be NULL */ ){ sqlite3 *db = pParse->db; if( pList==0 ){ | > | | | 87569 87570 87571 87572 87573 87574 87575 87576 87577 87578 87579 87580 87581 87582 87583 87584 87585 87586 87587 87588 87589 87590 | */ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend( Parse *pParse, /* Parsing context */ ExprList *pList, /* List to which to append. Might be NULL */ Expr *pExpr /* Expression to be appended. Might be NULL */ ){ sqlite3 *db = pParse->db; assert( db!=0 ); if( pList==0 ){ pList = sqlite3DbMallocRawNN(db, sizeof(ExprList) ); if( pList==0 ){ goto no_mem; } pList->nExpr = 0; pList->a = sqlite3DbMallocRawNN(db, sizeof(pList->a[0])); if( pList->a==0 ) goto no_mem; }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ struct ExprList_item *a; assert( pList->nExpr>0 ); a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0])); if( a==0 ){ goto no_mem; |
︙ | ︙ | |||
91007 91008 91009 91010 91011 91012 91013 | int r2 = sqlite3GetTempReg(pParse); int addr1; sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2); addr1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v); | | | 91300 91301 91302 91303 91304 91305 91306 91307 91308 91309 91310 91311 91312 91313 91314 | int r2 = sqlite3GetTempReg(pParse); int addr1; sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2); addr1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, minFormat); sqlite3VdbeJumpHere(v, addr1); sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempReg(pParse, r2); } } /* |
︙ | ︙ | |||
91094 91095 91096 91097 91098 91099 91100 | */ if( pDflt ){ sqlite3_value *pVal = 0; int rc; rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); if( rc!=SQLITE_OK ){ | | | 91387 91388 91389 91390 91391 91392 91393 91394 91395 91396 91397 91398 91399 91400 91401 | */ if( pDflt ){ sqlite3_value *pVal = 0; int rc; rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); if( rc!=SQLITE_OK ){ assert( db->mallocFailed == 1 ); return; } if( !pVal ){ sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default"); return; } sqlite3ValueFree(pVal); |
︙ | ︙ | |||
91202 91203 91204 91205 91206 91207 91208 | pNew->nCol = pTab->nCol; assert( pNew->nCol>0 ); nAlloc = (((pNew->nCol-1)/8)*8)+8; assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); if( !pNew->aCol || !pNew->zName ){ | | | 91495 91496 91497 91498 91499 91500 91501 91502 91503 91504 91505 91506 91507 91508 91509 | pNew->nCol = pTab->nCol; assert( pNew->nCol>0 ); nAlloc = (((pNew->nCol-1)/8)*8)+8; assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); if( !pNew->aCol || !pNew->zName ){ assert( db->mallocFailed ); goto exit_begin_add_column; } memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); for(i=0; i<pNew->nCol; i++){ Column *pCol = &pNew->aCol[i]; pCol->zName = sqlite3DbStrDup(db, pCol->zName); pCol->zColl = 0; |
︙ | ︙ | |||
91547 91548 91549 91550 91551 91552 91553 | /* Initialize the BLOB value of a ROWID */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){ assert( db!=0 ); if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); | | | 91840 91841 91842 91843 91844 91845 91846 91847 91848 91849 91850 91851 91852 91853 91854 | /* Initialize the BLOB value of a ROWID */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){ assert( db!=0 ); if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); p->u.aRowid = sqlite3DbMallocRawNN(db, n); if( p->u.aRowid ){ p->nRowid = n; memcpy(p->u.aRowid, pData, n); }else{ p->nRowid = 0; } } |
︙ | ︙ | |||
92349 92350 92351 92352 92353 92354 92355 | VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); addrNextRow = sqlite3VdbeCurrentAddr(v); if( nColTest>0 ){ int endDistinctTest = sqlite3VdbeMakeLabel(v); int *aGotoChng; /* Array of jump instruction addresses */ | | | 92642 92643 92644 92645 92646 92647 92648 92649 92650 92651 92652 92653 92654 92655 92656 | VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); addrNextRow = sqlite3VdbeCurrentAddr(v); if( nColTest>0 ){ int endDistinctTest = sqlite3VdbeMakeLabel(v); int *aGotoChng; /* Array of jump instruction addresses */ aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest); if( aGotoChng==0 ) continue; /* ** next_row: ** regChng = 0 ** if( idx(0) != regPrev(0) ) goto chng_addr_0 ** regChng = 1 |
︙ | ︙ | |||
92757 92758 92759 92760 92761 92762 92763 | int nCol = pIndex->nKeyCol+1; #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 /* Index.aiRowEst may already be set here if there are duplicate ** sqlite_stat1 entries for this index. In that case just clobber ** the old data with the new instead of allocating a new array. */ if( pIndex->aiRowEst==0 ){ pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); | | | 93050 93051 93052 93053 93054 93055 93056 93057 93058 93059 93060 93061 93062 93063 93064 | int nCol = pIndex->nKeyCol+1; #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 /* Index.aiRowEst may already be set here if there are duplicate ** sqlite_stat1 entries for this index. In that case just clobber ** the old data with the new instead of allocating a new array. */ if( pIndex->aiRowEst==0 ){ pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db); } aiRowEst = pIndex->aiRowEst; #endif pIndex->bUnordered = 0; decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; }else{ |
︙ | ︙ | |||
92904 92905 92906 92907 92908 92909 92910 | ){ int rc; /* Result codes from subroutines */ sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ char *zSql; /* Text of the SQL statement */ Index *pPrevIdx = 0; /* Previous index in the loop */ IndexSample *pSample; /* A slot in pIdx->aSample[] */ | | | 93197 93198 93199 93200 93201 93202 93203 93204 93205 93206 93207 93208 93209 93210 93211 | ){ int rc; /* Result codes from subroutines */ sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ char *zSql; /* Text of the SQL statement */ Index *pPrevIdx = 0; /* Previous index in the loop */ IndexSample *pSample; /* A slot in pIdx->aSample[] */ assert( db->lookaside.bDisable ); zSql = sqlite3MPrintf(db, zSql1, zDb); if( !zSql ){ return SQLITE_NOMEM; } rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); sqlite3DbFree(db, zSql); if( rc ) return rc; |
︙ | ︙ | |||
93018 93019 93020 93021 93022 93023 93024 | /* ** Load content from the sqlite_stat4 and sqlite_stat3 tables into ** the Index.aSample[] arrays of all indices. */ static int loadStat4(sqlite3 *db, const char *zDb){ int rc = SQLITE_OK; /* Result codes from subroutines */ | | | 93311 93312 93313 93314 93315 93316 93317 93318 93319 93320 93321 93322 93323 93324 93325 | /* ** Load content from the sqlite_stat4 and sqlite_stat3 tables into ** the Index.aSample[] arrays of all indices. */ static int loadStat4(sqlite3 *db, const char *zDb){ int rc = SQLITE_OK; /* Result codes from subroutines */ assert( db->lookaside.bDisable ); if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ rc = loadStatTbl(db, 0, "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", zDb ); } |
︙ | ︙ | |||
93100 93101 93102 93103 93104 93105 93106 | sqlite3DbFree(db, zSql); } /* Load the statistics from the sqlite_stat4 table. */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ | < | | | | 93393 93394 93395 93396 93397 93398 93399 93400 93401 93402 93403 93404 93405 93406 93407 93408 93409 93410 93411 93412 93413 93414 93415 93416 93417 93418 93419 | sqlite3DbFree(db, zSql); } /* Load the statistics from the sqlite_stat4 table. */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ db->lookaside.bDisable++; rc = loadStat4(db, sInfo.zDatabase); db->lookaside.bDisable--; } for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); sqlite3_free(pIdx->aiRowEst); pIdx->aiRowEst = 0; } #endif if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); } return rc; } #endif /* SQLITE_OMIT_ANALYZE */ |
︙ | ︙ | |||
93234 93235 93236 93237 93238 93239 93240 | } } /* Allocate the new entry in the db->aDb[] array and initialize the schema ** hash tables. */ if( db->aDb==db->aDbStatic ){ | | | | 93526 93527 93528 93529 93530 93531 93532 93533 93534 93535 93536 93537 93538 93539 93540 93541 93542 93543 93544 93545 93546 93547 93548 93549 93550 93551 93552 93553 93554 93555 93556 93557 93558 | } } /* Allocate the new entry in the db->aDb[] array and initialize the schema ** hash tables. */ if( db->aDb==db->aDbStatic ){ aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 ); if( aNew==0 ) return; memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); }else{ aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); if( aNew==0 ) return; } db->aDb = aNew; aNew = &db->aDb[db->nDb]; memset(aNew, 0, sizeof(*aNew)); /* Open the database file. If the btree is successfully opened, use ** it to obtain the database schema. At this point the schema may ** or may not be initialized. */ flags = db->openFlags; rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); sqlite3_result_error(context, zErr, -1); sqlite3_free(zErr); return; } assert( pVfs ); flags |= SQLITE_OPEN_MAIN_DB; rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags); |
︙ | ︙ | |||
93281 93282 93283 93284 93285 93286 93287 | } sqlite3BtreeEnter(aNew->pBt); pPager = sqlite3BtreePager(aNew->pBt); sqlite3PagerLockingMode(pPager, db->dfltLockMode); sqlite3BtreeSecureDelete(aNew->pBt, sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); #ifndef SQLITE_OMIT_PAGER_PRAGMAS | | > | 93573 93574 93575 93576 93577 93578 93579 93580 93581 93582 93583 93584 93585 93586 93587 93588 | } sqlite3BtreeEnter(aNew->pBt); pPager = sqlite3BtreePager(aNew->pBt); sqlite3PagerLockingMode(pPager, db->dfltLockMode); sqlite3BtreeSecureDelete(aNew->pBt, sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); #ifndef SQLITE_OMIT_PAGER_PRAGMAS sqlite3BtreeSetPagerFlags(aNew->pBt, PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK)); #endif sqlite3BtreeLeave(aNew->pBt); } aNew->safety_level = 3; aNew->zName = sqlite3DbStrDup(db, zName); if( rc==SQLITE_OK && aNew->zName==0 ){ rc = SQLITE_NOMEM; |
︙ | ︙ | |||
93354 93355 93356 93357 93358 93359 93360 | sqlite3BtreeClose(db->aDb[iDb].pBt); db->aDb[iDb].pBt = 0; db->aDb[iDb].pSchema = 0; } sqlite3ResetAllSchemasOfConnection(db); db->nDb = iDb; if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ | | | 93647 93648 93649 93650 93651 93652 93653 93654 93655 93656 93657 93658 93659 93660 93661 | sqlite3BtreeClose(db->aDb[iDb].pBt); db->aDb[iDb].pBt = 0; db->aDb[iDb].pSchema = 0; } sqlite3ResetAllSchemasOfConnection(db); db->nDb = iDb; if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ sqlite3OomFault(db); sqlite3DbFree(db, zErrDyn); zErrDyn = sqlite3MPrintf(db, "out of memory"); }else if( zErrDyn==0 ){ zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); } goto attach_error; } |
︙ | ︙ | |||
94051 94052 94053 94054 94055 94056 94057 | p = &pToplevel->aTableLock[pToplevel->nTableLock++]; p->iDb = iDb; p->iTab = iTab; p->isWriteLock = isWriteLock; p->zName = zName; }else{ pToplevel->nTableLock = 0; | | | 94344 94345 94346 94347 94348 94349 94350 94351 94352 94353 94354 94355 94356 94357 94358 | p = &pToplevel->aTableLock[pToplevel->nTableLock++]; p->iDb = iDb; p->iTab = iTab; p->isWriteLock = isWriteLock; p->zName = zName; }else{ pToplevel->nTableLock = 0; sqlite3OomFault(pToplevel->db); } } /* ** Code an OP_TableLock instruction for each table locked by the ** statement (configured by calls to sqlite3TableLock()). */ |
︙ | ︙ | |||
94899 94900 94901 94902 94903 94904 94905 | sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); goto begin_table_error; } } pTable = sqlite3DbMallocZero(db, sizeof(Table)); if( pTable==0 ){ | | | 95192 95193 95194 95195 95196 95197 95198 95199 95200 95201 95202 95203 95204 95205 95206 | sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); goto begin_table_error; } } pTable = sqlite3DbMallocZero(db, sizeof(Table)); if( pTable==0 ){ assert( db->mallocFailed ); pParse->rc = SQLITE_NOMEM; pParse->nErr++; goto begin_table_error; } pTable->zName = zName; pTable->iPKey = -1; pTable->pSchema = db->aDb[iDb].pSchema; |
︙ | ︙ | |||
94956 94957 94958 94959 94960 94961 94962 | reg2 = pParse->regRoot = ++pParse->nMem; reg3 = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT); sqlite3VdbeUsesBtree(v, iDb); addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v); fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? 1 : SQLITE_MAX_FILE_FORMAT; | < | < | | 95249 95250 95251 95252 95253 95254 95255 95256 95257 95258 95259 95260 95261 95262 95263 95264 | reg2 = pParse->regRoot = ++pParse->nMem; reg3 = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT); sqlite3VdbeUsesBtree(v, iDb); addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v); fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? 1 : SQLITE_MAX_FILE_FORMAT; sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db)); sqlite3VdbeJumpHere(v, addr1); /* This just creates a place-holder record in the sqlite_master table. ** The record created does not contain anything yet. It will be replaced ** by the real entry in code generated at sqlite3EndTable(). ** ** The rowid for the new entry is left in register pParse->regRowid. |
︙ | ︙ | |||
95444 95445 95446 95447 95448 95449 95450 | ** This plan is not completely bullet-proof. It is possible for ** the schema to change multiple times and for the cookie to be ** set back to prior value. But schema changes are infrequent ** and the probability of hitting the same cookie value is only ** 1 chance in 2^32. So we're safe enough. */ SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){ | < < | < > | 95735 95736 95737 95738 95739 95740 95741 95742 95743 95744 95745 95746 95747 95748 95749 95750 95751 95752 95753 | ** This plan is not completely bullet-proof. It is possible for ** the schema to change multiple times and for the cookie to be ** set back to prior value. But schema changes are infrequent ** and the probability of hitting the same cookie value is only ** 1 chance in 2^32. So we're safe enough. */ SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){ sqlite3 *db = pParse->db; Vdbe *v = pParse->pVdbe; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, db->aDb[iDb].pSchema->schema_cookie+1); } /* ** Measure the number of characters needed to output the given ** identifier. The number returned includes any quotes used ** but does not include the null terminator. ** |
︙ | ︙ | |||
95532 95533 95534 95535 95536 95537 95538 | zSep = "\n "; zSep2 = ",\n "; zEnd = "\n)"; } n += 35 + 6*p->nCol; zStmt = sqlite3DbMallocRaw(0, n); if( zStmt==0 ){ | | | 95821 95822 95823 95824 95825 95826 95827 95828 95829 95830 95831 95832 95833 95834 95835 | zSep = "\n "; zSep2 = ",\n "; zEnd = "\n)"; } n += 35 + 6*p->nCol; zStmt = sqlite3DbMallocRaw(0, n); if( zStmt==0 ){ sqlite3OomFault(db); return 0; } sqlite3_snprintf(n, zStmt, "CREATE TABLE "); k = sqlite3Strlen30(zStmt); identPut(zStmt, &k, p->zName); zStmt[k++] = '('; for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){ |
︙ | ︙ | |||
95681 95682 95683 95684 95685 95686 95687 | /* Locate the PRIMARY KEY index. Or, if this table was originally ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index. */ if( pTab->iPKey>=0 ){ ExprList *pList; Token ipkToken; | | < | 95970 95971 95972 95973 95974 95975 95976 95977 95978 95979 95980 95981 95982 95983 95984 | /* Locate the PRIMARY KEY index. Or, if this table was originally ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index. */ if( pTab->iPKey>=0 ){ ExprList *pList; Token ipkToken; sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); if( pList==0 ) return; pList->a[0].sortOrder = pParse->iPkSortOrder; assert( pParse->pNewTable==pTab ); pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0); if( pPk==0 ) return; |
︙ | ︙ | |||
95932 95933 95934 95935 95936 95937 95938 | sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); pParse->nTab = 2; addrTop = sqlite3VdbeCurrentAddr(v) + 1; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); sqlite3Select(pParse, pSelect, &dest); | | | 96220 96221 96222 96223 96224 96225 96226 96227 96228 96229 96230 96231 96232 96233 96234 | sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); pParse->nTab = 2; addrTop = sqlite3VdbeCurrentAddr(v) + 1; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); sqlite3Select(pParse, pSelect, &dest); sqlite3VdbeEndCoroutine(v, regYield); sqlite3VdbeJumpHere(v, addrTop - 1); if( pParse->nErr ) return; pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect); if( pSelTab==0 ) return; assert( p->aCol==0 ); p->nCol = pSelTab->nCol; p->aCol = pSelTab->aCol; |
︙ | ︙ | |||
96016 96017 96018 96019 96020 96021 96022 | if( db->init.busy ){ Table *pOld; Schema *pSchema = p->pSchema; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p); if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ | | | 96304 96305 96306 96307 96308 96309 96310 96311 96312 96313 96314 96315 96316 96317 96318 | if( db->init.busy ){ Table *pOld; Schema *pSchema = p->pSchema; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p); if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ sqlite3OomFault(db); return; } pParse->pNewTable = 0; db->flags |= SQLITE_InternChanges; #ifndef SQLITE_OMIT_ALTERTABLE if( !p->pSelect ){ |
︙ | ︙ | |||
96120 96121 96122 96123 96124 96125 96126 | SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ Table *pSelTab; /* A fake table from which we get the result set */ Select *pSel; /* Copy of the SELECT that implements the view */ int nErr = 0; /* Number of errors encountered */ int n; /* Temporarily holds the number of cursors assigned */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ sqlite3_xauth xAuth; /* Saved xAuth pointer */ | < | 96408 96409 96410 96411 96412 96413 96414 96415 96416 96417 96418 96419 96420 96421 | SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ Table *pSelTab; /* A fake table from which we get the result set */ Select *pSel; /* Copy of the SELECT that implements the view */ int nErr = 0; /* Number of errors encountered */ int n; /* Temporarily holds the number of cursors assigned */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ sqlite3_xauth xAuth; /* Saved xAuth pointer */ assert( pTable ); #ifndef SQLITE_OMIT_VIRTUALTABLE if( sqlite3VtabCallConnect(pParse, pTable) ){ return SQLITE_ERROR; } |
︙ | ︙ | |||
96166 96167 96168 96169 96170 96171 96172 | ** Note that the call to sqlite3ResultSetOfSelect() will expand any ** "*" elements in the results set of the view and will assign cursors ** to the elements of the FROM clause. But we do not want these changes ** to be permanent. So the computation is done on a copy of the SELECT ** statement that defines the view. */ assert( pTable->pSelect ); | < | > | > < | 96453 96454 96455 96456 96457 96458 96459 96460 96461 96462 96463 96464 96465 96466 96467 96468 96469 96470 96471 96472 96473 96474 96475 96476 96477 96478 96479 96480 96481 96482 96483 96484 96485 96486 96487 96488 96489 96490 96491 96492 96493 96494 96495 96496 96497 96498 96499 96500 96501 96502 96503 96504 96505 | ** Note that the call to sqlite3ResultSetOfSelect() will expand any ** "*" elements in the results set of the view and will assign cursors ** to the elements of the FROM clause. But we do not want these changes ** to be permanent. So the computation is done on a copy of the SELECT ** statement that defines the view. */ assert( pTable->pSelect ); if( pTable->pCheck ){ db->lookaside.bDisable++; sqlite3ColumnsFromExprList(pParse, pTable->pCheck, &pTable->nCol, &pTable->aCol); db->lookaside.bDisable--; }else{ pSel = sqlite3SelectDup(db, pTable->pSelect, 0); if( pSel ){ n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; db->lookaside.bDisable++; #ifndef SQLITE_OMIT_AUTHORIZATION xAuth = db->xAuth; db->xAuth = 0; pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); db->xAuth = xAuth; #else pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); #endif db->lookaside.bDisable--; pParse->nTab = n; if( pSelTab ){ assert( pTable->aCol==0 ); pTable->nCol = pSelTab->nCol; pTable->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; sqlite3DeleteTable(db, pSelTab); assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); }else{ pTable->nCol = 0; nErr++; } sqlite3SelectDelete(db, pSel); } else { nErr++; } } pTable->pSchema->schemaFlags |= DB_UnresetViews; #endif /* SQLITE_OMIT_VIEW */ return nErr; } #endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ #ifndef SQLITE_OMIT_VIEW |
︙ | ︙ | |||
96670 96671 96672 96673 96674 96675 96676 | pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */ assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, pFKey->zTo, (void *)pFKey ); if( pNextTo==pFKey ){ | | | 96957 96958 96959 96960 96961 96962 96963 96964 96965 96966 96967 96968 96969 96970 96971 | pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */ assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, pFKey->zTo, (void *)pFKey ); if( pNextTo==pFKey ){ sqlite3OomFault(db); goto fk_end; } if( pNextTo ){ assert( pNextTo->pPrevTo==0 ); pFKey->pNextTo = pNextTo; pNextTo->pPrevTo = pFKey; } |
︙ | ︙ | |||
97030 97031 97032 97033 97034 97035 97036 | /* If pList==0, it means this routine was called to make a primary ** key out of the last column added to the table under construction. ** So create a fake list to simulate this. */ if( pList==0 ){ Token prevCol; | | < | 97317 97318 97319 97320 97321 97322 97323 97324 97325 97326 97327 97328 97329 97330 97331 | /* If pList==0, it means this routine was called to make a primary ** key out of the last column added to the table under construction. ** So create a fake list to simulate this. */ if( pList==0 ){ Token prevCol; sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); if( pList==0 ) goto exit_create_index; assert( pList->nExpr==1 ); sqlite3ExprListSetSortOrder(pList, sortOrder); }else{ sqlite3ExprListCheckLength(pParse, pList, "index"); |
︙ | ︙ | |||
97253 97254 97255 97256 97257 97258 97259 | if( db->init.busy ){ Index *p; assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); p = sqlite3HashInsert(&pIndex->pSchema->idxHash, pIndex->zName, pIndex); if( p ){ assert( p==pIndex ); /* Malloc must have failed */ | | | 97539 97540 97541 97542 97543 97544 97545 97546 97547 97548 97549 97550 97551 97552 97553 | if( db->init.busy ){ Index *p; assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); p = sqlite3HashInsert(&pIndex->pSchema->idxHash, pIndex->zName, pIndex); if( p ){ assert( p==pIndex ); /* Malloc must have failed */ sqlite3OomFault(db); goto exit_create_index; } db->flags |= SQLITE_InternChanges; if( pTblName!=0 ){ pIndex->tnum = db->init.newTnum; } } |
︙ | ︙ | |||
97682 97683 97684 97685 97686 97687 97688 97689 | sqlite3 *db, /* Connection to notify of malloc failures */ SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */ Token *pTable, /* Table to append */ Token *pDatabase /* Database of the table */ ){ struct SrcList_item *pItem; assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ if( pList==0 ){ | > | | 97968 97969 97970 97971 97972 97973 97974 97975 97976 97977 97978 97979 97980 97981 97982 97983 97984 | sqlite3 *db, /* Connection to notify of malloc failures */ SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */ Token *pTable, /* Table to append */ Token *pDatabase /* Database of the table */ ){ struct SrcList_item *pItem; assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ assert( db!=0 ); if( pList==0 ){ pList = sqlite3DbMallocRawNN(db, sizeof(SrcList) ); if( pList==0 ) return 0; pList->nAlloc = 1; pList->nSrc = 0; } pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc); if( db->mallocFailed ){ sqlite3SrcListDelete(db, pList); |
︙ | ︙ | |||
97867 97868 97869 97870 97871 97872 97873 | p->a[i].fg.jointype = p->a[i-1].fg.jointype; } p->a[0].fg.jointype = 0; } } /* | | < | | | | | 98154 98155 98156 98157 98158 98159 98160 98161 98162 98163 98164 98165 98166 98167 98168 98169 98170 98171 98172 98173 98174 98175 98176 98177 98178 98179 98180 98181 98182 98183 98184 98185 98186 98187 98188 98189 98190 98191 98192 98193 98194 98195 98196 98197 98198 98199 98200 98201 98202 98203 98204 98205 98206 98207 98208 98209 98210 | p->a[i].fg.jointype = p->a[i-1].fg.jointype; } p->a[0].fg.jointype = 0; } } /* ** Generate VDBE code for a BEGIN statement. */ SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){ sqlite3 *db; Vdbe *v; int i; assert( pParse!=0 ); db = pParse->db; assert( db!=0 ); if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){ return; } v = sqlite3GetVdbe(pParse); if( !v ) return; if( type!=TK_DEFERRED ){ for(i=0; i<db->nDb; i++){ sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1); sqlite3VdbeUsesBtree(v, i); } } sqlite3VdbeAddOp0(v, OP_AutoCommit); } /* ** Generate VDBE code for a COMMIT statement. */ SQLITE_PRIVATE void sqlite3CommitTransaction(Parse *pParse){ Vdbe *v; assert( pParse!=0 ); assert( pParse->db!=0 ); if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){ return; } v = sqlite3GetVdbe(pParse); if( v ){ sqlite3VdbeAddOp1(v, OP_AutoCommit, 1); } } /* ** Generate VDBE code for a ROLLBACK statement. */ SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse *pParse){ Vdbe *v; assert( pParse!=0 ); assert( pParse->db!=0 ); if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){ |
︙ | ︙ | |||
97972 97973 97974 97975 97976 97977 97978 | "file for storing temporary tables"); pParse->rc = rc; return 1; } db->aDb[1].pBt = pBt; assert( db->aDb[1].pSchema ); if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ | | | 98258 98259 98260 98261 98262 98263 98264 98265 98266 98267 98268 98269 98270 98271 98272 | "file for storing temporary tables"); pParse->rc = rc; return 1; } db->aDb[1].pBt = pBt; assert( db->aDb[1].pSchema ); if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ sqlite3OomFault(db); return 1; } } return 0; } /* |
︙ | ︙ | |||
98107 98108 98109 98110 98111 98112 98113 | char *zErr; int j; StrAccum errMsg; Table *pTab = pIdx->pTable; sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200); if( pIdx->aColExpr ){ | | | | 98393 98394 98395 98396 98397 98398 98399 98400 98401 98402 98403 98404 98405 98406 98407 98408 98409 98410 98411 98412 98413 98414 | char *zErr; int j; StrAccum errMsg; Table *pTab = pIdx->pTable; sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200); if( pIdx->aColExpr ){ sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName); }else{ for(j=0; j<pIdx->nKeyCol; j++){ char *zCol; assert( pIdx->aiColumn[j]>=0 ); zCol = pTab->aCol[pIdx->aiColumn[j]].zName; if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2); sqlite3XPrintf(&errMsg, "%s.%s", pTab->zName, zCol); } } zErr = sqlite3StrAccumFinish(&errMsg); sqlite3HaltConstraint(pParse, IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY : SQLITE_CONSTRAINT_UNIQUE, onError, zErr, P4_DYNAMIC, P5_ConstraintUnique); |
︙ | ︙ | |||
98347 98348 98349 98350 98351 98352 98353 | if( pWith ){ int nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte); pNew = sqlite3DbRealloc(db, pWith, nByte); }else{ pNew = sqlite3DbMallocZero(db, sizeof(*pWith)); } | < | | | 98633 98634 98635 98636 98637 98638 98639 98640 98641 98642 98643 98644 98645 98646 98647 98648 98649 | if( pWith ){ int nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte); pNew = sqlite3DbRealloc(db, pWith, nByte); }else{ pNew = sqlite3DbMallocZero(db, sizeof(*pWith)); } assert( (pNew!=0 && zName!=0) || db->mallocFailed ); if( db->mallocFailed ){ sqlite3ExprListDelete(db, pArglist); sqlite3SelectDelete(db, pQuery); sqlite3DbFree(db, zName); pNew = pWith; }else{ pNew->a[pNew->nCte].pSelect = pQuery; pNew->a[pNew->nCte].pCols = pArglist; |
︙ | ︙ | |||
98564 98565 98566 98567 98568 98569 98570 | /* If a malloc() failure occurred in sqlite3HashInsert(), it will ** return the pColl pointer to be deleted (because it wasn't added ** to the hash table). */ assert( pDel==0 || pDel==pColl ); if( pDel!=0 ){ | | | 98849 98850 98851 98852 98853 98854 98855 98856 98857 98858 98859 98860 98861 98862 98863 | /* If a malloc() failure occurred in sqlite3HashInsert(), it will ** return the pColl pointer to be deleted (because it wasn't added ** to the hash table). */ assert( pDel==0 || pDel==pColl ); if( pDel!=0 ){ sqlite3OomFault(db); sqlite3DbFree(db, pDel); pColl = 0; } } } return pColl; } |
︙ | ︙ | |||
98852 98853 98854 98855 98856 98857 98858 | Schema * p; if( pBt ){ p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); }else{ p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema)); } if( !p ){ | | | 99137 99138 99139 99140 99141 99142 99143 99144 99145 99146 99147 99148 99149 99150 99151 | Schema * p; if( pBt ){ p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); }else{ p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema)); } if( !p ){ sqlite3OomFault(db); }else if ( 0==p->file_format ){ sqlite3HashInit(&p->tblHash); sqlite3HashInit(&p->idxHash); sqlite3HashInit(&p->trigHash); sqlite3HashInit(&p->fkeyHash); p->enc = SQLITE_UTF8; } |
︙ | ︙ | |||
99306 99307 99308 99309 99310 99311 99312 | } if( eOnePass!=ONEPASS_OFF ){ /* For ONEPASS, no need to store the rowid/primary-key. There is only ** one, so just keep it in its register(s) and fall through to the ** delete code. */ nKey = nPk; /* OP_Found will use an unpacked key */ | | | 99591 99592 99593 99594 99595 99596 99597 99598 99599 99600 99601 99602 99603 99604 99605 | } if( eOnePass!=ONEPASS_OFF ){ /* For ONEPASS, no need to store the rowid/primary-key. There is only ** one, so just keep it in its register(s) and fall through to the ** delete code. */ nKey = nPk; /* OP_Found will use an unpacked key */ aToOpen = sqlite3DbMallocRawNN(db, nIdx+2); if( aToOpen==0 ){ sqlite3WhereEnd(pWInfo); goto delete_from_cleanup; } memset(aToOpen, 1, nIdx+1); aToOpen[nIdx+1] = 0; if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; |
︙ | ︙ | |||
99346 99347 99348 99349 99350 99351 99352 | /* Unless this is a view, open cursors for the table we are ** deleting from and all its indices. If this is a view, then the ** only effect this statement has is to fire the INSTEAD OF ** triggers. */ if( !isView ){ int iAddrOnce = 0; | < | | | 99631 99632 99633 99634 99635 99636 99637 99638 99639 99640 99641 99642 99643 99644 99645 99646 99647 99648 99649 99650 | /* Unless this is a view, open cursors for the table we are ** deleting from and all its indices. If this is a view, then the ** only effect this statement has is to fire the INSTEAD OF ** triggers. */ if( !isView ){ int iAddrOnce = 0; if( eOnePass==ONEPASS_MULTI ){ iAddrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v); } testcase( IsVirtual(pTab) ); sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE, iTabCur, aToOpen, &iDataCur, &iIdxCur); assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur ); assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 ); if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce); } /* Set up a loop over the rowids/primary-keys that were found in the ** where-clause loop above. |
︙ | ︙ | |||
99585 99586 99587 99588 99589 99590 99591 99592 99593 99594 99595 99596 99597 99598 99599 | sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0); } /* Delete the index and table entries. Skip this step if pTab is really ** a view (in which case the only effect of the DELETE statement is to ** fire the INSTEAD OF triggers). */ if( pTab->pSelect==0 ){ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); if( count ){ sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT); } if( iIdxNoSeek>=0 ){ sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek); } | > > > > > | | 99869 99870 99871 99872 99873 99874 99875 99876 99877 99878 99879 99880 99881 99882 99883 99884 99885 99886 99887 99888 99889 99890 99891 99892 99893 99894 99895 99896 | sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0); } /* Delete the index and table entries. Skip this step if pTab is really ** a view (in which case the only effect of the DELETE statement is to ** fire the INSTEAD OF triggers). */ if( pTab->pSelect==0 ){ u8 p5 = 0; sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); if( count ){ sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT); } if( eMode!=ONEPASS_OFF ){ sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE); } if( iIdxNoSeek>=0 ){ sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek); } if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION; sqlite3VdbeChangeP5(v, p5); } /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to ** handle rows (possibly in other tables) that refer via a foreign key ** to the row just deleted. */ sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); |
︙ | ︙ | |||
100003 100004 100005 100006 100007 100008 100009 | sqlite3 *db = sqlite3_context_db_handle(context); if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){ x.nArg = argc-1; x.nUsed = 0; x.apArg = argv+1; sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); | > | | 100292 100293 100294 100295 100296 100297 100298 100299 100300 100301 100302 100303 100304 100305 100306 100307 | sqlite3 *db = sqlite3_context_db_handle(context); if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){ x.nArg = argc-1; x.nUsed = 0; x.apArg = argv+1; sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); str.printfFlags = SQLITE_PRINTF_SQLFUNC; sqlite3XPrintf(&str, zFormat, &x); n = str.nChar; sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, SQLITE_DYNAMIC); } } /* |
︙ | ︙ | |||
101378 101379 101380 101381 101382 101383 101384 | ** of the built-in functions above are part of the global function set. ** This routine only deals with those that are not global. */ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ int rc = sqlite3_overload_function(db, "MATCH", 2); assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); if( rc==SQLITE_NOMEM ){ | | | 101668 101669 101670 101671 101672 101673 101674 101675 101676 101677 101678 101679 101680 101681 101682 | ** of the built-in functions above are part of the global function set. ** This routine only deals with those that are not global. */ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ int rc = sqlite3_overload_function(db, "MATCH", 2); assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); } } /* ** Set the LIKEOPT flag on the 2-argument function with the given name. */ static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){ |
︙ | ︙ | |||
101793 101794 101795 101796 101797 101798 101799 | */ if( pParent->iPKey>=0 ){ if( !zKey ) return 0; if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0; } }else if( paiCol ){ assert( nCol>1 ); | | | 102083 102084 102085 102086 102087 102088 102089 102090 102091 102092 102093 102094 102095 102096 102097 | */ if( pParent->iPKey>=0 ){ if( !zKey ) return 0; if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0; } }else if( paiCol ){ assert( nCol>1 ); aiCol = (int *)sqlite3DbMallocRawNN(pParse->db, nCol*sizeof(int)); if( !aiCol ) return 1; *paiCol = aiCol; } for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) ){ /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number |
︙ | ︙ | |||
102739 102740 102741 102742 102743 102744 102745 | Trigger *pTrigger; /* Trigger definition to return */ int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ action = pFKey->aAction[iAction]; pTrigger = pFKey->apTrigger[iAction]; if( action!=OE_None && !pTrigger ){ | < | 103029 103030 103031 103032 103033 103034 103035 103036 103037 103038 103039 103040 103041 103042 | Trigger *pTrigger; /* Trigger definition to return */ int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ action = pFKey->aAction[iAction]; pTrigger = pFKey->apTrigger[iAction]; if( action!=OE_None && !pTrigger ){ char const *zFrom; /* Name of child table */ int nFrom; /* Length in bytes of zFrom */ Index *pIdx = 0; /* Parent key index for this FK */ int *aiCol = 0; /* child table cols -> parent key cols */ TriggerStep *pStep = 0; /* First (only) step of trigger program */ Expr *pWhere = 0; /* WHERE clause of trigger step */ ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */ |
︙ | ︙ | |||
102766 102767 102768 102769 102770 102771 102772 | int iFromCol; /* Idx of column in child table */ Expr *pEq; /* tFromCol = OLD.tToCol */ iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; assert( iFromCol>=0 ); assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) ); assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); | > | | < < < | 103055 103056 103057 103058 103059 103060 103061 103062 103063 103064 103065 103066 103067 103068 103069 103070 103071 | int iFromCol; /* Idx of column in child table */ Expr *pEq; /* tFromCol = OLD.tToCol */ iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; assert( iFromCol>=0 ); assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) ); assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); sqlite3TokenInit(&tToCol, pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName); sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName); /* Create the expression "OLD.zToCol = zFromCol". It is important ** that the "OLD.zToCol" term is on the LHS of the = operator, so ** that the affinity and collation sequence associated with the ** parent table are used for the comparison. */ pEq = sqlite3PExpr(pParse, TK_EQ, sqlite3PExpr(pParse, TK_DOT, |
︙ | ︙ | |||
102850 102851 102852 102853 102854 102855 102856 | pWhere, 0, 0, 0, 0, 0, 0 ); pWhere = 0; } /* Disable lookaside memory allocation */ | < | | 103137 103138 103139 103140 103141 103142 103143 103144 103145 103146 103147 103148 103149 103150 103151 | pWhere, 0, 0, 0, 0, 0, 0 ); pWhere = 0; } /* Disable lookaside memory allocation */ db->lookaside.bDisable++; pTrigger = (Trigger *)sqlite3DbMallocZero(db, sizeof(Trigger) + /* struct Trigger */ sizeof(TriggerStep) + /* Single step in trigger program */ nFrom + 1 /* Space for pStep->zTarget */ ); if( pTrigger ){ |
︙ | ︙ | |||
102873 102874 102875 102876 102877 102878 102879 | if( pWhen ){ pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0); pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); } } /* Re-enable the lookaside buffer, if it was disabled earlier. */ | | | 103159 103160 103161 103162 103163 103164 103165 103166 103167 103168 103169 103170 103171 103172 103173 | if( pWhen ){ pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0); pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); } } /* Re-enable the lookaside buffer, if it was disabled earlier. */ db->lookaside.bDisable--; sqlite3ExprDelete(db, pWhere); sqlite3ExprDelete(db, pWhen); sqlite3ExprListDelete(db, pList); sqlite3SelectDelete(db, pSelect); if( db->mallocFailed==1 ){ fkTriggerDelete(db, pTrigger); |
︙ | ︙ | |||
103068 103069 103070 103071 103072 103073 103074 | ** sqliteDeleteIndex() when the Index structure itself is cleaned ** up. */ int n; Table *pTab = pIdx->pTable; pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); if( !pIdx->zColAff ){ | | | 103354 103355 103356 103357 103358 103359 103360 103361 103362 103363 103364 103365 103366 103367 103368 | ** sqliteDeleteIndex() when the Index structure itself is cleaned ** up. */ int n; Table *pTab = pIdx->pTable; pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); if( !pIdx->zColAff ){ sqlite3OomFault(db); return 0; } for(n=0; n<pIdx->nColumn; n++){ i16 x = pIdx->aiColumn[n]; if( x>=0 ){ pIdx->zColAff[n] = pTab->aCol[x].affinity; }else if( x==XN_ROWID ){ |
︙ | ︙ | |||
103119 103120 103121 103122 103123 103124 103125 | SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ int i; char *zColAff = pTab->zColAff; if( zColAff==0 ){ sqlite3 *db = sqlite3VdbeDb(v); zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); if( !zColAff ){ | | | 103405 103406 103407 103408 103409 103410 103411 103412 103413 103414 103415 103416 103417 103418 103419 | SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ int i; char *zColAff = pTab->zColAff; if( zColAff==0 ){ sqlite3 *db = sqlite3VdbeDb(v); zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); if( !zColAff ){ sqlite3OomFault(db); return; } for(i=0; i<pTab->nCol; i++){ zColAff[i] = pTab->aCol[i].affinity; } do{ |
︙ | ︙ | |||
103215 103216 103217 103218 103219 103220 103221 | if( pTab->tabFlags & TF_Autoincrement ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); AutoincInfo *pInfo; pInfo = pToplevel->pAinc; while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } if( pInfo==0 ){ | | | 103501 103502 103503 103504 103505 103506 103507 103508 103509 103510 103511 103512 103513 103514 103515 | if( pTab->tabFlags & TF_Autoincrement ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); AutoincInfo *pInfo; pInfo = pToplevel->pAinc; while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } if( pInfo==0 ){ pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo)); if( pInfo==0 ) return 0; pInfo->pNext = pToplevel->pAinc; pToplevel->pAinc = pInfo; pInfo->pTab = pTab; pInfo->iDb = iDb; pToplevel->nMem++; /* Register to hold name of table */ pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */ |
︙ | ︙ | |||
103239 103240 103241 103242 103243 103244 103245 | ** register used by the autoincrement tracker. */ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){ AutoincInfo *p; /* Information about an AUTOINCREMENT */ sqlite3 *db = pParse->db; /* The database connection */ Db *pDb; /* Database only autoinc table */ int memId; /* Register holding max rowid */ | < > > > > > > > > > > > > > > < < | > | > > | > | | | < < | < | | | > > > > > > > > > < | > | < > | > > | | < > > > | 103525 103526 103527 103528 103529 103530 103531 103532 103533 103534 103535 103536 103537 103538 103539 103540 103541 103542 103543 103544 103545 103546 103547 103548 103549 103550 103551 103552 103553 103554 103555 103556 103557 103558 103559 103560 103561 103562 103563 103564 103565 103566 103567 103568 103569 103570 103571 103572 103573 103574 103575 103576 103577 103578 103579 103580 103581 103582 103583 103584 103585 103586 103587 103588 103589 103590 103591 103592 103593 103594 103595 103596 103597 103598 103599 103600 103601 103602 103603 103604 103605 103606 103607 103608 103609 103610 103611 103612 103613 103614 103615 103616 103617 103618 103619 103620 103621 103622 103623 103624 103625 103626 103627 103628 103629 103630 103631 103632 103633 103634 103635 103636 103637 103638 | ** register used by the autoincrement tracker. */ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){ AutoincInfo *p; /* Information about an AUTOINCREMENT */ sqlite3 *db = pParse->db; /* The database connection */ Db *pDb; /* Database only autoinc table */ int memId; /* Register holding max rowid */ Vdbe *v = pParse->pVdbe; /* VDBE under construction */ /* This routine is never called during trigger-generation. It is ** only called from the top-level */ assert( pParse->pTriggerTab==0 ); assert( sqlite3IsToplevel(pParse) ); assert( v ); /* We failed long ago if this is not so */ for(p = pParse->pAinc; p; p = p->pNext){ static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList autoInc[] = { /* 0 */ {OP_Null, 0, 0, 0}, /* 1 */ {OP_Rewind, 0, 9, 0}, /* 2 */ {OP_Column, 0, 0, 0}, /* 3 */ {OP_Ne, 0, 7, 0}, /* 4 */ {OP_Rowid, 0, 0, 0}, /* 5 */ {OP_Column, 0, 1, 0}, /* 6 */ {OP_Goto, 0, 9, 0}, /* 7 */ {OP_Next, 0, 2, 0}, /* 8 */ {OP_Integer, 0, 0, 0}, /* 9 */ {OP_Close, 0, 0, 0} }; VdbeOp *aOp; pDb = &db->aDb[p->iDb]; memId = p->regCtr; assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); sqlite3VdbeLoadString(v, memId-1, p->pTab->zName); aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn); if( aOp==0 ) break; aOp[0].p2 = memId; aOp[0].p3 = memId+1; aOp[2].p3 = memId; aOp[3].p1 = memId-1; aOp[3].p3 = memId; aOp[3].p5 = SQLITE_JUMPIFNULL; aOp[4].p2 = memId+1; aOp[5].p3 = memId; aOp[8].p2 = memId; } } /* ** Update the maximum rowid for an autoincrement calculation. ** ** This routine should be called when the regRowid register holds a ** new rowid that is about to be inserted. If that new rowid is ** larger than the maximum rowid in the memId memory cell, then the ** memory cell is updated. */ static void autoIncStep(Parse *pParse, int memId, int regRowid){ if( memId>0 ){ sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid); } } /* ** This routine generates the code needed to write autoincrement ** maximum rowid values back into the sqlite_sequence register. ** Every statement that might do an INSERT into an autoincrement ** table (either directly or through triggers) needs to call this ** routine just before the "exit" code. */ static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){ AutoincInfo *p; Vdbe *v = pParse->pVdbe; sqlite3 *db = pParse->db; assert( v ); for(p = pParse->pAinc; p; p = p->pNext){ static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList autoIncEnd[] = { /* 0 */ {OP_NotNull, 0, 2, 0}, /* 1 */ {OP_NewRowid, 0, 0, 0}, /* 2 */ {OP_MakeRecord, 0, 2, 0}, /* 3 */ {OP_Insert, 0, 0, 0}, /* 4 */ {OP_Close, 0, 0, 0} }; VdbeOp *aOp; Db *pDb = &db->aDb[p->iDb]; int iRec; int memId = p->regCtr; iRec = sqlite3GetTempReg(pParse); assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn); if( aOp==0 ) break; aOp[0].p1 = memId+1; aOp[1].p2 = memId+1; aOp[2].p1 = memId-1; aOp[2].p3 = iRec; aOp[3].p2 = iRec; aOp[3].p3 = memId+1; aOp[3].p5 = OPFLAG_APPEND; sqlite3ReleaseTempReg(pParse, iRec); } } SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ if( pParse->pAinc ) autoIncrementEnd(pParse); } #else /* ** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines ** above are all no-ops */ # define autoIncBegin(A,B,C) (0) |
︙ | ︙ | |||
103645 103646 103647 103648 103649 103650 103651 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); dest.iSdst = bIdListInOrder ? regData : 0; dest.nSdst = pTab->nCol; rc = sqlite3Select(pParse, pSelect, &dest); regFromSelect = dest.iSdst; if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup; | | | 103956 103957 103958 103959 103960 103961 103962 103963 103964 103965 103966 103967 103968 103969 103970 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); dest.iSdst = bIdListInOrder ? regData : 0; dest.nSdst = pTab->nCol; rc = sqlite3Select(pParse, pSelect, &dest); regFromSelect = dest.iSdst; if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup; sqlite3VdbeEndCoroutine(v, regYield); sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ assert( pSelect->pEList ); nColumn = pSelect->pEList->nExpr; /* Set useTempTable to TRUE if the result of the SELECT statement ** should be written into a temporary table (template 4). Set to ** FALSE if each output row of the SELECT can be written directly into |
︙ | ︙ | |||
103747 103748 103749 103750 103751 103752 103753 | } /* If this is not a view, open the table and and all indices */ if( !isView ){ int nIdx; nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0, &iDataCur, &iIdxCur); | | | 104058 104059 104060 104061 104062 104063 104064 104065 104066 104067 104068 104069 104070 104071 104072 | } /* If this is not a view, open the table and and all indices */ if( !isView ){ int nIdx; nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0, &iDataCur, &iIdxCur); aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1)); if( aRegIdx==0 ){ goto insert_cleanup; } for(i=0; i<nIdx; i++){ aRegIdx[i] = ++pParse->nMem; } } |
︙ | ︙ | |||
104632 104633 104634 104635 104636 104637 104638 | ** If pTab is a virtual table, then this routine is a no-op and the ** *piDataCur and *piIdxCur values are left uninitialized. */ SQLITE_PRIVATE int sqlite3OpenTableAndIndices( Parse *pParse, /* Parsing context */ Table *pTab, /* Table to be opened */ int op, /* OP_OpenRead or OP_OpenWrite */ | | | 104943 104944 104945 104946 104947 104948 104949 104950 104951 104952 104953 104954 104955 104956 104957 | ** If pTab is a virtual table, then this routine is a no-op and the ** *piDataCur and *piIdxCur values are left uninitialized. */ SQLITE_PRIVATE int sqlite3OpenTableAndIndices( Parse *pParse, /* Parsing context */ Table *pTab, /* Table to be opened */ int op, /* OP_OpenRead or OP_OpenWrite */ u8 p5, /* P5 value for OP_Open* opcodes (except on WITHOUT ROWID) */ int iBase, /* Use this for the table cursor, if there is one */ u8 *aToOpen, /* If not NULL: boolean for each table and index */ int *piDataCur, /* Write the database source cursor number here */ int *piIdxCur /* Write the first index cursor number here */ ){ int i; int iDb; |
︙ | ︙ | |||
104667 104668 104669 104670 104671 104672 104673 | }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); } if( piIdxCur ) *piIdxCur = iBase; for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ int iIdxCur = iBase++; assert( pIdx->pSchema==pTab->pSchema ); | < < < < > > > > > | 104978 104979 104980 104981 104982 104983 104984 104985 104986 104987 104988 104989 104990 104991 104992 104993 104994 104995 104996 104997 104998 104999 105000 | }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); } if( piIdxCur ) *piIdxCur = iBase; for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ int iIdxCur = iBase++; assert( pIdx->pSchema==pTab->pSchema ); if( aToOpen==0 || aToOpen[i+1] ){ sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "%s", pIdx->zName)); } if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ if( piDataCur ) *piDataCur = iIdxCur; }else{ sqlite3VdbeChangeP5(v, p5); } } if( iBase>pParse->nTab ) pParse->nTab = iBase; return i; } |
︙ | ︙ | |||
105165 105166 105167 105168 105169 105170 105171 | callbackIsInit = 1; } if( rc==SQLITE_ROW ){ azVals = &azCols[nCol]; for(i=0; i<nCol; i++){ azVals[i] = (char *)sqlite3_column_text(pStmt, i); if( !azVals[i] && sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){ | | | 105477 105478 105479 105480 105481 105482 105483 105484 105485 105486 105487 105488 105489 105490 105491 | callbackIsInit = 1; } if( rc==SQLITE_ROW ){ azVals = &azCols[nCol]; for(i=0; i<nCol; i++){ azVals[i] = (char *)sqlite3_column_text(pStmt, i); if( !azVals[i] && sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){ sqlite3OomFault(db); goto exec_out; } } } if( xCallback(pArg, nCol, azVals, azCols) ){ /* EVIDENCE-OF: R-38229-40159 If the callback function to ** sqlite3_exec() returns non-zero, then sqlite3_exec() will |
︙ | ︙ | |||
107053 107054 107055 107056 107057 107058 107059 | /* Number of pragmas: 60 on by default, 73 total. */ /************** End of pragma.h **********************************************/ /************** Continuing where we left off in pragma.c *********************/ /* ** Interpret the given string as a safety level. Return 0 for OFF, | | | | | | | | > | | > > | 107365 107366 107367 107368 107369 107370 107371 107372 107373 107374 107375 107376 107377 107378 107379 107380 107381 107382 107383 107384 107385 107386 107387 107388 107389 107390 107391 107392 107393 107394 107395 107396 107397 107398 107399 107400 107401 107402 107403 | /* Number of pragmas: 60 on by default, 73 total. */ /************** End of pragma.h **********************************************/ /************** Continuing where we left off in pragma.c *********************/ /* ** Interpret the given string as a safety level. Return 0 for OFF, ** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or ** unrecognized string argument. The FULL and EXTRA option is disallowed ** if the omitFull parameter it 1. ** ** Note that the values returned are one less that the values that ** should be passed into sqlite3BtreeSetSafetyLevel(). The is done ** to support legacy SQL code. The safety level used to be boolean ** and older scripts may have used numbers 0 for OFF and 1 for ON. */ static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){ /* 123456789 123456789 123 */ static const char zText[] = "onoffalseyestruextrafull"; static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 15, 20}; static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 5, 4}; static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 3, 2}; /* on no off false yes true extra full */ int i, n; if( sqlite3Isdigit(*z) ){ return (u8)sqlite3Atoi(z); } n = sqlite3Strlen30(z); for(i=0; i<ArraySize(iLength); i++){ if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 && (!omitFull || iValue[i]<=1) ){ return iValue[i]; } } return dflt; } /* |
︙ | ︙ | |||
107465 107466 107467 107468 107469 107470 107471 | if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE; }else{ int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); sqlite3BeginWriteOperation(pParse, 0, iDb); | < | | 107780 107781 107782 107783 107784 107785 107786 107787 107788 107789 107790 107791 107792 107793 107794 | if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE; }else{ int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, size); assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } break; } #endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */ |
︙ | ︙ | |||
107497 107498 107499 107500 107501 107502 107503 | returnSingleInt(v, "page_size", size); }else{ /* Malloc may fail when setting the page-size, as there is an internal ** buffer that the pager module resizes using sqlite3_realloc(). */ db->nextPagesize = sqlite3Atoi(zRight); if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){ | | | 107811 107812 107813 107814 107815 107816 107817 107818 107819 107820 107821 107822 107823 107824 107825 | returnSingleInt(v, "page_size", size); }else{ /* Malloc may fail when setting the page-size, as there is an internal ** buffer that the pager module resizes using sqlite3_realloc(). */ db->nextPagesize = sqlite3Atoi(zRight); if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){ sqlite3OomFault(db); } } break; } /* ** PRAGMA [schema.]secure_delete |
︙ | ︙ | |||
107704 107705 107706 107707 107708 107709 107710 | */ static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList setMeta6[] = { { OP_Transaction, 0, 1, 0}, /* 0 */ { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, { OP_If, 1, 0, 0}, /* 2 */ { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ | < | | | | 108018 108019 108020 108021 108022 108023 108024 108025 108026 108027 108028 108029 108030 108031 108032 108033 108034 108035 108036 108037 108038 108039 108040 108041 108042 108043 | */ static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList setMeta6[] = { { OP_Transaction, 0, 1, 0}, /* 0 */ { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, { OP_If, 1, 0, 0}, /* 2 */ { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ { OP_SetCookie, 0, BTREE_INCR_VACUUM, 0}, /* 4 */ }; VdbeOp *aOp; int iAddr = sqlite3VdbeCurrentAddr(v); sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setMeta6)); aOp = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn); if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[2].p2 = iAddr+4; aOp[4].p1 = iDb; aOp[4].p3 = eAuto - 1; sqlite3VdbeUsesBtree(v, iDb); } } break; } #endif |
︙ | ︙ | |||
107995 107996 107997 107998 107999 108000 108001 | } break; } #endif /* SQLITE_ENABLE_LOCKING_STYLE */ /* ** PRAGMA [schema.]synchronous | | | 108308 108309 108310 108311 108312 108313 108314 108315 108316 108317 108318 108319 108320 108321 108322 | } break; } #endif /* SQLITE_ENABLE_LOCKING_STYLE */ /* ** PRAGMA [schema.]synchronous ** PRAGMA [schema.]synchronous=OFF|ON|NORMAL|FULL|EXTRA ** ** Return or set the local value of the synchronous flag. Changing ** the local value does not make changes to the disk file and the ** default value will be restored the next time the database is ** opened. */ case PragTyp_SYNCHRONOUS: { |
︙ | ︙ | |||
108622 108623 108624 108625 108626 108627 108628 | #endif /* SQLITE_OMIT_BTREECOUNT */ } } { static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList endCode[] = { { OP_AddImm, 1, 0, 0}, /* 0 */ | | | < | 108935 108936 108937 108938 108939 108940 108941 108942 108943 108944 108945 108946 108947 108948 108949 108950 108951 108952 108953 108954 108955 108956 108957 | #endif /* SQLITE_OMIT_BTREECOUNT */ } } { static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList endCode[] = { { OP_AddImm, 1, 0, 0}, /* 0 */ { OP_If, 1, 4, 0}, /* 1 */ { OP_String8, 0, 3, 0}, /* 2 */ { OP_ResultRow, 3, 1, 0}, /* 3 */ }; VdbeOp *aOp; aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); if( aOp ){ aOp[0].p2 = -mxErr; aOp[2].p4type = P4_STATIC; aOp[2].p4.z = "ok"; } } } break; #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ |
︙ | ︙ | |||
108749 108750 108751 108752 108753 108754 108755 | case PragTyp_HEADER_VALUE: { int iCookie = pPragma->iArg; /* Which cookie to read or write */ sqlite3VdbeUsesBtree(v, iDb); if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){ /* Write the specified cookie value */ static const VdbeOpList setCookie[] = { { OP_Transaction, 0, 1, 0}, /* 0 */ | < | | < | > | 109061 109062 109063 109064 109065 109066 109067 109068 109069 109070 109071 109072 109073 109074 109075 109076 109077 109078 109079 109080 109081 109082 109083 109084 | case PragTyp_HEADER_VALUE: { int iCookie = pPragma->iArg; /* Which cookie to read or write */ sqlite3VdbeUsesBtree(v, iDb); if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){ /* Write the specified cookie value */ static const VdbeOpList setCookie[] = { { OP_Transaction, 0, 1, 0}, /* 0 */ { OP_SetCookie, 0, 0, 0}, /* 1 */ }; VdbeOp *aOp; sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie)); aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[1].p2 = iCookie; aOp[1].p3 = sqlite3Atoi(zRight); }else{ /* Read the specified cookie value */ static const VdbeOpList readCookie[] = { { OP_Transaction, 0, 0, 0}, /* 0 */ { OP_ReadCookie, 0, 1, 0}, /* 1 */ { OP_ResultRow, 1, 1, 0} }; |
︙ | ︙ | |||
109031 109032 109033 109034 109035 109036 109037 | const char *zObj, /* Object being parsed at the point of error */ const char *zExtra /* Error information */ ){ sqlite3 *db = pData->db; if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){ char *z; if( zObj==0 ) zObj = "?"; | | | < | 109342 109343 109344 109345 109346 109347 109348 109349 109350 109351 109352 109353 109354 109355 109356 109357 109358 109359 | const char *zObj, /* Object being parsed at the point of error */ const char *zExtra /* Error information */ ){ sqlite3 *db = pData->db; if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){ char *z; if( zObj==0 ) zObj = "?"; z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); if( zExtra ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); sqlite3DbFree(db, *pData->pzErrMsg); *pData->pzErrMsg = z; } pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT; } /* ** This is the callback routine for the code that initializes the ** database. See sqlite3Init() below for additional information. |
︙ | ︙ | |||
109094 109095 109096 109097 109098 109099 109100 | db->init.iDb = 0; if( SQLITE_OK!=rc ){ if( db->init.orphanTrigger ){ assert( iDb==1 ); }else{ pData->rc = rc; if( rc==SQLITE_NOMEM ){ | | | 109404 109405 109406 109407 109408 109409 109410 109411 109412 109413 109414 109415 109416 109417 109418 | db->init.iDb = 0; if( SQLITE_OK!=rc ){ if( db->init.orphanTrigger ){ assert( iDb==1 ); }else{ pData->rc = rc; if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ corruptSchema(pData, argv[0], sqlite3_errmsg(db)); } } } sqlite3_finalize(pStmt); }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){ |
︙ | ︙ | |||
109339 109340 109341 109342 109343 109344 109345 | if( openedTransaction ){ sqlite3BtreeCommit(pDb->pBt); } sqlite3BtreeLeave(pDb->pBt); error_out: if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ | | | 109649 109650 109651 109652 109653 109654 109655 109656 109657 109658 109659 109660 109661 109662 109663 | if( openedTransaction ){ sqlite3BtreeCommit(pDb->pBt); } sqlite3BtreeLeave(pDb->pBt); error_out: if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ sqlite3OomFault(db); } return rc; } /* ** Initialize all database files - the main database file, the file ** used to store temporary tables, and any additional database files |
︙ | ︙ | |||
109437 109438 109439 109440 109441 109442 109443 | /* If there is not already a read-only (or read-write) transaction opened ** on the b-tree database, open one now. If a transaction is opened, it ** will be closed immediately after reading the meta-value. */ if( !sqlite3BtreeIsInReadTrans(pBt) ){ rc = sqlite3BtreeBeginTrans(pBt, 0); if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ | | | 109747 109748 109749 109750 109751 109752 109753 109754 109755 109756 109757 109758 109759 109760 109761 | /* If there is not already a read-only (or read-write) transaction opened ** on the b-tree database, open one now. If a transaction is opened, it ** will be closed immediately after reading the meta-value. */ if( !sqlite3BtreeIsInReadTrans(pBt) ){ rc = sqlite3BtreeBeginTrans(pBt, 0); if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ sqlite3OomFault(db); } if( rc!=SQLITE_OK ) return; openedTransaction = 1; } /* Read the schema cookie from the database. If it does not match the ** value stored as part of the in-memory schema representation, |
︙ | ︙ | |||
109500 109501 109502 109503 109504 109505 109506 109507 109508 109509 109510 109511 109512 109513 | ** Free all memory allocations in the pParse object */ SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ if( pParse ){ sqlite3 *db = pParse->db; sqlite3DbFree(db, pParse->aLabel); sqlite3ExprListDelete(db, pParse->pConstExpr); } } /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ static int sqlite3Prepare( | > > > > > | 109810 109811 109812 109813 109814 109815 109816 109817 109818 109819 109820 109821 109822 109823 109824 109825 109826 109827 109828 | ** Free all memory allocations in the pParse object */ SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ if( pParse ){ sqlite3 *db = pParse->db; sqlite3DbFree(db, pParse->aLabel); sqlite3ExprListDelete(db, pParse->pConstExpr); if( db ){ assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; } pParse->disableLookaside = 0; } } /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ static int sqlite3Prepare( |
︙ | ︙ | |||
109528 109529 109530 109531 109532 109533 109534 | pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); if( pParse==0 ){ rc = SQLITE_NOMEM; goto end_prepare; } pParse->pReprepare = pReprepare; assert( ppStmt && *ppStmt==0 ); | | | 109843 109844 109845 109846 109847 109848 109849 109850 109851 109852 109853 109854 109855 109856 109857 | pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); if( pParse==0 ){ rc = SQLITE_NOMEM; goto end_prepare; } pParse->pReprepare = pReprepare; assert( ppStmt && *ppStmt==0 ); /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */ assert( sqlite3_mutex_held(db->mutex) ); /* Check to verify that it is possible to get a read lock on all ** database schemas. The inability to get a read lock indicates that ** some other database connection is holding a write-lock, which in ** turn means that the other connection has made uncommitted changes ** to the schema. |
︙ | ︙ | |||
109585 109586 109587 109588 109589 109590 109591 | sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long"); rc = sqlite3ApiExit(db, SQLITE_TOOBIG); goto end_prepare; } zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); if( zSqlCopy ){ sqlite3RunParser(pParse, zSqlCopy, &zErrMsg); | < > < < < | 109900 109901 109902 109903 109904 109905 109906 109907 109908 109909 109910 109911 109912 109913 109914 109915 109916 109917 109918 109919 109920 109921 109922 109923 | sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long"); rc = sqlite3ApiExit(db, SQLITE_TOOBIG); goto end_prepare; } zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); if( zSqlCopy ){ sqlite3RunParser(pParse, zSqlCopy, &zErrMsg); pParse->zTail = &zSql[pParse->zTail-zSqlCopy]; sqlite3DbFree(db, zSqlCopy); }else{ pParse->zTail = &zSql[nBytes]; } }else{ sqlite3RunParser(pParse, zSql, &zErrMsg); } assert( 0==pParse->nQueryLoop ); if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK; if( pParse->checkSchema ){ schemaIsValid(pParse); } if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM; } |
︙ | ︙ | |||
109719 109720 109721 109722 109723 109724 109725 | zSql = sqlite3_sql((sqlite3_stmt *)p); assert( zSql!=0 ); /* Reprepare only called for prepare_v2() statements */ db = sqlite3VdbeDb(p); assert( sqlite3_mutex_held(db->mutex) ); rc = sqlite3LockAndPrepare(db, zSql, -1, 0, p, &pNew, 0); if( rc ){ if( rc==SQLITE_NOMEM ){ | | | 110031 110032 110033 110034 110035 110036 110037 110038 110039 110040 110041 110042 110043 110044 110045 | zSql = sqlite3_sql((sqlite3_stmt *)p); assert( zSql!=0 ); /* Reprepare only called for prepare_v2() statements */ db = sqlite3VdbeDb(p); assert( sqlite3_mutex_held(db->mutex) ); rc = sqlite3LockAndPrepare(db, zSql, -1, 0, p, &pNew, 0); if( rc ){ if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); } assert( pNew==0 ); return rc; }else{ assert( pNew!=0 ); } sqlite3VdbeSwap((Vdbe*)pNew, p); |
︙ | ︙ | |||
109973 109974 109975 109976 109977 109978 109979 | u16 selFlags, /* Flag parameters, such as SF_Distinct */ Expr *pLimit, /* LIMIT value. NULL means not used */ Expr *pOffset /* OFFSET value. NULL means no offset */ ){ Select *pNew; Select standin; sqlite3 *db = pParse->db; | | | 110285 110286 110287 110288 110289 110290 110291 110292 110293 110294 110295 110296 110297 110298 110299 | u16 selFlags, /* Flag parameters, such as SF_Distinct */ Expr *pLimit, /* LIMIT value. NULL means not used */ Expr *pOffset /* OFFSET value. NULL means no offset */ ){ Select *pNew; Select standin; sqlite3 *db = pParse->db; pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); if( pNew==0 ){ assert( db->mallocFailed ); pNew = &standin; } if( pEList==0 ){ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0)); } |
︙ | ︙ | |||
110877 110878 110879 110880 110881 110882 110883 | p->nField = (u16)N; p->nXField = (u16)X; p->enc = ENC(db); p->db = db; p->nRef = 1; memset(&p[1], 0, nExtra); }else{ | | | 111189 111190 111191 111192 111193 111194 111195 111196 111197 111198 111199 111200 111201 111202 111203 | p->nField = (u16)N; p->nXField = (u16)X; p->enc = ENC(db); p->db = db; p->nRef = 1; memset(&p[1], 0, nExtra); }else{ sqlite3OomFault(db); } return p; } /* ** Deallocate a KeyInfo object */ |
︙ | ︙ | |||
111538 111539 111540 111541 111542 111543 111544 | } zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt); } pCol->zName = zName; sqlite3ColumnPropertiesFromName(0, pCol); if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){ | | | 111850 111851 111852 111853 111854 111855 111856 111857 111858 111859 111860 111861 111862 111863 111864 | } zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt); } pCol->zName = zName; sqlite3ColumnPropertiesFromName(0, pCol); if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){ sqlite3OomFault(db); } } sqlite3HashClear(&ht); if( db->mallocFailed ){ for(j=0; j<i; j++){ sqlite3DbFree(db, aCol[j].zName); } |
︙ | ︙ | |||
111625 111626 111627 111628 111629 111630 111631 | db->flags = savedFlags; pTab = sqlite3DbMallocZero(db, sizeof(Table) ); if( pTab==0 ){ return 0; } /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside ** is disabled */ | | | 111937 111938 111939 111940 111941 111942 111943 111944 111945 111946 111947 111948 111949 111950 111951 | db->flags = savedFlags; pTab = sqlite3DbMallocZero(db, sizeof(Table) ); if( pTab==0 ){ return 0; } /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside ** is disabled */ assert( db->lookaside.bDisable ); pTab->nRef = 1; pTab->zName = 0; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); selectAddColumnTypeAndCollation(pParse, pTab, pSelect); pTab->iPKey = -1; if( db->mallocFailed ){ |
︙ | ︙ | |||
111721 111722 111723 111724 111725 111726 111727 | } if( p->pOffset ){ p->iOffset = iOffset = ++pParse->nMem; pParse->nMem++; /* Allocate an extra register for limit+offset */ sqlite3ExprCode(pParse, p->pOffset, iOffset); sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); VdbeComment((v, "OFFSET counter")); | | < < | 112033 112034 112035 112036 112037 112038 112039 112040 112041 112042 112043 112044 112045 112046 112047 112048 | } if( p->pOffset ){ p->iOffset = iOffset = ++pParse->nMem; pParse->nMem++; /* Allocate an extra register for limit+offset */ sqlite3ExprCode(pParse, p->pOffset, iOffset); sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); VdbeComment((v, "OFFSET counter")); sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset); VdbeComment((v, "LIMIT+OFFSET")); } } } #ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** Return the appropriate collating sequence for the iCol-th column of |
︙ | ︙ | |||
112141 112142 112143 112144 112145 112146 112147 | p->pPrior = 0; p->iLimit = pPrior->iLimit; p->iOffset = pPrior->iOffset; if( p->iLimit ){ addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); VdbeComment((v, "Jump ahead if LIMIT reached")); if( p->iOffset ){ | | < | | 112451 112452 112453 112454 112455 112456 112457 112458 112459 112460 112461 112462 112463 112464 112465 112466 | p->pPrior = 0; p->iLimit = pPrior->iLimit; p->iOffset = pPrior->iOffset; if( p->iLimit ){ addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); VdbeComment((v, "Jump ahead if LIMIT reached")); if( p->iOffset ){ sqlite3VdbeAddOp3(v, OP_OffsetLimit, p->iLimit, p->iOffset+1, p->iOffset); } } explainSetInteger(iSub2, pParse->iNextSelectId); rc = sqlite3Select(pParse, p, &dest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; |
︙ | ︙ | |||
112734 112735 112736 112737 112738 112739 112740 | /* Compute the comparison permutation and keyinfo that is used with ** the permutation used to determine if the next ** row of results comes from selectA or selectB. Also add explicit ** collations to the ORDER BY clause terms so that when the subqueries ** to the right and the left are evaluated, they use the correct ** collation. */ | | > | | 113043 113044 113045 113046 113047 113048 113049 113050 113051 113052 113053 113054 113055 113056 113057 113058 113059 113060 113061 | /* Compute the comparison permutation and keyinfo that is used with ** the permutation used to determine if the next ** row of results comes from selectA or selectB. Also add explicit ** collations to the ORDER BY clause terms so that when the subqueries ** to the right and the left are evaluated, they use the correct ** collation. */ aPermute = sqlite3DbMallocRawNN(db, sizeof(int)*(nOrderBy + 1)); if( aPermute ){ struct ExprList_item *pItem; aPermute[0] = nOrderBy; for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){ assert( pItem->u.x.iOrderByCol>0 ); assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ); aPermute[i] = pItem->u.x.iOrderByCol - 1; } pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1); }else{ pKeyMerge = 0; |
︙ | ︙ | |||
112815 112816 112817 112818 112819 112820 112821 | */ addrSelectA = sqlite3VdbeCurrentAddr(v) + 1; addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); VdbeComment((v, "left SELECT")); pPrior->iLimit = regLimitA; explainSetInteger(iSub1, pParse->iNextSelectId); sqlite3Select(pParse, pPrior, &destA); | | | | 113125 113126 113127 113128 113129 113130 113131 113132 113133 113134 113135 113136 113137 113138 113139 113140 113141 113142 113143 113144 113145 113146 113147 113148 113149 113150 113151 113152 113153 113154 113155 113156 | */ addrSelectA = sqlite3VdbeCurrentAddr(v) + 1; addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); VdbeComment((v, "left SELECT")); pPrior->iLimit = regLimitA; explainSetInteger(iSub1, pParse->iNextSelectId); sqlite3Select(pParse, pPrior, &destA); sqlite3VdbeEndCoroutine(v, regAddrA); sqlite3VdbeJumpHere(v, addr1); /* Generate a coroutine to evaluate the SELECT statement on ** the right - the "B" select */ addrSelectB = sqlite3VdbeCurrentAddr(v) + 1; addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB); VdbeComment((v, "right SELECT")); savedLimit = p->iLimit; savedOffset = p->iOffset; p->iLimit = regLimitB; p->iOffset = 0; explainSetInteger(iSub2, pParse->iNextSelectId); sqlite3Select(pParse, p, &destB); p->iLimit = savedLimit; p->iOffset = savedOffset; sqlite3VdbeEndCoroutine(v, regAddrB); /* Generate a subroutine that outputs the current row of the A ** select as the next output row of the compound select. */ VdbeNoopComment((v, "Output routine for A")); addrOutA = generateOutputSubroutine(pParse, p, &destA, pDest, regOutA, |
︙ | ︙ | |||
114299 114300 114301 114302 114303 114304 114305 | zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName); zToFree = zColname; } }else{ pExpr = pRight; } pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); | | < | 114609 114610 114611 114612 114613 114614 114615 114616 114617 114618 114619 114620 114621 114622 114623 | zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName); zToFree = zColname; } }else{ pExpr = pRight; } pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); sqlite3TokenInit(&sColname, zColname); sqlite3ExprListSetName(pParse, pNew, &sColname, 0); if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){ struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; if( pSub ){ pX->zSpan = sqlite3DbStrDup(db, pSub->pEList->a[j].zSpan); testcase( pX->zSpan==0 ); }else{ |
︙ | ︙ | |||
114854 114855 114856 114857 114858 114859 114860 | pItem->addrFillSub = addrTop; sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow); pItem->fg.viaCoroutine = 1; pItem->regResult = dest.iSdst; | | | 115163 115164 115165 115166 115167 115168 115169 115170 115171 115172 115173 115174 115175 115176 115177 | pItem->addrFillSub = addrTop; sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow); pItem->fg.viaCoroutine = 1; pItem->regResult = dest.iSdst; sqlite3VdbeEndCoroutine(v, pItem->regReturn); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); }else{ /* Generate a subroutine that will fill an ephemeral table with ** the content of this subquery. pItem->addrFillSub will point ** to the address of the generated subroutine. pItem->regReturn ** is a register allocated to hold the subroutine return address |
︙ | ︙ | |||
115426 115427 115428 115429 115430 115431 115432 | flag = minMaxQuery(&sAggInfo, &pMinMax); } assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) ); if( flag ){ pMinMax = sqlite3ExprListDup(db, pMinMax, 0); pDel = pMinMax; | > | | 115735 115736 115737 115738 115739 115740 115741 115742 115743 115744 115745 115746 115747 115748 115749 115750 | flag = minMaxQuery(&sAggInfo, &pMinMax); } assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) ); if( flag ){ pMinMax = sqlite3ExprListDup(db, pMinMax, 0); pDel = pMinMax; assert( db->mallocFailed || pMinMax!=0 ); if( !db->mallocFailed ){ pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0; pMinMax->a[0].pExpr->op = TK_COLUMN; } } /* This case runs if the aggregate has no GROUP BY clause. The ** processing is much simpler since there is only a single row |
︙ | ︙ | |||
115999 116000 116001 116002 116003 116004 116005 | zName = pTrig->zName; iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); pTrig->step_list = pStepList; while( pStepList ){ pStepList->pTrig = pTrig; pStepList = pStepList->pNext; } | | < | 116309 116310 116311 116312 116313 116314 116315 116316 116317 116318 116319 116320 116321 116322 116323 | zName = pTrig->zName; iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); pTrig->step_list = pStepList; while( pStepList ){ pStepList->pTrig = pTrig; pStepList = pStepList->pNext; } sqlite3TokenInit(&nameToken, pTrig->zName); sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken); if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) || sqlite3FixExpr(&sFix, pTrig->pWhen) ){ goto triggerfinish_cleanup; } |
︙ | ︙ | |||
116036 116037 116038 116039 116040 116041 116042 | if( db->init.busy ){ Trigger *pLink = pTrig; Hash *pHash = &db->aDb[iDb].pSchema->trigHash; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pTrig = sqlite3HashInsert(pHash, zName, pTrig); if( pTrig ){ | | | 116345 116346 116347 116348 116349 116350 116351 116352 116353 116354 116355 116356 116357 116358 116359 | if( db->init.busy ){ Trigger *pLink = pTrig; Hash *pHash = &db->aDb[iDb].pSchema->trigHash; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pTrig = sqlite3HashInsert(pHash, zName, pTrig); if( pTrig ){ sqlite3OomFault(db); }else if( pLink->pSchema==pLink->pTabSchema ){ Table *pTab; pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table); assert( pTab!=0 ); pLink->pNext = pTab->pTrigger; pTab->pTrigger = pLink; } |
︙ | ︙ | |||
117012 117013 117014 117015 117016 117017 117018 | } pParse->nTab++; } /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. ** Initialize aXRef[] and aToOpen[] to their default values. */ | | | 117321 117322 117323 117324 117325 117326 117327 117328 117329 117330 117331 117332 117333 117334 117335 | } pParse->nTab++; } /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. ** Initialize aXRef[] and aToOpen[] to their default values. */ aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 ); if( aXRef==0 ) goto update_cleanup; aRegIdx = aXRef+pTab->nCol; aToOpen = (u8*)(aRegIdx+nIdx); memset(aToOpen, 1, nIdx+1); aToOpen[nIdx+1] = 0; for(i=0; i<pTab->nCol; i++) aXRef[i] = -1; |
︙ | ︙ | |||
118052 118053 118054 118055 118056 118057 118058 | sqlite3_mutex_enter(db->mutex); nName = sqlite3Strlen30(zName); if( sqlite3HashFind(&db->aModule, zName) ){ rc = SQLITE_MISUSE_BKPT; }else{ Module *pMod; | | | | 118361 118362 118363 118364 118365 118366 118367 118368 118369 118370 118371 118372 118373 118374 118375 118376 118377 118378 118379 118380 118381 118382 118383 118384 118385 118386 118387 118388 | sqlite3_mutex_enter(db->mutex); nName = sqlite3Strlen30(zName); if( sqlite3HashFind(&db->aModule, zName) ){ rc = SQLITE_MISUSE_BKPT; }else{ Module *pMod; pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1); if( pMod ){ Module *pDel; char *zCopy = (char *)(&pMod[1]); memcpy(zCopy, zName, nName+1); pMod->zName = zCopy; pMod->pModule = pModule; pMod->pAux = pAux; pMod->xDestroy = xDestroy; pMod->pEpoTab = 0; pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); assert( pDel==0 || pDel==pMod ); if( pDel ){ sqlite3OomFault(db); sqlite3DbFree(db, pDel); } } } rc = sqlite3ApiExit(db, rc); if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); |
︙ | ︙ | |||
118442 118443 118444 118445 118446 118447 118448 | else { Table *pOld; Schema *pSchema = pTab->pSchema; const char *zName = pTab->zName; assert( sqlite3SchemaMutexHeld(db, 0, pSchema) ); pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab); if( pOld ){ | | | 118751 118752 118753 118754 118755 118756 118757 118758 118759 118760 118761 118762 118763 118764 118765 | else { Table *pOld; Schema *pSchema = pTab->pSchema; const char *zName = pTab->zName; assert( sqlite3SchemaMutexHeld(db, 0, pSchema) ); pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab); if( pOld ){ sqlite3OomFault(db); assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ return; } pParse->pNewTable = 0; } } |
︙ | ︙ | |||
118533 118534 118535 118536 118537 118538 118539 | sCtx.pTab = pTab; sCtx.pVTable = pVTable; sCtx.pPrior = db->pVtabCtx; sCtx.bDeclared = 0; db->pVtabCtx = &sCtx; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); db->pVtabCtx = sCtx.pPrior; | | | 118842 118843 118844 118845 118846 118847 118848 118849 118850 118851 118852 118853 118854 118855 118856 | sCtx.pTab = pTab; sCtx.pVTable = pVTable; sCtx.pPrior = db->pVtabCtx; sCtx.bDeclared = 0; db->pVtabCtx = &sCtx; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); db->pVtabCtx = sCtx.pPrior; if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); assert( sCtx.pTab==pTab ); if( SQLITE_OK!=rc ){ if( zErr==0 ){ *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); }else { *pzErr = sqlite3MPrintf(db, "%s", zErr); |
︙ | ︙ | |||
119091 119092 119093 119094 119095 119096 119097 | } n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]); apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n); if( apVtabLock ){ pToplevel->apVtabLock = apVtabLock; pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab; }else{ | | | 119400 119401 119402 119403 119404 119405 119406 119407 119408 119409 119410 119411 119412 119413 119414 | } n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]); apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n); if( apVtabLock ){ pToplevel->apVtabLock = apVtabLock; pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab; }else{ sqlite3OomFault(pToplevel->db); } } /* ** Check to see if virtual tale module pMod can be have an eponymous ** virtual table instance. If it can, create one if one does not already ** exist. Return non-zero if the eponymous virtual table instance exists |
︙ | ︙ | |||
119833 119834 119835 119836 119837 119838 119839 | int i, j; if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return; sqlite3StrAccumAppend(pStr, " (", 2); for(i=0; i<nEq; i++){ const char *z = explainIndexColumnName(pIndex, i); if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5); | | | 120142 120143 120144 120145 120146 120147 120148 120149 120150 120151 120152 120153 120154 120155 120156 | int i, j; if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return; sqlite3StrAccumAppend(pStr, " (", 2); for(i=0; i<nEq; i++){ const char *z = explainIndexColumnName(pIndex, i); if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5); sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z); } j = i; if( pLoop->wsFlags&WHERE_BTM_LIMIT ){ const char *z = explainIndexColumnName(pIndex, i); explainAppendTerm(pStr, i++, z, ">"); } |
︙ | ︙ | |||
119892 119893 119894 119895 119896 119897 119898 | isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN"); if( pItem->pSelect ){ | | | | | 120201 120202 120203 120204 120205 120206 120207 120208 120209 120210 120211 120212 120213 120214 120215 120216 120217 120218 120219 120220 120221 | isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN"); if( pItem->pSelect ){ sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId); }else{ sqlite3XPrintf(&str, " TABLE %s", pItem->zName); } if( pItem->zAlias ){ sqlite3XPrintf(&str, " AS %s", pItem->zAlias); } if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ const char *zFmt = 0; Index *pIdx; assert( pLoop->u.btree.pIndex!=0 ); pIdx = pLoop->u.btree.pIndex; |
︙ | ︙ | |||
119922 119923 119924 119925 119926 119927 119928 | }else if( flags & WHERE_IDX_ONLY ){ zFmt = "COVERING INDEX %s"; }else{ zFmt = "INDEX %s"; } if( zFmt ){ sqlite3StrAccumAppend(&str, " USING ", 7); | | | | | | 120231 120232 120233 120234 120235 120236 120237 120238 120239 120240 120241 120242 120243 120244 120245 120246 120247 120248 120249 120250 120251 120252 120253 120254 120255 120256 120257 120258 120259 120260 120261 120262 120263 120264 120265 120266 120267 120268 120269 120270 | }else if( flags & WHERE_IDX_ONLY ){ zFmt = "COVERING INDEX %s"; }else{ zFmt = "INDEX %s"; } if( zFmt ){ sqlite3StrAccumAppend(&str, " USING ", 7); sqlite3XPrintf(&str, zFmt, pIdx->zName); explainIndexRange(&str, pLoop); } }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ const char *zRangeOp; if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ zRangeOp = "="; }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){ zRangeOp = ">? AND rowid<"; }else if( flags&WHERE_BTM_LIMIT ){ zRangeOp = ">"; }else{ assert( flags&WHERE_TOP_LIMIT); zRangeOp = "<"; } sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s", pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); } #endif #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS if( pLoop->nOut>=10 ){ sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut)); }else{ sqlite3StrAccumAppend(&str, " (~1 row)", 9); } #endif zMsg = sqlite3StrAccumFinish(&str); ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC); } |
︙ | ︙ | |||
120252 120253 120254 120255 120256 120257 120258 | /* Figure out how many memory cells we will need then allocate them. */ regBase = pParse->nMem + 1; nReg = pLoop->u.btree.nEq + nExtraReg; pParse->nMem += nReg; zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx)); | < | < | 120561 120562 120563 120564 120565 120566 120567 120568 120569 120570 120571 120572 120573 120574 120575 | /* Figure out how many memory cells we will need then allocate them. */ regBase = pParse->nMem + 1; nReg = pLoop->u.btree.nEq + nExtraReg; pParse->nMem += nReg; zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx)); assert( zAff!=0 || pParse->db->mallocFailed ); if( nSkip ){ int iIdxCur = pLevel->iIdxCur; sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); |
︙ | ︙ | |||
120502 120503 120504 120505 120506 120507 120508 120509 120510 120511 120512 120513 120514 120515 | (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0, (const char*)pExpr, P4_EXPR); } } #else # define codeCursorHint(A,B,C) /* No-op */ #endif /* SQLITE_ENABLE_CURSOR_HINTS */ /* ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. */ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( WhereInfo *pWInfo, /* Complete information about the WHERE clause */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 120809 120810 120811 120812 120813 120814 120815 120816 120817 120818 120819 120820 120821 120822 120823 120824 120825 120826 120827 120828 120829 120830 120831 120832 120833 120834 120835 120836 120837 120838 120839 120840 120841 120842 120843 120844 120845 120846 120847 120848 120849 120850 120851 120852 120853 120854 120855 120856 120857 120858 120859 120860 120861 120862 120863 120864 120865 120866 120867 120868 120869 120870 | (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0, (const char*)pExpr, P4_EXPR); } } #else # define codeCursorHint(A,B,C) /* No-op */ #endif /* SQLITE_ENABLE_CURSOR_HINTS */ /* ** Cursor iCur is open on an intkey b-tree (a table). Register iRowid contains ** a rowid value just read from cursor iIdxCur, open on index pIdx. This ** function generates code to do a deferred seek of cursor iCur to the ** rowid stored in register iRowid. ** ** Normally, this is just: ** ** OP_Seek $iCur $iRowid ** ** However, if the scan currently being coded is a branch of an OR-loop and ** the statement currently being coded is a SELECT, then P3 of the OP_Seek ** is set to iIdxCur and P4 is set to point to an array of integers ** containing one entry for each column of the table cursor iCur is open ** on. For each table column, if the column is the i'th column of the ** index, then the corresponding array entry is set to (i+1). If the column ** does not appear in the index at all, the array entry is set to 0. */ static void codeDeferredSeek( WhereInfo *pWInfo, /* Where clause context */ Index *pIdx, /* Index scan is using */ int iCur, /* Cursor for IPK b-tree */ int iIdxCur /* Index cursor */ ){ Parse *pParse = pWInfo->pParse; /* Parse context */ Vdbe *v = pParse->pVdbe; /* Vdbe to generate code within */ assert( iIdxCur>0 ); assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 ); sqlite3VdbeAddOp3(v, OP_Seek, iIdxCur, 0, iCur); if( (pWInfo->wctrlFlags & WHERE_FORCE_TABLE) && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask) ){ int i; Table *pTab = pIdx->pTable; int *ai = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*(pTab->nCol+1)); if( ai ){ ai[0] = pTab->nCol; for(i=0; i<pIdx->nColumn-1; i++){ assert( pIdx->aiColumn[i]<pTab->nCol ); if( pIdx->aiColumn[i]>=0 ) ai[pIdx->aiColumn[i]+1] = i+1; } sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY); } } } /* ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. */ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( WhereInfo *pWInfo, /* Complete information about the WHERE clause */ |
︙ | ︙ | |||
120982 120983 120984 120985 120986 120987 120988 | /* Seek the table cursor, if required */ disableTerm(pLevel, pRangeStart); disableTerm(pLevel, pRangeEnd); if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ | > | | | < | | 121337 121338 121339 121340 121341 121342 121343 121344 121345 121346 121347 121348 121349 121350 121351 121352 121353 121354 121355 121356 121357 121358 | /* Seek the table cursor, if required */ disableTerm(pLevel, pRangeStart); disableTerm(pLevel, pRangeEnd); if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ if( pWInfo->eOnePass!=ONEPASS_OFF ){ iRowidReg = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg); VdbeCoverage(v); }else{ codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur); } }else if( iCur!=iIdxCur ){ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol); for(j=0; j<pPk->nKeyCol; j++){ k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j); |
︙ | ︙ | |||
121158 121159 121160 121161 121162 121163 121164 | */ if( pWC->nTerm>1 ){ int iTerm; for(iTerm=0; iTerm<pWC->nTerm; iTerm++){ Expr *pExpr = pWC->a[iTerm].pExpr; if( &pWC->a[iTerm] == pTerm ) continue; if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; | | > > | 121513 121514 121515 121516 121517 121518 121519 121520 121521 121522 121523 121524 121525 121526 121527 121528 121529 | */ if( pWC->nTerm>1 ){ int iTerm; for(iTerm=0; iTerm<pWC->nTerm; iTerm++){ Expr *pExpr = pWC->a[iTerm].pExpr; if( &pWC->a[iTerm] == pTerm ) continue; if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); testcase( pWC->a[iTerm].wtFlags & TERM_CODED ); if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue; if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); pExpr = sqlite3ExprDup(db, pExpr, 0); pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr); } if( pAndExpr ){ pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr, 0); |
︙ | ︙ | |||
121498 121499 121500 121501 121502 121503 121504 | static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ WhereTerm *pTerm; int idx; testcase( wtFlags & TERM_VIRTUAL ); if( pWC->nTerm>=pWC->nSlot ){ WhereTerm *pOld = pWC->a; sqlite3 *db = pWC->pWInfo->pParse->db; | | | 121855 121856 121857 121858 121859 121860 121861 121862 121863 121864 121865 121866 121867 121868 121869 | static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ WhereTerm *pTerm; int idx; testcase( wtFlags & TERM_VIRTUAL ); if( pWC->nTerm>=pWC->nSlot ){ WhereTerm *pOld = pWC->a; sqlite3 *db = pWC->pWInfo->pParse->db; pWC->a = sqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 ); if( pWC->a==0 ){ if( wtFlags & TERM_DYNAMIC ){ sqlite3ExprDelete(db, p); } pWC->a = pOld; return 0; } |
︙ | ︙ | |||
121983 121984 121985 121986 121987 121988 121989 | indexable = ~(Bitmask)0; chngToIN = ~(Bitmask)0; for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){ if( (pOrTerm->eOperator & WO_SINGLE)==0 ){ WhereAndInfo *pAndInfo; assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 ); chngToIN = 0; | | < | 122340 122341 122342 122343 122344 122345 122346 122347 122348 122349 122350 122351 122352 122353 122354 122355 122356 122357 122358 122359 122360 122361 122362 122363 122364 122365 122366 122367 | indexable = ~(Bitmask)0; chngToIN = ~(Bitmask)0; for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){ if( (pOrTerm->eOperator & WO_SINGLE)==0 ){ WhereAndInfo *pAndInfo; assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 ); chngToIN = 0; pAndInfo = sqlite3DbMallocRawNN(db, sizeof(*pAndInfo)); if( pAndInfo ){ WhereClause *pAndWC; WhereTerm *pAndTerm; int j; Bitmask b = 0; pOrTerm->u.pAndInfo = pAndInfo; pOrTerm->wtFlags |= TERM_ANDINFO; pOrTerm->eOperator = WO_AND; pAndWC = &pAndInfo->wc; sqlite3WhereClauseInit(pAndWC, pWC->pWInfo); sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND); sqlite3WhereExprAnalyze(pSrc, pAndWC); pAndWC->pOuter = pWC; if( !db->mallocFailed ){ for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){ assert( pAndTerm->pExpr ); if( allowedOp(pAndTerm->pExpr->op) ){ b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor); } } |
︙ | ︙ | |||
123740 123741 123742 123743 123744 123745 123746 | TRACE_IDX_INPUTS(p); rc = pVtab->pModule->xBestIndex(pVtab, p); TRACE_IDX_OUTPUTS(p); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ){ | | | 124096 124097 124098 124099 124100 124101 124102 124103 124104 124105 124106 124107 124108 124109 124110 | TRACE_IDX_INPUTS(p); rc = pVtab->pModule->xBestIndex(pVtab, p); TRACE_IDX_OUTPUTS(p); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ){ sqlite3OomFault(pParse->db); }else if( !pVtab->zErrMsg ){ sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc)); }else{ sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg); } } sqlite3_free(pVtab->zErrMsg); |
︙ | ︙ | |||
124532 124533 124534 124535 124536 124537 124538 | /* ** Increase the memory allocation for pLoop->aLTerm[] to be at least n. */ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){ WhereTerm **paNew; if( p->nLSlot>=n ) return SQLITE_OK; n = (n+7)&~7; | | | 124888 124889 124890 124891 124892 124893 124894 124895 124896 124897 124898 124899 124900 124901 124902 | /* ** Increase the memory allocation for pLoop->aLTerm[] to be at least n. */ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){ WhereTerm **paNew; if( p->nLSlot>=n ) return SQLITE_OK; n = (n+7)&~7; paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n); if( paNew==0 ) return SQLITE_NOMEM; memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot); if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm); p->aLTerm = paNew; p->nLSlot = n; return SQLITE_OK; } |
︙ | ︙ | |||
124829 124830 124831 124832 124833 124834 124835 | } sqlite3DebugPrintf(" add: "); whereLoopPrint(pTemplate, pBuilder->pWC); } #endif if( p==0 ){ /* Allocate a new WhereLoop to add to the end of the list */ | | | 125185 125186 125187 125188 125189 125190 125191 125192 125193 125194 125195 125196 125197 125198 125199 | } sqlite3DebugPrintf(" add: "); whereLoopPrint(pTemplate, pBuilder->pWC); } #endif if( p==0 ){ /* Allocate a new WhereLoop to add to the end of the list */ *ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop)); if( p==0 ) return SQLITE_NOMEM; whereLoopInit(p); p->pNextLoop = 0; }else{ /* We will be overwriting WhereLoop p[]. But before we do, first ** go through the rest of the list and delete any other entries besides ** p[] that are also supplated by pTemplate */ |
︙ | ︙ | |||
126326 126327 126328 126329 126330 126331 126332 | }else{ nOrderBy = pWInfo->pOrderBy->nExpr; } /* Allocate and initialize space for aTo, aFrom and aSortCost[] */ nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2; nSpace += sizeof(LogEst) * nOrderBy; | | | 126682 126683 126684 126685 126686 126687 126688 126689 126690 126691 126692 126693 126694 126695 126696 | }else{ nOrderBy = pWInfo->pOrderBy->nExpr; } /* Allocate and initialize space for aTo, aFrom and aSortCost[] */ nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2; nSpace += sizeof(LogEst) * nOrderBy; pSpace = sqlite3DbMallocRawNN(db, nSpace); if( pSpace==0 ) return SQLITE_NOMEM; aTo = (WherePath*)pSpace; aFrom = aTo+mxChoice; memset(aFrom, 0, sizeof(aFrom[0])); pX = (WhereLoop**)(aFrom+mxChoice); for(ii=mxChoice*2, pFrom=aTo; ii>0; ii--, pFrom++, pX += nLoop){ pFrom->aLoop = pX; |
︙ | ︙ | |||
126811 126812 126813 126814 126815 126816 126817 | WhereLoopBuilder sWLB; /* The WhereLoop builder */ WhereMaskSet *pMaskSet; /* The expression mask set */ WhereLevel *pLevel; /* A single level in pWInfo->a[] */ WhereLoop *pLoop; /* Pointer to a single WhereLoop object */ int ii; /* Loop counter */ sqlite3 *db; /* Database connection */ int rc; /* Return code */ | | | 127167 127168 127169 127170 127171 127172 127173 127174 127175 127176 127177 127178 127179 127180 127181 | WhereLoopBuilder sWLB; /* The WhereLoop builder */ WhereMaskSet *pMaskSet; /* The expression mask set */ WhereLevel *pLevel; /* A single level in pWInfo->a[] */ WhereLoop *pLoop; /* Pointer to a single WhereLoop object */ int ii; /* Loop counter */ sqlite3 *db; /* Database connection */ int rc; /* Return code */ u8 bFordelete = 0; /* OPFLAG_FORDELETE or zero, as appropriate */ assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || ( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 )); /* Variable initialization */ |
︙ | ︙ | |||
127056 127057 127058 127059 127060 127061 127062 | } } WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; /* If the caller is an UPDATE or DELETE statement that is requesting ** to use a one-pass algorithm, determine if this is appropriate. | < < > | | | | 127412 127413 127414 127415 127416 127417 127418 127419 127420 127421 127422 127423 127424 127425 127426 127427 127428 127429 127430 127431 127432 127433 127434 | } } WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; /* If the caller is an UPDATE or DELETE statement that is requesting ** to use a one-pass algorithm, determine if this is appropriate. */ assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 ); if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){ int wsFlags = pWInfo->a[0].pWLoop->wsFlags; int bOnerow = (wsFlags & WHERE_ONEROW)!=0; if( bOnerow || ((wctrlFlags & WHERE_ONEPASS_MULTIROW)!=0 && 0==(wsFlags & WHERE_VIRTUALTABLE)) ){ pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){ bFordelete = OPFLAG_FORDELETE; } pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY); } |
︙ | ︙ | |||
127509 127510 127511 127512 127513 127514 127515 127516 127517 127518 127519 127520 127521 127522 | struct TrigEvent { int a; IdList * b; }; /* ** An instance of this structure holds the ATTACH key and the key type. */ struct AttachKey { int type; Token key; }; /* ** For a compound SELECT statement, make sure p->pPrior->pNext==p for ** all elements in the list. And make sure list length does not exceed ** SQLITE_LIMIT_COMPOUND_SELECT. */ static void parserDoubleLinkSelect(Parse *pParse, Select *p){ | > > > > > > > > > | 127864 127865 127866 127867 127868 127869 127870 127871 127872 127873 127874 127875 127876 127877 127878 127879 127880 127881 127882 127883 127884 127885 127886 | struct TrigEvent { int a; IdList * b; }; /* ** An instance of this structure holds the ATTACH key and the key type. */ struct AttachKey { int type; Token key; }; /* ** Disable lookaside memory allocation for objects that might be ** shared across database connections. */ static void disableLookaside(Parse *pParse){ pParse->disableLookaside++; pParse->db->lookaside.bDisable++; } /* ** For a compound SELECT statement, make sure p->pPrior->pNext==p for ** all elements in the list. And make sure list length does not exceed ** SQLITE_LIMIT_COMPOUND_SELECT. */ static void parserDoubleLinkSelect(Parse *pParse, Select *p){ |
︙ | ︙ | |||
127591 127592 127593 127594 127595 127596 127597 | pOut->zEnd = &pPostOp->z[pPostOp->n]; } /* A routine to convert a binary TK_IS or TK_ISNOT expression into a ** unary TK_ISNULL or TK_NOTNULL expression. */ static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){ sqlite3 *db = pParse->db; | | | 127955 127956 127957 127958 127959 127960 127961 127962 127963 127964 127965 127966 127967 127968 127969 | pOut->zEnd = &pPostOp->z[pPostOp->n]; } /* A routine to convert a binary TK_IS or TK_ISNOT expression into a ** unary TK_ISNULL or TK_NOTNULL expression. */ static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){ sqlite3 *db = pParse->db; if( pA && pY && pY->op==TK_NULL ){ pA->op = (u8)op; sqlite3ExprDelete(db, pA->pRight); pA->pRight = 0; } } /* Construct an expression node for a unary prefix operator |
︙ | ︙ | |||
129633 129634 129635 129636 129637 129638 129639 | case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy4,0,0,yymsp[-2].minor.yy4); } break; case 27: /* createkw ::= CREATE */ { | | | 129997 129998 129999 130000 130001 130002 130003 130004 130005 130006 130007 130008 130009 130010 130011 | case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy4,0,0,yymsp[-2].minor.yy4); } break; case 27: /* createkw ::= CREATE */ { disableLookaside(pParse); yygotominor.yy0 = yymsp[0].minor.yy0; } break; case 28: /* ifnotexists ::= */ case 31: /* temp ::= */ yytestcase(yyruleno==31); case 34: /* table_options ::= */ yytestcase(yyruleno==34); case 68: /* autoinc ::= */ yytestcase(yyruleno==68); |
︙ | ︙ | |||
130715 130716 130717 130718 130719 130720 130721 | case 306: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */ { sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0); } break; case 307: /* add_column_fullname ::= fullname */ { | | | 131079 131080 131081 131082 131083 131084 131085 131086 131087 131088 131089 131090 131091 131092 131093 | case 306: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */ { sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0); } break; case 307: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy259); } break; case 310: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; case 311: /* cmd ::= create_vtab LP vtabarglist RP */ |
︙ | ︙ | |||
131095 131096 131097 131098 131099 131100 131101 131102 | ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. */ /* #include "sqliteInt.h" */ /* #include <stdlib.h> */ /* | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > | > | 131459 131460 131461 131462 131463 131464 131465 131466 131467 131468 131469 131470 131471 131472 131473 131474 131475 131476 131477 131478 131479 131480 131481 131482 131483 131484 131485 131486 131487 131488 131489 131490 131491 131492 131493 131494 131495 131496 131497 131498 131499 131500 131501 131502 131503 131504 131505 131506 131507 131508 131509 131510 131511 131512 131513 131514 131515 131516 131517 131518 131519 131520 131521 131522 131523 131524 131525 131526 131527 131528 131529 131530 131531 131532 131533 131534 131535 131536 131537 131538 131539 131540 131541 131542 131543 131544 131545 131546 131547 131548 131549 131550 131551 131552 131553 131554 131555 131556 131557 131558 | ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. */ /* #include "sqliteInt.h" */ /* #include <stdlib.h> */ /* Character classes for tokenizing ** ** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented ** using a lookup table, whereas a switch() directly on c uses a binary search. ** The lookup table is much faster. To maximize speed, and to ensure that ** a lookup table is used, all of the classes need to be small integers and ** all of them need to be used within the switch. */ #define CC_X 0 /* The letter 'x', or start of BLOB literal */ #define CC_KYWD 1 /* Alphabetics or '_'. Usable in a keyword */ #define CC_ID 2 /* unicode characters usable in IDs */ #define CC_DIGIT 3 /* Digits */ #define CC_DOLLAR 4 /* '$' */ #define CC_VARALPHA 5 /* '@', '#', ':'. Alphabetic SQL variables */ #define CC_VARNUM 6 /* '?'. Numeric SQL variables */ #define CC_SPACE 7 /* Space characters */ #define CC_QUOTE 8 /* '"', '\'', or '`'. String literals, quoted ids */ #define CC_QUOTE2 9 /* '['. [...] style quoted ids */ #define CC_PIPE 10 /* '|'. Bitwise OR or concatenate */ #define CC_MINUS 11 /* '-'. Minus or SQL-style comment */ #define CC_LT 12 /* '<'. Part of < or <= or <> */ #define CC_GT 13 /* '>'. Part of > or >= */ #define CC_EQ 14 /* '='. Part of = or == */ #define CC_BANG 15 /* '!'. Part of != */ #define CC_SLASH 16 /* '/'. / or c-style comment */ #define CC_LP 17 /* '(' */ #define CC_RP 18 /* ')' */ #define CC_SEMI 19 /* ';' */ #define CC_PLUS 20 /* '+' */ #define CC_STAR 21 /* '*' */ #define CC_PERCENT 22 /* '%' */ #define CC_COMMA 23 /* ',' */ #define CC_AND 24 /* '&' */ #define CC_TILDA 25 /* '~' */ #define CC_DOT 26 /* '.' */ #define CC_ILLEGAL 27 /* Illegal character */ static const unsigned char aiClass[] = { #ifdef SQLITE_ASCII /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ /* 0x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27, /* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, /* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16, /* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6, /* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 9, 27, 27, 27, 1, /* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 10, 27, 25, 27, /* 8x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 9x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* Ax */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* Bx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* Cx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* Dx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* Ex */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* Fx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 #endif #ifdef SQLITE_EBCDIC /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ /* 0x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 7, 7, 27, 27, /* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, /* 2x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, /* 3x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, /* 4x */ 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 12, 17, 20, 10, /* 5x */ 24, 27, 27, 27, 27, 27, 27, 27, 27, 27, 15, 4, 21, 18, 19, 27, /* 6x */ 11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22, 1, 13, 7, /* 7x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 8, 5, 5, 5, 8, 14, 8, /* 8x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, /* 9x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, /* 9x */ 25, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, /* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 9, 27, 27, 27, 27, 27, /* Cx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, /* Dx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, /* Ex */ 27, 27, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, /* Fx */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 27, 27, 27, 27, 27, 27, #endif }; /* ** The charMap() macro maps alphabetic characters (only) into their ** lower-case ASCII equivalent. On ASCII machines, this is just ** an upper-to-lower case map. On EBCDIC machines we also need ** to adjust the encoding. The mapping is only valid for alphabetics ** which are the only characters for which this feature is used. ** ** Used by keywordhash.h */ #ifdef SQLITE_ASCII # define charMap(X) sqlite3UpperToLower[(unsigned char)X] #endif #ifdef SQLITE_EBCDIC # define charMap(X) ebcdicToAscii[(unsigned char)X] const unsigned char ebcdicToAscii[] = { |
︙ | ︙ | |||
131134 131135 131136 131137 131138 131139 131140 | /* ** The sqlite3KeywordCode function looks up an identifier to determine if ** it is a keyword. If it is a keyword, the token code of that keyword is ** returned. If the input is not a keyword, TK_ID is returned. ** ** The implementation of this routine was generated by a program, | | | 131578 131579 131580 131581 131582 131583 131584 131585 131586 131587 131588 131589 131590 131591 131592 | /* ** The sqlite3KeywordCode function looks up an identifier to determine if ** it is a keyword. If it is a keyword, the token code of that keyword is ** returned. If the input is not a keyword, TK_ID is returned. ** ** The implementation of this routine was generated by a program, ** mkkeywordhash.c, located in the tool subdirectory of the distribution. ** The output of the mkkeywordhash.c program is written into a file ** named keywordhash.h and then included into this source file by ** the #include below. */ /************** Include keywordhash.h in the middle of tokenize.c ************/ /************** Begin file keywordhash.h *************************************/ /***** This file contains automatically generated code ****** |
︙ | ︙ | |||
131275 131276 131277 131278 131279 131280 131281 | TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, TK_IS, TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW, TK_LIKE_KW, TK_BY, TK_IF, TK_ISNULL, TK_ORDER, TK_RESTRICT, TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_INITIALLY, TK_ALL, }; | | > | | > > | > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | 131719 131720 131721 131722 131723 131724 131725 131726 131727 131728 131729 131730 131731 131732 131733 131734 131735 131736 131737 131738 131739 131740 131741 131742 131743 131744 131745 131746 131747 131748 131749 131750 131751 131752 131753 131754 131755 131756 131757 131758 131759 131760 131761 131762 131763 131764 131765 131766 131767 131768 131769 131770 131771 131772 131773 131774 131775 131776 131777 131778 131779 131780 131781 131782 131783 131784 131785 131786 131787 131788 131789 131790 131791 131792 131793 131794 131795 131796 131797 131798 131799 131800 131801 131802 131803 131804 131805 131806 131807 131808 131809 131810 131811 131812 131813 131814 131815 131816 131817 131818 131819 131820 131821 131822 131823 131824 131825 131826 131827 131828 131829 131830 131831 131832 131833 131834 131835 131836 131837 131838 131839 131840 131841 131842 131843 131844 131845 131846 131847 131848 131849 131850 131851 131852 131853 131854 131855 131856 131857 131858 131859 131860 131861 131862 131863 131864 131865 131866 131867 131868 131869 131870 131871 131872 131873 | TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, TK_IS, TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW, TK_LIKE_KW, TK_BY, TK_IF, TK_ISNULL, TK_ORDER, TK_RESTRICT, TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_INITIALLY, TK_ALL, }; int i, j; const char *zKW; if( n>=2 ){ i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) % 127; for(i=((int)aHash[i])-1; i>=0; i=((int)aNext[i])-1){ if( aLen[i]!=n ) continue; j = 0; zKW = &zText[aOffset[i]]; #ifdef SQLITE_ASCII while( j<n && (z[j]&~0x20)==zKW[j] ){ j++; } #endif #ifdef SQLITE_EBCDIC while( j<n && toupper(z[j])==zKW[j] ){ j++; } #endif if( j<n ) continue; testcase( i==0 ); /* REINDEX */ testcase( i==1 ); /* INDEXED */ testcase( i==2 ); /* INDEX */ testcase( i==3 ); /* DESC */ testcase( i==4 ); /* ESCAPE */ testcase( i==5 ); /* EACH */ testcase( i==6 ); /* CHECK */ testcase( i==7 ); /* KEY */ testcase( i==8 ); /* BEFORE */ testcase( i==9 ); /* FOREIGN */ testcase( i==10 ); /* FOR */ testcase( i==11 ); /* IGNORE */ testcase( i==12 ); /* REGEXP */ testcase( i==13 ); /* EXPLAIN */ testcase( i==14 ); /* INSTEAD */ testcase( i==15 ); /* ADD */ testcase( i==16 ); /* DATABASE */ testcase( i==17 ); /* AS */ testcase( i==18 ); /* SELECT */ testcase( i==19 ); /* TABLE */ testcase( i==20 ); /* LEFT */ testcase( i==21 ); /* THEN */ testcase( i==22 ); /* END */ testcase( i==23 ); /* DEFERRABLE */ testcase( i==24 ); /* ELSE */ testcase( i==25 ); /* EXCEPT */ testcase( i==26 ); /* TRANSACTION */ testcase( i==27 ); /* ACTION */ testcase( i==28 ); /* ON */ testcase( i==29 ); /* NATURAL */ testcase( i==30 ); /* ALTER */ testcase( i==31 ); /* RAISE */ testcase( i==32 ); /* EXCLUSIVE */ testcase( i==33 ); /* EXISTS */ testcase( i==34 ); /* SAVEPOINT */ testcase( i==35 ); /* INTERSECT */ testcase( i==36 ); /* TRIGGER */ testcase( i==37 ); /* REFERENCES */ testcase( i==38 ); /* CONSTRAINT */ testcase( i==39 ); /* INTO */ testcase( i==40 ); /* OFFSET */ testcase( i==41 ); /* OF */ testcase( i==42 ); /* SET */ testcase( i==43 ); /* TEMPORARY */ testcase( i==44 ); /* TEMP */ testcase( i==45 ); /* OR */ testcase( i==46 ); /* UNIQUE */ testcase( i==47 ); /* QUERY */ testcase( i==48 ); /* WITHOUT */ testcase( i==49 ); /* WITH */ testcase( i==50 ); /* OUTER */ testcase( i==51 ); /* RELEASE */ testcase( i==52 ); /* ATTACH */ testcase( i==53 ); /* HAVING */ testcase( i==54 ); /* GROUP */ testcase( i==55 ); /* UPDATE */ testcase( i==56 ); /* BEGIN */ testcase( i==57 ); /* INNER */ testcase( i==58 ); /* RECURSIVE */ testcase( i==59 ); /* BETWEEN */ testcase( i==60 ); /* NOTNULL */ testcase( i==61 ); /* NOT */ testcase( i==62 ); /* NO */ testcase( i==63 ); /* NULL */ testcase( i==64 ); /* LIKE */ testcase( i==65 ); /* CASCADE */ testcase( i==66 ); /* ASC */ testcase( i==67 ); /* DELETE */ testcase( i==68 ); /* CASE */ testcase( i==69 ); /* COLLATE */ testcase( i==70 ); /* CREATE */ testcase( i==71 ); /* CURRENT_DATE */ testcase( i==72 ); /* DETACH */ testcase( i==73 ); /* IMMEDIATE */ testcase( i==74 ); /* JOIN */ testcase( i==75 ); /* INSERT */ testcase( i==76 ); /* MATCH */ testcase( i==77 ); /* PLAN */ testcase( i==78 ); /* ANALYZE */ testcase( i==79 ); /* PRAGMA */ testcase( i==80 ); /* ABORT */ testcase( i==81 ); /* VALUES */ testcase( i==82 ); /* VIRTUAL */ testcase( i==83 ); /* LIMIT */ testcase( i==84 ); /* WHEN */ testcase( i==85 ); /* WHERE */ testcase( i==86 ); /* RENAME */ testcase( i==87 ); /* AFTER */ testcase( i==88 ); /* REPLACE */ testcase( i==89 ); /* AND */ testcase( i==90 ); /* DEFAULT */ testcase( i==91 ); /* AUTOINCREMENT */ testcase( i==92 ); /* TO */ testcase( i==93 ); /* IN */ testcase( i==94 ); /* CAST */ testcase( i==95 ); /* COLUMN */ testcase( i==96 ); /* COMMIT */ testcase( i==97 ); /* CONFLICT */ testcase( i==98 ); /* CROSS */ testcase( i==99 ); /* CURRENT_TIMESTAMP */ testcase( i==100 ); /* CURRENT_TIME */ testcase( i==101 ); /* PRIMARY */ testcase( i==102 ); /* DEFERRED */ testcase( i==103 ); /* DISTINCT */ testcase( i==104 ); /* IS */ testcase( i==105 ); /* DROP */ testcase( i==106 ); /* FAIL */ testcase( i==107 ); /* FROM */ testcase( i==108 ); /* FULL */ testcase( i==109 ); /* GLOB */ testcase( i==110 ); /* BY */ testcase( i==111 ); /* IF */ testcase( i==112 ); /* ISNULL */ testcase( i==113 ); /* ORDER */ testcase( i==114 ); /* RESTRICT */ testcase( i==115 ); /* RIGHT */ testcase( i==116 ); /* ROLLBACK */ testcase( i==117 ); /* ROW */ testcase( i==118 ); /* UNION */ testcase( i==119 ); /* USING */ testcase( i==120 ); /* VACUUM */ testcase( i==121 ); /* VIEW */ testcase( i==122 ); /* INITIALLY */ testcase( i==123 ); /* ALL */ *pType = aCode[i]; break; } } return n; } SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){ int id = TK_ID; keywordCode((char*)z, n, &id); |
︙ | ︙ | |||
131467 131468 131469 131470 131471 131472 131473 | /* Make the IdChar function accessible from ctime.c */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); } #endif /* | | | > > | | | | | | | | | | | | | | | | | | < < | 131920 131921 131922 131923 131924 131925 131926 131927 131928 131929 131930 131931 131932 131933 131934 131935 131936 131937 131938 131939 131940 131941 131942 131943 131944 131945 131946 131947 131948 131949 131950 131951 131952 131953 131954 131955 131956 131957 131958 131959 131960 131961 131962 131963 131964 131965 131966 131967 131968 131969 131970 131971 131972 131973 131974 131975 131976 131977 131978 131979 131980 131981 131982 131983 131984 131985 131986 131987 131988 131989 131990 131991 131992 131993 131994 131995 131996 131997 131998 131999 132000 132001 132002 132003 132004 132005 132006 132007 132008 132009 132010 132011 132012 132013 132014 132015 132016 132017 132018 132019 132020 132021 132022 132023 132024 132025 132026 132027 132028 132029 132030 132031 132032 132033 132034 132035 132036 132037 132038 132039 132040 132041 132042 132043 132044 132045 132046 132047 132048 132049 132050 132051 132052 132053 132054 132055 132056 | /* Make the IdChar function accessible from ctime.c */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); } #endif /* ** Return the length (in bytes) of the token that begins at z[0]. ** Store the token type in *tokenType before returning. */ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ int i, c; switch( aiClass[*z] ){ /* Switch on the character-class of the first byte ** of the token. See the comment on the CC_ defines ** above. */ case CC_SPACE: { testcase( z[0]==' ' ); testcase( z[0]=='\t' ); testcase( z[0]=='\n' ); testcase( z[0]=='\f' ); testcase( z[0]=='\r' ); for(i=1; sqlite3Isspace(z[i]); i++){} *tokenType = TK_SPACE; return i; } case CC_MINUS: { if( z[1]=='-' ){ for(i=2; (c=z[i])!=0 && c!='\n'; i++){} *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ return i; } *tokenType = TK_MINUS; return 1; } case CC_LP: { *tokenType = TK_LP; return 1; } case CC_RP: { *tokenType = TK_RP; return 1; } case CC_SEMI: { *tokenType = TK_SEMI; return 1; } case CC_PLUS: { *tokenType = TK_PLUS; return 1; } case CC_STAR: { *tokenType = TK_STAR; return 1; } case CC_SLASH: { if( z[1]!='*' || z[2]==0 ){ *tokenType = TK_SLASH; return 1; } for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){} if( c ) i++; *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ return i; } case CC_PERCENT: { *tokenType = TK_REM; return 1; } case CC_EQ: { *tokenType = TK_EQ; return 1 + (z[1]=='='); } case CC_LT: { if( (c=z[1])=='=' ){ *tokenType = TK_LE; return 2; }else if( c=='>' ){ *tokenType = TK_NE; return 2; }else if( c=='<' ){ *tokenType = TK_LSHIFT; return 2; }else{ *tokenType = TK_LT; return 1; } } case CC_GT: { if( (c=z[1])=='=' ){ *tokenType = TK_GE; return 2; }else if( c=='>' ){ *tokenType = TK_RSHIFT; return 2; }else{ *tokenType = TK_GT; return 1; } } case CC_BANG: { if( z[1]!='=' ){ *tokenType = TK_ILLEGAL; return 2; }else{ *tokenType = TK_NE; return 2; } } case CC_PIPE: { if( z[1]!='|' ){ *tokenType = TK_BITOR; return 1; }else{ *tokenType = TK_CONCAT; return 2; } } case CC_COMMA: { *tokenType = TK_COMMA; return 1; } case CC_AND: { *tokenType = TK_BITAND; return 1; } case CC_TILDA: { *tokenType = TK_BITNOT; return 1; } case CC_QUOTE: { int delim = z[0]; testcase( delim=='`' ); testcase( delim=='\'' ); testcase( delim=='"' ); for(i=1; (c=z[i])!=0; i++){ if( c==delim ){ if( z[i+1]==delim ){ |
︙ | ︙ | |||
131614 131615 131616 131617 131618 131619 131620 | *tokenType = TK_ID; return i+1; }else{ *tokenType = TK_ILLEGAL; return i; } } | | | < | 132067 132068 132069 132070 132071 132072 132073 132074 132075 132076 132077 132078 132079 132080 132081 132082 132083 132084 132085 132086 132087 132088 132089 132090 132091 132092 | *tokenType = TK_ID; return i+1; }else{ *tokenType = TK_ILLEGAL; return i; } } case CC_DOT: { #ifndef SQLITE_OMIT_FLOATING_POINT if( !sqlite3Isdigit(z[1]) ) #endif { *tokenType = TK_DOT; return 1; } /* If the next character is a digit, this is a floating point ** number that begins with ".". Fall thru into the next case */ } case CC_DIGIT: { testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); testcase( z[0]=='9' ); *tokenType = TK_INTEGER; #ifndef SQLITE_OMIT_HEX_INTEGER if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ |
︙ | ︙ | |||
131661 131662 131663 131664 131665 131666 131667 | #endif while( IdChar(z[i]) ){ *tokenType = TK_ILLEGAL; i++; } return i; } | | | < | < < | < | 132113 132114 132115 132116 132117 132118 132119 132120 132121 132122 132123 132124 132125 132126 132127 132128 132129 132130 132131 132132 132133 132134 132135 132136 132137 132138 | #endif while( IdChar(z[i]) ){ *tokenType = TK_ILLEGAL; i++; } return i; } case CC_QUOTE2: { for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){} *tokenType = c==']' ? TK_ID : TK_ILLEGAL; return i; } case CC_VARNUM: { *tokenType = TK_VARIABLE; for(i=1; sqlite3Isdigit(z[i]); i++){} return i; } case CC_DOLLAR: case CC_VARALPHA: { int n = 0; testcase( z[0]=='$' ); testcase( z[0]=='@' ); testcase( z[0]==':' ); testcase( z[0]=='#' ); *tokenType = TK_VARIABLE; for(i=1; (c=z[i])!=0; i++){ if( IdChar(c) ){ n++; |
︙ | ︙ | |||
131705 131706 131707 131708 131709 131710 131711 131712 | }else{ break; } } if( n==0 ) *tokenType = TK_ILLEGAL; return i; } #ifndef SQLITE_OMIT_BLOB_LITERAL | > > > > > > > > > > > > | | > | < > | | < > | | > | | < | < < < | 132153 132154 132155 132156 132157 132158 132159 132160 132161 132162 132163 132164 132165 132166 132167 132168 132169 132170 132171 132172 132173 132174 132175 132176 132177 132178 132179 132180 132181 132182 132183 132184 132185 132186 132187 132188 132189 132190 132191 132192 132193 132194 132195 132196 132197 132198 132199 132200 132201 132202 132203 132204 132205 132206 132207 132208 132209 132210 132211 132212 132213 132214 132215 132216 132217 132218 132219 132220 132221 132222 132223 132224 132225 132226 132227 132228 132229 132230 132231 132232 132233 132234 132235 132236 132237 132238 132239 132240 132241 132242 132243 132244 132245 132246 132247 132248 132249 132250 132251 132252 132253 132254 132255 132256 132257 | }else{ break; } } if( n==0 ) *tokenType = TK_ILLEGAL; return i; } case CC_KYWD: { for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} if( IdChar(z[i]) ){ /* This token started out using characters that can appear in keywords, ** but z[i] is a character not allowed within keywords, so this must ** be an identifier instead */ i++; break; } *tokenType = TK_ID; return keywordCode((char*)z, i, tokenType); } #ifndef SQLITE_OMIT_BLOB_LITERAL case CC_X: { testcase( z[0]=='x' ); testcase( z[0]=='X' ); if( z[1]=='\'' ){ *tokenType = TK_BLOB; for(i=2; sqlite3Isxdigit(z[i]); i++){} if( z[i]!='\'' || i%2 ){ *tokenType = TK_ILLEGAL; while( z[i] && z[i]!='\'' ){ i++; } } if( z[i] ) i++; return i; } /* If it is not a BLOB literal, then it must be an ID, since no ** SQL keywords start with the letter 'x'. Fall through */ } #endif case CC_ID: { i = 1; break; } default: { *tokenType = TK_ILLEGAL; return 1; } } while( IdChar(z[i]) ){ i++; } *tokenType = TK_ID; return i; } /* ** Run the parser on the given SQL string. The parser structure is ** passed in. An SQLITE_ status code is returned. If an error occurs ** then an and attempt is made to write an error message into ** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that ** error message. */ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ int nErr = 0; /* Number of errors encountered */ int i; /* Loop counter */ void *pEngine; /* The LEMON-generated LALR(1) parser */ int tokenType; /* type of the next token */ int lastTokenParsed = -1; /* type of the previous token */ sqlite3 *db = pParse->db; /* The database connection */ int mxSqlLen; /* Max length of an SQL string */ assert( zSql!=0 ); mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; if( db->nVdbeActive==0 ){ db->u1.isInterrupted = 0; } pParse->rc = SQLITE_OK; pParse->zTail = zSql; i = 0; assert( pzErrMsg!=0 ); /* sqlite3ParserTrace(stdout, "parser: "); */ pEngine = sqlite3ParserAlloc(sqlite3Malloc); if( pEngine==0 ){ sqlite3OomFault(db); return SQLITE_NOMEM; } assert( pParse->pNewTable==0 ); assert( pParse->pNewTrigger==0 ); assert( pParse->nVar==0 ); assert( pParse->nzVar==0 ); assert( pParse->azVar==0 ); while( zSql[i]!=0 ){ assert( i>=0 ); pParse->sLastToken.z = &zSql[i]; pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType); i += pParse->sLastToken.n; if( i>mxSqlLen ){ pParse->rc = SQLITE_TOOBIG; break; } if( tokenType>=TK_SPACE ){ assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); if( db->u1.isInterrupted ){ pParse->rc = SQLITE_INTERRUPT; break; } if( tokenType==TK_ILLEGAL ){ sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &pParse->sLastToken); break; |
︙ | ︙ | |||
131820 131821 131822 131823 131824 131825 131826 | sqlite3_mutex_enter(sqlite3MallocMutex()); sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK, sqlite3ParserStackPeak(pEngine) ); sqlite3_mutex_leave(sqlite3MallocMutex()); #endif /* YYDEBUG */ sqlite3ParserFree(pEngine, sqlite3_free); | < | 132278 132279 132280 132281 132282 132283 132284 132285 132286 132287 132288 132289 132290 132291 | sqlite3_mutex_enter(sqlite3MallocMutex()); sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK, sqlite3ParserStackPeak(pEngine) ); sqlite3_mutex_leave(sqlite3MallocMutex()); #endif /* YYDEBUG */ sqlite3ParserFree(pEngine, sqlite3_free); if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM; } if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); } assert( pzErrMsg!=0 ); |
︙ | ︙ | |||
132961 132962 132963 132964 132965 132966 132967 | p = (LookasideSlot*)pStart; for(i=cnt-1; i>=0; i--){ p->pNext = db->lookaside.pFree; db->lookaside.pFree = p; p = (LookasideSlot*)&((u8*)p)[sz]; } db->lookaside.pEnd = p; | | | | 133418 133419 133420 133421 133422 133423 133424 133425 133426 133427 133428 133429 133430 133431 133432 133433 133434 133435 133436 133437 | p = (LookasideSlot*)pStart; for(i=cnt-1; i>=0; i--){ p->pNext = db->lookaside.pFree; db->lookaside.pFree = p; p = (LookasideSlot*)&((u8*)p)[sz]; } db->lookaside.pEnd = p; db->lookaside.bDisable = 0; db->lookaside.bMalloced = pBuf==0 ?1:0; }else{ db->lookaside.pStart = db; db->lookaside.pEnd = db; db->lookaside.bDisable = 1; db->lookaside.bMalloced = 0; } #endif /* SQLITE_OMIT_LOOKASIDE */ return SQLITE_OK; } /* |
︙ | ︙ | |||
134471 134472 134473 134474 134475 134476 134477 | z = sqlite3_value_text16(db->pErr); } /* A malloc() may have failed within the call to sqlite3_value_text16() ** above. If this is the case, then the db->mallocFailed flag needs to ** be cleared before returning. Do this directly, instead of via ** sqlite3ApiExit(), to avoid setting the database handle error message. */ | | | 134928 134929 134930 134931 134932 134933 134934 134935 134936 134937 134938 134939 134940 134941 134942 | z = sqlite3_value_text16(db->pErr); } /* A malloc() may have failed within the call to sqlite3_value_text16() ** above. If this is the case, then the db->mallocFailed flag needs to ** be cleared before returning. Do this directly, instead of via ** sqlite3ApiExit(), to avoid setting the database handle error message. */ sqlite3OomClear(db); } sqlite3_mutex_leave(db->mutex); return z; } #endif /* SQLITE_OMIT_UTF16 */ /* |
︙ | ︙ | |||
135109 135110 135111 135112 135113 135114 135115 | db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0); assert( db->pDfltColl!=0 ); /* Parse the filename/URI argument. */ db->openFlags = flags; rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); if( rc!=SQLITE_OK ){ | | | 135566 135567 135568 135569 135570 135571 135572 135573 135574 135575 135576 135577 135578 135579 135580 | db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0); assert( db->pDfltColl!=0 ); /* Parse the filename/URI argument. */ db->openFlags = flags; rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); sqlite3_free(zErrMsg); goto opendb_out; } /* Open the backend database driver */ rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, |
︙ | ︙ | |||
135829 135830 135831 135832 135833 135834 135835 | ** assert() is disabled, then the return value is zero. If X is ** false and assert() is enabled, then the assertion fires and the ** process aborts. If X is false and assert() is disabled, then the ** return value is zero. */ case SQLITE_TESTCTRL_ASSERT: { volatile int x = 0; | | | 136286 136287 136288 136289 136290 136291 136292 136293 136294 136295 136296 136297 136298 136299 136300 | ** assert() is disabled, then the return value is zero. If X is ** false and assert() is enabled, then the assertion fires and the ** process aborts. If X is false and assert() is disabled, then the ** return value is zero. */ case SQLITE_TESTCTRL_ASSERT: { volatile int x = 0; assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 ); rc = x; break; } /* ** sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, int X) |
︙ | ︙ | |||
146359 146360 146361 146362 146363 146364 146365 146366 146367 146368 146369 146370 146371 146372 146373 146374 146375 146376 146377 | pHash = (Fts3Hash *)sqlite3_user_data(context); zName = sqlite3_value_text(argv[0]); nName = sqlite3_value_bytes(argv[0])+1; if( argc==2 ){ void *pOld; int n = sqlite3_value_bytes(argv[1]); if( zName==0 || n!=sizeof(pPtr) ){ sqlite3_result_error(context, "argument type mismatch", -1); return; } pPtr = *(void **)sqlite3_value_blob(argv[1]); pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr); if( pOld==pPtr ){ sqlite3_result_error(context, "out of memory", -1); return; } | > > > > > > > | > | 146816 146817 146818 146819 146820 146821 146822 146823 146824 146825 146826 146827 146828 146829 146830 146831 146832 146833 146834 146835 146836 146837 146838 146839 146840 146841 146842 146843 146844 146845 146846 146847 146848 146849 146850 | pHash = (Fts3Hash *)sqlite3_user_data(context); zName = sqlite3_value_text(argv[0]); nName = sqlite3_value_bytes(argv[0])+1; if( argc==2 ){ #ifdef SQLITE_ENABLE_FTS3_TOKENIZER void *pOld; int n = sqlite3_value_bytes(argv[1]); if( zName==0 || n!=sizeof(pPtr) ){ sqlite3_result_error(context, "argument type mismatch", -1); return; } pPtr = *(void **)sqlite3_value_blob(argv[1]); pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr); if( pOld==pPtr ){ sqlite3_result_error(context, "out of memory", -1); return; } #else sqlite3_result_error(context, "fts3tokenize: " "disabled - rebuild with -DSQLITE_ENABLE_FTS3_TOKENIZER", -1 ); return; #endif /* SQLITE_ENABLE_FTS3_TOKENIZER */ }else { if( zName ){ pPtr = sqlite3Fts3HashFind(pHash, zName, nName); } if( !pPtr ){ char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName); sqlite3_result_error(context, zErr, -1); sqlite3_free(zErr); |
︙ | ︙ | |||
146620 146621 146622 146623 146624 146625 146626 146627 146628 146629 146630 146631 146632 146633 | sqlite3_result_error(context, zErr, -1); }else{ sqlite3_result_text(context, Tcl_GetString(pRet), -1, SQLITE_TRANSIENT); } Tcl_DecrRefCount(pRet); } static int registerTokenizer( sqlite3 *db, char *zName, const sqlite3_tokenizer_module *p ){ int rc; | > | 147085 147086 147087 147088 147089 147090 147091 147092 147093 147094 147095 147096 147097 147098 147099 | sqlite3_result_error(context, zErr, -1); }else{ sqlite3_result_text(context, Tcl_GetString(pRet), -1, SQLITE_TRANSIENT); } Tcl_DecrRefCount(pRet); } #ifdef SQLITE_ENABLE_FTS3_TOKENIZER static int registerTokenizer( sqlite3 *db, char *zName, const sqlite3_tokenizer_module *p ){ int rc; |
︙ | ︙ | |||
146641 146642 146643 146644 146645 146646 146647 146648 146649 146650 146651 146652 146653 146654 | sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); sqlite3_bind_blob(pStmt, 2, &p, sizeof(p), SQLITE_STATIC); sqlite3_step(pStmt); return sqlite3_finalize(pStmt); } static int queryTokenizer( sqlite3 *db, char *zName, const sqlite3_tokenizer_module **pp ){ | > > | 147107 147108 147109 147110 147111 147112 147113 147114 147115 147116 147117 147118 147119 147120 147121 147122 | sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); sqlite3_bind_blob(pStmt, 2, &p, sizeof(p), SQLITE_STATIC); sqlite3_step(pStmt); return sqlite3_finalize(pStmt); } #endif /* SQLITE_ENABLE_FTS3_TOKENIZER */ static int queryTokenizer( sqlite3 *db, char *zName, const sqlite3_tokenizer_module **pp ){ |
︙ | ︙ | |||
146712 146713 146714 146715 146716 146717 146718 146719 146720 146721 146722 146723 146724 146725 146726 146727 146728 146729 146730 | assert( p1==p2 ); rc = queryTokenizer(db, "nosuchtokenizer", &p2); assert( rc==SQLITE_ERROR ); assert( p2==0 ); assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") ); /* Test the storage function */ rc = registerTokenizer(db, "nosuchtokenizer", p1); assert( rc==SQLITE_OK ); rc = queryTokenizer(db, "nosuchtokenizer", &p2); assert( rc==SQLITE_OK ); assert( p2==p1 ); sqlite3_result_text(context, "ok", -1, SQLITE_STATIC); } #endif /* | > > | 147180 147181 147182 147183 147184 147185 147186 147187 147188 147189 147190 147191 147192 147193 147194 147195 147196 147197 147198 147199 147200 | assert( p1==p2 ); rc = queryTokenizer(db, "nosuchtokenizer", &p2); assert( rc==SQLITE_ERROR ); assert( p2==0 ); assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") ); /* Test the storage function */ #ifdef SQLITE_ENABLE_FTS3_TOKENIZER rc = registerTokenizer(db, "nosuchtokenizer", p1); assert( rc==SQLITE_OK ); rc = queryTokenizer(db, "nosuchtokenizer", &p2); assert( rc==SQLITE_OK ); assert( p2==p1 ); #endif sqlite3_result_text(context, "ok", -1, SQLITE_STATIC); } #endif /* |
︙ | ︙ | |||
164599 164600 164601 164602 164603 164604 164605 | char **pzErr ){ StatTable *pTab = 0; int rc = SQLITE_OK; int iDb; if( argc>=4 ){ | > > | | 165069 165070 165071 165072 165073 165074 165075 165076 165077 165078 165079 165080 165081 165082 165083 165084 165085 | char **pzErr ){ StatTable *pTab = 0; int rc = SQLITE_OK; int iDb; if( argc>=4 ){ Token nm; sqlite3TokenInit(&nm, (char*)argv[3]); iDb = sqlite3FindDb(db, &nm); if( iDb<0 ){ *pzErr = sqlite3_mprintf("no such database: %s", argv[3]); return SQLITE_ERROR; } }else{ iDb = 0; } |
︙ | ︙ | |||
165429 165430 165431 165432 165433 165434 165435 | ** string. */ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ u32 i; if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return; p->zBuf[p->nUsed++] = '"'; for(i=0; i<N; i++){ | | > > > > > > > > > > > > > > > > > > > > > > > | 165901 165902 165903 165904 165905 165906 165907 165908 165909 165910 165911 165912 165913 165914 165915 165916 165917 165918 165919 165920 165921 165922 165923 165924 165925 165926 165927 165928 165929 165930 165931 165932 165933 165934 165935 165936 165937 165938 165939 165940 165941 | ** string. */ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ u32 i; if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return; p->zBuf[p->nUsed++] = '"'; for(i=0; i<N; i++){ unsigned char c = ((unsigned const char*)zIn)[i]; if( c=='"' || c=='\\' ){ json_simple_escape: if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; p->zBuf[p->nUsed++] = '\\'; }else if( c<=0x1f ){ static const char aSpecial[] = { 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; assert( sizeof(aSpecial)==32 ); assert( aSpecial['\b']=='b' ); assert( aSpecial['\f']=='f' ); assert( aSpecial['\n']=='n' ); assert( aSpecial['\r']=='r' ); assert( aSpecial['\t']=='t' ); if( aSpecial[c] ){ c = aSpecial[c]; goto json_simple_escape; } if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return; p->zBuf[p->nUsed++] = '\\'; p->zBuf[p->nUsed++] = 'u'; p->zBuf[p->nUsed++] = '0'; p->zBuf[p->nUsed++] = '0'; p->zBuf[p->nUsed++] = '0' + (c>>4); c = "0123456789abcdef"[c&0xf]; } p->zBuf[p->nUsed++] = c; } p->zBuf[p->nUsed++] = '"'; assert( p->nUsed<p->nAlloc ); } |
︙ | ︙ | |||
165473 165474 165475 165476 165477 165478 165479 | jsonAppendString(p, z, n); } break; } default: { if( p->bErr==0 ){ sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); | | | 165968 165969 165970 165971 165972 165973 165974 165975 165976 165977 165978 165979 165980 165981 165982 | jsonAppendString(p, z, n); } break; } default: { if( p->bErr==0 ){ sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); p->bErr = 2; jsonReset(p); } break; } } } |
︙ | ︙ | |||
166701 166702 166703 166704 166705 166706 166707 | static void jsonArrayFinal(sqlite3_context *ctx){ JsonString *pStr; pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ pStr->pCtx = ctx; jsonAppendChar(pStr, ']'); if( pStr->bErr ){ | | | 167196 167197 167198 167199 167200 167201 167202 167203 167204 167205 167206 167207 167208 167209 167210 | static void jsonArrayFinal(sqlite3_context *ctx){ JsonString *pStr; pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ pStr->pCtx = ctx; jsonAppendChar(pStr, ']'); if( pStr->bErr ){ if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); assert( pStr->bStatic ); }else{ sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); pStr->bStatic = 1; } }else{ |
︙ | ︙ | |||
166749 166750 166751 166752 166753 166754 166755 | } static void jsonObjectFinal(sqlite3_context *ctx){ JsonString *pStr; pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ jsonAppendChar(pStr, '}'); if( pStr->bErr ){ | | | 167244 167245 167246 167247 167248 167249 167250 167251 167252 167253 167254 167255 167256 167257 167258 | } static void jsonObjectFinal(sqlite3_context *ctx){ JsonString *pStr; pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ jsonAppendChar(pStr, '}'); if( pStr->bErr ){ if( pStr->bErr==0 ) sqlite3_result_error_nomem(ctx); assert( pStr->bStatic ); }else{ sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); pStr->bStatic = 1; } }else{ |
︙ | ︙ | |||
167938 167939 167940 167941 167942 167943 167944 | typedef unsigned char u8; typedef unsigned int u32; typedef unsigned short u16; typedef sqlite3_int64 i64; typedef sqlite3_uint64 u64; | | | 168433 168434 168435 168436 168437 168438 168439 168440 168441 168442 168443 168444 168445 168446 168447 | typedef unsigned char u8; typedef unsigned int u32; typedef unsigned short u16; typedef sqlite3_int64 i64; typedef sqlite3_uint64 u64; #define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0]))) #define testcase(x) #define ALWAYS(x) 1 #define NEVER(x) 0 #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #define MAX(x,y) (((x) > (y)) ? (x) : (y)) |
︙ | ︙ | |||
168134 168135 168136 168137 168138 168139 168140 | /* ** Buffer object for the incremental building of string data. */ typedef struct Fts5Buffer Fts5Buffer; struct Fts5Buffer { u8 *p; | | | | | 168629 168630 168631 168632 168633 168634 168635 168636 168637 168638 168639 168640 168641 168642 168643 168644 168645 168646 168647 168648 168649 168650 168651 168652 168653 168654 168655 168656 168657 168658 168659 168660 168661 168662 168663 168664 168665 | /* ** Buffer object for the incremental building of string data. */ typedef struct Fts5Buffer Fts5Buffer; struct Fts5Buffer { u8 *p; int n; int nSpace; }; static int sqlite3Fts5BufferSize(int*, Fts5Buffer*, u32); static void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64); static void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, u32, const u8*); static void sqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*); static void sqlite3Fts5BufferFree(Fts5Buffer*); static void sqlite3Fts5BufferZero(Fts5Buffer*); static void sqlite3Fts5BufferSet(int*, Fts5Buffer*, int, const u8*); static void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...); static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); #define fts5BufferZero(x) sqlite3Fts5BufferZero(x) #define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c) #define fts5BufferFree(a) sqlite3Fts5BufferFree(a) #define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d) #define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d) #define fts5BufferGrow(pRc,pBuf,nn) ( \ (u32)((pBuf)->n) + (u32)(nn) <= (u32)((pBuf)->nSpace) ? 0 : \ sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \ ) /* Write and decode big-endian 32-bit integer values */ static void sqlite3Fts5Put32(u8*, int); static int sqlite3Fts5Get32(const u8*); |
︙ | ︙ | |||
168191 168192 168193 168194 168195 168196 168197 168198 168199 168200 168201 168202 168203 168204 | static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader*); typedef struct Fts5PoslistWriter Fts5PoslistWriter; struct Fts5PoslistWriter { i64 iPrev; }; static int sqlite3Fts5PoslistWriterAppend(Fts5Buffer*, Fts5PoslistWriter*, i64); static int sqlite3Fts5PoslistNext64( const u8 *a, int n, /* Buffer containing poslist */ int *pi, /* IN/OUT: Offset within a[] */ i64 *piOff /* IN/OUT: Current offset */ ); | > | 168686 168687 168688 168689 168690 168691 168692 168693 168694 168695 168696 168697 168698 168699 168700 | static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader*); typedef struct Fts5PoslistWriter Fts5PoslistWriter; struct Fts5PoslistWriter { i64 iPrev; }; static int sqlite3Fts5PoslistWriterAppend(Fts5Buffer*, Fts5PoslistWriter*, i64); static void sqlite3Fts5PoslistSafeAppend(Fts5Buffer*, i64*, i64); static int sqlite3Fts5PoslistNext64( const u8 *a, int n, /* Buffer containing poslist */ int *pi, /* IN/OUT: Offset within a[] */ i64 *piOff /* IN/OUT: Current offset */ ); |
︙ | ︙ | |||
168224 168225 168226 168227 168228 168229 168230 168231 168232 168233 168234 168235 168236 168237 168238 168239 168240 168241 168242 168243 168244 | ** Interface to code in fts5_index.c. fts5_index.c contains contains code ** to access the data stored in the %_data table. */ typedef struct Fts5Index Fts5Index; typedef struct Fts5IndexIter Fts5IndexIter; /* ** Values used as part of the flags argument passed to IndexQuery(). */ #define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */ #define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */ #define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */ #define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */ /* ** Create/destroy an Fts5Index object. */ static int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**); static int sqlite3Fts5IndexClose(Fts5Index *p); | > > > > > > > > > > > > > > > | 168720 168721 168722 168723 168724 168725 168726 168727 168728 168729 168730 168731 168732 168733 168734 168735 168736 168737 168738 168739 168740 168741 168742 168743 168744 168745 168746 168747 168748 168749 168750 168751 168752 168753 168754 168755 | ** Interface to code in fts5_index.c. fts5_index.c contains contains code ** to access the data stored in the %_data table. */ typedef struct Fts5Index Fts5Index; typedef struct Fts5IndexIter Fts5IndexIter; struct Fts5IndexIter { i64 iRowid; const u8 *pData; int nData; u8 bEof; }; #define sqlite3Fts5IterEof(x) ((x)->bEof) /* ** Values used as part of the flags argument passed to IndexQuery(). */ #define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */ #define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */ #define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */ #define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */ /* The following are used internally by the fts5_index.c module. They are ** defined here only to make it easier to avoid clashes with the flags ** above. */ #define FTS5INDEX_QUERY_SKIPEMPTY 0x0010 #define FTS5INDEX_QUERY_NOOUTPUT 0x0020 /* ** Create/destroy an Fts5Index object. */ static int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**); static int sqlite3Fts5IndexClose(Fts5Index *p); |
︙ | ︙ | |||
168287 168288 168289 168290 168291 168292 168293 | Fts5IndexIter **ppIter /* OUT: New iterator object */ ); /* ** The various operations on open token or token prefix iterators opened ** using sqlite3Fts5IndexQuery(). */ | < < < | 168798 168799 168800 168801 168802 168803 168804 168805 168806 168807 168808 168809 168810 168811 168812 168813 168814 | Fts5IndexIter **ppIter /* OUT: New iterator object */ ); /* ** The various operations on open token or token prefix iterators opened ** using sqlite3Fts5IndexQuery(). */ static int sqlite3Fts5IterNext(Fts5IndexIter*); static int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch); static i64 sqlite3Fts5IterRowid(Fts5IndexIter*); /* ** Close an iterator opened by sqlite3Fts5IndexQuery(). */ static void sqlite3Fts5IterClose(Fts5IndexIter*); /* |
︙ | ︙ | |||
168378 168379 168380 168381 168382 168383 168384 | static int sqlite3Fts5IndexReinit(Fts5Index *p); static int sqlite3Fts5IndexOptimize(Fts5Index *p); static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge); static int sqlite3Fts5IndexLoadConfig(Fts5Index *p); | < < | 168886 168887 168888 168889 168890 168891 168892 168893 168894 168895 168896 168897 168898 168899 | static int sqlite3Fts5IndexReinit(Fts5Index *p); static int sqlite3Fts5IndexOptimize(Fts5Index *p); static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge); static int sqlite3Fts5IndexLoadConfig(Fts5Index *p); /* ** End of interface to code in fts5_index.c. **************************************************************************/ /************************************************************************** ** Interface to code in fts5_varint.c. */ |
︙ | ︙ | |||
170430 170431 170432 170433 170434 170435 170436 | { "snippet", 0, fts5SnippetFunction, 0 }, { "highlight", 0, fts5HighlightFunction, 0 }, { "bm25", 0, fts5Bm25Function, 0 }, }; int rc = SQLITE_OK; /* Return code */ int i; /* To iterate through builtin functions */ | | | 170936 170937 170938 170939 170940 170941 170942 170943 170944 170945 170946 170947 170948 170949 170950 | { "snippet", 0, fts5SnippetFunction, 0 }, { "highlight", 0, fts5HighlightFunction, 0 }, { "bm25", 0, fts5Bm25Function, 0 }, }; int rc = SQLITE_OK; /* Return code */ int i; /* To iterate through builtin functions */ for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){ rc = pApi->xCreateFunction(pApi, aBuiltin[i].zFunc, aBuiltin[i].pUserData, aBuiltin[i].xFunc, aBuiltin[i].xDestroy ); } |
︙ | ︙ | |||
170462 170463 170464 170465 170466 170467 170468 | */ /* #include "fts5Int.h" */ static int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){ | > | | | | | | | | | | | | > | 170968 170969 170970 170971 170972 170973 170974 170975 170976 170977 170978 170979 170980 170981 170982 170983 170984 170985 170986 170987 170988 170989 170990 170991 170992 170993 170994 170995 | */ /* #include "fts5Int.h" */ static int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){ if( (u32)pBuf->nSpace<nByte ){ u32 nNew = pBuf->nSpace ? pBuf->nSpace : 64; u8 *pNew; while( nNew<nByte ){ nNew = nNew * 2; } pNew = sqlite3_realloc(pBuf->p, nNew); if( pNew==0 ){ *pRc = SQLITE_NOMEM; return 1; }else{ pBuf->nSpace = nNew; pBuf->p = pNew; } } return 0; } /* ** Encode value iVal as an SQLite varint and append it to the buffer object |
︙ | ︙ | |||
170653 170654 170655 170656 170657 170658 170659 170660 170661 170662 170663 170664 170665 | ){ memset(pIter, 0, sizeof(*pIter)); pIter->a = a; pIter->n = n; sqlite3Fts5PoslistReaderNext(pIter); return pIter->bEof; } static int sqlite3Fts5PoslistWriterAppend( Fts5Buffer *pBuf, Fts5PoslistWriter *pWriter, i64 iPos ){ | > > > > > > > > > > > > > > > > > > > > > < | | < < < < < < | < | | 171161 171162 171163 171164 171165 171166 171167 171168 171169 171170 171171 171172 171173 171174 171175 171176 171177 171178 171179 171180 171181 171182 171183 171184 171185 171186 171187 171188 171189 171190 171191 171192 171193 171194 171195 171196 171197 171198 171199 171200 171201 171202 171203 171204 171205 | ){ memset(pIter, 0, sizeof(*pIter)); pIter->a = a; pIter->n = n; sqlite3Fts5PoslistReaderNext(pIter); return pIter->bEof; } /* ** Append position iPos to the position list being accumulated in buffer ** pBuf, which must be already be large enough to hold the new data. ** The previous position written to this list is *piPrev. *piPrev is set ** to iPos before returning. */ static void sqlite3Fts5PoslistSafeAppend( Fts5Buffer *pBuf, i64 *piPrev, i64 iPos ){ static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32; if( (iPos & colmask) != (*piPrev & colmask) ){ pBuf->p[pBuf->n++] = 1; pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32)); *piPrev = (iPos & colmask); } pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2); *piPrev = iPos; } static int sqlite3Fts5PoslistWriterAppend( Fts5Buffer *pBuf, Fts5PoslistWriter *pWriter, i64 iPos ){ int rc; if( fts5BufferGrow(&rc, pBuf, 5+5+5) ) return rc; sqlite3Fts5PoslistSafeAppend(pBuf, &pWriter->iPrev, iPos); return SQLITE_OK; } static void *sqlite3Fts5MallocZero(int *pRc, int nByte){ void *pRet = 0; if( *pRc==SQLITE_OK ){ pRet = sqlite3_malloc(nByte); if( pRet==0 && nByte>0 ){ |
︙ | ︙ | |||
170768 170769 170770 170771 170772 170773 170774 | const char *pTerm, int nTerm, int *pbPresent ){ int rc = SQLITE_OK; *pbPresent = 0; if( p ){ int i; | | | | 171289 171290 171291 171292 171293 171294 171295 171296 171297 171298 171299 171300 171301 171302 171303 171304 171305 171306 171307 171308 171309 171310 171311 171312 171313 171314 171315 171316 171317 171318 171319 171320 | const char *pTerm, int nTerm, int *pbPresent ){ int rc = SQLITE_OK; *pbPresent = 0; if( p ){ int i; u32 hash = 13; Fts5TermsetEntry *pEntry; /* Calculate a hash value for this term. This is the same hash checksum ** used by the fts5_hash.c module. This is not important for correct ** operation of the module, but is necessary to ensure that some tests ** designed to produce hash table collisions really do work. */ for(i=nTerm-1; i>=0; i--){ hash = (hash << 3) ^ hash ^ pTerm[i]; } hash = (hash << 3) ^ hash ^ iIdx; hash = hash % ArraySize(p->apHash); for(pEntry=p->apHash[hash]; pEntry; pEntry=pEntry->pNext){ if( pEntry->iIdx==iIdx && pEntry->nTerm==nTerm && memcmp(pEntry->pTerm, pTerm, nTerm)==0 ){ *pbPresent = 1; break; } } if( pEntry==0 ){ pEntry = sqlite3Fts5MallocZero(&rc, sizeof(Fts5TermsetEntry) + nTerm); |
︙ | ︙ | |||
170809 170810 170811 170812 170813 170814 170815 | } return rc; } static void sqlite3Fts5TermsetFree(Fts5Termset *p){ if( p ){ | | | 171330 171331 171332 171333 171334 171335 171336 171337 171338 171339 171340 171341 171342 171343 171344 | } return rc; } static void sqlite3Fts5TermsetFree(Fts5Termset *p){ if( p ){ u32 i; for(i=0; i<ArraySize(p->apHash); i++){ Fts5TermsetEntry *pEntry = p->apHash[i]; while( pEntry ){ Fts5TermsetEntry *pDel = pEntry; pEntry = pEntry->pNext; sqlite3_free(pDel); } |
︙ | ︙ | |||
171836 171837 171838 171839 171840 171841 171842 171843 171844 171845 171846 171847 171848 171849 171850 171851 171852 171853 171854 171855 171856 171857 171858 171859 171860 | ** FTS5_TERM (pNear valid) */ struct Fts5ExprNode { int eType; /* Node type */ int bEof; /* True at EOF */ int bNomatch; /* True if entry is not a match */ i64 iRowid; /* Current rowid */ Fts5ExprNearset *pNear; /* For FTS5_STRING - cluster of phrases */ /* Child nodes. For a NOT node, this array always contains 2 entries. For ** AND or OR nodes, it contains 2 or more entries. */ int nChild; /* Number of child nodes */ Fts5ExprNode *apChild[1]; /* Array of child nodes */ }; #define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING) /* ** An instance of the following structure represents a single search term ** or term prefix. */ struct Fts5ExprTerm { int bPrefix; /* True for a prefix term */ char *zTerm; /* nul-terminated term */ | > > > > > > > > > | 172357 172358 172359 172360 172361 172362 172363 172364 172365 172366 172367 172368 172369 172370 172371 172372 172373 172374 172375 172376 172377 172378 172379 172380 172381 172382 172383 172384 172385 172386 172387 172388 172389 172390 | ** FTS5_TERM (pNear valid) */ struct Fts5ExprNode { int eType; /* Node type */ int bEof; /* True at EOF */ int bNomatch; /* True if entry is not a match */ /* Next method for this node. */ int (*xNext)(Fts5Expr*, Fts5ExprNode*, int, i64); i64 iRowid; /* Current rowid */ Fts5ExprNearset *pNear; /* For FTS5_STRING - cluster of phrases */ /* Child nodes. For a NOT node, this array always contains 2 entries. For ** AND or OR nodes, it contains 2 or more entries. */ int nChild; /* Number of child nodes */ Fts5ExprNode *apChild[1]; /* Array of child nodes */ }; #define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING) /* ** Invoke the xNext method of an Fts5ExprNode object. This macro should be ** used as if it has the same signature as the xNext() methods themselves. */ #define fts5ExprNodeNext(a,b,c,d) (b)->xNext((a), (b), (c), (d)) /* ** An instance of the following structure represents a single search term ** or term prefix. */ struct Fts5ExprTerm { int bPrefix; /* True for a prefix term */ char *zTerm; /* nul-terminated term */ |
︙ | ︙ | |||
172008 172009 172010 172011 172012 172013 172014 | assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 ); if( sParse.rc==SQLITE_OK ){ *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr)); if( pNew==0 ){ sParse.rc = SQLITE_NOMEM; sqlite3Fts5ParseNodeFree(sParse.pExpr); }else{ | > > > > > > > | > | 172538 172539 172540 172541 172542 172543 172544 172545 172546 172547 172548 172549 172550 172551 172552 172553 172554 172555 172556 172557 172558 172559 172560 | assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 ); if( sParse.rc==SQLITE_OK ){ *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr)); if( pNew==0 ){ sParse.rc = SQLITE_NOMEM; sqlite3Fts5ParseNodeFree(sParse.pExpr); }else{ if( !sParse.pExpr ){ const int nByte = sizeof(Fts5ExprNode); pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte); if( pNew->pRoot ){ pNew->pRoot->bEof = 1; } }else{ pNew->pRoot = sParse.pExpr; } pNew->pIndex = 0; pNew->pConfig = pConfig; pNew->apExprPhrase = sParse.apPhrase; pNew->nPhrase = sParse.nPhrase; sParse.apPhrase = 0; } } |
︙ | ︙ | |||
172060 172061 172062 172063 172064 172065 172066 | int bRetValid = 0; Fts5ExprTerm *p; assert( pTerm->pSynonym ); assert( bDesc==0 || bDesc==1 ); for(p=pTerm; p; p=p->pSynonym){ if( 0==sqlite3Fts5IterEof(p->pIter) ){ | | | | < < < < < < < < < < < | | < < > | | < < | | < | 172598 172599 172600 172601 172602 172603 172604 172605 172606 172607 172608 172609 172610 172611 172612 172613 172614 172615 172616 172617 172618 172619 172620 172621 172622 172623 172624 172625 172626 172627 172628 172629 172630 172631 172632 172633 172634 172635 172636 172637 172638 172639 172640 172641 172642 172643 172644 172645 172646 172647 172648 172649 172650 172651 172652 172653 172654 172655 172656 172657 172658 172659 172660 172661 172662 172663 172664 172665 172666 172667 172668 172669 172670 172671 172672 172673 172674 172675 172676 172677 172678 172679 172680 172681 172682 172683 172684 172685 172686 172687 172688 172689 172690 172691 | int bRetValid = 0; Fts5ExprTerm *p; assert( pTerm->pSynonym ); assert( bDesc==0 || bDesc==1 ); for(p=pTerm; p; p=p->pSynonym){ if( 0==sqlite3Fts5IterEof(p->pIter) ){ i64 iRowid = p->pIter->iRowid; if( bRetValid==0 || (bDesc!=(iRowid<iRet)) ){ iRet = iRowid; bRetValid = 1; } } } if( pbEof && bRetValid==0 ) *pbEof = 1; return iRet; } /* ** Argument pTerm must be a synonym iterator. */ static int fts5ExprSynonymList( Fts5ExprTerm *pTerm, int bCollist, Fts5Colset *pColset, i64 iRowid, Fts5Buffer *pBuf, /* Use this buffer for space if required */ u8 **pa, int *pn ){ Fts5PoslistReader aStatic[4]; Fts5PoslistReader *aIter = aStatic; int nIter = 0; int nAlloc = 4; int rc = SQLITE_OK; Fts5ExprTerm *p; assert( pTerm->pSynonym ); for(p=pTerm; p; p=p->pSynonym){ Fts5IndexIter *pIter = p->pIter; if( sqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){ if( pIter->nData==0 ) continue; if( nIter==nAlloc ){ int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2; Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte); if( aNew==0 ){ rc = SQLITE_NOMEM; goto synonym_poslist_out; } memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter); nAlloc = nAlloc*2; if( aIter!=aStatic ) sqlite3_free(aIter); aIter = aNew; } sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &aIter[nIter]); assert( aIter[nIter].bEof==0 ); nIter++; } } if( nIter==1 ){ *pa = (u8*)aIter[0].a; *pn = aIter[0].n; }else{ Fts5PoslistWriter writer = {0}; i64 iPrev = -1; fts5BufferZero(pBuf); while( 1 ){ int i; i64 iMin = FTS5_LARGEST_INT64; for(i=0; i<nIter; i++){ if( aIter[i].bEof==0 ){ if( aIter[i].iPos==iPrev ){ if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) continue; } if( aIter[i].iPos<iMin ){ iMin = aIter[i].iPos; } } } if( iMin==FTS5_LARGEST_INT64 || rc!=SQLITE_OK ) break; rc = sqlite3Fts5PoslistWriterAppend(pBuf, &writer, iMin); iPrev = iMin; } if( rc==SQLITE_OK ){ *pa = pBuf->p; *pn = pBuf->n; } } synonym_poslist_out: if( aIter!=aStatic ) sqlite3_free(aIter); return rc; } |
︙ | ︙ | |||
172191 172192 172193 172194 172195 172196 172197 | int i; int rc = SQLITE_OK; fts5BufferZero(&pPhrase->poslist); /* If the aStatic[] array is not large enough, allocate a large array ** using sqlite3_malloc(). This approach could be improved upon. */ | | < | > | > > > > > > | < | 172714 172715 172716 172717 172718 172719 172720 172721 172722 172723 172724 172725 172726 172727 172728 172729 172730 172731 172732 172733 172734 172735 172736 172737 172738 172739 172740 172741 172742 172743 172744 172745 172746 172747 172748 172749 172750 172751 172752 172753 172754 | int i; int rc = SQLITE_OK; fts5BufferZero(&pPhrase->poslist); /* If the aStatic[] array is not large enough, allocate a large array ** using sqlite3_malloc(). This approach could be improved upon. */ if( pPhrase->nTerm>ArraySize(aStatic) ){ int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm; aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte); if( !aIter ) return SQLITE_NOMEM; } memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm); /* Initialize a term iterator for each term in the phrase */ for(i=0; i<pPhrase->nTerm; i++){ Fts5ExprTerm *pTerm = &pPhrase->aTerm[i]; int n = 0; int bFlag = 0; u8 *a = 0; if( pTerm->pSynonym ){ Fts5Buffer buf = {0, 0, 0}; rc = fts5ExprSynonymList( pTerm, 0, pColset, pNode->iRowid, &buf, &a, &n ); if( rc ){ sqlite3_free(a); goto ismatch_out; } if( a==buf.p ) bFlag = 1; }else{ a = (u8*)pTerm->pIter->pData; n = pTerm->pIter->nData; } sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]); aIter[i].bFlag = (u8)bFlag; if( aIter[i].bEof ) goto ismatch_out; } while( 1 ){ int bMatch; |
︙ | ︙ | |||
172284 172285 172286 172287 172288 172289 172290 | memset(p, 0, sizeof(Fts5LookaheadReader)); p->a = a; p->n = n; fts5LookaheadReaderNext(p); return fts5LookaheadReaderNext(p); } | < < < < < < | 172812 172813 172814 172815 172816 172817 172818 172819 172820 172821 172822 172823 172824 172825 | memset(p, 0, sizeof(Fts5LookaheadReader)); p->a = a; p->n = n; fts5LookaheadReaderNext(p); return fts5LookaheadReaderNext(p); } typedef struct Fts5NearTrimmer Fts5NearTrimmer; struct Fts5NearTrimmer { Fts5LookaheadReader reader; /* Input iterator */ Fts5PoslistWriter writer; /* Writer context */ Fts5Buffer *pOut; /* Output poslist */ }; |
︙ | ︙ | |||
172327 172328 172329 172330 172331 172332 172333 | int rc = *pRc; int bMatch; assert( pNear->nPhrase>1 ); /* If the aStatic[] array is not large enough, allocate a large array ** using sqlite3_malloc(). This approach could be improved upon. */ | | | 172849 172850 172851 172852 172853 172854 172855 172856 172857 172858 172859 172860 172861 172862 172863 | int rc = *pRc; int bMatch; assert( pNear->nPhrase>1 ); /* If the aStatic[] array is not large enough, allocate a large array ** using sqlite3_malloc(). This approach could be improved upon. */ if( pNear->nPhrase>ArraySize(aStatic) ){ int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase; a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte); }else{ memset(aStatic, 0, sizeof(aStatic)); } if( rc!=SQLITE_OK ){ *pRc = rc; |
︙ | ︙ | |||
172404 172405 172406 172407 172408 172409 172410 | int bRet = a[0].pOut->n>0; *pRc = rc; if( a!=aStatic ) sqlite3_free(a); return bRet; } } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | 172926 172927 172928 172929 172930 172931 172932 172933 172934 172935 172936 172937 172938 172939 172940 172941 172942 172943 172944 172945 172946 172947 172948 172949 172950 172951 172952 172953 172954 172955 172956 172957 172958 172959 172960 172961 172962 172963 172964 172965 172966 172967 172968 172969 172970 172971 172972 172973 172974 172975 172976 172977 172978 172979 172980 172981 172982 172983 172984 172985 172986 172987 172988 | int bRet = a[0].pOut->n>0; *pRc = rc; if( a!=aStatic ) sqlite3_free(a); return bRet; } } /* ** Advance iterator pIter until it points to a value equal to or laster ** than the initial value of *piLast. If this means the iterator points ** to a value laster than *piLast, update *piLast to the new lastest value. ** ** If the iterator reaches EOF, set *pbEof to true before returning. If ** an error occurs, set *pRc to an error code. If either *pbEof or *pRc ** are set, return a non-zero value. Otherwise, return zero. */ static int fts5ExprAdvanceto( Fts5IndexIter *pIter, /* Iterator to advance */ int bDesc, /* True if iterator is "rowid DESC" */ i64 *piLast, /* IN/OUT: Lastest rowid seen so far */ int *pRc, /* OUT: Error code */ int *pbEof /* OUT: Set to true if EOF */ ){ i64 iLast = *piLast; i64 iRowid; iRowid = pIter->iRowid; if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){ int rc = sqlite3Fts5IterNextFrom(pIter, iLast); if( rc || sqlite3Fts5IterEof(pIter) ){ *pRc = rc; *pbEof = 1; return 1; } iRowid = pIter->iRowid; assert( (bDesc==0 && iRowid>=iLast) || (bDesc==1 && iRowid<=iLast) ); } *piLast = iRowid; return 0; } static int fts5ExprSynonymAdvanceto( Fts5ExprTerm *pTerm, /* Term iterator to advance */ int bDesc, /* True if iterator is "rowid DESC" */ i64 *piLast, /* IN/OUT: Lastest rowid seen so far */ int *pRc /* OUT: Error code */ ){ int rc = SQLITE_OK; i64 iLast = *piLast; Fts5ExprTerm *p; int bEof = 0; for(p=pTerm; rc==SQLITE_OK && p; p=p->pSynonym){ if( sqlite3Fts5IterEof(p->pIter)==0 ){ i64 iRowid = p->pIter->iRowid; if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){ rc = sqlite3Fts5IterNextFrom(p->pIter, iLast); } } } if( rc!=SQLITE_OK ){ |
︙ | ︙ | |||
172549 172550 172551 172552 172553 172554 172555 | if( pExpr->pConfig->eDetail!=FTS5_DETAIL_FULL ){ Fts5ExprTerm *pTerm; Fts5ExprPhrase *pPhrase = pNear->apPhrase[0]; pPhrase->poslist.n = 0; for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){ Fts5IndexIter *pIter = pTerm->pIter; if( sqlite3Fts5IterEof(pIter)==0 ){ | < < < < < < | < | < > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > | 173006 173007 173008 173009 173010 173011 173012 173013 173014 173015 173016 173017 173018 173019 173020 173021 173022 173023 173024 173025 173026 173027 173028 173029 173030 173031 173032 173033 173034 173035 173036 173037 173038 173039 173040 173041 173042 173043 173044 173045 173046 173047 173048 173049 173050 173051 173052 173053 173054 173055 173056 173057 173058 173059 173060 173061 173062 173063 173064 173065 173066 | if( pExpr->pConfig->eDetail!=FTS5_DETAIL_FULL ){ Fts5ExprTerm *pTerm; Fts5ExprPhrase *pPhrase = pNear->apPhrase[0]; pPhrase->poslist.n = 0; for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){ Fts5IndexIter *pIter = pTerm->pIter; if( sqlite3Fts5IterEof(pIter)==0 ){ if( pIter->iRowid==pNode->iRowid && pIter->nData>0 ){ pPhrase->poslist.n = 1; } } } return pPhrase->poslist.n; }else{ int i; /* Check that each phrase in the nearset matches the current row. ** Populate the pPhrase->poslist buffers at the same time. If any ** phrase is not a match, break out of the loop early. */ for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i]; if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){ int bMatch = 0; rc = fts5ExprPhraseIsMatch(pNode, pNear->pColset, pPhrase, &bMatch); if( bMatch==0 ) break; }else{ Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter; fts5BufferSet(&rc, &pPhrase->poslist, pIter->nData, pIter->pData); } } *pRc = rc; if( i==pNear->nPhrase && (i==1 || fts5ExprNearIsMatch(pRc, pNear)) ){ return 1; } return 0; } } /* ** Initialize all term iterators in the pNear object. If any term is found ** to match no documents at all, return immediately without initializing any ** further iterators. */ static int fts5ExprNearInitAll( Fts5Expr *pExpr, Fts5ExprNode *pNode ){ Fts5ExprNearset *pNear = pNode->pNear; int i, j; int rc = SQLITE_OK; assert( pNode->bNomatch==0 ); for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i]; for(j=0; j<pPhrase->nTerm; j++){ Fts5ExprTerm *pTerm = &pPhrase->aTerm[j]; Fts5ExprTerm *p; int bEof = 1; |
︙ | ︙ | |||
172733 172734 172735 172736 172737 172738 172739 | return rc; } } } return rc; } | < < < < | 173087 173088 173089 173090 173091 173092 173093 173094 173095 173096 173097 173098 173099 173100 | return rc; } } } return rc; } /* ** If pExpr is an ASC iterator, this function returns a value with the ** same sign as: ** ** (iLhs - iRhs) ** |
︙ | ︙ | |||
172766 172767 172768 172769 172770 172771 172772 172773 172774 172775 172776 172777 172778 172779 | return (iLhs < iRhs); } } static void fts5ExprSetEof(Fts5ExprNode *pNode){ int i; pNode->bEof = 1; for(i=0; i<pNode->nChild; i++){ fts5ExprSetEof(pNode->apChild[i]); } } static void fts5ExprNodeZeroPoslist(Fts5ExprNode *pNode){ if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){ | > | 173116 173117 173118 173119 173120 173121 173122 173123 173124 173125 173126 173127 173128 173129 173130 | return (iLhs < iRhs); } } static void fts5ExprSetEof(Fts5ExprNode *pNode){ int i; pNode->bEof = 1; pNode->bNomatch = 0; for(i=0; i<pNode->nChild; i++){ fts5ExprSetEof(pNode->apChild[i]); } } static void fts5ExprNodeZeroPoslist(Fts5ExprNode *pNode){ if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){ |
︙ | ︙ | |||
172788 172789 172790 172791 172792 172793 172794 | for(i=0; i<pNode->nChild; i++){ fts5ExprNodeZeroPoslist(pNode->apChild[i]); } } } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > | < < < | | | | | < | 173139 173140 173141 173142 173143 173144 173145 173146 173147 173148 173149 173150 173151 173152 173153 173154 173155 173156 173157 173158 173159 173160 173161 173162 173163 173164 173165 173166 173167 173168 173169 173170 173171 173172 173173 173174 173175 173176 173177 173178 173179 173180 173181 173182 173183 173184 173185 173186 173187 173188 173189 173190 173191 173192 173193 173194 173195 173196 173197 173198 173199 173200 173201 173202 173203 173204 173205 173206 173207 173208 173209 173210 173211 173212 173213 173214 173215 173216 173217 173218 173219 173220 173221 173222 173223 173224 173225 173226 173227 173228 173229 173230 173231 173232 173233 173234 173235 173236 173237 173238 173239 173240 173241 173242 173243 173244 173245 173246 173247 173248 173249 173250 173251 173252 173253 173254 173255 173256 173257 173258 173259 173260 173261 173262 173263 173264 173265 173266 173267 173268 173269 173270 173271 173272 173273 173274 173275 173276 173277 173278 173279 173280 173281 173282 173283 173284 173285 173286 173287 173288 173289 173290 173291 173292 173293 173294 173295 173296 173297 173298 173299 173300 173301 173302 173303 173304 173305 173306 173307 173308 173309 173310 173311 173312 173313 173314 173315 173316 173317 173318 173319 173320 173321 173322 173323 173324 173325 173326 173327 173328 173329 173330 173331 173332 173333 173334 173335 173336 173337 173338 173339 173340 173341 173342 173343 173344 173345 173346 173347 173348 173349 173350 173351 173352 173353 173354 173355 173356 173357 173358 173359 173360 173361 173362 173363 173364 173365 173366 173367 173368 173369 173370 173371 173372 173373 173374 173375 173376 173377 173378 173379 173380 173381 173382 173383 173384 173385 173386 173387 173388 173389 173390 173391 173392 173393 173394 173395 173396 173397 173398 173399 173400 173401 173402 173403 173404 173405 173406 173407 173408 173409 173410 173411 173412 173413 173414 173415 173416 173417 173418 173419 173420 173421 173422 173423 173424 173425 173426 173427 173428 173429 173430 173431 173432 173433 173434 173435 173436 173437 173438 173439 173440 | for(i=0; i<pNode->nChild; i++){ fts5ExprNodeZeroPoslist(pNode->apChild[i]); } } } /* ** Compare the values currently indicated by the two nodes as follows: ** ** res = (*p1) - (*p2) ** ** Nodes that point to values that come later in the iteration order are ** considered to be larger. Nodes at EOF are the largest of all. ** ** This means that if the iteration order is ASC, then numerically larger ** rowids are considered larger. Or if it is the default DESC, numerically ** smaller rowids are larger. */ static int fts5NodeCompare( Fts5Expr *pExpr, Fts5ExprNode *p1, Fts5ExprNode *p2 ){ if( p2->bEof ) return -1; if( p1->bEof ) return +1; return fts5RowidCmp(pExpr, p1->iRowid, p2->iRowid); } /* ** All individual term iterators in pNear are guaranteed to be valid when ** this function is called. This function checks if all term iterators ** point to the same rowid, and if not, advances them until they do. ** If an EOF is reached before this happens, *pbEof is set to true before ** returning. ** ** SQLITE_OK is returned if an error occurs, or an SQLite error code ** otherwise. It is not considered an error code if an iterator reaches ** EOF. */ static int fts5ExprNodeTest_STRING( Fts5Expr *pExpr, /* Expression pPhrase belongs to */ Fts5ExprNode *pNode ){ Fts5ExprNearset *pNear = pNode->pNear; Fts5ExprPhrase *pLeft = pNear->apPhrase[0]; int rc = SQLITE_OK; i64 iLast; /* Lastest rowid any iterator points to */ int i, j; /* Phrase and token index, respectively */ int bMatch; /* True if all terms are at the same rowid */ const int bDesc = pExpr->bDesc; /* Check that this node should not be FTS5_TERM */ assert( pNear->nPhrase>1 || pNear->apPhrase[0]->nTerm>1 || pNear->apPhrase[0]->aTerm[0].pSynonym ); /* Initialize iLast, the "lastest" rowid any iterator points to. If the ** iterator skips through rowids in the default ascending order, this means ** the maximum rowid. Or, if the iterator is "ORDER BY rowid DESC", then it ** means the minimum rowid. */ if( pLeft->aTerm[0].pSynonym ){ iLast = fts5ExprSynonymRowid(&pLeft->aTerm[0], bDesc, 0); }else{ iLast = pLeft->aTerm[0].pIter->iRowid; } do { bMatch = 1; for(i=0; i<pNear->nPhrase; i++){ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i]; for(j=0; j<pPhrase->nTerm; j++){ Fts5ExprTerm *pTerm = &pPhrase->aTerm[j]; if( pTerm->pSynonym ){ i64 iRowid = fts5ExprSynonymRowid(pTerm, bDesc, 0); if( iRowid==iLast ) continue; bMatch = 0; if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){ pNode->bNomatch = 0; pNode->bEof = 1; return rc; } }else{ Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter; if( pIter->iRowid==iLast ) continue; bMatch = 0; if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){ return rc; } } } } }while( bMatch==0 ); pNode->iRowid = iLast; pNode->bNomatch = ((0==fts5ExprNearTest(&rc, pExpr, pNode)) && rc==SQLITE_OK); assert( pNode->bEof==0 || pNode->bNomatch==0 ); return rc; } /* ** Advance the first term iterator in the first phrase of pNear. Set output ** variable *pbEof to true if it reaches EOF or if an error occurs. ** ** Return SQLITE_OK if successful, or an SQLite error code if an error ** occurs. */ static int fts5ExprNodeNext_STRING( Fts5Expr *pExpr, /* Expression pPhrase belongs to */ Fts5ExprNode *pNode, /* FTS5_STRING or FTS5_TERM node */ int bFromValid, i64 iFrom ){ Fts5ExprTerm *pTerm = &pNode->pNear->apPhrase[0]->aTerm[0]; int rc = SQLITE_OK; pNode->bNomatch = 0; if( pTerm->pSynonym ){ int bEof = 1; Fts5ExprTerm *p; /* Find the firstest rowid any synonym points to. */ i64 iRowid = fts5ExprSynonymRowid(pTerm, pExpr->bDesc, 0); /* Advance each iterator that currently points to iRowid. Or, if iFrom ** is valid - each iterator that points to a rowid before iFrom. */ for(p=pTerm; p; p=p->pSynonym){ if( sqlite3Fts5IterEof(p->pIter)==0 ){ i64 ii = p->pIter->iRowid; if( ii==iRowid || (bFromValid && ii!=iFrom && (ii>iFrom)==pExpr->bDesc) ){ if( bFromValid ){ rc = sqlite3Fts5IterNextFrom(p->pIter, iFrom); }else{ rc = sqlite3Fts5IterNext(p->pIter); } if( rc!=SQLITE_OK ) break; if( sqlite3Fts5IterEof(p->pIter)==0 ){ bEof = 0; } }else{ bEof = 0; } } } /* Set the EOF flag if either all synonym iterators are at EOF or an ** error has occurred. */ pNode->bEof = (rc || bEof); }else{ Fts5IndexIter *pIter = pTerm->pIter; assert( Fts5NodeIsString(pNode) ); if( bFromValid ){ rc = sqlite3Fts5IterNextFrom(pIter, iFrom); }else{ rc = sqlite3Fts5IterNext(pIter); } pNode->bEof = (rc || sqlite3Fts5IterEof(pIter)); } if( pNode->bEof==0 ){ assert( rc==SQLITE_OK ); rc = fts5ExprNodeTest_STRING(pExpr, pNode); } return rc; } static int fts5ExprNodeTest_TERM( Fts5Expr *pExpr, /* Expression that pNear is a part of */ Fts5ExprNode *pNode /* The "NEAR" node (FTS5_TERM) */ ){ /* As this "NEAR" object is actually a single phrase that consists ** of a single term only, grab pointers into the poslist managed by the ** fts5_index.c iterator object. This is much faster than synthesizing ** a new poslist the way we have to for more complicated phrase or NEAR ** expressions. */ Fts5ExprPhrase *pPhrase = pNode->pNear->apPhrase[0]; Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter; assert( pNode->eType==FTS5_TERM ); assert( pNode->pNear->nPhrase==1 && pPhrase->nTerm==1 ); assert( pPhrase->aTerm[0].pSynonym==0 ); pPhrase->poslist.n = pIter->nData; if( pExpr->pConfig->eDetail==FTS5_DETAIL_FULL ){ pPhrase->poslist.p = (u8*)pIter->pData; } pNode->iRowid = pIter->iRowid; pNode->bNomatch = (pPhrase->poslist.n==0); return SQLITE_OK; } /* ** xNext() method for a node of type FTS5_TERM. */ static int fts5ExprNodeNext_TERM( Fts5Expr *pExpr, Fts5ExprNode *pNode, int bFromValid, i64 iFrom ){ int rc; Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter; assert( pNode->bEof==0 ); if( bFromValid ){ rc = sqlite3Fts5IterNextFrom(pIter, iFrom); }else{ rc = sqlite3Fts5IterNext(pIter); } if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){ rc = fts5ExprNodeTest_TERM(pExpr, pNode); }else{ pNode->bEof = 1; pNode->bNomatch = 0; } return rc; } static void fts5ExprNodeTest_OR( Fts5Expr *pExpr, /* Expression of which pNode is a part */ Fts5ExprNode *pNode /* Expression node to test */ ){ Fts5ExprNode *pNext = pNode->apChild[0]; int i; for(i=1; i<pNode->nChild; i++){ Fts5ExprNode *pChild = pNode->apChild[i]; int cmp = fts5NodeCompare(pExpr, pNext, pChild); if( cmp>0 || (cmp==0 && pChild->bNomatch==0) ){ pNext = pChild; } } pNode->iRowid = pNext->iRowid; pNode->bEof = pNext->bEof; pNode->bNomatch = pNext->bNomatch; } static int fts5ExprNodeNext_OR( Fts5Expr *pExpr, Fts5ExprNode *pNode, int bFromValid, i64 iFrom ){ int i; i64 iLast = pNode->iRowid; for(i=0; i<pNode->nChild; i++){ Fts5ExprNode *p1 = pNode->apChild[i]; assert( p1->bEof || fts5RowidCmp(pExpr, p1->iRowid, iLast)>=0 ); if( p1->bEof==0 ){ if( (p1->iRowid==iLast) || (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0) ){ int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom); if( rc!=SQLITE_OK ) return rc; } } } fts5ExprNodeTest_OR(pExpr, pNode); return SQLITE_OK; } /* ** Argument pNode is an FTS5_AND node. */ static int fts5ExprNodeTest_AND( Fts5Expr *pExpr, /* Expression pPhrase belongs to */ Fts5ExprNode *pAnd /* FTS5_AND node to advance */ ){ int iChild; i64 iLast = pAnd->iRowid; int rc = SQLITE_OK; int bMatch; assert( pAnd->bEof==0 ); do { pAnd->bNomatch = 0; bMatch = 1; for(iChild=0; iChild<pAnd->nChild; iChild++){ Fts5ExprNode *pChild = pAnd->apChild[iChild]; int cmp = fts5RowidCmp(pExpr, iLast, pChild->iRowid); if( cmp>0 ){ /* Advance pChild until it points to iLast or laster */ rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast); if( rc!=SQLITE_OK ) return rc; } /* If the child node is now at EOF, so is the parent AND node. Otherwise, ** the child node is guaranteed to have advanced at least as far as ** rowid iLast. So if it is not at exactly iLast, pChild->iRowid is the ** new lastest rowid seen so far. */ assert( pChild->bEof || fts5RowidCmp(pExpr, iLast, pChild->iRowid)<=0 ); |
︙ | ︙ | |||
172846 172847 172848 172849 172850 172851 172852 | if( pAnd->bNomatch && pAnd!=pExpr->pRoot ){ fts5ExprNodeZeroPoslist(pAnd); } pAnd->iRowid = iLast; return SQLITE_OK; } | > > > > > > > > > | < < < | > | < < < < < < < | | > > > | | < | < < | > > > > > | < > > > > | < | | > > > > > | < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < | | | < < < < < < < < < < < < < < < | < | | | < < | < < < < < < < < < < < < < < < < < < < < < < | < < < < < < > > > > > > > > > > > > > > > > > > > > | | 173456 173457 173458 173459 173460 173461 173462 173463 173464 173465 173466 173467 173468 173469 173470 173471 173472 173473 173474 173475 173476 173477 173478 173479 173480 173481 173482 173483 173484 173485 173486 173487 173488 173489 173490 173491 173492 173493 173494 173495 173496 173497 173498 173499 173500 173501 173502 173503 173504 173505 173506 173507 173508 173509 173510 173511 173512 173513 173514 173515 173516 173517 173518 173519 173520 173521 173522 173523 173524 173525 173526 173527 173528 173529 173530 173531 173532 173533 173534 173535 173536 173537 173538 173539 173540 173541 173542 173543 173544 173545 173546 173547 173548 173549 173550 173551 173552 173553 173554 173555 173556 173557 173558 173559 173560 173561 173562 173563 173564 173565 173566 173567 173568 173569 173570 173571 173572 173573 173574 173575 173576 173577 173578 173579 173580 173581 173582 173583 173584 173585 173586 173587 173588 173589 173590 173591 173592 173593 173594 173595 173596 173597 173598 173599 173600 173601 173602 173603 173604 173605 173606 173607 173608 173609 173610 | if( pAnd->bNomatch && pAnd!=pExpr->pRoot ){ fts5ExprNodeZeroPoslist(pAnd); } pAnd->iRowid = iLast; return SQLITE_OK; } static int fts5ExprNodeNext_AND( Fts5Expr *pExpr, Fts5ExprNode *pNode, int bFromValid, i64 iFrom ){ int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom); if( rc==SQLITE_OK ){ rc = fts5ExprNodeTest_AND(pExpr, pNode); } return rc; } static int fts5ExprNodeTest_NOT( Fts5Expr *pExpr, /* Expression pPhrase belongs to */ Fts5ExprNode *pNode /* FTS5_NOT node to advance */ ){ int rc = SQLITE_OK; Fts5ExprNode *p1 = pNode->apChild[0]; Fts5ExprNode *p2 = pNode->apChild[1]; assert( pNode->nChild==2 ); while( rc==SQLITE_OK && p1->bEof==0 ){ int cmp = fts5NodeCompare(pExpr, p1, p2); if( cmp>0 ){ rc = fts5ExprNodeNext(pExpr, p2, 1, p1->iRowid); cmp = fts5NodeCompare(pExpr, p1, p2); } assert( rc!=SQLITE_OK || cmp<=0 ); if( cmp || p2->bNomatch ) break; rc = fts5ExprNodeNext(pExpr, p1, 0, 0); } pNode->bEof = p1->bEof; pNode->bNomatch = p1->bNomatch; pNode->iRowid = p1->iRowid; if( p1->bEof ){ fts5ExprNodeZeroPoslist(p2); } return rc; } static int fts5ExprNodeNext_NOT( Fts5Expr *pExpr, Fts5ExprNode *pNode, int bFromValid, i64 iFrom ){ int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom); if( rc==SQLITE_OK ){ rc = fts5ExprNodeTest_NOT(pExpr, pNode); } return rc; } /* ** If pNode currently points to a match, this function returns SQLITE_OK ** without modifying it. Otherwise, pNode is advanced until it does point ** to a match or EOF is reached. */ static int fts5ExprNodeTest( Fts5Expr *pExpr, /* Expression of which pNode is a part */ Fts5ExprNode *pNode /* Expression node to test */ ){ int rc = SQLITE_OK; if( pNode->bEof==0 ){ switch( pNode->eType ){ case FTS5_STRING: { rc = fts5ExprNodeTest_STRING(pExpr, pNode); break; } case FTS5_TERM: { rc = fts5ExprNodeTest_TERM(pExpr, pNode); break; } case FTS5_AND: { rc = fts5ExprNodeTest_AND(pExpr, pNode); break; } case FTS5_OR: { fts5ExprNodeTest_OR(pExpr, pNode); break; } default: assert( pNode->eType==FTS5_NOT ); { rc = fts5ExprNodeTest_NOT(pExpr, pNode); break; } } } return rc; } /* ** Set node pNode, which is part of expression pExpr, to point to the first ** match. If there are no matches, set the Node.bEof flag to indicate EOF. ** ** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise. ** It is not an error if there are no matches. */ static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){ int rc = SQLITE_OK; pNode->bEof = 0; pNode->bNomatch = 0; if( Fts5NodeIsString(pNode) ){ /* Initialize all term iterators in the NEAR object. */ rc = fts5ExprNearInitAll(pExpr, pNode); }else{ int i; int nEof = 0; for(i=0; i<pNode->nChild && rc==SQLITE_OK; i++){ Fts5ExprNode *pChild = pNode->apChild[i]; rc = fts5ExprNodeFirst(pExpr, pNode->apChild[i]); assert( pChild->bEof==0 || pChild->bEof==1 ); nEof += pChild->bEof; } pNode->iRowid = pNode->apChild[0]->iRowid; switch( pNode->eType ){ case FTS5_AND: if( nEof>0 ) fts5ExprSetEof(pNode); break; case FTS5_OR: if( pNode->nChild==nEof ) fts5ExprSetEof(pNode); break; default: assert( pNode->eType==FTS5_NOT ); pNode->bEof = pNode->apChild[0]->bEof; break; } } if( rc==SQLITE_OK ){ rc = fts5ExprNodeTest(pExpr, pNode); } return rc; } /* ** Begin iterating through the set of documents in index pIdx matched by |
︙ | ︙ | |||
173081 173082 173083 173084 173085 173086 173087 | ** ** Return SQLITE_OK if successful, or an SQLite error code otherwise. It ** is not considered an error if the query does not match any documents. */ static int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){ Fts5ExprNode *pRoot = p->pRoot; int rc = SQLITE_OK; | | | > > > | | | 173620 173621 173622 173623 173624 173625 173626 173627 173628 173629 173630 173631 173632 173633 173634 173635 173636 173637 173638 173639 173640 173641 173642 173643 173644 173645 173646 173647 173648 173649 173650 173651 173652 173653 173654 173655 173656 173657 173658 173659 173660 173661 173662 173663 173664 173665 173666 173667 173668 173669 173670 173671 173672 173673 173674 173675 | ** ** Return SQLITE_OK if successful, or an SQLite error code otherwise. It ** is not considered an error if the query does not match any documents. */ static int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){ Fts5ExprNode *pRoot = p->pRoot; int rc = SQLITE_OK; if( pRoot->xNext ){ p->pIndex = pIdx; p->bDesc = bDesc; rc = fts5ExprNodeFirst(p, pRoot); /* If not at EOF but the current rowid occurs earlier than iFirst in ** the iteration order, move to document iFirst or later. */ if( pRoot->bEof==0 && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 ){ rc = fts5ExprNodeNext(p, pRoot, 1, iFirst); } /* If the iterator is not at a real match, skip forward until it is. */ while( pRoot->bNomatch ){ assert( pRoot->bEof==0 && rc==SQLITE_OK ); rc = fts5ExprNodeNext(p, pRoot, 0, 0); } } return rc; } /* ** Move to the next document ** ** Return SQLITE_OK if successful, or an SQLite error code otherwise. It ** is not considered an error if the query does not match any documents. */ static int sqlite3Fts5ExprNext(Fts5Expr *p, i64 iLast){ int rc; Fts5ExprNode *pRoot = p->pRoot; assert( pRoot->bEof==0 && pRoot->bNomatch==0 ); do { rc = fts5ExprNodeNext(p, pRoot, 0, 0); assert( pRoot->bNomatch==0 || (rc==SQLITE_OK && pRoot->bEof==0) ); }while( pRoot->bNomatch ); if( fts5RowidCmp(p, pRoot->iRowid, iLast)>0 ){ pRoot->bEof = 1; } return rc; } static int sqlite3Fts5ExprEof(Fts5Expr *p){ return p->pRoot->bEof; } static i64 sqlite3Fts5ExprRowid(Fts5Expr *p){ return p->pRoot->iRowid; } static int fts5ParseStringFromToken(Fts5Token *pToken, char **pz){ |
︙ | ︙ | |||
173144 173145 173146 173147 173148 173149 173150 | int i; for(i=0; i<pPhrase->nTerm; i++){ Fts5ExprTerm *pSyn; Fts5ExprTerm *pNext; Fts5ExprTerm *pTerm = &pPhrase->aTerm[i]; sqlite3_free(pTerm->zTerm); sqlite3Fts5IterClose(pTerm->pIter); | < > | 173686 173687 173688 173689 173690 173691 173692 173693 173694 173695 173696 173697 173698 173699 173700 173701 173702 173703 | int i; for(i=0; i<pPhrase->nTerm; i++){ Fts5ExprTerm *pSyn; Fts5ExprTerm *pNext; Fts5ExprTerm *pTerm = &pPhrase->aTerm[i]; sqlite3_free(pTerm->zTerm); sqlite3Fts5IterClose(pTerm->pIter); for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){ pNext = pSyn->pSynonym; sqlite3Fts5IterClose(pSyn->pIter); fts5BufferFree((Fts5Buffer*)&pSyn[1]); sqlite3_free(pSyn); } } if( pPhrase->poslist.nSpace>0 ) fts5BufferFree(&pPhrase->poslist); sqlite3_free(pPhrase); } } |
︙ | ︙ | |||
173235 173236 173237 173238 173239 173240 173241 | /* If an error has already occurred, this is a no-op */ if( pCtx->rc!=SQLITE_OK ) return pCtx->rc; assert( pPhrase==0 || pPhrase->nTerm>0 ); if( pPhrase && (tflags & FTS5_TOKEN_COLOCATED) ){ Fts5ExprTerm *pSyn; | | | | 173777 173778 173779 173780 173781 173782 173783 173784 173785 173786 173787 173788 173789 173790 173791 173792 173793 173794 173795 173796 173797 | /* If an error has already occurred, this is a no-op */ if( pCtx->rc!=SQLITE_OK ) return pCtx->rc; assert( pPhrase==0 || pPhrase->nTerm>0 ); if( pPhrase && (tflags & FTS5_TOKEN_COLOCATED) ){ Fts5ExprTerm *pSyn; int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1; pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte); if( pSyn==0 ){ rc = SQLITE_NOMEM; }else{ memset(pSyn, 0, nByte); pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer); memcpy(pSyn->zTerm, pToken, nToken); pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym; pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn; } }else{ Fts5ExprTerm *pTerm; if( pPhrase==0 || (pPhrase->nTerm % SZALLOC)==0 ){ |
︙ | ︙ | |||
173420 173421 173422 173423 173424 173425 173426 173427 173428 173429 173430 173431 173432 173433 173434 173435 | pNew->apExprPhrase[0] = sCtx.pPhrase; pNew->pRoot->pNear->apPhrase[0] = sCtx.pPhrase; pNew->pRoot->pNear->nPhrase = 1; sCtx.pPhrase->pNode = pNew->pRoot; if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){ pNew->pRoot->eType = FTS5_TERM; }else{ pNew->pRoot->eType = FTS5_STRING; } }else{ sqlite3Fts5ExprFree(pNew); fts5ExprPhraseFree(sCtx.pPhrase); pNew = 0; } | > > | 173962 173963 173964 173965 173966 173967 173968 173969 173970 173971 173972 173973 173974 173975 173976 173977 173978 173979 | pNew->apExprPhrase[0] = sCtx.pPhrase; pNew->pRoot->pNear->apPhrase[0] = sCtx.pPhrase; pNew->pRoot->pNear->nPhrase = 1; sCtx.pPhrase->pNode = pNew->pRoot; if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){ pNew->pRoot->eType = FTS5_TERM; pNew->pRoot->xNext = fts5ExprNodeNext_TERM; }else{ pNew->pRoot->eType = FTS5_STRING; pNew->pRoot->xNext = fts5ExprNodeNext_STRING; } }else{ sqlite3Fts5ExprFree(pNew); fts5ExprPhraseFree(sCtx.pPhrase); pNew = 0; } |
︙ | ︙ | |||
173568 173569 173570 173571 173572 173573 173574 173575 173576 173577 173578 173579 173580 173581 | if( pNear ){ pNear->pColset = pColset; }else{ sqlite3_free(pColset); } } static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ int nByte = sizeof(Fts5ExprNode*) * pSub->nChild; memcpy(&p->apChild[p->nChild], pSub->apChild, nByte); p->nChild += pSub->nChild; sqlite3_free(pSub); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 174112 174113 174114 174115 174116 174117 174118 174119 174120 174121 174122 174123 174124 174125 174126 174127 174128 174129 174130 174131 174132 174133 174134 174135 174136 174137 174138 174139 174140 174141 174142 174143 174144 174145 174146 174147 174148 174149 174150 174151 174152 174153 174154 174155 174156 174157 | if( pNear ){ pNear->pColset = pColset; }else{ sqlite3_free(pColset); } } static void fts5ExprAssignXNext(Fts5ExprNode *pNode){ switch( pNode->eType ){ case FTS5_STRING: { Fts5ExprNearset *pNear = pNode->pNear; if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1 && pNear->apPhrase[0]->aTerm[0].pSynonym==0 ){ pNode->eType = FTS5_TERM; pNode->xNext = fts5ExprNodeNext_TERM; }else{ pNode->xNext = fts5ExprNodeNext_STRING; } break; }; case FTS5_OR: { pNode->xNext = fts5ExprNodeNext_OR; break; }; case FTS5_AND: { pNode->xNext = fts5ExprNodeNext_AND; break; }; default: assert( pNode->eType==FTS5_NOT ); { pNode->xNext = fts5ExprNodeNext_NOT; break; }; } } static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ int nByte = sizeof(Fts5ExprNode*) * pSub->nChild; memcpy(&p->apChild[p->nChild], pSub->apChild, nByte); p->nChild += pSub->nChild; sqlite3_free(pSub); |
︙ | ︙ | |||
173618 173619 173620 173621 173622 173623 173624 173625 173626 173627 173628 173629 | nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1); pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); if( pRet ){ pRet->eType = eType; pRet->pNear = pNear; if( eType==FTS5_STRING ){ int iPhrase; for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){ pNear->apPhrase[iPhrase]->pNode = pRet; } | > < < < | | > > > | 174194 174195 174196 174197 174198 174199 174200 174201 174202 174203 174204 174205 174206 174207 174208 174209 174210 174211 174212 174213 174214 174215 174216 174217 174218 174219 174220 174221 174222 174223 174224 174225 174226 174227 174228 | nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1); pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); if( pRet ){ pRet->eType = eType; pRet->pNear = pNear; fts5ExprAssignXNext(pRet); if( eType==FTS5_STRING ){ int iPhrase; for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){ pNear->apPhrase[iPhrase]->pNode = pRet; } if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL && (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm!=1) ){ assert( pParse->rc==SQLITE_OK ); pParse->rc = SQLITE_ERROR; assert( pParse->zErr==0 ); pParse->zErr = sqlite3_mprintf( "fts5: %s queries are not supported (detail!=full)", pNear->nPhrase==1 ? "phrase": "NEAR" ); sqlite3_free(pRet); pRet = 0; } }else{ fts5ExprAddChildren(pRet, pLeft); fts5ExprAddChildren(pRet, pRight); } } } |
︙ | ︙ | |||
173920 173921 173922 173923 173924 173925 173926 | rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr); if( rc==SQLITE_OK ){ rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pExpr, &zErr); } if( rc==SQLITE_OK ){ char *zText; | | | 174497 174498 174499 174500 174501 174502 174503 174504 174505 174506 174507 174508 174509 174510 174511 | rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr); if( rc==SQLITE_OK ){ rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pExpr, &zErr); } if( rc==SQLITE_OK ){ char *zText; if( pExpr->pRoot->xNext==0 ){ zText = sqlite3_mprintf(""); }else if( bTcl ){ zText = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->pRoot); }else{ zText = fts5ExprPrint(pConfig, pExpr->pRoot); } if( zText==0 ){ |
︙ | ︙ | |||
174020 174021 174022 174023 174024 174025 174026 | { "fts5_isalnum", fts5ExprIsAlnum }, { "fts5_fold", fts5ExprFold }, }; int i; int rc = SQLITE_OK; void *pCtx = (void*)pGlobal; | | | 174597 174598 174599 174600 174601 174602 174603 174604 174605 174606 174607 174608 174609 174610 174611 | { "fts5_isalnum", fts5ExprIsAlnum }, { "fts5_fold", fts5ExprFold }, }; int i; int rc = SQLITE_OK; void *pCtx = (void*)pGlobal; for(i=0; rc==SQLITE_OK && i<ArraySize(aFunc); i++){ struct Fts5ExprFunc *p = &aFunc[i]; rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0); } /* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */ #ifndef NDEBUG (void)sqlite3Fts5ParserTrace; |
︙ | ︙ | |||
174258 174259 174260 174261 174262 174263 174264 174265 174266 174267 174268 174269 174270 | int *pnCollist ){ Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase]; Fts5ExprNode *pNode = pPhrase->pNode; int rc = SQLITE_OK; assert( iPhrase>=0 && iPhrase<pExpr->nPhrase ); if( pNode->bEof==0 && pNode->iRowid==pExpr->pRoot->iRowid && pPhrase->poslist.n>0 ){ Fts5ExprTerm *pTerm = &pPhrase->aTerm[0]; if( pTerm->pSynonym ){ | > > | < | < < < < | | < < | | 174835 174836 174837 174838 174839 174840 174841 174842 174843 174844 174845 174846 174847 174848 174849 174850 174851 174852 174853 174854 174855 174856 174857 174858 174859 174860 174861 174862 174863 | int *pnCollist ){ Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase]; Fts5ExprNode *pNode = pPhrase->pNode; int rc = SQLITE_OK; assert( iPhrase>=0 && iPhrase<pExpr->nPhrase ); assert( pExpr->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); if( pNode->bEof==0 && pNode->iRowid==pExpr->pRoot->iRowid && pPhrase->poslist.n>0 ){ Fts5ExprTerm *pTerm = &pPhrase->aTerm[0]; if( pTerm->pSynonym ){ Fts5Buffer *pBuf = (Fts5Buffer*)&pTerm->pSynonym[1]; rc = fts5ExprSynonymList( pTerm, 1, 0, pNode->iRowid, pBuf, (u8**)ppCollist, pnCollist ); }else{ *ppCollist = pPhrase->aTerm[0].pIter->pData; *pnCollist = pPhrase->aTerm[0].pIter->nData; } }else{ *ppCollist = 0; *pnCollist = 0; } return rc; |
︙ | ︙ | |||
175078 175079 175080 175081 175082 175083 175084 175085 175086 175087 175088 175089 175090 175091 | #define FTS5_DATA_ZERO_PADDING 8 #define FTS5_DATA_PADDING 20 typedef struct Fts5Data Fts5Data; typedef struct Fts5DlidxIter Fts5DlidxIter; typedef struct Fts5DlidxLvl Fts5DlidxLvl; typedef struct Fts5DlidxWriter Fts5DlidxWriter; typedef struct Fts5PageWriter Fts5PageWriter; typedef struct Fts5SegIter Fts5SegIter; typedef struct Fts5DoclistIter Fts5DoclistIter; typedef struct Fts5SegWriter Fts5SegWriter; typedef struct Fts5Structure Fts5Structure; typedef struct Fts5StructureLevel Fts5StructureLevel; typedef struct Fts5StructureSegment Fts5StructureSegment; | > | 175650 175651 175652 175653 175654 175655 175656 175657 175658 175659 175660 175661 175662 175663 175664 | #define FTS5_DATA_ZERO_PADDING 8 #define FTS5_DATA_PADDING 20 typedef struct Fts5Data Fts5Data; typedef struct Fts5DlidxIter Fts5DlidxIter; typedef struct Fts5DlidxLvl Fts5DlidxLvl; typedef struct Fts5DlidxWriter Fts5DlidxWriter; typedef struct Fts5Iter Fts5Iter; typedef struct Fts5PageWriter Fts5PageWriter; typedef struct Fts5SegIter Fts5SegIter; typedef struct Fts5DoclistIter Fts5DoclistIter; typedef struct Fts5SegWriter Fts5SegWriter; typedef struct Fts5Structure Fts5Structure; typedef struct Fts5StructureLevel Fts5StructureLevel; typedef struct Fts5StructureSegment Fts5StructureSegment; |
︙ | ︙ | |||
175320 175321 175322 175323 175324 175325 175326 | ** aFirst[1] contains the index in aSeg[] of the iterator that points to ** the smallest key overall. aFirst[0] is unused. ** ** poslist: ** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered. ** There is no way to tell if this is populated or not. */ | | > > > > > > < < | 175893 175894 175895 175896 175897 175898 175899 175900 175901 175902 175903 175904 175905 175906 175907 175908 175909 175910 175911 175912 175913 175914 175915 175916 175917 175918 175919 175920 | ** aFirst[1] contains the index in aSeg[] of the iterator that points to ** the smallest key overall. aFirst[0] is unused. ** ** poslist: ** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered. ** There is no way to tell if this is populated or not. */ struct Fts5Iter { Fts5IndexIter base; /* Base class containing output vars */ Fts5Index *pIndex; /* Index that owns this iterator */ Fts5Structure *pStruct; /* Database structure for this iterator */ Fts5Buffer poslist; /* Buffer containing current poslist */ Fts5Colset *pColset; /* Restrict matches to these columns */ /* Invoked to set output variables. */ void (*xSetOutputs)(Fts5Iter*, Fts5SegIter*); int nSeg; /* Size of aSeg[] array */ int bRev; /* True to iterate in reverse order */ u8 bSkipEmpty; /* True to skip deleted entries */ i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */ Fts5CResult *aFirst; /* Current merge state (see above) */ Fts5SegIter aSeg[1]; /* Array of segment iterators */ }; |
︙ | ︙ | |||
176569 176570 176571 176572 176573 176574 176575 | } /* ** Return true if the iterator passed as the second argument currently ** points to a delete marker. A delete marker is an entry with a 0 byte ** position-list. */ | | | 177146 177147 177148 177149 177150 177151 177152 177153 177154 177155 177156 177157 177158 177159 177160 | } /* ** Return true if the iterator passed as the second argument currently ** points to a delete marker. A delete marker is an entry with a 0 byte ** position-list. */ static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5Iter *pIter){ Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst]; return (p->rc==SQLITE_OK && pSeg->pLeaf && pSeg->nPos==0); } /* ** Advance iterator pIter to the next entry. ** |
︙ | ︙ | |||
176841 176842 176843 176844 176845 176846 176847 | int iPoslist; if( pIter->iTermLeafPgno==pIter->iLeafPgno ){ iPoslist = pIter->iTermLeafOffset; }else{ iPoslist = 4; } fts5IndexSkipVarint(pLeaf->p, iPoslist); | < < < | 177418 177419 177420 177421 177422 177423 177424 177425 177426 177427 177428 177429 177430 177431 | int iPoslist; if( pIter->iTermLeafPgno==pIter->iLeafPgno ){ iPoslist = pIter->iTermLeafOffset; }else{ iPoslist = 4; } fts5IndexSkipVarint(pLeaf->p, iPoslist); pIter->iLeafOffset = iPoslist; /* If this condition is true then the largest rowid for the current ** term may not be stored on the current page. So search forward to ** see where said rowid really is. */ if( pIter->iEndofDoclist>=pLeaf->szLeaf ){ int pgno; |
︙ | ︙ | |||
177075 177076 177077 177078 177079 177080 177081 | Fts5StructureSegment *pSeg, /* Description of segment */ Fts5SegIter *pIter /* Object to populate */ ){ int iPg = 1; int bGe = (flags & FTS5INDEX_QUERY_SCAN); int bDlidx = 0; /* True if there is a doclist-index */ | < < < | 177649 177650 177651 177652 177653 177654 177655 177656 177657 177658 177659 177660 177661 177662 | Fts5StructureSegment *pSeg, /* Description of segment */ Fts5SegIter *pIter /* Object to populate */ ){ int iPg = 1; int bGe = (flags & FTS5INDEX_QUERY_SCAN); int bDlidx = 0; /* True if there is a doclist-index */ assert( bGe==0 || (flags & FTS5INDEX_QUERY_DESC)==0 ); assert( pTerm && nTerm ); memset(pIter, 0, sizeof(*pIter)); pIter->pSeg = pSeg; /* This block sets stack variable iPg to the leaf page number that may ** contain term (pTerm/nTerm), if it is present in the segment. */ |
︙ | ︙ | |||
177223 177224 177225 177226 177227 177228 177229 | /* ** This function is used as part of the big assert() procedure implemented by ** fts5AssertMultiIterSetup(). It ensures that the result currently stored ** in *pRes is the correct result of comparing the current positions of the ** two iterators. */ static void fts5AssertComparisonResult( | | | 177794 177795 177796 177797 177798 177799 177800 177801 177802 177803 177804 177805 177806 177807 177808 | /* ** This function is used as part of the big assert() procedure implemented by ** fts5AssertMultiIterSetup(). It ensures that the result currently stored ** in *pRes is the correct result of comparing the current positions of the ** two iterators. */ static void fts5AssertComparisonResult( Fts5Iter *pIter, Fts5SegIter *p1, Fts5SegIter *p2, Fts5CResult *pRes ){ int i1 = p1 - pIter->aSeg; int i2 = p2 - pIter->aSeg; |
︙ | ︙ | |||
177264 177265 177266 177267 177268 177269 177270 | /* ** This function is a no-op unless SQLITE_DEBUG is defined when this module ** is compiled. In that case, this function is essentially an assert() ** statement used to verify that the contents of the pIter->aFirst[] array ** are correct. */ | | | | 177835 177836 177837 177838 177839 177840 177841 177842 177843 177844 177845 177846 177847 177848 177849 177850 177851 177852 177853 177854 | /* ** This function is a no-op unless SQLITE_DEBUG is defined when this module ** is compiled. In that case, this function is essentially an assert() ** statement used to verify that the contents of the pIter->aFirst[] array ** are correct. */ static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5Iter *pIter){ if( p->rc==SQLITE_OK ){ Fts5SegIter *pFirst = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; int i; assert( (pFirst->pLeaf==0)==pIter->base.bEof ); /* Check that pIter->iSwitchRowid is set correctly. */ for(i=0; i<pIter->nSeg; i++){ Fts5SegIter *p1 = &pIter->aSeg[i]; assert( p1==pFirst || p1->pLeaf==0 || fts5BufferCompare(&pFirst->term, &p1->term) |
︙ | ︙ | |||
177309 177310 177311 177312 177313 177314 177315 | ** Do the comparison necessary to populate pIter->aFirst[iOut]. ** ** If the returned value is non-zero, then it is the index of an entry ** in the pIter->aSeg[] array that is (a) not at EOF, and (b) pointing ** to a key that is a duplicate of another, higher priority, ** segment-iterator in the pSeg->aSeg[] array. */ | | | 177880 177881 177882 177883 177884 177885 177886 177887 177888 177889 177890 177891 177892 177893 177894 | ** Do the comparison necessary to populate pIter->aFirst[iOut]. ** ** If the returned value is non-zero, then it is the index of an entry ** in the pIter->aSeg[] array that is (a) not at EOF, and (b) pointing ** to a key that is a duplicate of another, higher priority, ** segment-iterator in the pSeg->aSeg[] array. */ static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){ int i1; /* Index of left-hand Fts5SegIter */ int i2; /* Index of right-hand Fts5SegIter */ int iRes; Fts5SegIter *p1; /* Left-hand Fts5SegIter */ Fts5SegIter *p2; /* Right-hand Fts5SegIter */ Fts5CResult *pRes = &pIter->aFirst[iOut]; |
︙ | ︙ | |||
177455 177456 177457 177458 177459 177460 177461 | }while( p->rc==SQLITE_OK ); } /* ** Free the iterator object passed as the second argument. */ | | | | 178026 178027 178028 178029 178030 178031 178032 178033 178034 178035 178036 178037 178038 178039 178040 178041 178042 178043 178044 178045 178046 178047 178048 178049 178050 178051 178052 178053 178054 | }while( p->rc==SQLITE_OK ); } /* ** Free the iterator object passed as the second argument. */ static void fts5MultiIterFree(Fts5Index *p, Fts5Iter *pIter){ if( pIter ){ int i; for(i=0; i<pIter->nSeg; i++){ fts5SegIterClear(&pIter->aSeg[i]); } fts5StructureRelease(pIter->pStruct); fts5BufferFree(&pIter->poslist); sqlite3_free(pIter); } } static void fts5MultiIterAdvanced( Fts5Index *p, /* FTS5 backend to iterate within */ Fts5Iter *pIter, /* Iterator to update aFirst[] array for */ int iChanged, /* Index of sub-iterator just advanced */ int iMinset /* Minimum entry in aFirst[] to set */ ){ int i; for(i=(pIter->nSeg+iChanged)/2; i>=iMinset && p->rc==SQLITE_OK; i=i/2){ int iEq; if( (iEq = fts5MultiIterDoCompare(pIter, i)) ){ |
︙ | ︙ | |||
177497 177498 177499 177500 177501 177502 177503 | ** ** If non-zero is returned, the caller should call fts5MultiIterAdvanced() ** on the iterator instead. That function does the same as this one, except ** that it deals with more complicated cases as well. */ static int fts5MultiIterAdvanceRowid( Fts5Index *p, /* FTS5 backend to iterate within */ | | | > | 178068 178069 178070 178071 178072 178073 178074 178075 178076 178077 178078 178079 178080 178081 178082 178083 178084 | ** ** If non-zero is returned, the caller should call fts5MultiIterAdvanced() ** on the iterator instead. That function does the same as this one, except ** that it deals with more complicated cases as well. */ static int fts5MultiIterAdvanceRowid( Fts5Index *p, /* FTS5 backend to iterate within */ Fts5Iter *pIter, /* Iterator to update aFirst[] array for */ int iChanged, /* Index of sub-iterator just advanced */ Fts5SegIter **ppFirst ){ Fts5SegIter *pNew = &pIter->aSeg[iChanged]; if( pNew->iRowid==pIter->iSwitchRowid || (pNew->iRowid<pIter->iSwitchRowid)==pIter->bRev ){ int i; |
︙ | ︙ | |||
177531 177532 177533 177534 177535 177536 177537 177538 177539 177540 177541 177542 177543 | pRes->iFirst = (u16)(pNew - pIter->aSeg); if( i==1 ) break; pOther = &pIter->aSeg[ pIter->aFirst[i ^ 0x0001].iFirst ]; } } return 0; } /* ** Set the pIter->bEof variable based on the state of the sub-iterators. */ | > | | | < | < > | | | | | | | | | | | | | | > > | > | > > > > | | < | | > | > | | | > < < < < < < < < < < < | | < < < > | < < < < < < > > | < < | < | | < < < | < < | > > > | | < < < < | | | > > > > < < < < < < < | < > > > > > | < < | < < < | > | < < < < < | < > | | | < > | | | | > | | < | | > > > < < | < < | < < < | < < < < < < < | | < < < > > > | < | > > | > < < | < > | < < | | < | < < | < < | < | < < < < < < < < < < < < < < < | | < < < < < < < < > > > | > > | < < < < < < < | | | < > | > > > | | < > > | | | < < < < < < < < > > | 178103 178104 178105 178106 178107 178108 178109 178110 178111 178112 178113 178114 178115 178116 178117 178118 178119 178120 178121 178122 178123 178124 178125 178126 178127 178128 178129 178130 178131 178132 178133 178134 178135 178136 178137 178138 178139 178140 178141 178142 178143 178144 178145 178146 178147 178148 178149 178150 178151 178152 178153 178154 178155 178156 178157 178158 178159 178160 178161 178162 178163 178164 178165 178166 178167 178168 178169 178170 178171 178172 178173 178174 178175 178176 178177 178178 178179 178180 178181 178182 178183 178184 178185 178186 178187 178188 178189 178190 178191 178192 178193 178194 178195 178196 178197 178198 178199 178200 178201 178202 178203 178204 178205 178206 178207 178208 178209 178210 178211 178212 178213 178214 178215 178216 178217 178218 178219 178220 178221 178222 178223 178224 178225 178226 178227 178228 178229 178230 178231 178232 178233 178234 178235 178236 178237 178238 178239 178240 178241 178242 178243 178244 178245 178246 178247 178248 178249 178250 178251 178252 178253 178254 178255 178256 178257 178258 178259 178260 178261 178262 178263 178264 178265 178266 178267 178268 178269 178270 178271 178272 178273 178274 178275 178276 178277 178278 178279 178280 178281 178282 178283 178284 178285 178286 178287 178288 178289 178290 178291 178292 178293 178294 178295 178296 178297 178298 178299 178300 178301 178302 178303 178304 178305 178306 178307 178308 178309 178310 178311 178312 178313 178314 178315 178316 178317 178318 178319 178320 178321 178322 178323 178324 178325 178326 178327 178328 178329 178330 178331 178332 178333 178334 178335 | pRes->iFirst = (u16)(pNew - pIter->aSeg); if( i==1 ) break; pOther = &pIter->aSeg[ pIter->aFirst[i ^ 0x0001].iFirst ]; } } *ppFirst = pNew; return 0; } /* ** Set the pIter->bEof variable based on the state of the sub-iterators. */ static void fts5MultiIterSetEof(Fts5Iter *pIter){ Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; pIter->base.bEof = pSeg->pLeaf==0; pIter->iSwitchRowid = pSeg->iRowid; } /* ** Move the iterator to the next entry. ** ** If an error occurs, an error code is left in Fts5Index.rc. It is not ** considered an error if the iterator reaches EOF, or if it is already at ** EOF when this function is called. */ static void fts5MultiIterNext( Fts5Index *p, Fts5Iter *pIter, int bFrom, /* True if argument iFrom is valid */ i64 iFrom /* Advance at least as far as this */ ){ int bUseFrom = bFrom; while( p->rc==SQLITE_OK ){ int iFirst = pIter->aFirst[1].iFirst; int bNewTerm = 0; Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; assert( p->rc==SQLITE_OK ); if( bUseFrom && pSeg->pDlidx ){ fts5SegIterNextFrom(p, pSeg, iFrom); }else{ pSeg->xNext(p, pSeg, &bNewTerm); } if( pSeg->pLeaf==0 || bNewTerm || fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg) ){ fts5MultiIterAdvanced(p, pIter, iFirst, 1); fts5MultiIterSetEof(pIter); pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst]; if( pSeg->pLeaf==0 ) return; } fts5AssertMultiIterSetup(p, pIter); assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf ); if( pIter->bSkipEmpty==0 || pSeg->nPos ){ pIter->xSetOutputs(pIter, pSeg); return; } bUseFrom = 0; } } static void fts5MultiIterNext2( Fts5Index *p, Fts5Iter *pIter, int *pbNewTerm /* OUT: True if *might* be new term */ ){ assert( pIter->bSkipEmpty ); if( p->rc==SQLITE_OK ){ do { int iFirst = pIter->aFirst[1].iFirst; Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; int bNewTerm = 0; assert( p->rc==SQLITE_OK ); pSeg->xNext(p, pSeg, &bNewTerm); if( pSeg->pLeaf==0 || bNewTerm || fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg) ){ fts5MultiIterAdvanced(p, pIter, iFirst, 1); fts5MultiIterSetEof(pIter); *pbNewTerm = 1; }else{ *pbNewTerm = 0; } fts5AssertMultiIterSetup(p, pIter); }while( fts5MultiIterIsEmpty(p, pIter) ); } } static void fts5IterSetOutputs_Noop(Fts5Iter *pIter, Fts5SegIter *pSeg){ } static Fts5Iter *fts5MultiIterAlloc( Fts5Index *p, /* FTS5 backend to iterate within */ int nSeg ){ Fts5Iter *pNew; int nSlot; /* Power of two >= nSeg */ for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2); pNew = fts5IdxMalloc(p, sizeof(Fts5Iter) + /* pNew */ sizeof(Fts5SegIter) * (nSlot-1) + /* pNew->aSeg[] */ sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */ ); if( pNew ){ pNew->nSeg = nSlot; pNew->aFirst = (Fts5CResult*)&pNew->aSeg[nSlot]; pNew->pIndex = p; pNew->xSetOutputs = fts5IterSetOutputs_Noop; } return pNew; } static void fts5PoslistCallback( Fts5Index *p, void *pContext, const u8 *pChunk, int nChunk ){ assert_nc( nChunk>=0 ); if( nChunk>0 ){ fts5BufferSafeAppendBlob((Fts5Buffer*)pContext, pChunk, nChunk); } } typedef struct PoslistCallbackCtx PoslistCallbackCtx; struct PoslistCallbackCtx { Fts5Buffer *pBuf; /* Append to this buffer */ Fts5Colset *pColset; /* Restrict matches to this column */ int eState; /* See above */ }; typedef struct PoslistOffsetsCtx PoslistOffsetsCtx; struct PoslistOffsetsCtx { Fts5Buffer *pBuf; /* Append to this buffer */ Fts5Colset *pColset; /* Restrict matches to this column */ int iRead; int iWrite; }; /* ** TODO: Make this more efficient! */ static int fts5IndexColsetTest(Fts5Colset *pColset, int iCol){ int i; for(i=0; i<pColset->nCol; i++){ if( pColset->aiCol[i]==iCol ) return 1; } return 0; } static void fts5PoslistOffsetsCallback( Fts5Index *p, void *pContext, const u8 *pChunk, int nChunk ){ PoslistOffsetsCtx *pCtx = (PoslistOffsetsCtx*)pContext; assert_nc( nChunk>=0 ); if( nChunk>0 ){ int i = 0; while( i<nChunk ){ int iVal; i += fts5GetVarint32(&pChunk[i], iVal); iVal += pCtx->iRead - 2; pCtx->iRead = iVal; if( fts5IndexColsetTest(pCtx->pColset, iVal) ){ fts5BufferSafeAppendVarint(pCtx->pBuf, iVal + 2 - pCtx->iWrite); pCtx->iWrite = iVal; } } } } static void fts5PoslistFilterCallback( Fts5Index *p, void *pContext, const u8 *pChunk, int nChunk ){ PoslistCallbackCtx *pCtx = (PoslistCallbackCtx*)pContext; assert_nc( nChunk>=0 ); if( nChunk>0 ){ /* Search through to find the first varint with value 1. This is the ** start of the next columns hits. */ int i = 0; int iStart = 0; if( pCtx->eState==2 ){ int iCol; fts5FastGetVarint32(pChunk, i, iCol); if( fts5IndexColsetTest(pCtx->pColset, iCol) ){ pCtx->eState = 1; fts5BufferSafeAppendVarint(pCtx->pBuf, 1); }else{ pCtx->eState = 0; } } do { while( i<nChunk && pChunk[i]!=0x01 ){ while( pChunk[i] & 0x80 ) i++; i++; } if( pCtx->eState ){ fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart); } if( i<nChunk ){ int iCol; iStart = i; i++; if( i>=nChunk ){ pCtx->eState = 2; }else{ fts5FastGetVarint32(pChunk, i, iCol); pCtx->eState = fts5IndexColsetTest(pCtx->pColset, iCol); if( pCtx->eState ){ fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart); iStart = i; } } } }while( i<nChunk ); } } static void fts5ChunkIterate( Fts5Index *p, /* Index object */ Fts5SegIter *pSeg, /* Poslist of this iterator */ void *pCtx, /* Context pointer for xChunk callback */ void (*xChunk)(Fts5Index*, void*, const u8*, int) |
︙ | ︙ | |||
177864 177865 177866 177867 177868 177869 177870 | pSeg->pNextLeaf = pData; pData = 0; } } } } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 178365 178366 178367 178368 178369 178370 178371 178372 178373 178374 178375 178376 178377 178378 178379 178380 178381 178382 178383 178384 178385 178386 178387 178388 178389 178390 178391 178392 178393 178394 178395 178396 178397 178398 178399 178400 178401 178402 178403 178404 178405 178406 178407 178408 178409 178410 178411 178412 178413 178414 178415 178416 178417 178418 178419 178420 178421 178422 178423 178424 178425 178426 178427 178428 178429 178430 178431 178432 178433 178434 178435 178436 178437 178438 178439 178440 178441 178442 178443 178444 178445 178446 178447 178448 178449 178450 178451 178452 178453 178454 178455 178456 178457 178458 178459 178460 178461 178462 178463 178464 178465 178466 178467 178468 178469 178470 178471 178472 178473 178474 178475 178476 178477 178478 178479 178480 178481 178482 178483 178484 178485 178486 178487 178488 178489 178490 178491 178492 178493 178494 178495 178496 178497 178498 178499 178500 178501 178502 178503 178504 178505 178506 178507 178508 178509 178510 178511 178512 178513 178514 178515 178516 178517 178518 178519 178520 178521 178522 178523 178524 178525 178526 178527 178528 178529 178530 178531 178532 178533 178534 178535 178536 178537 178538 178539 178540 178541 178542 178543 178544 178545 178546 178547 178548 178549 178550 178551 178552 178553 178554 178555 178556 178557 178558 178559 178560 178561 178562 178563 178564 178565 178566 178567 178568 178569 178570 178571 178572 178573 178574 178575 178576 178577 178578 178579 178580 178581 178582 178583 178584 178585 178586 178587 178588 178589 178590 178591 178592 178593 178594 178595 178596 178597 178598 178599 178600 178601 178602 178603 178604 178605 178606 178607 178608 178609 178610 178611 178612 178613 178614 178615 178616 178617 178618 178619 178620 178621 178622 178623 178624 178625 178626 178627 178628 178629 178630 178631 178632 178633 178634 178635 178636 178637 178638 178639 178640 178641 178642 178643 178644 178645 178646 178647 178648 178649 178650 178651 178652 178653 178654 178655 178656 178657 178658 178659 178660 178661 178662 178663 178664 178665 178666 178667 178668 178669 178670 178671 178672 178673 178674 178675 178676 178677 178678 178679 178680 178681 178682 178683 178684 178685 178686 178687 178688 178689 178690 178691 178692 178693 178694 178695 178696 178697 178698 178699 178700 178701 178702 178703 178704 178705 178706 178707 178708 178709 178710 178711 178712 178713 178714 178715 178716 178717 178718 178719 178720 178721 178722 178723 178724 178725 178726 178727 178728 178729 178730 178731 178732 178733 178734 178735 178736 178737 178738 178739 178740 178741 178742 178743 178744 178745 178746 178747 178748 178749 178750 178751 178752 178753 178754 178755 178756 178757 178758 178759 178760 178761 178762 178763 178764 178765 178766 178767 178768 178769 178770 178771 178772 178773 178774 178775 178776 178777 178778 178779 178780 178781 178782 178783 178784 178785 178786 178787 178788 178789 178790 178791 178792 178793 178794 178795 178796 178797 178798 178799 178800 178801 178802 178803 178804 178805 178806 178807 178808 178809 178810 178811 178812 178813 178814 178815 178816 178817 178818 178819 178820 178821 178822 178823 178824 178825 178826 178827 178828 178829 178830 | pSeg->pNextLeaf = pData; pData = 0; } } } } /* ** Iterator pIter currently points to a valid entry (not EOF). This ** function appends the position list data for the current entry to ** buffer pBuf. It does not make a copy of the position-list size ** field. */ static void fts5SegiterPoslist( Fts5Index *p, Fts5SegIter *pSeg, Fts5Colset *pColset, Fts5Buffer *pBuf ){ if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){ if( pColset==0 ){ fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback); }else{ if( p->pConfig->eDetail==FTS5_DETAIL_FULL ){ PoslistCallbackCtx sCtx; sCtx.pBuf = pBuf; sCtx.pColset = pColset; sCtx.eState = fts5IndexColsetTest(pColset, 0); assert( sCtx.eState==0 || sCtx.eState==1 ); fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback); }else{ PoslistOffsetsCtx sCtx; memset(&sCtx, 0, sizeof(sCtx)); sCtx.pBuf = pBuf; sCtx.pColset = pColset; fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistOffsetsCallback); } } } } /* ** IN/OUT parameter (*pa) points to a position list n bytes in size. If ** the position list contains entries for column iCol, then (*pa) is set ** to point to the sub-position-list for that column and the number of ** bytes in it returned. Or, if the argument position list does not ** contain any entries for column iCol, return 0. */ static int fts5IndexExtractCol( const u8 **pa, /* IN/OUT: Pointer to poslist */ int n, /* IN: Size of poslist in bytes */ int iCol /* Column to extract from poslist */ ){ int iCurrent = 0; /* Anything before the first 0x01 is col 0 */ const u8 *p = *pa; const u8 *pEnd = &p[n]; /* One byte past end of position list */ while( iCol>iCurrent ){ /* Advance pointer p until it points to pEnd or an 0x01 byte that is ** not part of a varint. Note that it is not possible for a negative ** or extremely large varint to occur within an uncorrupted position ** list. So the last byte of each varint may be assumed to have a clear ** 0x80 bit. */ while( *p!=0x01 ){ while( *p++ & 0x80 ); if( p>=pEnd ) return 0; } *pa = p++; iCurrent = *p++; if( iCurrent & 0x80 ){ p--; p += fts5GetVarint32(p, iCurrent); } } if( iCol!=iCurrent ) return 0; /* Advance pointer p until it points to pEnd or an 0x01 byte that is ** not part of a varint */ while( p<pEnd && *p!=0x01 ){ while( *p++ & 0x80 ); } return p - (*pa); } static int fts5IndexExtractColset ( Fts5Colset *pColset, /* Colset to filter on */ const u8 *pPos, int nPos, /* Position list */ Fts5Buffer *pBuf /* Output buffer */ ){ int rc = SQLITE_OK; int i; fts5BufferZero(pBuf); for(i=0; i<pColset->nCol; i++){ const u8 *pSub = pPos; int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]); if( nSub ){ fts5BufferAppendBlob(&rc, pBuf, nSub, pSub); } } return rc; } /* ** xSetOutputs callback used by detail=none tables. */ static void fts5IterSetOutputs_None(Fts5Iter *pIter, Fts5SegIter *pSeg){ assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_NONE ); pIter->base.iRowid = pSeg->iRowid; pIter->base.nData = pSeg->nPos; } /* ** xSetOutputs callback used by detail=full and detail=col tables when no ** column filters are specified. */ static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){ pIter->base.iRowid = pSeg->iRowid; pIter->base.nData = pSeg->nPos; assert( pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_NONE ); assert( pIter->pColset==0 ); if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){ /* All data is stored on the current page. Populate the output ** variables to point into the body of the page object. */ pIter->base.pData = &pSeg->pLeaf->p[pSeg->iLeafOffset]; }else{ /* The data is distributed over two or more pages. Copy it into the ** Fts5Iter.poslist buffer and then set the output pointer to point ** to this buffer. */ fts5BufferZero(&pIter->poslist); fts5SegiterPoslist(pIter->pIndex, pSeg, 0, &pIter->poslist); pIter->base.pData = pIter->poslist.p; } } /* ** xSetOutputs callback used by detail=col when there is a column filter ** and there are 100 or more columns. Also called as a fallback from ** fts5IterSetOutputs_Col100 if the column-list spans more than one page. */ static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){ fts5BufferZero(&pIter->poslist); fts5SegiterPoslist(pIter->pIndex, pSeg, pIter->pColset, &pIter->poslist); pIter->base.iRowid = pSeg->iRowid; pIter->base.pData = pIter->poslist.p; pIter->base.nData = pIter->poslist.n; } /* ** xSetOutputs callback used when: ** ** * detail=col, ** * there is a column filter, and ** * the table contains 100 or fewer columns. ** ** The last point is to ensure all column numbers are stored as ** single-byte varints. */ static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){ assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); assert( pIter->pColset ); if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf ){ fts5IterSetOutputs_Col(pIter, pSeg); }else{ u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset]; u8 *pEnd = (u8*)&a[pSeg->nPos]; int iPrev = 0; int *aiCol = pIter->pColset->aiCol; int *aiColEnd = &aiCol[pIter->pColset->nCol]; u8 *aOut = pIter->poslist.p; int iPrevOut = 0; pIter->base.iRowid = pSeg->iRowid; while( a<pEnd ){ iPrev += (int)a++[0] - 2; while( *aiCol<iPrev ){ aiCol++; if( aiCol==aiColEnd ) goto setoutputs_col_out; } if( *aiCol==iPrev ){ *aOut++ = (iPrev - iPrevOut) + 2; iPrevOut = iPrev; } } setoutputs_col_out: pIter->base.pData = pIter->poslist.p; pIter->base.nData = aOut - pIter->poslist.p; } } /* ** xSetOutputs callback used by detail=full when there is a column filter. */ static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){ Fts5Colset *pColset = pIter->pColset; pIter->base.iRowid = pSeg->iRowid; assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_FULL ); assert( pColset ); if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){ /* All data is stored on the current page. Populate the output ** variables to point into the body of the page object. */ const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset]; if( pColset->nCol==1 ){ pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]); pIter->base.pData = a; }else{ fts5BufferZero(&pIter->poslist); fts5IndexExtractColset(pColset, a, pSeg->nPos, &pIter->poslist); pIter->base.pData = pIter->poslist.p; pIter->base.nData = pIter->poslist.n; } }else{ /* The data is distributed over two or more pages. Copy it into the ** Fts5Iter.poslist buffer and then set the output pointer to point ** to this buffer. */ fts5BufferZero(&pIter->poslist); fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist); pIter->base.pData = pIter->poslist.p; pIter->base.nData = pIter->poslist.n; } } static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ if( *pRc==SQLITE_OK ){ Fts5Config *pConfig = pIter->pIndex->pConfig; if( pConfig->eDetail==FTS5_DETAIL_NONE ){ pIter->xSetOutputs = fts5IterSetOutputs_None; } else if( pIter->pColset==0 ){ pIter->xSetOutputs = fts5IterSetOutputs_Nocolset; } else if( pConfig->eDetail==FTS5_DETAIL_FULL ){ pIter->xSetOutputs = fts5IterSetOutputs_Full; } else{ assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS ); if( pConfig->nCol<=100 ){ pIter->xSetOutputs = fts5IterSetOutputs_Col100; sqlite3Fts5BufferSize(pRc, &pIter->poslist, pConfig->nCol); }else{ pIter->xSetOutputs = fts5IterSetOutputs_Col; } } } } /* ** Allocate a new Fts5Iter object. ** ** The new object will be used to iterate through data in structure pStruct. ** If iLevel is -ve, then all data in all segments is merged. Or, if iLevel ** is zero or greater, data from the first nSegment segments on level iLevel ** is merged. ** ** The iterator initially points to the first term/rowid entry in the ** iterated data. */ static void fts5MultiIterNew( Fts5Index *p, /* FTS5 backend to iterate within */ Fts5Structure *pStruct, /* Structure of specific index */ int flags, /* FTS5INDEX_QUERY_XXX flags */ Fts5Colset *pColset, /* Colset to filter on (or NULL) */ const u8 *pTerm, int nTerm, /* Term to seek to (or NULL/0) */ int iLevel, /* Level to iterate (-1 for all) */ int nSegment, /* Number of segments to merge (iLevel>=0) */ Fts5Iter **ppOut /* New object */ ){ int nSeg = 0; /* Number of segment-iters in use */ int iIter = 0; /* */ int iSeg; /* Used to iterate through segments */ Fts5Buffer buf = {0,0,0}; /* Buffer used by fts5SegIterSeekInit() */ Fts5StructureLevel *pLvl; Fts5Iter *pNew; assert( (pTerm==0 && nTerm==0) || iLevel<0 ); /* Allocate space for the new multi-seg-iterator. */ if( p->rc==SQLITE_OK ){ if( iLevel<0 ){ assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) ); nSeg = pStruct->nSegment; nSeg += (p->pHash ? 1 : 0); }else{ nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment); } } *ppOut = pNew = fts5MultiIterAlloc(p, nSeg); if( pNew==0 ) return; pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC)); pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY)); pNew->pStruct = pStruct; pNew->pColset = pColset; fts5StructureRef(pStruct); if( (flags & FTS5INDEX_QUERY_NOOUTPUT)==0 ){ fts5IterSetOutputCb(&p->rc, pNew); } /* Initialize each of the component segment iterators. */ if( p->rc==SQLITE_OK ){ if( iLevel<0 ){ Fts5StructureLevel *pEnd = &pStruct->aLevel[pStruct->nLevel]; if( p->pHash ){ /* Add a segment iterator for the current contents of the hash table. */ Fts5SegIter *pIter = &pNew->aSeg[iIter++]; fts5SegIterHashInit(p, pTerm, nTerm, flags, pIter); } for(pLvl=&pStruct->aLevel[0]; pLvl<pEnd; pLvl++){ for(iSeg=pLvl->nSeg-1; iSeg>=0; iSeg--){ Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg]; Fts5SegIter *pIter = &pNew->aSeg[iIter++]; if( pTerm==0 ){ fts5SegIterInit(p, pSeg, pIter); }else{ fts5SegIterSeekInit(p, &buf, pTerm, nTerm, flags, pSeg, pIter); } } } }else{ pLvl = &pStruct->aLevel[iLevel]; for(iSeg=nSeg-1; iSeg>=0; iSeg--){ fts5SegIterInit(p, &pLvl->aSeg[iSeg], &pNew->aSeg[iIter++]); } } assert( iIter==nSeg ); } /* If the above was successful, each component iterators now points ** to the first entry in its segment. In this case initialize the ** aFirst[] array. Or, if an error has occurred, free the iterator ** object and set the output variable to NULL. */ if( p->rc==SQLITE_OK ){ for(iIter=pNew->nSeg-1; iIter>0; iIter--){ int iEq; if( (iEq = fts5MultiIterDoCompare(pNew, iIter)) ){ Fts5SegIter *pSeg = &pNew->aSeg[iEq]; if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0); fts5MultiIterAdvanced(p, pNew, iEq, iIter); } } fts5MultiIterSetEof(pNew); fts5AssertMultiIterSetup(p, pNew); if( pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew) ){ fts5MultiIterNext(p, pNew, 0, 0); }else if( pNew->base.bEof==0 ){ Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst]; pNew->xSetOutputs(pNew, pSeg); } }else{ fts5MultiIterFree(p, pNew); *ppOut = 0; } fts5BufferFree(&buf); } /* ** Create an Fts5Iter that iterates through the doclist provided ** as the second argument. */ static void fts5MultiIterNew2( Fts5Index *p, /* FTS5 backend to iterate within */ Fts5Data *pData, /* Doclist to iterate through */ int bDesc, /* True for descending rowid order */ Fts5Iter **ppOut /* New object */ ){ Fts5Iter *pNew; pNew = fts5MultiIterAlloc(p, 2); if( pNew ){ Fts5SegIter *pIter = &pNew->aSeg[1]; pIter->flags = FTS5_SEGITER_ONETERM; if( pData->szLeaf>0 ){ pIter->pLeaf = pData; pIter->iLeafOffset = fts5GetVarint(pData->p, (u64*)&pIter->iRowid); pIter->iEndofDoclist = pData->nn; pNew->aFirst[1].iFirst = 1; if( bDesc ){ pNew->bRev = 1; pIter->flags |= FTS5_SEGITER_REVERSE; fts5SegIterReverseInitPage(p, pIter); }else{ fts5SegIterLoadNPos(p, pIter); } pData = 0; }else{ pNew->base.bEof = 1; } fts5SegIterSetNext(p, pIter); *ppOut = pNew; } fts5DataRelease(pData); } /* ** Return true if the iterator is at EOF or if an error has occurred. ** False otherwise. */ static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){ assert( p->rc || (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->base.bEof ); return (p->rc || pIter->base.bEof); } /* ** Return the rowid of the entry that the iterator currently points ** to. If the iterator points to EOF when this function is called the ** results are undefined. */ static i64 fts5MultiIterRowid(Fts5Iter *pIter){ assert( pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf ); return pIter->aSeg[ pIter->aFirst[1].iFirst ].iRowid; } /* ** Move the iterator to the next entry at or following iMatch. */ static void fts5MultiIterNextFrom( Fts5Index *p, Fts5Iter *pIter, i64 iMatch ){ while( 1 ){ i64 iRowid; fts5MultiIterNext(p, pIter, 1, iMatch); if( fts5MultiIterEof(p, pIter) ) break; iRowid = fts5MultiIterRowid(pIter); if( pIter->bRev==0 && iRowid>=iMatch ) break; if( pIter->bRev!=0 && iRowid<=iMatch ) break; } } /* ** Return a pointer to a buffer containing the term associated with the ** entry that the iterator currently points to. */ static const u8 *fts5MultiIterTerm(Fts5Iter *pIter, int *pn){ Fts5SegIter *p = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; *pn = p->term.n; return p->term.p; } /* ** Allocate a new segment-id for the structure pStruct. The new segment ** id must be between 1 and 65335 inclusive, and must not be used by ** any currently existing segment. If a free segment id cannot be found, ** SQLITE_FULL is returned. ** |
︙ | ︙ | |||
178399 178400 178401 178402 178403 178404 178405 | } /* ** Iterator pIter was used to iterate through the input segments of on an ** incremental merge operation. This function is called if the incremental ** merge step has finished but the input has not been completely exhausted. */ | | | 179351 179352 179353 179354 179355 179356 179357 179358 179359 179360 179361 179362 179363 179364 179365 | } /* ** Iterator pIter was used to iterate through the input segments of on an ** incremental merge operation. This function is called if the incremental ** merge step has finished but the input has not been completely exhausted. */ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){ int i; Fts5Buffer buf; memset(&buf, 0, sizeof(Fts5Buffer)); for(i=0; i<pIter->nSeg; i++){ Fts5SegIter *pSeg = &pIter->aSeg[i]; if( pSeg->pSeg==0 ){ /* no-op */ |
︙ | ︙ | |||
178477 178478 178479 178480 178481 178482 178483 | Fts5Structure **ppStruct, /* IN/OUT: Stucture of index */ int iLvl, /* Level to read input from */ int *pnRem /* Write up to this many output leaves */ ){ Fts5Structure *pStruct = *ppStruct; Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl]; Fts5StructureLevel *pLvlOut; | | > | 179429 179430 179431 179432 179433 179434 179435 179436 179437 179438 179439 179440 179441 179442 179443 179444 179445 179446 179447 179448 179449 179450 179451 | Fts5Structure **ppStruct, /* IN/OUT: Stucture of index */ int iLvl, /* Level to read input from */ int *pnRem /* Write up to this many output leaves */ ){ Fts5Structure *pStruct = *ppStruct; Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl]; Fts5StructureLevel *pLvlOut; Fts5Iter *pIter = 0; /* Iterator to read input data */ int nRem = pnRem ? *pnRem : 0; /* Output leaf pages left to write */ int nInput; /* Number of input segments */ Fts5SegWriter writer; /* Writer object */ Fts5StructureSegment *pSeg; /* Output segment */ Fts5Buffer term; int bOldest; /* True if the output segment is the oldest */ int eDetail = p->pConfig->eDetail; const int flags = FTS5INDEX_QUERY_NOOUTPUT; assert( iLvl<pStruct->nLevel ); assert( pLvl->nMerge<=pLvl->nSeg ); memset(&writer, 0, sizeof(Fts5SegWriter)); memset(&term, 0, sizeof(Fts5Buffer)); if( pLvl->nMerge ){ |
︙ | ︙ | |||
178529 178530 178531 178532 178533 178534 178535 | /* Read input from all segments in the input level */ nInput = pLvl->nSeg; } bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2); assert( iLvl>=0 ); | | | 179482 179483 179484 179485 179486 179487 179488 179489 179490 179491 179492 179493 179494 179495 179496 | /* Read input from all segments in the input level */ nInput = pLvl->nSeg; } bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2); assert( iLvl>=0 ); for(fts5MultiIterNew(p, pStruct, flags, 0, 0, 0, iLvl, nInput, &pIter); fts5MultiIterEof(p, pIter)==0; fts5MultiIterNext(p, pIter, 0, 0) ){ Fts5SegIter *pSegIter = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; int nPos; /* position-list size field value */ int nTerm; const u8 *pTerm; |
︙ | ︙ | |||
178974 178975 178976 178977 178978 178979 178980 | fts5StructureWrite(p, pStruct); } fts5StructureRelease(pStruct); return fts5IndexReturn(p); } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < | | < < | < | | < < < < < < < < < < < < < | | | < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 179927 179928 179929 179930 179931 179932 179933 179934 179935 179936 179937 179938 179939 179940 179941 179942 179943 179944 179945 179946 179947 179948 179949 179950 179951 179952 179953 179954 179955 179956 179957 179958 179959 179960 179961 179962 | fts5StructureWrite(p, pStruct); } fts5StructureRelease(pStruct); return fts5IndexReturn(p); } static void fts5AppendRowid( Fts5Index *p, i64 iDelta, Fts5Iter *pMulti, Fts5Buffer *pBuf ){ fts5BufferAppendVarint(&p->rc, pBuf, iDelta); } static void fts5AppendPoslist( Fts5Index *p, i64 iDelta, Fts5Iter *pMulti, Fts5Buffer *pBuf ){ int nData = pMulti->base.nData; assert( nData>0 ); if( p->rc==SQLITE_OK && 0==fts5BufferGrow(&p->rc, pBuf, nData+9+9) ){ fts5BufferSafeAppendVarint(pBuf, iDelta); fts5BufferSafeAppendVarint(pBuf, nData*2); fts5BufferSafeAppendBlob(pBuf, pMulti->base.pData, nData); } } static void fts5DoclistIterNext(Fts5DoclistIter *pIter){ u8 *p = pIter->aPoslist + pIter->nSize + pIter->nPoslist; assert( pIter->aPoslist ); |
︙ | ︙ | |||
179386 179387 179388 179389 179390 179391 179392 | Fts5Buffer *p1, /* First list to merge */ Fts5Buffer *p2 /* Second list to merge */ ){ if( p2->n ){ i64 iLastRowid = 0; Fts5DoclistIter i1; Fts5DoclistIter i2; | | | < < | | > | > | > > > < > > > < < | | | | | | > > > > | > > > | > > > > > > > | > > | > > > > > > > > > > > > > > > | | | > > | | > > | | | > > > > | | | < | 180092 180093 180094 180095 180096 180097 180098 180099 180100 180101 180102 180103 180104 180105 180106 180107 180108 180109 180110 180111 180112 180113 180114 180115 180116 180117 180118 180119 180120 180121 180122 180123 180124 180125 180126 180127 180128 180129 180130 180131 180132 180133 180134 180135 180136 180137 180138 180139 180140 180141 180142 180143 180144 180145 180146 180147 180148 180149 180150 180151 180152 180153 180154 180155 180156 180157 180158 180159 180160 180161 180162 180163 180164 180165 180166 180167 180168 180169 180170 180171 180172 180173 180174 180175 180176 180177 180178 180179 180180 180181 180182 180183 180184 180185 180186 180187 180188 180189 180190 180191 180192 180193 180194 180195 180196 180197 180198 180199 180200 180201 180202 180203 180204 180205 180206 180207 180208 180209 180210 180211 180212 180213 180214 180215 180216 180217 180218 180219 180220 180221 180222 180223 180224 180225 180226 180227 180228 180229 180230 180231 180232 180233 180234 180235 180236 180237 180238 180239 180240 180241 180242 180243 180244 180245 180246 180247 180248 180249 180250 180251 180252 180253 180254 180255 180256 180257 180258 180259 180260 180261 180262 180263 180264 180265 180266 180267 180268 180269 180270 180271 180272 180273 180274 180275 180276 180277 180278 180279 180280 | Fts5Buffer *p1, /* First list to merge */ Fts5Buffer *p2 /* Second list to merge */ ){ if( p2->n ){ i64 iLastRowid = 0; Fts5DoclistIter i1; Fts5DoclistIter i2; Fts5Buffer out = {0, 0, 0}; Fts5Buffer tmp = {0, 0, 0}; if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n) ) return; fts5DoclistIterInit(p1, &i1); fts5DoclistIterInit(p2, &i2); while( 1 ){ if( i1.iRowid<i2.iRowid ){ /* Copy entry from i1 */ fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid); fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.nPoslist+i1.nSize); fts5DoclistIterNext(&i1); if( i1.aPoslist==0 ) break; } else if( i2.iRowid!=i1.iRowid ){ /* Copy entry from i2 */ fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize); fts5DoclistIterNext(&i2); if( i2.aPoslist==0 ) break; } else{ /* Merge the two position lists. */ i64 iPos1 = 0; i64 iPos2 = 0; int iOff1 = 0; int iOff2 = 0; u8 *a1 = &i1.aPoslist[i1.nSize]; u8 *a2 = &i2.aPoslist[i2.nSize]; i64 iPrev = 0; Fts5PoslistWriter writer; memset(&writer, 0, sizeof(writer)); fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); fts5BufferZero(&tmp); sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist); if( p->rc ) break; sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); assert( iPos1>=0 && iPos2>=0 ); if( iPos1<iPos2 ){ sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); }else{ sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); } if( iPos1>=0 && iPos2>=0 ){ while( 1 ){ if( iPos1<iPos2 ){ if( iPos1!=iPrev ){ sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); } sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); if( iPos1<0 ) break; }else{ assert( iPos2!=iPrev ); sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); if( iPos2<0 ) break; } } } if( iPos1>=0 ){ if( iPos1!=iPrev ){ sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); } fts5BufferSafeAppendBlob(&tmp, &a1[iOff1], i1.nPoslist-iOff1); }else{ assert( iPos2>=0 && iPos2!=iPrev ); sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); fts5BufferSafeAppendBlob(&tmp, &a2[iOff2], i2.nPoslist-iOff2); } /* WRITEPOSLISTSIZE */ fts5BufferSafeAppendVarint(&out, tmp.n * 2); fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); fts5DoclistIterNext(&i1); fts5DoclistIterNext(&i2); if( i1.aPoslist==0 || i2.aPoslist==0 ) break; } } if( i1.aPoslist ){ fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid); fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.aEof - i1.aPoslist); } else if( i2.aPoslist ){ fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist); } fts5BufferSet(&p->rc, p1, out.n, out.p); fts5BufferFree(&tmp); fts5BufferFree(&out); } } static void fts5SetupPrefixIter( Fts5Index *p, /* Index to read from */ int bDesc, /* True for "ORDER BY rowid DESC" */ const u8 *pToken, /* Buffer containing prefix to match */ int nToken, /* Size of buffer pToken in bytes */ Fts5Colset *pColset, /* Restrict matches to these columns */ Fts5Iter **ppIter /* OUT: New iterator */ ){ Fts5Structure *pStruct; Fts5Buffer *aBuf; const int nBuf = 32; void (*xMerge)(Fts5Index*, Fts5Buffer*, Fts5Buffer*); void (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Buffer*); if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ xMerge = fts5MergeRowidLists; xAppend = fts5AppendRowid; }else{ xMerge = fts5MergePrefixLists; xAppend = fts5AppendPoslist; } aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf); pStruct = fts5StructureRead(p); if( aBuf && pStruct ){ const int flags = FTS5INDEX_QUERY_SCAN | FTS5INDEX_QUERY_SKIPEMPTY | FTS5INDEX_QUERY_NOOUTPUT; int i; i64 iLastRowid = 0; Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ Fts5Data *pData; Fts5Buffer doclist; int bNewTerm = 1; memset(&doclist, 0, sizeof(doclist)); fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); fts5IterSetOutputCb(&p->rc, p1); for( /* no-op */ ; fts5MultiIterEof(p, p1)==0; fts5MultiIterNext2(p, p1, &bNewTerm) ){ Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; int nTerm = pSeg->term.n; const u8 *pTerm = pSeg->term.p; p1->xSetOutputs(p1, pSeg); assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 ); if( bNewTerm ){ if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break; } if( p1->base.nData==0 ) continue; if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ assert( i<nBuf ); if( aBuf[i].n==0 ){ fts5BufferSwap(&doclist, &aBuf[i]); fts5BufferZero(&doclist); }else{ xMerge(p, &doclist, &aBuf[i]); fts5BufferZero(&aBuf[i]); } } iLastRowid = 0; } xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist); iLastRowid = p1->base.iRowid; } for(i=0; i<nBuf; i++){ if( p->rc==SQLITE_OK ){ xMerge(p, &doclist, &aBuf[i]); } fts5BufferFree(&aBuf[i]); |
︙ | ︙ | |||
179589 179590 179591 179592 179593 179594 179595 | ** to the database. Additionally, assume that the contents of the %_data ** table may have changed on disk. So any in-memory caches of %_data ** records must be invalidated. */ static int sqlite3Fts5IndexRollback(Fts5Index *p){ fts5CloseReader(p); fts5IndexDiscardData(p); | | | 180336 180337 180338 180339 180340 180341 180342 180343 180344 180345 180346 180347 180348 180349 180350 | ** to the database. Additionally, assume that the contents of the %_data ** table may have changed on disk. So any in-memory caches of %_data ** records must be invalidated. */ static int sqlite3Fts5IndexRollback(Fts5Index *p){ fts5CloseReader(p); fts5IndexDiscardData(p); /* assert( p->rc==SQLITE_OK ); */ return SQLITE_OK; } /* ** The %_data table is completely empty when this function is called. This ** function populates it with the initial structure objects for each index, ** and the initial version of the "averages" record (a zero-byte blob). |
︙ | ︙ | |||
179761 179762 179763 179764 179765 179766 179767 | Fts5Index *p, /* FTS index to query */ const char *pToken, int nToken, /* Token (or prefix) to query for */ int flags, /* Mask of FTS5INDEX_QUERY_X flags */ Fts5Colset *pColset, /* Match these columns only */ Fts5IndexIter **ppIter /* OUT: New iterator object */ ){ Fts5Config *pConfig = p->pConfig; | | < > < > > > > > | > > > | > > > > > > > > | > | < < < < < | > | > | | > < < < < < < < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | > | 180508 180509 180510 180511 180512 180513 180514 180515 180516 180517 180518 180519 180520 180521 180522 180523 180524 180525 180526 180527 180528 180529 180530 180531 180532 180533 180534 180535 180536 180537 180538 180539 180540 180541 180542 180543 180544 180545 180546 180547 180548 180549 180550 180551 180552 180553 180554 180555 180556 180557 180558 180559 180560 180561 180562 180563 180564 180565 180566 180567 180568 180569 180570 180571 180572 180573 180574 180575 180576 180577 180578 180579 180580 180581 180582 180583 180584 180585 180586 180587 180588 180589 180590 180591 180592 180593 180594 180595 180596 180597 180598 180599 180600 180601 180602 180603 180604 180605 180606 180607 180608 180609 180610 180611 180612 180613 180614 180615 180616 180617 180618 180619 180620 180621 180622 180623 180624 180625 180626 180627 180628 180629 180630 180631 180632 180633 180634 180635 180636 180637 180638 180639 180640 180641 180642 180643 180644 180645 180646 180647 180648 180649 180650 180651 | Fts5Index *p, /* FTS index to query */ const char *pToken, int nToken, /* Token (or prefix) to query for */ int flags, /* Mask of FTS5INDEX_QUERY_X flags */ Fts5Colset *pColset, /* Match these columns only */ Fts5IndexIter **ppIter /* OUT: New iterator object */ ){ Fts5Config *pConfig = p->pConfig; Fts5Iter *pRet = 0; Fts5Buffer buf = {0, 0, 0}; /* If the QUERY_SCAN flag is set, all other flags must be clear. */ assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN ); if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ memcpy(&buf.p[1], pToken, nToken); /* Figure out which index to search and set iIdx accordingly. If this ** is a prefix query for which there is no prefix index, set iIdx to ** greater than pConfig->nPrefix to indicate that the query will be ** satisfied by scanning multiple terms in the main index. ** ** If the QUERY_TEST_NOIDX flag was specified, then this must be a ** prefix-query. Instead of using a prefix-index (if one exists), ** evaluate the prefix query using the main FTS index. This is used ** for internal sanity checking by the integrity-check in debug ** mode only. */ #ifdef SQLITE_DEBUG if( pConfig->bPrefixIndex==0 || (flags & FTS5INDEX_QUERY_TEST_NOIDX) ){ assert( flags & FTS5INDEX_QUERY_PREFIX ); iIdx = 1+pConfig->nPrefix; }else #endif if( flags & FTS5INDEX_QUERY_PREFIX ){ int nChar = fts5IndexCharlen(pToken, nToken); for(iIdx=1; iIdx<=pConfig->nPrefix; iIdx++){ if( pConfig->aPrefix[iIdx-1]==nChar ) break; } } if( iIdx<=pConfig->nPrefix ){ /* Straight index lookup */ Fts5Structure *pStruct = fts5StructureRead(p); buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx); if( pStruct ){ fts5MultiIterNew(p, pStruct, flags | FTS5INDEX_QUERY_SKIPEMPTY, pColset, buf.p, nToken+1, -1, 0, &pRet ); fts5StructureRelease(pStruct); } }else{ /* Scan multiple terms in the main index */ int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0; buf.p[0] = FTS5_MAIN_PREFIX; fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet); assert( pRet->pColset==0 ); fts5IterSetOutputCb(&p->rc, pRet); if( p->rc==SQLITE_OK ){ Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst]; if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); } } if( p->rc ){ sqlite3Fts5IterClose(&pRet->base); pRet = 0; fts5CloseReader(p); } *ppIter = &pRet->base; sqlite3Fts5BufferFree(&buf); } return fts5IndexReturn(p); } /* ** Return true if the iterator passed as the only argument is at EOF. */ /* ** Move to the next matching rowid. */ static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; assert( pIter->pIndex->rc==SQLITE_OK ); fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); return fts5IndexReturn(pIter->pIndex); } /* ** Move to the next matching term/rowid. Used by the fts5vocab module. */ static int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5Index *p = pIter->pIndex; assert( pIter->pIndex->rc==SQLITE_OK ); fts5MultiIterNext(p, pIter, 0, 0); if( p->rc==SQLITE_OK ){ Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; if( pSeg->pLeaf && pSeg->term.p[0]!=FTS5_MAIN_PREFIX ){ fts5DataRelease(pSeg->pLeaf); pSeg->pLeaf = 0; pIter->base.bEof = 1; } } return fts5IndexReturn(pIter->pIndex); } /* ** Move to the next matching rowid that occurs at or after iMatch. The ** definition of "at or after" depends on whether this iterator iterates ** in ascending or descending rowid order. */ static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); return fts5IndexReturn(pIter->pIndex); } /* ** Return the current term. */ static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ int n; const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n); *pn = n-1; return &z[1]; } /* ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery(). */ static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ if( pIndexIter ){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5Index *pIndex = pIter->pIndex; fts5MultiIterFree(pIter->pIndex, pIter); fts5CloseReader(pIndex); } } /* |
︙ | ︙ | |||
180145 180146 180147 180148 180149 180150 180151 | const char *z, /* Index key to query for */ int n, /* Size of index key in bytes */ int flags, /* Flags for Fts5IndexQuery */ u64 *pCksum /* IN/OUT: Checksum value */ ){ int eDetail = p->pConfig->eDetail; u64 cksum = *pCksum; | | < | | | < < | | | | | | | | < | | < | 180804 180805 180806 180807 180808 180809 180810 180811 180812 180813 180814 180815 180816 180817 180818 180819 180820 180821 180822 180823 180824 180825 180826 180827 180828 180829 180830 180831 180832 180833 180834 180835 180836 180837 180838 180839 180840 180841 | const char *z, /* Index key to query for */ int n, /* Size of index key in bytes */ int flags, /* Flags for Fts5IndexQuery */ u64 *pCksum /* IN/OUT: Checksum value */ ){ int eDetail = p->pConfig->eDetail; u64 cksum = *pCksum; Fts5IndexIter *pIter = 0; int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter); while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIter) ){ i64 rowid = pIter->iRowid; if( eDetail==FTS5_DETAIL_NONE ){ cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n); }else{ Fts5PoslistReader sReader; for(sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &sReader); sReader.bEof==0; sqlite3Fts5PoslistReaderNext(&sReader) ){ int iCol = FTS5_POS2COLUMN(sReader.iPos); int iOff = FTS5_POS2OFFSET(sReader.iPos); cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n); } } if( rc==SQLITE_OK ){ rc = sqlite3Fts5IterNext(pIter); } } sqlite3Fts5IterClose(pIter); *pCksum = cksum; return rc; } /* |
︙ | ︙ | |||
180478 180479 180480 180481 180482 180483 180484 | ** error, or some other SQLite error code if another error (e.g. OOM) ** occurs. */ static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ int eDetail = p->pConfig->eDetail; u64 cksum2 = 0; /* Checksum based on contents of indexes */ Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */ | | > | 181132 181133 181134 181135 181136 181137 181138 181139 181140 181141 181142 181143 181144 181145 181146 181147 181148 181149 181150 181151 181152 181153 181154 | ** error, or some other SQLite error code if another error (e.g. OOM) ** occurs. */ static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ int eDetail = p->pConfig->eDetail; u64 cksum2 = 0; /* Checksum based on contents of indexes */ Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */ Fts5Iter *pIter; /* Used to iterate through entire index */ Fts5Structure *pStruct; /* Index structure */ #ifdef SQLITE_DEBUG /* Used by extra internal tests only run if NDEBUG is not defined */ u64 cksum3 = 0; /* Checksum based on contents of indexes */ Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */ #endif const int flags = FTS5INDEX_QUERY_NOOUTPUT; /* Load the FTS index structure */ pStruct = fts5StructureRead(p); /* Check that the internal nodes of each segment match the leaves */ if( pStruct ){ int iLvl, iSeg; |
︙ | ︙ | |||
180514 180515 180516 180517 180518 180519 180520 | ** variable cksum2) based on entries extracted from the full-text index ** while doing a linear scan of each individual index in turn. ** ** As each term visited by the linear scans, a separate query for the ** same term is performed. cksum3 is calculated based on the entries ** extracted by these queries. */ | | | 181169 181170 181171 181172 181173 181174 181175 181176 181177 181178 181179 181180 181181 181182 181183 | ** variable cksum2) based on entries extracted from the full-text index ** while doing a linear scan of each individual index in turn. ** ** As each term visited by the linear scans, a separate query for the ** same term is performed. cksum3 is calculated based on the entries ** extracted by these queries. */ for(fts5MultiIterNew(p, pStruct, flags, 0, 0, 0, -1, 0, &pIter); fts5MultiIterEof(p, pIter)==0; fts5MultiIterNext(p, pIter, 0, 0) ){ int n; /* Size of term in bytes */ i64 iPos = 0; /* Position read from poslist */ int iOff = 0; /* Offset within poslist */ i64 iRowid = fts5MultiIterRowid(pIter); |
︙ | ︙ | |||
181232 181233 181234 181235 181236 181237 181238 | #define FTS5_BI_ORDER_RANK 0x0020 #define FTS5_BI_ORDER_ROWID 0x0040 #define FTS5_BI_ORDER_DESC 0x0080 /* ** Values for Fts5Cursor.csrflags */ | > | | | < | 181887 181888 181889 181890 181891 181892 181893 181894 181895 181896 181897 181898 181899 181900 181901 181902 181903 181904 | #define FTS5_BI_ORDER_RANK 0x0020 #define FTS5_BI_ORDER_ROWID 0x0040 #define FTS5_BI_ORDER_DESC 0x0080 /* ** Values for Fts5Cursor.csrflags */ #define FTS5CSR_EOF 0x01 #define FTS5CSR_REQUIRE_CONTENT 0x02 #define FTS5CSR_REQUIRE_DOCSIZE 0x04 #define FTS5CSR_REQUIRE_INST 0x08 #define FTS5CSR_FREE_ZRANK 0x10 #define FTS5CSR_REQUIRE_RESEEK 0x20 #define FTS5CSR_REQUIRE_POSLIST 0x40 #define BitFlagAllTest(x,y) (((x) & (y))==(y)) #define BitFlagTest(x,y) (((x) & (y))!=0) |
︙ | ︙ | |||
181550 181551 181552 181553 181554 181555 181556 | aColMap[1] = pConfig->nCol; aColMap[2] = pConfig->nCol+1; /* Set idxFlags flags for all WHERE clause terms that will be used. */ for(i=0; i<pInfo->nConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; int j; | | | 182205 182206 182207 182208 182209 182210 182211 182212 182213 182214 182215 182216 182217 182218 182219 | aColMap[1] = pConfig->nCol; aColMap[2] = pConfig->nCol+1; /* Set idxFlags flags for all WHERE clause terms that will be used. */ for(i=0; i<pInfo->nConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; int j; for(j=0; j<ArraySize(aConstraint); j++){ struct Constraint *pC = &aConstraint[j]; if( p->iColumn==aColMap[pC->iCol] && p->op & pC->op ){ if( p->usable ){ pC->iConsIndex = i; idxFlags |= pC->fts5op; }else if( j==0 ){ /* As there exists an unusable MATCH constraint this is an |
︙ | ︙ | |||
181597 181598 181599 181600 181601 181602 181603 | pInfo->estimatedCost = bHasMatch ? 750.0 : 750000.0; }else{ pInfo->estimatedCost = bHasMatch ? 1000.0 : 1000000.0; } /* Assign argvIndex values to each constraint in use. */ iNext = 1; | | | 182252 182253 182254 182255 182256 182257 182258 182259 182260 182261 182262 182263 182264 182265 182266 | pInfo->estimatedCost = bHasMatch ? 750.0 : 750000.0; }else{ pInfo->estimatedCost = bHasMatch ? 1000.0 : 1000000.0; } /* Assign argvIndex values to each constraint in use. */ iNext = 1; for(i=0; i<ArraySize(aConstraint); i++){ struct Constraint *pC = &aConstraint[i]; if( pC->iConsIndex>=0 ){ pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++; pInfo->aConstraintUsage[pC->iConsIndex].omit = (unsigned char)pC->omit; } } |
︙ | ︙ | |||
181790 181791 181792 181793 181794 181795 181796 | assert( *pbSkip==0 ); if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); int bDesc = pCsr->bDesc; i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr); rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->pIndex, iRowid, bDesc); | | > | > | < < > | 182445 182446 182447 182448 182449 182450 182451 182452 182453 182454 182455 182456 182457 182458 182459 182460 182461 182462 182463 182464 182465 182466 182467 182468 182469 182470 182471 182472 182473 182474 182475 182476 182477 182478 182479 182480 182481 182482 182483 182484 182485 182486 182487 182488 182489 182490 182491 182492 182493 182494 182495 182496 182497 182498 182499 182500 182501 | assert( *pbSkip==0 ); if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); int bDesc = pCsr->bDesc; i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr); rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->pIndex, iRowid, bDesc); if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){ *pbSkip = 1; } CsrFlagClear(pCsr, FTS5CSR_REQUIRE_RESEEK); fts5CsrNewrow(pCsr); if( sqlite3Fts5ExprEof(pCsr->pExpr) ){ CsrFlagSet(pCsr, FTS5CSR_EOF); *pbSkip = 1; } } return rc; } /* ** Advance the cursor to the next row in the table that matches the ** search criteria. ** ** Return SQLITE_OK if nothing goes wrong. SQLITE_OK is returned ** even if we reach end-of-file. The fts5EofMethod() will be called ** subsequently to determine whether or not an EOF was hit. */ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; int rc; assert( (pCsr->ePlan<3)== (pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE) ); assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) ); if( pCsr->ePlan<3 ){ int bSkip = 0; if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc; rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid); CsrFlagSet(pCsr, sqlite3Fts5ExprEof(pCsr->pExpr)); fts5CsrNewrow(pCsr); }else{ switch( pCsr->ePlan ){ case FTS5_PLAN_SPECIAL: { CsrFlagSet(pCsr, FTS5CSR_EOF); rc = SQLITE_OK; break; } case FTS5_PLAN_SORTED_MATCH: { rc = fts5SorterNext(pCsr); break; } |
︙ | ︙ | |||
183603 183604 183605 183606 183607 183608 183609 | */ static void fts5SourceIdFunc( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ sqlite3_value **apVal /* Function arguments */ ){ assert( nArg==0 ); | | | 184259 184260 184261 184262 184263 184264 184265 184266 184267 184268 184269 184270 184271 184272 184273 | */ static void fts5SourceIdFunc( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ sqlite3_value **apVal /* Function arguments */ ){ assert( nArg==0 ); sqlite3_result_text(pCtx, "fts5: 2016-02-08 20:45:37 6eab74c9ae57676044b5bc82fa14e92fd2448008", -1, SQLITE_TRANSIENT); } static int fts5Init(sqlite3 *db){ static const sqlite3_module fts5Mod = { /* iVersion */ 2, /* xCreate */ fts5CreateMethod, /* xConnect */ fts5ConnectMethod, |
︙ | ︙ | |||
184048 184049 184050 184051 184052 184053 184054 | */ static int sqlite3Fts5StorageClose(Fts5Storage *p){ int rc = SQLITE_OK; if( p ){ int i; /* Finalize all SQL statements */ | | | 184704 184705 184706 184707 184708 184709 184710 184711 184712 184713 184714 184715 184716 184717 184718 | */ static int sqlite3Fts5StorageClose(Fts5Storage *p){ int rc = SQLITE_OK; if( p ){ int i; /* Finalize all SQL statements */ for(i=0; i<ArraySize(p->aStmt); i++){ sqlite3_finalize(p->aStmt[i]); } sqlite3_free(p); } return rc; } |
︙ | ︙ | |||
186053 186054 186055 186056 186057 186058 186059 | { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }}, { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }}, }; int rc = SQLITE_OK; /* Return code */ int i; /* To iterate through builtin functions */ | | | 186709 186710 186711 186712 186713 186714 186715 186716 186717 186718 186719 186720 186721 186722 186723 | { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }}, { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }}, }; int rc = SQLITE_OK; /* Return code */ int i; /* To iterate through builtin functions */ for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){ rc = pApi->xCreateTokenizer(pApi, aBuiltin[i].zName, (void*)pApi, &aBuiltin[i].x, 0 ); } |
︙ | ︙ | |||
186763 186764 186765 186766 186767 186768 186769 186770 186771 186772 186773 186774 186775 186776 186777 | return 2; } return fts5PutVarint64(p,v); } static int sqlite3Fts5GetVarintLen(u32 iVal){ if( iVal<(1 << 7 ) ) return 1; if( iVal<(1 << 14) ) return 2; if( iVal<(1 << 21) ) return 3; if( iVal<(1 << 28) ) return 4; return 5; } | > > > | 187419 187420 187421 187422 187423 187424 187425 187426 187427 187428 187429 187430 187431 187432 187433 187434 187435 187436 | return 2; } return fts5PutVarint64(p,v); } static int sqlite3Fts5GetVarintLen(u32 iVal){ #if 0 if( iVal<(1 << 7 ) ) return 1; #endif assert( iVal>=(1 << 7) ); if( iVal<(1 << 14) ) return 2; if( iVal<(1 << 21) ) return 3; if( iVal<(1 << 28) ) return 4; return 5; } |
︙ | ︙ | |||
186957 186958 186959 186960 186961 186962 186963 | const char *zType = bDb ? argv[5] : argv[4]; int nDb = (int)strlen(zDb)+1; int nTab = (int)strlen(zTab)+1; int eType = 0; rc = fts5VocabTableType(zType, pzErr, &eType); if( rc==SQLITE_OK ){ | | | 187616 187617 187618 187619 187620 187621 187622 187623 187624 187625 187626 187627 187628 187629 187630 | const char *zType = bDb ? argv[5] : argv[4]; int nDb = (int)strlen(zDb)+1; int nTab = (int)strlen(zTab)+1; int eType = 0; rc = fts5VocabTableType(zType, pzErr, &eType); if( rc==SQLITE_OK ){ assert( eType>=0 && eType<ArraySize(azSchema) ); rc = sqlite3_declare_vtab(db, azSchema[eType]); } nByte = sizeof(Fts5VocabTable) + nDb + nTab; pRet = sqlite3Fts5MallocZero(&rc, nByte); if( pRet ){ pRet->pGlobal = (Fts5Global*)pAux; |
︙ | ︙ | |||
187180 187181 187182 187183 187184 187185 187186 | sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm); memset(pCsr->aCnt, 0, nCol * sizeof(i64)); memset(pCsr->aDoc, 0, nCol * sizeof(i64)); pCsr->iCol = 0; assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW ); while( rc==SQLITE_OK ){ | < > > > | < | | | | | | | | | | | | | | | | | < < < < | | | | | | | | < < | 187839 187840 187841 187842 187843 187844 187845 187846 187847 187848 187849 187850 187851 187852 187853 187854 187855 187856 187857 187858 187859 187860 187861 187862 187863 187864 187865 187866 187867 187868 187869 187870 187871 187872 187873 187874 187875 187876 187877 187878 187879 187880 187881 187882 187883 187884 187885 187886 187887 187888 187889 187890 187891 187892 187893 187894 187895 187896 | sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm); memset(pCsr->aCnt, 0, nCol * sizeof(i64)); memset(pCsr->aDoc, 0, nCol * sizeof(i64)); pCsr->iCol = 0; assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW ); while( rc==SQLITE_OK ){ const u8 *pPos; int nPos; /* Position list */ i64 iPos = 0; /* 64-bit position read from poslist */ int iOff = 0; /* Current offset within position list */ pPos = pCsr->pIter->pData; nPos = pCsr->pIter->nData; switch( pCsr->pConfig->eDetail ){ case FTS5_DETAIL_FULL: pPos = pCsr->pIter->pData; nPos = pCsr->pIter->nData; if( pTab->eType==FTS5_VOCAB_ROW ){ while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ pCsr->aCnt[0]++; } pCsr->aDoc[0]++; }else{ int iCol = -1; while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ int ii = FTS5_POS2COLUMN(iPos); pCsr->aCnt[ii]++; if( iCol!=ii ){ if( ii>=nCol ){ rc = FTS5_CORRUPT; break; } pCsr->aDoc[ii]++; iCol = ii; } } } break; case FTS5_DETAIL_COLUMNS: if( pTab->eType==FTS5_VOCAB_ROW ){ pCsr->aDoc[0]++; }else{ while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){ assert_nc( iPos>=0 && iPos<nCol ); if( iPos>=nCol ){ rc = FTS5_CORRUPT; break; } pCsr->aDoc[iPos]++; } } break; default: assert( pCsr->pConfig->eDetail==FTS5_DETAIL_NONE ); pCsr->aDoc[0]++; break; |
︙ | ︙ |
Changes to src/sqlite3.h.
︙ | ︙ | |||
109 110 111 112 113 114 115 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.11.0" #define SQLITE_VERSION_NUMBER 3011000 | | | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.11.0" #define SQLITE_VERSION_NUMBER 3011000 #define SQLITE_SOURCE_ID "2016-02-09 02:12:20 ca72be8618e5d466d6f35819ca8bbd2b84269959" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ | |||
5693 5694 5695 5696 5697 5698 5699 | ** sqlite3_libversion_number() returns a value greater than or equal to ** 3009000. */ struct sqlite3_index_info { /* Inputs */ int nConstraint; /* Number of entries in aConstraint */ struct sqlite3_index_constraint { | | | 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 | ** sqlite3_libversion_number() returns a value greater than or equal to ** 3009000. */ struct sqlite3_index_info { /* Inputs */ int nConstraint; /* Number of entries in aConstraint */ struct sqlite3_index_constraint { int iColumn; /* Column constrained. -1 for ROWID */ unsigned char op; /* Constraint operator */ unsigned char usable; /* True if this constraint is usable */ int iTermOffset; /* Used internally - xBestIndex should ignore */ } *aConstraint; /* Table of WHERE clause constraints */ int nOrderBy; /* Number of terms in the ORDER BY clause */ struct sqlite3_index_orderby { int iColumn; /* Column number */ |
︙ | ︙ |