Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Update the built-in SQLite to the latest 3.47.0 alpha. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
0819ed51b398f2fa90d29f24a2508bed |
User & Date: | drh 2024-09-29 22:03:35.372 |
Context
2024-09-29
| ||
22:40 | Fix is so that it runs with Tcl9. (check-in: 199a1a71c1 user: drh tags: trunk) | |
22:03 | Update the built-in SQLite to the latest 3.47.0 alpha. (check-in: 0819ed51b3 user: drh tags: trunk) | |
2024-05-23
| ||
14:28 | Update the built-in SQLite to the 3.46.0 release (check-in: 5e67d066e5 user: drh tags: trunk) | |
Changes
Changes to Makefile.
1 2 3 4 5 | #!/usr/bin/make CFLAGS = -Os -static CC = gcc $(CFLAGS) OPTS = -DSQLITE_ENABLE_DESERIALIZE | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | #!/usr/bin/make CFLAGS = -Os -static CC = gcc $(CFLAGS) OPTS = -DSQLITE_ENABLE_DESERIALIZE TCLLIB = /home/drh/tcl/lib/libtcl8.6.a -lm -lz -lpthread -ldl TCLINC = /home/drh/tcl/include TCLSH = tclsh all: wapptclsh wapptclsh: wapptclsh.c $(CC) -I. -I$(TCLINC) -o $@ $(OPTS) wapptclsh.c $(TCLLIB) |
︙ | ︙ |
Changes to tclsqlite3.c.
1 2 3 | #ifndef USE_SYSTEM_SQLITE /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #ifndef USE_SYSTEM_SQLITE /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version 3.47.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. ** ** This file is all you need to compile SQLite. To use SQLite in other ** programs, you need this file and the "sqlite3.h" header file that defines ** the programming interface to the SQLite library. (If you do not have ** the "sqlite3.h" header file at hand, you will find a copy embedded within ** the text of this file. Search for "Begin file sqlite3.h" to find the start ** of the embedded sqlite3.h header file.) Additional code files may be needed ** if you want a wrapper to interface SQLite with your choice of programming ** language. The code for the "sqlite3" command-line shell is also in a ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in ** 76b6331e6a705a420a64820a18214f07cf4c. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE # define SQLITE_PRIVATE static #endif /************** Begin file sqliteInt.h ***************************************/ |
︙ | ︙ | |||
253 254 255 256 257 258 259 | #if defined(__OpenBSD__) && !defined(_BSD_SOURCE) # define _BSD_SOURCE #endif /* ** Macro to disable warnings about missing "break" at the end of a "case". */ | | > | > | > | | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | #if defined(__OpenBSD__) && !defined(_BSD_SOURCE) # define _BSD_SOURCE #endif /* ** Macro to disable warnings about missing "break" at the end of a "case". */ #if defined(__has_attribute) # if __has_attribute(fallthrough) # define deliberate_fall_through __attribute__((fallthrough)); # endif #endif #if !defined(deliberate_fall_through) # define deliberate_fall_through #endif /* ** For MinGW, check to see if we can include the header file containing its ** version information, among other things. Normally, this internal MinGW ** header file would [only] be included automatically by other MinGW header ** files; however, the contained version information is now required by this |
︙ | ︙ | |||
456 457 458 459 460 461 462 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.47.0" #define SQLITE_VERSION_NUMBER 3047000 #define SQLITE_SOURCE_ID "2024-09-28 19:52:38 76b6331e6a705a420a64820a18214f07cf4c1d5151e7158d6fff09964e63f352" /* ** 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 |
︙ | ︙ | |||
1082 1083 1084 1085 1086 1087 1088 | ** SQLITE_LOCK_NONE. If the database file lock is already at or above the ** requested lock, then the call to xLock() is a no-op. ** xUnlock() downgrades the database file lock to either SHARED or NONE. ** If the lock is already at or below the requested lock state, then the call ** to xUnlock() is a no-op. ** The xCheckReservedLock() method checks whether any database connection, ** either in this process or in some other process, is holding a RESERVED, | | | | 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 | ** SQLITE_LOCK_NONE. If the database file lock is already at or above the ** requested lock, then the call to xLock() is a no-op. ** xUnlock() downgrades the database file lock to either SHARED or NONE. ** If the lock is already at or below the requested lock state, then the call ** to xUnlock() is a no-op. ** The xCheckReservedLock() method checks whether any database connection, ** either in this process or in some other process, is holding a RESERVED, ** PENDING, or EXCLUSIVE lock on the file. It returns, via its output ** pointer parameter, true if such a lock exists and false otherwise. ** ** The xFileControl() method is a generic interface that allows custom ** VFS implementations to directly control an open file using the ** [sqlite3_file_control()] interface. The second "op" argument is an ** integer opcode. The third argument is a generic pointer intended to ** point to a structure that may contain arguments or space in which to ** write return values. Potential uses for xFileControl() might be |
︙ | ︙ | |||
3880 3881 3882 3883 3884 3885 3886 | ** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt> ** <dd>The database is opened [shared cache] disabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ ** ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt> ** <dd>The database connection comes up in "extended result code mode". | | | | 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 | ** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt> ** <dd>The database is opened [shared cache] disabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ ** ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt> ** <dd>The database connection comes up in "extended result code mode". ** In other words, the database behaves as if ** [sqlite3_extended_result_codes(db,1)] were called on the database ** connection as soon as the connection is created. In addition to setting ** the extended result code mode, this flag also causes [sqlite3_open_v2()] ** to return an extended result code.</dd> ** ** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt> ** <dd>The database filename is not allowed to contain a symbolic link</dd> ** </dl>)^ |
︙ | ︙ | |||
4532 4533 4534 4535 4536 4537 4538 | ** The second argument, "zSql", is the statement to be compiled, encoded ** as either UTF-8 or UTF-16. The sqlite3_prepare(), sqlite3_prepare_v2(), ** and sqlite3_prepare_v3() ** interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(), ** and sqlite3_prepare16_v3() use UTF-16. ** ** ^If the nByte argument is negative, then zSql is read up to the | | | > > > > | 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 | ** The second argument, "zSql", is the statement to be compiled, encoded ** as either UTF-8 or UTF-16. The sqlite3_prepare(), sqlite3_prepare_v2(), ** and sqlite3_prepare_v3() ** interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(), ** and sqlite3_prepare16_v3() use UTF-16. ** ** ^If the nByte argument is negative, then zSql is read up to the ** first zero terminator. ^If nByte is positive, then it is the maximum ** number of bytes read from zSql. When nByte is positive, zSql is read ** up to the first zero terminator or until the nByte bytes have been read, ** whichever comes first. ^If nByte is zero, then no prepared ** statement is generated. ** If the caller knows that the supplied string is nul-terminated, then ** there is a small performance advantage to passing an nByte parameter that ** is the number of bytes in the input string <i>including</i> ** the nul-terminator. ** Note that nByte measure the length of the input in bytes, not ** characters, even for the UTF-16 inferfaces. ** ** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** past the end of the first SQL statement in zSql. These routines only ** compile the first statement in zSql, so *pzTail is left pointing to ** what remains uncompiled. ** ** ^*ppStmt is left pointing to a compiled [prepared statement] that can be |
︙ | ︙ | |||
5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 | ** Every function that invokes [sqlite3_result_subtype()] should have this ** property. If it does not, then the call to [sqlite3_result_subtype()] ** might become a no-op if the function is used as term in an ** [expression index]. On the other hand, SQL functions that never invoke ** [sqlite3_result_subtype()] should avoid setting this property, as the ** purpose of this property is to disable certain optimizations that are ** incompatible with subtypes. ** </dd> ** </dl> */ #define SQLITE_DETERMINISTIC 0x000000800 #define SQLITE_DIRECTONLY 0x000080000 #define SQLITE_SUBTYPE 0x000100000 #define SQLITE_INNOCUOUS 0x000200000 #define SQLITE_RESULT_SUBTYPE 0x001000000 /* ** CAPI3REF: Deprecated Functions ** DEPRECATED ** ** These functions are [deprecated]. In order to maintain ** backwards compatibility with older code, these functions continue | > > > > > > > > > > | 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 | ** Every function that invokes [sqlite3_result_subtype()] should have this ** property. If it does not, then the call to [sqlite3_result_subtype()] ** might become a no-op if the function is used as term in an ** [expression index]. On the other hand, SQL functions that never invoke ** [sqlite3_result_subtype()] should avoid setting this property, as the ** purpose of this property is to disable certain optimizations that are ** incompatible with subtypes. ** ** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd> ** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate ** that internally orders the values provided to the first argument. The ** ordered-set aggregate SQL notation with a single ORDER BY term can be ** used to invoke this function. If the ordered-set aggregate notation is ** used on a function that lacks this flag, then an error is raised. Note ** that the ordered-set aggregate syntax is only available if SQLite is ** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option. ** </dd> ** </dl> */ #define SQLITE_DETERMINISTIC 0x000000800 #define SQLITE_DIRECTONLY 0x000080000 #define SQLITE_SUBTYPE 0x000100000 #define SQLITE_INNOCUOUS 0x000200000 #define SQLITE_RESULT_SUBTYPE 0x001000000 #define SQLITE_SELFORDER1 0x002000000 /* ** CAPI3REF: Deprecated Functions ** DEPRECATED ** ** These functions are [deprecated]. In order to maintain ** backwards compatibility with older code, these functions continue |
︙ | ︙ | |||
6130 6131 6132 6133 6134 6135 6136 | ** ** The sqlite3_value_subtype(V) function returns the subtype for ** an [application-defined SQL function] argument V. The subtype ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. ** | | | 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 | ** ** The sqlite3_value_subtype(V) function returns the subtype for ** an [application-defined SQL function] argument V. The subtype ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. ** ** Every [application-defined SQL function] that invokes this interface ** should include the [SQLITE_SUBTYPE] property in the text ** encoding argument when the function is [sqlite3_create_function|registered]. ** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() ** might return zero instead of the upstream subtype in some corner cases. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); |
︙ | ︙ | |||
7737 7738 7739 7740 7741 7742 7743 | ** indicates that the expense of the operation is similar to that of a ** binary search on a unique indexed field of an SQLite table with N rows. ** ** ^The estimatedRows value is an estimate of the number of rows that ** will be returned by the strategy. ** ** The xBestIndex method may optionally populate the idxFlags field with a | | > > | | | 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 | ** indicates that the expense of the operation is similar to that of a ** binary search on a unique indexed field of an SQLite table with N rows. ** ** ^The estimatedRows value is an estimate of the number of rows that ** will be returned by the strategy. ** ** The xBestIndex method may optionally populate the idxFlags field with a ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] ** output to show the idxNum has hex instead of as decimal. Another flag is ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will ** return at most one row. ** ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then ** SQLite also assumes that if a call to the xUpdate() method is made as ** part of the same statement to delete or update a virtual table row and the ** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback ** any database changes. In other words, if the xUpdate() returns ** SQLITE_CONSTRAINT, the database contents must be exactly as they were |
︙ | ︙ | |||
7803 7804 7805 7806 7807 7808 7809 | /* ** CAPI3REF: Virtual Table Scan Flags ** ** Virtual table implementations are allowed to set the ** [sqlite3_index_info].idxFlags field to some combination of ** these bits. */ | | > > | 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 | /* ** CAPI3REF: Virtual Table Scan Flags ** ** Virtual table implementations are allowed to set the ** [sqlite3_index_info].idxFlags field to some combination of ** these bits. */ #define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */ #define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */ /* in EXPLAIN QUERY PLAN */ /* ** CAPI3REF: Virtual Table Constraint Operator Codes ** ** These macros define the allowed values for the ** [sqlite3_index_info].aConstraint[].op field. Each value represents ** an operator that is part of a constraint term in the WHERE clause of |
︙ | ︙ | |||
8640 8641 8642 8643 8644 8645 8646 8647 8648 8649 8650 8651 8652 8653 | #define SQLITE_TESTCTRL_PENDING_BYTE 11 #define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ #define SQLITE_TESTCTRL_JSON_SELFCHECK 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 | > | 8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 | #define SQLITE_TESTCTRL_PENDING_BYTE 11 #define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ #define SQLITE_TESTCTRL_JSON_SELFCHECK 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ #define SQLITE_TESTCTRL_GETOPT 16 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 |
︙ | ︙ | |||
11142 11143 11144 11145 11146 11147 11148 | #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif #if defined(__wasi__) # undef SQLITE_WASI # define SQLITE_WASI 1 | < < | 11164 11165 11166 11167 11168 11169 11170 11171 11172 11173 11174 11175 11176 11177 | #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif #if defined(__wasi__) # undef SQLITE_WASI # define SQLITE_WASI 1 # ifndef SQLITE_OMIT_LOAD_EXTENSION # define SQLITE_OMIT_LOAD_EXTENSION # endif # ifndef SQLITE_THREADSAFE # define SQLITE_THREADSAFE 0 # endif #endif |
︙ | ︙ | |||
13346 13347 13348 13349 13350 13351 13352 13353 13354 13355 13356 13357 13358 13359 | ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. If the FTS5 table is created ** with either "detail=none" or "detail=column" and "content=" option ** (i.e. if it is a contentless table), then this API always iterates ** through an empty set (all calls to xPhraseFirst() set iCol to -1). ** ** xPhraseNext() ** See xPhraseFirst above. ** ** xPhraseFirstColumn() ** This function and xPhraseNextColumn() are similar to the xPhraseFirst() ** and xPhraseNext() APIs described above. The difference is that instead ** of iterating through all instances of a phrase in the current row, these | > > > > | 13366 13367 13368 13369 13370 13371 13372 13373 13374 13375 13376 13377 13378 13379 13380 13381 13382 13383 | ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. If the FTS5 table is created ** with either "detail=none" or "detail=column" and "content=" option ** (i.e. if it is a contentless table), then this API always iterates ** through an empty set (all calls to xPhraseFirst() set iCol to -1). ** ** In all cases, matches are visited in (column ASC, offset ASC) order. ** i.e. all those in column 0, sorted by offset, followed by those in ** column 1, etc. ** ** xPhraseNext() ** See xPhraseFirst above. ** ** xPhraseFirstColumn() ** This function and xPhraseNextColumn() are similar to the xPhraseFirst() ** and xPhraseNext() APIs described above. The difference is that instead ** of iterating through all instances of a phrase in the current row, these |
︙ | ︙ | |||
13412 13413 13414 13415 13416 13417 13418 13419 13420 | ** ** The output text is not a copy of the document text that was tokenized. ** It is the output of the tokenizer module. For tokendata=1 tables, this ** includes any embedded 0x00 and trailing data. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. */ struct Fts5ExtensionApi { | > > > > > > > > > > > > > > > > > > > > > > > | | 13436 13437 13438 13439 13440 13441 13442 13443 13444 13445 13446 13447 13448 13449 13450 13451 13452 13453 13454 13455 13456 13457 13458 13459 13460 13461 13462 13463 13464 13465 13466 13467 13468 13469 13470 13471 13472 13473 13474 13475 | ** ** The output text is not a copy of the document text that was tokenized. ** It is the output of the tokenizer module. For tokendata=1 tables, this ** includes any embedded 0x00 and trailing data. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. ** ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) ** If parameter iCol is less than zero, or greater than or equal to the ** number of columns in the table, SQLITE_RANGE is returned. ** ** Otherwise, this function attempts to retrieve the locale associated ** with column iCol of the current row. Usually, there is no associated ** locale, and output parameters (*pzLocale) and (*pnLocale) are set ** to NULL and 0, respectively. However, if the fts5_locale() function ** was used to associate a locale with the value when it was inserted ** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated ** buffer containing the name of the locale in utf-8 encoding. (*pnLocale) ** is set to the size in bytes of the buffer, not including the ** nul-terminator. ** ** If successful, SQLITE_OK is returned. Or, if an error occurs, an ** SQLite error code is returned. The final value of the output parameters ** is undefined in this case. ** ** xTokenize_v2: ** Tokenize text using the tokenizer belonging to the FTS5 table. This ** API is the same as the xTokenize() API, except that it allows a tokenizer ** locale to be specified. */ struct Fts5ExtensionApi { int iVersion; /* Currently always set to 4 */ void *(*xUserData)(Fts5Context*); int (*xColumnCount)(Fts5Context*); int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow); int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken); |
︙ | ︙ | |||
13456 13457 13458 13459 13460 13461 13462 13463 13464 13465 13466 13467 13468 13469 13470 13471 13472 13473 13474 13475 13476 13477 13478 13479 13480 13481 13482 | /* Below this point are iVersion>=3 only */ int (*xQueryToken)(Fts5Context*, int iPhrase, int iToken, const char **ppToken, int *pnToken ); int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); }; /* ** CUSTOM AUXILIARY FUNCTIONS *************************************************************************/ /************************************************************************* ** CUSTOM TOKENIZERS ** ** Applications may also register custom tokenizer types. A tokenizer ** is registered by providing fts5 with a populated instance of the ** following structure. All structure methods must be defined, setting ** any member of the fts5_tokenizer struct to NULL leads to undefined ** behaviour. The structure methods are expected to function as follows: ** ** xCreate: ** This function is used to allocate and initialize a tokenizer instance. ** A tokenizer instance is required to actually tokenize text. ** ** The first argument passed to this function is a copy of the (void*) | > > > > > > > > > > | | 13503 13504 13505 13506 13507 13508 13509 13510 13511 13512 13513 13514 13515 13516 13517 13518 13519 13520 13521 13522 13523 13524 13525 13526 13527 13528 13529 13530 13531 13532 13533 13534 13535 13536 13537 13538 13539 13540 13541 13542 13543 13544 13545 13546 13547 | /* Below this point are iVersion>=3 only */ int (*xQueryToken)(Fts5Context*, int iPhrase, int iToken, const char **ppToken, int *pnToken ); int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); /* Below this point are iVersion>=4 only */ int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); int (*xTokenize_v2)(Fts5Context*, const char *pText, int nText, /* Text to tokenize */ const char *pLocale, int nLocale, /* Locale to pass to tokenizer */ void *pCtx, /* Context passed to xToken() */ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ ); }; /* ** CUSTOM AUXILIARY FUNCTIONS *************************************************************************/ /************************************************************************* ** CUSTOM TOKENIZERS ** ** Applications may also register custom tokenizer types. A tokenizer ** is registered by providing fts5 with a populated instance of the ** following structure. All structure methods must be defined, setting ** ** any member of the fts5_tokenizer struct to NULL leads to undefined ** behaviour. The structure methods are expected to function as follows: ** ** xCreate: ** This function is used to allocate and initialize a tokenizer instance. ** A tokenizer instance is required to actually tokenize text. ** ** The first argument passed to this function is a copy of the (void*) ** pointer provided by the application when the fts5_tokenizer_v2 object ** was registered with FTS5 (the third argument to xCreateTokenizer()). ** The second and third arguments are an array of nul-terminated strings ** containing the tokenizer arguments, if any, specified following the ** tokenizer name as part of the CREATE VIRTUAL TABLE statement used ** to create the FTS5 table. ** ** The final argument is an output variable. If successful, (*ppOut) |
︙ | ︙ | |||
13500 13501 13502 13503 13504 13505 13506 | ** ** xTokenize: ** This function is expected to tokenize the nText byte string indicated ** by argument pText. pText may or may not be nul-terminated. The first ** argument passed to this function is a pointer to an Fts5Tokenizer object ** returned by an earlier call to xCreate(). ** | | | 13557 13558 13559 13560 13561 13562 13563 13564 13565 13566 13567 13568 13569 13570 13571 | ** ** xTokenize: ** This function is expected to tokenize the nText byte string indicated ** by argument pText. pText may or may not be nul-terminated. The first ** argument passed to this function is a pointer to an Fts5Tokenizer object ** returned by an earlier call to xCreate(). ** ** The third argument indicates the reason that FTS5 is requesting ** tokenization of the supplied text. This is always one of the following ** four values: ** ** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into ** or removed from the FTS table. The tokenizer is being invoked to ** determine the set of tokens to add to (or delete from) the ** FTS index. |
︙ | ︙ | |||
13523 13524 13525 13526 13527 13528 13529 13530 13531 13532 13533 13534 13535 13536 | ** returned by the tokenizer will be treated as a token prefix. ** ** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to ** satisfy an fts5_api.xTokenize() request made by an auxiliary ** function. Or an fts5_api.xColumnSize() request made by the same ** on a columnsize=0 database. ** </ul> ** ** For each token in the input string, the supplied callback xToken() must ** be invoked. The first argument to it should be a copy of the pointer ** passed as the second argument to xTokenize(). The third and fourth ** arguments are a pointer to a buffer containing the token text, and the ** size of the token in bytes. The 4th and 5th arguments are the byte offsets ** of the first byte of and first byte immediately following the text from | > > > > > > > | 13580 13581 13582 13583 13584 13585 13586 13587 13588 13589 13590 13591 13592 13593 13594 13595 13596 13597 13598 13599 13600 | ** returned by the tokenizer will be treated as a token prefix. ** ** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to ** satisfy an fts5_api.xTokenize() request made by an auxiliary ** function. Or an fts5_api.xColumnSize() request made by the same ** on a columnsize=0 database. ** </ul> ** ** The sixth and seventh arguments passed to xTokenize() - pLocale and ** nLocale - are a pointer to a buffer containing the locale to use for ** tokenization (e.g. "en_US") and its size in bytes, respectively. The ** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in ** which case nLocale is always 0) to indicate that the tokenizer should ** use its default locale. ** ** For each token in the input string, the supplied callback xToken() must ** be invoked. The first argument to it should be a copy of the pointer ** passed as the second argument to xTokenize(). The third and fourth ** arguments are a pointer to a buffer containing the token text, and the ** size of the token in bytes. The 4th and 5th arguments are the byte offsets ** of the first byte of and first byte immediately following the text from |
︙ | ︙ | |||
13546 13547 13548 13549 13550 13551 13552 13553 13554 13555 13556 13557 13558 13559 | ** If an xToken() callback returns any value other than SQLITE_OK, then ** the tokenization should be abandoned and the xTokenize() method should ** immediately return a copy of the xToken() return value. Or, if the ** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally, ** if an error occurs with the xTokenize() implementation itself, it ** may abandon the tokenization and return any error code other than ** SQLITE_OK or SQLITE_DONE. ** ** SYNONYM SUPPORT ** ** Custom tokenizers may also support synonyms. Consider a case in which a ** user wishes to query for a phrase such as "first place". Using the ** built-in tokenizers, the FTS5 query 'first + place' will match instances ** of "first place" within the document set, but not alternative forms | > > > > > > > > > > > > > > > > > > > > > > > > | 13610 13611 13612 13613 13614 13615 13616 13617 13618 13619 13620 13621 13622 13623 13624 13625 13626 13627 13628 13629 13630 13631 13632 13633 13634 13635 13636 13637 13638 13639 13640 13641 13642 13643 13644 13645 13646 13647 | ** If an xToken() callback returns any value other than SQLITE_OK, then ** the tokenization should be abandoned and the xTokenize() method should ** immediately return a copy of the xToken() return value. Or, if the ** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally, ** if an error occurs with the xTokenize() implementation itself, it ** may abandon the tokenization and return any error code other than ** SQLITE_OK or SQLITE_DONE. ** ** If the tokenizer is registered using an fts5_tokenizer_v2 object, ** then the xTokenize() method has two additional arguments - pLocale ** and nLocale. These specify the locale that the tokenizer should use ** for the current request. If pLocale and nLocale are both 0, then the ** tokenizer should use its default locale. Otherwise, pLocale points to ** an nLocale byte buffer containing the name of the locale to use as utf-8 ** text. pLocale is not nul-terminated. ** ** FTS5_TOKENIZER ** ** There is also an fts5_tokenizer object. This is an older, deprecated, ** version of fts5_tokenizer_v2. It is similar except that: ** ** <ul> ** <li> There is no "iVersion" field, and ** <li> The xTokenize() method does not take a locale argument. ** </ul> ** ** Legacy fts5_tokenizer tokenizers must be registered using the ** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). ** ** Tokenizer implementations registered using either API may be retrieved ** using both xFindTokenizer() and xFindTokenizer_v2(). ** ** SYNONYM SUPPORT ** ** Custom tokenizers may also support synonyms. Consider a case in which a ** user wishes to query for a phrase such as "first place". Using the ** built-in tokenizers, the FTS5 query 'first + place' will match instances ** of "first place" within the document set, but not alternative forms |
︙ | ︙ | |||
13655 13656 13657 13658 13659 13660 13661 13662 13663 13664 13665 13666 13667 13668 13669 13670 13671 13672 13673 13674 13675 13676 13677 13678 13679 13680 13681 13682 13683 13684 13685 13686 13687 13688 13689 13690 13691 13692 13693 13694 13695 13696 13697 13698 13699 | ** ** When using methods (2) or (3), it is important that the tokenizer only ** provide synonyms when tokenizing document text (method (3)) or query ** text (method (2)), not both. Doing so will not cause any errors, but is ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; typedef struct fts5_tokenizer fts5_tokenizer; struct fts5_tokenizer { int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); void (*xDelete)(Fts5Tokenizer*); int (*xTokenize)(Fts5Tokenizer*, void *pCtx, int flags, /* Mask of FTS5_TOKENIZE_* flags */ const char *pText, int nText, int (*xToken)( void *pCtx, /* Copy of 2nd argument to xTokenize() */ int tflags, /* Mask of FTS5_TOKEN_* flags */ const char *pToken, /* Pointer to buffer containing token */ int nToken, /* Size of token in bytes */ int iStart, /* Byte offset of token within input text */ int iEnd /* Byte offset of end of token within input text */ ) ); }; /* Flags that may be passed as the third argument to xTokenize() */ #define FTS5_TOKENIZE_QUERY 0x0001 #define FTS5_TOKENIZE_PREFIX 0x0002 #define FTS5_TOKENIZE_DOCUMENT 0x0004 #define FTS5_TOKENIZE_AUX 0x0008 /* Flags that may be passed by the tokenizer implementation back to FTS5 ** as the third argument to the supplied xToken callback. */ #define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */ /* ** END OF CUSTOM TOKENIZERS *************************************************************************/ /************************************************************************* ** FTS5 EXTENSION REGISTRATION API */ typedef struct fts5_api fts5_api; struct fts5_api { | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 13743 13744 13745 13746 13747 13748 13749 13750 13751 13752 13753 13754 13755 13756 13757 13758 13759 13760 13761 13762 13763 13764 13765 13766 13767 13768 13769 13770 13771 13772 13773 13774 13775 13776 13777 13778 13779 13780 13781 13782 13783 13784 13785 13786 13787 13788 13789 13790 13791 13792 13793 13794 13795 13796 13797 13798 13799 13800 13801 13802 13803 13804 13805 13806 13807 13808 13809 13810 13811 13812 13813 13814 13815 13816 13817 13818 13819 13820 13821 13822 13823 | ** ** When using methods (2) or (3), it is important that the tokenizer only ** provide synonyms when tokenizing document text (method (3)) or query ** text (method (2)), not both. Doing so will not cause any errors, but is ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; struct fts5_tokenizer_v2 { int iVersion; /* Currently always 2 */ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); void (*xDelete)(Fts5Tokenizer*); int (*xTokenize)(Fts5Tokenizer*, void *pCtx, int flags, /* Mask of FTS5_TOKENIZE_* flags */ const char *pText, int nText, const char *pLocale, int nLocale, int (*xToken)( void *pCtx, /* Copy of 2nd argument to xTokenize() */ int tflags, /* Mask of FTS5_TOKEN_* flags */ const char *pToken, /* Pointer to buffer containing token */ int nToken, /* Size of token in bytes */ int iStart, /* Byte offset of token within input text */ int iEnd /* Byte offset of end of token within input text */ ) ); }; /* ** New code should use the fts5_tokenizer_v2 type to define tokenizer ** implementations. The following type is included for legacy applications ** that still use it. */ typedef struct fts5_tokenizer fts5_tokenizer; struct fts5_tokenizer { int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); void (*xDelete)(Fts5Tokenizer*); int (*xTokenize)(Fts5Tokenizer*, void *pCtx, int flags, /* Mask of FTS5_TOKENIZE_* flags */ const char *pText, int nText, int (*xToken)( void *pCtx, /* Copy of 2nd argument to xTokenize() */ int tflags, /* Mask of FTS5_TOKEN_* flags */ const char *pToken, /* Pointer to buffer containing token */ int nToken, /* Size of token in bytes */ int iStart, /* Byte offset of token within input text */ int iEnd /* Byte offset of end of token within input text */ ) ); }; /* Flags that may be passed as the third argument to xTokenize() */ #define FTS5_TOKENIZE_QUERY 0x0001 #define FTS5_TOKENIZE_PREFIX 0x0002 #define FTS5_TOKENIZE_DOCUMENT 0x0004 #define FTS5_TOKENIZE_AUX 0x0008 /* Flags that may be passed by the tokenizer implementation back to FTS5 ** as the third argument to the supplied xToken callback. */ #define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */ /* ** END OF CUSTOM TOKENIZERS *************************************************************************/ /************************************************************************* ** FTS5 EXTENSION REGISTRATION API */ typedef struct fts5_api fts5_api; struct fts5_api { int iVersion; /* Currently always set to 3 */ /* Create a new tokenizer */ int (*xCreateTokenizer)( fts5_api *pApi, const char *zName, void *pUserData, fts5_tokenizer *pTokenizer, |
︙ | ︙ | |||
13720 13721 13722 13723 13724 13725 13726 13727 13728 13729 13730 13731 13732 13733 | int (*xCreateFunction)( fts5_api *pApi, const char *zName, void *pUserData, fts5_extension_function xFunction, void (*xDestroy)(void*) ); }; /* ** END OF REGISTRATION API *************************************************************************/ #if 0 | > > > > > > > > > > > > > > > > > > > | 13836 13837 13838 13839 13840 13841 13842 13843 13844 13845 13846 13847 13848 13849 13850 13851 13852 13853 13854 13855 13856 13857 13858 13859 13860 13861 13862 13863 13864 13865 13866 13867 13868 | int (*xCreateFunction)( fts5_api *pApi, const char *zName, void *pUserData, fts5_extension_function xFunction, void (*xDestroy)(void*) ); /* APIs below this point are only available if iVersion>=3 */ /* Create a new tokenizer */ int (*xCreateTokenizer_v2)( fts5_api *pApi, const char *zName, void *pUserData, fts5_tokenizer_v2 *pTokenizer, void (*xDestroy)(void*) ); /* Find an existing tokenizer */ int (*xFindTokenizer_v2)( fts5_api *pApi, const char *zName, void **ppUserData, fts5_tokenizer_v2 **ppTokenizer ); }; /* ** END OF REGISTRATION API *************************************************************************/ #if 0 |
︙ | ︙ | |||
14529 14530 14531 14532 14533 14534 14535 | #define TK_DESC 39 #define TK_DETACH 40 #define TK_EACH 41 #define TK_FAIL 42 #define TK_OR 43 #define TK_AND 44 #define TK_IS 45 | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | 14664 14665 14666 14667 14668 14669 14670 14671 14672 14673 14674 14675 14676 14677 14678 14679 14680 14681 14682 14683 14684 14685 14686 14687 14688 14689 14690 14691 14692 14693 14694 14695 14696 14697 14698 14699 14700 14701 14702 14703 14704 14705 14706 14707 14708 14709 14710 14711 14712 14713 14714 14715 14716 14717 14718 14719 14720 14721 14722 14723 14724 14725 14726 14727 14728 14729 14730 14731 14732 14733 14734 14735 14736 14737 14738 14739 14740 14741 14742 14743 14744 14745 14746 14747 14748 14749 14750 14751 14752 14753 14754 14755 14756 14757 14758 14759 14760 14761 14762 14763 14764 14765 14766 14767 14768 14769 14770 14771 14772 14773 14774 14775 14776 14777 14778 14779 14780 14781 14782 14783 14784 14785 14786 14787 14788 14789 14790 14791 14792 14793 14794 14795 14796 14797 14798 14799 14800 14801 14802 14803 | #define TK_DESC 39 #define TK_DETACH 40 #define TK_EACH 41 #define TK_FAIL 42 #define TK_OR 43 #define TK_AND 44 #define TK_IS 45 #define TK_ISNOT 46 #define TK_MATCH 47 #define TK_LIKE_KW 48 #define TK_BETWEEN 49 #define TK_IN 50 #define TK_ISNULL 51 #define TK_NOTNULL 52 #define TK_NE 53 #define TK_EQ 54 #define TK_GT 55 #define TK_LE 56 #define TK_LT 57 #define TK_GE 58 #define TK_ESCAPE 59 #define TK_ID 60 #define TK_COLUMNKW 61 #define TK_DO 62 #define TK_FOR 63 #define TK_IGNORE 64 #define TK_INITIALLY 65 #define TK_INSTEAD 66 #define TK_NO 67 #define TK_KEY 68 #define TK_OF 69 #define TK_OFFSET 70 #define TK_PRAGMA 71 #define TK_RAISE 72 #define TK_RECURSIVE 73 #define TK_REPLACE 74 #define TK_RESTRICT 75 #define TK_ROW 76 #define TK_ROWS 77 #define TK_TRIGGER 78 #define TK_VACUUM 79 #define TK_VIEW 80 #define TK_VIRTUAL 81 #define TK_WITH 82 #define TK_NULLS 83 #define TK_FIRST 84 #define TK_LAST 85 #define TK_CURRENT 86 #define TK_FOLLOWING 87 #define TK_PARTITION 88 #define TK_PRECEDING 89 #define TK_RANGE 90 #define TK_UNBOUNDED 91 #define TK_EXCLUDE 92 #define TK_GROUPS 93 #define TK_OTHERS 94 #define TK_TIES 95 #define TK_GENERATED 96 #define TK_ALWAYS 97 #define TK_MATERIALIZED 98 #define TK_REINDEX 99 #define TK_RENAME 100 #define TK_CTIME_KW 101 #define TK_ANY 102 #define TK_BITAND 103 #define TK_BITOR 104 #define TK_LSHIFT 105 #define TK_RSHIFT 106 #define TK_PLUS 107 #define TK_MINUS 108 #define TK_STAR 109 #define TK_SLASH 110 #define TK_REM 111 #define TK_CONCAT 112 #define TK_PTR 113 #define TK_COLLATE 114 #define TK_BITNOT 115 #define TK_ON 116 #define TK_INDEXED 117 #define TK_STRING 118 #define TK_JOIN_KW 119 #define TK_CONSTRAINT 120 #define TK_DEFAULT 121 #define TK_NULL 122 #define TK_PRIMARY 123 #define TK_UNIQUE 124 #define TK_CHECK 125 #define TK_REFERENCES 126 #define TK_AUTOINCR 127 #define TK_INSERT 128 #define TK_DELETE 129 #define TK_UPDATE 130 #define TK_SET 131 #define TK_DEFERRABLE 132 #define TK_FOREIGN 133 #define TK_DROP 134 #define TK_UNION 135 #define TK_ALL 136 #define TK_EXCEPT 137 #define TK_INTERSECT 138 #define TK_SELECT 139 #define TK_VALUES 140 #define TK_DISTINCT 141 #define TK_DOT 142 #define TK_FROM 143 #define TK_JOIN 144 #define TK_USING 145 #define TK_ORDER 146 #define TK_GROUP 147 #define TK_HAVING 148 #define TK_LIMIT 149 #define TK_WHERE 150 #define TK_RETURNING 151 #define TK_INTO 152 #define TK_NOTHING 153 #define TK_FLOAT 154 #define TK_BLOB 155 #define TK_INTEGER 156 #define TK_VARIABLE 157 #define TK_CASE 158 #define TK_WHEN 159 #define TK_THEN 160 #define TK_ELSE 161 #define TK_INDEX 162 #define TK_ALTER 163 #define TK_ADD 164 #define TK_WINDOW 165 #define TK_OVER 166 #define TK_FILTER 167 #define TK_COLUMN 168 #define TK_AGG_FUNCTION 169 #define TK_AGG_COLUMN 170 #define TK_TRUEFALSE 171 #define TK_FUNCTION 172 #define TK_UPLUS 173 #define TK_UMINUS 174 #define TK_TRUTH 175 #define TK_REGISTER 176 #define TK_VECTOR 177 #define TK_SELECT_COLUMN 178 |
︙ | ︙ | |||
14697 14698 14699 14700 14701 14702 14703 14704 14705 14706 14707 14708 14709 14710 | /* ** If compiling for a processor that lacks floating point support, ** substitute integer for floating-point */ #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite_int64 # define float sqlite_int64 # define LONGDOUBLE_TYPE sqlite_int64 # ifndef SQLITE_BIG_DBL # define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) # endif # define SQLITE_OMIT_DATETIME_FUNCS 1 # define SQLITE_OMIT_TRACE 1 # undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT | > > | 14832 14833 14834 14835 14836 14837 14838 14839 14840 14841 14842 14843 14844 14845 14846 14847 | /* ** If compiling for a processor that lacks floating point support, ** substitute integer for floating-point */ #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite_int64 # define float sqlite_int64 # define fabs(X) ((X)<0?-(X):(X)) # define sqlite3IsOverflow(X) 0 # define LONGDOUBLE_TYPE sqlite_int64 # ifndef SQLITE_BIG_DBL # define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) # endif # define SQLITE_OMIT_DATETIME_FUNCS 1 # define SQLITE_OMIT_TRACE 1 # undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT |
︙ | ︙ | |||
15374 15375 15376 15377 15378 15379 15380 15381 15382 15383 15384 15385 15386 15387 | typedef struct RenameToken RenameToken; typedef struct Returning Returning; typedef struct RowSet RowSet; typedef struct Savepoint Savepoint; typedef struct Select Select; typedef struct SQLiteThread SQLiteThread; typedef struct SelectDest SelectDest; typedef struct SrcItem SrcItem; typedef struct SrcList SrcList; typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ typedef struct Table Table; typedef struct TableLock TableLock; typedef struct Token Token; typedef struct TreeView TreeView; | > | 15511 15512 15513 15514 15515 15516 15517 15518 15519 15520 15521 15522 15523 15524 15525 | typedef struct RenameToken RenameToken; typedef struct Returning Returning; typedef struct RowSet RowSet; typedef struct Savepoint Savepoint; typedef struct Select Select; typedef struct SQLiteThread SQLiteThread; typedef struct SelectDest SelectDest; typedef struct Subquery Subquery; typedef struct SrcItem SrcItem; typedef struct SrcList SrcList; typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ typedef struct Table Table; typedef struct TableLock TableLock; typedef struct Token Token; typedef struct TreeView TreeView; |
︙ | ︙ | |||
16474 16475 16476 16477 16478 16479 16480 16481 16482 16483 16484 16485 16486 16487 | /* ** The names of the following types declared in vdbeInt.h are required ** for the VdbeOp definition. */ typedef struct sqlite3_value Mem; typedef struct SubProgram SubProgram; /* ** A single instruction of the virtual machine has an opcode ** and as many as three operands. The instruction is recorded ** as an instance of the following structure: */ struct VdbeOp { | > > > > > > > > > > > > > | 16612 16613 16614 16615 16616 16617 16618 16619 16620 16621 16622 16623 16624 16625 16626 16627 16628 16629 16630 16631 16632 16633 16634 16635 16636 16637 16638 | /* ** The names of the following types declared in vdbeInt.h are required ** for the VdbeOp definition. */ typedef struct sqlite3_value Mem; typedef struct SubProgram SubProgram; typedef struct SubrtnSig SubrtnSig; /* ** A signature for a reusable subroutine that materializes the RHS of ** an IN operator. */ struct SubrtnSig { int selId; /* SELECT-id for the SELECT statement on the RHS */ char *zAff; /* Affinity of the overall IN expression */ int iTable; /* Ephemeral table generated by the subroutine */ int iAddr; /* Subroutine entry address */ int regReturn; /* Register used to hold return address */ }; /* ** A single instruction of the virtual machine has an opcode ** and as many as three operands. The instruction is recorded ** as an instance of the following structure: */ struct VdbeOp { |
︙ | ︙ | |||
16502 16503 16504 16505 16506 16507 16508 16509 16510 16511 16512 16513 16514 16515 | CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */ Mem *pMem; /* Used when p4type is P4_MEM */ VTable *pVtab; /* Used when p4type is P4_VTAB */ KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */ u32 *ai; /* Used when p4type is P4_INTARRAY */ SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ Table *pTab; /* Used when p4type is P4_TABLE */ #ifdef SQLITE_ENABLE_CURSOR_HINTS Expr *pExpr; /* Used when p4type is P4_EXPR */ #endif } p4; #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS char *zComment; /* Comment to improve readability */ #endif | > | 16653 16654 16655 16656 16657 16658 16659 16660 16661 16662 16663 16664 16665 16666 16667 | CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */ Mem *pMem; /* Used when p4type is P4_MEM */ VTable *pVtab; /* Used when p4type is P4_VTAB */ KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */ u32 *ai; /* Used when p4type is P4_INTARRAY */ SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ Table *pTab; /* Used when p4type is P4_TABLE */ SubrtnSig *pSubrtnSig; /* Used when p4type is P4_SUBRTNSIG */ #ifdef SQLITE_ENABLE_CURSOR_HINTS Expr *pExpr; /* Used when p4type is P4_EXPR */ #endif } p4; #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS char *zComment; /* Comment to improve readability */ #endif |
︙ | ︙ | |||
16569 16570 16571 16572 16573 16574 16575 16576 16577 16578 16579 16580 16581 16582 | #define P4_MEM (-10) /* P4 is a pointer to a Mem* structure */ #define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */ #define P4_REAL (-12) /* P4 is a 64-bit floating point value */ #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ #define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 #define P5_ConstraintUnique 2 #define P5_ConstraintCheck 3 #define P5_ConstraintFK 4 | > | 16721 16722 16723 16724 16725 16726 16727 16728 16729 16730 16731 16732 16733 16734 16735 | #define P4_MEM (-10) /* P4 is a pointer to a Mem* structure */ #define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */ #define P4_REAL (-12) /* P4 is a 64-bit floating point value */ #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ #define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ #define P4_SUBRTNSIG (-17) /* P4 is a SubrtnSig pointer */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 #define P5_ConstraintUnique 2 #define P5_ConstraintCheck 3 #define P5_ConstraintFK 4 |
︙ | ︙ | |||
16660 16661 16662 16663 16664 16665 16666 | #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ #define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ #define OP_IdxGE 45 /* jump, synopsis: key=r[P3@P4] */ #define OP_RowSetRead 46 /* jump, synopsis: r[P3]=rowset(P1) */ #define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ #define OP_Program 48 /* jump0 */ #define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ | > | | | | | | | | | < | 16813 16814 16815 16816 16817 16818 16819 16820 16821 16822 16823 16824 16825 16826 16827 16828 16829 16830 16831 16832 16833 16834 16835 16836 | #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ #define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ #define OP_IdxGE 45 /* jump, synopsis: key=r[P3@P4] */ #define OP_RowSetRead 46 /* jump, synopsis: r[P3]=rowset(P1) */ #define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ #define OP_Program 48 /* jump0 */ #define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ #define OP_IfPos 50 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ #define OP_IsNull 51 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ #define OP_NotNull 52 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ #define OP_Ne 53 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ #define OP_Eq 54 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ #define OP_Gt 55 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ #define OP_Le 56 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ #define OP_Lt 57 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */ #define OP_Ge 58 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */ #define OP_ElseEq 59 /* jump, same as TK_ESCAPE */ #define OP_IfNotZero 60 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ #define OP_DecrJumpZero 61 /* jump, synopsis: if (--r[P1])==0 goto P2 */ #define OP_IncrVacuum 62 /* jump */ #define OP_VNext 63 /* jump */ #define OP_Filter 64 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ #define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */ #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */ |
︙ | ︙ | |||
16712 16713 16714 16715 16716 16717 16718 | #define OP_TypeCheck 95 /* synopsis: typecheck(r[P1@P2]) */ #define OP_Affinity 96 /* synopsis: affinity(r[P1@P2]) */ #define OP_MakeRecord 97 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ #define OP_Count 98 /* synopsis: r[P2]=count() */ #define OP_ReadCookie 99 #define OP_SetCookie 100 #define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */ | > | | | | | | | | | | < < | > < | > | 16865 16866 16867 16868 16869 16870 16871 16872 16873 16874 16875 16876 16877 16878 16879 16880 16881 16882 16883 16884 16885 16886 16887 16888 16889 16890 16891 16892 16893 16894 16895 | #define OP_TypeCheck 95 /* synopsis: typecheck(r[P1@P2]) */ #define OP_Affinity 96 /* synopsis: affinity(r[P1@P2]) */ #define OP_MakeRecord 97 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ #define OP_Count 98 /* synopsis: r[P2]=count() */ #define OP_ReadCookie 99 #define OP_SetCookie 100 #define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */ #define OP_OpenRead 102 /* synopsis: root=P2 iDb=P3 */ #define OP_BitAnd 103 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ #define OP_BitOr 104 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ #define OP_ShiftLeft 105 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ #define OP_ShiftRight 106 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ #define OP_Add 107 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ #define OP_Subtract 108 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ #define OP_Multiply 109 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ #define OP_Divide 110 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ #define OP_Remainder 111 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ #define OP_Concat 112 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ #define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */ #define OP_OpenDup 114 #define OP_BitNot 115 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ #define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */ #define OP_OpenEphemeral 117 /* synopsis: nColumn=P2 */ #define OP_String8 118 /* same as TK_STRING, synopsis: r[P2]='P4' */ #define OP_SorterOpen 119 #define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ #define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */ #define OP_Close 122 #define OP_ColumnsUsed 123 #define OP_SeekScan 124 /* synopsis: Scan-ahead up to P1 rows */ #define OP_SeekHit 125 /* synopsis: set P2<=seekHit<=P3 */ |
︙ | ︙ | |||
16763 16764 16765 16766 16767 16768 16769 | #define OP_ResetSorter 146 #define OP_CreateBtree 147 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ #define OP_SqlExec 148 #define OP_ParseSchema 149 #define OP_LoadAnalysis 150 #define OP_DropTable 151 #define OP_DropIndex 152 | < | > | 16916 16917 16918 16919 16920 16921 16922 16923 16924 16925 16926 16927 16928 16929 16930 16931 | #define OP_ResetSorter 146 #define OP_CreateBtree 147 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ #define OP_SqlExec 148 #define OP_ParseSchema 149 #define OP_LoadAnalysis 150 #define OP_DropTable 151 #define OP_DropIndex 152 #define OP_DropTrigger 153 #define OP_Real 154 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ #define OP_IntegrityCk 155 #define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */ #define OP_Param 157 #define OP_FkCounter 158 /* synopsis: fkctr[P1]+=P2 */ #define OP_MemMax 159 /* synopsis: r[P1]=max(r[P1],r[P2]) */ #define OP_OffsetLimit 160 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ #define OP_AggInverse 161 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ |
︙ | ︙ | |||
16820 16821 16822 16823 16824 16825 16826 | #define OPFLG_INITIALIZER {\ /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\ /* 8 */ 0x81, 0x01, 0x01, 0x81, 0x83, 0x83, 0x01, 0x01,\ /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0xc9, 0xc9, 0xc9,\ /* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\ /* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x41, 0x41,\ /* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\ | | | | | | | 16973 16974 16975 16976 16977 16978 16979 16980 16981 16982 16983 16984 16985 16986 16987 16988 16989 16990 16991 16992 16993 16994 16995 16996 16997 16998 16999 17000 | #define OPFLG_INITIALIZER {\ /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\ /* 8 */ 0x81, 0x01, 0x01, 0x81, 0x83, 0x83, 0x01, 0x01,\ /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0xc9, 0xc9, 0xc9,\ /* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\ /* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x41, 0x41,\ /* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\ /* 48 */ 0x81, 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ /* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x41,\ /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\ /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40, 0x00,\ /* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x40, 0x26,\ /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ /* 112 */ 0x26, 0x00, 0x40, 0x12, 0x40, 0x40, 0x10, 0x00,\ /* 120 */ 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10, 0x10,\ /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50,\ /* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\ /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ /* 152 */ 0x00, 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04,\ /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\ /* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12, 0x00,\ /* 184 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} /* The resolve3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum |
︙ | ︙ | |||
17894 17895 17896 17897 17898 17899 17900 17901 17902 17903 17904 17905 17906 17907 | #define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. */ #define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) #define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) | > | 18047 18048 18049 18050 18051 18052 18053 18054 18055 18056 18057 18058 18059 18060 18061 | #define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ #define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. */ #define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) #define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) |
︙ | ︙ | |||
18881 18882 18883 18884 18885 18886 18887 18888 18889 18890 18891 18892 18893 18894 18895 18896 18897 | /* ** Macros to compute aCol[] and aFunc[] register numbers. ** ** These macros should not be used prior to the call to ** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. ** The assert()s that are part of this macro verify that constraint. */ #define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I)) #define AggInfoFuncReg(A,I) \ (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I)) /* ** The datatype ynVar is a signed integer, either 16-bit or 32-bit. ** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater ** than 32767 we have to make it 32-bit. 16-bit is preferred because ** it uses less memory in the Expr object, which is a big memory user ** in systems with lots of prepared statements. And few applications | > > > > > > | 19035 19036 19037 19038 19039 19040 19041 19042 19043 19044 19045 19046 19047 19048 19049 19050 19051 19052 19053 19054 19055 19056 19057 | /* ** Macros to compute aCol[] and aFunc[] register numbers. ** ** These macros should not be used prior to the call to ** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. ** The assert()s that are part of this macro verify that constraint. */ #ifndef NDEBUG #define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I)) #define AggInfoFuncReg(A,I) \ (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I)) #else #define AggInfoColumnReg(A,I) ((A)->iFirstReg+(I)) #define AggInfoFuncReg(A,I) \ ((A)->iFirstReg+(A)->nColumn+(I)) #endif /* ** The datatype ynVar is a signed integer, either 16-bit or 32-bit. ** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater ** than 32767 we have to make it 32-bit. 16-bit is preferred because ** it uses less memory in the Expr object, which is a big memory user ** in systems with lots of prepared statements. And few applications |
︙ | ︙ | |||
19235 19236 19237 19238 19239 19240 19241 19242 19243 19244 19245 19246 19247 19248 19249 19250 19251 19252 19253 | ** Allowed values for IdList.eType, which determines which value of the a.u4 ** is valid. */ #define EU4_NONE 0 /* Does not use IdList.a.u4 */ #define EU4_IDX 1 /* Uses IdList.a.u4.idx */ #define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */ /* ** The SrcItem object represents a single term in the FROM clause of a query. ** The SrcList object is mostly an array of SrcItems. ** ** The jointype starts out showing the join type between the current table ** and the next table on the list. The parser builds the list this way. ** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each ** jointype expresses the join between the table and the previous table. ** ** In the colUsed field, the high-order bit (bit 63) is set if the table ** contains more than 63 columns and the 64-th or later column is used. ** | > > > > > > > > > > > > | > > > | | | | > > > > > > > > > > > < < | < < < < > > > < < < < > > > > > > > > > | 19395 19396 19397 19398 19399 19400 19401 19402 19403 19404 19405 19406 19407 19408 19409 19410 19411 19412 19413 19414 19415 19416 19417 19418 19419 19420 19421 19422 19423 19424 19425 19426 19427 19428 19429 19430 19431 19432 19433 19434 19435 19436 19437 19438 19439 19440 19441 19442 19443 19444 19445 19446 19447 19448 19449 19450 19451 19452 19453 19454 19455 19456 19457 19458 19459 19460 19461 19462 19463 19464 19465 19466 19467 19468 19469 19470 19471 19472 19473 19474 19475 19476 19477 19478 19479 19480 19481 19482 19483 19484 19485 19486 19487 19488 19489 19490 19491 19492 19493 19494 19495 19496 19497 19498 19499 19500 | ** Allowed values for IdList.eType, which determines which value of the a.u4 ** is valid. */ #define EU4_NONE 0 /* Does not use IdList.a.u4 */ #define EU4_IDX 1 /* Uses IdList.a.u4.idx */ #define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */ /* ** Details of the implementation of a subquery. */ struct Subquery { Select *pSelect; /* A SELECT statement used in place of a table name */ int addrFillSub; /* Address of subroutine to initialize a subquery */ int regReturn; /* Register holding return address of addrFillSub */ int regResult; /* Registers holding results of a co-routine */ }; /* ** The SrcItem object represents a single term in the FROM clause of a query. ** The SrcList object is mostly an array of SrcItems. ** ** The jointype starts out showing the join type between the current table ** and the next table on the list. The parser builds the list this way. ** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each ** jointype expresses the join between the table and the previous table. ** ** In the colUsed field, the high-order bit (bit 63) is set if the table ** contains more than 63 columns and the 64-th or later column is used. ** ** Aggressive use of "union" helps keep the size of the object small. This ** has been shown to boost performance, in addition to saving memory. ** Access to union elements is gated by the following rules which should ** always be checked, either by an if-statement or by an assert(). ** ** Field Only access if this is true ** --------------- ----------------------------------- ** u1.zIndexedBy fg.isIndexedBy ** u1.pFuncArg fg.isTabFunc ** u1.nRow !fg.isTabFunc && !fg.isIndexedBy ** ** u2.pIBIndex fg.isIndexedBy ** u2.pCteUse fg.isCte ** ** u3.pOn !fg.isUsing ** u3.pUsing fg.isUsing ** ** u4.zDatabase !fg.fixedSchema && !fg.isSubquery ** u4.pSchema fg.fixedSchema ** u4.pSubq fg.isSubquery ** ** See also the sqlite3SrcListDelete() routine for assert() statements that ** check invariants on the fields of this object, especially the flags ** inside the fg struct. */ struct SrcItem { char *zName; /* Name of the table */ char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ Table *pSTab; /* Table object for zName. Mnemonic: Srcitem-TABle */ struct { u8 jointype; /* Type of join between this table and the previous */ unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ unsigned isSubquery :1; /* True if this term is a subquery */ unsigned isTabFunc :1; /* True if table-valued-function syntax */ unsigned isCorrelated :1; /* True if sub-query is correlated */ unsigned isMaterialized:1; /* This is a materialized view */ unsigned viaCoroutine :1; /* Implemented as a co-routine */ unsigned isRecursive :1; /* True for recursive reference in WITH */ unsigned fromDDL :1; /* Comes from sqlite_schema */ unsigned isCte :1; /* This is a CTE */ unsigned notCte :1; /* This item may not match a CTE */ unsigned isUsing :1; /* u3.pUsing is valid */ unsigned isOn :1; /* u3.pOn was once valid and non-NULL */ unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ unsigned rowidUsed :1; /* The ROWID of this table is referenced */ unsigned fixedSchema :1; /* Uses u4.pSchema, not u4.zDatabase */ unsigned hadSchema :1; /* Had u4.zDatabase before u4.pSchema */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */ union { char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */ ExprList *pFuncArg; /* Arguments to table-valued-function */ u32 nRow; /* Number of rows in a VALUES clause */ } u1; union { Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */ } u2; union { Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ } u3; union { Schema *pSchema; /* Schema to which this item is fixed */ char *zDatabase; /* Name of database holding this table */ Subquery *pSubq; /* Description of a subquery */ } u4; }; /* ** The OnOrUsing object represents either an ON clause or a USING clause. ** It can never be both at the same time, but it can be neither. */ struct OnOrUsing { |
︙ | ︙ | |||
19358 19359 19360 19361 19362 19363 19364 | #define WHERE_GROUPBY 0x0040 /* pOrderBy is really a GROUP BY */ #define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */ #define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */ #define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */ #define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */ #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ #define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */ | | | 19546 19547 19548 19549 19550 19551 19552 19553 19554 19555 19556 19557 19558 19559 19560 | #define WHERE_GROUPBY 0x0040 /* pOrderBy is really a GROUP BY */ #define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */ #define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */ #define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */ #define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */ #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ #define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */ #define WHERE_KEEP_ALL_JOINS 0x2000 /* Do not do the omit-noop-join opt */ #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ /* 0x8000 not currently used */ /* Allowed return values from sqlite3WhereIsDistinct() */ #define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ #define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ |
︙ | ︙ | |||
19430 19431 19432 19433 19434 19435 19436 | #define NC_SelfRef 0x00002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */ #define NC_Subquery 0x000040 /* A subquery has been seen */ #define NC_UEList 0x000080 /* True if uNC.pEList is used */ #define NC_UAggInfo 0x000100 /* True if uNC.pAggInfo is used */ #define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ #define NC_UBaseReg 0x000400 /* True if uNC.iBaseReg is used */ #define NC_MinMaxAgg 0x001000 /* min/max aggregates seen. See note above */ | | | 19618 19619 19620 19621 19622 19623 19624 19625 19626 19627 19628 19629 19630 19631 19632 | #define NC_SelfRef 0x00002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */ #define NC_Subquery 0x000040 /* A subquery has been seen */ #define NC_UEList 0x000080 /* True if uNC.pEList is used */ #define NC_UAggInfo 0x000100 /* True if uNC.pAggInfo is used */ #define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ #define NC_UBaseReg 0x000400 /* True if uNC.iBaseReg is used */ #define NC_MinMaxAgg 0x001000 /* min/max aggregates seen. See note above */ /* 0x002000 // available for reuse */ #define NC_AllowWin 0x004000 /* Window functions are allowed here */ #define NC_HasWin 0x008000 /* One or more window functions seen */ #define NC_IsDDL 0x010000 /* Resolving names in a CREATE statement */ #define NC_InAggFunc 0x020000 /* True if analyzing arguments to an agg func */ #define NC_FromDDL 0x040000 /* SQL text comes from sqlite_schema */ #define NC_NoSelect 0x080000 /* Do not descend into sub-selects */ #define NC_Where 0x100000 /* Processing WHERE clause of a SELECT */ |
︙ | ︙ | |||
19558 19559 19560 19561 19562 19563 19564 | #define SF_PushDown 0x1000000 /* Modified by WHERE-clause push-down opt */ #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ #define SF_Correlated 0x20000000 /* True if references the outer context */ | | | > > | 19746 19747 19748 19749 19750 19751 19752 19753 19754 19755 19756 19757 19758 19759 19760 19761 19762 19763 | #define SF_PushDown 0x1000000 /* Modified by WHERE-clause push-down opt */ #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ #define SF_Correlated 0x20000000 /* True if references the outer context */ /* True if SrcItem X is a subquery that has SF_NestedFrom */ #define IsNestedFrom(X) \ ((X)->fg.isSubquery && \ ((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0) /* ** The results of a SELECT can be distributed in several ways, as defined ** by one of the following macros. The "SRT" prefix means "SELECT Result ** Type". ** ** SRT_Union Store results as a key in a temporary index |
︙ | ︙ | |||
19589 19590 19591 19592 19593 19594 19595 | ** Store the first column of the first result row ** in register pDest->iSDParm then abandon the rest ** of the query. This destination implies "LIMIT 1". ** ** SRT_Set The result must be a single column. Store each ** row of result as the key in table pDest->iSDParm. ** Apply the affinity pDest->affSdst before storing | > > > > | | 19779 19780 19781 19782 19783 19784 19785 19786 19787 19788 19789 19790 19791 19792 19793 19794 19795 19796 19797 | ** Store the first column of the first result row ** in register pDest->iSDParm then abandon the rest ** of the query. This destination implies "LIMIT 1". ** ** SRT_Set The result must be a single column. Store each ** row of result as the key in table pDest->iSDParm. ** Apply the affinity pDest->affSdst before storing ** results. if pDest->iSDParm2 is positive, then it is ** a regsiter holding a Bloom filter for the IN operator ** that should be populated in addition to the ** pDest->iSDParm table. This SRT is used to ** implement "IN (SELECT ...)". ** ** SRT_EphemTab Create an temporary table pDest->iSDParm and store ** the result there. The cursor is left open after ** returning. This is like SRT_Table except that ** this destination uses OP_OpenEphemeral to create ** the table first. ** |
︙ | ︙ | |||
19797 19798 19799 19800 19801 19802 19803 19804 19805 19806 19807 19808 19809 19810 | 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 */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ u8 bHasWith; /* True if statement contains WITH */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ #endif #ifdef SQLITE_DEBUG u8 ifNotExists; /* Might be true if IF NOT EXISTS. Assert()s only */ #endif int nRangeReg; /* Size of the temporary register block */ | > | 19991 19992 19993 19994 19995 19996 19997 19998 19999 20000 20001 20002 20003 20004 20005 | 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 */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ u8 bHasWith; /* True if statement contains WITH */ u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ #endif #ifdef SQLITE_DEBUG u8 ifNotExists; /* Might be true if IF NOT EXISTS. Assert()s only */ #endif int nRangeReg; /* Size of the temporary register block */ |
︙ | ︙ | |||
20092 20093 20094 20095 20096 20097 20098 | int iRetCur; /* Transient table holding RETURNING results */ int nRetCol; /* Number of in pReturnEL after expansion */ int iRetReg; /* Register array for holding a row of RETURNING */ char zName[40]; /* Name of trigger: "sqlite_returning_%p" */ }; /* | | | | 20287 20288 20289 20290 20291 20292 20293 20294 20295 20296 20297 20298 20299 20300 20301 20302 20303 20304 20305 20306 20307 20308 20309 20310 20311 20312 20313 20314 20315 | int iRetCur; /* Transient table holding RETURNING results */ int nRetCol; /* Number of in pReturnEL after expansion */ int iRetReg; /* Register array for holding a row of RETURNING */ char zName[40]; /* Name of trigger: "sqlite_returning_%p" */ }; /* ** An object used to accumulate the text of a string where we ** do not necessarily know how big the string will be in the end. */ struct sqlite3_str { sqlite3 *db; /* Optional database for lookaside. Can be NULL */ char *zText; /* The string collected so far */ u32 nAlloc; /* Amount of space allocated in zText */ u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ u32 nChar; /* Length of the string so far */ u8 accError; /* SQLITE_NOMEM or SQLITE_TOOBIG */ u8 printfFlags; /* SQLITE_PRINTF flags below */ }; #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 zText is allocated space */ #define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) /* ** The following object is the header for an "RCStr" or "reference-counted ** string". An RCStr is passed around and used like any other char* ** that has been dynamically allocated. The important interface |
︙ | ︙ | |||
20946 20947 20948 20949 20950 20951 20952 20953 20954 20955 20956 20957 20958 20959 | #endif SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*); SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2); SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, Token*, Select*, OnOrUsing*); SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *); SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse*,SrcList*); SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); | > > > | 21141 21142 21143 21144 21145 21146 21147 21148 21149 21150 21151 21152 21153 21154 21155 21156 21157 | #endif SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*); SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2); SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3*,Subquery*); SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3*,SrcItem*); SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery(Parse*, SrcItem*, Select*, int); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, Token*, Select*, OnOrUsing*); SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *); SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse*,SrcList*); SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); |
︙ | ︙ | |||
20995 20996 20997 20998 20999 21000 21001 21002 21003 21004 21005 21006 21007 21008 | #define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */ #define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */ SQLITE_PRIVATE int sqlite3WhereUsesDeferredSeek(WhereInfo*); SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int); SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); #ifndef SQLITE_OMIT_GENERATED_COLUMNS SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int); #endif SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int); SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int); | > | 21193 21194 21195 21196 21197 21198 21199 21200 21201 21202 21203 21204 21205 21206 21207 | #define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */ #define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */ SQLITE_PRIVATE int sqlite3WhereUsesDeferredSeek(WhereInfo*); SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int); SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg); SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); #ifndef SQLITE_OMIT_GENERATED_COLUMNS SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int); #endif SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int); SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int); |
︙ | ︙ | |||
21057 21058 21059 21060 21061 21062 21063 | SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse*,Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,int); #ifdef SQLITE_ENABLE_CURSOR_HINTS SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); #endif | | | 21256 21257 21258 21259 21260 21261 21262 21263 21264 21265 21266 21267 21268 21269 21270 | SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse*,Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,int); #ifdef SQLITE_ENABLE_CURSOR_HINTS SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); #endif SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*, Parse*); SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); SQLITE_PRIVATE int sqlite3IsRowid(const char*); SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab); SQLITE_PRIVATE void sqlite3GenerateRowDelete( Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); |
︙ | ︙ | |||
21185 21186 21187 21188 21189 21190 21191 | SQLITE_PRIVATE i64 sqlite3RealToI64(double); SQLITE_PRIVATE int sqlite3Int64ToText(i64,char*); SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8); SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); SQLITE_PRIVATE int sqlite3Atoi(const char*); #ifndef SQLITE_OMIT_UTF16 | | | 21384 21385 21386 21387 21388 21389 21390 21391 21392 21393 21394 21395 21396 21397 21398 | SQLITE_PRIVATE i64 sqlite3RealToI64(double); SQLITE_PRIVATE int sqlite3Int64ToText(i64,char*); SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8); SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); SQLITE_PRIVATE int sqlite3Atoi(const char*); #ifndef SQLITE_OMIT_UTF16 SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nByte, int nChar); #endif SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); SQLITE_PRIVATE int sqlite3Utf8ReadLimited(const u8*, int, u32*); SQLITE_PRIVATE LogEst sqlite3LogEst(u64); SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst); SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); |
︙ | ︙ | |||
22170 22171 22172 22173 22174 22175 22176 22177 22178 22179 22180 22181 22182 22183 | "ENABLE_NORMALIZE", #endif #ifdef SQLITE_ENABLE_NULL_TRIM "ENABLE_NULL_TRIM", #endif #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC "ENABLE_OFFSET_SQL_FUNC", #endif #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK "ENABLE_OVERSIZE_CELL_CHECK", #endif #ifdef SQLITE_ENABLE_PREUPDATE_HOOK "ENABLE_PREUPDATE_HOOK", #endif | > > > | 22369 22370 22371 22372 22373 22374 22375 22376 22377 22378 22379 22380 22381 22382 22383 22384 22385 | "ENABLE_NORMALIZE", #endif #ifdef SQLITE_ENABLE_NULL_TRIM "ENABLE_NULL_TRIM", #endif #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC "ENABLE_OFFSET_SQL_FUNC", #endif #ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES "ENABLE_ORDERED_SET_AGGREGATES", #endif #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK "ENABLE_OVERSIZE_CELL_CHECK", #endif #ifdef SQLITE_ENABLE_PREUPDATE_HOOK "ENABLE_PREUPDATE_HOOK", #endif |
︙ | ︙ | |||
23641 23642 23643 23644 23645 23646 23647 23648 23649 23650 23651 23652 23653 23654 | int iNewReg; /* Register for new.* values */ int iBlobWrite; /* Value returned by preupdate_blobwrite() */ i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ Mem *aNew; /* Array of new.* values */ Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ }; /* ** An instance of this object is used to pass an vector of values into ** OP_VFilter, the xFilter method of a virtual table. The vector is the ** set of values on the right-hand side of an IN constraint. ** | > | 23843 23844 23845 23846 23847 23848 23849 23850 23851 23852 23853 23854 23855 23856 23857 | int iNewReg; /* Register for new.* values */ int iBlobWrite; /* Value returned by preupdate_blobwrite() */ i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ Mem *aNew; /* Array of new.* values */ Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ sqlite3_value **apDflt; /* Array of default values, if required */ }; /* ** An instance of this object is used to pass an vector of values into ** OP_VFilter, the xFilter method of a virtual table. The vector is the ** set of values on the right-hand side of an IN constraint. ** |
︙ | ︙ | |||
24487 24488 24489 24490 24491 24492 24493 | datetimeError(p); return; } if( M<=2 ){ Y--; M += 12; } | | | | 24690 24691 24692 24693 24694 24695 24696 24697 24698 24699 24700 24701 24702 24703 24704 24705 | datetimeError(p); return; } if( M<=2 ){ Y--; M += 12; } A = (Y+4800)/100; B = 38 - A + (A/4); X1 = 36525*(Y+4716)/100; X2 = 306001*(M+1)/10000; p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); p->validJD = 1; if( p->validHMS ){ p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5); if( p->tz ){ |
︙ | ︙ | |||
24672 24673 24674 24675 24676 24677 24678 | return iJD>=0 && iJD<=INT_464269060799999; } /* ** Compute the Year, Month, and Day from the julian day number. */ static void computeYMD(DateTime *p){ | | | | | 24875 24876 24877 24878 24879 24880 24881 24882 24883 24884 24885 24886 24887 24888 24889 24890 24891 24892 24893 24894 24895 24896 24897 24898 24899 24900 24901 | return iJD>=0 && iJD<=INT_464269060799999; } /* ** Compute the Year, Month, and Day from the julian day number. */ static void computeYMD(DateTime *p){ int Z, alpha, A, B, C, D, E, X1; if( p->validYMD ) return; if( !p->validJD ){ p->Y = 2000; p->M = 1; p->D = 1; }else if( !validJulianDay(p->iJD) ){ datetimeError(p); return; }else{ Z = (int)((p->iJD + 43200000)/86400000); alpha = (int)((Z + 32044.75)/36524.25) - 52; A = Z + 1 + alpha - ((alpha+100)/4) + 25; B = A + 1524; C = (int)((B - 122.1)/365.25); D = (36525*(C&32767))/100; E = (int)((B-D)/30.6001); X1 = (int)(30.6001*E); p->D = B - D - X1; p->M = E<14 ? E-1 : E-13; |
︙ | ︙ | |||
24883 24884 24885 24886 24887 24888 24889 | float rLimit; /* Maximum NNN value for this transform */ float rXform; /* Constant used for this transform */ } aXformType[] = { /* 0 */ { 6, "second", 4.6427e+14, 1.0 }, /* 1 */ { 6, "minute", 7.7379e+12, 60.0 }, /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 }, /* 3 */ { 3, "day", 5373485.0, 86400.0 }, | | | | 25086 25087 25088 25089 25090 25091 25092 25093 25094 25095 25096 25097 25098 25099 25100 25101 | float rLimit; /* Maximum NNN value for this transform */ float rXform; /* Constant used for this transform */ } aXformType[] = { /* 0 */ { 6, "second", 4.6427e+14, 1.0 }, /* 1 */ { 6, "minute", 7.7379e+12, 60.0 }, /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 }, /* 3 */ { 3, "day", 5373485.0, 86400.0 }, /* 4 */ { 5, "month", 176546.0, 2592000.0 }, /* 5 */ { 4, "year", 14713.0, 31536000.0 }, }; /* ** If the DateTime p is raw number, try to figure out if it is ** a julian day number of a unix timestamp. Set the p value ** appropriately. */ |
︙ | ︙ | |||
29086 29087 29088 29089 29090 29091 29092 29093 29094 29095 29096 29097 29098 29099 29100 29101 | } } #ifndef NDEBUG /* ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use inside assert() statements. */ SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){ assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld ); return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); } SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld ); return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); } | > > > > > > > > > > > > > | | 29289 29290 29291 29292 29293 29294 29295 29296 29297 29298 29299 29300 29301 29302 29303 29304 29305 29306 29307 29308 29309 29310 29311 29312 29313 29314 29315 29316 29317 29318 29319 29320 29321 29322 29323 29324 29325 | } } #ifndef NDEBUG /* ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use inside assert() statements. ** ** Because these routines raise false-positive alerts in TSAN, disable ** them (make them always return 1) when compiling with TSAN. */ SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){ # if defined(__has_feature) # if __has_feature(thread_sanitizer) p = 0; # endif # endif assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld ); return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); } SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ # if defined(__has_feature) # if __has_feature(thread_sanitizer) p = 0; # endif # endif assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld ); return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); } #endif /* NDEBUG */ #endif /* !defined(SQLITE_MUTEX_OMIT) */ /************** End of mutex.c ***********************************************/ /************** Begin file mutex_noop.c **************************************/ /* ** 2008 October 07 |
︙ | ︙ | |||
31983 31984 31985 31986 31987 31988 31989 | SrcItem *pItem; if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; pItem = va_arg(ap, SrcItem*); assert( bArgList==0 ); if( pItem->zAlias && !flag_altform2 ){ sqlite3_str_appendall(pAccum, pItem->zAlias); }else if( pItem->zName ){ | | > > > | | | | | 32199 32200 32201 32202 32203 32204 32205 32206 32207 32208 32209 32210 32211 32212 32213 32214 32215 32216 32217 32218 32219 32220 32221 32222 32223 32224 32225 | SrcItem *pItem; if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; pItem = va_arg(ap, SrcItem*); assert( bArgList==0 ); if( pItem->zAlias && !flag_altform2 ){ sqlite3_str_appendall(pAccum, pItem->zAlias); }else if( pItem->zName ){ if( pItem->fg.fixedSchema==0 && pItem->fg.isSubquery==0 && pItem->u4.zDatabase!=0 ){ sqlite3_str_appendall(pAccum, pItem->u4.zDatabase); sqlite3_str_append(pAccum, ".", 1); } sqlite3_str_appendall(pAccum, pItem->zName); }else if( pItem->zAlias ){ sqlite3_str_appendall(pAccum, pItem->zAlias); }else if( ALWAYS(pItem->fg.isSubquery) ){/* Because of tag-20240424-1 */ Select *pSel = pItem->u4.pSubq->pSelect; assert( pSel!=0 ); if( pSel->selFlags & SF_NestedFrom ){ sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId); }else if( pSel->selFlags & SF_MultiValue ){ assert( !pItem->fg.isTabFunc && !pItem->fg.isIndexedBy ); sqlite3_str_appendf(pAccum, "%u-ROW VALUES CLAUSE", pItem->u1.nRow); }else{ |
︙ | ︙ | |||
32774 32775 32776 32777 32778 32779 32780 | const SrcItem *pItem = &pSrc->a[i]; StrAccum x; int n = 0; char zLine[1000]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); x.printfFlags |= SQLITE_PRINTF_INTERNAL; sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); | | | | 32993 32994 32995 32996 32997 32998 32999 33000 33001 33002 33003 33004 33005 33006 33007 33008 33009 | const SrcItem *pItem = &pSrc->a[i]; StrAccum x; int n = 0; char zLine[1000]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); x.printfFlags |= SQLITE_PRINTF_INTERNAL; sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); if( pItem->pSTab ){ sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s", pItem->pSTab->zName, pItem->pSTab->nCol, pItem->pSTab, pItem->colUsed, pItem->fg.rowidUsed ? "+rowid" : ""); } if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){ sqlite3_str_appendf(&x, " FULL-OUTER-JOIN"); }else if( pItem->fg.jointype & JT_LEFT ){ sqlite3_str_appendf(&x, " LEFT-JOIN"); |
︙ | ︙ | |||
32807 32808 32809 32810 32811 32812 32813 32814 32815 32816 32817 | } if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc"); if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated"); if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized"); if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine"); if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte"); if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom"); sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); n = 0; | > > > | | | | | | | > > | 33026 33027 33028 33029 33030 33031 33032 33033 33034 33035 33036 33037 33038 33039 33040 33041 33042 33043 33044 33045 33046 33047 33048 33049 33050 33051 33052 33053 33054 33055 33056 33057 33058 33059 33060 33061 33062 33063 | } if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc"); if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated"); if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized"); if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine"); if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte"); if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom"); if( pItem->fg.fixedSchema ) sqlite3_str_appendf(&x, " fixedSchema"); if( pItem->fg.hadSchema ) sqlite3_str_appendf(&x, " hadSchema"); if( pItem->fg.isSubquery ) sqlite3_str_appendf(&x, " isSubquery"); sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); n = 0; if( pItem->fg.isSubquery ) n++; if( pItem->fg.isTabFunc ) n++; if( pItem->fg.isUsing ) n++; if( pItem->fg.isUsing ){ sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); } if( pItem->fg.isSubquery ){ assert( n==1 ); if( pItem->pSTab ){ Table *pTab = pItem->pSTab; sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); } assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); sqlite3TreeViewPush(&pView, 0); sqlite3TreeViewLine(pView, "SUBQUERY"); sqlite3TreeViewPop(&pView); sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0); } if( pItem->fg.isTabFunc ){ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); } sqlite3TreeViewPop(&pView); } } |
︙ | ︙ | |||
32867 32868 32869 32870 32871 32872 32873 | ); } if( cnt++ ) sqlite3TreeViewPop(&pView); if( p->pPrior ){ n = 1000; }else{ n = 0; | | | 33091 33092 33093 33094 33095 33096 33097 33098 33099 33100 33101 33102 33103 33104 33105 | ); } if( cnt++ ) sqlite3TreeViewPop(&pView); if( p->pPrior ){ n = 1000; }else{ n = 0; if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ) n++; if( p->pWhere ) n++; if( p->pGroupBy ) n++; if( p->pHaving ) n++; if( p->pOrderBy ) n++; if( p->pLimit ) n++; #ifndef SQLITE_OMIT_WINDOWFUNC if( p->pWin ) n++; |
︙ | ︙ | |||
32893 32894 32895 32896 32897 32898 32899 | sqlite3TreeViewLine(pView, "window-functions"); for(pX=p->pWin; pX; pX=pX->pNextWin){ sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0); } sqlite3TreeViewPop(&pView); } #endif | | | 33117 33118 33119 33120 33121 33122 33123 33124 33125 33126 33127 33128 33129 33130 33131 | sqlite3TreeViewLine(pView, "window-functions"); for(pX=p->pWin; pX; pX=pX->pNextWin){ sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0); } sqlite3TreeViewPop(&pView); } #endif if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ){ sqlite3TreeViewPush(&pView, (n--)>0); sqlite3TreeViewLine(pView, "FROM"); sqlite3TreeViewSrcList(pView, p->pSrc); sqlite3TreeViewPop(&pView); } if( p->pWhere ){ sqlite3TreeViewItem(pView, "WHERE", (n--)>0); |
︙ | ︙ | |||
33401 33402 33403 33404 33405 33406 33407 | switch( pExpr->affExpr ){ case OE_Rollback: zType = "rollback"; break; case OE_Abort: zType = "abort"; break; case OE_Fail: zType = "fail"; break; case OE_Ignore: zType = "ignore"; break; } assert( !ExprHasProperty(pExpr, EP_IntValue) ); | | > | 33625 33626 33627 33628 33629 33630 33631 33632 33633 33634 33635 33636 33637 33638 33639 33640 | switch( pExpr->affExpr ){ case OE_Rollback: zType = "rollback"; break; case OE_Abort: zType = "abort"; break; case OE_Fail: zType = "fail"; break; case OE_Ignore: zType = "ignore"; break; } assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3TreeViewLine(pView, "RAISE %s", zType); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } #endif case TK_MATCH: { sqlite3TreeViewLine(pView, "MATCH {%d:%d}%s", pExpr->iTable, pExpr->iColumn, zFlgs); sqlite3TreeViewExpr(pView, pExpr->pRight, 0); |
︙ | ︙ | |||
33481 33482 33483 33484 33485 33486 33487 33488 33489 | if( pList==0 ){ sqlite3TreeViewLine(pView, "%s (empty)", zLabel); }else{ int i; sqlite3TreeViewLine(pView, "%s", zLabel); for(i=0; i<pList->nExpr; i++){ int j = pList->a[i].u.x.iOrderByCol; char *zName = pList->a[i].zEName; int moreToFollow = i<pList->nExpr - 1; | > | | > > > > > | | 33706 33707 33708 33709 33710 33711 33712 33713 33714 33715 33716 33717 33718 33719 33720 33721 33722 33723 33724 33725 33726 33727 33728 33729 33730 33731 33732 33733 33734 33735 33736 33737 33738 33739 33740 33741 33742 33743 33744 33745 33746 33747 33748 33749 33750 33751 33752 33753 33754 33755 | if( pList==0 ){ sqlite3TreeViewLine(pView, "%s (empty)", zLabel); }else{ int i; sqlite3TreeViewLine(pView, "%s", zLabel); for(i=0; i<pList->nExpr; i++){ int j = pList->a[i].u.x.iOrderByCol; u8 sortFlags = pList->a[i].fg.sortFlags; char *zName = pList->a[i].zEName; int moreToFollow = i<pList->nExpr - 1; if( j || zName || sortFlags ){ sqlite3TreeViewPush(&pView, moreToFollow); moreToFollow = 0; sqlite3TreeViewLine(pView, 0); if( zName ){ switch( pList->a[i].fg.eEName ){ default: fprintf(stdout, "AS %s ", zName); break; case ENAME_TAB: fprintf(stdout, "TABLE-ALIAS-NAME(\"%s\") ", zName); if( pList->a[i].fg.bUsed ) fprintf(stdout, "(used) "); if( pList->a[i].fg.bUsingTerm ) fprintf(stdout, "(USING-term) "); if( pList->a[i].fg.bNoExpand ) fprintf(stdout, "(NoExpand) "); break; case ENAME_SPAN: fprintf(stdout, "SPAN(\"%s\") ", zName); break; } } if( j ){ fprintf(stdout, "iOrderByCol=%d ", j); } if( sortFlags & KEYINFO_ORDER_DESC ){ fprintf(stdout, "DESC "); }else if( sortFlags & KEYINFO_ORDER_BIGNULL ){ fprintf(stdout, "NULLS-LAST"); } fprintf(stdout, "\n"); fflush(stdout); } sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); if( j || zName || sortFlags ){ sqlite3TreeViewPop(&pView); } } } } SQLITE_PRIVATE void sqlite3TreeViewExprList( TreeView *pView, |
︙ | ︙ | |||
34851 34852 34853 34854 34855 34856 34857 | assert( (m.flags & MEM_Term)!=0 || db->mallocFailed ); assert( (m.flags & MEM_Str)!=0 || db->mallocFailed ); assert( m.z || db->mallocFailed ); return m.z; } /* | | | > | > | | | 35082 35083 35084 35085 35086 35087 35088 35089 35090 35091 35092 35093 35094 35095 35096 35097 35098 35099 35100 35101 35102 35103 35104 35105 35106 35107 35108 35109 35110 35111 | assert( (m.flags & MEM_Term)!=0 || db->mallocFailed ); assert( (m.flags & MEM_Str)!=0 || db->mallocFailed ); assert( m.z || db->mallocFailed ); return m.z; } /* ** zIn is a UTF-16 encoded unicode string at least nByte bytes long. ** Return the number of bytes in the first nChar unicode characters ** in pZ. nChar must be non-negative. Surrogate pairs count as a single ** character. */ SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nByte, int nChar){ int c; unsigned char const *z = zIn; unsigned char const *zEnd = &z[nByte-1]; int n = 0; if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++; while( n<nChar && ALWAYS(z<=zEnd) ){ c = z[0]; z += 2; if( c>=0xd8 && c<0xdc && z<=zEnd && z[0]>=0xdc && z[0]<0xe0 ) z += 2; n++; } return (int)(z-(unsigned char const *)zIn) - (SQLITE_UTF16NATIVE==SQLITE_UTF16LE); } #if defined(SQLITE_TEST) |
︙ | ︙ | |||
35921 35922 35923 35924 35925 35926 35927 | return x; } /* ** Decode a floating-point value into an approximate decimal ** representation. ** | | > | < | > > > > > | 36154 36155 36156 36157 36158 36159 36160 36161 36162 36163 36164 36165 36166 36167 36168 36169 36170 36171 36172 36173 36174 36175 36176 36177 36178 36179 36180 36181 36182 36183 36184 36185 36186 36187 36188 | return x; } /* ** Decode a floating-point value into an approximate decimal ** representation. ** ** If iRound<=0 then round to -iRound significant digits to the ** the left of the decimal point, or to a maximum of mxRound total ** significant digits. ** ** If iRound>0 round to min(iRound,mxRound) significant digits total. ** ** mxRound must be positive. ** ** The significant digits of the decimal representation are ** stored in p->z[] which is a often (but not always) a pointer ** into the middle of p->zBuf[]. There are p->n significant digits. ** The p->z[] array is *not* zero-terminated. */ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){ int i; u64 v; int e, exp = 0; p->isSpecial = 0; p->z = p->zBuf; assert( mxRound>0 ); /* Convert negative numbers to positive. Deal with Infinity, 0.0, and ** NaN. */ if( r<0.0 ){ p->sign = '-'; r = -r; }else if( r==0.0 ){ |
︙ | ︙ | |||
37224 37225 37226 37227 37228 37229 37230 | /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), /* 45 */ "IdxGE" OpHelp("key=r[P3@P4]"), /* 46 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), /* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), /* 48 */ "Program" OpHelp(""), /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), | > | | | | | | | | | < | 37462 37463 37464 37465 37466 37467 37468 37469 37470 37471 37472 37473 37474 37475 37476 37477 37478 37479 37480 37481 37482 37483 37484 37485 | /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), /* 45 */ "IdxGE" OpHelp("key=r[P3@P4]"), /* 46 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), /* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), /* 48 */ "Program" OpHelp(""), /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), /* 50 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), /* 51 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), /* 52 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), /* 53 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), /* 54 */ "Eq" OpHelp("IF r[P3]==r[P1]"), /* 55 */ "Gt" OpHelp("IF r[P3]>r[P1]"), /* 56 */ "Le" OpHelp("IF r[P3]<=r[P1]"), /* 57 */ "Lt" OpHelp("IF r[P3]<r[P1]"), /* 58 */ "Ge" OpHelp("IF r[P3]>=r[P1]"), /* 59 */ "ElseEq" OpHelp(""), /* 60 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), /* 61 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), /* 62 */ "IncrVacuum" OpHelp(""), /* 63 */ "VNext" OpHelp(""), /* 64 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), |
︙ | ︙ | |||
37276 37277 37278 37279 37280 37281 37282 | /* 95 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), /* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"), /* 97 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), /* 98 */ "Count" OpHelp("r[P2]=count()"), /* 99 */ "ReadCookie" OpHelp(""), /* 100 */ "SetCookie" OpHelp(""), /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), | > | | | | | | | | | | < > | < < | > | 37514 37515 37516 37517 37518 37519 37520 37521 37522 37523 37524 37525 37526 37527 37528 37529 37530 37531 37532 37533 37534 37535 37536 37537 37538 37539 37540 37541 37542 37543 37544 | /* 95 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), /* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"), /* 97 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), /* 98 */ "Count" OpHelp("r[P2]=count()"), /* 99 */ "ReadCookie" OpHelp(""), /* 100 */ "SetCookie" OpHelp(""), /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), /* 102 */ "OpenRead" OpHelp("root=P2 iDb=P3"), /* 103 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), /* 104 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), /* 105 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), /* 106 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), /* 107 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), /* 108 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), /* 109 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), /* 110 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), /* 111 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), /* 112 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), /* 114 */ "OpenDup" OpHelp(""), /* 115 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"), /* 117 */ "OpenEphemeral" OpHelp("nColumn=P2"), /* 118 */ "String8" OpHelp("r[P2]='P4'"), /* 119 */ "SorterOpen" OpHelp(""), /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), /* 122 */ "Close" OpHelp(""), /* 123 */ "ColumnsUsed" OpHelp(""), /* 124 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), /* 125 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), |
︙ | ︙ | |||
37327 37328 37329 37330 37331 37332 37333 | /* 146 */ "ResetSorter" OpHelp(""), /* 147 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), /* 148 */ "SqlExec" OpHelp(""), /* 149 */ "ParseSchema" OpHelp(""), /* 150 */ "LoadAnalysis" OpHelp(""), /* 151 */ "DropTable" OpHelp(""), /* 152 */ "DropIndex" OpHelp(""), | > | < | 37565 37566 37567 37568 37569 37570 37571 37572 37573 37574 37575 37576 37577 37578 37579 37580 | /* 146 */ "ResetSorter" OpHelp(""), /* 147 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), /* 148 */ "SqlExec" OpHelp(""), /* 149 */ "ParseSchema" OpHelp(""), /* 150 */ "LoadAnalysis" OpHelp(""), /* 151 */ "DropTable" OpHelp(""), /* 152 */ "DropIndex" OpHelp(""), /* 153 */ "DropTrigger" OpHelp(""), /* 154 */ "Real" OpHelp("r[P2]=P4"), /* 155 */ "IntegrityCk" OpHelp(""), /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), /* 157 */ "Param" OpHelp(""), /* 158 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), /* 159 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), /* 160 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), /* 161 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), |
︙ | ︙ | |||
38677 38678 38679 38680 38681 38682 38683 | /* ** Allowed values for the unixFile.ctrlFlags bitmask: */ #define UNIXFILE_EXCL 0x01 /* Connections from one process only */ #define UNIXFILE_RDONLY 0x02 /* Connection is read only */ #define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ | | | 38915 38916 38917 38918 38919 38920 38921 38922 38923 38924 38925 38926 38927 38928 38929 | /* ** Allowed values for the unixFile.ctrlFlags bitmask: */ #define UNIXFILE_EXCL 0x01 /* Connections from one process only */ #define UNIXFILE_RDONLY 0x02 /* Connection is read only */ #define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ #if !defined(SQLITE_DISABLE_DIRSYNC) && !defined(_AIX) # define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ #else # define UNIXFILE_DIRSYNC 0x00 #endif #define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ #define UNIXFILE_DELETE 0x20 /* Delete on close */ #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ |
︙ | ︙ | |||
40634 40635 40636 40637 40638 40639 40640 | ** The file suffix added to the data base filename in order to create the ** lock directory. */ #define DOTLOCK_SUFFIX ".lock" /* ** This routine checks if there is a RESERVED lock held on the specified | | | | < < < | < < < | > > | > | < | | 40872 40873 40874 40875 40876 40877 40878 40879 40880 40881 40882 40883 40884 40885 40886 40887 40888 40889 40890 40891 40892 40893 40894 40895 40896 40897 40898 40899 40900 40901 | ** The file suffix added to the data base filename in order to create the ** lock directory. */ #define DOTLOCK_SUFFIX ".lock" /* ** This routine checks if there is a RESERVED lock held on the specified ** file by this or any other process. If the caller holds a SHARED ** or greater lock when it is called, then it is assumed that no other ** client may hold RESERVED. Or, if the caller holds no lock, then it ** is assumed another client holds RESERVED if the lock-file exists. */ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { unixFile *pFile = (unixFile*)id; SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); if( pFile->eFileLock>=SHARED_LOCK ){ *pResOut = 0; }else{ *pResOut = osAccess((const char*)pFile->lockingContext, 0)==0; } OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, 0, *pResOut)); return SQLITE_OK; } /* ** Lock the file with the lock specified by parameter eFileLock - one ** of the following: ** ** (1) SHARED_LOCK |
︙ | ︙ | |||
42342 42343 42344 42345 42346 42347 42348 | }else{ pFile->ctrlFlags |= mask; } } /* Forward declaration */ static int unixGetTempname(int nBuf, char *zBuf); | | | 42576 42577 42578 42579 42580 42581 42582 42583 42584 42585 42586 42587 42588 42589 42590 | }else{ pFile->ctrlFlags |= mask; } } /* Forward declaration */ static int unixGetTempname(int nBuf, char *zBuf); #if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) static int unixFcntlExternalReader(unixFile*, int*); #endif /* ** Information and control of an open file handle. */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ |
︙ | ︙ | |||
42469 42470 42471 42472 42473 42474 42475 | case SQLITE_FCNTL_SET_LOCKPROXYFILE: case SQLITE_FCNTL_GET_LOCKPROXYFILE: { return proxyFileControl(id,op,pArg); } #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ case SQLITE_FCNTL_EXTERNAL_READER: { | | | 42703 42704 42705 42706 42707 42708 42709 42710 42711 42712 42713 42714 42715 42716 42717 | case SQLITE_FCNTL_SET_LOCKPROXYFILE: case SQLITE_FCNTL_GET_LOCKPROXYFILE: { return proxyFileControl(id,op,pArg); } #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ case SQLITE_FCNTL_EXTERNAL_READER: { #if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) return unixFcntlExternalReader((unixFile*)id, (int*)pArg); #else *(int*)pArg = 0; return SQLITE_OK; #endif } } |
︙ | ︙ | |||
42558 42559 42560 42561 42562 42563 42564 | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind ** so it is ordered */ 0; }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){ pFile->sectorSize = fsInfo.f_bsize; pFile->deviceCharacteristics = /* full bitset of atomics from max sector size and smaller */ | | | | 42792 42793 42794 42795 42796 42797 42798 42799 42800 42801 42802 42803 42804 42805 42806 42807 42808 42809 42810 42811 42812 42813 42814 | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind ** so it is ordered */ 0; }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){ pFile->sectorSize = fsInfo.f_bsize; pFile->deviceCharacteristics = /* full bitset of atomics from max sector size and smaller */ (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind ** so it is ordered */ 0; }else if( strstr(fsInfo.f_basetype, "dos") ){ pFile->sectorSize = fsInfo.f_bsize; pFile->deviceCharacteristics = /* full bitset of atomics from max sector size and smaller */ (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind ** so it is ordered */ 0; }else{ pFile->deviceCharacteristics = SQLITE_IOCAP_ATOMIC512 | /* blocks are atomic */ SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until |
︙ | ︙ | |||
42642 42643 42644 42645 42646 42647 42648 | #else return (int)sysconf(_SC_PAGESIZE); #endif } #endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */ | | | 42876 42877 42878 42879 42880 42881 42882 42883 42884 42885 42886 42887 42888 42889 42890 | #else return (int)sysconf(_SC_PAGESIZE); #endif } #endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */ #if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) /* ** Object used to represent an shared memory buffer. ** ** When multiple threads all reference the same wal-index, each thread ** has its own unixShm object, but they all point to a single instance ** of this unixShmNode object. In other words, each wal-index is opened |
︙ | ︙ | |||
54727 54728 54729 54730 54731 54732 54733 54734 54735 54736 54737 54738 54739 54740 | pPgHdr = (PgHdr*)pPage->pExtra; assert( pPgHdr->pPage==0 ); memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty)); pPgHdr->pPage = pPage; pPgHdr->pData = pPage->pBuf; pPgHdr->pExtra = (void *)&pPgHdr[1]; memset(pPgHdr->pExtra, 0, 8); pPgHdr->pCache = pCache; pPgHdr->pgno = pgno; pPgHdr->flags = PGHDR_CLEAN; return sqlite3PcacheFetchFinish(pCache,pgno,pPage); } /* | > | 54961 54962 54963 54964 54965 54966 54967 54968 54969 54970 54971 54972 54973 54974 54975 | pPgHdr = (PgHdr*)pPage->pExtra; assert( pPgHdr->pPage==0 ); memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty)); pPgHdr->pPage = pPage; pPgHdr->pData = pPage->pBuf; pPgHdr->pExtra = (void *)&pPgHdr[1]; memset(pPgHdr->pExtra, 0, 8); assert( EIGHT_BYTE_ALIGNMENT( pPgHdr->pExtra ) ); pPgHdr->pCache = pCache; pPgHdr->pgno = pgno; pPgHdr->flags = PGHDR_CLEAN; return sqlite3PcacheFetchFinish(pCache,pgno,pPage); } /* |
︙ | ︙ | |||
55473 55474 55475 55476 55477 55478 55479 | zBulk = pCache->pBulk = sqlite3Malloc( szBulk ); sqlite3EndBenignMalloc(); if( zBulk ){ int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc; do{ PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; pX->page.pBuf = zBulk; | | > | 55708 55709 55710 55711 55712 55713 55714 55715 55716 55717 55718 55719 55720 55721 55722 55723 | zBulk = pCache->pBulk = sqlite3Malloc( szBulk ); sqlite3EndBenignMalloc(); if( zBulk ){ int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc; do{ PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; pX->page.pBuf = zBulk; pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX)); assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) ); pX->isBulkLocal = 1; pX->isAnchor = 0; pX->pNext = pCache->pFree; pX->pLruPrev = 0; /* Initializing this saves a valgrind error */ pCache->pFree = pX; zBulk += pCache->szAlloc; }while( --nBulk ); |
︙ | ︙ | |||
55610 55611 55612 55613 55614 55615 55616 | if( benignMalloc ){ sqlite3EndBenignMalloc(); } #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT pcache1EnterMutex(pCache->pGroup); #endif if( pPg==0 ) return 0; p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; p->page.pBuf = pPg; | | > | 55846 55847 55848 55849 55850 55851 55852 55853 55854 55855 55856 55857 55858 55859 55860 55861 | if( benignMalloc ){ sqlite3EndBenignMalloc(); } #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT pcache1EnterMutex(pCache->pGroup); #endif if( pPg==0 ) return 0; p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; p->page.pBuf = pPg; p->page.pExtra = (u8*)p + ROUND8(sizeof(*p)); assert( EIGHT_BYTE_ALIGNMENT( p->page.pExtra ) ); p->isBulkLocal = 0; p->isAnchor = 0; p->pLruPrev = 0; /* Initializing this saves a valgrind error */ } (*pCache->pnPurgeable)++; return p; } |
︙ | ︙ | |||
61169 61170 61171 61172 61173 61174 61175 61176 61177 61178 61179 61180 61181 61182 | }else{ *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra); if( p==0 ){ sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData); return SQLITE_NOMEM_BKPT; } p->pExtra = (void *)&p[1]; p->flags = PGHDR_MMAP; p->nRef = 1; p->pPager = pPager; } assert( p->pExtra==(void *)&p[1] ); assert( p->pPage==0 ); | > | 61406 61407 61408 61409 61410 61411 61412 61413 61414 61415 61416 61417 61418 61419 61420 | }else{ *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra); if( p==0 ){ sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData); return SQLITE_NOMEM_BKPT; } p->pExtra = (void *)&p[1]; assert( EIGHT_BYTE_ALIGNMENT( p->pExtra ) ); p->flags = PGHDR_MMAP; p->nRef = 1; p->pPager = pPager; } assert( p->pExtra==(void *)&p[1] ); assert( p->pPage==0 ); |
︙ | ︙ | |||
64952 64953 64954 64955 64956 64957 64958 | ** 12: Checkpoint sequence number ** 16: Salt-1, random integer incremented with each checkpoint ** 20: Salt-2, a different random integer changing with each ckpt ** 24: Checksum-1 (first part of checksum for first 24 bytes of header). ** 28: Checksum-2 (second part of checksum for first 24 bytes of header). ** ** Immediately following the wal-header are zero or more frames. Each | | | 65190 65191 65192 65193 65194 65195 65196 65197 65198 65199 65200 65201 65202 65203 65204 | ** 12: Checkpoint sequence number ** 16: Salt-1, random integer incremented with each checkpoint ** 20: Salt-2, a different random integer changing with each ckpt ** 24: Checksum-1 (first part of checksum for first 24 bytes of header). ** 28: Checksum-2 (second part of checksum for first 24 bytes of header). ** ** Immediately following the wal-header are zero or more frames. Each ** frame consists of a 24-byte frame-header followed by <page-size> bytes ** of page data. The frame-header is six big-endian 32-bit unsigned ** integer values, as follows: ** ** 0: Page number. ** 4: For commit records, the size of the database image in pages ** after the commit. For all other records, zero. ** 8: Salt-1 (copied from the header) |
︙ | ︙ | |||
76529 76530 76531 76532 76533 76534 76535 | *pRes = c; return SQLITE_OK; /* Cursor already pointing at the correct spot */ } if( pCur->iPage>0 && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 && pIdxKey->errCode==SQLITE_OK ){ | | | 76767 76768 76769 76770 76771 76772 76773 76774 76775 76776 76777 76778 76779 76780 76781 | *pRes = c; return SQLITE_OK; /* Cursor already pointing at the correct spot */ } if( pCur->iPage>0 && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 && pIdxKey->errCode==SQLITE_OK ){ pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast); if( !pCur->pPage->isInit ){ return SQLITE_CORRUPT_BKPT; } goto bypass_moveto_root; /* Start search on the current page */ } pIdxKey->errCode = SQLITE_OK; } |
︙ | ︙ | |||
78107 78108 78109 78110 78111 78112 78113 | assert( nCell>0 ); assert( i<iEnd ); j = get2byte(&aData[hdr+5]); if( j>(u32)usableSize ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); | > | | 78345 78346 78347 78348 78349 78350 78351 78352 78353 78354 78355 78356 78357 78358 78359 78360 | assert( nCell>0 ); assert( i<iEnd ); j = get2byte(&aData[hdr+5]); if( j>(u32)usableSize ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); assert( pCArray->ixNx[NB*2-1]>i ); for(k=0; pCArray->ixNx[k]<=i; k++){} pSrcEnd = pCArray->apEnd[k]; pData = pEnd; while( 1/*exit by break*/ ){ u8 *pCell = pCArray->apCell[i]; u16 sz = pCArray->szCell[i]; assert( sz>0 ); |
︙ | ︙ | |||
78190 78191 78192 78193 78194 78195 78196 | u8 *aData = pPg->aData; /* Complete page */ u8 *pData = *ppData; /* Content area. A subset of aData[] */ int iEnd = iFirst + nCell; /* End of loop. One past last cell to ins */ int k; /* Current slot in pCArray->apEnd[] */ u8 *pEnd; /* Maximum extent of cell data */ assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ if( iEnd<=iFirst ) return 0; | > | | 78429 78430 78431 78432 78433 78434 78435 78436 78437 78438 78439 78440 78441 78442 78443 78444 | u8 *aData = pPg->aData; /* Complete page */ u8 *pData = *ppData; /* Content area. A subset of aData[] */ int iEnd = iFirst + nCell; /* End of loop. One past last cell to ins */ int k; /* Current slot in pCArray->apEnd[] */ u8 *pEnd; /* Maximum extent of cell data */ assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ if( iEnd<=iFirst ) return 0; assert( pCArray->ixNx[NB*2-1]>i ); for(k=0; pCArray->ixNx[k]<=i ; k++){} pEnd = pCArray->apEnd[k]; while( 1 /*Exit by break*/ ){ int sz, rc; u8 *pSlot; assert( pCArray->szCell[i]!=0 ); sz = pCArray->szCell[i]; if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){ |
︙ | ︙ | |||
78475 78476 78477 78478 78479 78480 78481 78482 78483 78484 78485 78486 78487 78488 | zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF); b.nCell = 1; b.pRef = pPage; b.apCell = &pCell; b.szCell = &szCell; b.apEnd[0] = pPage->aDataEnd; b.ixNx[0] = 2; rc = rebuildPage(&b, 0, 1, pNew); if( NEVER(rc) ){ releasePage(pNew); return rc; } pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell; | > | 78715 78716 78717 78718 78719 78720 78721 78722 78723 78724 78725 78726 78727 78728 78729 | zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF); b.nCell = 1; b.pRef = pPage; b.apCell = &pCell; b.szCell = &szCell; b.apEnd[0] = pPage->aDataEnd; b.ixNx[0] = 2; b.ixNx[NB*2-1] = 0x7fffffff; rc = rebuildPage(&b, 0, 1, pNew); if( NEVER(rc) ){ releasePage(pNew); return rc; } pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell; |
︙ | ︙ | |||
78710 78711 78712 78713 78714 78715 78716 | u8 *aSpace1; /* Space for copies of dividers cells */ Pgno pgno; /* Temp var to store a page number in */ u8 abDone[NB+2]; /* True after i'th new page is populated */ Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */ CellArray b; /* Parsed information on cells being balanced */ memset(abDone, 0, sizeof(abDone)); | > | > | 78951 78952 78953 78954 78955 78956 78957 78958 78959 78960 78961 78962 78963 78964 78965 78966 78967 | u8 *aSpace1; /* Space for copies of dividers cells */ Pgno pgno; /* Temp var to store a page number in */ u8 abDone[NB+2]; /* True after i'th new page is populated */ Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */ CellArray b; /* Parsed information on cells being balanced */ memset(abDone, 0, sizeof(abDone)); assert( sizeof(b) - sizeof(b.ixNx) == offsetof(CellArray,ixNx) ); memset(&b, 0, sizeof(b)-sizeof(b.ixNx[0])); b.ixNx[NB*2-1] = 0x7fffffff; pBt = pParent->pBt; assert( sqlite3_mutex_held(pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); /* At this point pParent may have at most one overflow cell. And if ** this overflow cell is present, it must be the cell with ** index iParentIdx. This scenario comes about when this function |
︙ | ︙ | |||
79301 79302 79303 79304 79305 79306 79307 | assert(leafCorrection==4); sz = pParent->xCellSize(pParent, pCell); } } iOvflSpace += sz; assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); | > | | 79544 79545 79546 79547 79548 79549 79550 79551 79552 79553 79554 79555 79556 79557 79558 79559 | assert(leafCorrection==4); sz = pParent->xCellSize(pParent, pCell); } } iOvflSpace += sz; assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); assert( b.ixNx[NB*2-1]>j ); for(k=0; b.ixNx[k]<=j; k++){} pSrcEnd = b.apEnd[k]; if( SQLITE_OVERFLOW(pSrcEnd, pCell, pCell+sz) ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } rc = insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno); if( rc!=SQLITE_OK ) goto balance_cleanup; |
︙ | ︙ | |||
84313 84314 84315 84316 84317 84318 84319 | if( pList ){ apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal); if( apVal==0 ){ rc = SQLITE_NOMEM_BKPT; goto value_from_function_out; } for(i=0; i<nVal; i++){ | | > | 84557 84558 84559 84560 84561 84562 84563 84564 84565 84566 84567 84568 84569 84570 84571 84572 | if( pList ){ apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal); if( apVal==0 ){ rc = SQLITE_NOMEM_BKPT; goto value_from_function_out; } for(i=0; i<nVal; i++){ rc = sqlite3Stat4ValueFromExpr(pCtx->pParse, pList->a[i].pExpr, aff, &apVal[i]); if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out; } } pVal = valueNew(db, pCtx); if( pVal==0 ){ rc = SQLITE_NOMEM_BKPT; |
︙ | ︙ | |||
86247 86248 86249 86250 86251 86252 86253 86254 86255 86256 86257 86258 86259 86260 | if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); break; } case P4_TABLEREF: { if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4); break; } } } /* ** Free the space allocated for aOp and any p4 values allocated for the ** opcodes contained within. If aOp is not NULL it is assumed to contain ** nOp entries. | > > > > > > | 86492 86493 86494 86495 86496 86497 86498 86499 86500 86501 86502 86503 86504 86505 86506 86507 86508 86509 86510 86511 | if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); break; } case P4_TABLEREF: { if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4); break; } case P4_SUBRTNSIG: { SubrtnSig *pSig = (SubrtnSig*)p4; sqlite3DbFree(db, pSig->zAff); sqlite3DbFree(db, pSig); break; } } } /* ** Free the space allocated for aOp and any p4 values allocated for the ** opcodes contained within. If aOp is not NULL it is assumed to contain ** nOp entries. |
︙ | ︙ | |||
86825 86826 86827 86828 86829 86830 86831 86832 86833 86834 86835 86836 86837 86838 | case P4_SUBPROGRAM: { zP4 = "program"; break; } case P4_TABLE: { zP4 = pOp->p4.pTab->zName; break; } default: { zP4 = pOp->p4.z; } } if( zP4 ) sqlite3_str_appendall(&x, zP4); if( (x.accError & SQLITE_NOMEM)!=0 ){ | > > > > > | 87076 87077 87078 87079 87080 87081 87082 87083 87084 87085 87086 87087 87088 87089 87090 87091 87092 87093 87094 | case P4_SUBPROGRAM: { zP4 = "program"; break; } case P4_TABLE: { zP4 = pOp->p4.pTab->zName; break; } case P4_SUBRTNSIG: { SubrtnSig *pSig = pOp->p4.pSubrtnSig; sqlite3_str_appendf(&x, "subrtnsig:%d,%s", pSig->selId, pSig->zAff); break; } default: { zP4 = pOp->p4.z; } } if( zP4 ) sqlite3_str_appendall(&x, zP4); if( (x.accError & SQLITE_NOMEM)!=0 ){ |
︙ | ︙ | |||
90170 90171 90172 90173 90174 90175 90176 | ** ** The returned value must be freed by the caller using sqlite3ValueFree(). */ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){ assert( iVar>0 ); if( v ){ Mem *pMem = &v->aVar[iVar-1]; | | > | > | 90426 90427 90428 90429 90430 90431 90432 90433 90434 90435 90436 90437 90438 90439 90440 90441 90442 90443 90444 90445 90446 90447 90448 90449 90450 90451 90452 90453 90454 90455 90456 90457 90458 90459 90460 90461 90462 | ** ** The returned value must be freed by the caller using sqlite3ValueFree(). */ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){ assert( iVar>0 ); if( v ){ Mem *pMem = &v->aVar[iVar-1]; assert( (v->db->flags & SQLITE_EnableQPSG)==0 || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 ); if( 0==(pMem->flags & MEM_Null) ){ sqlite3_value *pRet = sqlite3ValueNew(v->db); if( pRet ){ sqlite3VdbeMemCopy((Mem *)pRet, pMem); sqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8); } return pRet; } } return 0; } /* ** Configure SQL variable iVar so that binding a new value to it signals ** to sqlite3_reoptimize() that re-preparing the statement may result ** in a better query plan. */ SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ assert( iVar>0 ); assert( (v->db->flags & SQLITE_EnableQPSG)==0 || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 ); if( iVar>=32 ){ v->expmask |= 0x80000000; }else{ v->expmask |= ((u32)1 << (iVar-1)); } } |
︙ | ︙ | |||
90364 90365 90366 90367 90368 90369 90370 90371 90372 90373 90374 90375 90376 90377 | if( preupdate.aNew ){ int i; for(i=0; i<pCsr->nField; i++){ sqlite3VdbeMemRelease(&preupdate.aNew[i]); } sqlite3DbNNFreeNN(db, preupdate.aNew); } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ /************** End of vdbeaux.c *********************************************/ /************** Begin file vdbeapi.c *****************************************/ /* ** 2004 May 26 | > > > > > > > | 90622 90623 90624 90625 90626 90627 90628 90629 90630 90631 90632 90633 90634 90635 90636 90637 90638 90639 90640 90641 90642 | if( preupdate.aNew ){ int i; for(i=0; i<pCsr->nField; i++){ sqlite3VdbeMemRelease(&preupdate.aNew[i]); } sqlite3DbNNFreeNN(db, preupdate.aNew); } if( preupdate.apDflt ){ int i; for(i=0; i<pTab->nCol; i++){ sqlite3ValueFree(preupdate.apDflt[i]); } sqlite3DbFree(db, preupdate.apDflt); } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ /************** End of vdbeaux.c *********************************************/ /************** Begin file vdbeapi.c *****************************************/ /* ** 2004 May 26 |
︙ | ︙ | |||
91992 91993 91994 91995 91996 91997 91998 91999 92000 92001 92002 92003 92004 92005 | ** out of range, then SQLITE_RANGE is returned. Otherwise SQLITE_OK. ** ** A successful evaluation of this routine acquires the mutex on p. ** the mutex is released if any kind of error occurs. ** ** The error code stored in database p->db is overwritten with the return ** value in any case. */ static int vdbeUnbind(Vdbe *p, unsigned int i){ Mem *pVar; if( vdbeSafetyNotNull(p) ){ return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(p->db->mutex); | > > > > > > > > > > > | 92257 92258 92259 92260 92261 92262 92263 92264 92265 92266 92267 92268 92269 92270 92271 92272 92273 92274 92275 92276 92277 92278 92279 92280 92281 | ** out of range, then SQLITE_RANGE is returned. Otherwise SQLITE_OK. ** ** A successful evaluation of this routine acquires the mutex on p. ** the mutex is released if any kind of error occurs. ** ** The error code stored in database p->db is overwritten with the return ** value in any case. ** ** (tag-20240917-01) If vdbeUnbind(p,(u32)(i-1)) returns SQLITE_OK, ** that means all of the the following will be true: ** ** p!=0 ** p->pVar!=0 ** i>0 ** i<=p->nVar ** ** An assert() is normally added after vdbeUnbind() to help static analyzers ** realize this. */ static int vdbeUnbind(Vdbe *p, unsigned int i){ Mem *pVar; if( vdbeSafetyNotNull(p) ){ return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(p->db->mutex); |
︙ | ︙ | |||
92049 92050 92051 92052 92053 92054 92055 92056 92057 92058 92059 92060 92061 92062 | ){ Vdbe *p = (Vdbe *)pStmt; Mem *pVar; int rc; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ if( zData!=0 ){ pVar = &p->aVar[i-1]; rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); if( rc==SQLITE_OK && encoding!=0 ){ rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); } if( rc ){ | > | 92325 92326 92327 92328 92329 92330 92331 92332 92333 92334 92335 92336 92337 92338 92339 | ){ Vdbe *p = (Vdbe *)pStmt; Mem *pVar; int rc; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ if( zData!=0 ){ pVar = &p->aVar[i-1]; rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); if( rc==SQLITE_OK && encoding!=0 ){ rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); } if( rc ){ |
︙ | ︙ | |||
92098 92099 92100 92101 92102 92103 92104 92105 92106 92107 92108 92109 92110 92111 92112 92113 92114 92115 92116 92117 92118 92119 92120 92121 92122 92123 92124 92125 92126 92127 92128 92129 92130 92131 92132 92133 92134 92135 92136 92137 92138 92139 92140 92141 92142 92143 92144 92145 92146 92147 92148 92149 | return bindText(pStmt, i, zData, nData, xDel, 0); } SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ int rc; Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); sqlite3_mutex_leave(p->db->mutex); } return rc; } SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){ return sqlite3_bind_int64(p, i, (i64)iValue); } SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ int rc; Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); sqlite3_mutex_leave(p->db->mutex); } return rc; } SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ int rc; Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ sqlite3_mutex_leave(p->db->mutex); } return rc; } SQLITE_API int sqlite3_bind_pointer( sqlite3_stmt *pStmt, int i, void *pPtr, const char *zPTtype, void (*xDestructor)(void*) ){ int rc; Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); sqlite3_mutex_leave(p->db->mutex); }else if( xDestructor ){ xDestructor(pPtr); } return rc; } | > > > > | 92375 92376 92377 92378 92379 92380 92381 92382 92383 92384 92385 92386 92387 92388 92389 92390 92391 92392 92393 92394 92395 92396 92397 92398 92399 92400 92401 92402 92403 92404 92405 92406 92407 92408 92409 92410 92411 92412 92413 92414 92415 92416 92417 92418 92419 92420 92421 92422 92423 92424 92425 92426 92427 92428 92429 92430 | return bindText(pStmt, i, zData, nData, xDel, 0); } SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ int rc; Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); sqlite3_mutex_leave(p->db->mutex); } return rc; } SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){ return sqlite3_bind_int64(p, i, (i64)iValue); } SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ int rc; Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); sqlite3_mutex_leave(p->db->mutex); } return rc; } SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ int rc; Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3_mutex_leave(p->db->mutex); } return rc; } SQLITE_API int sqlite3_bind_pointer( sqlite3_stmt *pStmt, int i, void *pPtr, const char *zPTtype, void (*xDestructor)(void*) ){ int rc; Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); sqlite3_mutex_leave(p->db->mutex); }else if( xDestructor ){ xDestructor(pPtr); } return rc; } |
︙ | ︙ | |||
92217 92218 92219 92220 92221 92222 92223 92224 92225 92226 92227 92228 92229 92230 | return rc; } SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ int rc; Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ #ifndef SQLITE_OMIT_INCRBLOB sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); #else rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); #endif sqlite3_mutex_leave(p->db->mutex); } | > | 92498 92499 92500 92501 92502 92503 92504 92505 92506 92507 92508 92509 92510 92511 92512 | return rc; } SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ int rc; Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ #ifndef SQLITE_OMIT_INCRBLOB sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); #else rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); #endif sqlite3_mutex_leave(p->db->mutex); } |
︙ | ︙ | |||
92576 92577 92578 92579 92580 92581 92582 | p->aRecord = aRec; } pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; if( iIdx==p->pTab->iPKey ){ sqlite3VdbeMemSetInt64(pMem, p->iKey1); }else if( iIdx>=p->pUnpacked->nField ){ | > > > > > > > > > > > > > > > > > > > > > > | > | 92858 92859 92860 92861 92862 92863 92864 92865 92866 92867 92868 92869 92870 92871 92872 92873 92874 92875 92876 92877 92878 92879 92880 92881 92882 92883 92884 92885 92886 92887 92888 92889 92890 92891 92892 92893 92894 92895 | p->aRecord = aRec; } pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; if( iIdx==p->pTab->iPKey ){ sqlite3VdbeMemSetInt64(pMem, p->iKey1); }else if( iIdx>=p->pUnpacked->nField ){ /* This occurs when the table has been extended using ALTER TABLE ** ADD COLUMN. The value to return is the default value of the column. */ Column *pCol = &p->pTab->aCol[iIdx]; if( pCol->iDflt>0 ){ if( p->apDflt==0 ){ int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); if( p->apDflt==0 ) goto preupdate_old_out; } if( p->apDflt[iIdx]==0 ){ sqlite3_value *pVal = 0; Expr *pDflt; assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); if( rc==SQLITE_OK && pVal==0 ){ rc = SQLITE_CORRUPT_BKPT; } p->apDflt[iIdx] = pVal; } *ppValue = p->apDflt[iIdx]; }else{ *ppValue = (sqlite3_value *)columnNullValue(); } }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ if( pMem->flags & (MEM_Int|MEM_IntReal) ){ testcase( pMem->flags & MEM_Int ); testcase( pMem->flags & MEM_IntReal ); sqlite3VdbeMemRealify(pMem); } } |
︙ | ︙ | |||
94322 94323 94324 94325 94326 94327 94328 | if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } #endif if( (pIn3->flags & MEM_Null)==0 ) break; /* Fall through into OP_Halt */ /* no break */ deliberate_fall_through } | | > | > > > | > < | | > > > | 94627 94628 94629 94630 94631 94632 94633 94634 94635 94636 94637 94638 94639 94640 94641 94642 94643 94644 94645 94646 94647 94648 94649 94650 94651 94652 94653 94654 94655 94656 94657 94658 94659 94660 94661 94662 94663 94664 94665 94666 94667 94668 94669 94670 94671 94672 94673 94674 94675 94676 94677 94678 94679 94680 94681 94682 94683 94684 | if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } #endif if( (pIn3->flags & MEM_Null)==0 ) break; /* Fall through into OP_Halt */ /* no break */ deliberate_fall_through } /* Opcode: Halt P1 P2 P3 P4 P5 ** ** Exit immediately. All open cursors, etc are closed ** automatically. ** ** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(), ** or sqlite3_finalize(). For a normal halt, this should be SQLITE_OK (0). ** For errors, it can be some other value. If P1!=0 then P2 will determine ** whether or not to rollback the current transaction. Do not rollback ** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort, ** then back out all changes that have occurred during this execution of the ** VDBE, but do not rollback the transaction. ** ** If P3 is not zero and P4 is NULL, then P3 is a register that holds the ** text of an error message. ** ** If P3 is zero and P4 is not null then the error message string is held ** in P4. ** ** P5 is a value between 1 and 4, inclusive, then the P4 error message ** string is modified as follows: ** ** 1: NOT NULL constraint failed: P4 ** 2: UNIQUE constraint failed: P4 ** 3: CHECK constraint failed: P4 ** 4: FOREIGN KEY constraint failed: P4 ** ** If P3 is zero and P5 is not zero and P4 is NULL, then everything after ** the ":" is omitted. ** ** There is an implied "Halt 0 0 0" instruction inserted at the very end of ** every program. So a jump past the last instruction of the program ** is the same as executing Halt. */ case OP_Halt: { VdbeFrame *pFrame; int pcx; #ifdef SQLITE_DEBUG if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } #endif assert( pOp->p4type==P4_NOTUSED || pOp->p4type==P4_STATIC || pOp->p4type==P4_DYNAMIC ); /* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates ** something is wrong with the code generator. Raise an assertion in order ** to bring this to the attention of fuzzers and other testing tools. */ assert( pOp->p1!=SQLITE_INTERNAL ); if( p->pFrame && pOp->p1==SQLITE_OK ){ |
︙ | ︙ | |||
94389 94390 94391 94392 94393 94394 94395 | pOp = &aOp[pcx]; break; } p->rc = pOp->p1; p->errorAction = (u8)pOp->p2; assert( pOp->p5<=4 ); if( p->rc ){ | > > > > > | | 94701 94702 94703 94704 94705 94706 94707 94708 94709 94710 94711 94712 94713 94714 94715 94716 94717 94718 94719 94720 | pOp = &aOp[pcx]; break; } p->rc = pOp->p1; p->errorAction = (u8)pOp->p2; assert( pOp->p5<=4 ); if( p->rc ){ if( pOp->p3>0 && pOp->p4type==P4_NOTUSED ){ const char *zErr; assert( pOp->p3<=(p->nMem + 1 - p->nCursor) ); zErr = sqlite3ValueText(&aMem[pOp->p3], SQLITE_UTF8); sqlite3VdbeError(p, "%s", zErr); }else if( pOp->p5 ){ static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", "FOREIGN KEY" }; testcase( pOp->p5==1 ); testcase( pOp->p5==2 ); testcase( pOp->p5==3 ); testcase( pOp->p5==4 ); sqlite3VdbeError(p, "%s constraint failed", azType[pOp->p5-1]); |
︙ | ︙ | |||
95192 95193 95194 95195 95196 95197 95198 | sqlite3VdbeMemRealify(pIn1); REGISTER_TRACE(pOp->p1, pIn1); } break; } #endif | | | 95509 95510 95511 95512 95513 95514 95515 95516 95517 95518 95519 95520 95521 95522 95523 | sqlite3VdbeMemRealify(pIn1); REGISTER_TRACE(pOp->p1, pIn1); } break; } #endif #if !defined(SQLITE_OMIT_CAST) || !defined(SQLITE_OMIT_ANALYZE) /* Opcode: Cast P1 P2 * * * ** Synopsis: affinity(r[P1]) ** ** Force the value in register P1 to be the type defined by P2. ** ** <ul> ** <li> P2=='A' → BLOB |
︙ | ︙ | |||
97432 97433 97434 97435 97436 97437 97438 | if( pOp->opcode==OP_OpenWrite ){ assert( OPFLAG_FORDELETE==BTREE_FORDELETE ); wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE); assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( pDb->pSchema->file_format < p->minWriteFileFormat ){ p->minWriteFileFormat = pDb->pSchema->file_format; } | < < < | | | < | | | | | | | | | | > > > > | 97749 97750 97751 97752 97753 97754 97755 97756 97757 97758 97759 97760 97761 97762 97763 97764 97765 97766 97767 97768 97769 97770 97771 97772 97773 97774 97775 97776 97777 97778 97779 | if( pOp->opcode==OP_OpenWrite ){ assert( OPFLAG_FORDELETE==BTREE_FORDELETE ); wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE); assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( pDb->pSchema->file_format < p->minWriteFileFormat ){ p->minWriteFileFormat = pDb->pSchema->file_format; } if( pOp->p5 & OPFLAG_P2ISREG ){ assert( p2>0 ); assert( p2<=(u32)(p->nMem+1 - p->nCursor) ); pIn2 = &aMem[p2]; assert( memIsValid(pIn2) ); assert( (pIn2->flags & MEM_Int)!=0 ); sqlite3VdbeMemIntegerify(pIn2); p2 = (int)pIn2->u.i; /* The p2 value always comes from a prior OP_CreateBtree opcode and ** that opcode will always set the p2 value to 2 or more or else fail. ** If there were a failure, the prepared statement would have halted ** before reaching this instruction. */ assert( p2>=2 ); } }else{ wrFlag = 0; assert( (pOp->p5 & OPFLAG_P2ISREG)==0 ); } if( pOp->p4type==P4_KEYINFO ){ pKeyInfo = pOp->p4.pKeyInfo; assert( pKeyInfo->enc==ENC(db) ); assert( pKeyInfo->db==db ); nField = pKeyInfo->nAllField; }else if( pOp->p4type==P4_INT32 ){ |
︙ | ︙ | |||
98404 98405 98406 98407 98408 98409 98410 98411 98412 98413 98414 98415 98416 98417 | assert( pC->isTable==0 ); r.nField = (u16)pOp->p4.i; if( r.nField>0 ){ /* Key values in an array of registers */ r.pKeyInfo = pC->pKeyInfo; r.default_rc = 0; #ifdef SQLITE_DEBUG for(ii=0; ii<r.nField; ii++){ assert( memIsValid(&r.aMem[ii]) ); assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 ); if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]); } #endif rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &pC->seekResult); | > | 98721 98722 98723 98724 98725 98726 98727 98728 98729 98730 98731 98732 98733 98734 98735 | assert( pC->isTable==0 ); r.nField = (u16)pOp->p4.i; if( r.nField>0 ){ /* Key values in an array of registers */ r.pKeyInfo = pC->pKeyInfo; r.default_rc = 0; #ifdef SQLITE_DEBUG (void)sqlite3FaultSim(50); /* For use by --counter in TH3 */ for(ii=0; ii<r.nField; ii++){ assert( memIsValid(&r.aMem[ii]) ); assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 ); if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]); } #endif rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &pC->seekResult); |
︙ | ︙ | |||
100766 100767 100768 100769 100770 100771 100772 100773 100774 100775 100776 100777 100778 | ** sqlite3_context only happens once, instead of on each call to the ** step function. */ case OP_AggInverse: case OP_AggStep: { int n; sqlite3_context *pCtx; assert( pOp->p4type==P4_FUNCDEF ); n = pOp->p5; assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); | > > > > > > > > > > | < < | > > > | 101084 101085 101086 101087 101088 101089 101090 101091 101092 101093 101094 101095 101096 101097 101098 101099 101100 101101 101102 101103 101104 101105 101106 101107 101108 101109 101110 101111 101112 101113 101114 101115 101116 101117 101118 101119 101120 | ** sqlite3_context only happens once, instead of on each call to the ** step function. */ case OP_AggInverse: case OP_AggStep: { int n; sqlite3_context *pCtx; u64 nAlloc; assert( pOp->p4type==P4_FUNCDEF ); n = pOp->p5; assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); /* Allocate space for (a) the context object and (n-1) extra pointers ** to append to the sqlite3_context.argv[1] array, and (b) a memory ** cell in which to store the accumulation. Be careful that the memory ** cell is 8-byte aligned, even on platforms where a pointer is 32-bits. ** ** Note: We could avoid this by using a regular memory cell from aMem[] for ** the accumulator, instead of allocating one here. */ nAlloc = ROUND8P( sizeof(pCtx[0]) + (n-1)*sizeof(sqlite3_value*) ); pCtx = sqlite3DbMallocRawNN(db, nAlloc + sizeof(Mem)); if( pCtx==0 ) goto no_mem; pCtx->pOut = (Mem*)((u8*)pCtx + nAlloc); assert( EIGHT_BYTE_ALIGNMENT(pCtx->pOut) ); sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); pCtx->pMem = 0; pCtx->pFunc = pOp->p4.pFunc; pCtx->iOp = (int)(pOp - aOp); pCtx->pVdbe = p; pCtx->skipFlag = 0; pCtx->isError = 0; pCtx->enc = encoding; pCtx->argc = n; |
︙ | ︙ | |||
102111 102112 102113 102114 102115 102116 102117 | } break; } #endif /* Opcode: Noop * * * * * ** | | < > | | > | > > > > > > > > > > > > > > | | | 102440 102441 102442 102443 102444 102445 102446 102447 102448 102449 102450 102451 102452 102453 102454 102455 102456 102457 102458 102459 102460 102461 102462 102463 102464 102465 102466 102467 102468 102469 102470 102471 102472 102473 102474 102475 102476 | } break; } #endif /* Opcode: Noop * * * * * ** ** Do nothing. Continue downward to the next opcode. */ /* Opcode: Explain P1 P2 P3 P4 * ** ** This is the same as OP_Noop during normal query execution. The ** purpose of this opcode is to hold information about the query ** plan for the purpose of EXPLAIN QUERY PLAN output. ** ** The P4 value is human-readable text that describes the query plan ** element. Something like "SCAN t1" or "SEARCH t2 USING INDEX t2x1". ** ** The P1 value is the ID of the current element and P2 is the parent ** element for the case of nested query plan elements. If P2 is zero ** then this element is a top-level element. ** ** For loop elements, P3 is the estimated code of each invocation of this ** element. ** ** As with all opcodes, the meanings of the parameters for OP_Explain ** are subject to change from one release to the next. Applications ** should not attempt to interpret or use any of the information ** contined in the OP_Explain opcode. The information provided by this ** opcode is intended for testing and debugging use only. */ default: { /* This is really OP_Noop, OP_Explain */ assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain ); break; } |
︙ | ︙ | |||
102444 102445 102446 102447 102448 102449 102450 102451 102452 102453 102454 102455 102456 102457 | if( pTab && IsVirtual(pTab) ){ pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable); } if( pTab && !HasRowid(pTab) ){ pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); } #ifndef SQLITE_OMIT_VIEW if( pTab && IsView(pTab) ){ pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); } #endif | > > > > > | 102788 102789 102790 102791 102792 102793 102794 102795 102796 102797 102798 102799 102800 102801 102802 102803 102804 102805 102806 | if( pTab && IsVirtual(pTab) ){ pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable); } if( pTab && !HasRowid(pTab) ){ pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); } if( pTab && (pTab->tabFlags&TF_HasGenerated)!=0 ){ pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open table with generated columns: %s", zTable); } #ifndef SQLITE_OMIT_VIEW if( pTab && IsView(pTab) ){ pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); } #endif |
︙ | ︙ | |||
103352 103353 103354 103355 103356 103357 103358 | nRem = nByte - nAvail; /* The following loop copies up to p->nBuffer bytes per iteration into ** the p->aAlloc[] buffer. */ while( nRem>0 ){ int rc; /* vdbePmaReadBlob() return code */ int nCopy; /* Number of bytes to copy */ | | > | 103701 103702 103703 103704 103705 103706 103707 103708 103709 103710 103711 103712 103713 103714 103715 103716 103717 103718 103719 103720 103721 103722 | nRem = nByte - nAvail; /* The following loop copies up to p->nBuffer bytes per iteration into ** the p->aAlloc[] buffer. */ while( nRem>0 ){ int rc; /* vdbePmaReadBlob() return code */ int nCopy; /* Number of bytes to copy */ u8 *aNext = 0; /* Pointer to buffer to copy data from */ nCopy = nRem; if( nRem>p->nBuffer ) nCopy = p->nBuffer; rc = vdbePmaReadBlob(p, nCopy, &aNext); if( rc!=SQLITE_OK ) return rc; assert( aNext!=p->aAlloc ); assert( aNext!=0 ); memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); nRem -= nCopy; } *ppOut = p->aAlloc; } |
︙ | ︙ | |||
106628 106629 106630 106631 106632 106633 106634 | SrcList *pSrc; int i; SrcItem *pItem; pSrc = p->pSrc; if( ALWAYS(pSrc) ){ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ | > | > | 106978 106979 106980 106981 106982 106983 106984 106985 106986 106987 106988 106989 106990 106991 106992 106993 106994 | SrcList *pSrc; int i; SrcItem *pItem; pSrc = p->pSrc; if( ALWAYS(pSrc) ){ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ if( pItem->fg.isSubquery && sqlite3WalkSelect(pWalker, pItem->u4.pSubq->pSelect) ){ return WRC_Abort; } if( pItem->fg.isTabFunc && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) ){ return WRC_Abort; } |
︙ | ︙ | |||
106934 106935 106936 106937 106938 106939 106940 | SrcItem *pMatch, /* Source table containing the column */ i16 iColumn /* The column number */ ){ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0); if( pNew ){ pNew->iTable = pMatch->iCursor; pNew->iColumn = iColumn; | | | | | 107286 107287 107288 107289 107290 107291 107292 107293 107294 107295 107296 107297 107298 107299 107300 107301 107302 107303 107304 107305 107306 107307 107308 107309 107310 107311 107312 107313 107314 107315 107316 107317 107318 107319 107320 107321 107322 107323 107324 | SrcItem *pMatch, /* Source table containing the column */ i16 iColumn /* The column number */ ){ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0); if( pNew ){ pNew->iTable = pMatch->iCursor; pNew->iColumn = iColumn; pNew->y.pTab = pMatch->pSTab; assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ); ExprSetProperty(pNew, EP_CanBeNull); *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew); } } /* ** Return TRUE (non-zero) if zTab is a valid name for the schema table pTab. */ static SQLITE_NOINLINE int isValidSchemaTableName( const char *zTab, /* Name as it appears in the SQL */ Table *pTab, /* The schema table we are trying to match */ const char *zDb /* non-NULL if a database qualifier is present */ ){ const char *zLegacy; assert( pTab!=0 ); assert( pTab->tnum==1 ); if( sqlite3StrNICmp(zTab, "sqlite_", 7)!=0 ) return 0; zLegacy = pTab->zName; if( strcmp(zLegacy+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){ if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ return 1; } if( zDb==0 ) return 0; if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1; if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; }else{ if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; } return 0; } |
︙ | ︙ | |||
107065 107066 107067 107068 107069 107070 107071 | do{ ExprList *pEList; SrcList *pSrcList = pNC->pSrcList; if( pSrcList ){ for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){ u8 hCol; | | | > > | > > | | 107417 107418 107419 107420 107421 107422 107423 107424 107425 107426 107427 107428 107429 107430 107431 107432 107433 107434 107435 107436 107437 107438 107439 107440 107441 107442 107443 107444 107445 107446 107447 107448 | do{ ExprList *pEList; SrcList *pSrcList = pNC->pSrcList; if( pSrcList ){ for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){ u8 hCol; pTab = pItem->pSTab; assert( pTab!=0 && pTab->zName!=0 ); assert( pTab->nCol>0 || pParse->nErr ); assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem)); if( pItem->fg.isNestedFrom ){ /* In this case, pItem is a subquery that has been formed from a ** parenthesized subset of the FROM clause terms. Example: ** .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ... ** \_________________________/ ** This pItem -------------^ */ int hit = 0; Select *pSel; assert( pItem->fg.isSubquery ); assert( pItem->u4.pSubq!=0 ); pSel = pItem->u4.pSubq->pSelect; assert( pSel!=0 ); pEList = pSel->pEList; assert( pEList!=0 ); assert( pEList->nExpr==pTab->nCol ); for(j=0; j<pEList->nExpr; j++){ int bRowid = 0; /* True if possible rowid match */ if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, &bRowid) ){ continue; } |
︙ | ︙ | |||
107141 107142 107143 107144 107145 107146 107147 | } if( pItem->zAlias!=0 ){ if( sqlite3StrICmp(zTab, pItem->zAlias)!=0 ){ continue; } }else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){ if( pTab->tnum!=1 ) continue; | | | 107497 107498 107499 107500 107501 107502 107503 107504 107505 107506 107507 107508 107509 107510 107511 | } if( pItem->zAlias!=0 ){ if( sqlite3StrICmp(zTab, pItem->zAlias)!=0 ){ continue; } }else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){ if( pTab->tnum!=1 ) continue; if( !isValidSchemaTableName(zTab, pTab, zDb) ) continue; } assert( ExprUseYTab(pExpr) ); if( IN_RENAME_OBJECT && pItem->zAlias ){ sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); } } hCol = sqlite3StrIHash(zCol); |
︙ | ︙ | |||
107201 107202 107203 107204 107205 107206 107207 | /* In SQLITE_ALLOW_ROWID_IN_VIEW mode, allow a ROWID match ** if there is a single VIEW candidate or if there is a single ** non-VIEW candidate plus multiple VIEW candidates. In other ** words non-VIEW candidate terms take precedence over VIEWs. */ if( cntTab==0 || (cntTab==1 | | | | | | 107557 107558 107559 107560 107561 107562 107563 107564 107565 107566 107567 107568 107569 107570 107571 107572 107573 107574 107575 107576 107577 107578 107579 107580 107581 107582 107583 107584 107585 107586 107587 107588 107589 107590 107591 107592 107593 107594 | /* In SQLITE_ALLOW_ROWID_IN_VIEW mode, allow a ROWID match ** if there is a single VIEW candidate or if there is a single ** non-VIEW candidate plus multiple VIEW candidates. In other ** words non-VIEW candidate terms take precedence over VIEWs. */ if( cntTab==0 || (cntTab==1 && pMatch!=0 && ALWAYS(pMatch->pSTab!=0) && (pMatch->pSTab->tabFlags & TF_Ephemeral)!=0 && (pTab->tabFlags & TF_Ephemeral)==0) ){ cntTab = 1; pMatch = pItem; }else{ cntTab++; } #else /* The (much more common) non-SQLITE_ALLOW_ROWID_IN_VIEW case is ** simpler since we require exactly one candidate, which will ** always be a non-VIEW */ cntTab++; pMatch = pItem; #endif } } if( pMatch ){ pExpr->iTable = pMatch->iCursor; assert( ExprUseYTab(pExpr) ); pExpr->y.pTab = pMatch->pSTab; if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){ ExprSetProperty(pExpr, EP_CanBeNull); } pSchema = pExpr->y.pTab->pSchema; } } /* if( pSrcList ) */ |
︙ | ︙ | |||
107266 107267 107268 107269 107270 107271 107272 | } } #endif /* SQLITE_OMIT_TRIGGER */ #ifndef SQLITE_OMIT_UPSERT if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){ Upsert *pUpsert = pNC->uNC.pUpsert; if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ | | | 107622 107623 107624 107625 107626 107627 107628 107629 107630 107631 107632 107633 107634 107635 107636 | } } #endif /* SQLITE_OMIT_TRIGGER */ #ifndef SQLITE_OMIT_UPSERT if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){ Upsert *pUpsert = pNC->uNC.pUpsert; if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ pTab = pUpsert->pUpsertSrc->a[0].pSTab; pExpr->iTable = EXCLUDED_TABLE_NUMBER; } } #endif /* SQLITE_OMIT_UPSERT */ if( pTab ){ int iCol; |
︙ | ︙ | |||
107349 107350 107351 107352 107353 107354 107355 | ** Perhaps the name is a reference to the ROWID */ if( cnt==0 && cntTab>=1 && pMatch && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 && sqlite3IsRowid(zCol) | | | | 107705 107706 107707 107708 107709 107710 107711 107712 107713 107714 107715 107716 107717 107718 107719 107720 107721 107722 107723 | ** Perhaps the name is a reference to the ROWID */ if( cnt==0 && cntTab>=1 && pMatch && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 && sqlite3IsRowid(zCol) && ALWAYS(VisibleRowid(pMatch->pSTab) || pMatch->fg.isNestedFrom) ){ cnt = cntTab; #if SQLITE_ALLOW_ROWID_IN_VIEW+0==2 if( pMatch->pSTab!=0 && IsView(pMatch->pSTab) ){ eNewExprOp = TK_NULL; } #endif if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1; pExpr->affExpr = SQLITE_AFF_INTEGER; } |
︙ | ︙ | |||
107590 107591 107592 107593 107594 107595 107596 | */ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); if( p ){ SrcItem *pItem = &pSrc->a[iSrc]; Table *pTab; assert( ExprUseYTab(p) ); | | | 107946 107947 107948 107949 107950 107951 107952 107953 107954 107955 107956 107957 107958 107959 107960 | */ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); if( p ){ SrcItem *pItem = &pSrc->a[iSrc]; Table *pTab; assert( ExprUseYTab(p) ); pTab = p->y.pTab = pItem->pSTab; p->iTable = pItem->iCursor; if( p->y.pTab->iPKey==iCol ){ p->iColumn = -1; }else{ p->iColumn = (ynVar)iCol; if( (pTab->tabFlags & TF_HasGenerated)!=0 && (pTab->aCol[iCol].colFlags & COLFLAG_GENERATED)!=0 |
︙ | ︙ | |||
107709 107710 107711 107712 107713 107714 107715 | case TK_ROW: { SrcList *pSrcList = pNC->pSrcList; SrcItem *pItem; assert( pSrcList && pSrcList->nSrc>=1 ); pItem = pSrcList->a; pExpr->op = TK_COLUMN; assert( ExprUseYTab(pExpr) ); | | | 108065 108066 108067 108068 108069 108070 108071 108072 108073 108074 108075 108076 108077 108078 108079 | case TK_ROW: { SrcList *pSrcList = pNC->pSrcList; SrcItem *pItem; assert( pSrcList && pSrcList->nSrc>=1 ); pItem = pSrcList->a; pExpr->op = TK_COLUMN; assert( ExprUseYTab(pExpr) ); pExpr->y.pTab = pItem->pSTab; pExpr->iTable = pItem->iCursor; pExpr->iColumn--; pExpr->affExpr = SQLITE_AFF_INTEGER; break; } /* An optimization: Attempt to convert |
︙ | ︙ | |||
107834 107835 107836 107837 107838 107839 107840 | } return lookupName(pParse, zDb, zTable, pRight, pNC, pExpr); } /* Resolve function names */ case TK_FUNCTION: { | | | > > | 108190 108191 108192 108193 108194 108195 108196 108197 108198 108199 108200 108201 108202 108203 108204 108205 108206 108207 108208 108209 108210 108211 108212 108213 108214 108215 108216 108217 108218 108219 | } return lookupName(pParse, zDb, zTable, pRight, pNC, pExpr); } /* Resolve function names */ case TK_FUNCTION: { ExprList *pList; /* The argument list */ int n; /* Number of arguments */ int no_such_func = 0; /* True if no such function exists */ int wrong_num_args = 0; /* True if wrong number of arguments */ int is_agg = 0; /* True if is an aggregate function */ const char *zId; /* The function name. */ FuncDef *pDef; /* Information about the function */ u8 enc = ENC(pParse->db); /* The database encoding */ int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin)); #ifndef SQLITE_OMIT_WINDOWFUNC Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0); #endif assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER ); pList = pExpr->x.pList; n = pList ? pList->nExpr : 0; zId = pExpr->u.zToken; pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); if( pDef==0 ){ pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0); if( pDef==0 ){ no_such_func = 1; }else{ |
︙ | ︙ | |||
108015 108016 108017 108018 108019 108020 108021 | if( is_agg ){ if( pExpr->pLeft ){ assert( pExpr->pLeft->op==TK_ORDER ); assert( ExprUseXList(pExpr->pLeft) ); sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList); } #ifndef SQLITE_OMIT_WINDOWFUNC | | | | 108373 108374 108375 108376 108377 108378 108379 108380 108381 108382 108383 108384 108385 108386 108387 108388 108389 | if( is_agg ){ if( pExpr->pLeft ){ assert( pExpr->pLeft->op==TK_ORDER ); assert( ExprUseXList(pExpr->pLeft) ); sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList); } #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin && pParse->nErr==0 ){ Select *pSel = pNC->pWinSelect; assert( ExprUseYWin(pExpr) && pWin==pExpr->y.pWin ); if( IN_RENAME_OBJECT==0 ){ sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); if( pParse->db->mallocFailed ) break; } sqlite3WalkExprList(pWalker, pWin->pPartition); sqlite3WalkExprList(pWalker, pWin->pOrderBy); sqlite3WalkExpr(pWalker, pWin->pFilter); |
︙ | ︙ | |||
108224 108225 108226 108227 108228 108229 108230 | int i; /* Loop counter */ ExprList *pEList; /* The columns of the result set */ NameContext nc; /* Name context for resolving pE */ sqlite3 *db; /* Database connection */ int rc; /* Return code from subprocedures */ u8 savedSuppErr; /* Saved value of db->suppressErr */ | | | 108582 108583 108584 108585 108586 108587 108588 108589 108590 108591 108592 108593 108594 108595 108596 | int i; /* Loop counter */ ExprList *pEList; /* The columns of the result set */ NameContext nc; /* Name context for resolving pE */ sqlite3 *db; /* Database connection */ int rc; /* Return code from subprocedures */ u8 savedSuppErr; /* Saved value of db->suppressErr */ assert( sqlite3ExprIsInteger(pE, &i, 0)==0 ); pEList = pSelect->pEList; /* Resolve all names in the ORDER BY term expression */ memset(&nc, 0, sizeof(nc)); nc.pParse = pParse; nc.pSrcList = pSelect->pSrc; |
︙ | ︙ | |||
108323 108324 108325 108326 108327 108328 108329 | assert( pEList!=0 ); for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ int iCol = -1; Expr *pE, *pDup; if( pItem->fg.done ) continue; pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); if( NEVER(pE==0) ) continue; | | | 108681 108682 108683 108684 108685 108686 108687 108688 108689 108690 108691 108692 108693 108694 108695 | assert( pEList!=0 ); for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ int iCol = -1; Expr *pE, *pDup; if( pItem->fg.done ) continue; pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); if( NEVER(pE==0) ) continue; if( sqlite3ExprIsInteger(pE, &iCol, 0) ){ if( iCol<=0 || iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE); return 1; } }else{ iCol = resolveAsName(pParse, pEList, pE); if( iCol==0 ){ |
︙ | ︙ | |||
108508 108509 108510 108511 108512 108513 108514 | ** a copy of the iCol-th result-set column. The subsequent call to ** sqlite3ResolveOrderGroupBy() will convert the expression to a ** copy of the iCol-th result-set expression. */ pItem->u.x.iOrderByCol = (u16)iCol; continue; } } | | | 108866 108867 108868 108869 108870 108871 108872 108873 108874 108875 108876 108877 108878 108879 108880 | ** a copy of the iCol-th result-set column. The subsequent call to ** sqlite3ResolveOrderGroupBy() will convert the expression to a ** copy of the iCol-th result-set expression. */ pItem->u.x.iOrderByCol = (u16)iCol; continue; } } if( sqlite3ExprIsInteger(pE2, &iCol, 0) ){ /* The ORDER BY term is an integer constant. Again, set the column ** number so that sqlite3ResolveOrderGroupBy() will convert the ** order-by term to a copy of the result-set expression */ if( iCol<1 || iCol>0xffff ){ resolveOutOfRangeError(pParse, zType, i+1, nResult, pE2); return 1; } |
︙ | ︙ | |||
108599 108600 108601 108602 108603 108604 108605 | /* If the SF_Converted flags is set, then this Select object was ** was created by the convertCompoundSelectToSubquery() function. ** In this case the ORDER BY clause (p->pOrderBy) should be resolved ** as if it were part of the sub-query, not the parent. This block ** moves the pOrderBy down to the sub-query. It will be moved back ** after the names have been resolved. */ if( p->selFlags & SF_Converted ){ | | > > > > | > > | > | | 108957 108958 108959 108960 108961 108962 108963 108964 108965 108966 108967 108968 108969 108970 108971 108972 108973 108974 108975 108976 108977 108978 108979 108980 108981 108982 108983 108984 108985 108986 108987 108988 108989 108990 108991 108992 108993 108994 108995 108996 | /* If the SF_Converted flags is set, then this Select object was ** was created by the convertCompoundSelectToSubquery() function. ** In this case the ORDER BY clause (p->pOrderBy) should be resolved ** as if it were part of the sub-query, not the parent. This block ** moves the pOrderBy down to the sub-query. It will be moved back ** after the names have been resolved. */ if( p->selFlags & SF_Converted ){ Select *pSub; assert( p->pSrc->a[0].fg.isSubquery ); assert( p->pSrc->a[0].u4.pSubq!=0 ); pSub = p->pSrc->a[0].u4.pSubq->pSelect; assert( pSub!=0 ); assert( p->pSrc->nSrc==1 && p->pOrderBy ); assert( pSub->pPrior && pSub->pOrderBy==0 ); pSub->pOrderBy = p->pOrderBy; p->pOrderBy = 0; } /* Recursively resolve names in all subqueries in the FROM clause */ if( pOuterNC ) pOuterNC->nNestedSelect++; for(i=0; i<p->pSrc->nSrc; i++){ SrcItem *pItem = &p->pSrc->a[i]; assert( pItem->zName!=0 || pItem->fg.isSubquery ); /* Test of tag-20240424-1*/ if( pItem->fg.isSubquery && (pItem->u4.pSubq->pSelect->selFlags & SF_Resolved)==0 ){ int nRef = pOuterNC ? pOuterNC->nRef : 0; const char *zSavedContext = pParse->zAuthContext; if( pItem->zName ) pParse->zAuthContext = pItem->zName; sqlite3ResolveSelectNames(pParse, pItem->u4.pSubq->pSelect, pOuterNC); pParse->zAuthContext = zSavedContext; if( pParse->nErr ) return WRC_Abort; assert( db->mallocFailed==0 ); /* If the number of references to the outer context changed when ** expressions in the sub-select were resolved, the sub-select ** is correlated. It is not required to check the refcount on any |
︙ | ︙ | |||
108719 108720 108721 108722 108723 108724 108725 | /* If this is a converted compound query, move the ORDER BY clause from ** the sub-query back to the parent query. At this point each term ** within the ORDER BY clause has been transformed to an integer value. ** These integers will be replaced by copies of the corresponding result ** set expressions by the call to resolveOrderGroupBy() below. */ if( p->selFlags & SF_Converted ){ | | > > > | 109084 109085 109086 109087 109088 109089 109090 109091 109092 109093 109094 109095 109096 109097 109098 109099 109100 109101 | /* If this is a converted compound query, move the ORDER BY clause from ** the sub-query back to the parent query. At this point each term ** within the ORDER BY clause has been transformed to an integer value. ** These integers will be replaced by copies of the corresponding result ** set expressions by the call to resolveOrderGroupBy() below. */ if( p->selFlags & SF_Converted ){ Select *pSub; assert( p->pSrc->a[0].fg.isSubquery ); pSub = p->pSrc->a[0].u4.pSubq->pSelect; assert( pSub!=0 ); p->pOrderBy = pSub->pOrderBy; pSub->pOrderBy = 0; } /* Process the ORDER BY clause for singleton SELECT statements. ** The ORDER BY clause for compounds SELECT statements is handled ** below, after all of the result-sets for all of the elements of |
︙ | ︙ | |||
108873 108874 108875 108876 108877 108878 108879 108880 108881 108882 108883 108884 108885 108886 108887 | return pNC->nNcErr>0 || w.pParse->nErr>0; } /* ** Resolve all names for all expression in an expression list. This is ** just like sqlite3ResolveExprNames() except that it works for an expression ** list rather than a single expression. */ SQLITE_PRIVATE int sqlite3ResolveExprListNames( NameContext *pNC, /* Namespace to resolve expressions in. */ ExprList *pList /* The expression list to be analyzed. */ ){ int i; int savedHasAgg = 0; Walker w; | > > > | | | | | 109241 109242 109243 109244 109245 109246 109247 109248 109249 109250 109251 109252 109253 109254 109255 109256 109257 109258 109259 109260 109261 109262 109263 109264 109265 109266 109267 109268 109269 109270 109271 109272 109273 109274 109275 109276 109277 109278 109279 109280 109281 109282 109283 109284 109285 109286 109287 109288 109289 109290 109291 109292 109293 109294 109295 109296 109297 109298 109299 109300 | return pNC->nNcErr>0 || w.pParse->nErr>0; } /* ** Resolve all names for all expression in an expression list. This is ** just like sqlite3ResolveExprNames() except that it works for an expression ** list rather than a single expression. ** ** The return value is SQLITE_OK (0) for success or SQLITE_ERROR (1) for a ** failure. */ SQLITE_PRIVATE int sqlite3ResolveExprListNames( NameContext *pNC, /* Namespace to resolve expressions in. */ ExprList *pList /* The expression list to be analyzed. */ ){ int i; int savedHasAgg = 0; Walker w; if( pList==0 ) return SQLITE_OK; w.pParse = pNC->pParse; w.xExprCallback = resolveExprStep; w.xSelectCallback = resolveSelectStep; w.xSelectCallback2 = 0; w.u.pNC = pNC; savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); for(i=0; i<pList->nExpr; i++){ Expr *pExpr = pList->a[i].pExpr; if( pExpr==0 ) continue; #if SQLITE_MAX_EXPR_DEPTH>0 w.pParse->nHeight += pExpr->nHeight; if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ return SQLITE_ERROR; } #endif sqlite3WalkExprNN(&w, pExpr); #if SQLITE_MAX_EXPR_DEPTH>0 w.pParse->nHeight -= pExpr->nHeight; #endif assert( EP_Agg==NC_HasAgg ); assert( EP_Win==NC_HasWin ); testcase( pNC->ncFlags & NC_HasAgg ); testcase( pNC->ncFlags & NC_HasWin ); if( pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg) ){ ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) ); savedHasAgg |= pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); } if( w.pParse->nErr>0 ) return SQLITE_ERROR; } pNC->ncFlags |= savedHasAgg; return SQLITE_OK; } /* ** Resolve all names in all expressions of a SELECT and in all ** descendants of the SELECT, including compounds off of p->pPrior, ** subqueries in expressions, and subqueries used as FROM clause ** terms. |
︙ | ︙ | |||
108983 108984 108985 108986 108987 108988 108989 | assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || type==NC_GenCol || pTab==0 ); memset(&sNC, 0, sizeof(sNC)); memset(&sSrc, 0, sizeof(sSrc)); if( pTab ){ sSrc.nSrc = 1; sSrc.a[0].zName = pTab->zName; | | | 109354 109355 109356 109357 109358 109359 109360 109361 109362 109363 109364 109365 109366 109367 109368 | assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || type==NC_GenCol || pTab==0 ); memset(&sNC, 0, sizeof(sNC)); memset(&sSrc, 0, sizeof(sSrc)); if( pTab ){ sSrc.nSrc = 1; sSrc.a[0].zName = pTab->zName; sSrc.a[0].pSTab = pTab; sSrc.a[0].iCursor = -1; if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP ** schema elements */ type |= NC_FromDDL; } } |
︙ | ︙ | |||
109088 109089 109090 109091 109092 109093 109094 | assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) ); pExpr = pExpr->pLeft; op = pExpr->op; continue; } | | > > | 109459 109460 109461 109462 109463 109464 109465 109466 109467 109468 109469 109470 109471 109472 109473 109474 109475 | assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) ); pExpr = pExpr->pLeft; op = pExpr->op; continue; } if( op!=TK_REGISTER ) break; op = pExpr->op2; if( NEVER( op==TK_REGISTER ) ) break; } return pExpr->affExpr; } /* ** Make a guess at all the possible datatypes of the result that could ** be returned by an expression. Return a bitmask indicating the answer: |
︙ | ︙ | |||
110878 110879 110880 110881 110882 110883 110884 | pNew = sqlite3DbMallocRawNN(db, nByte ); if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; i<p->nSrc; i++){ SrcItem *pNewItem = &pNew->a[i]; const SrcItem *pOldItem = &p->a[i]; Table *pTab; | > > > > > > > > > > > > > > > > > | > | > < < < < | < | 111251 111252 111253 111254 111255 111256 111257 111258 111259 111260 111261 111262 111263 111264 111265 111266 111267 111268 111269 111270 111271 111272 111273 111274 111275 111276 111277 111278 111279 111280 111281 111282 111283 111284 111285 111286 111287 111288 111289 111290 111291 111292 111293 111294 111295 111296 111297 111298 111299 111300 111301 111302 111303 111304 | pNew = sqlite3DbMallocRawNN(db, nByte ); if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; i<p->nSrc; i++){ SrcItem *pNewItem = &pNew->a[i]; const SrcItem *pOldItem = &p->a[i]; Table *pTab; pNewItem->fg = pOldItem->fg; if( pOldItem->fg.isSubquery ){ Subquery *pNewSubq = sqlite3DbMallocRaw(db, sizeof(Subquery)); if( pNewSubq==0 ){ assert( db->mallocFailed ); pNewItem->fg.isSubquery = 0; }else{ memcpy(pNewSubq, pOldItem->u4.pSubq, sizeof(*pNewSubq)); pNewSubq->pSelect = sqlite3SelectDup(db, pNewSubq->pSelect, flags); if( pNewSubq->pSelect==0 ){ sqlite3DbFree(db, pNewSubq); pNewSubq = 0; pNewItem->fg.isSubquery = 0; } } pNewItem->u4.pSubq = pNewSubq; }else if( pOldItem->fg.fixedSchema ){ pNewItem->u4.pSchema = pOldItem->u4.pSchema; }else{ pNewItem->u4.zDatabase = sqlite3DbStrDup(db, pOldItem->u4.zDatabase); } pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); pNewItem->iCursor = pOldItem->iCursor; if( pNewItem->fg.isIndexedBy ){ pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); }else if( pNewItem->fg.isTabFunc ){ pNewItem->u1.pFuncArg = sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); }else{ pNewItem->u1.nRow = pOldItem->u1.nRow; } pNewItem->u2 = pOldItem->u2; if( pNewItem->fg.isCte ){ pNewItem->u2.pCteUse->nUse++; } pTab = pNewItem->pSTab = pOldItem->pSTab; if( pTab ){ pTab->nTabRef++; } if( pOldItem->fg.isUsing ){ assert( pNewItem->fg.isUsing ); pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing); }else{ pNewItem->u3.pOn = sqlite3ExprDup(db, pOldItem->u3.pOn, flags); } pNewItem->colUsed = pOldItem->colUsed; |
︙ | ︙ | |||
110977 110978 110979 110980 110981 110982 110983 | sqlite3SelectDelete(db, pNew); break; } *pp = pNew; pp = &pNew->pPrior; pNext = pNew; } | < | 111364 111365 111366 111367 111368 111369 111370 111371 111372 111373 111374 111375 111376 111377 | sqlite3SelectDelete(db, pNew); break; } *pp = pNew; pp = &pNew->pPrior; pNext = pNew; } return pRet; } #else SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){ assert( p==0 ); return 0; } |
︙ | ︙ | |||
111792 111793 111794 111795 111796 111797 111798 111799 | #endif /* ** If the expression p codes a constant integer that is small enough ** to fit in a 32-bit integer, return 1 and put the value of the integer ** in *pValue. If the expression is not an integer or if it is too big ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. */ | > > > > | | | > > > > > > > > > > > > > > > > > > > > | 112178 112179 112180 112181 112182 112183 112184 112185 112186 112187 112188 112189 112190 112191 112192 112193 112194 112195 112196 112197 112198 112199 112200 112201 112202 112203 112204 112205 112206 112207 112208 112209 112210 112211 112212 112213 112214 112215 112216 112217 112218 112219 112220 112221 112222 112223 112224 112225 112226 112227 112228 112229 112230 112231 112232 112233 112234 112235 112236 112237 112238 112239 112240 112241 112242 | #endif /* ** If the expression p codes a constant integer that is small enough ** to fit in a 32-bit integer, return 1 and put the value of the integer ** in *pValue. If the expression is not an integer or if it is too big ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. ** ** If the pParse pointer is provided, then allow the expression p to be ** a parameter (TK_VARIABLE) that is bound to an integer. ** But if pParse is NULL, then p must be a pure integer literal. */ SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue, Parse *pParse){ int rc = 0; if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */ /* If an expression is an integer literal that fits in a signed 32-bit ** integer, then the EP_IntValue flag will have already been set */ assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0 || sqlite3GetInt32(p->u.zToken, &rc)==0 ); if( p->flags & EP_IntValue ){ *pValue = p->u.iValue; return 1; } switch( p->op ){ case TK_UPLUS: { rc = sqlite3ExprIsInteger(p->pLeft, pValue, 0); break; } case TK_UMINUS: { int v = 0; if( sqlite3ExprIsInteger(p->pLeft, &v, 0) ){ assert( ((unsigned int)v)!=0x80000000 ); *pValue = -v; rc = 1; } break; } case TK_VARIABLE: { sqlite3_value *pVal; if( pParse==0 ) break; if( NEVER(pParse->pVdbe==0) ) break; if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) break; sqlite3VdbeSetVarmask(pParse->pVdbe, p->iColumn); pVal = sqlite3VdbeGetBoundValue(pParse->pReprepare, p->iColumn, SQLITE_AFF_BLOB); if( pVal ){ if( sqlite3_value_type(pVal)==SQLITE_INTEGER ){ sqlite3_int64 vv = sqlite3_value_int64(pVal); if( vv == (vv & 0x7fffffff) ){ /* non-negative numbers only */ *pValue = (int)vv; rc = 1; } } sqlite3ValueFree(pVal); } break; } default: break; } return rc; } /* |
︙ | ︙ | |||
111973 111974 111975 111976 111977 111978 111979 | } assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */ if( p->pLimit ) return 0; /* Has no LIMIT clause */ if( p->pWhere ) return 0; /* Has no WHERE clause */ pSrc = p->pSrc; assert( pSrc!=0 ); if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */ | | | | 112383 112384 112385 112386 112387 112388 112389 112390 112391 112392 112393 112394 112395 112396 112397 112398 | } assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */ if( p->pLimit ) return 0; /* Has no LIMIT clause */ if( p->pWhere ) return 0; /* Has no WHERE clause */ pSrc = p->pSrc; assert( pSrc!=0 ); if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */ if( pSrc->a[0].fg.isSubquery) return 0;/* FROM is not a subquery or view */ pTab = pSrc->a[0].pSTab; assert( pTab!=0 ); assert( !IsView(pTab) ); /* FROM clause is not a view */ if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ pEList = p->pEList; assert( pEList!=0 ); /* All SELECT results must be columns. */ for(i=0; i<pEList->nExpr; i++){ |
︙ | ︙ | |||
112157 112158 112159 112160 112161 112162 112163 | int iDb; /* Database idx for pTab */ ExprList *pEList = p->pEList; int nExpr = pEList->nExpr; assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */ | | | 112567 112568 112569 112570 112571 112572 112573 112574 112575 112576 112577 112578 112579 112580 112581 | int iDb; /* Database idx for pTab */ ExprList *pEList = p->pEList; int nExpr = pEList->nExpr; assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */ pTab = p->pSrc->a[0].pSTab; /* Code an OP_Transaction and OP_TableLock for <table>. */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 && iDb<SQLITE_MAX_DB ); sqlite3CodeVerifySchema(pParse, iDb); sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); |
︙ | ︙ | |||
112397 112398 112399 112400 112401 112402 112403 112404 112405 112406 112407 112408 112409 112410 | }else #endif { sqlite3ErrorMsg(pParse, "row value misused"); } } #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code that will construct an ephemeral table containing all terms ** in the RHS of an IN operator. The IN operator can be in either of two ** forms: ** ** x IN (4,5,11) -- IN operator with list on right-hand side | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 112807 112808 112809 112810 112811 112812 112813 112814 112815 112816 112817 112818 112819 112820 112821 112822 112823 112824 112825 112826 112827 112828 112829 112830 112831 112832 112833 112834 112835 112836 112837 112838 112839 112840 112841 112842 112843 112844 112845 112846 112847 112848 112849 112850 112851 112852 112853 112854 112855 112856 112857 112858 112859 112860 112861 112862 112863 | }else #endif { sqlite3ErrorMsg(pParse, "row value misused"); } } #ifndef SQLITE_OMIT_SUBQUERY /* ** Scan all previously generated bytecode looking for an OP_BeginSubrtn ** that is compatible with pExpr. If found, add the y.sub values ** to pExpr and return true. If not found, return false. */ static int findCompatibleInRhsSubrtn( Parse *pParse, /* Parsing context */ Expr *pExpr, /* IN operator with RHS that we want to reuse */ SubrtnSig *pNewSig /* Signature for the IN operator */ ){ VdbeOp *pOp, *pEnd; SubrtnSig *pSig; Vdbe *v; if( pNewSig==0 ) return 0; if( (pParse->mSubrtnSig & (1<<(pNewSig->selId&7)))==0 ) return 0; assert( pExpr->op==TK_IN ); assert( !ExprUseYSub(pExpr) ); assert( ExprUseXSelect(pExpr) ); assert( pExpr->x.pSelect!=0 ); assert( (pExpr->x.pSelect->selFlags & SF_All)==0 ); v = pParse->pVdbe; assert( v!=0 ); pOp = sqlite3VdbeGetOp(v, 1); pEnd = sqlite3VdbeGetLastOp(v); for(; pOp<pEnd; pOp++){ if( pOp->p4type!=P4_SUBRTNSIG ) continue; assert( pOp->opcode==OP_BeginSubrtn ); pSig = pOp->p4.pSubrtnSig; assert( pSig!=0 ); if( pNewSig->selId!=pSig->selId ) continue; if( strcmp(pNewSig->zAff,pSig->zAff)!=0 ) continue; pExpr->y.sub.iAddr = pSig->iAddr; pExpr->y.sub.regReturn = pSig->regReturn; pExpr->iTable = pSig->iTable; ExprSetProperty(pExpr, EP_Subrtn); return 1; } return 0; } #endif /* SQLITE_OMIT_SUBQUERY */ #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code that will construct an ephemeral table containing all terms ** in the RHS of an IN operator. The IN operator can be in either of two ** forms: ** ** x IN (4,5,11) -- IN operator with list on right-hand side |
︙ | ︙ | |||
112446 112447 112448 112449 112450 112451 112452 | ** * The right-hand side is an expression list containing variables ** * We are inside a trigger ** ** If all of the above are false, then we can compute the RHS just once ** and reuse it many names. */ if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ | | | > > > > > > > > > > > > | > > > | > > > > > > > > > > > > | | 112899 112900 112901 112902 112903 112904 112905 112906 112907 112908 112909 112910 112911 112912 112913 112914 112915 112916 112917 112918 112919 112920 112921 112922 112923 112924 112925 112926 112927 112928 112929 112930 112931 112932 112933 112934 112935 112936 112937 112938 112939 112940 112941 112942 112943 112944 112945 112946 112947 112948 112949 112950 112951 112952 112953 112954 112955 112956 112957 112958 112959 112960 112961 112962 112963 112964 112965 112966 | ** * The right-hand side is an expression list containing variables ** * We are inside a trigger ** ** If all of the above are false, then we can compute the RHS just once ** and reuse it many names. */ if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ /* Reuse of the RHS is allowed ** ** Compute a signature for the RHS of the IN operator to facility ** finding and reusing prior instances of the same IN operator. */ SubrtnSig *pSig = 0; assert( !ExprUseXSelect(pExpr) || pExpr->x.pSelect!=0 ); if( ExprUseXSelect(pExpr) && (pExpr->x.pSelect->selFlags & SF_All)==0 ){ pSig = sqlite3DbMallocRawNN(pParse->db, sizeof(pSig[0])); if( pSig ){ pSig->selId = pExpr->x.pSelect->selId; pSig->zAff = exprINAffinity(pParse, pExpr); } } /* Check to see if there is a prior materialization of the RHS of ** this IN operator. If there is, then make use of that prior ** materialization rather than recomputing it. */ if( ExprHasProperty(pExpr, EP_Subrtn) || findCompatibleInRhsSubrtn(pParse, pExpr, pSig) ){ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); if( ExprUseXSelect(pExpr) ){ ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d", pExpr->x.pSelect->selId)); } assert( ExprUseYSub(pExpr) ); sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); assert( iTab!=pExpr->iTable ); sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); sqlite3VdbeJumpHere(v, addrOnce); if( pSig ){ sqlite3DbFree(pParse->db, pSig->zAff); sqlite3DbFree(pParse->db, pSig); } return; } /* Begin coding the subroutine */ assert( !ExprUseYWin(pExpr) ); ExprSetProperty(pExpr, EP_Subrtn); assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; if( pSig ){ pSig->iAddr = pExpr->y.sub.iAddr; pSig->regReturn = pExpr->y.sub.regReturn; pSig->iTable = iTab; pParse->mSubrtnSig = 1 << (pSig->selId&7); sqlite3VdbeChangeP4(v, -1, (const char*)pSig, P4_SUBRTNSIG); } addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } /* Check to see if this is a vector IN operator */ pLeft = pExpr->pLeft; nVal = sqlite3ExprVectorSize(pLeft); |
︙ | ︙ | |||
112513 112514 112515 112516 112517 112518 112519 112520 112521 112522 112523 112524 112525 112526 112527 112528 112529 112530 112531 112532 112533 112534 112535 | /* If the LHS and RHS of the IN operator do not match, that ** error will have been caught long before we reach this point. */ if( ALWAYS(pEList->nExpr==nVal) ){ Select *pCopy; SelectDest dest; int i; int rc; sqlite3SelectDestInit(&dest, SRT_Set, iTab); dest.zAffSdst = exprINAffinity(pParse, pExpr); pSelect->iLimit = 0; testcase( pSelect->selFlags & SF_Distinct ); testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); sqlite3SelectDelete(pParse->db, pCopy); sqlite3DbFree(pParse->db, dest.zAffSdst); if( rc ){ sqlite3KeyInfoUnref(pKeyInfo); return; } assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ assert( pEList!=0 ); assert( pEList->nExpr>0 ); | > > > > > > > > > > > > > > > | 112993 112994 112995 112996 112997 112998 112999 113000 113001 113002 113003 113004 113005 113006 113007 113008 113009 113010 113011 113012 113013 113014 113015 113016 113017 113018 113019 113020 113021 113022 113023 113024 113025 113026 113027 113028 113029 113030 | /* If the LHS and RHS of the IN operator do not match, that ** error will have been caught long before we reach this point. */ if( ALWAYS(pEList->nExpr==nVal) ){ Select *pCopy; SelectDest dest; int i; int rc; int addrBloom = 0; sqlite3SelectDestInit(&dest, SRT_Set, iTab); dest.zAffSdst = exprINAffinity(pParse, pExpr); pSelect->iLimit = 0; if( addrOnce && OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){ int regBloom = ++pParse->nMem; addrBloom = sqlite3VdbeAddOp2(v, OP_Blob, 10000, regBloom); VdbeComment((v, "Bloom filter")); dest.iSDParm2 = regBloom; } testcase( pSelect->selFlags & SF_Distinct ); testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); sqlite3SelectDelete(pParse->db, pCopy); sqlite3DbFree(pParse->db, dest.zAffSdst); if( addrBloom ){ sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; if( dest.iSDParm2==0 ){ sqlite3VdbeChangeToNoop(v, addrBloom); }else{ sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; } } if( rc ){ sqlite3KeyInfoUnref(pKeyInfo); return; } assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ assert( pEList!=0 ); assert( pEList->nExpr>0 ); |
︙ | ︙ | |||
112819 112820 112821 112822 112823 112824 112825 | u8 okConstFactor = pParse->okConstFactor; assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); pLeft = pExpr->pLeft; if( sqlite3ExprCheckIN(pParse, pExpr) ) return; zAff = exprINAffinity(pParse, pExpr); nVector = sqlite3ExprVectorSize(pExpr->pLeft); | | < < | 113314 113315 113316 113317 113318 113319 113320 113321 113322 113323 113324 113325 113326 113327 113328 | u8 okConstFactor = pParse->okConstFactor; assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); pLeft = pExpr->pLeft; if( sqlite3ExprCheckIN(pParse, pExpr) ) return; zAff = exprINAffinity(pParse, pExpr); nVector = sqlite3ExprVectorSize(pExpr->pLeft); aiMap = (int*)sqlite3DbMallocZero(pParse->db, nVector*sizeof(int)); if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; /* Attempt to compute the RHS. After this step, if anything other than ** IN_INDEX_NOOP is returned, the table opened with cursor iTab ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned, ** the RHS has not yet been coded. */ v = pParse->pVdbe; |
︙ | ︙ | |||
112964 112965 112966 112967 112968 112969 112970 112971 112972 112973 112974 112975 112976 112977 | sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs); VdbeCoverage(v); addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */ }else{ sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); if( destIfFalse==destIfNull ){ /* Combine Step 3 and Step 5 into a single opcode */ sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, rLhs, nVector); VdbeCoverage(v); goto sqlite3ExprCodeIN_finished; } /* Ordinary Step 3, for the case where FALSE and NULL are distinct */ addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, iTab, 0, rLhs, nVector); VdbeCoverage(v); | > > > > > > > > > | 113457 113458 113459 113460 113461 113462 113463 113464 113465 113466 113467 113468 113469 113470 113471 113472 113473 113474 113475 113476 113477 113478 113479 | sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs); VdbeCoverage(v); addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */ }else{ sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); if( destIfFalse==destIfNull ){ /* Combine Step 3 and Step 5 into a single opcode */ if( ExprHasProperty(pExpr, EP_Subrtn) ){ const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr); assert( pOp->opcode==OP_Once || pParse->nErr ); if( pOp->opcode==OP_Once && pOp->p3>0 ){ assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ); sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse, rLhs, nVector); VdbeCoverage(v); } } sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, rLhs, nVector); VdbeCoverage(v); goto sqlite3ExprCodeIN_finished; } /* Ordinary Step 3, for the case where FALSE and NULL are distinct */ addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, iTab, 0, rLhs, nVector); VdbeCoverage(v); |
︙ | ︙ | |||
113246 113247 113248 113249 113250 113251 113252 | } /* ** Convert a scalar expression node to a TK_REGISTER referencing ** register iReg. The caller must ensure that iReg already contains ** the correct value for the expression. */ | | > > > | | | | > | 113748 113749 113750 113751 113752 113753 113754 113755 113756 113757 113758 113759 113760 113761 113762 113763 113764 113765 113766 113767 113768 113769 113770 113771 113772 | } /* ** Convert a scalar expression node to a TK_REGISTER referencing ** register iReg. The caller must ensure that iReg already contains ** the correct value for the expression. */ SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg){ Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); if( NEVER(p==0) ) return; if( p->op==TK_REGISTER ){ assert( p->iTable==iReg ); }else{ p->op2 = p->op; p->op = TK_REGISTER; p->iTable = iReg; ExprClearProperty(p, EP_Skip); } } /* ** Evaluate an expression (either a vector or a scalar expression) and store ** the result in contiguous temporary registers. Return the index of ** the first register used to store the result. ** |
︙ | ︙ | |||
114255 114256 114257 114258 114259 114260 114261 | if( (pX = pExpr->pLeft)!=0 ){ pDel = sqlite3ExprDup(db, pX, 0); if( db->mallocFailed ){ sqlite3ExprDelete(db, pDel); break; } testcase( pX->op==TK_COLUMN ); | | | 114761 114762 114763 114764 114765 114766 114767 114768 114769 114770 114771 114772 114773 114774 114775 | if( (pX = pExpr->pLeft)!=0 ){ pDel = sqlite3ExprDup(db, pX, 0); if( db->mallocFailed ){ sqlite3ExprDelete(db, pDel); break; } testcase( pX->op==TK_COLUMN ); sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); testcase( regFree1==0 ); memset(&opCompare, 0, sizeof(opCompare)); opCompare.op = TK_EQ; opCompare.pLeft = pDel; pTest = &opCompare; /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001: ** The value in regFree1 might get SCopy-ed into the file result. |
︙ | ︙ | |||
114309 114310 114311 114312 114313 114314 114315 | return 0; } if( pExpr->affExpr==OE_Abort ){ sqlite3MayAbort(pParse); } assert( !ExprHasProperty(pExpr, EP_IntValue) ); if( pExpr->affExpr==OE_Ignore ){ | | < > | | < | 114815 114816 114817 114818 114819 114820 114821 114822 114823 114824 114825 114826 114827 114828 114829 114830 114831 114832 114833 114834 114835 114836 | return 0; } if( pExpr->affExpr==OE_Abort ){ sqlite3MayAbort(pParse); } assert( !ExprHasProperty(pExpr, EP_IntValue) ); if( pExpr->affExpr==OE_Ignore ){ sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, OE_Ignore); VdbeCoverage(v); }else{ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); sqlite3VdbeAddOp3(v, OP_Halt, pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR, pExpr->affExpr, r1); } break; } #endif } sqlite3ReleaseTempReg(pParse, regFree1); sqlite3ReleaseTempReg(pParse, regFree2); return inReg; |
︙ | ︙ | |||
114606 114607 114608 114609 114610 114611 114612 | exprAnd.pRight = &compRight; compLeft.op = TK_GE; compLeft.pLeft = pDel; compLeft.pRight = pExpr->x.pList->a[0].pExpr; compRight.op = TK_LE; compRight.pLeft = pDel; compRight.pRight = pExpr->x.pList->a[1].pExpr; | | | 115111 115112 115113 115114 115115 115116 115117 115118 115119 115120 115121 115122 115123 115124 115125 | exprAnd.pRight = &compRight; compLeft.op = TK_GE; compLeft.pLeft = pDel; compLeft.pRight = pExpr->x.pList->a[0].pExpr; compRight.op = TK_LE; compRight.pLeft = pDel; compRight.pRight = pExpr->x.pList->a[1].pExpr; sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); if( xJump ){ xJump(pParse, &exprAnd, dest, jumpIfNull); }else{ /* Mark the expression is being from the ON or USING clause of a join ** so that the sqlite3ExprCodeTarget() routine will not attempt to move ** it into the Parse.pConstExpr list. We should use a new bit for this, ** for clarity, but we are out of bits in the Expr.flags field so we |
︙ | ︙ | |||
117454 117455 117456 117457 117458 117459 117460 | pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName ); pParse->eTriggerOp = pNew->op; /* ALWAYS() because if the table of the trigger does not exist, the ** error would have been hit before this point */ if( ALWAYS(pParse->pTriggerTab) ){ | | | 117959 117960 117961 117962 117963 117964 117965 117966 117967 117968 117969 117970 117971 117972 117973 | pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName ); pParse->eTriggerOp = pNew->op; /* ALWAYS() because if the table of the trigger does not exist, the ** error would have been hit before this point */ if( ALWAYS(pParse->pTriggerTab) ){ rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab)!=0; } /* Resolve symbols in WHEN clause */ if( rc==SQLITE_OK && pNew->pWhen ){ rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen); } |
︙ | ︙ | |||
117500 117501 117502 117503 117504 117505 117506 | pSel->pSrc = 0; sqlite3SelectDelete(db, pSel); } if( pStep->pFrom ){ int i; for(i=0; i<pStep->pFrom->nSrc && rc==SQLITE_OK; i++){ SrcItem *p = &pStep->pFrom->a[i]; | | > | | 118005 118006 118007 118008 118009 118010 118011 118012 118013 118014 118015 118016 118017 118018 118019 118020 118021 | pSel->pSrc = 0; sqlite3SelectDelete(db, pSel); } if( pStep->pFrom ){ int i; for(i=0; i<pStep->pFrom->nSrc && rc==SQLITE_OK; i++){ SrcItem *p = &pStep->pFrom->a[i]; if( p->fg.isSubquery ){ assert( p->u4.pSubq!=0 ); sqlite3SelectPrep(pParse, p->u4.pSubq->pSelect, 0); } } } if( db->mallocFailed ){ rc = SQLITE_NOMEM; } |
︙ | ︙ | |||
117569 117570 117571 117572 117573 117574 117575 | sqlite3WalkExprList(pWalker, pUpsert->pUpsertTarget); sqlite3WalkExprList(pWalker, pUpsert->pUpsertSet); sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere); sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere); } if( pStep->pFrom ){ int i; | > | > > | > | 118075 118076 118077 118078 118079 118080 118081 118082 118083 118084 118085 118086 118087 118088 118089 118090 118091 118092 118093 118094 | sqlite3WalkExprList(pWalker, pUpsert->pUpsertTarget); sqlite3WalkExprList(pWalker, pUpsert->pUpsertSet); sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere); sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere); } if( pStep->pFrom ){ int i; SrcList *pFrom = pStep->pFrom; for(i=0; i<pFrom->nSrc; i++){ if( pFrom->a[i].fg.isSubquery ){ assert( pFrom->a[i].u4.pSubq!=0 ); sqlite3WalkSelect(pWalker, pFrom->a[i].u4.pSubq->pSelect); } } } } } /* ** Free the contents of Parse object (*pParse). Do not free the memory |
︙ | ︙ | |||
117817 117818 117819 117820 117821 117822 117823 | } if( NEVER(pSrc==0) ){ assert( pWalker->pParse->db->mallocFailed ); return WRC_Abort; } for(i=0; i<pSrc->nSrc; i++){ SrcItem *pItem = &pSrc->a[i]; | | | 118327 118328 118329 118330 118331 118332 118333 118334 118335 118336 118337 118338 118339 118340 118341 | } if( NEVER(pSrc==0) ){ assert( pWalker->pParse->db->mallocFailed ); return WRC_Abort; } for(i=0; i<pSrc->nSrc; i++){ SrcItem *pItem = &pSrc->a[i]; if( pItem->pSTab==p->pTab ){ renameTokenFind(pWalker->pParse, p, pItem->zName); } } renameWalkWith(pWalker, pSelect); return WRC_Continue; } |
︙ | ︙ | |||
120245 120246 120247 120248 120249 120250 120251 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); sqlite3DbFree(db, zSql); if( rc ) return rc; while( sqlite3_step(pStmt)==SQLITE_ROW ){ int nIdxCol = 1; /* Number of columns in stat4 records */ | | | | | | | > | > > | > | 120755 120756 120757 120758 120759 120760 120761 120762 120763 120764 120765 120766 120767 120768 120769 120770 120771 120772 120773 120774 120775 120776 120777 120778 120779 120780 120781 120782 120783 120784 120785 120786 120787 120788 120789 120790 120791 120792 120793 120794 120795 120796 120797 120798 120799 120800 120801 120802 120803 120804 120805 120806 120807 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); sqlite3DbFree(db, zSql); if( rc ) return rc; while( sqlite3_step(pStmt)==SQLITE_ROW ){ int nIdxCol = 1; /* Number of columns in stat4 records */ char *zIndex; /* Index name */ Index *pIdx; /* Pointer to the index object */ int nSample; /* Number of samples */ int nByte; /* Bytes of space required */ int i; /* Bytes of space required */ tRowcnt *pSpace; /* Available allocated memory space */ u8 *pPtr; /* Available memory as a u8 for easier manipulation */ zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; nSample = sqlite3_column_int(pStmt, 1); pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); assert( pIdx==0 || pIdx->nSample==0 ); if( pIdx==0 ) continue; if( pIdx->aSample!=0 ){ /* The same index appears in sqlite_stat4 under multiple names */ continue; } assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 ); if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ nIdxCol = pIdx->nKeyCol; }else{ nIdxCol = pIdx->nColumn; } pIdx->nSampleCol = nIdxCol; pIdx->mxSample = nSample; nByte = ROUND8(sizeof(IndexSample) * nSample); nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ pIdx->aSample = sqlite3DbMallocZero(db, nByte); if( pIdx->aSample==0 ){ sqlite3_finalize(pStmt); return SQLITE_NOMEM_BKPT; } pPtr = (u8*)pIdx->aSample; pPtr += ROUND8(nSample*sizeof(pIdx->aSample[0])); pSpace = (tRowcnt*)pPtr; assert( EIGHT_BYTE_ALIGNMENT( pSpace ) ); pIdx->aAvgEq = pSpace; pSpace += nIdxCol; pIdx->pTable->tabFlags |= TF_HasStat4; for(i=0; i<nSample; i++){ pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol; pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol; } |
︙ | ︙ | |||
120947 120948 120949 120950 120951 120952 120953 | SrcItem *pItem; sqlite3 *db = pFix->pParse->db; int iDb = sqlite3FindDbName(db, pFix->zDb); SrcList *pList = pSelect->pSrc; if( NEVER(pList==0) ) return WRC_Continue; for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ | | | | | | < > | > | 121461 121462 121463 121464 121465 121466 121467 121468 121469 121470 121471 121472 121473 121474 121475 121476 121477 121478 121479 121480 121481 121482 121483 121484 121485 121486 121487 121488 121489 | SrcItem *pItem; sqlite3 *db = pFix->pParse->db; int iDb = sqlite3FindDbName(db, pFix->zDb); SrcList *pList = pSelect->pSrc; if( NEVER(pList==0) ) return WRC_Continue; for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ if( pFix->bTemp==0 && pItem->fg.isSubquery==0 ){ if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){ if( iDb!=sqlite3FindDbName(db, pItem->u4.zDatabase) ){ sqlite3ErrorMsg(pFix->pParse, "%s %T cannot reference objects in database %s", pFix->zType, pFix->pName, pItem->u4.zDatabase); return WRC_Abort; } sqlite3DbFree(db, pItem->u4.zDatabase); pItem->fg.notCte = 1; pItem->fg.hadSchema = 1; } pItem->u4.pSchema = pFix->pSchema; pItem->fg.fromDDL = 1; pItem->fg.fixedSchema = 1; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) if( pList->a[i].fg.isUsing==0 && sqlite3WalkExpr(&pFix->w, pList->a[i].u3.pOn) ){ return WRC_Abort; } |
︙ | ︙ | |||
121253 121254 121255 121256 121257 121258 121259 | if( pExpr->op==TK_TRIGGER ){ pTab = pParse->pTriggerTab; }else{ assert( pTabList ); for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ | | | 121768 121769 121770 121771 121772 121773 121774 121775 121776 121777 121778 121779 121780 121781 121782 | if( pExpr->op==TK_TRIGGER ){ pTab = pParse->pTriggerTab; }else{ assert( pTabList ); for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ pTab = pTabList->a[iSrc].pSTab; break; } } } iCol = pExpr->iColumn; if( pTab==0 ) return; |
︙ | ︙ | |||
121856 121857 121858 121859 121860 121861 121862 | */ SQLITE_PRIVATE Table *sqlite3LocateTableItem( Parse *pParse, u32 flags, SrcItem *p ){ const char *zDb; | < | | > | | 122371 122372 122373 122374 122375 122376 122377 122378 122379 122380 122381 122382 122383 122384 122385 122386 122387 122388 122389 122390 | */ SQLITE_PRIVATE Table *sqlite3LocateTableItem( Parse *pParse, u32 flags, SrcItem *p ){ const char *zDb; if( p->fg.fixedSchema ){ int iDb = sqlite3SchemaToIndex(pParse->db, p->u4.pSchema); zDb = pParse->db->aDb[iDb].zDbSName; }else{ assert( !p->fg.isSubquery ); zDb = p->u4.zDatabase; } return sqlite3LocateTable(pParse, flags, p->zName, zDb); } /* ** Return the preferred table name for system tables. Translate legacy ** names into the new preferred names, as appropriate. |
︙ | ︙ | |||
124423 124424 124425 124426 124427 124428 124429 | return; } #endif /* SQLITE_OMIT_VIEW */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) /* ** The Table structure pTable is really a VIEW. Fill in the names of | | > | | 124938 124939 124940 124941 124942 124943 124944 124945 124946 124947 124948 124949 124950 124951 124952 124953 124954 | return; } #endif /* SQLITE_OMIT_VIEW */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) /* ** The Table structure pTable is really a VIEW. Fill in the names of ** the columns of the view in the pTable structure. Return non-zero if ** there are errors. If an error is seen an error message is left ** in pParse->zErrMsg. */ static SQLITE_NOINLINE int viewGetColumnNames(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 */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ #ifndef SQLITE_OMIT_VIRTUALTABLE |
︙ | ︙ | |||
124547 124548 124549 124550 124551 124552 124553 | nErr++; } pTable->pSchema->schemaFlags |= DB_UnresetViews; if( db->mallocFailed ){ sqlite3DeleteColumnNames(db, pTable); } #endif /* SQLITE_OMIT_VIEW */ | | | 125063 125064 125065 125066 125067 125068 125069 125070 125071 125072 125073 125074 125075 125076 125077 | nErr++; } pTable->pSchema->schemaFlags |= DB_UnresetViews; if( db->mallocFailed ){ sqlite3DeleteColumnNames(db, pTable); } #endif /* SQLITE_OMIT_VIEW */ return nErr + pParse->nErr; } SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable!=0 ); if( !IsVirtual(pTable) && pTable->nCol>0 ) return 0; return viewGetColumnNames(pParse, pTable); } #endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ |
︙ | ︙ | |||
124845 124846 124847 124848 124849 124850 124851 124852 124853 124854 124855 124856 124857 124858 124859 | int iDb; if( db->mallocFailed ){ goto exit_drop_table; } assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; if( noErr ) db->suppressErr++; assert( isView==0 || isView==LOCATE_VIEW ); pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); if( noErr ) db->suppressErr--; if( pTab==0 ){ if( noErr ){ | > > | | 125361 125362 125363 125364 125365 125366 125367 125368 125369 125370 125371 125372 125373 125374 125375 125376 125377 125378 125379 125380 125381 125382 125383 125384 125385 | int iDb; if( db->mallocFailed ){ goto exit_drop_table; } assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); assert( pName->a[0].fg.fixedSchema==0 ); assert( pName->a[0].fg.isSubquery==0 ); if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; if( noErr ) db->suppressErr++; assert( isView==0 || isView==LOCATE_VIEW ); pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); if( noErr ) db->suppressErr--; if( pTab==0 ){ if( noErr ){ sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase); sqlite3ForceNotReadOnly(pParse); } goto exit_drop_table; } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 && iDb<db->nDb ); |
︙ | ︙ | |||
125944 125945 125946 125947 125948 125949 125950 125951 125952 125953 | int iDb; if( db->mallocFailed ){ goto exit_drop_index; } assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */ assert( pName->nSrc==1 ); if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_drop_index; } | > > | | | 126462 126463 126464 126465 126466 126467 126468 126469 126470 126471 126472 126473 126474 126475 126476 126477 126478 126479 126480 126481 126482 126483 126484 126485 126486 | int iDb; if( db->mallocFailed ){ goto exit_drop_index; } assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */ assert( pName->nSrc==1 ); assert( pName->a[0].fg.fixedSchema==0 ); assert( pName->a[0].fg.isSubquery==0 ); if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_drop_index; } pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].u4.zDatabase); if( pIndex==0 ){ if( !ifExists ){ sqlite3ErrorMsg(pParse, "no such index: %S", pName->a); }else{ sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase); sqlite3ForceNotReadOnly(pParse); } pParse->checkSchema = 1; goto exit_drop_index; } if( pIndex->idxType!=SQLITE_IDXTYPE_APPDEF ){ sqlite3ErrorMsg(pParse, "index associated with UNIQUE " |
︙ | ︙ | |||
126249 126250 126251 126252 126253 126254 126255 126256 126257 | pList = pNew; } } pItem = &pList->a[pList->nSrc-1]; if( pDatabase && pDatabase->z==0 ){ pDatabase = 0; } if( pDatabase ){ pItem->zName = sqlite3NameFromToken(db, pDatabase); | > > | | | > > > | > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 126769 126770 126771 126772 126773 126774 126775 126776 126777 126778 126779 126780 126781 126782 126783 126784 126785 126786 126787 126788 126789 126790 126791 126792 126793 126794 126795 126796 126797 126798 126799 126800 126801 126802 126803 126804 126805 126806 126807 126808 126809 126810 126811 126812 126813 126814 126815 126816 126817 126818 126819 126820 126821 126822 126823 126824 126825 126826 126827 126828 126829 126830 126831 126832 126833 126834 126835 126836 126837 126838 126839 126840 126841 126842 126843 126844 126845 126846 126847 126848 126849 126850 126851 126852 126853 126854 126855 126856 126857 126858 126859 126860 126861 126862 126863 126864 126865 126866 126867 126868 126869 126870 126871 126872 126873 126874 126875 126876 126877 126878 126879 126880 126881 126882 126883 126884 126885 126886 126887 126888 126889 126890 126891 126892 126893 126894 126895 126896 126897 126898 126899 126900 126901 126902 126903 126904 126905 126906 126907 126908 126909 126910 126911 126912 126913 126914 126915 126916 126917 126918 126919 126920 126921 126922 | pList = pNew; } } pItem = &pList->a[pList->nSrc-1]; if( pDatabase && pDatabase->z==0 ){ pDatabase = 0; } assert( pItem->fg.fixedSchema==0 ); assert( pItem->fg.isSubquery==0 ); if( pDatabase ){ pItem->zName = sqlite3NameFromToken(db, pDatabase); pItem->u4.zDatabase = sqlite3NameFromToken(db, pTable); }else{ pItem->zName = sqlite3NameFromToken(db, pTable); pItem->u4.zDatabase = 0; } return pList; } /* ** Assign VdbeCursor index numbers to all tables in a SrcList */ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; SrcItem *pItem; assert( pList || pParse->db->mallocFailed ); if( ALWAYS(pList) ){ for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ if( pItem->iCursor>=0 ) continue; pItem->iCursor = pParse->nTab++; if( pItem->fg.isSubquery ){ assert( pItem->u4.pSubq!=0 ); assert( pItem->u4.pSubq->pSelect!=0 ); assert( pItem->u4.pSubq->pSelect->pSrc!=0 ); sqlite3SrcListAssignCursors(pParse, pItem->u4.pSubq->pSelect->pSrc); } } } } /* ** Delete a Subquery object and its substructure. */ SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3 *db, Subquery *pSubq){ assert( pSubq!=0 && pSubq->pSelect!=0 ); sqlite3SelectDelete(db, pSubq->pSelect); sqlite3DbFree(db, pSubq); } /* ** Remove a Subquery from a SrcItem. Return the associated Select object. ** The returned Select becomes the responsibility of the caller. */ SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3 *db, SrcItem *pItem){ Select *pSel; assert( pItem!=0 ); assert( pItem->fg.isSubquery ); pSel = pItem->u4.pSubq->pSelect; sqlite3DbFree(db, pItem->u4.pSubq); pItem->u4.pSubq = 0; pItem->fg.isSubquery = 0; return pSel; } /* ** Delete an entire SrcList including all its substructure. */ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ int i; SrcItem *pItem; assert( db!=0 ); if( pList==0 ) return; for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){ /* Check invariants on SrcItem */ assert( !pItem->fg.isIndexedBy || !pItem->fg.isTabFunc ); assert( !pItem->fg.isCte || !pItem->fg.isIndexedBy ); assert( !pItem->fg.fixedSchema || !pItem->fg.isSubquery ); assert( !pItem->fg.isSubquery || (pItem->u4.pSubq!=0 && pItem->u4.pSubq->pSelect!=0) ); if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName); if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias); if( pItem->fg.isSubquery ){ sqlite3SubqueryDelete(db, pItem->u4.pSubq); }else if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){ sqlite3DbNNFreeNN(db, pItem->u4.zDatabase); } if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); sqlite3DeleteTable(db, pItem->pSTab); if( pItem->fg.isUsing ){ sqlite3IdListDelete(db, pItem->u3.pUsing); }else if( pItem->u3.pOn ){ sqlite3ExprDelete(db, pItem->u3.pOn); } } sqlite3DbNNFreeNN(db, pList); } /* ** Attach a Subquery object to pItem->uv.pSubq. Set the ** pSelect value but leave all the other values initialized ** to zero. ** ** A copy of the Select object is made if dupSelect is true, and the ** SrcItem takes responsibility for deleting the copy. If dupSelect is ** false, ownership of the Select passes to the SrcItem. Either way, ** the SrcItem will take responsibility for deleting the Select. ** ** When dupSelect is zero, that means the Select might get deleted right ** away if there is an OOM error. Beware. ** ** Return non-zero on success. Return zero on an OOM error. */ SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery( Parse *pParse, /* Parsing context */ SrcItem *pItem, /* Item to which the subquery is to be attached */ Select *pSelect, /* The subquery SELECT. Must be non-NULL */ int dupSelect /* If true, attach a copy of pSelect, not pSelect itself.*/ ){ Subquery *p; assert( pSelect!=0 ); assert( pItem->fg.isSubquery==0 ); if( pItem->fg.fixedSchema ){ pItem->u4.pSchema = 0; pItem->fg.fixedSchema = 0; }else if( pItem->u4.zDatabase!=0 ){ sqlite3DbFree(pParse->db, pItem->u4.zDatabase); pItem->u4.zDatabase = 0; } if( dupSelect ){ pSelect = sqlite3SelectDup(pParse->db, pSelect, 0); if( pSelect==0 ) return 0; } p = pItem->u4.pSubq = sqlite3DbMallocRawNN(pParse->db, sizeof(Subquery)); if( p==0 ){ sqlite3SelectDelete(pParse->db, pSelect); return 0; } pItem->fg.isSubquery = 1; p->pSelect = pSelect; assert( offsetof(Subquery, pSelect)==0 ); memset(((char*)p)+sizeof(p->pSelect), 0, sizeof(*p)-sizeof(p->pSelect)); return 1; } /* ** This routine is called by the parser to add a new term to the ** end of a growing FROM clause. The "p" parameter is the part of ** the FROM clause that has already been constructed. "p" is NULL ** if this is the first term of the FROM clause. pTable and pDatabase ** are the name of the table and database named in the FROM clause term. |
︙ | ︙ | |||
126351 126352 126353 126354 126355 126356 126357 126358 | Token *pToken = (ALWAYS(pDatabase) && pDatabase->z) ? pDatabase : pTable; sqlite3RenameTokenMap(pParse, pItem->zName, pToken); } assert( pAlias!=0 ); if( pAlias->n ){ pItem->zAlias = sqlite3NameFromToken(db, pAlias); } if( pSubquery ){ | > | | | > | 126959 126960 126961 126962 126963 126964 126965 126966 126967 126968 126969 126970 126971 126972 126973 126974 126975 126976 126977 126978 | Token *pToken = (ALWAYS(pDatabase) && pDatabase->z) ? pDatabase : pTable; sqlite3RenameTokenMap(pParse, pItem->zName, pToken); } assert( pAlias!=0 ); if( pAlias->n ){ pItem->zAlias = sqlite3NameFromToken(db, pAlias); } assert( pSubquery==0 || pDatabase==0 ); if( pSubquery ){ if( sqlite3SrcItemAttachSubquery(pParse, pItem, pSubquery, 0) ){ if( pSubquery->selFlags & SF_NestedFrom ){ pItem->fg.isNestedFrom = 1; } } } assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 ); assert( pItem->fg.isUsing==0 ); if( pOnUsing==0 ){ pItem->u3.pOn = 0; }else if( pOnUsing->pUsing ){ |
︙ | ︙ | |||
127632 127633 127634 127635 127636 127637 127638 | ** the name of a single table, as one might find in an INSERT, DELETE, ** or UPDATE statement. Look up that table in the symbol table and ** return a pointer. Set an error message and return NULL if the table ** name is not found or if any other error occurs. ** ** The following fields are initialized appropriate in pSrc: ** | | | | | | 128242 128243 128244 128245 128246 128247 128248 128249 128250 128251 128252 128253 128254 128255 128256 128257 128258 128259 128260 128261 128262 128263 128264 128265 128266 | ** the name of a single table, as one might find in an INSERT, DELETE, ** or UPDATE statement. Look up that table in the symbol table and ** return a pointer. Set an error message and return NULL if the table ** name is not found or if any other error occurs. ** ** The following fields are initialized appropriate in pSrc: ** ** pSrc->a[0].spTab Pointer to the Table object ** pSrc->a[0].u2.pIBIndex Pointer to the INDEXED BY index, if there is one ** */ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ SrcItem *pItem = pSrc->a; Table *pTab; assert( pItem && pSrc->nSrc>=1 ); pTab = sqlite3LocateTableItem(pParse, 0, pItem); if( pItem->pSTab ) sqlite3DeleteTable(pParse->db, pItem->pSTab); pItem->pSTab = pTab; pItem->fg.notCte = 1; if( pTab ){ pTab->nTabRef++; if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){ pTab = 0; } } |
︙ | ︙ | |||
127683 127684 127685 127686 127687 127688 127689 127690 127691 127692 127693 127694 127695 127696 | ** been specified ** ** 4) The table is a shadow table, the database connection is in ** defensive mode, and the current sqlite3_prepare() ** is for a top-level SQL statement. */ static int vtabIsReadOnly(Parse *pParse, Table *pTab){ if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){ return 1; } /* Within triggers: ** * Do not allow DELETE, INSERT, or UPDATE of SQLITE_VTAB_DIRECTONLY ** virtual tables | > | 128293 128294 128295 128296 128297 128298 128299 128300 128301 128302 128303 128304 128305 128306 128307 | ** been specified ** ** 4) The table is a shadow table, the database connection is in ** defensive mode, and the current sqlite3_prepare() ** is for a top-level SQL statement. */ static int vtabIsReadOnly(Parse *pParse, Table *pTab){ assert( IsVirtual(pTab) ); if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){ return 1; } /* Within triggers: ** * Do not allow DELETE, INSERT, or UPDATE of SQLITE_VTAB_DIRECTONLY ** virtual tables |
︙ | ︙ | |||
127764 127765 127766 127767 127768 127769 127770 | sqlite3 *db = pParse->db; int iDb = sqlite3SchemaToIndex(db, pView->pSchema); pWhere = sqlite3ExprDup(db, pWhere, 0); pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pFrom ){ assert( pFrom->nSrc==1 ); pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); | > | | 128375 128376 128377 128378 128379 128380 128381 128382 128383 128384 128385 128386 128387 128388 128389 128390 | sqlite3 *db = pParse->db; int iDb = sqlite3SchemaToIndex(db, pView->pSchema); pWhere = sqlite3ExprDup(db, pWhere, 0); pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pFrom ){ assert( pFrom->nSrc==1 ); pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); assert( pFrom->a[0].fg.fixedSchema==0 && pFrom->a[0].fg.isSubquery==0 ); pFrom->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); assert( pFrom->a[0].fg.isUsing==0 ); assert( pFrom->a[0].u3.pOn==0 ); } pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, SF_IncludeHidden, pLimit); sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); sqlite3Select(pParse, pSel, &dest); |
︙ | ︙ | |||
127826 127827 127828 127829 127830 127831 127832 | ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 ** becomes: ** DELETE FROM table_a WHERE rowid IN ( ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 ** ); */ | | | 128438 128439 128440 128441 128442 128443 128444 128445 128446 128447 128448 128449 128450 128451 128452 | ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 ** becomes: ** DELETE FROM table_a WHERE rowid IN ( ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 ** ); */ pTab = pSrc->a[0].pSTab; if( HasRowid(pTab) ){ pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0); pEList = sqlite3ExprListAppend( pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0) ); }else{ Index *pPk = sqlite3PrimaryKeyIndex(pTab); |
︙ | ︙ | |||
127859 127860 127861 127862 127863 127864 127865 | pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0); } } } /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree ** and the SELECT subtree. */ | | | | 128471 128472 128473 128474 128475 128476 128477 128478 128479 128480 128481 128482 128483 128484 128485 128486 128487 | pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0); } } } /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree ** and the SELECT subtree. */ pSrc->a[0].pSTab = 0; pSelectSrc = sqlite3SrcListDup(db, pSrc, 0); pSrc->a[0].pSTab = pTab; if( pSrc->a[0].fg.isIndexedBy ){ assert( pSrc->a[0].fg.isCte==0 ); pSrc->a[0].u2.pIBIndex = 0; pSrc->a[0].fg.isIndexedBy = 0; sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy); }else if( pSrc->a[0].fg.isCte ){ pSrc->a[0].u2.pCteUse->nUse++; |
︙ | ︙ | |||
130688 130689 130690 130691 130692 130693 130694 | minMaxValueFinalize(context, 0); } /* ** group_concat(EXPR, ?SEPARATOR?) ** string_agg(EXPR, SEPARATOR) ** | > > > > | | 131300 131301 131302 131303 131304 131305 131306 131307 131308 131309 131310 131311 131312 131313 131314 131315 131316 131317 131318 | minMaxValueFinalize(context, 0); } /* ** group_concat(EXPR, ?SEPARATOR?) ** string_agg(EXPR, SEPARATOR) ** ** Content is accumulated in GroupConcatCtx.str with the SEPARATOR ** coming before the EXPR value, except for the first entry which ** omits the SEPARATOR. ** ** It is tragic that the SEPARATOR goes before the EXPR string. The ** groupConcatInverse() implementation would have been easier if the ** SEPARATOR were appended after EXPR. And the order is undocumented, ** so we could change it, in theory. But the old behavior has been ** around for so long that we dare not, for fear of breaking something. */ typedef struct { StrAccum str; /* The accumulated concatenation */ |
︙ | ︙ | |||
130792 130793 130794 130795 130796 130797 130798 | assert( argc==1 || argc==2 ); (void)argc; /* Suppress unused parameter warning */ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC)); /* pGCC is always non-NULL since groupConcatStep() will have always ** run first to initialize it */ if( ALWAYS(pGCC) ){ | | | 131408 131409 131410 131411 131412 131413 131414 131415 131416 131417 131418 131419 131420 131421 131422 | assert( argc==1 || argc==2 ); (void)argc; /* Suppress unused parameter warning */ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC)); /* pGCC is always non-NULL since groupConcatStep() will have always ** run first to initialize it */ if( ALWAYS(pGCC) ){ int nVS; /* Number of characters to remove */ /* Must call sqlite3_value_text() to convert the argument into text prior ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */ (void)sqlite3_value_text(argv[0]); nVS = sqlite3_value_bytes(argv[0]); pGCC->nAccum -= 1; if( pGCC->pnSepLengths!=0 ){ assert(pGCC->nAccum >= 0); |
︙ | ︙ | |||
130845 130846 130847 130848 130849 130850 130851 130852 130853 130854 130855 130856 130857 130858 | = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0); if( pGCC ){ StrAccum *pAccum = &pGCC->str; if( pAccum->accError==SQLITE_TOOBIG ){ sqlite3_result_error_toobig(context); }else if( pAccum->accError==SQLITE_NOMEM ){ sqlite3_result_error_nomem(context); }else{ const char *zText = sqlite3_str_value(pAccum); sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT); } } } #else | > > | 131461 131462 131463 131464 131465 131466 131467 131468 131469 131470 131471 131472 131473 131474 131475 131476 | = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0); if( pGCC ){ StrAccum *pAccum = &pGCC->str; if( pAccum->accError==SQLITE_TOOBIG ){ sqlite3_result_error_toobig(context); }else if( pAccum->accError==SQLITE_NOMEM ){ sqlite3_result_error_nomem(context); }else if( pGCC->nAccum>0 && pAccum->nChar==0 ){ sqlite3_result_text(context, "", 1, SQLITE_STATIC); }else{ const char *zText = sqlite3_str_value(pAccum); sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT); } } } #else |
︙ | ︙ | |||
131184 131185 131186 131187 131188 131189 131190 131191 131192 131193 131194 131195 131196 131197 | int y, z; char zBuf[100]; UNUSED_PARAMETER(argc); assert( argc==3 ); x = sqlite3_value_double(argv[0]); y = sqlite3_value_int(argv[1]); z = sqlite3_value_int(argv[2]); sqlite3FpDecode(&s, x, y, z); if( s.isSpecial==2 ){ sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN"); }else{ sqlite3_snprintf(sizeof(zBuf), zBuf, "%c%.*s/%d", s.sign, s.n, s.z, s.iDP); } sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); | > | 131802 131803 131804 131805 131806 131807 131808 131809 131810 131811 131812 131813 131814 131815 131816 | int y, z; char zBuf[100]; UNUSED_PARAMETER(argc); assert( argc==3 ); x = sqlite3_value_double(argv[0]); y = sqlite3_value_int(argv[1]); z = sqlite3_value_int(argv[2]); if( z<=0 ) z = 1; sqlite3FpDecode(&s, x, y, z); if( s.isSpecial==2 ){ sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN"); }else{ sqlite3_snprintf(sizeof(zBuf), zBuf, "%c%.*s/%d", s.sign, s.n, s.z, s.iDP); } sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); |
︙ | ︙ | |||
132440 132441 132442 132443 132444 132445 132446 | assert( aiCol || pFKey->nCol==1 ); /* Create a SrcList structure containing the child table. We need the ** child table as a SrcList for sqlite3WhereBegin() */ pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pSrc ){ SrcItem *pItem = pSrc->a; | | | | 133059 133060 133061 133062 133063 133064 133065 133066 133067 133068 133069 133070 133071 133072 133073 133074 133075 | assert( aiCol || pFKey->nCol==1 ); /* Create a SrcList structure containing the child table. We need the ** child table as a SrcList for sqlite3WhereBegin() */ pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pSrc ){ SrcItem *pItem = pSrc->a; pItem->pSTab = pFKey->pFrom; pItem->zName = pFKey->pFrom->zName; pItem->pSTab->nTabRef++; pItem->iCursor = pParse->nTab++; if( regNew!=0 ){ fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1); } if( regOld!=0 ){ int eAction = pFKey->aAction[aChange!=0]; |
︙ | ︙ | |||
132725 132726 132727 132728 132729 132730 132731 | nFrom = sqlite3Strlen30(zFrom); if( action==OE_Restrict ){ int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); SrcList *pSrc; Expr *pRaise; | | > > | | 133344 133345 133346 133347 133348 133349 133350 133351 133352 133353 133354 133355 133356 133357 133358 133359 133360 133361 133362 133363 133364 133365 133366 133367 133368 | nFrom = sqlite3Strlen30(zFrom); if( action==OE_Restrict ){ int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); SrcList *pSrc; Expr *pRaise; pRaise = sqlite3Expr(db, TK_STRING, "FOREIGN KEY constraint failed"), pRaise = sqlite3PExpr(pParse, TK_RAISE, pRaise, 0); if( pRaise ){ pRaise->affExpr = OE_Abort; } pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pSrc ){ assert( pSrc->nSrc==1 ); pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom); assert( pSrc->a[0].fg.fixedSchema==0 && pSrc->a[0].fg.isSubquery==0 ); pSrc->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); } pSelect = sqlite3SelectNew(pParse, sqlite3ExprListAppend(pParse, 0, pRaise), pSrc, pWhere, 0, 0, 0, 0, 0 ); |
︙ | ︙ | |||
133467 133468 133469 133470 133471 133472 133473 | ** If argument pVal is a Select object returned by an sqlite3MultiValues() ** that was able to use the co-routine optimization, finish coding the ** co-routine. */ SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){ if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){ SrcItem *pItem = &pVal->pSrc->a[0]; | > > | | > | 134088 134089 134090 134091 134092 134093 134094 134095 134096 134097 134098 134099 134100 134101 134102 134103 134104 134105 134106 | ** If argument pVal is a Select object returned by an sqlite3MultiValues() ** that was able to use the co-routine optimization, finish coding the ** co-routine. */ SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){ if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){ SrcItem *pItem = &pVal->pSrc->a[0]; assert( (pItem->fg.isSubquery && pItem->u4.pSubq!=0) || pParse->nErr ); if( pItem->fg.isSubquery ){ sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->u4.pSubq->regReturn); sqlite3VdbeJumpHere(pParse->pVdbe, pItem->u4.pSubq->addrFillSub - 1); } } } /* ** Return true if all expressions in the expression-list passed as the ** only argument are constant. */ |
︙ | ︙ | |||
133596 133597 133598 133599 133600 133601 133602 133603 133604 133605 133606 133607 133608 133609 133610 | ** the correct text encoding. */ if( (pParse->db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ){ sqlite3ReadSchema(pParse); } if( pRet ){ SelectDest dest; pRet->pSrc->nSrc = 1; pRet->pPrior = pLeft->pPrior; pRet->op = pLeft->op; pLeft->pPrior = 0; pLeft->op = TK_SELECT; assert( pLeft->pNext==0 ); assert( pRet->pNext==0 ); p = &pRet->pSrc->a[0]; | > > < < < > > > > > | > | | | | | | | | | | | | | > > > > > > > | | | | | 134220 134221 134222 134223 134224 134225 134226 134227 134228 134229 134230 134231 134232 134233 134234 134235 134236 134237 134238 134239 134240 134241 134242 134243 134244 134245 134246 134247 134248 134249 134250 134251 134252 134253 134254 134255 134256 134257 134258 134259 134260 134261 134262 134263 134264 134265 134266 134267 134268 134269 134270 134271 134272 134273 134274 134275 134276 134277 134278 134279 134280 134281 134282 134283 134284 134285 134286 134287 134288 134289 134290 | ** the correct text encoding. */ if( (pParse->db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ){ sqlite3ReadSchema(pParse); } if( pRet ){ SelectDest dest; Subquery *pSubq; pRet->pSrc->nSrc = 1; pRet->pPrior = pLeft->pPrior; pRet->op = pLeft->op; if( pRet->pPrior ) pRet->selFlags |= SF_Values; pLeft->pPrior = 0; pLeft->op = TK_SELECT; assert( pLeft->pNext==0 ); assert( pRet->pNext==0 ); p = &pRet->pSrc->a[0]; p->fg.viaCoroutine = 1; p->iCursor = -1; assert( !p->fg.isIndexedBy && !p->fg.isTabFunc ); p->u1.nRow = 2; if( sqlite3SrcItemAttachSubquery(pParse, p, pLeft, 0) ){ pSubq = p->u4.pSubq; pSubq->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1; pSubq->regReturn = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_InitCoroutine, pSubq->regReturn, 0, pSubq->addrFillSub); sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn); /* Allocate registers for the output of the co-routine. Do so so ** that there are two unused registers immediately before those ** used by the co-routine. This allows the code in sqlite3Insert() ** to use these registers directly, instead of copying the output ** of the co-routine to a separate array for processing. */ dest.iSdst = pParse->nMem + 3; dest.nSdst = pLeft->pEList->nExpr; pParse->nMem += 2 + dest.nSdst; pLeft->selFlags |= SF_MultiValue; sqlite3Select(pParse, pLeft, &dest); pSubq->regResult = dest.iSdst; assert( pParse->nErr || dest.iSdst>0 ); } pLeft = pRet; } }else{ p = &pLeft->pSrc->a[0]; assert( !p->fg.isTabFunc && !p->fg.isIndexedBy ); p->u1.nRow++; } if( pParse->nErr==0 ){ Subquery *pSubq; assert( p!=0 ); assert( p->fg.isSubquery ); pSubq = p->u4.pSubq; assert( pSubq!=0 ); assert( pSubq->pSelect!=0 ); assert( pSubq->pSelect->pEList!=0 ); if( pSubq->pSelect->pEList->nExpr!=pRow->nExpr ){ sqlite3SelectWrongNumTermsError(pParse, pSubq->pSelect); }else{ sqlite3ExprCodeExprList(pParse, pRow, pSubq->regResult, 0, 0); sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, pSubq->regReturn); } } sqlite3ExprListDelete(pParse->db, pRow); } return pLeft; } |
︙ | ︙ | |||
133991 133992 133993 133994 133995 133996 133997 | int rc; /* Result code */ if( pSelect->pSrc->nSrc==1 && pSelect->pSrc->a[0].fg.viaCoroutine && pSelect->pPrior==0 ){ SrcItem *pItem = &pSelect->pSrc->a[0]; | > > > | | > > | | 134627 134628 134629 134630 134631 134632 134633 134634 134635 134636 134637 134638 134639 134640 134641 134642 134643 134644 134645 134646 134647 134648 | int rc; /* Result code */ if( pSelect->pSrc->nSrc==1 && pSelect->pSrc->a[0].fg.viaCoroutine && pSelect->pPrior==0 ){ SrcItem *pItem = &pSelect->pSrc->a[0]; Subquery *pSubq; assert( pItem->fg.isSubquery ); pSubq = pItem->u4.pSubq; dest.iSDParm = pSubq->regReturn; regFromSelect = pSubq->regResult; assert( pSubq->pSelect!=0 ); assert( pSubq->pSelect->pEList!=0 ); nColumn = pSubq->pSelect->pEList->nExpr; ExplainQueryPlan((pParse, 0, "SCAN %S", pItem)); if( bIdListInOrder && nColumn==pTab->nCol ){ regData = regFromSelect; regRowid = regData - 1; regIns = regRowid - (IsVirtual(pTab) ? 1 : 0); } }else{ |
︙ | ︙ | |||
135913 135914 135915 135916 135917 135918 135919 | if( pDest->iPKey>=0 ) onError = pDest->keyConf; if( onError==OE_Default ) onError = OE_Abort; } assert(pSelect->pSrc); /* allocated even if there is no FROM clause */ if( pSelect->pSrc->nSrc!=1 ){ return 0; /* FROM clause must have exactly one term */ } | | | 136554 136555 136556 136557 136558 136559 136560 136561 136562 136563 136564 136565 136566 136567 136568 | if( pDest->iPKey>=0 ) onError = pDest->keyConf; if( onError==OE_Default ) onError = OE_Abort; } assert(pSelect->pSrc); /* allocated even if there is no FROM clause */ if( pSelect->pSrc->nSrc!=1 ){ return 0; /* FROM clause must have exactly one term */ } if( pSelect->pSrc->a[0].fg.isSubquery ){ return 0; /* FROM clause cannot contain a subquery */ } if( pSelect->pWhere ){ return 0; /* SELECT may not have a WHERE clause */ } if( pSelect->pOrderBy ){ return 0; /* SELECT may not have an ORDER BY clause */ |
︙ | ︙ | |||
142798 142799 142800 142801 142802 142803 142804 142805 142806 142807 142808 142809 142810 142811 142812 142813 142814 142815 142816 142817 142818 142819 142820 142821 142822 142823 | #ifdef SQLITE_ENABLE_API_ARMOR if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; #endif *ppStmt = 0; if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ return SQLITE_MISUSE_BKPT; } if( nBytes>=0 ){ int sz; const char *z = (const char*)zSql; for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){} nBytes = sz; } sqlite3_mutex_enter(db->mutex); zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); if( zSql8 ){ rc = sqlite3LockAndPrepare(db, zSql8, -1, prepFlags, 0, ppStmt, &zTail8); } if( zTail8 && pzTail ){ /* If sqlite3_prepare returns a tail pointer, we calculate the ** equivalent pointer into the UTF-16 string by counting the unicode ** characters between zSql8 and zTail8, and then returning a pointer ** the same number of characters into the UTF-16 string. */ int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); | > > > > > > > > > > > > | | 143439 143440 143441 143442 143443 143444 143445 143446 143447 143448 143449 143450 143451 143452 143453 143454 143455 143456 143457 143458 143459 143460 143461 143462 143463 143464 143465 143466 143467 143468 143469 143470 143471 143472 143473 143474 143475 143476 143477 143478 143479 143480 143481 143482 143483 143484 | #ifdef SQLITE_ENABLE_API_ARMOR if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; #endif *ppStmt = 0; if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ return SQLITE_MISUSE_BKPT; } /* Make sure nBytes is non-negative and correct. It should be the ** number of bytes until the end of the input buffer or until the first ** U+0000 character. If the input nBytes is odd, convert it into ** an even number. If the input nBytes is negative, then the input ** must be terminated by at least one U+0000 character */ if( nBytes>=0 ){ int sz; const char *z = (const char*)zSql; for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){} nBytes = sz; }else{ int sz; const char *z = (const char*)zSql; for(sz=0; z[sz]!=0 || z[sz+1]!=0; sz += 2){} nBytes = sz; } sqlite3_mutex_enter(db->mutex); zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); if( zSql8 ){ rc = sqlite3LockAndPrepare(db, zSql8, -1, prepFlags, 0, ppStmt, &zTail8); } if( zTail8 && pzTail ){ /* If sqlite3_prepare returns a tail pointer, we calculate the ** equivalent pointer into the UTF-16 string by counting the unicode ** characters between zSql8 and zTail8, and then returning a pointer ** the same number of characters into the UTF-16 string. */ int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, nBytes, chars_parsed); } sqlite3DbFree(db, zSql8); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; } |
︙ | ︙ | |||
143211 143212 143213 143214 143215 143216 143217 | } /* ** Mark a subquery result column as having been used. */ SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ assert( pItem!=0 ); | | > | > | | 143864 143865 143866 143867 143868 143869 143870 143871 143872 143873 143874 143875 143876 143877 143878 143879 143880 143881 143882 143883 143884 | } /* ** Mark a subquery result column as having been used. */ SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ assert( pItem!=0 ); assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); if( pItem->fg.isNestedFrom ){ ExprList *pResults; assert( pItem->fg.isSubquery ); assert( pItem->u4.pSubq!=0 ); assert( pItem->u4.pSubq->pSelect!=0 ); pResults = pItem->u4.pSubq->pSelect->pEList; assert( pResults!=0 ); assert( iCol>=0 && iCol<pResults->nExpr ); pResults->a[iCol].fg.bUsed = 1; } } /* |
︙ | ︙ | |||
143249 143250 143251 143252 143253 143254 143255 | int iCol; /* Index of column matching zCol */ assert( iEnd<pSrc->nSrc ); assert( iStart>=0 ); assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=iStart; i<=iEnd; i++){ | | | | 143904 143905 143906 143907 143908 143909 143910 143911 143912 143913 143914 143915 143916 143917 143918 143919 143920 | int iCol; /* Index of column matching zCol */ assert( iEnd<pSrc->nSrc ); assert( iStart>=0 ); assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=iStart; i<=iEnd; i++){ iCol = sqlite3ColumnIndex(pSrc->a[i].pSTab, zCol); if( iCol>=0 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pSTab->aCol[iCol])==0) ){ if( piTab ){ sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol); *piTab = i; *piCol = iCol; } return 1; |
︙ | ︙ | |||
143380 143381 143382 143383 143384 143385 143386 | SrcItem *pLeft; /* Left table being joined */ SrcItem *pRight; /* Right table being joined */ pSrc = p->pSrc; pLeft = &pSrc->a[0]; pRight = &pLeft[1]; for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){ | | | | 144035 144036 144037 144038 144039 144040 144041 144042 144043 144044 144045 144046 144047 144048 144049 144050 144051 144052 | SrcItem *pLeft; /* Left table being joined */ SrcItem *pRight; /* Right table being joined */ pSrc = p->pSrc; pLeft = &pSrc->a[0]; pRight = &pLeft[1]; for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){ Table *pRightTab = pRight->pSTab; u32 joinType; if( NEVER(pLeft->pSTab==0 || pRightTab==0) ) continue; joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON; /* If this is a NATURAL join, synthesize an appropriate USING clause ** to specify which columns should be joined. */ if( pRight->fg.jointype & JT_NATURAL ){ IdList *pUsing = 0; |
︙ | ︙ | |||
144256 144257 144258 144259 144260 144261 144262 144263 144264 144265 144266 144267 144268 144269 144270 144271 144272 144273 144274 144275 | if( pSort ){ /* At first glance you would think we could optimize out the ** ORDER BY in this case since the order of entries in the set ** does not matter. But there might be a LIMIT clause, in which ** case the order does matter */ pushOntoSorter( pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); }else{ int r1 = sqlite3GetTempReg(pParse); assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, r1, pDest->zAffSdst, nResultCol); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); sqlite3ReleaseTempReg(pParse, r1); } break; } /* If any row exist in the result set, record that fact and abort. | > > > > > > | 144911 144912 144913 144914 144915 144916 144917 144918 144919 144920 144921 144922 144923 144924 144925 144926 144927 144928 144929 144930 144931 144932 144933 144934 144935 144936 | if( pSort ){ /* At first glance you would think we could optimize out the ** ORDER BY in this case since the order of entries in the set ** does not matter. But there might be a LIMIT clause, in which ** case the order does matter */ pushOntoSorter( pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); pDest->iSDParm2 = 0; /* Signal that any Bloom filter is unpopulated */ }else{ int r1 = sqlite3GetTempReg(pParse); assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, r1, pDest->zAffSdst, nResultCol); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); if( pDest->iSDParm2 ){ sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, regResult, nResultCol); ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); } sqlite3ReleaseTempReg(pParse, r1); } break; } /* If any row exist in the result set, record that fact and abort. |
︙ | ︙ | |||
144803 144804 144805 144806 144807 144808 144809 | Table *pTab = 0; /* Table structure column is extracted from */ Select *pS = 0; /* Select the column is extracted from */ int iCol = pExpr->iColumn; /* Index of column in pTab */ while( pNC && !pTab ){ SrcList *pTabList = pNC->pSrcList; for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); if( j<pTabList->nSrc ){ | | > | > > > | 145464 145465 145466 145467 145468 145469 145470 145471 145472 145473 145474 145475 145476 145477 145478 145479 145480 145481 145482 145483 | Table *pTab = 0; /* Table structure column is extracted from */ Select *pS = 0; /* Select the column is extracted from */ int iCol = pExpr->iColumn; /* Index of column in pTab */ while( pNC && !pTab ){ SrcList *pTabList = pNC->pSrcList; for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); if( j<pTabList->nSrc ){ pTab = pTabList->a[j].pSTab; if( pTabList->a[j].fg.isSubquery ){ pS = pTabList->a[j].u4.pSubq->pSelect; }else{ pS = 0; } }else{ pNC = pNC->pNext; } } if( pTab==0 ){ /* At one time, code such as "SELECT new.x" within a trigger would |
︙ | ︙ | |||
145371 145372 145373 145374 145375 145376 145377 | */ if( pLimit ){ assert( pLimit->op==TK_LIMIT ); assert( pLimit->pLeft!=0 ); p->iLimit = iLimit = ++pParse->nMem; v = sqlite3GetVdbe(pParse); assert( v!=0 ); | | | 146036 146037 146038 146039 146040 146041 146042 146043 146044 146045 146046 146047 146048 146049 146050 | */ if( pLimit ){ assert( pLimit->op==TK_LIMIT ); assert( pLimit->pLeft!=0 ); p->iLimit = iLimit = ++pParse->nMem; v = sqlite3GetVdbe(pParse); assert( v!=0 ); if( sqlite3ExprIsInteger(pLimit->pLeft, &n, pParse) ){ sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); VdbeComment((v, "LIMIT counter")); if( n==0 ){ sqlite3VdbeGoto(v, iBreak); }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){ p->nSelectRow = sqlite3LogEst((u64)n); p->selFlags |= SF_FixedLimit; |
︙ | ︙ | |||
145851 145852 145853 145854 145855 145856 145857 | TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL right...\n")); rc = sqlite3Select(pParse, p, &dest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); if( p->pLimit | | | 146516 146517 146518 146519 146520 146521 146522 146523 146524 146525 146526 146527 146528 146529 146530 | TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL right...\n")); rc = sqlite3Select(pParse, p, &dest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); if( p->pLimit && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit, pParse) && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) ){ p->nSelectRow = sqlite3LogEst((u64)nLimit); } if( addr ){ sqlite3VdbeJumpHere(v, addr); } |
︙ | ︙ | |||
146195 146196 146197 146198 146199 146200 146201 146202 146203 146204 146205 146206 146207 146208 | int r1; testcase( pIn->nSdst>1 ); r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1, pDest->zAffSdst, pIn->nSdst); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, pIn->iSdst, pIn->nSdst); sqlite3ReleaseTempReg(pParse, r1); break; } /* If this is a scalar select that is part of an expression, then ** store the results in the appropriate memory cell and break out ** of the scan loop. Note that the select might return multiple columns | > > > > > | 146860 146861 146862 146863 146864 146865 146866 146867 146868 146869 146870 146871 146872 146873 146874 146875 146876 146877 146878 | int r1; testcase( pIn->nSdst>1 ); r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1, pDest->zAffSdst, pIn->nSdst); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, pIn->iSdst, pIn->nSdst); if( pDest->iSDParm2>0 ){ sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, pIn->iSdst, pIn->nSdst); ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); } sqlite3ReleaseTempReg(pParse, r1); break; } /* If this is a scalar select that is part of an expression, then ** store the results in the appropriate memory cell and break out ** of the scan loop. Note that the select might return multiple columns |
︙ | ︙ | |||
146851 146852 146853 146854 146855 146856 146857 | substExprList(pSubst, p->pGroupBy); substExprList(pSubst, p->pOrderBy); p->pHaving = substExpr(pSubst, p->pHaving); p->pWhere = substExpr(pSubst, p->pWhere); pSrc = p->pSrc; assert( pSrc!=0 ); for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ | > | > | 147521 147522 147523 147524 147525 147526 147527 147528 147529 147530 147531 147532 147533 147534 147535 147536 147537 | substExprList(pSubst, p->pGroupBy); substExprList(pSubst, p->pOrderBy); p->pHaving = substExpr(pSubst, p->pHaving); p->pWhere = substExpr(pSubst, p->pWhere); pSrc = p->pSrc; assert( pSrc!=0 ); for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ if( pItem->fg.isSubquery ){ substSelect(pSubst, pItem->u4.pSubq->pSelect, 1); } if( pItem->fg.isTabFunc ){ substExprList(pSubst, pItem->u1.pFuncArg); } } }while( doPrior && (p = p->pPrior)!=0 ); } #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ |
︙ | ︙ | |||
146882 146883 146884 146885 146886 146887 146888 | return WRC_Continue; } static void recomputeColumnsUsed( Select *pSelect, /* The complete SELECT statement */ SrcItem *pSrcItem /* Which FROM clause item to recompute */ ){ Walker w; | | | 147554 147555 147556 147557 147558 147559 147560 147561 147562 147563 147564 147565 147566 147567 147568 | return WRC_Continue; } static void recomputeColumnsUsed( Select *pSelect, /* The complete SELECT statement */ SrcItem *pSrcItem /* Which FROM clause item to recompute */ ){ Walker w; if( NEVER(pSrcItem->pSTab==0) ) return; memset(&w, 0, sizeof(w)); w.xExprCallback = recomputeColumnsUsedExpr; w.xSelectCallback = sqlite3SelectWalkNoop; w.u.pSrcItem = pSrcItem; pSrcItem->colUsed = 0; sqlite3WalkSelect(&w, pSelect); } |
︙ | ︙ | |||
146922 146923 146924 146925 146926 146927 146928 | if( i!=iExcept ){ Select *p; assert( pItem->iCursor < aCsrMap[0] ); if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor+1]==0 ){ aCsrMap[pItem->iCursor+1] = pParse->nTab++; } pItem->iCursor = aCsrMap[pItem->iCursor+1]; | > | | > | 147594 147595 147596 147597 147598 147599 147600 147601 147602 147603 147604 147605 147606 147607 147608 147609 147610 147611 | if( i!=iExcept ){ Select *p; assert( pItem->iCursor < aCsrMap[0] ); if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor+1]==0 ){ aCsrMap[pItem->iCursor+1] = pParse->nTab++; } pItem->iCursor = aCsrMap[pItem->iCursor+1]; if( pItem->fg.isSubquery ){ for(p=pItem->u4.pSubq->pSelect; p; p=p->pPrior){ srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); } } } } } /* ** *piCursor is a cursor number. Change it if it needs to be mapped. |
︙ | ︙ | |||
147234 147235 147236 147237 147238 147239 147240 | assert( p!=0 ); assert( p->pPrior==0 ); if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0; pSrc = p->pSrc; assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc ); pSubitem = &pSrc->a[iFrom]; iParent = pSubitem->iCursor; | > | | 147908 147909 147910 147911 147912 147913 147914 147915 147916 147917 147918 147919 147920 147921 147922 147923 | assert( p!=0 ); assert( p->pPrior==0 ); if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0; pSrc = p->pSrc; assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc ); pSubitem = &pSrc->a[iFrom]; iParent = pSubitem->iCursor; assert( pSubitem->fg.isSubquery ); pSub = pSubitem->u4.pSubq->pSelect; assert( pSub!=0 ); #ifndef SQLITE_OMIT_WINDOWFUNC if( p->pWin || pSub->pWin ) return 0; /* Restriction (25) */ #endif pSubSrc = pSub->pSrc; |
︙ | ︙ | |||
147287 147288 147289 147290 147291 147292 147293 | ** ** which is not at all the same thing. ** ** See also tickets #306, #350, and #3300. */ if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ if( pSubSrc->nSrc>1 /* (3a) */ | | | 147962 147963 147964 147965 147966 147967 147968 147969 147970 147971 147972 147973 147974 147975 147976 | ** ** which is not at all the same thing. ** ** See also tickets #306, #350, and #3300. */ if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ if( pSubSrc->nSrc>1 /* (3a) */ || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */ || (p->selFlags & SF_Distinct)!=0 /* (3d) */ || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ ){ return 0; } isOuterJoin = 1; } |
︙ | ︙ | |||
147373 147374 147375 147376 147377 147378 147379 | /* Authorize the subquery */ pParse->zAuthContext = pSubitem->zName; TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); testcase( i==SQLITE_DENY ); pParse->zAuthContext = zSavedAuthContext; /* Delete the transient structures associated with the subquery */ | > > > > | > | > < < | 148048 148049 148050 148051 148052 148053 148054 148055 148056 148057 148058 148059 148060 148061 148062 148063 148064 148065 148066 148067 148068 148069 148070 148071 148072 148073 | /* Authorize the subquery */ pParse->zAuthContext = pSubitem->zName; TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); testcase( i==SQLITE_DENY ); pParse->zAuthContext = zSavedAuthContext; /* Delete the transient structures associated with the subquery */ if( ALWAYS(pSubitem->fg.isSubquery) ){ pSub1 = sqlite3SubqueryDetach(db, pSubitem); }else{ pSub1 = 0; } assert( pSubitem->fg.isSubquery==0 ); assert( pSubitem->fg.fixedSchema==0 ); sqlite3DbFree(db, pSubitem->zName); sqlite3DbFree(db, pSubitem->zAlias); pSubitem->zName = 0; pSubitem->zAlias = 0; assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 ); /* If the sub-query is a compound SELECT statement, then (by restrictions ** 17 and 18 above) it must be a UNION ALL and the parent query must ** be of the form: ** ** SELECT <expr-list> FROM (<sub-query>) <where-clause> |
︙ | ︙ | |||
147421 147422 147423 147424 147425 147426 147427 | ** We call this the "compound-subquery flattening". */ for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){ Select *pNew; ExprList *pOrderBy = p->pOrderBy; Expr *pLimit = p->pLimit; Select *pPrior = p->pPrior; | | | | | > | > > | | | | 148100 148101 148102 148103 148104 148105 148106 148107 148108 148109 148110 148111 148112 148113 148114 148115 148116 148117 148118 148119 148120 148121 148122 148123 148124 148125 148126 148127 148128 148129 148130 148131 148132 148133 148134 148135 148136 148137 148138 148139 148140 148141 148142 148143 148144 148145 148146 148147 148148 148149 148150 148151 148152 148153 148154 148155 148156 148157 148158 148159 148160 148161 148162 148163 148164 148165 | ** We call this the "compound-subquery flattening". */ for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){ Select *pNew; ExprList *pOrderBy = p->pOrderBy; Expr *pLimit = p->pLimit; Select *pPrior = p->pPrior; Table *pItemTab = pSubitem->pSTab; pSubitem->pSTab = 0; p->pOrderBy = 0; p->pPrior = 0; p->pLimit = 0; pNew = sqlite3SelectDup(db, p, 0); p->pLimit = pLimit; p->pOrderBy = pOrderBy; p->op = TK_ALL; pSubitem->pSTab = pItemTab; if( pNew==0 ){ p->pPrior = pPrior; }else{ pNew->selId = ++pParse->nSelect; if( aCsrMap && ALWAYS(db->mallocFailed==0) ){ renumberCursors(pParse, pNew, iFrom, aCsrMap); } pNew->pPrior = pPrior; if( pPrior ) pPrior->pNext = pNew; pNew->pNext = p; p->pPrior = pNew; TREETRACE(0x4,pParse,p,("compound-subquery flattener" " creates %u as peer\n",pNew->selId)); } assert( pSubitem->fg.isSubquery==0 ); } sqlite3DbFree(db, aCsrMap); if( db->mallocFailed ){ assert( pSubitem->fg.fixedSchema==0 ); assert( pSubitem->fg.isSubquery==0 ); assert( pSubitem->u4.zDatabase==0 ); sqlite3SrcItemAttachSubquery(pParse, pSubitem, pSub1, 0); return 1; } /* Defer deleting the Table object associated with the ** subquery until code generation is ** complete, since there may still exist Expr.pTab entries that ** refer to the subquery even after flattening. Ticket #3346. ** ** pSubitem->pTab is always non-NULL by test restrictions and tests above. */ if( ALWAYS(pSubitem->pSTab!=0) ){ Table *pTabToDel = pSubitem->pSTab; if( pTabToDel->nTabRef==1 ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel); testcase( pToplevel->earlyCleanup ); }else{ pTabToDel->nTabRef--; } pSubitem->pSTab = 0; } /* The following loop runs once for each term in a compound-subquery ** flattening (as described above). If we are doing a different kind ** of flattening - a flattening other than a compound-subquery flattening - ** then this loop only runs once. ** |
︙ | ︙ | |||
147525 147526 147527 147528 147529 147530 147531 | } /* Transfer the FROM clause terms from the subquery into the ** outer query. */ for(i=0; i<nSubSrc; i++){ SrcItem *pItem = &pSrc->a[i+iFrom]; | | | > > > | 148207 148208 148209 148210 148211 148212 148213 148214 148215 148216 148217 148218 148219 148220 148221 148222 148223 148224 148225 | } /* Transfer the FROM clause terms from the subquery into the ** outer query. */ for(i=0; i<nSubSrc; i++){ SrcItem *pItem = &pSrc->a[i+iFrom]; assert( pItem->fg.isTabFunc==0 ); assert( pItem->fg.isSubquery || pItem->fg.fixedSchema || pItem->u4.zDatabase==0 ); if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); *pItem = pSubSrc->a[i]; pItem->fg.jointype |= ltorj; iNewParent = pSubSrc->a[i].iCursor; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } pSrc->a[iFrom].fg.jointype &= JT_LTORJ; pSrc->a[iFrom].fg.jointype |= jointype | ltorj; |
︙ | ︙ | |||
147945 147946 147947 147948 147949 147950 147951 | ** WHERE x=5 AND y=10; ** ** The hope is that the terms added to the inner query will make it more ** efficient. ** ** NAME AMBIGUITY ** | | > | 148630 148631 148632 148633 148634 148635 148636 148637 148638 148639 148640 148641 148642 148643 148644 148645 | ** WHERE x=5 AND y=10; ** ** The hope is that the terms added to the inner query will make it more ** efficient. ** ** NAME AMBIGUITY ** ** This optimization is called the "WHERE-clause push-down optimization" ** or sometimes the "predicate push-down optimization". ** ** Do not confuse this optimization with another unrelated optimization ** with a similar name: The "MySQL push-down optimization" causes WHERE ** clause terms that can be evaluated using only the index and without ** reference to the table are run first, so that if they are false, ** unnecessary table seeks are avoided. ** |
︙ | ︙ | |||
148209 148210 148211 148212 148213 148214 148215 | int nChng = 0; /* Number of columns converted to NULL */ Bitmask colUsed; /* Columns that may not be NULLed out */ assert( pItem!=0 ); if( pItem->fg.isCorrelated || pItem->fg.isCte ){ return 0; } | | | | | | 148895 148896 148897 148898 148899 148900 148901 148902 148903 148904 148905 148906 148907 148908 148909 148910 148911 148912 | int nChng = 0; /* Number of columns converted to NULL */ Bitmask colUsed; /* Columns that may not be NULLed out */ assert( pItem!=0 ); if( pItem->fg.isCorrelated || pItem->fg.isCte ){ return 0; } assert( pItem->pSTab!=0 ); pTab = pItem->pSTab; assert( pItem->fg.isSubquery ); pSub = pItem->u4.pSubq->pSelect; assert( pSub->pEList->nExpr==pTab->nCol ); for(pX=pSub; pX; pX=pX->pPrior){ if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ testcase( pX->selFlags & SF_Distinct ); testcase( pX->selFlags & SF_Aggregate ); return 0; } |
︙ | ︙ | |||
148341 148342 148343 148344 148345 148346 148347 | Expr *pExpr; assert( !p->pGroupBy ); if( p->pWhere || p->pEList->nExpr!=1 || p->pSrc->nSrc!=1 | | | | 149027 149028 149029 149030 149031 149032 149033 149034 149035 149036 149037 149038 149039 149040 149041 149042 149043 149044 149045 149046 149047 | Expr *pExpr; assert( !p->pGroupBy ); if( p->pWhere || p->pEList->nExpr!=1 || p->pSrc->nSrc!=1 || p->pSrc->a[0].fg.isSubquery || pAggInfo->nFunc!=1 || p->pHaving ){ return 0; } pTab = p->pSrc->a[0].pSTab; assert( pTab!=0 ); assert( !IsView(pTab) ); if( !IsOrdinaryTable(pTab) ) return 0; pExpr = p->pEList->a[0].pExpr; assert( pExpr!=0 ); if( pExpr->op!=TK_AGG_FUNCTION ) return 0; if( pExpr->pAggInfo!=pAggInfo ) return 0; |
︙ | ︙ | |||
148372 148373 148374 148375 148376 148377 148378 | ** If the source-list item passed as an argument was augmented with an ** INDEXED BY clause, then try to locate the specified index. If there ** was such a clause and the named index cannot be found, return ** SQLITE_ERROR and leave an error in pParse. Otherwise, populate ** pFrom->pIndex and return SQLITE_OK. */ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ | | | 149058 149059 149060 149061 149062 149063 149064 149065 149066 149067 149068 149069 149070 149071 149072 | ** If the source-list item passed as an argument was augmented with an ** INDEXED BY clause, then try to locate the specified index. If there ** was such a clause and the named index cannot be found, return ** SQLITE_ERROR and leave an error in pParse. Otherwise, populate ** pFrom->pIndex and return SQLITE_OK. */ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ Table *pTab = pFrom->pSTab; char *zIndexedBy = pFrom->u1.zIndexedBy; Index *pIdx; assert( pTab!=0 ); assert( pFrom->fg.isIndexedBy!=0 ); for(pIdx=pTab->pIndex; pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); |
︙ | ︙ | |||
148449 148450 148451 148452 148453 148454 148455 | pParse = pWalker->pParse; db = pParse->db; pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); if( pNew==0 ) return WRC_Abort; memset(&dummy, 0, sizeof(dummy)); pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0); | > > > | > | 149135 149136 149137 149138 149139 149140 149141 149142 149143 149144 149145 149146 149147 149148 149149 149150 149151 149152 149153 | pParse = pWalker->pParse; db = pParse->db; pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); if( pNew==0 ) return WRC_Abort; memset(&dummy, 0, sizeof(dummy)); pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0); assert( pNewSrc!=0 || pParse->nErr ); if( pParse->nErr ){ sqlite3SrcListDelete(db, pNewSrc); return WRC_Abort; } *pNew = *p; p->pSrc = pNewSrc; p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0)); p->op = TK_SELECT; p->pWhere = 0; pNew->pGroupBy = 0; pNew->pHaving = 0; |
︙ | ︙ | |||
148504 148505 148506 148507 148508 148509 148510 | static struct Cte *searchWith( With *pWith, /* Current innermost WITH clause */ SrcItem *pItem, /* FROM clause element to resolve */ With **ppContext /* OUT: WITH clause return value belongs to */ ){ const char *zName = pItem->zName; With *p; | | | 149194 149195 149196 149197 149198 149199 149200 149201 149202 149203 149204 149205 149206 149207 149208 | static struct Cte *searchWith( With *pWith, /* Current innermost WITH clause */ SrcItem *pItem, /* FROM clause element to resolve */ With **ppContext /* OUT: WITH clause return value belongs to */ ){ const char *zName = pItem->zName; With *p; assert( pItem->fg.fixedSchema || pItem->u4.zDatabase==0 ); assert( zName!=0 ); for(p=pWith; p; p=p->pOuter){ int i; for(i=0; i<p->nCte; i++){ if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ *ppContext = p; return &p->a[i]; |
︙ | ︙ | |||
148574 148575 148576 148577 148578 148579 148580 | Parse *pParse, /* The parsing context */ Walker *pWalker, /* Current tree walker */ SrcItem *pFrom /* The FROM clause term to check */ ){ Cte *pCte; /* Matched CTE (or NULL if no match) */ With *pWith; /* The matching WITH */ | | > | | 149264 149265 149266 149267 149268 149269 149270 149271 149272 149273 149274 149275 149276 149277 149278 149279 149280 149281 149282 149283 149284 149285 149286 149287 149288 149289 | Parse *pParse, /* The parsing context */ Walker *pWalker, /* Current tree walker */ SrcItem *pFrom /* The FROM clause term to check */ ){ Cte *pCte; /* Matched CTE (or NULL if no match) */ With *pWith; /* The matching WITH */ assert( pFrom->pSTab==0 ); if( pParse->pWith==0 ){ /* There are no WITH clauses in the stack. No match is possible */ return 0; } if( pParse->nErr ){ /* Prior errors might have left pParse->pWith in a goofy state, so ** go no further. */ return 0; } assert( pFrom->fg.hadSchema==0 || pFrom->fg.notCte!=0 ); if( pFrom->fg.fixedSchema==0 && pFrom->u4.zDatabase!=0 ){ /* The FROM term contains a schema qualifier (ex: main.t1) and so ** it cannot possibly be a CTE reference. */ return 0; } if( pFrom->fg.notCte ){ /* The FROM term is specifically excluded from matching a CTE. ** (1) It is part of a trigger that used to have zDatabase but had |
︙ | ︙ | |||
148620 148621 148622 148623 148624 148625 148626 | ** In this case, proceed. */ if( pCte->zCteErr ){ sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName); return 2; } if( cannotBeFunction(pParse, pFrom) ) return 2; | | | | > > > | < > | | | > > | | 149311 149312 149313 149314 149315 149316 149317 149318 149319 149320 149321 149322 149323 149324 149325 149326 149327 149328 149329 149330 149331 149332 149333 149334 149335 149336 149337 149338 149339 149340 149341 149342 149343 149344 149345 149346 149347 149348 149349 149350 149351 149352 149353 149354 149355 149356 149357 149358 149359 149360 149361 149362 149363 149364 149365 149366 149367 149368 149369 149370 149371 149372 149373 149374 149375 | ** In this case, proceed. */ if( pCte->zCteErr ){ sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName); return 2; } if( cannotBeFunction(pParse, pFrom) ) return 2; assert( pFrom->pSTab==0 ); pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return 2; pCteUse = pCte->pUse; if( pCteUse==0 ){ pCte->pUse = pCteUse = sqlite3DbMallocZero(db, sizeof(pCteUse[0])); if( pCteUse==0 || sqlite3ParserAddCleanup(pParse,sqlite3DbFree,pCteUse)==0 ){ sqlite3DbFree(db, pTab); return 2; } pCteUse->eM10d = pCte->eM10d; } pFrom->pSTab = pTab; pTab->nTabRef = 1; pTab->zName = sqlite3DbStrDup(db, pCte->zName); pTab->iPKey = -1; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; sqlite3SrcItemAttachSubquery(pParse, pFrom, pCte->pSelect, 1); if( db->mallocFailed ) return 2; assert( pFrom->fg.isSubquery && pFrom->u4.pSubq ); pSel = pFrom->u4.pSubq->pSelect; assert( pSel!=0 ); pSel->selFlags |= SF_CopyCte; if( pFrom->fg.isIndexedBy ){ sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy); return 2; } assert( !pFrom->fg.isIndexedBy ); pFrom->fg.isCte = 1; pFrom->u2.pCteUse = pCteUse; pCteUse->nUse++; /* Check if this is a recursive CTE. */ pRecTerm = pSel; bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); while( bMayRecursive && pRecTerm->op==pSel->op ){ int i; SrcList *pSrc = pRecTerm->pSrc; assert( pRecTerm->pPrior!=0 ); for(i=0; i<pSrc->nSrc; i++){ SrcItem *pItem = &pSrc->a[i]; if( pItem->zName!=0 && !pItem->fg.hadSchema && ALWAYS( !pItem->fg.isSubquery ) && (pItem->fg.fixedSchema || pItem->u4.zDatabase==0) && 0==sqlite3StrICmp(pItem->zName, pCte->zName) ){ pItem->pSTab = pTab; pTab->nTabRef++; pItem->fg.isRecursive = 1; if( pRecTerm->selFlags & SF_Recursive ){ sqlite3ErrorMsg(pParse, "multiple references to recursive table: %s", pCte->zName ); return 2; |
︙ | ︙ | |||
148767 148768 148769 148770 148771 148772 148773 | ** The SrcItem structure passed as the second argument represents a ** sub-query in the FROM clause of a SELECT statement. This function ** allocates and populates the SrcItem.pTab object. If successful, ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, ** SQLITE_NOMEM. */ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ | | > > > | | 149463 149464 149465 149466 149467 149468 149469 149470 149471 149472 149473 149474 149475 149476 149477 149478 149479 149480 149481 149482 149483 149484 | ** The SrcItem structure passed as the second argument represents a ** sub-query in the FROM clause of a SELECT statement. This function ** allocates and populates the SrcItem.pTab object. If successful, ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, ** SQLITE_NOMEM. */ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ Select *pSel; Table *pTab; assert( pFrom->fg.isSubquery ); assert( pFrom->u4.pSubq!=0 ); pSel = pFrom->u4.pSubq->pSelect; assert( pSel ); pFrom->pSTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); if( pTab==0 ) return SQLITE_NOMEM; pTab->nTabRef = 1; if( pFrom->zAlias ){ pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias); }else{ pTab->zName = sqlite3MPrintf(pParse->db, "%!S", pFrom); } |
︙ | ︙ | |||
148891 148892 148893 148894 148895 148896 148897 | /* Look up every table named in the FROM clause of the select. If ** an entry of the FROM clause is a subquery instead of a table or view, ** then create a transient table structure to describe the subquery. */ for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ Table *pTab; | | | | > > | | | | | | | > | > | 149590 149591 149592 149593 149594 149595 149596 149597 149598 149599 149600 149601 149602 149603 149604 149605 149606 149607 149608 149609 149610 149611 149612 149613 149614 149615 149616 149617 149618 149619 149620 149621 149622 149623 149624 149625 149626 149627 149628 149629 149630 149631 149632 149633 149634 149635 149636 149637 149638 149639 149640 149641 149642 149643 149644 149645 149646 149647 149648 149649 149650 149651 149652 149653 149654 149655 149656 149657 149658 149659 149660 149661 149662 149663 149664 149665 149666 149667 149668 149669 149670 | /* Look up every table named in the FROM clause of the select. If ** an entry of the FROM clause is a subquery instead of a table or view, ** then create a transient table structure to describe the subquery. */ for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ Table *pTab; assert( pFrom->fg.isRecursive==0 || pFrom->pSTab!=0 ); if( pFrom->pSTab ) continue; assert( pFrom->fg.isRecursive==0 ); if( pFrom->zName==0 ){ #ifndef SQLITE_OMIT_SUBQUERY Select *pSel; assert( pFrom->fg.isSubquery && pFrom->u4.pSubq!=0 ); pSel = pFrom->u4.pSubq->pSelect; /* A sub-query in the FROM clause of a SELECT */ assert( pSel!=0 ); assert( pFrom->pSTab==0 ); if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; #endif #ifndef SQLITE_OMIT_CTE }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){ if( rc>1 ) return WRC_Abort; pTab = pFrom->pSTab; assert( pTab!=0 ); #endif }else{ /* An ordinary table or view name in the FROM clause */ assert( pFrom->pSTab==0 ); pFrom->pSTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); if( pTab==0 ) return WRC_Abort; if( pTab->nTabRef>=0xffff ){ sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", pTab->zName); pFrom->pSTab = 0; return WRC_Abort; } pTab->nTabRef++; if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){ return WRC_Abort; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) if( !IsOrdinaryTable(pTab) ){ i16 nCol; u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->fg.isSubquery==0 ); if( IsView(pTab) ){ if( (db->flags & SQLITE_EnableView)==0 && pTab->pSchema!=db->aDb[1].pSchema ){ sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", pTab->zName); } sqlite3SrcItemAttachSubquery(pParse, pFrom, pTab->u.view.pSelect, 1); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( ALWAYS(IsVirtual(pTab)) && pFrom->fg.fromDDL && ALWAYS(pTab->u.vtab.p!=0) && pTab->u.vtab.p->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0) ){ sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", pTab->zName); } assert( SQLITE_VTABRISK_Normal==1 && SQLITE_VTABRISK_High==2 ); #endif nCol = pTab->nCol; pTab->nCol = -1; pWalker->eCode = 1; /* Turn on Select.selId renumbering */ if( pFrom->fg.isSubquery ){ sqlite3WalkSelect(pWalker, pFrom->u4.pSubq->pSelect); } pWalker->eCode = eCodeOrig; pTab->nCol = nCol; } #endif } /* Locate the index named by the INDEXED BY clause, if any. */ |
︙ | ︙ | |||
149040 149041 149042 149043 149044 149045 149046 | iErrOfst = pE->pRight->w.iOfst; }else{ assert( ExprUseWOfst(pE) ); iErrOfst = pE->w.iOfst; } for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ int nAdd; /* Number of cols including rowid */ | | | > | | | 149743 149744 149745 149746 149747 149748 149749 149750 149751 149752 149753 149754 149755 149756 149757 149758 149759 149760 149761 149762 149763 149764 149765 149766 149767 149768 149769 149770 149771 149772 | iErrOfst = pE->pRight->w.iOfst; }else{ assert( ExprUseWOfst(pE) ); iErrOfst = pE->w.iOfst; } for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ int nAdd; /* Number of cols including rowid */ Table *pTab = pFrom->pSTab; /* Table for this data source */ ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ char *zTabName; /* AS name for this data source */ const char *zSchemaName = 0; /* Schema name for this data source */ int iDb; /* Schema index for this data src */ IdList *pUsing; /* USING clause for pFrom[1] */ if( (zTabName = pFrom->zAlias)==0 ){ zTabName = pTab->zName; } if( db->mallocFailed ) break; assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom) ); if( pFrom->fg.isNestedFrom ){ assert( pFrom->fg.isSubquery && pFrom->u4.pSubq ); assert( pFrom->u4.pSubq->pSelect!=0 ); pNestedFrom = pFrom->u4.pSubq->pSelect->pEList; assert( pNestedFrom!=0 ); assert( pNestedFrom->nExpr==pTab->nCol ); assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid ); }else{ if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ continue; } |
︙ | ︙ | |||
149293 149294 149295 149296 149297 149298 149299 | if( p->selFlags & SF_HasTypeInfo ) return; p->selFlags |= SF_HasTypeInfo; pParse = pWalker->pParse; assert( (p->selFlags & SF_Resolved) ); pTabList = p->pSrc; for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ | | | | < | < | 149997 149998 149999 150000 150001 150002 150003 150004 150005 150006 150007 150008 150009 150010 150011 150012 150013 150014 150015 150016 | if( p->selFlags & SF_HasTypeInfo ) return; p->selFlags |= SF_HasTypeInfo; pParse = pWalker->pParse; assert( (p->selFlags & SF_Resolved) ); pTabList = p->pSrc; for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ Table *pTab = pFrom->pSTab; assert( pTab!=0 ); if( (pTab->tabFlags & TF_Ephemeral)!=0 && pFrom->fg.isSubquery ){ /* A sub-query in the FROM clause of a SELECT */ Select *pSel = pFrom->u4.pSubq->pSelect; sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); } } } #endif /* |
︙ | ︙ | |||
149614 149615 149616 149617 149618 149619 149620 149621 149622 149623 149624 149625 149626 149627 | static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ Vdbe *v = pParse->pVdbe; int i; struct AggInfo_func *pF; for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){ ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); pList = pF->pFExpr->x.pList; if( pF->iOBTab>=0 ){ /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs ** were stored in emphermal table pF->iOBTab. Here, we extract those ** inputs (in ORDER BY order) and make all calls to OP_AggStep ** before doing the OP_AggFinal call. */ int iTop; /* Start of loop for extracting columns */ | > | 150316 150317 150318 150319 150320 150321 150322 150323 150324 150325 150326 150327 150328 150329 150330 | static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ Vdbe *v = pParse->pVdbe; int i; struct AggInfo_func *pF; for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){ ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); if( pParse->nErr ) return; pList = pF->pFExpr->x.pList; if( pF->iOBTab>=0 ){ /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs ** were stored in emphermal table pF->iOBTab. Here, we extract those ** inputs (in ORDER BY order) and make all calls to OP_AggStep ** before doing the OP_AggFinal call. */ int iTop; /* Start of loop for extracting columns */ |
︙ | ︙ | |||
149823 149824 149825 149826 149827 149828 149829 149830 149831 149832 149833 149834 149835 149836 149837 149838 149839 149840 149841 149842 149843 149844 149845 | sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nArg); sqlite3ReleaseTempRange(pParse, regAgg, nArg); } if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } } if( regHit==0 && pAggInfo->nAccumulator ){ regHit = regAcc; } if( regHit ){ addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); } for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){ sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i)); } pAggInfo->directMode = 0; if( addrHitTest ){ sqlite3VdbeJumpHereOrPopInst(v, addrHitTest); } } | > > | 150526 150527 150528 150529 150530 150531 150532 150533 150534 150535 150536 150537 150538 150539 150540 150541 150542 150543 150544 150545 150546 150547 150548 150549 150550 | sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nArg); sqlite3ReleaseTempRange(pParse, regAgg, nArg); } if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } if( pParse->nErr ) return; } if( regHit==0 && pAggInfo->nAccumulator ){ regHit = regAcc; } if( regHit ){ addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); } for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){ sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i)); if( pParse->nErr ) return; } pAggInfo->directMode = 0; if( addrHitTest ){ sqlite3VdbeJumpHereOrPopInst(v, addrHitTest); } } |
︙ | ︙ | |||
149947 149948 149949 149950 149951 149952 149953 | */ static SrcItem *isSelfJoinView( SrcList *pTabList, /* Search for self-joins in this FROM clause */ SrcItem *pThis, /* Search for prior reference to this subquery */ int iFirst, int iEnd /* Range of FROM-clause entries to search. */ ){ SrcItem *pItem; | > | > > | | | | | | | | | 150652 150653 150654 150655 150656 150657 150658 150659 150660 150661 150662 150663 150664 150665 150666 150667 150668 150669 150670 150671 150672 150673 150674 150675 150676 150677 150678 150679 150680 150681 150682 150683 150684 150685 150686 150687 | */ static SrcItem *isSelfJoinView( SrcList *pTabList, /* Search for self-joins in this FROM clause */ SrcItem *pThis, /* Search for prior reference to this subquery */ int iFirst, int iEnd /* Range of FROM-clause entries to search. */ ){ SrcItem *pItem; Select *pSel; assert( pThis->fg.isSubquery ); pSel = pThis->u4.pSubq->pSelect; assert( pSel!=0 ); if( pSel->selFlags & SF_PushDown ) return 0; while( iFirst<iEnd ){ Select *pS1; pItem = &pTabList->a[iFirst++]; if( !pItem->fg.isSubquery ) continue; if( pItem->fg.viaCoroutine ) continue; if( pItem->zName==0 ) continue; assert( pItem->pSTab!=0 ); assert( pThis->pSTab!=0 ); if( pItem->pSTab->pSchema!=pThis->pSTab->pSchema ) continue; if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue; pS1 = pItem->u4.pSubq->pSelect; if( pItem->pSTab->pSchema==0 && pSel->selId!=pS1->selId ){ /* The query flattener left two different CTE tables with identical ** names in the same FROM clause. */ continue; } if( pS1->selFlags & SF_PushDown ){ /* The view was modified by some other optimization such as ** pushDownWhereTerms() */ continue; } return pItem; } return 0; |
︙ | ︙ | |||
150009 150010 150011 150012 150013 150014 150015 150016 150017 150018 150019 150020 150021 150022 150023 150024 150025 150026 150027 150028 150029 | ** Return TRUE if the optimization is undertaken. */ static int countOfViewOptimization(Parse *pParse, Select *p){ Select *pSub, *pPrior; Expr *pExpr; Expr *pCount; sqlite3 *db; if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ if( p->pWhere ) return 0; if( p->pHaving ) return 0; if( p->pGroupBy ) return 0; if( p->pOrderBy ) return 0; pExpr = p->pEList->a[0].pExpr; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */ assert( ExprUseUToken(pExpr) ); if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */ assert( ExprUseXList(pExpr) ); if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */ | > | | > | | < | 150717 150718 150719 150720 150721 150722 150723 150724 150725 150726 150727 150728 150729 150730 150731 150732 150733 150734 150735 150736 150737 150738 150739 150740 150741 150742 150743 150744 150745 150746 150747 150748 150749 150750 150751 150752 150753 150754 150755 150756 150757 150758 150759 150760 150761 150762 150763 150764 150765 | ** Return TRUE if the optimization is undertaken. */ static int countOfViewOptimization(Parse *pParse, Select *p){ Select *pSub, *pPrior; Expr *pExpr; Expr *pCount; sqlite3 *db; SrcItem *pFrom; if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ if( p->pWhere ) return 0; if( p->pHaving ) return 0; if( p->pGroupBy ) return 0; if( p->pOrderBy ) return 0; pExpr = p->pEList->a[0].pExpr; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */ assert( ExprUseUToken(pExpr) ); if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */ assert( ExprUseXList(pExpr) ); if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */ pFrom = p->pSrc->a; if( pFrom->fg.isSubquery==0 ) return 0; /* FROM is a subquery */ pSub = pFrom->u4.pSubq->pSelect; if( pSub->pPrior==0 ) return 0; /* Must be a compound */ if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ do{ if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */ if( pSub->pWhere ) return 0; /* No WHERE clause */ if( pSub->pLimit ) return 0; /* No LIMIT clause */ if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ assert( pSub->pHaving==0 ); /* Due to the previous */ pSub = pSub->pPrior; /* Repeat over compound */ }while( pSub ); /* If we reach this point then it is OK to perform the transformation */ db = pParse->db; pCount = pExpr; pExpr = 0; pSub = sqlite3SubqueryDetach(db, pFrom); sqlite3SrcListDelete(db, p->pSrc); p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc)); while( pSub ){ Expr *pTerm; pPrior = pSub->pPrior; pSub->pPrior = 0; pSub->pNext = 0; |
︙ | ︙ | |||
150087 150088 150089 150090 150091 150092 150093 | ** Otherwise return false. */ static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){ int i; for(i=0; i<pSrc->nSrc; i++){ SrcItem *p1 = &pSrc->a[i]; if( p1==p0 ) continue; | | | | | | 150796 150797 150798 150799 150800 150801 150802 150803 150804 150805 150806 150807 150808 150809 150810 150811 150812 150813 150814 150815 | ** Otherwise return false. */ static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){ int i; for(i=0; i<pSrc->nSrc; i++){ SrcItem *p1 = &pSrc->a[i]; if( p1==p0 ) continue; if( p0->pSTab==p1->pSTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ return 1; } if( p1->fg.isSubquery && (p1->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 && sameSrcAlias(p0, p1->u4.pSubq->pSelect->pSrc) ){ return 1; } } return 0; } |
︙ | ︙ | |||
150157 150158 150159 150160 150161 150162 150163 | } if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */ while( 1 /*exit-by-break*/ ){ if( pItem->fg.jointype & (JT_OUTER|JT_CROSS) ) return 0; /* (1c-ii) */ if( i==0 ) break; i--; pItem--; | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 150866 150867 150868 150869 150870 150871 150872 150873 150874 150875 150876 150877 150878 150879 150880 150881 150882 150883 150884 150885 150886 150887 150888 150889 150890 150891 150892 150893 150894 150895 150896 150897 150898 150899 150900 150901 150902 150903 150904 150905 150906 150907 150908 150909 150910 150911 150912 150913 150914 150915 150916 150917 150918 150919 150920 150921 150922 150923 150924 150925 150926 150927 150928 150929 150930 | } if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */ while( 1 /*exit-by-break*/ ){ if( pItem->fg.jointype & (JT_OUTER|JT_CROSS) ) return 0; /* (1c-ii) */ if( i==0 ) break; i--; pItem--; if( pItem->fg.isSubquery ) return 0; /* (1c-i) */ } return 1; } /* ** Generate byte-code for the SELECT statement given in the p argument. ** ** The results are returned according to the SelectDest structure. ** See comments in sqliteInt.h for further information. ** ** This routine returns the number of errors. If any errors are ** encountered, then an appropriate error message is left in ** pParse->zErrMsg. ** ** This routine does NOT free the Select structure passed in. The ** calling function needs to do that. ** ** This is a long function. The following is an outline of the processing ** steps, with tags referencing various milestones: ** ** * Resolve names and similar preparation tag-select-0100 ** * Scan of the FROM clause tag-select-0200 ** + OUTER JOIN strength reduction tag-select-0220 ** + Sub-query ORDER BY removal tag-select-0230 ** + Query flattening tag-select-0240 ** * Separate subroutine for compound-SELECT tag-select-0300 ** * WHERE-clause constant propagation tag-select-0330 ** * Count()-of-VIEW optimization tag-select-0350 ** * Scan of the FROM clause again tag-select-0400 ** + Authorize unreferenced tables tag-select-0410 ** + Predicate push-down optimization tag-select-0420 ** + Omit unused subquery columns optimization tag-select-0440 ** + Generate code to implement subqueries tag-select-0480 ** - Co-routines tag-select-0482 ** - Reuse previously computed CTE tag-select-0484 ** - REuse previously computed VIEW tag-select-0486 ** - Materialize a VIEW or CTE tag-select-0488 ** * DISTINCT ORDER BY -> GROUP BY optimization tag-select-0500 ** * Set up for ORDER BY tag-select-0600 ** * Create output table tag-select-0630 ** * Prepare registers for LIMIT tag-select-0650 ** * Setup for DISTINCT tag-select-0680 ** * Generate code for non-aggregate and non-GROUP BY tag-select-0700 ** * Generate code for aggregate and/or GROUP BY tag-select-0800 ** + GROUP BY queries tag-select-0810 ** + non-GROUP BY queries tag-select-0820 ** - Special case of count() w/o GROUP BY tag-select-0821 ** - General case of non-GROUP BY aggregates tag-select-0822 ** * Sort results, as needed tag-select-0900 ** * Internal self-checks tag-select-1000 */ SQLITE_PRIVATE int sqlite3Select( Parse *pParse, /* The parser context */ Select *p, /* The SELECT statement being coded. */ SelectDest *pDest /* What to do with the query results */ ){ int i, j; /* Loop counters */ |
︙ | ︙ | |||
150217 150218 150219 150220 150221 150222 150223 150224 150225 150226 150227 150228 150229 150230 | sqlite3TreeViewLine(0, "In sqlite3Select() at %s:%d", __FILE__, __LINE__); } sqlite3ShowSelect(p); } #endif assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue ); if( IgnorableDistinct(pDest) ){ assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || | > | 150960 150961 150962 150963 150964 150965 150966 150967 150968 150969 150970 150971 150972 150973 150974 | sqlite3TreeViewLine(0, "In sqlite3Select() at %s:%d", __FILE__, __LINE__); } sqlite3ShowSelect(p); } #endif /* tag-select-0100 */ assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue ); if( IgnorableDistinct(pDest) ){ assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || |
︙ | ︙ | |||
150268 150269 150270 150271 150272 150273 150274 | ** which is just confusing. To avoid this, we follow PG's lead and ** disallow it altogether. */ if( p->selFlags & SF_UFSrcCheck ){ SrcItem *p0 = &p->pSrc->a[0]; if( sameSrcAlias(p0, p->pSrc) ){ sqlite3ErrorMsg(pParse, "target object/alias may not appear in FROM clause: %s", | | | 151012 151013 151014 151015 151016 151017 151018 151019 151020 151021 151022 151023 151024 151025 151026 | ** which is just confusing. To avoid this, we follow PG's lead and ** disallow it altogether. */ if( p->selFlags & SF_UFSrcCheck ){ SrcItem *p0 = &p->pSrc->a[0]; if( sameSrcAlias(p0, p->pSrc) ){ sqlite3ErrorMsg(pParse, "target object/alias may not appear in FROM clause: %s", p0->zAlias ? p0->zAlias : p0->pSTab->zName ); goto select_end; } /* Clear the SF_UFSrcCheck flag. The check has already been performed, ** and leaving this flag set can cause errors if a compound sub-query ** in p->pSrc is flattened into this query and this function called |
︙ | ︙ | |||
150303 150304 150305 150306 150307 150308 150309 150310 150311 150312 150313 | pTabList = p->pSrc; isAgg = (p->selFlags & SF_Aggregate)!=0; memset(&sSort, 0, sizeof(sSort)); sSort.pOrderBy = p->pOrderBy; /* Try to do various optimizations (flattening subqueries, and strength ** reduction of join operators) in the FROM clause up into the main query */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ SrcItem *pItem = &pTabList->a[i]; | > | | > | 151047 151048 151049 151050 151051 151052 151053 151054 151055 151056 151057 151058 151059 151060 151061 151062 151063 151064 151065 151066 151067 151068 151069 151070 151071 151072 151073 151074 151075 151076 151077 151078 151079 151080 151081 151082 151083 151084 | pTabList = p->pSrc; isAgg = (p->selFlags & SF_Aggregate)!=0; memset(&sSort, 0, sizeof(sSort)); sSort.pOrderBy = p->pOrderBy; /* Try to do various optimizations (flattening subqueries, and strength ** reduction of join operators) in the FROM clause up into the main query ** tag-select-0200 */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ SrcItem *pItem = &pTabList->a[i]; Select *pSub = pItem->fg.isSubquery ? pItem->u4.pSubq->pSelect : 0; Table *pTab = pItem->pSTab; /* The expander should have already created transient Table objects ** even for FROM clause elements such as subqueries that do not correspond ** to a real table */ assert( pTab!=0 ); /* Try to simplify joins: ** ** LEFT JOIN -> JOIN ** RIGHT JOIN -> JOIN ** FULL JOIN -> RIGHT JOIN ** ** If terms of the i-th table are used in the WHERE clause in such a ** way that the i-th table cannot be the NULL row of a join, then ** perform the appropriate simplification. This is called ** "OUTER JOIN strength reduction" in the SQLite documentation. ** tag-select-0220 */ if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor, pItem->fg.jointype & JT_LTORJ) && OptimizationEnabled(db, SQLITE_SimplifyJoin) ){ if( pItem->fg.jointype & JT_LEFT ){ |
︙ | ︙ | |||
150395 150396 150397 150398 150399 150400 150401 | ** is not a join. But if the outer query is not a join, then the subquery ** will be implemented as a co-routine and there is no advantage to ** flattening in that case. */ if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; assert( pSub->pGroupBy==0 ); | > | > > > | | 151141 151142 151143 151144 151145 151146 151147 151148 151149 151150 151151 151152 151153 151154 151155 151156 151157 151158 151159 151160 151161 151162 151163 151164 151165 151166 151167 151168 151169 151170 151171 151172 151173 151174 151175 151176 151177 151178 151179 151180 151181 151182 151183 151184 | ** is not a join. But if the outer query is not a join, then the subquery ** will be implemented as a co-routine and there is no advantage to ** flattening in that case. */ if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; assert( pSub->pGroupBy==0 ); /* tag-select-0230: ** If a FROM-clause subquery has an ORDER BY clause that is not ** really doing anything, then delete it now so that it does not ** interfere with query flattening. See the discussion at ** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a ** ** Beware of these cases where the ORDER BY clause may not be safely ** omitted: ** ** (1) There is also a LIMIT clause ** (2) The subquery was added to help with window-function ** processing ** (3) The subquery is in the FROM clause of an UPDATE ** (4) The outer query uses an aggregate function other than ** the built-in count(), min(), or max(). ** (5) The ORDER BY isn't going to accomplish anything because ** one of: ** (a) The outer query has a different ORDER BY clause ** (b) The subquery is part of a join ** See forum post 062d576715d277c8 ** (6) The subquery is not a recursive CTE. ORDER BY has a different ** meaning for recursive CTEs and this optimization does not ** apply. ** ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled. */ if( pSub->pOrderBy!=0 && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ && pSub->pLimit==0 /* Condition (1) */ && (pSub->selFlags & (SF_OrderByReqd|SF_Recursive))==0 /* (2) and (6) */ && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ && OptimizationEnabled(db, SQLITE_OmitOrderBy) ){ TREETRACE(0x800,pParse,p, ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pSub->pOrderBy); |
︙ | ︙ | |||
150458 150459 150460 150461 150462 150463 150464 150465 150466 150467 150468 150469 150470 150471 150472 150473 150474 150475 150476 150477 150478 150479 | && (p->selFlags & SF_ComplexResult)!=0 && (pTabList->nSrc==1 || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0) ){ continue; } if( flattenSubquery(pParse, p, i, isAgg) ){ if( pParse->nErr ) goto select_end; /* This subquery can be absorbed into its parent. */ i = -1; } pTabList = p->pSrc; if( db->mallocFailed ) goto select_end; if( !IgnorableOrderby(pDest) ){ sSort.pOrderBy = p->pOrderBy; } } #endif #ifndef SQLITE_OMIT_COMPOUND_SELECT /* Handle compound SELECT statements using the separate multiSelect() | > | | | > | > | | > > > > > | > > > > > > > > > | > | | > | > | > | | | | | | | | | > | | | > > > > | | > | | | | | | | | | 151208 151209 151210 151211 151212 151213 151214 151215 151216 151217 151218 151219 151220 151221 151222 151223 151224 151225 151226 151227 151228 151229 151230 151231 151232 151233 151234 151235 151236 151237 151238 151239 151240 151241 151242 151243 151244 151245 151246 151247 151248 151249 151250 151251 151252 151253 151254 151255 151256 151257 151258 151259 151260 151261 151262 151263 151264 151265 151266 151267 151268 151269 151270 151271 151272 151273 151274 151275 151276 151277 151278 151279 151280 151281 151282 151283 151284 151285 151286 151287 151288 151289 151290 151291 151292 151293 151294 151295 151296 151297 151298 151299 151300 151301 151302 151303 151304 151305 151306 151307 151308 151309 151310 151311 151312 151313 151314 151315 151316 151317 151318 151319 151320 151321 151322 151323 151324 151325 151326 151327 151328 151329 151330 151331 151332 151333 151334 151335 151336 151337 151338 151339 151340 151341 151342 151343 151344 151345 151346 151347 151348 151349 151350 151351 151352 151353 151354 151355 151356 151357 151358 151359 151360 151361 151362 151363 151364 151365 151366 151367 151368 151369 151370 151371 151372 151373 151374 151375 151376 151377 151378 151379 151380 151381 151382 151383 151384 151385 151386 151387 151388 151389 151390 151391 151392 151393 151394 151395 151396 151397 151398 151399 151400 151401 151402 151403 151404 151405 151406 151407 151408 151409 151410 151411 151412 151413 151414 151415 151416 151417 151418 151419 151420 151421 151422 151423 151424 151425 151426 151427 151428 151429 151430 151431 151432 151433 151434 151435 151436 151437 151438 151439 151440 151441 151442 151443 151444 151445 151446 151447 151448 151449 151450 151451 151452 151453 151454 151455 151456 151457 151458 151459 151460 151461 151462 151463 151464 151465 151466 151467 151468 151469 151470 151471 151472 151473 151474 | && (p->selFlags & SF_ComplexResult)!=0 && (pTabList->nSrc==1 || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0) ){ continue; } /* tag-select-0240 */ if( flattenSubquery(pParse, p, i, isAgg) ){ if( pParse->nErr ) goto select_end; /* This subquery can be absorbed into its parent. */ i = -1; } pTabList = p->pSrc; if( db->mallocFailed ) goto select_end; if( !IgnorableOrderby(pDest) ){ sSort.pOrderBy = p->pOrderBy; } } #endif #ifndef SQLITE_OMIT_COMPOUND_SELECT /* Handle compound SELECT statements using the separate multiSelect() ** procedure. tag-select-0300 */ if( p->pPrior ){ rc = multiSelect(pParse, p, pDest); #if TREETRACE_ENABLED TREETRACE(0x400,pParse,p,("end compound-select processing\n")); if( (sqlite3TreeTrace & 0x400)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif if( p->pNext==0 ) ExplainQueryPlanPop(pParse); return rc; } #endif /* Do the WHERE-clause constant propagation optimization if this is ** a join. No need to spend time on this operation for non-join queries ** as the equivalent optimization will be handled by query planner in ** sqlite3WhereBegin(). tag-select-0330 */ if( p->pWhere!=0 && p->pWhere->op==TK_AND && OptimizationEnabled(db, SQLITE_PropagateConst) && propagateConstants(pParse, p) ){ #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x2000 ){ TREETRACE(0x2000,pParse,p,("After constant propagation:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif }else{ TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n")); } /* tag-select-0350 */ if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) && countOfViewOptimization(pParse, p) ){ if( db->mallocFailed ) goto select_end; pTabList = p->pSrc; } /* Loop over all terms in the FROM clause and do two things for each term: ** ** (1) Authorize unreferenced tables ** (2) Generate code for all sub-queries ** ** tag-select-0400 */ for(i=0; i<pTabList->nSrc; i++){ SrcItem *pItem = &pTabList->a[i]; SrcItem *pPrior; SelectDest dest; Subquery *pSubq; Select *pSub; #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) const char *zSavedAuthContext; #endif /* Authorized unreferenced tables. tag-select-0410 ** ** Issue SQLITE_READ authorizations with a fake column name for any ** tables that are referenced but from which no values are extracted. ** Examples of where these kinds of null SQLITE_READ authorizations ** would occur: ** ** SELECT count(*) FROM t1; -- SQLITE_READ t1."" ** SELECT t1.* FROM t1, t2; -- SQLITE_READ t2."" ** ** The fake column name is an empty string. It is possible for a table to ** have a column named by the empty string, in which case there is no way to ** distinguish between an unreferenced table and an actual reference to the ** "" column. The original design was for the fake column name to be a NULL, ** which would be unambiguous. But legacy authorization callbacks might ** assume the column name is non-NULL and segfault. The use of an empty ** string for the fake column name seems safer. */ if( pItem->colUsed==0 && pItem->zName!=0 ){ const char *zDb; if( pItem->fg.fixedSchema ){ int iDb = sqlite3SchemaToIndex(pParse->db, pItem->u4.pSchema); zDb = db->aDb[iDb].zDbSName; }else if( pItem->fg.isSubquery ){ zDb = 0; }else{ zDb = pItem->u4.zDatabase; } sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", zDb); } #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* Generate code for all sub-queries in the FROM clause */ if( pItem->fg.isSubquery==0 ) continue; pSubq = pItem->u4.pSubq; assert( pSubq!=0 ); pSub = pSubq->pSelect; /* The code for a subquery should only be generated once. */ if( pSubq->addrFillSub!=0 ) continue; /* Increment Parse.nHeight by the height of the largest expression ** tree referred to by this, the parent select. The child select ** may contain expression trees of at most ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit ** more conservative than necessary, but much easier than enforcing ** an exact limit. */ pParse->nHeight += sqlite3SelectExprHeight(p); /* Make copies of constant WHERE-clause terms in the outer query down ** inside the subquery. This can help the subquery to run more efficiently. ** This is the "predicate push-down optimization". tag-select-0420 */ if( OptimizationEnabled(db, SQLITE_PushDown) && (pItem->fg.isCte==0 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) && pushDownWhereTerms(pParse, pSub, p->pWhere, pTabList, i) ){ #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x4000 ){ TREETRACE(0x4000,pParse,p, ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); sqlite3TreeViewSelect(0, p, 0); } #endif assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 ); }else{ TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n")); } /* Convert unused result columns of the subquery into simple NULL ** expressions, to avoid unneeded searching and computation. ** tag-select-0440 */ if( OptimizationEnabled(db, SQLITE_NullUnusedCols) && disableUnusedSubqueryResultColumns(pItem) ){ #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x4000 ){ TREETRACE(0x4000,pParse,p, ("Change unused result columns to NULL for subquery %d:\n", pSub->selId)); sqlite3TreeViewSelect(0, p, 0); } #endif } zSavedAuthContext = pParse->zAuthContext; pParse->zAuthContext = pItem->zName; /* Generate byte-code to implement the subquery tag-select-0480 */ if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. tag-select-0482 */ int addrTop = sqlite3VdbeCurrentAddr(v)+1; pSubq->regReturn = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_InitCoroutine, pSubq->regReturn, 0, addrTop); VdbeComment((v, "%!S", pItem)); pSubq->addrFillSub = addrTop; sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn); ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem)); sqlite3Select(pParse, pSub, &dest); pItem->pSTab->nRowLogEst = pSub->nSelectRow; pItem->fg.viaCoroutine = 1; pSubq->regResult = dest.iSdst; sqlite3VdbeEndCoroutine(v, pSubq->regReturn); VdbeComment((v, "end %!S", pItem)); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ /* This is a CTE for which materialization code has already been ** generated. Invoke the subroutine to compute the materialization, ** then make the pItem->iCursor be a copy of the ephemeral table that ** holds the result of the materialization. tag-select-0484 */ CteUse *pCteUse = pItem->u2.pCteUse; sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); if( pItem->iCursor!=pCteUse->iCur ){ sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur); VdbeComment((v, "%!S", pItem)); } pSub->nSelectRow = pCteUse->nRowEst; }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){ /* This view has already been materialized by a prior entry in ** this same FROM clause. Reuse it. tag-select-0486 */ Subquery *pPriorSubq; assert( pPrior->fg.isSubquery ); pPriorSubq = pPrior->u4.pSubq; assert( pPriorSubq!=0 ); if( pPriorSubq->addrFillSub ){ sqlite3VdbeAddOp2(v, OP_Gosub, pPriorSubq->regReturn, pPriorSubq->addrFillSub); } sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); pSub->nSelectRow = pPriorSubq->pSelect->nSelectRow; }else{ /* Materialize the view. If the view is not correlated, generate a ** subroutine to do the materialization so that subsequent uses of ** the same view can reuse the materialization. tag-select-0488 */ int topAddr; int onceAddr = 0; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS int addrExplain; #endif pSubq->regReturn = ++pParse->nMem; topAddr = sqlite3VdbeAddOp0(v, OP_Goto); pSubq->addrFillSub = topAddr+1; pItem->fg.isMaterialized = 1; if( pItem->fg.isCorrelated==0 ){ /* If the subquery is not correlated and if we are not inside of ** a trigger, then we only need to compute the value of the subquery ** once. */ onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); VdbeComment((v, "materialize %!S", pItem)); }else{ VdbeNoopComment((v, "materialize %!S", pItem)); } sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem)); sqlite3Select(pParse, pSub, &dest); pItem->pSTab->nRowLogEst = pSub->nSelectRow; if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); sqlite3VdbeAddOp2(v, OP_Return, pSubq->regReturn, topAddr+1); VdbeComment((v, "end %!S", pItem)); sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); sqlite3VdbeJumpHere(v, topAddr); sqlite3ClearTempRegCache(pParse); if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ CteUse *pCteUse = pItem->u2.pCteUse; pCteUse->addrM9e = pSubq->addrFillSub; pCteUse->regRtn = pSubq->regReturn; pCteUse->iCur = pItem->iCursor; pCteUse->nRowEst = pSub->nSelectRow; } } if( db->mallocFailed ) goto select_end; pParse->nHeight -= sqlite3SelectExprHeight(p); pParse->zAuthContext = zSavedAuthContext; |
︙ | ︙ | |||
150709 150710 150711 150712 150713 150714 150715 | #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x8000 ){ TREETRACE(0x8000,pParse,p,("After all FROM-clause analysis:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif | > > | > > > > > > | 151486 151487 151488 151489 151490 151491 151492 151493 151494 151495 151496 151497 151498 151499 151500 151501 151502 151503 151504 151505 151506 151507 151508 151509 151510 151511 151512 151513 151514 151515 151516 151517 151518 151519 151520 151521 151522 151523 151524 151525 151526 151527 151528 151529 151530 | #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x8000 ){ TREETRACE(0x8000,pParse,p,("After all FROM-clause analysis:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif /* tag-select-0500 ** ** If the query is DISTINCT with an ORDER BY but is not an aggregate, and ** if the select-list is the same as the ORDER BY list, then this query ** can be rewritten as a GROUP BY. In other words, this: ** ** SELECT DISTINCT xyz FROM ... ORDER BY xyz ** ** is transformed to: ** ** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz ** ** The second form is preferred as a single index (or temp-table) may be ** used for both the ORDER BY and DISTINCT processing. As originally ** written the query must use a temp-table for at least one of the ORDER ** BY and DISTINCT, and an index or separate temp-table for the other. */ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 && OptimizationEnabled(db, SQLITE_GroupByOrder) #ifndef SQLITE_OMIT_WINDOWFUNC && p->pWin==0 #endif ){ p->selFlags &= ~SF_Distinct; pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); if( pGroupBy ){ for(i=0; i<pGroupBy->nExpr; i++){ pGroupBy->a[i].u.x.iOrderByCol = i+1; } } p->selFlags |= SF_Aggregate; /* Notice that even thought SF_Distinct has been cleared from p->selFlags, ** the sDistinct.isTnct is still set. Hence, isTnct represents the ** original setting of the SF_Distinct flag, not the current setting */ assert( sDistinct.isTnct ); sDistinct.isTnct = 2; |
︙ | ︙ | |||
150753 150754 150755 150756 150757 150758 150759 | /* If there is an ORDER BY clause, then create an ephemeral index to ** do the sorting. But this sorting ephemeral index might end up ** being unused if the data can be extracted in pre-sorted order. ** If that is the case, then the OP_OpenEphemeral instruction will be ** changed to an OP_Noop once we figure out that the sorting index is ** not needed. The sSort.addrSortIndex variable is used to facilitate | | > | | | | 151538 151539 151540 151541 151542 151543 151544 151545 151546 151547 151548 151549 151550 151551 151552 151553 151554 151555 151556 151557 151558 151559 151560 151561 151562 151563 151564 151565 151566 151567 151568 151569 151570 151571 151572 151573 151574 151575 151576 151577 151578 151579 151580 151581 151582 151583 151584 151585 151586 151587 151588 151589 151590 151591 151592 151593 151594 151595 151596 151597 151598 151599 151600 151601 151602 151603 151604 151605 151606 151607 151608 151609 151610 151611 151612 151613 151614 | /* If there is an ORDER BY clause, then create an ephemeral index to ** do the sorting. But this sorting ephemeral index might end up ** being unused if the data can be extracted in pre-sorted order. ** If that is the case, then the OP_OpenEphemeral instruction will be ** changed to an OP_Noop once we figure out that the sorting index is ** not needed. The sSort.addrSortIndex variable is used to facilitate ** that change. tag-select-0600 */ if( sSort.pOrderBy ){ KeyInfo *pKeyInfo; pKeyInfo = sqlite3KeyInfoFromExprList( pParse, sSort.pOrderBy, 0, pEList->nExpr); sSort.iECursor = pParse->nTab++; sSort.addrSortIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, sSort.iECursor, sSort.pOrderBy->nExpr+1+pEList->nExpr, 0, (char*)pKeyInfo, P4_KEYINFO ); }else{ sSort.addrSortIndex = -1; } /* If the output is destined for a temporary table, open that table. ** tag-select-0630 */ if( pDest->eDest==SRT_EphemTab ){ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); if( p->selFlags & SF_NestedFrom ){ /* Delete or NULL-out result columns that will never be used */ int ii; for(ii=pEList->nExpr-1; ii>0 && pEList->a[ii].fg.bUsed==0; ii--){ sqlite3ExprDelete(db, pEList->a[ii].pExpr); sqlite3DbFree(db, pEList->a[ii].zEName); pEList->nExpr--; } for(ii=0; ii<pEList->nExpr; ii++){ if( pEList->a[ii].fg.bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL; } } } /* Set the limiter. tag-select-0650 */ iEnd = sqlite3VdbeMakeLabel(pParse); if( (p->selFlags & SF_FixedLimit)==0 ){ p->nSelectRow = 320; /* 4 billion rows */ } if( p->pLimit ) computeLimitRegisters(pParse, p, iEnd); if( p->iLimit==0 && sSort.addrSortIndex>=0 ){ sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen); sSort.sortFlags |= SORTFLAG_UseSorter; } /* Open an ephemeral index to use for the distinct set. tag-select-0680 */ if( p->selFlags & SF_Distinct ){ sDistinct.tabTnct = pParse->nTab++; sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, sDistinct.tabTnct, 0, 0, (char*)sqlite3KeyInfoFromExprList(pParse, p->pEList,0,0), P4_KEYINFO); sqlite3VdbeChangeP5(v, BTREE_UNORDERED); sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; }else{ sDistinct.eTnctType = WHERE_DISTINCT_NOOP; } if( !isAgg && pGroupBy==0 ){ /* No aggregate functions and no GROUP BY clause. tag-select-0700 */ u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0) | (p->selFlags & SF_FixedLimit); #ifndef SQLITE_OMIT_WINDOWFUNC Window *pWin = p->pWin; /* Main window object (or NULL) */ if( pWin ){ sqlite3WindowCodeInit(pParse, p); } |
︙ | ︙ | |||
150887 150888 150889 150890 150891 150892 150893 | /* End the database scan loop. */ TREETRACE(0x2,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); } }else{ | | | | 151673 151674 151675 151676 151677 151678 151679 151680 151681 151682 151683 151684 151685 151686 151687 151688 | /* End the database scan loop. */ TREETRACE(0x2,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); } }else{ /* This case is for when there exist aggregate functions or a GROUP BY ** clause or both. tag-select-0800 */ NameContext sNC; /* Name context for processing aggregate information */ int iAMem; /* First Mem address for storing current GROUP BY */ int iBMem; /* First Mem address for previous GROUP BY */ int iUseFlag; /* Mem address holding flag indicating that at least ** one row of the input to the aggregator has been ** processed */ int iAbortFlag; /* Mem address which causes query abort if positive */ |
︙ | ︙ | |||
151007 151008 151009 151010 151011 151012 151013 | } printAggInfo(pAggInfo); } #endif /* Processing for aggregates with GROUP BY is very different and | | | 151793 151794 151795 151796 151797 151798 151799 151800 151801 151802 151803 151804 151805 151806 151807 | } printAggInfo(pAggInfo); } #endif /* Processing for aggregates with GROUP BY is very different and ** much more complex than aggregates without a GROUP BY. tag-select-0810 */ if( pGroupBy ){ KeyInfo *pKeyInfo; /* Keying information for the group by clause */ int addr1; /* A-vs-B comparison jump */ int addrOutputRow; /* Start of subroutine that outputs a result row */ int regOutputRow; /* Return address register for output subroutine */ int addrSetAbort; /* Set the abort flag and return */ |
︙ | ︙ | |||
151194 151195 151196 151197 151198 151199 151200 151201 151202 151203 151204 151205 151206 151207 151208 151209 151210 151211 151212 151213 151214 151215 151216 151217 151218 151219 151220 151221 | */ addrTopOfLoop = sqlite3VdbeCurrentAddr(v); if( groupBySort ){ sqlite3VdbeAddOp3(v, OP_SorterData, pAggInfo->sortingIdx, sortOut, sortPTab); } for(j=0; j<pGroupBy->nExpr; j++){ if( groupBySort ){ sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); }else{ pAggInfo->directMode = 1; sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); } } sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); addr1 = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v); /* Generate code that runs whenever the GROUP BY changes. ** Changes in the GROUP BY are detected by the previous code ** block. If there were no changes, this block is skipped. ** ** This code copies current group by terms in b0,b1,b2,... ** over to a0,a1,a2. It then calls the output subroutine ** and resets the aggregate accumulator registers in preparation ** for the next GROUP BY batch. */ | > > > > > > > > > > > > > < > | 151980 151981 151982 151983 151984 151985 151986 151987 151988 151989 151990 151991 151992 151993 151994 151995 151996 151997 151998 151999 152000 152001 152002 152003 152004 152005 152006 152007 152008 152009 152010 152011 152012 152013 152014 152015 152016 152017 152018 152019 152020 152021 152022 152023 152024 152025 152026 152027 152028 152029 152030 | */ addrTopOfLoop = sqlite3VdbeCurrentAddr(v); if( groupBySort ){ sqlite3VdbeAddOp3(v, OP_SorterData, pAggInfo->sortingIdx, sortOut, sortPTab); } for(j=0; j<pGroupBy->nExpr; j++){ int iOrderByCol = pGroupBy->a[j].u.x.iOrderByCol; if( groupBySort ){ sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); }else{ pAggInfo->directMode = 1; sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); } if( iOrderByCol ){ Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); if( ALWAYS(pBase!=0) && pBase->op!=TK_AGG_COLUMN && pBase->op!=TK_REGISTER ){ sqlite3ExprToRegister(pX, iAMem+j); } } } sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); addr1 = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v); /* Generate code that runs whenever the GROUP BY changes. ** Changes in the GROUP BY are detected by the previous code ** block. If there were no changes, this block is skipped. ** ** This code copies current group by terms in b0,b1,b2,... ** over to a0,a1,a2. It then calls the output subroutine ** and resets the aggregate accumulator registers in preparation ** for the next GROUP BY batch. */ sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); VdbeComment((v, "output one row")); sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); VdbeComment((v, "check abort flag")); sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); VdbeComment((v, "reset accumulator")); /* Update the aggregate accumulators based on the content of ** the current row |
︙ | ︙ | |||
151291 151292 151293 151294 151295 151296 151297 151298 151299 | if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){ struct AggInfo_func *pF = &pAggInfo->aFunc[0]; fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); } } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ else { Table *pTab; if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){ | > > > | | 152090 152091 152092 152093 152094 152095 152096 152097 152098 152099 152100 152101 152102 152103 152104 152105 152106 152107 152108 152109 | if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){ struct AggInfo_func *pF = &pAggInfo->aFunc[0]; fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); } } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ else { /* Aggregate functions without GROUP BY. tag-select-0820 */ Table *pTab; if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){ /* tag-select-0821 ** ** If isSimpleCount() returns a pointer to a Table structure, then ** the SQL statement is of the form: ** ** SELECT count(*) FROM <tbl> ** ** where the Table structure returned represents table <tbl>. ** ** This statement is so common that it is optimized specially. The |
︙ | ︙ | |||
151352 151353 151354 151355 151356 151357 151358 151359 151360 151361 151362 151363 151364 151365 | sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); } assignAggregateRegisters(pParse, pAggInfo); sqlite3VdbeAddOp2(v, OP_Count, iCsr, AggInfoFuncReg(pAggInfo,0)); sqlite3VdbeAddOp1(v, OP_Close, iCsr); explainSimpleCount(pParse, pTab, pBest); }else{ int regAcc = 0; /* "populate accumulators" flag */ ExprList *pDistinct = 0; u16 distFlag = 0; int eDist; /* If there are accumulator registers but no min() or max() functions ** without FILTER clauses, allocate register regAcc. Register regAcc | > > | 152154 152155 152156 152157 152158 152159 152160 152161 152162 152163 152164 152165 152166 152167 152168 152169 | sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); } assignAggregateRegisters(pParse, pAggInfo); sqlite3VdbeAddOp2(v, OP_Count, iCsr, AggInfoFuncReg(pAggInfo,0)); sqlite3VdbeAddOp1(v, OP_Close, iCsr); explainSimpleCount(pParse, pTab, pBest); }else{ /* The general case of an aggregate query without GROUP BY ** tag-select-0822 */ int regAcc = 0; /* "populate accumulators" flag */ ExprList *pDistinct = 0; u16 distFlag = 0; int eDist; /* If there are accumulator registers but no min() or max() functions ** without FILTER clauses, allocate register regAcc. Register regAcc |
︙ | ︙ | |||
151440 151441 151442 151443 151444 151445 151446 | } /* endif aggregate query */ if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){ explainTempTable(pParse, "DISTINCT"); } /* If there is an ORDER BY clause, then we need to sort the results | | | 152244 152245 152246 152247 152248 152249 152250 152251 152252 152253 152254 152255 152256 152257 152258 | } /* endif aggregate query */ if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){ explainTempTable(pParse, "DISTINCT"); } /* If there is an ORDER BY clause, then we need to sort the results ** and send them to the callback one by one. tag-select-0900 */ if( sSort.pOrderBy ){ assert( p->pEList==pEList ); generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); } /* Jump here to skip this query |
︙ | ︙ | |||
151463 151464 151465 151466 151467 151468 151469 151470 151471 151472 151473 151474 151475 151476 | ** successful coding of the SELECT. */ select_end: assert( db->mallocFailed==0 || db->mallocFailed==1 ); assert( db->mallocFailed==0 || pParse->nErr!=0 ); sqlite3ExprListDelete(db, pMinMaxOrderBy); #ifdef SQLITE_DEBUG if( pAggInfo && !db->mallocFailed ){ #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x20 ){ TREETRACE(0x20,pParse,p,("Finished with AggInfo\n")); printAggInfo(pAggInfo); } #endif | > | 152267 152268 152269 152270 152271 152272 152273 152274 152275 152276 152277 152278 152279 152280 152281 | ** successful coding of the SELECT. */ select_end: assert( db->mallocFailed==0 || db->mallocFailed==1 ); assert( db->mallocFailed==0 || pParse->nErr!=0 ); sqlite3ExprListDelete(db, pMinMaxOrderBy); #ifdef SQLITE_DEBUG /* Internal self-checks. tag-select-1000 */ if( pAggInfo && !db->mallocFailed ){ #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x20 ){ TREETRACE(0x20,pParse,p,("Finished with AggInfo\n")); printAggInfo(pAggInfo); } #endif |
︙ | ︙ | |||
151852 151853 151854 151855 151856 151857 151858 | ** CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab .... ** ^^^^^^^^ ** ** To maintain backwards compatibility, ignore the database ** name on pTableName if we are reparsing out of the schema table */ if( db->init.busy && iDb!=1 ){ | > > | | | 152657 152658 152659 152660 152661 152662 152663 152664 152665 152666 152667 152668 152669 152670 152671 152672 152673 152674 | ** CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab .... ** ^^^^^^^^ ** ** To maintain backwards compatibility, ignore the database ** name on pTableName if we are reparsing out of the schema table */ if( db->init.busy && iDb!=1 ){ assert( pTableName->a[0].fg.fixedSchema==0 ); assert( pTableName->a[0].fg.isSubquery==0 ); sqlite3DbFree(db, pTableName->a[0].u4.zDatabase); pTableName->a[0].u4.zDatabase = 0; } /* If the trigger name was unqualified, and the table is a temp table, ** then set iDb to 1 to create the trigger in the temporary database. ** If sqlite3SrcListLookup() returns 0, indicating the table does not ** exist, the error is caught by the block below. */ |
︙ | ︙ | |||
152331 152332 152333 152334 152335 152336 152337 | if( db->mallocFailed ) goto drop_trigger_cleanup; if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto drop_trigger_cleanup; } assert( pName->nSrc==1 ); | > | | 153138 153139 153140 153141 153142 153143 153144 153145 153146 153147 153148 153149 153150 153151 153152 153153 | if( db->mallocFailed ) goto drop_trigger_cleanup; if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto drop_trigger_cleanup; } assert( pName->nSrc==1 ); assert( pName->a[0].fg.fixedSchema==0 && pName->a[0].fg.isSubquery==0 ); zDb = pName->a[0].u4.zDatabase; zName = pName->a[0].zName; assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); for(i=OMIT_TEMPDB; i<db->nDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue; assert( sqlite3SchemaMutexHeld(db, j, 0) ); pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName); |
︙ | ︙ | |||
152568 152569 152570 152571 152572 152573 152574 | pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); assert( pSrc==0 || pSrc->nSrc==1 ); assert( zName || pSrc==0 ); if( pSrc ){ Schema *pSchema = pStep->pTrig->pSchema; pSrc->a[0].zName = zName; if( pSchema!=db->aDb[1].pSchema ){ | > | > | 153376 153377 153378 153379 153380 153381 153382 153383 153384 153385 153386 153387 153388 153389 153390 153391 153392 | pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); assert( pSrc==0 || pSrc->nSrc==1 ); assert( zName || pSrc==0 ); if( pSrc ){ Schema *pSchema = pStep->pTrig->pSchema; pSrc->a[0].zName = zName; if( pSchema!=db->aDb[1].pSchema ){ assert( pSrc->a[0].fg.fixedSchema || pSrc->a[0].u4.zDatabase==0 ); pSrc->a[0].u4.pSchema = pSchema; pSrc->a[0].fg.fixedSchema = 1; } if( pStep->pFrom ){ SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0); if( pDup && pDup->nSrc>1 && !IN_RENAME_OBJECT ){ Select *pSubquery; Token as; pSubquery = sqlite3SelectNew(pParse,0,pDup,0,0,0,0,SF_NestedFrom,0); |
︙ | ︙ | |||
152681 152682 152683 152684 152685 152686 152687 | static int sqlite3ReturningSubqueryCorrelated(Walker *pWalker, Select *pSelect){ int i; SrcList *pSrc; assert( pSelect!=0 ); pSrc = pSelect->pSrc; assert( pSrc!=0 ); for(i=0; i<pSrc->nSrc; i++){ | | | 153491 153492 153493 153494 153495 153496 153497 153498 153499 153500 153501 153502 153503 153504 153505 | static int sqlite3ReturningSubqueryCorrelated(Walker *pWalker, Select *pSelect){ int i; SrcList *pSrc; assert( pSelect!=0 ); pSrc = pSelect->pSrc; assert( pSrc!=0 ); for(i=0; i<pSrc->nSrc; i++){ if( pSrc->a[i].pSTab==pWalker->u.pTab ){ testcase( pSelect->selFlags & SF_Correlated ); pSelect->selFlags |= SF_Correlated; pWalker->eCode = 1; break; } } return WRC_Continue; |
︙ | ︙ | |||
152752 152753 152754 152755 152756 152757 152758 | return; } memset(&sSelect, 0, sizeof(sSelect)); memset(&sFrom, 0, sizeof(sFrom)); sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); sSelect.pSrc = &sFrom; sFrom.nSrc = 1; | | | 153562 153563 153564 153565 153566 153567 153568 153569 153570 153571 153572 153573 153574 153575 153576 | return; } memset(&sSelect, 0, sizeof(sSelect)); memset(&sFrom, 0, sizeof(sFrom)); sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); sSelect.pSrc = &sFrom; sFrom.nSrc = 1; sFrom.a[0].pSTab = pTab; sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */ sFrom.a[0].iCursor = -1; sqlite3SelectPrep(pParse, &sSelect, 0); if( pParse->nErr==0 ){ assert( db->mallocFailed==0 ); sqlite3GenerateColumnNames(pParse, &sSelect); } |
︙ | ︙ | |||
153463 153464 153465 153466 153467 153468 153469 | SelectDest dest; Select *pSelect = 0; ExprList *pList = 0; ExprList *pGrp = 0; Expr *pLimit2 = 0; ExprList *pOrderBy2 = 0; sqlite3 *db = pParse->db; | | | 154273 154274 154275 154276 154277 154278 154279 154280 154281 154282 154283 154284 154285 154286 154287 | SelectDest dest; Select *pSelect = 0; ExprList *pList = 0; ExprList *pGrp = 0; Expr *pLimit2 = 0; ExprList *pOrderBy2 = 0; sqlite3 *db = pParse->db; Table *pTab = pTabList->a[0].pSTab; SrcList *pSrc; Expr *pWhere2; int eDest; #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT if( pOrderBy && pLimit==0 ) { sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on UPDATE"); |
︙ | ︙ | |||
153487 153488 153489 153490 153491 153492 153493 | pSrc = sqlite3SrcListDup(db, pTabList, 0); pWhere2 = sqlite3ExprDup(db, pWhere, 0); assert( pTabList->nSrc>1 ); if( pSrc ){ assert( pSrc->a[0].fg.notCte ); pSrc->a[0].iCursor = -1; | | | | 154297 154298 154299 154300 154301 154302 154303 154304 154305 154306 154307 154308 154309 154310 154311 154312 | pSrc = sqlite3SrcListDup(db, pTabList, 0); pWhere2 = sqlite3ExprDup(db, pWhere, 0); assert( pTabList->nSrc>1 ); if( pSrc ){ assert( pSrc->a[0].fg.notCte ); pSrc->a[0].iCursor = -1; pSrc->a[0].pSTab->nTabRef--; pSrc->a[0].pSTab = 0; } if( pPk ){ for(i=0; i<pPk->nKeyCol; i++){ Expr *pNew = exprRowColumn(pParse, pPk->aiColumn[i]); #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT if( pLimit ){ pGrp = sqlite3ExprListAppend(pParse, pGrp, sqlite3ExprDup(db, pNew, 0)); |
︙ | ︙ | |||
154736 154737 154738 154739 154740 154741 154742 | ExprList *pTarget; /* The conflict-target clause */ Expr *pTerm; /* One term of the conflict-target clause */ NameContext sNC; /* Context for resolving symbolic names */ Expr sCol[2]; /* Index column converted into an Expr */ int nClause = 0; /* Counter of ON CONFLICT clauses */ assert( pTabList->nSrc==1 ); | | | | 155546 155547 155548 155549 155550 155551 155552 155553 155554 155555 155556 155557 155558 155559 155560 155561 155562 155563 155564 155565 155566 155567 155568 155569 155570 155571 155572 155573 155574 155575 155576 155577 155578 155579 | ExprList *pTarget; /* The conflict-target clause */ Expr *pTerm; /* One term of the conflict-target clause */ NameContext sNC; /* Context for resolving symbolic names */ Expr sCol[2]; /* Index column converted into an Expr */ int nClause = 0; /* Counter of ON CONFLICT clauses */ assert( pTabList->nSrc==1 ); assert( pTabList->a[0].pSTab!=0 ); assert( pUpsert!=0 ); assert( pUpsert->pUpsertTarget!=0 ); /* Resolve all symbolic names in the conflict-target clause, which ** includes both the list of columns and the optional partial-index ** WHERE clause. */ memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; sNC.pSrcList = pTabList; for(; pUpsert && pUpsert->pUpsertTarget; pUpsert=pUpsert->pNextUpsert, nClause++){ rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); if( rc ) return rc; rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); if( rc ) return rc; /* Check to see if the conflict target matches the rowid. */ pTab = pTabList->a[0].pSTab; pTarget = pUpsert->pUpsertTarget; iCursor = pTabList->a[0].iCursor; if( HasRowid(pTab) && pTarget->nExpr==1 && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN && pTerm->iColumn==XN_ROWID ){ |
︙ | ︙ | |||
155126 155127 155128 155129 155130 155131 155132 155133 155134 155135 155136 155137 155138 155139 | Db *pDb = 0; /* Database to detach at end of vacuum */ int isMemDb; /* True if vacuuming a :memory: database */ int nRes; /* Bytes of reserved space at the end of each page */ int nDb; /* Number of attached databases */ const char *zDbMain; /* Schema name of database to vacuum */ const char *zOut; /* Name of output file */ u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); return SQLITE_ERROR; /* IMP: R-12218-18073 */ } if( db->nVdbeActive>1 ){ sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress"); | > > > | 155936 155937 155938 155939 155940 155941 155942 155943 155944 155945 155946 155947 155948 155949 155950 155951 155952 | Db *pDb = 0; /* Database to detach at end of vacuum */ int isMemDb; /* True if vacuuming a :memory: database */ int nRes; /* Bytes of reserved space at the end of each page */ int nDb; /* Number of attached databases */ const char *zDbMain; /* Schema name of database to vacuum */ const char *zOut; /* Name of output file */ u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ u64 iRandom; /* Random value used for zDbVacuum[] */ char zDbVacuum[42]; /* Name of the ATTACH-ed database used for vacuum */ if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); return SQLITE_ERROR; /* IMP: R-12218-18073 */ } if( db->nVdbeActive>1 ){ sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress"); |
︙ | ︙ | |||
155166 155167 155168 155169 155170 155171 155172 | | SQLITE_Defensive | SQLITE_CountRows); db->mTrace = 0; zDbMain = db->aDb[iDb].zDbSName; pMain = db->aDb[iDb].pBt; isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); | | | > > | | | 155979 155980 155981 155982 155983 155984 155985 155986 155987 155988 155989 155990 155991 155992 155993 155994 155995 155996 155997 155998 155999 156000 156001 156002 156003 156004 156005 156006 156007 156008 156009 156010 156011 156012 156013 156014 156015 | | SQLITE_Defensive | SQLITE_CountRows); db->mTrace = 0; zDbMain = db->aDb[iDb].zDbSName; pMain = db->aDb[iDb].pBt; isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); /* Attach the temporary database as 'vacuum_XXXXXX'. The synchronous pragma ** can be set to 'off' for this file, as it is not recovered if a crash ** occurs anyway. The integrity of the database is maintained by a ** (possibly synchronous) transaction opened on the main database before ** sqlite3BtreeCopyFile() is called. ** ** An optimization would be to use a non-journaled pager. ** (Later:) I tried setting "PRAGMA vacuum_XXXXXX.journal_mode=OFF" but ** that actually made the VACUUM run slower. Very little journalling ** actually occurs when doing a vacuum since the vacuum_db is initially ** empty. Only the journal header is written. Apparently it takes more ** time to parse and run the PRAGMA to turn journalling off than it does ** to write the journal header file. */ sqlite3_randomness(sizeof(iRandom),&iRandom); sqlite3_snprintf(sizeof(zDbVacuum), zDbVacuum, "vacuum_%016llx", iRandom); nDb = db->nDb; rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS %s", zOut, zDbVacuum); db->openFlags = saved_openFlags; if( rc!=SQLITE_OK ) goto end_of_vacuum; assert( (db->nDb-1)==nDb ); pDb = &db->aDb[nDb]; assert( strcmp(pDb->zDbSName,zDbVacuum)==0 ); pTemp = pDb->pBt; if( pOut ){ sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); i64 sz = 0; if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){ rc = SQLITE_ERROR; sqlite3SetString(pzErrMsg, db, "output file already exists"); |
︙ | ︙ | |||
155263 155264 155265 155266 155267 155268 155269 | db->init.iDb = 0; /* Loop through the tables in the main database. For each, do ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy ** the contents to the temporary database. */ rc = execSqlF(db, pzErrMsg, | | | | | | | 156078 156079 156080 156081 156082 156083 156084 156085 156086 156087 156088 156089 156090 156091 156092 156093 156094 156095 156096 156097 156098 156099 156100 156101 156102 156103 156104 156105 156106 156107 156108 156109 156110 156111 156112 | db->init.iDb = 0; /* Loop through the tables in the main database. For each, do ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy ** the contents to the temporary database. */ rc = execSqlF(db, pzErrMsg, "SELECT'INSERT INTO %s.'||quote(name)" "||' SELECT*FROM\"%w\".'||quote(name)" "FROM %s.sqlite_schema " "WHERE type='table'AND coalesce(rootpage,1)>0", zDbVacuum, zDbMain, zDbVacuum ); assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 ); db->mDbFlags &= ~DBFLAG_Vacuum; if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Copy the triggers, views, and virtual tables from the main database ** over to the temporary database. None of these objects has any ** associated storage, so all we have to do is copy their entries ** from the schema table. */ rc = execSqlF(db, pzErrMsg, "INSERT INTO %s.sqlite_schema" " SELECT*FROM \"%w\".sqlite_schema" " WHERE type IN('view','trigger')" " OR(type='table'AND rootpage=0)", zDbVacuum, zDbMain ); if( rc ) goto end_of_vacuum; /* At this point, there is a write transaction open on both the ** vacuum database and the main database. Assuming no error occurs, ** both transactions are closed by this block - the main database ** transaction by sqlite3BtreeCopyFile() and the other by an explicit |
︙ | ︙ | |||
156247 156248 156249 156250 156251 156252 156253 156254 156255 156256 156257 156258 156259 156260 | assert( !db->mallocFailed ); assert( IsOrdinaryTable(sParse.pNewTable) ); assert( sParse.zErrMsg==0 ); if( !pTab->aCol ){ Table *pNew = sParse.pNewTable; Index *pIdx; pTab->aCol = pNew->aCol; sqlite3ExprListDelete(db, pNew->u.tab.pDfltList); pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); pNew->nCol = 0; pNew->aCol = 0; assert( pTab->pIndex==0 ); assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 ); | > | 157062 157063 157064 157065 157066 157067 157068 157069 157070 157071 157072 157073 157074 157075 157076 | assert( !db->mallocFailed ); assert( IsOrdinaryTable(sParse.pNewTable) ); assert( sParse.zErrMsg==0 ); if( !pTab->aCol ){ Table *pNew = sParse.pNewTable; Index *pIdx; pTab->aCol = pNew->aCol; assert( IsOrdinaryTable(pNew) ); sqlite3ExprListDelete(db, pNew->u.tab.pDfltList); pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); pNew->nCol = 0; pNew->aCol = 0; assert( pTab->pIndex==0 ); assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 ); |
︙ | ︙ | |||
156921 156922 156923 156924 156925 156926 156927 156928 156929 156930 156931 156932 156933 156934 156935 156936 156937 156938 156939 156940 156941 156942 156943 156944 156945 156946 156947 156948 156949 156950 156951 | union { struct { /* Information for internal btree tables */ u16 nEq; /* Number of equality constraints */ u16 nBtm; /* Size of BTM vector */ u16 nTop; /* Size of TOP vector */ u16 nDistinctCol; /* Index columns used to sort for DISTINCT */ Index *pIndex; /* Index used, or NULL */ } btree; struct { /* Information for virtual tables */ int idxNum; /* Index number */ u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */ u32 bOmitOffset : 1; /* True to let virtual table handle offset */ i8 isOrdered; /* True if satisfies ORDER BY */ u16 omitMask; /* Terms that may be omitted */ char *idxStr; /* Index identifier string */ u32 mHandleIn; /* Terms to handle as IN(...) instead of == */ } vtab; } u; u32 wsFlags; /* WHERE_* flags describing the plan */ u16 nLTerm; /* Number of entries in aLTerm[] */ u16 nSkip; /* Number of NULL aLTerm[] entries */ /**** whereLoopXfer() copies fields above ***********************/ # define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) u16 nLSlot; /* Number of slots allocated for aLTerm[] */ WhereTerm **aLTerm; /* WhereTerms used */ WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */ WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */ }; /* This object holds the prerequisites and the cost of running a ** subquery on one operand of an OR operator in the WHERE clause. | > > > > | 157737 157738 157739 157740 157741 157742 157743 157744 157745 157746 157747 157748 157749 157750 157751 157752 157753 157754 157755 157756 157757 157758 157759 157760 157761 157762 157763 157764 157765 157766 157767 157768 157769 157770 157771 | union { struct { /* Information for internal btree tables */ u16 nEq; /* Number of equality constraints */ u16 nBtm; /* Size of BTM vector */ u16 nTop; /* Size of TOP vector */ u16 nDistinctCol; /* Index columns used to sort for DISTINCT */ Index *pIndex; /* Index used, or NULL */ ExprList *pOrderBy; /* ORDER BY clause if this is really a subquery */ } btree; struct { /* Information for virtual tables */ int idxNum; /* Index number */ u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */ u32 bOmitOffset : 1; /* True to let virtual table handle offset */ u32 bIdxNumHex : 1; /* Show idxNum as hex in EXPLAIN QUERY PLAN */ i8 isOrdered; /* True if satisfies ORDER BY */ u16 omitMask; /* Terms that may be omitted */ char *idxStr; /* Index identifier string */ u32 mHandleIn; /* Terms to handle as IN(...) instead of == */ } vtab; } u; u32 wsFlags; /* WHERE_* flags describing the plan */ u16 nLTerm; /* Number of entries in aLTerm[] */ u16 nSkip; /* Number of NULL aLTerm[] entries */ /**** whereLoopXfer() copies fields above ***********************/ # define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) u16 nLSlot; /* Number of slots allocated for aLTerm[] */ LogEst rStarDelta; /* Cost delta due to star-schema heuristic. Not ** initialized unless pWInfo->nOutStarDelta>0 */ WhereTerm **aLTerm; /* WhereTerms used */ WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */ WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */ }; /* This object holds the prerequisites and the cost of running a ** subquery on one operand of an OR operator in the WHERE clause. |
︙ | ︙ | |||
157260 157261 157262 157263 157264 157265 157266 157267 157268 157269 157270 157271 157272 157273 | i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */ u8 eDistinct; /* One of the WHERE_DISTINCT_* values */ unsigned bDeferredSeek :1; /* Uses OP_DeferredSeek */ unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ unsigned sorted :1; /* True if really sorted (not just grouped) */ LogEst nRowOut; /* Estimated number of output rows */ int iTop; /* The very beginning of the WHERE loop */ int iEndWhere; /* End of the WHERE clause itself */ WhereLoop *pLoops; /* List of all WhereLoop objects */ WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ WhereClause sWC; /* Decomposition of the WHERE clause */ | > | 158080 158081 158082 158083 158084 158085 158086 158087 158088 158089 158090 158091 158092 158093 158094 | i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */ u8 eDistinct; /* One of the WHERE_DISTINCT_* values */ unsigned bDeferredSeek :1; /* Uses OP_DeferredSeek */ unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ unsigned sorted :1; /* True if really sorted (not just grouped) */ LogEst nOutStarDelta; /* Artifical nOut reduction for star-query */ LogEst nRowOut; /* Estimated number of output rows */ int iTop; /* The very beginning of the WHERE loop */ int iEndWhere; /* End of the WHERE clause itself */ WhereLoop *pLoops; /* List of all WhereLoop objects */ WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ WhereClause sWC; /* Decomposition of the WHERE clause */ |
︙ | ︙ | |||
157411 157412 157413 157414 157415 157416 157417 | #define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */ #define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */ #define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */ #define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */ #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ | | > | 158232 158233 158234 158235 158236 158237 158238 158239 158240 158241 158242 158243 158244 158245 158246 158247 | #define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */ #define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */ #define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */ #define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */ #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ #define WHERE_COROUTINE 0x02000000 /* Implemented by co-routine. ** NB: False-negatives are possible */ #define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */ #endif /* !defined(SQLITE_WHEREINT_H) */ /************** End of whereInt.h ********************************************/ /************** Continuing where we left off in wherecode.c ******************/ |
︙ | ︙ | |||
157556 157557 157558 157559 157560 157561 157562 | if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ const char *zFmt = 0; Index *pIdx; assert( pLoop->u.btree.pIndex!=0 ); pIdx = pLoop->u.btree.pIndex; assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); | | | 158378 158379 158380 158381 158382 158383 158384 158385 158386 158387 158388 158389 158390 158391 158392 | if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ const char *zFmt = 0; Index *pIdx; assert( pLoop->u.btree.pIndex!=0 ); pIdx = pLoop->u.btree.pIndex; assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); if( !HasRowid(pItem->pSTab) && IsPrimaryKeyIndex(pIdx) ){ if( isSearch ){ zFmt = "PRIMARY KEY"; } }else if( flags & WHERE_PARTIALIDX ){ zFmt = "AUTOMATIC PARTIAL COVERING INDEX"; }else if( flags & WHERE_AUTO_INDEX ){ zFmt = "AUTOMATIC COVERING INDEX"; |
︙ | ︙ | |||
157599 157600 157601 157602 157603 157604 157605 | assert( flags&WHERE_TOP_LIMIT); cRangeOp = '<'; } sqlite3_str_appendf(&str, "%c?)", cRangeOp); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ | > | > | > | 158421 158422 158423 158424 158425 158426 158427 158428 158429 158430 158431 158432 158433 158434 158435 158436 158437 158438 158439 158440 158441 158442 158443 158444 158445 158446 158447 158448 158449 158450 158451 158452 158453 158454 158455 158456 | assert( flags&WHERE_TOP_LIMIT); cRangeOp = '<'; } sqlite3_str_appendf(&str, "%c?)", cRangeOp); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ sqlite3_str_appendall(&str, " VIRTUAL TABLE INDEX "); sqlite3_str_appendf(&str, pLoop->u.vtab.bIdxNumHex ? "0x%x:%s" : "%d:%s", pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); } #endif if( pItem->fg.jointype & JT_LEFT ){ sqlite3_str_appendf(&str, " LEFT-JOIN"); } #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS if( pLoop->nOut>=10 ){ sqlite3_str_appendf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut)); }else{ sqlite3_str_append(&str, " (~1 row)", 9); } #endif zMsg = sqlite3StrAccumFinish(&str); sqlite3ExplainBreakpoint("",zMsg); ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), pParse->addrExplain, pLoop->rRun, zMsg, P4_DYNAMIC); } return ret; } /* ** Add a single OP_Explain opcode that describes a Bloom filter. ** |
︙ | ︙ | |||
157652 157653 157654 157655 157656 157657 157658 | char zBuf[100]; /* Initial space for EQP output string */ sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); str.printfFlags = SQLITE_PRINTF_INTERNAL; sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem); pLoop = pLevel->pWLoop; if( pLoop->wsFlags & WHERE_IPK ){ | | | 158477 158478 158479 158480 158481 158482 158483 158484 158485 158486 158487 158488 158489 158490 158491 | char zBuf[100]; /* Initial space for EQP output string */ sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); str.printfFlags = SQLITE_PRINTF_INTERNAL; sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem); pLoop = pLevel->pWLoop; if( pLoop->wsFlags & WHERE_IPK ){ const Table *pTab = pItem->pSTab; if( pTab->iPKey>=0 ){ sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName); }else{ sqlite3_str_appendf(&str, "rowid=?"); } }else{ for(i=pLoop->nSkip; i<pLoop->u.btree.nEq; i++){ |
︙ | ︙ | |||
157715 157716 157717 157718 157719 157720 157721 | if( (wsFlags & (WHERE_MULTI_OR|WHERE_AUTO_INDEX))==0 ){ sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur); } if( wsFlags & WHERE_INDEXED ){ sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); } }else{ | > > | | 158540 158541 158542 158543 158544 158545 158546 158547 158548 158549 158550 158551 158552 158553 158554 158555 158556 | if( (wsFlags & (WHERE_MULTI_OR|WHERE_AUTO_INDEX))==0 ){ sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur); } if( wsFlags & WHERE_INDEXED ){ sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); } }else{ int addr; assert( pSrclist->a[pLvl->iFrom].fg.isSubquery ); addr = pSrclist->a[pLvl->iFrom].u4.pSubq->addrFillSub; VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); sqlite3VdbeScanStatusRange(v, addrExplain, addr, pOp->p2-1); } } } |
︙ | ︙ | |||
157859 157860 157861 157862 157863 157864 157865 157866 157867 157868 157869 157870 157871 157872 | || sqlite3ExprNeedsNoAffinityChange(p, zAff[i]) ){ zAff[i] = SQLITE_AFF_BLOB; } } } /* ** pX is an expression of the form: (vector) IN (SELECT ...) ** In other words, it is a vector IN operator with a SELECT clause on the ** LHS. But not all terms in the vector are indexable and the terms might ** not be in the correct order for indexing. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 158686 158687 158688 158689 158690 158691 158692 158693 158694 158695 158696 158697 158698 158699 158700 158701 158702 158703 158704 158705 158706 158707 158708 158709 158710 158711 158712 158713 158714 158715 158716 158717 158718 158719 158720 158721 158722 158723 158724 158725 158726 158727 158728 158729 158730 158731 158732 | || sqlite3ExprNeedsNoAffinityChange(p, zAff[i]) ){ zAff[i] = SQLITE_AFF_BLOB; } } } /* ** The pOrderBy->a[].u.x.iOrderByCol values might be incorrect because ** columns might have been rearranged in the result set. This routine ** fixes them up. ** ** pEList is the new result set. The pEList->a[].u.x.iOrderByCol values ** contain the *old* locations of each expression. This is a temporary ** use of u.x.iOrderByCol, not its intended use. The caller must reset ** u.x.iOrderByCol back to zero for all entries in pEList before the ** caller returns. ** ** This routine changes pOrderBy->a[].u.x.iOrderByCol values from ** pEList->a[N].u.x.iOrderByCol into N+1. (The "+1" is because of the 1-based ** indexing used by iOrderByCol.) Or if no match, iOrderByCol is set to zero. */ static void adjustOrderByCol(ExprList *pOrderBy, ExprList *pEList){ int i, j; if( pOrderBy==0 ) return; for(i=0; i<pOrderBy->nExpr; i++){ int t = pOrderBy->a[i].u.x.iOrderByCol; if( t==0 ) continue; for(j=0; j<pEList->nExpr; j++){ if( pEList->a[j].u.x.iOrderByCol==t ){ pOrderBy->a[i].u.x.iOrderByCol = j+1; break; } } if( j>=pEList->nExpr ){ pOrderBy->a[i].u.x.iOrderByCol = 0; } } } /* ** pX is an expression of the form: (vector) IN (SELECT ...) ** In other words, it is a vector IN operator with a SELECT clause on the ** LHS. But not all terms in the vector are indexable and the terms might ** not be in the correct order for indexing. ** |
︙ | ︙ | |||
157922 157923 157924 157925 157926 157927 157928 157929 157930 157931 157932 157933 157934 157935 | if( pLoop->aLTerm[i]->pExpr==pX ){ int iField; assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 ); iField = pLoop->aLTerm[i]->u.x.iField - 1; if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); pOrigRhs->a[iField].pExpr = 0; if( pOrigLhs ){ assert( pOrigLhs->a[iField].pExpr!=0 ); pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr); pOrigLhs->a[iField].pExpr = 0; } } } | > | 158782 158783 158784 158785 158786 158787 158788 158789 158790 158791 158792 158793 158794 158795 158796 | if( pLoop->aLTerm[i]->pExpr==pX ){ int iField; assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 ); iField = pLoop->aLTerm[i]->u.x.iField - 1; if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); pOrigRhs->a[iField].pExpr = 0; if( pRhs ) pRhs->a[pRhs->nExpr-1].u.x.iOrderByCol = iField+1; if( pOrigLhs ){ assert( pOrigLhs->a[iField].pExpr!=0 ); pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr); pOrigLhs->a[iField].pExpr = 0; } } } |
︙ | ︙ | |||
157944 157945 157946 157947 157948 157949 157950 | ** single value. Since the parser never creates such a vector, some ** of the subroutines do not handle this case. */ Expr *p = pLhs->a[0].pExpr; pLhs->a[0].pExpr = 0; sqlite3ExprDelete(db, pNew->pLeft); pNew->pLeft = p; } | | | | | | | | < | | | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 158805 158806 158807 158808 158809 158810 158811 158812 158813 158814 158815 158816 158817 158818 158819 158820 158821 158822 158823 158824 158825 158826 158827 158828 158829 158830 158831 158832 158833 158834 158835 158836 158837 158838 158839 158840 158841 158842 158843 158844 158845 158846 158847 158848 158849 158850 158851 158852 158853 158854 158855 158856 158857 158858 158859 158860 158861 158862 158863 158864 158865 158866 158867 158868 158869 158870 158871 158872 158873 158874 158875 158876 158877 158878 158879 158880 158881 158882 158883 158884 158885 158886 158887 158888 158889 158890 158891 158892 158893 158894 158895 158896 158897 158898 158899 158900 158901 158902 158903 158904 158905 158906 158907 158908 158909 158910 158911 158912 158913 158914 158915 158916 158917 158918 158919 158920 158921 158922 158923 158924 158925 158926 158927 158928 158929 158930 158931 158932 158933 158934 158935 158936 158937 158938 158939 158940 158941 158942 158943 158944 158945 158946 158947 158948 158949 158950 158951 158952 158953 158954 158955 158956 158957 158958 158959 158960 158961 158962 158963 158964 158965 158966 158967 158968 158969 158970 158971 158972 158973 158974 158975 158976 158977 158978 158979 158980 158981 158982 | ** single value. Since the parser never creates such a vector, some ** of the subroutines do not handle this case. */ Expr *p = pLhs->a[0].pExpr; pLhs->a[0].pExpr = 0; sqlite3ExprDelete(db, pNew->pLeft); pNew->pLeft = p; } /* If either the ORDER BY clause or the GROUP BY clause contains ** references to result-set columns, those references might now be ** obsolete. So fix them up. */ assert( pRhs!=0 || db->mallocFailed ); if( pRhs ){ adjustOrderByCol(pSelect->pOrderBy, pRhs); adjustOrderByCol(pSelect->pGroupBy, pRhs); for(i=0; i<pRhs->nExpr; i++) pRhs->a[i].u.x.iOrderByCol = 0; } #if 0 printf("For indexing, change the IN expr:\n"); sqlite3TreeViewExpr(0, pX, 0); printf("Into:\n"); sqlite3TreeViewExpr(0, pNew, 0); #endif } } return pNew; } #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code for a single X IN (....) term of the WHERE clause. ** ** This is a special-case of codeEqualityTerm() that works for IN operators ** only. It is broken out into a subroutine because this case is ** uncommon and by splitting it off into a subroutine, the common case ** runs faster. ** ** The current value for the constraint is left in register iTarget. ** This routine sets up a loop that will iterate over all values of X. */ static SQLITE_NOINLINE void codeINTerm( Parse *pParse, /* The parsing context */ WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ WhereLevel *pLevel, /* The level of the FROM clause we are working on */ int iEq, /* Index of the equality term within this level */ int bRev, /* True for reverse-order IN operations */ int iTarget /* Attempt to leave results in this register */ ){ Expr *pX = pTerm->pExpr; int eType = IN_INDEX_NOOP; int iTab; struct InLoop *pIn; WhereLoop *pLoop = pLevel->pWLoop; Vdbe *v = pParse->pVdbe; int i; int nEq = 0; int *aiMap = 0; if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 && pLoop->u.btree.pIndex->aSortOrder[iEq] ){ testcase( iEq==0 ); testcase( bRev ); bRev = !bRev; } assert( pX->op==TK_IN ); for(i=0; i<iEq; i++){ if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ disableTerm(pLevel, pTerm); return; } } for(i=iEq;i<pLoop->nLTerm; i++){ assert( pLoop->aLTerm[i]!=0 ); if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; } iTab = 0; if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); }else{ Expr *pExpr = pTerm->pExpr; if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ sqlite3 *db = pParse->db; pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); if( !db->mallocFailed ){ aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); pExpr->iTable = iTab; } sqlite3ExprDelete(db, pX); }else{ int n = sqlite3ExprVectorSize(pX->pLeft); aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); } pX = pExpr; } if( eType==IN_INDEX_INDEX_DESC ){ testcase( bRev ); bRev = !bRev; } sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); VdbeCoverageIf(v, bRev); VdbeCoverageIf(v, !bRev); assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); pLoop->wsFlags |= WHERE_IN_ABLE; if( pLevel->u.in.nIn==0 ){ pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); } if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){ pLoop->wsFlags |= WHERE_IN_EARLYOUT; } i = pLevel->u.in.nIn; pLevel->u.in.nIn += nEq; pLevel->u.in.aInLoop = sqlite3WhereRealloc(pTerm->pWC->pWInfo, pLevel->u.in.aInLoop, sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); pIn = pLevel->u.in.aInLoop; if( pIn ){ int iMap = 0; /* Index in aiMap[] */ pIn += i; for(i=iEq;i<pLoop->nLTerm; i++){ if( pLoop->aLTerm[i]->pExpr==pX ){ int iOut = iTarget + i - iEq; if( eType==IN_INDEX_ROWID ){ pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); }else{ int iCol = aiMap ? aiMap[iMap++] : 0; pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); } sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); if( i==iEq ){ pIn->iCur = iTab; pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; if( iEq>0 ){ pIn->iBase = iTarget - i; pIn->nPrefix = i; }else{ pIn->nPrefix = 0; } }else{ pIn->eEndLoopOp = OP_Noop; } pIn++; } } testcase( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); if( iEq>0 && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 ){ sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); } }else{ pLevel->u.in.nIn = 0; } sqlite3DbFree(pParse->db, aiMap); } #endif /* ** Generate code for a single equality term of the WHERE clause. An equality ** term can be either X=expr or X IN (...). pTerm is the term to be ** coded. ** ** The current value for the constraint is left in a register, the index |
︙ | ︙ | |||
157994 157995 157996 157997 157998 157999 158000 | WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ WhereLevel *pLevel, /* The level of the FROM clause we are working on */ int iEq, /* Index of the equality term within this level */ int bRev, /* True for reverse-order IN operations */ int iTarget /* Attempt to leave results in this register */ ){ Expr *pX = pTerm->pExpr; | < | < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 158994 158995 158996 158997 158998 158999 159000 159001 159002 159003 159004 159005 159006 159007 159008 159009 159010 159011 159012 159013 159014 159015 159016 159017 159018 159019 159020 159021 | WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ WhereLevel *pLevel, /* The level of the FROM clause we are working on */ int iEq, /* Index of the equality term within this level */ int bRev, /* True for reverse-order IN operations */ int iTarget /* Attempt to leave results in this register */ ){ Expr *pX = pTerm->pExpr; int iReg; /* Register holding results */ assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); assert( iTarget>0 ); if( pX->op==TK_EQ || pX->op==TK_IS ){ iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); }else if( pX->op==TK_ISNULL ){ iReg = iTarget; sqlite3VdbeAddOp2(pParse->pVdbe, OP_Null, 0, iReg); #ifndef SQLITE_OMIT_SUBQUERY }else{ assert( pX->op==TK_IN ); iReg = iTarget; codeINTerm(pParse, pTerm, pLevel, iEq, bRev, iTarget); #endif } /* As an optimization, try to disable the WHERE clause term that is ** driving the index as it will always be true. The correct answer is ** obtained regardless, but we might get the answer with fewer CPU cycles ** by omitting the term. |
︙ | ︙ | |||
158793 158794 158795 158796 158797 158798 158799 | pWC = &pWInfo->sWC; db = pParse->db; pLoop = pLevel->pWLoop; pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; iCur = pTabItem->iCursor; pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); bRev = (pWInfo->revMask>>iLevel)&1; | | > | 159679 159680 159681 159682 159683 159684 159685 159686 159687 159688 159689 159690 159691 159692 159693 159694 | pWC = &pWInfo->sWC; db = pParse->db; pLoop = pLevel->pWLoop; pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; iCur = pTabItem->iCursor; pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); bRev = (pWInfo->revMask>>iLevel)&1; VdbeModuleComment((v, "Begin WHERE-loop%d: %s", iLevel, pTabItem->pSTab->zName)); #if WHERETRACE_ENABLED /* 0x4001 */ if( sqlite3WhereTrace & 0x1 ){ sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom); if( sqlite3WhereTrace & 0x1000 ){ sqlite3WhereLoopPrint(pLoop, pWC); } |
︙ | ︙ | |||
158848 158849 158850 158851 158852 158853 158854 | if( pWInfo->a[j].iLeftJoin ) break; if( pWInfo->a[j].pRJ ) break; } addrHalt = pWInfo->a[j].addrBrk; /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->fg.viaCoroutine ){ | | > > > > | | | 159735 159736 159737 159738 159739 159740 159741 159742 159743 159744 159745 159746 159747 159748 159749 159750 159751 159752 159753 159754 159755 159756 159757 | if( pWInfo->a[j].iLeftJoin ) break; if( pWInfo->a[j].pRJ ) break; } addrHalt = pWInfo->a[j].addrBrk; /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->fg.viaCoroutine ){ int regYield; Subquery *pSubq; assert( pTabItem->fg.isSubquery && pTabItem->u4.pSubq!=0 ); pSubq = pTabItem->u4.pSubq; regYield = pSubq->regReturn; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub); pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); VdbeCoverage(v); VdbeComment((v, "next row of %s", pTabItem->pSTab->zName)); pLevel->op = OP_Goto; }else #ifndef SQLITE_OMIT_VIRTUALTABLE if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ /* Case 1: The table is a virtual-table. Use the VFilter and VNext ** to access the data. |
︙ | ︙ | |||
159581 159582 159583 159584 159585 159586 159587 | int regRowset = 0; /* Register for RowSet object */ int regRowid = 0; /* Register holding rowid */ int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */ int iRetInit; /* Address of regReturn init */ int untestedTerms = 0; /* Some terms not completely tested */ int ii; /* Loop counter */ Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ | | | 160472 160473 160474 160475 160476 160477 160478 160479 160480 160481 160482 160483 160484 160485 160486 | int regRowset = 0; /* Register for RowSet object */ int regRowid = 0; /* Register holding rowid */ int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */ int iRetInit; /* Address of regReturn init */ int untestedTerms = 0; /* Some terms not completely tested */ int ii; /* Loop counter */ Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ Table *pTab = pTabItem->pSTab; pTerm = pLoop->aLTerm[0]; assert( pTerm!=0 ); assert( pTerm->eOperator & WO_OR ); assert( (pTerm->wtFlags & TERM_ORINFO)!=0 ); pOrWc = &pTerm->u.pOrInfo->wc; pLevel->op = OP_Return; |
︙ | ︙ | |||
160040 160041 160042 160043 160044 160045 160046 | WhereRightJoin *pRJ = pLevel->pRJ; /* pTab is the right-hand table of the RIGHT JOIN. Generate code that ** will record that the current row of that table has been matched at ** least once. This is accomplished by storing the PK for the row in ** both the iMatch index and the regBloom Bloom filter. */ | | | 160931 160932 160933 160934 160935 160936 160937 160938 160939 160940 160941 160942 160943 160944 160945 | WhereRightJoin *pRJ = pLevel->pRJ; /* pTab is the right-hand table of the RIGHT JOIN. Generate code that ** will record that the current row of that table has been matched at ** least once. This is accomplished by storing the PK for the row in ** both the iMatch index and the regBloom Bloom filter. */ pTab = pWInfo->pTabList->a[pLevel->iFrom].pSTab; if( HasRowid(pTab) ){ r = sqlite3GetTempRange(pParse, 2); sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1); nPk = 1; }else{ int iPk; Index *pPk = sqlite3PrimaryKeyIndex(pTab); |
︙ | ︙ | |||
160147 160148 160149 160150 160151 160152 160153 | WhereInfo *pSubWInfo; WhereLoop *pLoop = pLevel->pWLoop; SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; SrcList sFrom; Bitmask mAll = 0; int k; | | > > > > | | | 161038 161039 161040 161041 161042 161043 161044 161045 161046 161047 161048 161049 161050 161051 161052 161053 161054 161055 161056 161057 161058 161059 161060 161061 161062 161063 161064 161065 161066 161067 161068 | WhereInfo *pSubWInfo; WhereLoop *pLoop = pLevel->pWLoop; SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; SrcList sFrom; Bitmask mAll = 0; int k; ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName)); sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn, pRJ->regReturn); for(k=0; k<iLevel; k++){ int iIdxCur; SrcItem *pRight; assert( pWInfo->a[k].pWLoop->iTab == pWInfo->a[k].iFrom ); pRight = &pWInfo->pTabList->a[pWInfo->a[k].iFrom]; mAll |= pWInfo->a[k].pWLoop->maskSelf; if( pRight->fg.viaCoroutine ){ Subquery *pSubq; assert( pRight->fg.isSubquery && pRight->u4.pSubq!=0 ); pSubq = pRight->u4.pSubq; assert( pSubq->pSelect!=0 && pSubq->pSelect->pEList!=0 ); sqlite3VdbeAddOp3( v, OP_Null, 0, pSubq->regResult, pSubq->regResult + pSubq->pSelect->pEList->nExpr-1 ); } sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); iIdxCur = pWInfo->a[k].iIdxCur; if( iIdxCur ){ sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); } |
︙ | ︙ | |||
160197 160198 160199 160200 160201 160202 160203 | WHERE_RIGHT_JOIN, 0); if( pSubWInfo ){ int iCur = pLevel->iTabCur; int r = ++pParse->nMem; int nPk; int jmp; int addrCont = sqlite3WhereContinueLabel(pSubWInfo); | | | 161092 161093 161094 161095 161096 161097 161098 161099 161100 161101 161102 161103 161104 161105 161106 | WHERE_RIGHT_JOIN, 0); if( pSubWInfo ){ int iCur = pLevel->iTabCur; int r = ++pParse->nMem; int nPk; int jmp; int addrCont = sqlite3WhereContinueLabel(pSubWInfo); Table *pTab = pTabItem->pSTab; if( HasRowid(pTab) ){ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); nPk = 1; }else{ int iPk; Index *pPk = sqlite3PrimaryKeyIndex(pTab); nPk = pPk->nKeyCol; |
︙ | ︙ | |||
160330 160331 160332 160333 160334 160335 160336 | ** "=", "<", ">", "<=", ">=", "IN", "IS", and "IS NULL" */ static int allowedOp(int op){ assert( TK_GT>TK_EQ && TK_GT<TK_GE ); assert( TK_LT>TK_EQ && TK_LT<TK_GE ); assert( TK_LE>TK_EQ && TK_LE<TK_GE ); assert( TK_GE==TK_EQ+4 ); | > > > > > | | 161225 161226 161227 161228 161229 161230 161231 161232 161233 161234 161235 161236 161237 161238 161239 161240 161241 161242 161243 161244 | ** "=", "<", ">", "<=", ">=", "IN", "IS", and "IS NULL" */ static int allowedOp(int op){ assert( TK_GT>TK_EQ && TK_GT<TK_GE ); assert( TK_LT>TK_EQ && TK_LT<TK_GE ); assert( TK_LE>TK_EQ && TK_LE<TK_GE ); assert( TK_GE==TK_EQ+4 ); assert( TK_IN<TK_EQ ); assert( TK_IS<TK_EQ ); assert( TK_ISNULL<TK_EQ ); if( op>TK_GE ) return 0; if( op>=TK_EQ ) return 1; return op==TK_IN || op==TK_ISNULL || op==TK_IS; } /* ** Commute a comparison operator. Expressions of the form "X op Y" ** are converted into "Y op X". */ static u16 exprCommute(Parse *pParse, Expr *pExpr){ |
︙ | ︙ | |||
160363 160364 160365 160366 160367 160368 160369 | /* ** Translate from TK_xx operator to WO_xx bitmask. */ static u16 operatorMask(int op){ u16 c; assert( allowedOp(op) ); | > > > | > | < < < | 161263 161264 161265 161266 161267 161268 161269 161270 161271 161272 161273 161274 161275 161276 161277 161278 161279 161280 161281 161282 161283 161284 161285 161286 | /* ** Translate from TK_xx operator to WO_xx bitmask. */ static u16 operatorMask(int op){ u16 c; assert( allowedOp(op) ); if( op>=TK_EQ ){ assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); c = (u16)(WO_EQ<<(op-TK_EQ)); }else if( op==TK_IN ){ c = WO_IN; }else if( op==TK_ISNULL ){ c = WO_ISNULL; }else{ assert( op==TK_IS ); c = WO_IS; } assert( op!=TK_ISNULL || c==WO_ISNULL ); assert( op!=TK_IN || c==WO_IN ); assert( op!=TK_EQ || c==WO_EQ ); assert( op!=TK_LT || c==WO_LT ); assert( op!=TK_LE || c==WO_LE ); assert( op!=TK_GT || c==WO_GT ); |
︙ | ︙ | |||
160443 160444 160445 160446 160447 160448 160449 | assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); }else if( op==TK_STRING ){ assert( !ExprHasProperty(pRight, EP_IntValue) ); z = (u8*)pRight->u.zToken; } if( z ){ | | > > > > | > > > > > | | 161344 161345 161346 161347 161348 161349 161350 161351 161352 161353 161354 161355 161356 161357 161358 161359 161360 161361 161362 161363 161364 161365 161366 161367 161368 161369 161370 161371 161372 161373 161374 161375 161376 161377 161378 161379 161380 161381 161382 161383 161384 161385 161386 | assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); }else if( op==TK_STRING ){ assert( !ExprHasProperty(pRight, EP_IntValue) ); z = (u8*)pRight->u.zToken; } if( z ){ /* Count the number of prefix characters prior to the first wildcard. ** If the underlying database has a UTF16LE encoding, then only consider ** ASCII characters. Note that the encoding of z[] is UTF8 - we are ** dealing with only UTF8 here in this code, but the database engine ** itself might be processing content using a different encoding. */ cnt = 0; while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ cnt++; if( c==wc[3] && z[cnt]!=0 ){ cnt++; }else if( c>=0x80 && ENC(db)==SQLITE_UTF16LE ){ cnt--; break; } } /* The optimization is possible only if (1) the pattern does not begin ** with a wildcard and if (2) the non-wildcard prefix does not end with ** an (illegal 0xff) character, or (3) the pattern does not consist of ** a single escape character. The second condition is necessary so ** that we can increment the prefix key to find an upper bound for the ** range search. The third is because the caller assumes that the pattern ** consists of at least one character after all escapes have been ** removed. */ if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){ Expr *pPrefix; /* A "complete" match if the pattern ends with "*" or "%" */ *pisComplete = c==wc[0] && z[cnt+1]==0 && ENC(db)!=SQLITE_UTF16LE; /* Get the pattern prefix. Remove all escapes from the prefix. */ pPrefix = sqlite3Expr(db, TK_STRING, (char*)z); if( pPrefix ){ int iFrom, iTo; char *zNew; assert( !ExprHasProperty(pPrefix, EP_IntValue) ); |
︙ | ︙ | |||
160658 160659 160660 160661 160662 160663 160664 160665 160666 160667 160668 160669 160670 160671 | *peOp2 = i; *ppRight = pList->a[1].pExpr; *ppLeft = pCol; return 1; } } } }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ int res = 0; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; assert( pLeft->op!=TK_COLUMN || (ExprUseYTab(pLeft) && pLeft->y.pTab!=0) ); if( ExprIsVtab(pLeft) ){ res++; | > > > > > > > | 161568 161569 161570 161571 161572 161573 161574 161575 161576 161577 161578 161579 161580 161581 161582 161583 161584 161585 161586 161587 161588 | *peOp2 = i; *ppRight = pList->a[1].pExpr; *ppLeft = pCol; return 1; } } } }else if( pExpr->op>=TK_EQ ){ /* Comparison operators are a common case. Save a few comparisons for ** that common case by terminating early. */ assert( TK_NE < TK_EQ ); assert( TK_ISNOT < TK_EQ ); assert( TK_NOTNULL < TK_EQ ); return 0; }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ int res = 0; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; assert( pLeft->op!=TK_COLUMN || (ExprUseYTab(pLeft) && pLeft->y.pTab!=0) ); if( ExprIsVtab(pLeft) ){ res++; |
︙ | ︙ | |||
161174 161175 161176 161177 161178 161179 161180 | mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pGroupBy); mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pOrderBy); mask |= sqlite3WhereExprUsage(pMaskSet, pS->pWhere); mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving); if( ALWAYS(pSrc!=0) ){ int i; for(i=0; i<pSrc->nSrc; i++){ | > | > | 162091 162092 162093 162094 162095 162096 162097 162098 162099 162100 162101 162102 162103 162104 162105 162106 162107 | mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pGroupBy); mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pOrderBy); mask |= sqlite3WhereExprUsage(pMaskSet, pS->pWhere); mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving); if( ALWAYS(pSrc!=0) ){ int i; for(i=0; i<pSrc->nSrc; i++){ if( pSrc->a[i].fg.isSubquery ){ mask |= exprSelectUsage(pMaskSet, pSrc->a[i].u4.pSubq->pSelect); } if( pSrc->a[i].fg.isUsing==0 ){ mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn); } if( pSrc->a[i].fg.isTabFunc ){ mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg); } } |
︙ | ︙ | |||
161212 161213 161214 161215 161216 161217 161218 | int j /* Start looking with the j-th pFrom entry */ ){ Index *pIdx; int i; int iCur; do{ iCur = pFrom->a[j].iCursor; | | | 162131 162132 162133 162134 162135 162136 162137 162138 162139 162140 162141 162142 162143 162144 162145 | int j /* Start looking with the j-th pFrom entry */ ){ Index *pIdx; int i; int iCur; do{ iCur = pFrom->a[j].iCursor; for(pIdx=pFrom->a[j].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->aColExpr==0 ) continue; for(i=0; i<pIdx->nKeyCol; i++){ if( pIdx->aiColumn[i]!=XN_EXPR ) continue; assert( pIdx->bHasExpr ); if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0 && !sqlite3ExprIsConstant(0,pIdx->aColExpr->a[i].pExpr) ){ |
︙ | ︙ | |||
161256 161257 161258 161259 161260 161261 161262 | aiCurCol[0] = pExpr->iTable; aiCurCol[1] = pExpr->iColumn; return 1; } for(i=0; i<pFrom->nSrc; i++){ Index *pIdx; | | | 162175 162176 162177 162178 162179 162180 162181 162182 162183 162184 162185 162186 162187 162188 162189 | aiCurCol[0] = pExpr->iTable; aiCurCol[1] = pExpr->iColumn; return 1; } for(i=0; i<pFrom->nSrc; i++){ Index *pIdx; for(pIdx=pFrom->a[i].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->aColExpr ){ return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i); } } } return 0; } |
︙ | ︙ | |||
161799 161800 161801 161802 161803 161804 161805 | int eMatchOp /* SQLITE_INDEX_CONSTRAINT_LIMIT or _OFFSET */ ){ Parse *pParse = pWC->pWInfo->pParse; sqlite3 *db = pParse->db; Expr *pNew; int iVal = 0; | | | 162718 162719 162720 162721 162722 162723 162724 162725 162726 162727 162728 162729 162730 162731 162732 | int eMatchOp /* SQLITE_INDEX_CONSTRAINT_LIMIT or _OFFSET */ ){ Parse *pParse = pWC->pWInfo->pParse; sqlite3 *db = pParse->db; Expr *pNew; int iVal = 0; if( sqlite3ExprIsInteger(pExpr, &iVal, pParse) && iVal>=0 ){ Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0); if( pVal==0 ) return; ExprSetProperty(pVal, EP_IntValue); pVal->u.iValue = iVal; pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal); }else{ Expr *pVal = sqlite3Expr(db, TK_REGISTER, 0); |
︙ | ︙ | |||
161844 161845 161846 161847 161848 161849 161850 | ** exist only so that they may be passed to the xBestIndex method of the ** single virtual table in the FROM clause of the SELECT. */ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */ if( p->pGroupBy==0 && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ | | | 162763 162764 162765 162766 162767 162768 162769 162770 162771 162772 162773 162774 162775 162776 162777 | ** exist only so that they may be passed to the xBestIndex method of the ** single virtual table in the FROM clause of the SELECT. */ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */ if( p->pGroupBy==0 && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pSTab)) /* 3 */ ){ ExprList *pOrderBy = p->pOrderBy; int iCsr = p->pSrc->a[0].iCursor; int ii; /* Check condition (4). Return early if it is not met. */ for(ii=0; ii<pWC->nTerm; ii++){ |
︙ | ︙ | |||
162065 162066 162067 162068 162069 162070 162071 | ){ Table *pTab; int j, k; ExprList *pArgs; Expr *pColRef; Expr *pTerm; if( pItem->fg.isTabFunc==0 ) return; | | | 162984 162985 162986 162987 162988 162989 162990 162991 162992 162993 162994 162995 162996 162997 162998 | ){ Table *pTab; int j, k; ExprList *pArgs; Expr *pColRef; Expr *pTerm; if( pItem->fg.isTabFunc==0 ) return; pTab = pItem->pSTab; assert( pTab!=0 ); pArgs = pItem->u1.pFuncArg; if( pArgs==0 ) return; for(j=k=0; j<pArgs->nExpr; j++){ Expr *pRhs; u32 joinType; while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;} |
︙ | ︙ | |||
162749 162750 162751 162752 162753 162754 162755 | int iBase; /* If there is more than one table or sub-select in the FROM clause of ** this query, then it will not be possible to show that the DISTINCT ** clause is redundant. */ if( pTabList->nSrc!=1 ) return 0; iBase = pTabList->a[0].iCursor; | | | 163668 163669 163670 163671 163672 163673 163674 163675 163676 163677 163678 163679 163680 163681 163682 | int iBase; /* If there is more than one table or sub-select in the FROM clause of ** this query, then it will not be possible to show that the DISTINCT ** clause is redundant. */ if( pTabList->nSrc!=1 ) return 0; iBase = pTabList->a[0].iCursor; pTab = pTabList->a[0].pSTab; /* If any of the expressions is an IPK column on table iBase, then return ** true. Note: The (p->iTable==iBase) part of this test may be false if the ** current SELECT is a correlated sub-query. */ for(i=0; i<pDistinct->nExpr; i++){ Expr *p = sqlite3ExprSkipCollateAndLikely(pDistinct->a[i].pExpr); |
︙ | ︙ | |||
162824 162825 162826 162827 162828 162829 162830 162831 162832 162833 162834 162835 162836 162837 | int iRegister, /* The first column is in this register */ int iAutoidxCur /* If non-zero, cursor of autoindex being generated */ ){ Vdbe *v = pParse->pVdbe; VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); int iEnd = sqlite3VdbeCurrentAddr(v); if( pParse->db->mallocFailed ) return; for(; iStart<iEnd; iStart++, pOp++){ if( pOp->p1!=iTabCur ) continue; if( pOp->opcode==OP_Column ){ #ifdef SQLITE_DEBUG if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ printf("TRANSLATE OP_Column to OP_Copy at %d\n", iStart); } | > > > > > > | 163743 163744 163745 163746 163747 163748 163749 163750 163751 163752 163753 163754 163755 163756 163757 163758 163759 163760 163761 163762 | int iRegister, /* The first column is in this register */ int iAutoidxCur /* If non-zero, cursor of autoindex being generated */ ){ Vdbe *v = pParse->pVdbe; VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); int iEnd = sqlite3VdbeCurrentAddr(v); if( pParse->db->mallocFailed ) return; #ifdef SQLITE_DEBUG if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ printf("CHECKING for column-to-copy on cursor %d for %d..%d\n", iTabCur, iStart, iEnd); } #endif for(; iStart<iEnd; iStart++, pOp++){ if( pOp->p1!=iTabCur ) continue; if( pOp->opcode==OP_Column ){ #ifdef SQLITE_DEBUG if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ printf("TRANSLATE OP_Column to OP_Copy at %d\n", iStart); } |
︙ | ︙ | |||
162945 162946 162947 162948 162949 162950 162951 162952 162953 162954 162955 162956 162957 162958 162959 162960 162961 162962 162963 162964 162965 162966 162967 162968 162969 162970 162971 162972 162973 162974 162975 | && ExprHasProperty(pTerm->pExpr, EP_InnerON) ){ return 0; } return 1; } #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* ** Return TRUE if the WHERE clause term pTerm is of a form where it ** could be used with an index to access pSrc, assuming an appropriate ** index existed. */ static int termCanDriveIndex( const WhereTerm *pTerm, /* WHERE clause term to check */ const SrcItem *pSrc, /* Table we are trying to access */ const Bitmask notReady /* Tables in outer loops of the join */ ){ char aff; if( pTerm->leftCursor!=pSrc->iCursor ) return 0; if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; assert( (pSrc->fg.jointype & JT_RIGHT)==0 ); if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 && !constraintCompatibleWithOuterJoin(pTerm,pSrc) ){ return 0; /* See https://sqlite.org/forum/forumpost/51e6959f61 */ } if( (pTerm->prereqRight & notReady)!=0 ) return 0; assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | | | 163870 163871 163872 163873 163874 163875 163876 163877 163878 163879 163880 163881 163882 163883 163884 163885 163886 163887 163888 163889 163890 163891 163892 163893 163894 163895 163896 163897 163898 163899 163900 163901 163902 163903 163904 163905 163906 163907 163908 163909 163910 163911 163912 163913 163914 163915 163916 163917 163918 163919 163920 163921 163922 163923 163924 163925 163926 163927 163928 163929 163930 163931 163932 163933 163934 163935 163936 163937 163938 163939 163940 163941 163942 163943 163944 163945 163946 163947 163948 163949 | && ExprHasProperty(pTerm->pExpr, EP_InnerON) ){ return 0; } return 1; } #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* ** Return true if column iCol of table pTab seem like it might be a ** good column to use as part of a query-time index. ** ** Current algorithm (subject to improvement!): ** ** 1. If iCol is already the left-most column of some other index, ** then return false. ** ** 2. If iCol is part of an existing index that has an aiRowLogEst of ** more than 20, then return false. ** ** 3. If no disqualifying conditions above are found, return true. */ static SQLITE_NOINLINE int columnIsGoodIndexCandidate( const Table *pTab, int iCol ){ const Index *pIdx; for(pIdx = pTab->pIndex; pIdx!=0; pIdx=pIdx->pNext){ int j; for(j=0; j<pIdx->nKeyCol; j++){ if( pIdx->aiColumn[j]==iCol ){ if( j==0 ) return 0; if( pIdx->hasStat1 && pIdx->aiRowLogEst[j+1]>20 ) return 0; break; } } } return 1; } #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* ** Return TRUE if the WHERE clause term pTerm is of a form where it ** could be used with an index to access pSrc, assuming an appropriate ** index existed. */ static int termCanDriveIndex( const WhereTerm *pTerm, /* WHERE clause term to check */ const SrcItem *pSrc, /* Table we are trying to access */ const Bitmask notReady /* Tables in outer loops of the join */ ){ char aff; int leftCol; if( pTerm->leftCursor!=pSrc->iCursor ) return 0; if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; assert( (pSrc->fg.jointype & JT_RIGHT)==0 ); if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 && !constraintCompatibleWithOuterJoin(pTerm,pSrc) ){ return 0; /* See https://sqlite.org/forum/forumpost/51e6959f61 */ } if( (pTerm->prereqRight & notReady)!=0 ) return 0; assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); leftCol = pTerm->u.x.leftColumn; if( leftCol<0 ) return 0; aff = pSrc->pSTab->aCol[leftCol].affinity; if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; testcase( pTerm->pExpr->op==TK_IS ); return columnIsGoodIndexCandidate(pSrc->pSTab, leftCol); } #endif #ifndef SQLITE_OMIT_AUTOMATIC_INDEX #ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
︙ | ︙ | |||
163081 163082 163083 163084 163085 163086 163087 | addrInit = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); /* Count the number of columns that will be added to the index ** and used to match WHERE clause constraints */ nKeyCol = 0; pTabList = pWC->pWInfo->pTabList; pSrc = &pTabList->a[pLevel->iFrom]; | | | 164043 164044 164045 164046 164047 164048 164049 164050 164051 164052 164053 164054 164055 164056 164057 | addrInit = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); /* Count the number of columns that will be added to the index ** and used to match WHERE clause constraints */ nKeyCol = 0; pTabList = pWC->pWInfo->pTabList; pSrc = &pTabList->a[pLevel->iFrom]; pTable = pSrc->pSTab; pWCEnd = &pWC->a[pWC->nTerm]; pLoop = pLevel->pWLoop; idxCols = 0; for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ Expr *pExpr = pTerm->pExpr; /* Make the automatic index a partial index if there are terms in the ** WHERE clause (or the ON clause of a LEFT join) that constrain which |
︙ | ︙ | |||
163223 163224 163225 163226 163227 163228 163229 | pLevel->regFilter = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter); } /* Fill the automatic index with content */ assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] ); if( pSrc->fg.viaCoroutine ){ | | > > > > > | | | 164185 164186 164187 164188 164189 164190 164191 164192 164193 164194 164195 164196 164197 164198 164199 164200 164201 164202 164203 164204 164205 164206 164207 164208 164209 | pLevel->regFilter = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter); } /* Fill the automatic index with content */ assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] ); if( pSrc->fg.viaCoroutine ){ int regYield; Subquery *pSubq; assert( pSrc->fg.isSubquery ); pSubq = pSrc->u4.pSubq; assert( pSubq!=0 ); regYield = pSubq->regReturn; addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub); addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); VdbeCoverage(v); VdbeComment((v, "next row of %s", pSrc->pSTab->zName)); }else{ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); } if( pPartial ){ iContinue = sqlite3VdbeMakeLabel(pParse); sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL); pLoop->wsFlags |= WHERE_PARTIALIDX; |
︙ | ︙ | |||
163250 163251 163252 163253 163254 163255 163256 163257 163258 163259 163260 | regBase, pLoop->u.btree.nEq); } sqlite3VdbeScanStatusCounters(v, addrExp, addrExp, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); if( pSrc->fg.viaCoroutine ){ sqlite3VdbeChangeP2(v, addrCounter, regBase+n); testcase( pParse->db->mallocFailed ); assert( pLevel->iIdxCur>0 ); translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, | > | | 164217 164218 164219 164220 164221 164222 164223 164224 164225 164226 164227 164228 164229 164230 164231 164232 164233 164234 164235 164236 | regBase, pLoop->u.btree.nEq); } sqlite3VdbeScanStatusCounters(v, addrExp, addrExp, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); if( pSrc->fg.viaCoroutine ){ assert( pSrc->fg.isSubquery && pSrc->u4.pSubq!=0 ); sqlite3VdbeChangeP2(v, addrCounter, regBase+n); testcase( pParse->db->mallocFailed ); assert( pLevel->iIdxCur>0 ); translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, pSrc->u4.pSubq->regResult, pLevel->iIdxCur); sqlite3VdbeGoto(v, addrTop); pSrc->fg.viaCoroutine = 0; }else{ sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); } sqlite3VdbeJumpHere(v, addrTop); |
︙ | ︙ | |||
163345 163346 163347 163348 163349 163350 163351 | ** testing complicated. By basing the blob size on the value in the ** sqlite_stat1 table, testing is much easier. */ pTabList = pWInfo->pTabList; iSrc = pLevel->iFrom; pItem = &pTabList->a[iSrc]; assert( pItem!=0 ); | | | 164313 164314 164315 164316 164317 164318 164319 164320 164321 164322 164323 164324 164325 164326 164327 | ** testing complicated. By basing the blob size on the value in the ** sqlite_stat1 table, testing is much easier. */ pTabList = pWInfo->pTabList; iSrc = pLevel->iFrom; pItem = &pTabList->a[iSrc]; assert( pItem!=0 ); pTab = pItem->pSTab; assert( pTab!=0 ); sz = sqlite3LogEstToInt(pTab->nRowLogEst); if( sz<10000 ){ sz = 10000; }else if( sz>10000000 ){ sz = 10000000; } |
︙ | ︙ | |||
163376 163377 163378 163379 163380 163381 163382 | sqlite3ReleaseTempReg(pParse, r1); }else{ Index *pIdx = pLoop->u.btree.pIndex; int n = pLoop->u.btree.nEq; int r1 = sqlite3GetTempRange(pParse, n); int jj; for(jj=0; jj<n; jj++){ | | | 164344 164345 164346 164347 164348 164349 164350 164351 164352 164353 164354 164355 164356 164357 164358 | sqlite3ReleaseTempReg(pParse, r1); }else{ Index *pIdx = pLoop->u.btree.pIndex; int n = pLoop->u.btree.nEq; int r1 = sqlite3GetTempRange(pParse, n); int jj; for(jj=0; jj<n; jj++){ assert( pIdx->pTable==pItem->pSTab ); sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj); } sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n); sqlite3ReleaseTempRange(pParse, r1, n); } sqlite3VdbeResolveLabel(v, addrCont); sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); |
︙ | ︙ | |||
163414 163415 163416 163417 163418 163419 163420 163421 163422 163423 163424 163425 163426 163427 | sqlite3VdbeJumpHere(v, addrOnce); pParse->pIdxEpr = saved_pIdxEpr; pParse->pIdxPartExpr = saved_pIdxPartExpr; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Allocate and populate an sqlite3_index_info structure. It is the ** responsibility of the caller to eventually release the structure ** by passing the pointer returned by this function to freeIndexInfo(). */ static sqlite3_index_info *allocateIndexInfo( WhereInfo *pWInfo, /* The WHERE clause */ | > > > > > > > > > > > > > > | 164382 164383 164384 164385 164386 164387 164388 164389 164390 164391 164392 164393 164394 164395 164396 164397 164398 164399 164400 164401 164402 164403 164404 164405 164406 164407 164408 164409 | sqlite3VdbeJumpHere(v, addrOnce); pParse->pIdxEpr = saved_pIdxEpr; pParse->pIdxPartExpr = saved_pIdxPartExpr; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Return term iTerm of the WhereClause passed as the first argument. Terms ** are numbered from 0 upwards, starting with the terms in pWC->a[], then ** those in pWC->pOuter->a[] (if any), and so on. */ static WhereTerm *termFromWhereClause(WhereClause *pWC, int iTerm){ WhereClause *p; for(p=pWC; p; p=p->pOuter){ if( iTerm<p->nTerm ) return &p->a[iTerm]; iTerm -= p->nTerm; } return 0; } /* ** Allocate and populate an sqlite3_index_info structure. It is the ** responsibility of the caller to eventually release the structure ** by passing the pointer returned by this function to freeIndexInfo(). */ static sqlite3_index_info *allocateIndexInfo( WhereInfo *pWInfo, /* The WHERE clause */ |
︙ | ︙ | |||
163440 163441 163442 163443 163444 163445 163446 163447 163448 | WhereTerm *pTerm; int nOrderBy; sqlite3_index_info *pIdxInfo; u16 mNoOmit = 0; const Table *pTab; int eDistinct = 0; ExprList *pOrderBy = pWInfo->pOrderBy; assert( pSrc!=0 ); | > | > | | | | | | | | | | | | | | | | | | | | | > | 164422 164423 164424 164425 164426 164427 164428 164429 164430 164431 164432 164433 164434 164435 164436 164437 164438 164439 164440 164441 164442 164443 164444 164445 164446 164447 164448 164449 164450 164451 164452 164453 164454 164455 164456 164457 164458 164459 164460 164461 164462 164463 164464 164465 164466 164467 164468 164469 164470 | WhereTerm *pTerm; int nOrderBy; sqlite3_index_info *pIdxInfo; u16 mNoOmit = 0; const Table *pTab; int eDistinct = 0; ExprList *pOrderBy = pWInfo->pOrderBy; WhereClause *p; assert( pSrc!=0 ); pTab = pSrc->pSTab; assert( pTab!=0 ); assert( IsVirtual(pTab) ); /* Find all WHERE clause constraints referring to this virtual table. ** Mark each term with the TERM_OK flag. Set nTerm to the number of ** terms found. */ for(p=pWC, nTerm=0; p; p=p->pOuter){ for(i=0, pTerm=p->a; i<p->nTerm; i++, pTerm++){ pTerm->wtFlags &= ~TERM_OK; if( pTerm->leftCursor != pSrc->iCursor ) continue; if( pTerm->prereqRight & mUnusable ) continue; assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); testcase( pTerm->eOperator & WO_IN ); testcase( pTerm->eOperator & WO_ISNULL ); testcase( pTerm->eOperator & WO_IS ); testcase( pTerm->eOperator & WO_ALL ); if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; if( pTerm->wtFlags & TERM_VNULL ) continue; assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); assert( pTerm->u.x.leftColumn>=XN_ROWID ); assert( pTerm->u.x.leftColumn<pTab->nCol ); if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 && !constraintCompatibleWithOuterJoin(pTerm,pSrc) ){ continue; } nTerm++; pTerm->wtFlags |= TERM_OK; } } /* If the ORDER BY clause contains only columns in the current ** virtual table then allocate space for the aOrderBy part of ** the sqlite3_index_info structure. */ nOrderBy = 0; |
︙ | ︙ | |||
163546 163547 163548 163549 163550 163551 163552 163553 163554 163555 163556 | pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1]; pIdxCons = (struct sqlite3_index_constraint*)&pHidden->aRhs[nTerm]; pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; pIdxInfo->aConstraint = pIdxCons; pIdxInfo->aOrderBy = pIdxOrderBy; pIdxInfo->aConstraintUsage = pUsage; pHidden->pWC = pWC; pHidden->pParse = pParse; pHidden->eDistinct = eDistinct; pHidden->mIn = 0; | > > > > > > > > > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > > > > > > > < > > > | 164531 164532 164533 164534 164535 164536 164537 164538 164539 164540 164541 164542 164543 164544 164545 164546 164547 164548 164549 164550 164551 164552 164553 164554 164555 164556 164557 164558 164559 164560 164561 164562 164563 164564 164565 164566 164567 164568 164569 164570 164571 164572 164573 164574 164575 164576 164577 164578 164579 164580 164581 164582 164583 164584 164585 164586 164587 164588 164589 164590 164591 164592 164593 164594 164595 164596 164597 164598 164599 164600 164601 164602 164603 164604 164605 164606 164607 164608 164609 164610 164611 164612 164613 164614 164615 164616 164617 164618 164619 164620 164621 164622 164623 164624 164625 164626 164627 164628 164629 164630 164631 164632 164633 164634 164635 164636 164637 164638 164639 164640 164641 164642 164643 164644 164645 164646 164647 164648 164649 164650 164651 164652 164653 164654 164655 164656 164657 164658 164659 164660 164661 164662 164663 164664 164665 164666 164667 164668 164669 164670 164671 164672 164673 164674 164675 164676 164677 164678 | pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1]; pIdxCons = (struct sqlite3_index_constraint*)&pHidden->aRhs[nTerm]; pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; pIdxInfo->aConstraint = pIdxCons; pIdxInfo->aOrderBy = pIdxOrderBy; pIdxInfo->aConstraintUsage = pUsage; pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; if( HasRowid(pTab)==0 ){ /* Ensure that all bits associated with PK columns are set. This is to ** ensure they are available for cases like RIGHT joins or OR loops. */ Index *pPk = sqlite3PrimaryKeyIndex((Table*)pTab); assert( pPk!=0 ); for(i=0; i<pPk->nKeyCol; i++){ int iCol = pPk->aiColumn[i]; assert( iCol>=0 ); if( iCol>=BMS-1 ) iCol = BMS-1; pIdxInfo->colUsed |= MASKBIT(iCol); } } pHidden->pWC = pWC; pHidden->pParse = pParse; pHidden->eDistinct = eDistinct; pHidden->mIn = 0; for(p=pWC, i=j=0; p; p=p->pOuter){ int nLast = i+p->nTerm;; for(pTerm=p->a; i<nLast; i++, pTerm++){ u16 op; if( (pTerm->wtFlags & TERM_OK)==0 ) continue; pIdxCons[j].iColumn = pTerm->u.x.leftColumn; pIdxCons[j].iTermOffset = i; op = pTerm->eOperator & WO_ALL; if( op==WO_IN ){ if( (pTerm->wtFlags & TERM_SLICE)==0 ){ pHidden->mIn |= SMASKBIT32(j); } op = WO_EQ; } if( op==WO_AUX ){ pIdxCons[j].op = pTerm->eMatchOp; }else if( op & (WO_ISNULL|WO_IS) ){ if( op==WO_ISNULL ){ pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL; }else{ pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS; } }else{ pIdxCons[j].op = (u8)op; /* The direct assignment in the previous line is possible only because ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The ** following asserts verify this fact. */ assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); if( op & (WO_LT|WO_LE|WO_GT|WO_GE) && sqlite3ExprIsVector(pTerm->pExpr->pRight) ){ testcase( j!=i ); if( j<16 ) mNoOmit |= (1 << j); if( op==WO_LT ) pIdxCons[j].op = WO_LE; if( op==WO_GT ) pIdxCons[j].op = WO_GE; } } j++; } } assert( j==nTerm ); pIdxInfo->nConstraint = j; for(i=j=0; i<nOrderBy; i++){ Expr *pExpr = pOrderBy->a[i].pExpr; if( sqlite3ExprIsConstant(0, pExpr) ) continue; assert( pExpr->op==TK_COLUMN || (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN && pExpr->iColumn==pExpr->pLeft->iColumn) ); pIdxOrderBy[j].iColumn = pExpr->iColumn; pIdxOrderBy[j].desc = pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC; j++; } pIdxInfo->nOrderBy = j; *pmNoOmit = mNoOmit; return pIdxInfo; } /* ** Free and zero the sqlite3_index_info.idxStr value if needed. */ static void freeIdxStr(sqlite3_index_info *pIdxInfo){ if( pIdxInfo->needToFreeIdxStr ){ sqlite3_free(pIdxInfo->idxStr); pIdxInfo->idxStr = 0; pIdxInfo->needToFreeIdxStr = 0; } } /* ** Free an sqlite3_index_info structure allocated by allocateIndexInfo() ** and possibly modified by xBestIndex methods. */ static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){ HiddenIndexInfo *pHidden; int i; assert( pIdxInfo!=0 ); pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; assert( pHidden->pParse!=0 ); assert( pHidden->pParse->db==db ); for(i=0; i<pIdxInfo->nConstraint; i++){ sqlite3ValueFree(pHidden->aRhs[i]); /* IMP: R-14553-25174 */ pHidden->aRhs[i] = 0; } freeIdxStr(pIdxInfo); sqlite3DbFree(db, pIdxInfo); } /* ** The table object reference passed as the second argument to this function ** must represent a virtual table. This function invokes the xBestIndex() ** method of the virtual table with the sqlite3_index_info object that ** comes in as the 3rd argument to this function. ** ** If an error occurs, pParse is populated with an error message and an ** appropriate error code is returned. A return of SQLITE_CONSTRAINT from ** xBestIndex is not considered an error. SQLITE_CONSTRAINT indicates that ** the current configuration of "unusable" flags in sqlite3_index_info can ** not result in a valid plan. ** ** Whether or not an error is returned, it is the responsibility of the ** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates ** that this is required. */ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ int rc; sqlite3_vtab *pVtab; assert( IsVirtual(pTab) ); pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; whereTraceIndexInfoInputs(p, pTab); pParse->db->nSchemaLock++; rc = pVtab->pModule->xBestIndex(pVtab, p); pParse->db->nSchemaLock--; whereTraceIndexInfoOutputs(p, pTab); if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){ |
︙ | ︙ | |||
164420 164421 164422 164423 164424 164425 164426 | ** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31 */ SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){ if( pWC ){ WhereInfo *pWInfo = pWC->pWInfo; int nb = 1+(pWInfo->pTabList->nSrc+3)/4; SrcItem *pItem = pWInfo->pTabList->a + p->iTab; | | | 165435 165436 165437 165438 165439 165440 165441 165442 165443 165444 165445 165446 165447 165448 165449 | ** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31 */ SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){ if( pWC ){ WhereInfo *pWInfo = pWC->pWInfo; int nb = 1+(pWInfo->pTabList->nSrc+3)/4; SrcItem *pItem = pWInfo->pTabList->a + p->iTab; Table *pTab = pItem->pSTab; Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); sqlite3DebugPrintf(" %12s", pItem->zAlias ? pItem->zAlias : pTab->zName); }else{ sqlite3DebugPrintf("%c%2d.%03llx.%03llx %c%d", |
︙ | ︙ | |||
164978 164979 164980 164981 164982 164983 164984 | pLoop->nOut--; if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && (pTerm->wtFlags & TERM_HIGHTRUTH)==0 /* tag-20200224-1 */ ){ Expr *pRight = pTerm->pExpr->pRight; int k = 0; testcase( pTerm->pExpr->op==TK_IS ); | | | 165993 165994 165995 165996 165997 165998 165999 166000 166001 166002 166003 166004 166005 166006 166007 | pLoop->nOut--; if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && (pTerm->wtFlags & TERM_HIGHTRUTH)==0 /* tag-20200224-1 */ ){ Expr *pRight = pTerm->pExpr->pRight; int k = 0; testcase( pTerm->pExpr->op==TK_IS ); if( sqlite3ExprIsInteger(pRight, &k, 0) && k>=(-1) && k<=1 ){ k = 10; }else{ k = 20; } if( iReduce<k ){ pTerm->wtFlags |= TERM_HEURTRUTH; iReduce = k; |
︙ | ︙ | |||
165275 165276 165277 165278 165279 165280 165281 | int iCol = pProbe->aiColumn[saved_nEq]; pNew->wsFlags |= WHERE_COLUMN_EQ; assert( saved_nEq==pNew->u.btree.nEq ); if( iCol==XN_ROWID || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) ){ if( iCol==XN_ROWID || pProbe->uniqNotNull | | | 166290 166291 166292 166293 166294 166295 166296 166297 166298 166299 166300 166301 166302 166303 166304 | int iCol = pProbe->aiColumn[saved_nEq]; pNew->wsFlags |= WHERE_COLUMN_EQ; assert( saved_nEq==pNew->u.btree.nEq ); if( iCol==XN_ROWID || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) ){ if( iCol==XN_ROWID || pProbe->uniqNotNull || (pProbe->nKeyCol==1 && pProbe->onError && (eOp & WO_EQ)) ){ pNew->wsFlags |= WHERE_ONEROW; }else{ pNew->wsFlags |= WHERE_UNQ_WANTED; } } if( scan.iEquiv>1 ) pNew->wsFlags |= WHERE_TRANSCONS; |
︙ | ︙ | |||
165408 165409 165410 165411 165412 165413 165414 | /* Set rCostIdx to the estimated cost of visiting selected rows in the ** index. The estimate is the sum of two values: ** 1. The cost of doing one search-by-key to find the first matching ** entry ** 2. Stepping forward in the index pNew->nOut times to find all ** additional matching entries. */ | | | | 166423 166424 166425 166426 166427 166428 166429 166430 166431 166432 166433 166434 166435 166436 166437 166438 166439 166440 166441 166442 166443 166444 166445 | /* Set rCostIdx to the estimated cost of visiting selected rows in the ** index. The estimate is the sum of two values: ** 1. The cost of doing one search-by-key to find the first matching ** entry ** 2. Stepping forward in the index pNew->nOut times to find all ** additional matching entries. */ assert( pSrc->pSTab->szTabRow>0 ); if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ /* The pProbe->szIdxRow is low for an IPK table since the interior ** pages are small. Thus szIdxRow gives a good estimate of seek cost. ** But the leaf pages are full-size, so pProbe->szIdxRow would badly ** under-estimate the scanning cost. */ rCostIdx = pNew->nOut + 16; }else{ rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pSTab->szTabRow; } rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx); /* Estimate the cost of running the loop. If all data is coming ** from the index, then this is just the cost of doing the index ** lookup and scan. But if some data is coming out of the main table, ** we also have to add in the cost of doing pNew->nOut searches to |
︙ | ︙ | |||
165881 165882 165883 165884 165885 165886 165887 | WhereClause *pWC; /* The parsed WHERE clause */ Table *pTab; /* Table being queried */ pNew = pBuilder->pNew; pWInfo = pBuilder->pWInfo; pTabList = pWInfo->pTabList; pSrc = pTabList->a + pNew->iTab; | | | | 166896 166897 166898 166899 166900 166901 166902 166903 166904 166905 166906 166907 166908 166909 166910 166911 166912 | WhereClause *pWC; /* The parsed WHERE clause */ Table *pTab; /* Table being queried */ pNew = pBuilder->pNew; pWInfo = pBuilder->pWInfo; pTabList = pWInfo->pTabList; pSrc = pTabList->a + pNew->iTab; pTab = pSrc->pSTab; pWC = pBuilder->pWC; assert( !IsVirtual(pSrc->pSTab) ); if( pSrc->fg.isIndexedBy ){ assert( pSrc->fg.isCte==0 ); /* An INDEXED BY clause specifies a particular index to use */ pProbe = pSrc->u2.pIBIndex; }else if( !HasRowid(pTab) ){ pProbe = pTab->pIndex; |
︙ | ︙ | |||
165908 165909 165910 165911 165912 165913 165914 | sPk.aiRowLogEst = aiRowEstPk; sPk.onError = OE_Replace; sPk.pTable = pTab; sPk.szIdxRow = 3; /* TUNING: Interior rows of IPK table are very small */ sPk.idxType = SQLITE_IDXTYPE_IPK; aiRowEstPk[0] = pTab->nRowLogEst; aiRowEstPk[1] = 0; | | | 166923 166924 166925 166926 166927 166928 166929 166930 166931 166932 166933 166934 166935 166936 166937 | sPk.aiRowLogEst = aiRowEstPk; sPk.onError = OE_Replace; sPk.pTable = pTab; sPk.szIdxRow = 3; /* TUNING: Interior rows of IPK table are very small */ sPk.idxType = SQLITE_IDXTYPE_IPK; aiRowEstPk[0] = pTab->nRowLogEst; aiRowEstPk[1] = 0; pFirst = pSrc->pSTab->pIndex; if( pSrc->fg.notIndexed==0 ){ /* The real indices of the table are only considered if the ** NOT INDEXED qualifier is omitted from the FROM clause */ sPk.pNext = pFirst; } pProbe = &sPk; } |
︙ | ︙ | |||
165998 165999 166000 166001 166002 166003 166004 166005 166006 166007 166008 166009 166010 166011 | pNew->nSkip = 0; pNew->nLTerm = 0; pNew->iSortIdx = 0; pNew->rSetup = 0; pNew->prereq = mPrereq; pNew->nOut = rSize; pNew->u.btree.pIndex = pProbe; b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor); /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */ assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 ); if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ /* Integer primary key index */ pNew->wsFlags = WHERE_IPK; | > | 167013 167014 167015 167016 167017 167018 167019 167020 167021 167022 167023 167024 167025 167026 167027 | pNew->nSkip = 0; pNew->nLTerm = 0; pNew->iSortIdx = 0; pNew->rSetup = 0; pNew->prereq = mPrereq; pNew->nOut = rSize; pNew->u.btree.pIndex = pProbe; pNew->u.btree.pOrderBy = 0; b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor); /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */ assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 ); if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ /* Integer primary key index */ pNew->wsFlags = WHERE_IPK; |
︙ | ︙ | |||
166027 166028 166029 166030 166031 166032 166033 166034 166035 166036 166037 166038 166039 166040 | #ifdef SQLITE_ENABLE_STAT4 pNew->rRun = rSize + 16 - 2*((pTab->tabFlags & TF_HasStat4)!=0); #else pNew->rRun = rSize + 16; #endif ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); rc = whereLoopInsert(pBuilder, pNew); pNew->nOut = rSize; if( rc ) break; }else{ Bitmask m; if( pProbe->isCovering ){ m = 0; | > > > > | 167043 167044 167045 167046 167047 167048 167049 167050 167051 167052 167053 167054 167055 167056 167057 167058 167059 167060 | #ifdef SQLITE_ENABLE_STAT4 pNew->rRun = rSize + 16 - 2*((pTab->tabFlags & TF_HasStat4)!=0); #else pNew->rRun = rSize + 16; #endif ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); if( pSrc->fg.isSubquery ){ if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE; pNew->u.btree.pOrderBy = pSrc->u4.pSubq->pSelect->pOrderBy; } rc = whereLoopInsert(pBuilder, pNew); pNew->nOut = rSize; if( rc ) break; }else{ Bitmask m; if( pProbe->isCovering ){ m = 0; |
︙ | ︙ | |||
166064 166065 166066 166067 166068 166069 166070 | }else{ assert( isCov==WHERE_EXPRIDX ); WHERETRACE(0x200, ("-> %s might be a covering expression index" " according to whereIsCoveringIndex()\n", pProbe->zName)); } } | | > > | 167084 167085 167086 167087 167088 167089 167090 167091 167092 167093 167094 167095 167096 167097 167098 167099 167100 | }else{ assert( isCov==WHERE_EXPRIDX ); WHERETRACE(0x200, ("-> %s might be a covering expression index" " according to whereIsCoveringIndex()\n", pProbe->zName)); } } }else if( m==0 && (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700)) ){ WHERETRACE(0x200, ("-> %s a covering index according to bitmasks\n", pProbe->zName, m==0 ? "is" : "is not")); pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; } } |
︙ | ︙ | |||
166227 166228 166229 166230 166231 166232 166233 | *pbIn = 0; pNew->prereq = mPrereq; /* Set the usable flag on the subset of constraints identified by ** arguments mUsable and mExclude. */ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; for(i=0; i<nConstraint; i++, pIdxCons++){ | | < | > | | | < | 167249 167250 167251 167252 167253 167254 167255 167256 167257 167258 167259 167260 167261 167262 167263 167264 167265 167266 167267 167268 167269 167270 167271 167272 167273 167274 167275 167276 167277 167278 167279 167280 167281 167282 167283 167284 167285 167286 167287 167288 167289 167290 167291 167292 167293 167294 167295 167296 167297 167298 167299 167300 167301 167302 167303 167304 167305 167306 167307 167308 167309 167310 167311 167312 167313 167314 167315 167316 167317 167318 167319 167320 167321 | *pbIn = 0; pNew->prereq = mPrereq; /* Set the usable flag on the subset of constraints identified by ** arguments mUsable and mExclude. */ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; for(i=0; i<nConstraint; i++, pIdxCons++){ WhereTerm *pTerm = termFromWhereClause(pWC, pIdxCons->iTermOffset); pIdxCons->usable = 0; if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight && (pTerm->eOperator & mExclude)==0 && (pbRetryLimit || !isLimitTerm(pTerm)) ){ pIdxCons->usable = 1; } } /* Initialize the output fields of the sqlite3_index_info structure */ memset(pUsage, 0, sizeof(pUsage[0])*nConstraint); assert( pIdxInfo->needToFreeIdxStr==0 ); pIdxInfo->idxStr = 0; pIdxInfo->idxNum = 0; pIdxInfo->orderByConsumed = 0; pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; pIdxInfo->estimatedRows = 25; pIdxInfo->idxFlags = 0; pHidden->mHandleIn = 0; /* Invoke the virtual table xBestIndex() method */ rc = vtabBestIndex(pParse, pSrc->pSTab, pIdxInfo); if( rc ){ if( rc==SQLITE_CONSTRAINT ){ /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means ** that the particular combination of parameters provided is unusable. ** Make no entries in the loop table. */ WHERETRACE(0xffffffff, (" ^^^^--- non-viable plan rejected!\n")); freeIdxStr(pIdxInfo); return SQLITE_OK; } return rc; } mxTerm = -1; assert( pNew->nLSlot>=nConstraint ); memset(pNew->aLTerm, 0, sizeof(pNew->aLTerm[0])*nConstraint ); memset(&pNew->u.vtab, 0, sizeof(pNew->u.vtab)); pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; for(i=0; i<nConstraint; i++, pIdxCons++){ int iTerm; if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){ WhereTerm *pTerm; int j = pIdxCons->iTermOffset; if( iTerm>=nConstraint || j<0 || (pTerm = termFromWhereClause(pWC, j))==0 || pNew->aLTerm[iTerm]!=0 || pIdxCons->usable==0 ){ sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName); freeIdxStr(pIdxInfo); return SQLITE_ERROR; } testcase( iTerm==nConstraint-1 ); testcase( j==0 ); testcase( j==pWC->nTerm-1 ); pNew->prereq |= pTerm->prereqRight; assert( iTerm<pNew->nLSlot ); pNew->aLTerm[iTerm] = pTerm; if( iTerm>mxTerm ) mxTerm = iTerm; testcase( iTerm==15 ); testcase( iTerm==16 ); if( pUsage[i].omit ){ |
︙ | ︙ | |||
166331 166332 166333 166334 166335 166336 166337 | /* If there is an IN(...) term handled as an == (separate call to ** xFilter for each value on the RHS of the IN) and a LIMIT or ** OFFSET term handled as well, the plan is unusable. Similarly, ** if there is a LIMIT/OFFSET and there are other unused terms, ** the plan cannot be used. In these cases set variable *pbRetryLimit ** to true to tell the caller to retry with LIMIT and OFFSET ** disabled. */ | < < | < < | | > | 167352 167353 167354 167355 167356 167357 167358 167359 167360 167361 167362 167363 167364 167365 167366 167367 167368 167369 167370 167371 167372 167373 167374 167375 167376 167377 167378 167379 167380 167381 167382 167383 167384 167385 167386 167387 167388 167389 167390 | /* If there is an IN(...) term handled as an == (separate call to ** xFilter for each value on the RHS of the IN) and a LIMIT or ** OFFSET term handled as well, the plan is unusable. Similarly, ** if there is a LIMIT/OFFSET and there are other unused terms, ** the plan cannot be used. In these cases set variable *pbRetryLimit ** to true to tell the caller to retry with LIMIT and OFFSET ** disabled. */ freeIdxStr(pIdxInfo); *pbRetryLimit = 1; return SQLITE_OK; } } } pNew->nLTerm = mxTerm+1; for(i=0; i<=mxTerm; i++){ if( pNew->aLTerm[i]==0 ){ /* The non-zero argvIdx values must be contiguous. Raise an ** error if they are not */ sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName); freeIdxStr(pIdxInfo); return SQLITE_ERROR; } } assert( pNew->nLTerm<=pNew->nLSlot ); pNew->u.vtab.idxNum = pIdxInfo->idxNum; pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr; pIdxInfo->needToFreeIdxStr = 0; pNew->u.vtab.idxStr = pIdxInfo->idxStr; pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? pIdxInfo->nOrderBy : 0); pNew->u.vtab.bIdxNumHex = (pIdxInfo->idxFlags&SQLITE_INDEX_SCAN_HEX)!=0; pNew->rSetup = 0; pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated ** that the scan will visit at most one row. Clear it otherwise. */ if( pIdxInfo->idxFlags & SQLITE_INDEX_SCAN_UNIQUE ){ |
︙ | ︙ | |||
166403 166404 166405 166406 166407 166408 166409 | */ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; const char *zRet = 0; if( iCons>=0 && iCons<pIdxInfo->nConstraint ){ CollSeq *pC = 0; int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; | | | 167421 167422 167423 167424 167425 167426 167427 167428 167429 167430 167431 167432 167433 167434 167435 | */ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; const char *zRet = 0; if( iCons>=0 && iCons<pIdxInfo->nConstraint ){ CollSeq *pC = 0; int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; Expr *pX = termFromWhereClause(pHidden->pWC, iTerm)->pExpr; if( pX->pLeft ){ pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX); } zRet = (pC ? pC->zName : sqlite3StrBINARY); } return zRet; } |
︙ | ︙ | |||
166449 166450 166451 166452 166453 166454 166455 | HiddenIndexInfo *pH = (HiddenIndexInfo*)&pIdxInfo[1]; sqlite3_value *pVal = 0; int rc = SQLITE_OK; if( iCons<0 || iCons>=pIdxInfo->nConstraint ){ rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */ }else{ if( pH->aRhs[iCons]==0 ){ | > | > | 167467 167468 167469 167470 167471 167472 167473 167474 167475 167476 167477 167478 167479 167480 167481 167482 167483 | HiddenIndexInfo *pH = (HiddenIndexInfo*)&pIdxInfo[1]; sqlite3_value *pVal = 0; int rc = SQLITE_OK; if( iCons<0 || iCons>=pIdxInfo->nConstraint ){ rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */ }else{ if( pH->aRhs[iCons]==0 ){ WhereTerm *pTerm = termFromWhereClause( pH->pWC, pIdxInfo->aConstraint[iCons].iTermOffset ); rc = sqlite3ValueFromExpr( pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db), SQLITE_AFF_BLOB, &pH->aRhs[iCons] ); testcase( rc!=SQLITE_OK ); } pVal = pH->aRhs[iCons]; |
︙ | ︙ | |||
166547 166548 166549 166550 166551 166552 166553 | assert( (mPrereq & mUnusable)==0 ); pWInfo = pBuilder->pWInfo; pParse = pWInfo->pParse; pWC = pBuilder->pWC; pNew = pBuilder->pNew; pSrc = &pWInfo->pTabList->a[pNew->iTab]; | | | | 167567 167568 167569 167570 167571 167572 167573 167574 167575 167576 167577 167578 167579 167580 167581 167582 167583 167584 167585 167586 167587 167588 167589 167590 167591 167592 167593 167594 167595 | assert( (mPrereq & mUnusable)==0 ); pWInfo = pBuilder->pWInfo; pParse = pWInfo->pParse; pWC = pBuilder->pWC; pNew = pBuilder->pNew; pSrc = &pWInfo->pTabList->a[pNew->iTab]; assert( IsVirtual(pSrc->pSTab) ); p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit); if( p==0 ) return SQLITE_NOMEM_BKPT; pNew->rSetup = 0; pNew->wsFlags = WHERE_VIRTUALTABLE; pNew->nLTerm = 0; pNew->u.vtab.needFree = 0; nConstraint = p->nConstraint; if( whereLoopResize(pParse->db, pNew, nConstraint) ){ freeIndexInfo(pParse->db, p); return SQLITE_NOMEM_BKPT; } /* First call xBestIndex() with all constraints usable. */ WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pSTab->zName)); WHERETRACE(0x800, (" VirtualOne: all usable\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry ); if( bRetry ){ assert( rc==SQLITE_OK ); rc = whereLoopAddVirtualOne( |
︙ | ︙ | |||
166605 166606 166607 166608 166609 166610 166611 | /* Call xBestIndex once for each distinct value of (prereqRight & ~mPrereq) ** in the set of terms that apply to the current virtual table. */ while( rc==SQLITE_OK ){ int i; Bitmask mNext = ALLBITS; assert( mNext>0 ); for(i=0; i<nConstraint; i++){ | < | < > | 167625 167626 167627 167628 167629 167630 167631 167632 167633 167634 167635 167636 167637 167638 167639 167640 | /* Call xBestIndex once for each distinct value of (prereqRight & ~mPrereq) ** in the set of terms that apply to the current virtual table. */ while( rc==SQLITE_OK ){ int i; Bitmask mNext = ALLBITS; assert( mNext>0 ); for(i=0; i<nConstraint; i++){ int iTerm = p->aConstraint[i].iTermOffset; Bitmask mThis = termFromWhereClause(pWC, iTerm)->prereqRight & ~mPrereq; if( mThis>mPrev && mThis<mNext ) mNext = mThis; } mPrev = mNext; if( mNext==ALLBITS ) break; if( mNext==mBest || mNext==mBestNoIn ) continue; WHERETRACE(0x800, (" VirtualOne: mPrev=%04llx mNext=%04llx\n", (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext)); |
︙ | ︙ | |||
166643 166644 166645 166646 166647 166648 166649 | if( rc==SQLITE_OK && seenZeroNoIN==0 ){ WHERETRACE(0x800, (" VirtualOne: all disabled and w/o IN\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0); } } | < | | 167662 167663 167664 167665 167666 167667 167668 167669 167670 167671 167672 167673 167674 167675 167676 167677 | if( rc==SQLITE_OK && seenZeroNoIN==0 ){ WHERETRACE(0x800, (" VirtualOne: all disabled and w/o IN\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0); } } freeIndexInfo(pParse->db, p); WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pSTab->zName, rc)); return rc; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* ** Add WhereLoop entries to handle OR terms. This works for either ** btrees or virtual tables. |
︙ | ︙ | |||
166717 166718 166719 166720 166721 166722 166723 | WHERETRACE(0x400, ("OR-term %d of %p has %d subterms:\n", (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm)); if( sqlite3WhereTrace & 0x20000 ){ sqlite3WhereClausePrint(sSubBuild.pWC); } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE | | | 167735 167736 167737 167738 167739 167740 167741 167742 167743 167744 167745 167746 167747 167748 167749 | WHERETRACE(0x400, ("OR-term %d of %p has %d subterms:\n", (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm)); if( sqlite3WhereTrace & 0x20000 ){ sqlite3WhereClausePrint(sSubBuild.pWC); } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pSTab) ){ rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable); }else #endif { rc = whereLoopAddBtree(&sSubBuild, mPrereq); } if( rc==SQLITE_OK ){ |
︙ | ︙ | |||
166831 166832 166833 166834 166835 166836 166837 | if( pItem->fg.jointype & JT_LTORJ ) hasRightJoin = 1; mPrereq |= mPrior; bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0; }else if( !hasRightJoin ){ mPrereq = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE | | | 167849 167850 167851 167852 167853 167854 167855 167856 167857 167858 167859 167860 167861 167862 167863 | if( pItem->fg.jointype & JT_LTORJ ) hasRightJoin = 1; mPrereq |= mPrior; bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0; }else if( !hasRightJoin ){ mPrereq = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pSTab) ){ SrcItem *p; for(p=&pItem[1]; p<pEnd; p++){ if( mUnusable || (p->fg.jointype & (JT_OUTER|JT_CROSS)) ){ mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); } } rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable); |
︙ | ︙ | |||
166862 166863 166864 166865 166866 166867 166868 166869 166870 166871 166872 166873 166874 166875 | } } } whereLoopClear(db, pNew); return rc; } /* ** Examine a WherePath (with the addition of the extra WhereLoop of the 6th ** parameters) to see if it outputs rows in the requested ORDER BY ** (or GROUP BY) without requiring a separate sort operation. Return N: ** ** N>0: N terms of the ORDER BY clause are satisfied | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 167880 167881 167882 167883 167884 167885 167886 167887 167888 167889 167890 167891 167892 167893 167894 167895 167896 167897 167898 167899 167900 167901 167902 167903 167904 167905 167906 167907 167908 167909 167910 167911 167912 167913 167914 167915 167916 167917 167918 167919 167920 167921 167922 167923 167924 167925 167926 167927 167928 167929 167930 167931 167932 167933 167934 167935 167936 167937 167938 167939 167940 167941 167942 167943 167944 167945 167946 167947 167948 167949 167950 167951 167952 167953 167954 167955 167956 167957 167958 167959 167960 167961 167962 167963 167964 167965 167966 167967 167968 167969 167970 167971 167972 167973 167974 167975 167976 167977 167978 167979 167980 167981 167982 167983 167984 | } } } whereLoopClear(db, pNew); return rc; } /* Implementation of the order-by-subquery optimization: ** ** WhereLoop pLoop, which the iLoop-th term of the nested loop, is really ** a subquery or CTE that has an ORDER BY clause. See if any of the terms ** in the subquery ORDER BY clause will satisfy pOrderBy from the outer ** query. Mark off all satisfied terms (by setting bits in *pOBSat) and ** return TRUE if they do. If not, return false. ** ** Example: ** ** CREATE TABLE t1(a,b,c, PRIMARY KEY(a,b)); ** CREATE TABLE t2(x,y); ** WITH t3(p,q) AS MATERIALIZED (SELECT x+y, x-y FROM t2 ORDER BY x+y) ** SELECT * FROM t3 JOIN t1 ON a=q ORDER BY p, b; ** ** The CTE named "t3" comes out in the natural order of "p", so the first ** first them of "ORDER BY p,b" is satisfied by a sequential scan of "t3" ** and sorting only needs to occur on the second term "b". ** ** Limitations: ** ** (1) The optimization is not applied if the outer ORDER BY contains ** a COLLATE clause. The optimization might be applied if the ** outer ORDER BY uses NULLS FIRST, NULLS LAST, ASC, and/or DESC as ** long as the subquery ORDER BY does the same. But if the ** outer ORDER BY uses COLLATE, even a redundant COLLATE, the ** optimization is bypassed. ** ** (2) The subquery ORDER BY terms must exactly match subquery result ** columns, including any COLLATE annotations. This routine relies ** on iOrderByCol to do matching between order by terms and result ** columns, and iOrderByCol will not be set if the result column ** and ORDER BY collations differ. ** ** (3) The subquery and outer ORDER BY can be in opposite directions as ** long as the subquery is materialized. If the subquery is ** implemented as a co-routine, the sort orders must be in the same ** direction because there is no way to run a co-routine backwards. */ static SQLITE_NOINLINE int wherePathMatchSubqueryOB( WhereInfo *pWInfo, /* The WHERE clause */ WhereLoop *pLoop, /* The nested loop term that is a subquery */ int iLoop, /* Which level of the nested loop. 0==outermost */ int iCur, /* Cursor used by the this loop */ ExprList *pOrderBy, /* The ORDER BY clause on the whole query */ Bitmask *pRevMask, /* When loops need to go in reverse order */ Bitmask *pOBSat /* Which terms of pOrderBy are satisfied so far */ ){ int iOB; /* Index into pOrderBy->a[] */ int jSub; /* Index into pSubOB->a[] */ u8 rev = 0; /* True if iOB and jSub sort in opposite directions */ u8 revIdx = 0; /* Sort direction for jSub */ Expr *pOBExpr; /* Current term of outer ORDER BY */ ExprList *pSubOB; /* Complete ORDER BY on the subquery */ pSubOB = pLoop->u.btree.pOrderBy; assert( pSubOB!=0 ); for(iOB=0; (MASKBIT(iOB) & *pOBSat)!=0; iOB++){} for(jSub=0; jSub<pSubOB->nExpr && iOB<pOrderBy->nExpr; jSub++, iOB++){ if( pSubOB->a[jSub].u.x.iOrderByCol==0 ) break; pOBExpr = pOrderBy->a[iOB].pExpr; if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) break; if( pOBExpr->iTable!=iCur ) break; if( pOBExpr->iColumn!=pSubOB->a[jSub].u.x.iOrderByCol-1 ) break; if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){ u8 sfOB = pOrderBy->a[iOB].fg.sortFlags; /* sortFlags for iOB */ u8 sfSub = pSubOB->a[jSub].fg.sortFlags; /* sortFlags for jSub */ if( (sfSub & KEYINFO_ORDER_BIGNULL) != (sfOB & KEYINFO_ORDER_BIGNULL) ){ break; } revIdx = sfSub & KEYINFO_ORDER_DESC; if( jSub>0 ){ if( (rev^revIdx)!=(sfOB & KEYINFO_ORDER_DESC) ){ break; } }else{ rev = revIdx ^ (sfOB & KEYINFO_ORDER_DESC); if( rev ){ if( (pLoop->wsFlags & WHERE_COROUTINE)!=0 ){ /* Cannot run a co-routine in reverse order */ break; } *pRevMask |= MASKBIT(iLoop); } } } *pOBSat |= MASKBIT(iOB); } return jSub>0; } /* ** Examine a WherePath (with the addition of the extra WhereLoop of the 6th ** parameters) to see if it outputs rows in the requested ORDER BY ** (or GROUP BY) without requiring a separate sort operation. Return N: ** ** N>0: N terms of the ORDER BY clause are satisfied |
︙ | ︙ | |||
167008 167009 167010 167011 167012 167013 167014 167015 167016 | testcase( pTerm->pExpr->op==TK_IS ); } obSat |= MASKBIT(i); } if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ if( pLoop->wsFlags & WHERE_IPK ){ pIndex = 0; nKeyCol = 0; | > > > > > > > > > > < | | 168117 168118 168119 168120 168121 168122 168123 168124 168125 168126 168127 168128 168129 168130 168131 168132 168133 168134 168135 168136 168137 168138 168139 168140 168141 168142 168143 168144 168145 168146 168147 168148 168149 168150 168151 168152 | testcase( pTerm->pExpr->op==TK_IS ); } obSat |= MASKBIT(i); } if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ if( pLoop->wsFlags & WHERE_IPK ){ if( pLoop->u.btree.pOrderBy && OptimizationEnabled(db, SQLITE_OrderBySubq) && wherePathMatchSubqueryOB(pWInfo,pLoop,iLoop,iCur, pOrderBy,pRevMask, &obSat) ){ nColumn = 0; isOrderDistinct = 0; }else{ nColumn = 1; } pIndex = 0; nKeyCol = 0; }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ return 0; }else{ nKeyCol = pIndex->nKeyCol; nColumn = pIndex->nColumn; assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); assert( pIndex->aiColumn[nColumn-1]==XN_ROWID || !HasRowid(pIndex->pTable)); /* All relevant terms of the index must also be non-NULL in order ** for isOrderDistinct to be true. So the isOrderDistinct value ** computed here might be a false positive. Corrections will be ** made at tag-20210426-1 below */ isOrderDistinct = IsUniqueIndex(pIndex) && (pLoop->wsFlags & WHERE_SKIPSCAN)==0; } /* Loop through all columns of the index and deal with the ones |
︙ | ︙ | |||
167105 167106 167107 167108 167109 167110 167111 | } if( iColumn==XN_EXPR ){ isOrderDistinct = 0; } } /* Find the ORDER BY term that corresponds to the j-th column | | | 168223 168224 168225 168226 168227 168228 168229 168230 168231 168232 168233 168234 168235 168236 168237 | } if( iColumn==XN_EXPR ){ isOrderDistinct = 0; } } /* Find the ORDER BY term that corresponds to the j-th column ** of the index and mark that ORDER BY term having been satisfied. */ isMatch = 0; for(i=0; bOnce && i<nOrderBy; i++){ if( MASKBIT(i) & obSat ) continue; pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr); testcase( wctrlFlags & WHERE_GROUPBY ); testcase( wctrlFlags & WHERE_DISTINCTBY ); |
︙ | ︙ | |||
167311 167312 167313 167314 167315 167316 167317 167318 167319 167320 167321 167322 167323 167324 | /* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT ** reduces the number of output rows by a factor of 2 */ if( nRow>10 ){ nRow -= 10; assert( 10==sqlite3LogEst(2) ); } } rSortCost += estLog(nRow); return rSortCost; } /* ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine ** attempts to find the lowest cost path that visits each WhereLoop ** once. This path is then loaded into the pWInfo->a[].pWLoop fields. ** ** Assume that the total number of output rows that will need to be sorted | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 168429 168430 168431 168432 168433 168434 168435 168436 168437 168438 168439 168440 168441 168442 168443 168444 168445 168446 168447 168448 168449 168450 168451 168452 168453 168454 168455 168456 168457 168458 168459 168460 168461 168462 168463 168464 168465 168466 168467 168468 168469 168470 168471 168472 168473 168474 168475 168476 168477 168478 168479 168480 168481 168482 168483 168484 168485 168486 168487 168488 168489 168490 168491 168492 168493 168494 168495 168496 168497 168498 168499 168500 168501 168502 168503 168504 168505 168506 168507 168508 168509 168510 168511 168512 168513 168514 168515 168516 168517 168518 168519 | /* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT ** reduces the number of output rows by a factor of 2 */ if( nRow>10 ){ nRow -= 10; assert( 10==sqlite3LogEst(2) ); } } rSortCost += estLog(nRow); return rSortCost; } /* ** Compute the maximum number of paths in the solver algorithm, for ** queries that have three or more terms in the FROM clause. Queries with ** two or fewer FROM clause terms are handled by the caller. ** ** Query planning is NP-hard. We must limit the number of paths at ** each step of the solver search algorithm to avoid exponential behavior. ** ** The value returned is a tuning parameter. Currently the value is: ** ** 18 for star queries ** 12 otherwise ** ** For the purposes of SQLite, a star-query is defined as a query ** with a large central table that is joined against four or more ** smaller tables. The central table is called the "fact" table. ** The smaller tables that get joined are "dimension tables". ** ** SIDE EFFECT: (and really the whole point of this subroutine) ** ** If pWInfo describes a star-query, then the cost on WhereLoops for the ** fact table is reduced. This heuristic helps keep fact tables in ** outer loops. Without this heuristic, paths with fact tables in outer ** loops tend to get pruned by the mxChoice limit on the number of paths, ** resulting in poor query plans. The total amount of heuristic cost ** adjustment is stored in pWInfo->nOutStarDelta and the cost adjustment ** for each WhereLoop is stored in its rStarDelta field. */ static int computeMxChoice(WhereInfo *pWInfo, LogEst nRowEst){ int nLoop = pWInfo->nLevel; /* Number of terms in the join */ if( nRowEst==0 && nLoop>=5 ){ /* Check to see if we are dealing with a star schema and if so, reduce ** the cost of fact tables relative to dimension tables, as a heuristic ** to help keep the fact tables in outer loops. */ int iLoop; /* Counter over join terms */ Bitmask m; /* Bitmask for current loop */ assert( pWInfo->nOutStarDelta==0 ); for(iLoop=0, m=1; iLoop<nLoop; iLoop++, m<<=1){ WhereLoop *pWLoop; /* For looping over WhereLoops */ int nDep = 0; /* Number of dimension tables */ LogEst rDelta; /* Heuristic cost adjustment */ Bitmask mSeen = 0; /* Mask of dimension tables */ for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ if( (pWLoop->prereq & m)!=0 && (pWLoop->maskSelf & mSeen)==0 ){ nDep++; mSeen |= pWLoop->maskSelf; } } if( nDep<=3 ) continue; rDelta = 15*(nDep-3); #ifdef WHERETRACE_ENABLED /* 0x4 */ if( sqlite3WhereTrace&0x4 ){ SrcItem *pItem = pWInfo->pTabList->a + iLoop; sqlite3DebugPrintf("Fact-table %s: %d dimensions, cost reduced %d\n", pItem->zAlias ? pItem->zAlias : pItem->pSTab->zName, nDep, rDelta); } #endif if( pWInfo->nOutStarDelta==0 ){ for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ pWLoop->rStarDelta = 0; } } pWInfo->nOutStarDelta += rDelta; for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ if( pWLoop->maskSelf==m ){ pWLoop->rRun -= rDelta; pWLoop->nOut -= rDelta; pWLoop->rStarDelta = rDelta; } } } } return pWInfo->nOutStarDelta>0 ? 18 : 12; } /* ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine ** attempts to find the lowest cost path that visits each WhereLoop ** once. This path is then loaded into the pWInfo->a[].pWLoop fields. ** ** Assume that the total number of output rows that will need to be sorted |
︙ | ︙ | |||
167347 167348 167349 167350 167351 167352 167353 | WhereLoop **pX; /* Used to divy up the pSpace memory */ LogEst *aSortCost = 0; /* Sorting and partial sorting costs */ char *pSpace; /* Temporary memory used by this routine */ int nSpace; /* Bytes of space allocated at pSpace */ pParse = pWInfo->pParse; nLoop = pWInfo->nLevel; | < < < < < > > > > > > > > > > > > > > > > > | 168542 168543 168544 168545 168546 168547 168548 168549 168550 168551 168552 168553 168554 168555 168556 168557 168558 168559 168560 168561 168562 168563 168564 168565 168566 168567 168568 168569 168570 168571 168572 168573 168574 | WhereLoop **pX; /* Used to divy up the pSpace memory */ LogEst *aSortCost = 0; /* Sorting and partial sorting costs */ char *pSpace; /* Temporary memory used by this routine */ int nSpace; /* Bytes of space allocated at pSpace */ pParse = pWInfo->pParse; nLoop = pWInfo->nLevel; WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n", nRowEst, pParse->nQueryLoop)); /* TUNING: mxChoice is the maximum number of possible paths to preserve ** at each step. Based on the number of loops in the FROM clause: ** ** nLoop mxChoice ** ----- -------- ** 1 1 // the most common case ** 2 5 ** 3+ 12 or 18 // see computeMxChoice() */ if( nLoop<=1 ){ mxChoice = 1; }else if( nLoop==2 ){ mxChoice = 5; }else{ mxChoice = computeMxChoice(pWInfo, nRowEst); } assert( nLoop<=pWInfo->pTabList->nSrc ); /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this ** case the purpose of this call is to estimate the number of rows returned ** by the overall query. Once this estimate has been obtained, the caller ** will invoke this function a second time, passing the estimate as the ** nRowEst parameter. */ if( pWInfo->pOrderBy==0 || nRowEst==0 ){ |
︙ | ︙ | |||
167436 167437 167438 167439 167440 167441 167442 | ** index is useful in the outer loop of a correlated subquery. */ assert( 10==sqlite3LogEst(2) ); continue; } /* At this point, pWLoop is a candidate to be the next loop. ** Compute its cost */ | > > | > | 168643 168644 168645 168646 168647 168648 168649 168650 168651 168652 168653 168654 168655 168656 168657 168658 168659 168660 | ** index is useful in the outer loop of a correlated subquery. */ assert( 10==sqlite3LogEst(2) ); continue; } /* At this point, pWLoop is a candidate to be the next loop. ** Compute its cost */ rUnsorted = pWLoop->rRun + pFrom->nRow; if( pWLoop->rSetup ){ rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup, rUnsorted); } rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); nOut = pFrom->nRow + pWLoop->nOut; maskNew = pFrom->maskLoop | pWLoop->maskSelf; isOrdered = pFrom->isOrdered; if( isOrdered<0 ){ revMask = 0; isOrdered = wherePathSatisfiesOrderBy(pWInfo, |
︙ | ︙ | |||
167481 167482 167483 167484 167485 167486 167487 167488 167489 167490 167491 167492 167493 167494 | ** that covers the same set of loops and has the same isOrdered ** setting as the current path candidate. ** ** The term "((pTo->isOrdered^isOrdered)&0x80)==0" is equivalent ** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range ** of legal values for isOrdered, -1..64. */ for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){ if( pTo->maskLoop==maskNew && ((pTo->isOrdered^isOrdered)&0x80)==0 ){ testcase( jj==nTo-1 ); break; } | > | 168691 168692 168693 168694 168695 168696 168697 168698 168699 168700 168701 168702 168703 168704 168705 | ** that covers the same set of loops and has the same isOrdered ** setting as the current path candidate. ** ** The term "((pTo->isOrdered^isOrdered)&0x80)==0" is equivalent ** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range ** of legal values for isOrdered, -1..64. */ testcase( nTo==0 ); for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){ if( pTo->maskLoop==maskNew && ((pTo->isOrdered^isOrdered)&0x80)==0 ){ testcase( jj==nTo-1 ); break; } |
︙ | ︙ | |||
167597 167598 167599 167600 167601 167602 167603 167604 | } } } } #ifdef WHERETRACE_ENABLED /* >=2 */ if( sqlite3WhereTrace & 0x02 ){ sqlite3DebugPrintf("---- after round %d ----\n", iLoop); | > > > > | > > > > | | | | | | | | > > > > | 168808 168809 168810 168811 168812 168813 168814 168815 168816 168817 168818 168819 168820 168821 168822 168823 168824 168825 168826 168827 168828 168829 168830 168831 168832 168833 168834 168835 168836 168837 168838 168839 168840 168841 168842 168843 | } } } } #ifdef WHERETRACE_ENABLED /* >=2 */ if( sqlite3WhereTrace & 0x02 ){ LogEst rMin, rFloor = 0; int nDone = 0; sqlite3DebugPrintf("---- after round %d ----\n", iLoop); while( nDone<nTo ){ rMin = 0x7fff; for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){ if( pTo->rCost>rFloor && pTo->rCost<rMin ) rMin = pTo->rCost; } for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){ if( pTo->rCost==rMin ){ sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c", wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); if( pTo->isOrdered>0 ){ sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); }else{ sqlite3DebugPrintf("\n"); } nDone++; } } rFloor = rMin; } } #endif /* Swap the roles of aFrom and aTo for the next generation */ pFrom = aTo; aTo = aFrom; |
︙ | ︙ | |||
167701 167702 167703 167704 167705 167706 167707 | if( nOrder==pWInfo->pOrderBy->nExpr ){ pWInfo->sorted = 1; pWInfo->revMask = revMask; } } } | | | 168924 168925 168926 168927 168928 168929 168930 168931 168932 168933 168934 168935 168936 168937 168938 | if( nOrder==pWInfo->pOrderBy->nExpr ){ pWInfo->sorted = 1; pWInfo->revMask = revMask; } } } pWInfo->nRowOut = pFrom->nRow + pWInfo->nOutStarDelta; /* Free temporary memory and return success */ sqlite3StackFreeNN(pParse->db, pSpace); return SQLITE_OK; } /* |
︙ | ︙ | |||
167812 167813 167814 167815 167816 167817 167818 | Index *pIdx; WhereScan scan; pWInfo = pBuilder->pWInfo; if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; assert( pWInfo->pTabList->nSrc>=1 ); pItem = pWInfo->pTabList->a; | | | 169035 169036 169037 169038 169039 169040 169041 169042 169043 169044 169045 169046 169047 169048 169049 | Index *pIdx; WhereScan scan; pWInfo = pBuilder->pWInfo; if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; assert( pWInfo->pTabList->nSrc>=1 ); pItem = pWInfo->pTabList->a; pTab = pItem->pSTab; if( IsVirtual(pTab) ) return 0; if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){ testcase( pItem->fg.isIndexedBy ); testcase( pItem->fg.notIndexed ); return 0; } iCur = pItem->iCursor; |
︙ | ︙ | |||
167953 167954 167955 167956 167957 167958 167959 167960 167961 167962 167963 167964 167965 167966 | ** 5) The table must not have an inner-join ON or USING clause if there is ** a RIGHT JOIN anywhere in the query. Otherwise the ON/USING clause ** might move from the right side to the left side of the RIGHT JOIN. ** Note: Due to (2), this condition can only arise if the table is ** the right-most table of a subquery that was flattened into the ** main query and that subquery was the right-hand operand of an ** inner join that held an ON or USING clause. ** ** For example, given: ** ** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1); ** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2); ** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3); ** | > > > > | 169176 169177 169178 169179 169180 169181 169182 169183 169184 169185 169186 169187 169188 169189 169190 169191 169192 169193 | ** 5) The table must not have an inner-join ON or USING clause if there is ** a RIGHT JOIN anywhere in the query. Otherwise the ON/USING clause ** might move from the right side to the left side of the RIGHT JOIN. ** Note: Due to (2), this condition can only arise if the table is ** the right-most table of a subquery that was flattened into the ** main query and that subquery was the right-hand operand of an ** inner join that held an ON or USING clause. ** 6) The ORDER BY clause has 63 or fewer terms ** 7) The omit-noop-join optimization is enabled. ** ** Items (1), (6), and (7) are checked by the caller. ** ** For example, given: ** ** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1); ** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2); ** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3); ** |
︙ | ︙ | |||
167998 167999 168000 168001 168002 168003 168004 168005 168006 168007 168008 168009 168010 168011 | tabUsed |= sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pOrderBy); } hasRightJoin = (pWInfo->pTabList->a[0].fg.jointype & JT_LTORJ)!=0; for(i=pWInfo->nLevel-1; i>=1; i--){ WhereTerm *pTerm, *pEnd; SrcItem *pItem; WhereLoop *pLoop; pLoop = pWInfo->a[i].pWLoop; pItem = &pWInfo->pTabList->a[pLoop->iTab]; if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue; if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)==0 && (pLoop->wsFlags & WHERE_ONEROW)==0 ){ continue; | > | 169225 169226 169227 169228 169229 169230 169231 169232 169233 169234 169235 169236 169237 169238 169239 | tabUsed |= sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pOrderBy); } hasRightJoin = (pWInfo->pTabList->a[0].fg.jointype & JT_LTORJ)!=0; for(i=pWInfo->nLevel-1; i>=1; i--){ WhereTerm *pTerm, *pEnd; SrcItem *pItem; WhereLoop *pLoop; Bitmask m1; pLoop = pWInfo->a[i].pWLoop; pItem = &pWInfo->pTabList->a[pLoop->iTab]; if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue; if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)==0 && (pLoop->wsFlags & WHERE_ONEROW)==0 ){ continue; |
︙ | ︙ | |||
168024 168025 168026 168027 168028 168029 168030 | && ExprHasProperty(pTerm->pExpr, EP_InnerON) && pTerm->pExpr->w.iJoin==pItem->iCursor ){ break; /* restriction (5) */ } } if( pTerm<pEnd ) continue; | | > > > | 169252 169253 169254 169255 169256 169257 169258 169259 169260 169261 169262 169263 169264 169265 169266 169267 169268 169269 | && ExprHasProperty(pTerm->pExpr, EP_InnerON) && pTerm->pExpr->w.iJoin==pItem->iCursor ){ break; /* restriction (5) */ } } if( pTerm<pEnd ) continue; WHERETRACE(0xffffffff,("-> omit unused FROM-clause term %c\n",pLoop->cId)); m1 = MASKBIT(i)-1; testcase( ((pWInfo->revMask>>1) & ~m1)!=0 ); pWInfo->revMask = (m1 & pWInfo->revMask) | ((pWInfo->revMask>>1) & ~m1); notReady &= ~pLoop->maskSelf; for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){ if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){ pTerm->wtFlags |= TERM_CODED; } } if( i!=pWInfo->nLevel-1 ){ |
︙ | ︙ | |||
168071 168072 168073 168074 168075 168076 168077 | assert( pWInfo->nLevel>=2 ); assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) ); for(i=0; i<pWInfo->nLevel; i++){ WhereLoop *pLoop = pWInfo->a[i].pWLoop; const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; | | > | 169302 169303 169304 169305 169306 169307 169308 169309 169310 169311 169312 169313 169314 169315 169316 169317 169318 169319 169320 169321 169322 169323 169324 169325 169326 169327 169328 169329 169330 169331 169332 169333 169334 169335 169336 | assert( pWInfo->nLevel>=2 ); assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) ); for(i=0; i<pWInfo->nLevel; i++){ WhereLoop *pLoop = pWInfo->a[i].pWLoop; const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; Table *pTab = pItem->pSTab; if( (pTab->tabFlags & TF_HasStat1)==0 ) break; pTab->tabFlags |= TF_MaybeReanalyze; if( i>=1 && (pLoop->wsFlags & reqFlags)==reqFlags /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ && ALWAYS((pLoop->wsFlags & (WHERE_IPK|WHERE_INDEXED))!=0) ){ if( nSearch > pTab->nRowLogEst ){ testcase( pItem->fg.jointype & JT_LEFT ); pLoop->wsFlags |= WHERE_BLOOMFILTER; pLoop->wsFlags &= ~WHERE_IDX_ONLY; WHERETRACE(0xffffffff, ( "-> use Bloom-filter on loop %c because there are ~%.1e " "lookups into %s which has only ~%.1e rows\n", pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName, (double)sqlite3LogEstToInt(pTab->nRowLogEst))); } } nSearch += pLoop->nOut; if( pWInfo->nOutStarDelta ) nSearch += pLoop->rStarDelta; } } /* ** Expression Node callback for sqlite3ExprCanReturnSubtype(). ** ** Only a function call is able to return a subtype. So if the node |
︙ | ︙ | |||
168227 168228 168229 168230 168231 168232 168233 | */ static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){ int ii; for(ii=0; ii<pWInfo->pTabList->nSrc; ii++){ SrcItem *pItem = &pWInfo->pTabList->a[ii]; if( !pItem->fg.isCte || pItem->u2.pCteUse->eM10d!=M10d_Yes | | | | 169459 169460 169461 169462 169463 169464 169465 169466 169467 169468 169469 169470 169471 169472 169473 169474 | */ static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){ int ii; for(ii=0; ii<pWInfo->pTabList->nSrc; ii++){ SrcItem *pItem = &pWInfo->pTabList->a[ii]; if( !pItem->fg.isCte || pItem->u2.pCteUse->eM10d!=M10d_Yes || NEVER(pItem->fg.isSubquery==0) || pItem->u4.pSubq->pSelect->pOrderBy==0 ){ pWInfo->revMask |= MASKBIT(ii); } } } /* |
︙ | ︙ | |||
168366 168367 168368 168369 168370 168371 168372 168373 168374 168375 168376 168377 168378 168379 | memset(&sWLB, 0, sizeof(sWLB)); /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); if( pOrderBy && pOrderBy->nExpr>=BMS ){ pOrderBy = 0; wctrlFlags &= ~WHERE_WANT_DISTINCT; } /* The number of tables in the FROM clause is limited by the number of ** bits in a Bitmask */ testcase( pTabList->nSrc==BMS ); if( pTabList->nSrc>BMS ){ | > | 169598 169599 169600 169601 169602 169603 169604 169605 169606 169607 169608 169609 169610 169611 169612 | memset(&sWLB, 0, sizeof(sWLB)); /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); if( pOrderBy && pOrderBy->nExpr>=BMS ){ pOrderBy = 0; wctrlFlags &= ~WHERE_WANT_DISTINCT; wctrlFlags |= WHERE_KEEP_ALL_JOINS; /* Disable omit-noop-join opt */ } /* The number of tables in the FROM clause is limited by the number of ** bits in a Bitmask */ testcase( pTabList->nSrc==BMS ); if( pTabList->nSrc>BMS ){ |
︙ | ︙ | |||
168606 168607 168608 168609 168610 168611 168612 | #endif WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); wherePathSolver(pWInfo, 0); if( db->mallocFailed ) goto whereBeginError; if( pWInfo->pOrderBy ){ whereInterstageHeuristic(pWInfo); | | | 169839 169840 169841 169842 169843 169844 169845 169846 169847 169848 169849 169850 169851 169852 169853 | #endif WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); wherePathSolver(pWInfo, 0); if( db->mallocFailed ) goto whereBeginError; if( pWInfo->pOrderBy ){ whereInterstageHeuristic(pWInfo); wherePathSolver(pWInfo, pWInfo->nRowOut<0 ? 1 : pWInfo->nRowOut+1); if( db->mallocFailed ) goto whereBeginError; } /* TUNING: Assume that a DISTINCT clause on a subquery reduces ** the output size by a factor of 8 (LogEst -30). */ if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){ |
︙ | ︙ | |||
168666 168667 168668 168669 168670 168671 168672 | ** procedure to keep the sqlite3WhereBegin() procedure from becoming ** too large. If sqlite3WhereBegin() becomes too large, that prevents ** some C-compiler optimizers from in-lining the ** sqlite3WhereCodeOneLoopStart() procedure, and it is important to ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons. */ notReady = ~(Bitmask)0; | | | | | | 169899 169900 169901 169902 169903 169904 169905 169906 169907 169908 169909 169910 169911 169912 169913 169914 169915 169916 | ** procedure to keep the sqlite3WhereBegin() procedure from becoming ** too large. If sqlite3WhereBegin() becomes too large, that prevents ** some C-compiler optimizers from in-lining the ** sqlite3WhereCodeOneLoopStart() procedure, and it is important to ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons. */ notReady = ~(Bitmask)0; if( pWInfo->nLevel>=2 /* Must be a join, or this opt8n is pointless */ && pResultSet!=0 /* Condition (1) */ && 0==(wctrlFlags & (WHERE_AGG_DISTINCT|WHERE_KEEP_ALL_JOINS)) /* (1),(6) */ && OptimizationEnabled(db, SQLITE_OmitNoopJoin) /* (7) */ ){ notReady = whereOmitNoopJoin(pWInfo, notReady); nTabList = pWInfo->nLevel; assert( nTabList>0 ); } /* Check to see if there are any SEARCH loops that might benefit from |
︙ | ︙ | |||
168717 168718 168719 168720 168721 168722 168723 | ** use a one-pass approach, and this is not set accurately for scans ** that use the OR optimization. */ 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; | | | | | | 169950 169951 169952 169953 169954 169955 169956 169957 169958 169959 169960 169961 169962 169963 169964 169965 169966 169967 169968 169969 169970 169971 169972 169973 169974 169975 169976 169977 169978 169979 169980 169981 169982 169983 169984 169985 169986 169987 169988 169989 169990 | ** use a one-pass approach, and this is not set accurately for scans ** that use the OR optimization. */ 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; assert( !(wsFlags&WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pSTab) ); if( bOnerow || ( 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) && !IsVirtual(pTabList->a[0].pSTab) && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) && OptimizationEnabled(db, SQLITE_OnePass) )){ pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; if( HasRowid(pTabList->a[0].pSTab) && (wsFlags & WHERE_IDX_ONLY) ){ if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){ bFordelete = OPFLAG_FORDELETE; } pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY); } } } /* Open all tables in the pTabList and any indices selected for ** searching those tables. */ for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){ Table *pTab; /* Table to open */ int iDb; /* Index of database containing table/index */ SrcItem *pTabItem; pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pSTab; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pLoop = pLevel->pWLoop; if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){ /* Do nothing */ }else #ifndef SQLITE_OMIT_VIRTUALTABLE if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ |
︙ | ︙ | |||
168814 168815 168816 168817 168818 168819 168820 | && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ){ /* This is one term of an OR-optimization using the PRIMARY KEY of a ** WITHOUT ROWID table. No need for a separate index */ iIndexCur = pLevel->iTabCur; op = 0; }else if( pWInfo->eOnePass!=ONEPASS_OFF ){ | | | 170047 170048 170049 170050 170051 170052 170053 170054 170055 170056 170057 170058 170059 170060 170061 | && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ){ /* This is one term of an OR-optimization using the PRIMARY KEY of a ** WITHOUT ROWID table. No need for a separate index */ iIndexCur = pLevel->iTabCur; op = 0; }else if( pWInfo->eOnePass!=ONEPASS_OFF ){ Index *pJ = pTabItem->pSTab->pIndex; iIndexCur = iAuxArg; assert( wctrlFlags & WHERE_ONEPASS_DESIRED ); while( ALWAYS(pJ) && pJ!=pIx ){ iIndexCur++; pJ = pJ->pNext; } op = OP_OpenWrite; |
︙ | ︙ | |||
168881 168882 168883 168884 168885 168886 168887 | ){ WhereRightJoin *pRJ = pLevel->pRJ; pRJ->iMatch = pParse->nTab++; pRJ->regBloom = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); pRJ->regReturn = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn); | | | 170114 170115 170116 170117 170118 170119 170120 170121 170122 170123 170124 170125 170126 170127 170128 | ){ WhereRightJoin *pRJ = pLevel->pRJ; pRJ->iMatch = pParse->nTab++; pRJ->regBloom = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); pRJ->regReturn = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn); assert( pTab==pTabItem->pSTab ); if( HasRowid(pTab) ){ KeyInfo *pInfo; sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1); pInfo = sqlite3KeyInfoAlloc(pParse->db, 1, 0); if( pInfo ){ pInfo->aColl[0] = 0; pInfo->aSortFlags[0] = 0; |
︙ | ︙ | |||
168920 168921 168922 168923 168924 168925 168926 | int wsFlags; SrcItem *pSrc; if( pParse->nErr ) goto whereBeginError; pLevel = &pWInfo->a[ii]; wsFlags = pLevel->pWLoop->wsFlags; pSrc = &pTabList->a[pLevel->iFrom]; if( pSrc->fg.isMaterialized ){ | > > > > | | | > | > | < | 170153 170154 170155 170156 170157 170158 170159 170160 170161 170162 170163 170164 170165 170166 170167 170168 170169 170170 170171 170172 170173 170174 170175 170176 170177 170178 | int wsFlags; SrcItem *pSrc; if( pParse->nErr ) goto whereBeginError; pLevel = &pWInfo->a[ii]; wsFlags = pLevel->pWLoop->wsFlags; pSrc = &pTabList->a[pLevel->iFrom]; if( pSrc->fg.isMaterialized ){ Subquery *pSubq; int iOnce = 0; assert( pSrc->fg.isSubquery ); pSubq = pSrc->u4.pSubq; if( pSrc->fg.isCorrelated==0 ){ iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); }else{ iOnce = 0; } sqlite3VdbeAddOp2(v, OP_Gosub, pSubq->regReturn, pSubq->addrFillSub); VdbeComment((v, "materialize %!S", pSrc)); if( iOnce ) sqlite3VdbeJumpHere(v, iOnce); } assert( pTabList == pWInfo->pTabList ); if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){ #ifndef SQLITE_OMIT_AUTOMATIC_INDEX constructAutomaticIndex(pParse, &pWInfo->sWC, notReady, pLevel); #endif |
︙ | ︙ | |||
168989 168990 168991 168992 168993 168994 168995 | VdbeOp *pOp ){ if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; sqlite3VdbePrintOp(0, pc, pOp); } #endif | < < < < < < < < < < < < < < < < < < < < | 170227 170228 170229 170230 170231 170232 170233 170234 170235 170236 170237 170238 170239 170240 | VdbeOp *pOp ){ if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; sqlite3VdbePrintOp(0, pc, pOp); } #endif /* ** Generate the end of the WHERE loop. See comments on ** sqlite3WhereBegin() for additional information. */ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ Parse *pParse = pWInfo->pParse; Vdbe *v = pParse->pVdbe; |
︙ | ︙ | |||
169159 169160 169161 169162 169163 169164 169165 | addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 ); if( (ws & WHERE_IDX_ONLY)==0 ){ SrcItem *pSrc = &pTabList->a[pLevel->iFrom]; assert( pLevel->iTabCur==pSrc->iCursor ); if( pSrc->fg.viaCoroutine ){ int m, n; | > | | | | 170377 170378 170379 170380 170381 170382 170383 170384 170385 170386 170387 170388 170389 170390 170391 170392 170393 170394 | addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 ); if( (ws & WHERE_IDX_ONLY)==0 ){ SrcItem *pSrc = &pTabList->a[pLevel->iFrom]; assert( pLevel->iTabCur==pSrc->iCursor ); if( pSrc->fg.viaCoroutine ){ int m, n; assert( pSrc->fg.isSubquery ); n = pSrc->u4.pSubq->regResult; assert( pSrc->pSTab!=0 ); m = pSrc->pSTab->nCol; sqlite3VdbeAddOp3(v, OP_Null, 0, n, n+m-1); } sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); } if( (ws & WHERE_INDEXED) || ((ws & WHERE_MULTI_OR) && pLevel->u.pCoveringIdx) ){ |
︙ | ︙ | |||
169185 169186 169187 169188 169189 169190 169191 | sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst); }else{ sqlite3VdbeGoto(v, pLevel->addrFirst); } sqlite3VdbeJumpHere(v, addr); } VdbeModuleComment((v, "End WHERE-loop%d: %s", i, | | | | > | | 170404 170405 170406 170407 170408 170409 170410 170411 170412 170413 170414 170415 170416 170417 170418 170419 170420 170421 170422 170423 170424 170425 170426 170427 170428 170429 170430 170431 170432 170433 170434 170435 170436 170437 170438 170439 170440 170441 170442 170443 170444 170445 170446 170447 170448 170449 | sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst); }else{ sqlite3VdbeGoto(v, pLevel->addrFirst); } sqlite3VdbeJumpHere(v, addr); } VdbeModuleComment((v, "End WHERE-loop%d: %s", i, pWInfo->pTabList->a[pLevel->iFrom].pSTab->zName)); } assert( pWInfo->nLevel<=pTabList->nSrc ); for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){ int k, last; VdbeOp *pOp, *pLastOp; Index *pIdx = 0; SrcItem *pTabItem = &pTabList->a[pLevel->iFrom]; Table *pTab = pTabItem->pSTab; assert( pTab!=0 ); pLoop = pLevel->pWLoop; /* Do RIGHT JOIN processing. Generate code that will output the ** unmatched rows of the right operand of the RIGHT JOIN with ** all of the columns of the left operand set to NULL. */ if( pLevel->pRJ ){ sqlite3WhereRightJoinLoop(pWInfo, i, pLevel); continue; } /* For a co-routine, change all OP_Column references to the table of ** the co-routine into OP_Copy of result contained in a register. ** OP_Rowid becomes OP_Null. */ if( pTabItem->fg.viaCoroutine ){ testcase( pParse->db->mallocFailed ); assert( pTabItem->fg.isSubquery ); assert( pTabItem->u4.pSubq->regResult>=0 ); translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur, pTabItem->u4.pSubq->regResult, 0); continue; } /* If this scan uses an index, make VDBE code substitutions to read data ** from the index instead of from the table where possible. In some cases ** this optimization prevents the table from ever being read, which can ** yield a significant performance boost. |
︙ | ︙ | |||
169308 169309 169310 169311 169312 169313 169314 | pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); }else{ /* Unable to translate the table reference into an index ** reference. Verify that this is harmless - that the ** table being referenced really is open. */ | < | < < < > | < < < < > | 170528 170529 170530 170531 170532 170533 170534 170535 170536 170537 170538 170539 170540 170541 170542 170543 170544 170545 | pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); }else{ /* Unable to translate the table reference into an index ** reference. Verify that this is harmless - that the ** table being referenced really is open. */ if( pLoop->wsFlags & WHERE_IDX_ONLY ){ sqlite3ErrorMsg(pParse, "internal query planner error"); pParse->rc = SQLITE_INTERNAL; } } }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; pOp->opcode = OP_IdxRowid; OpcodeRewriteTrace(db, k, pOp); }else if( pOp->opcode==OP_IfNullRow ){ pOp->p1 = pLevel->iIdxCur; |
︙ | ︙ | |||
170263 170264 170265 170266 170267 170268 170269 | sqlite3ExprDelete(db, pDup); break; } if( bIntToNull ){ int iDummy; Expr *pSub; pSub = sqlite3ExprSkipCollateAndLikely(pDup); | | | 171477 171478 171479 171480 171481 171482 171483 171484 171485 171486 171487 171488 171489 171490 171491 | sqlite3ExprDelete(db, pDup); break; } if( bIntToNull ){ int iDummy; Expr *pSub; pSub = sqlite3ExprSkipCollateAndLikely(pDup); if( sqlite3ExprIsInteger(pSub, &iDummy, 0) ){ pSub->op = TK_NULL; pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); pSub->u.zToken = 0; } } pList = sqlite3ExprListAppend(pParse, pList, pDup); if( pList ) pList->a[nInit+i].fg.sortFlags = pAppend->a[i].fg.sortFlags; |
︙ | ︙ | |||
170431 170432 170433 170434 170435 170436 170437 | TREETRACE(0x40,pParse,pSub, ("New window-function subquery in FROM clause of (%u/%p)\n", p->selId, p)); p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside ** of sqlite3DbMallocRawNN() called from ** sqlite3SrcListAppend() */ | | > > < | < < | 171645 171646 171647 171648 171649 171650 171651 171652 171653 171654 171655 171656 171657 171658 171659 171660 171661 171662 171663 171664 171665 171666 171667 171668 171669 171670 171671 171672 171673 171674 171675 171676 171677 171678 171679 171680 171681 171682 171683 | TREETRACE(0x40,pParse,pSub, ("New window-function subquery in FROM clause of (%u/%p)\n", p->selId, p)); p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside ** of sqlite3DbMallocRawNN() called from ** sqlite3SrcListAppend() */ if( p->pSrc==0 ){ sqlite3SelectDelete(db, pSub); }else if( sqlite3SrcItemAttachSubquery(pParse, &p->pSrc->a[0], pSub, 0) ){ Table *pTab2; p->pSrc->a[0].fg.isCorrelated = 1; sqlite3SrcListAssignCursors(pParse, p->pSrc); pSub->selFlags |= SF_Expanded|SF_OrderByReqd; pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); pSub->selFlags |= (selFlags & SF_Aggregate); if( pTab2==0 ){ /* Might actually be some other kind of error, but in that case ** pParse->nErr will be set, so if SQLITE_NOMEM is set, we will get ** the correct error message regardless. */ rc = SQLITE_NOMEM; }else{ memcpy(pTab, pTab2, sizeof(Table)); pTab->tabFlags |= TF_Ephemeral; p->pSrc->a[0].pSTab = pTab; pTab = pTab2; memset(&w, 0, sizeof(w)); w.xExprCallback = sqlite3WindowExtraAggFuncDepth; w.xSelectCallback = sqlite3WalkerDepthIncrease; w.xSelectCallback2 = sqlite3WalkerDepthDecrease; sqlite3WalkSelect(&w, pSub); } } if( db->mallocFailed ) rc = SQLITE_NOMEM; /* Defer deleting the temporary table pTab because if an error occurred, ** there could still be references to that table embedded in the ** result-set or ORDER BY clause of the SELECT statement p. */ sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab); |
︙ | ︙ | |||
170743 170744 170745 170746 170747 170748 170749 | /* ** This is called by code in select.c before it calls sqlite3WhereBegin() ** to begin iterating through the sub-query results. It is used to allocate ** and initialize registers and cursors used by sqlite3WindowCodeStep(). */ SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ | > | | > | > > > | | 171956 171957 171958 171959 171960 171961 171962 171963 171964 171965 171966 171967 171968 171969 171970 171971 171972 171973 171974 171975 171976 171977 171978 | /* ** This is called by code in select.c before it calls sqlite3WhereBegin() ** to begin iterating through the sub-query results. It is used to allocate ** and initialize registers and cursors used by sqlite3WindowCodeStep(). */ SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ Window *pWin; int nEphExpr; Window *pMWin; Vdbe *v; assert( pSelect->pSrc->a[0].fg.isSubquery ); nEphExpr = pSelect->pSrc->a[0].u4.pSubq->pSelect->pEList->nExpr; pMWin = pSelect->pWin; v = sqlite3GetVdbe(pParse); sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr); sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr); sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr); sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr); /* Allocate registers to use for PARTITION BY values, if any. Initialize |
︙ | ︙ | |||
172143 172144 172145 172146 172147 172148 172149 | int addrGosub /* OP_Gosub here to return each row */ ){ Window *pMWin = p->pWin; ExprList *pOrderBy = pMWin->pOrderBy; Vdbe *v = sqlite3GetVdbe(pParse); int csrWrite; /* Cursor used to write to eph. table */ int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */ | | | 173361 173362 173363 173364 173365 173366 173367 173368 173369 173370 173371 173372 173373 173374 173375 | int addrGosub /* OP_Gosub here to return each row */ ){ Window *pMWin = p->pWin; ExprList *pOrderBy = pMWin->pOrderBy; Vdbe *v = sqlite3GetVdbe(pParse); int csrWrite; /* Cursor used to write to eph. table */ int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */ int nInput = p->pSrc->a[0].pSTab->nCol; /* Number of cols returned by sub */ int iInput; /* To iterate through sub cols */ int addrNe; /* Address of OP_Ne */ int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */ int addrInteger = 0; /* Address of OP_Integer */ int addrEmpty; /* Address of OP_Rewind in flush: */ int regNew; /* Array of registers holding new input row */ int regRecord; /* regNew array in record form */ |
︙ | ︙ | |||
172588 172589 172590 172591 172592 172593 172594 | if( pLoop->pOrderBy || pLoop->pLimit ){ sqlite3ErrorMsg(pParse,"%s clause should come after %s not before", pLoop->pOrderBy!=0 ? "ORDER BY" : "LIMIT", sqlite3SelectOpName(pNext->op)); break; } } | | | | | 173806 173807 173808 173809 173810 173811 173812 173813 173814 173815 173816 173817 173818 173819 173820 173821 173822 | if( pLoop->pOrderBy || pLoop->pLimit ){ sqlite3ErrorMsg(pParse,"%s clause should come after %s not before", pLoop->pOrderBy!=0 ? "ORDER BY" : "LIMIT", sqlite3SelectOpName(pNext->op)); break; } } if( (p->selFlags & (SF_MultiValue|SF_Values))==0 && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && cnt>mxSelect ){ sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); } } } /* Attach a With object describing the WITH clause to a Select |
︙ | ︙ | |||
172740 172741 172742 172743 172744 172745 172746 | #define TK_DESC 39 #define TK_DETACH 40 #define TK_EACH 41 #define TK_FAIL 42 #define TK_OR 43 #define TK_AND 44 #define TK_IS 45 | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | 173958 173959 173960 173961 173962 173963 173964 173965 173966 173967 173968 173969 173970 173971 173972 173973 173974 173975 173976 173977 173978 173979 173980 173981 173982 173983 173984 173985 173986 173987 173988 173989 173990 173991 173992 173993 173994 173995 173996 173997 173998 173999 174000 174001 174002 174003 174004 174005 174006 174007 174008 174009 174010 174011 174012 174013 174014 174015 174016 174017 174018 174019 174020 174021 174022 174023 174024 174025 174026 174027 174028 174029 174030 174031 174032 174033 174034 174035 174036 174037 174038 174039 174040 174041 174042 174043 174044 174045 174046 174047 174048 174049 174050 174051 174052 174053 174054 174055 174056 174057 174058 174059 174060 174061 174062 174063 174064 174065 174066 174067 174068 174069 174070 174071 174072 174073 174074 174075 174076 174077 174078 174079 174080 174081 174082 174083 174084 174085 174086 174087 174088 174089 174090 174091 174092 174093 174094 174095 174096 174097 | #define TK_DESC 39 #define TK_DETACH 40 #define TK_EACH 41 #define TK_FAIL 42 #define TK_OR 43 #define TK_AND 44 #define TK_IS 45 #define TK_ISNOT 46 #define TK_MATCH 47 #define TK_LIKE_KW 48 #define TK_BETWEEN 49 #define TK_IN 50 #define TK_ISNULL 51 #define TK_NOTNULL 52 #define TK_NE 53 #define TK_EQ 54 #define TK_GT 55 #define TK_LE 56 #define TK_LT 57 #define TK_GE 58 #define TK_ESCAPE 59 #define TK_ID 60 #define TK_COLUMNKW 61 #define TK_DO 62 #define TK_FOR 63 #define TK_IGNORE 64 #define TK_INITIALLY 65 #define TK_INSTEAD 66 #define TK_NO 67 #define TK_KEY 68 #define TK_OF 69 #define TK_OFFSET 70 #define TK_PRAGMA 71 #define TK_RAISE 72 #define TK_RECURSIVE 73 #define TK_REPLACE 74 #define TK_RESTRICT 75 #define TK_ROW 76 #define TK_ROWS 77 #define TK_TRIGGER 78 #define TK_VACUUM 79 #define TK_VIEW 80 #define TK_VIRTUAL 81 #define TK_WITH 82 #define TK_NULLS 83 #define TK_FIRST 84 #define TK_LAST 85 #define TK_CURRENT 86 #define TK_FOLLOWING 87 #define TK_PARTITION 88 #define TK_PRECEDING 89 #define TK_RANGE 90 #define TK_UNBOUNDED 91 #define TK_EXCLUDE 92 #define TK_GROUPS 93 #define TK_OTHERS 94 #define TK_TIES 95 #define TK_GENERATED 96 #define TK_ALWAYS 97 #define TK_MATERIALIZED 98 #define TK_REINDEX 99 #define TK_RENAME 100 #define TK_CTIME_KW 101 #define TK_ANY 102 #define TK_BITAND 103 #define TK_BITOR 104 #define TK_LSHIFT 105 #define TK_RSHIFT 106 #define TK_PLUS 107 #define TK_MINUS 108 #define TK_STAR 109 #define TK_SLASH 110 #define TK_REM 111 #define TK_CONCAT 112 #define TK_PTR 113 #define TK_COLLATE 114 #define TK_BITNOT 115 #define TK_ON 116 #define TK_INDEXED 117 #define TK_STRING 118 #define TK_JOIN_KW 119 #define TK_CONSTRAINT 120 #define TK_DEFAULT 121 #define TK_NULL 122 #define TK_PRIMARY 123 #define TK_UNIQUE 124 #define TK_CHECK 125 #define TK_REFERENCES 126 #define TK_AUTOINCR 127 #define TK_INSERT 128 #define TK_DELETE 129 #define TK_UPDATE 130 #define TK_SET 131 #define TK_DEFERRABLE 132 #define TK_FOREIGN 133 #define TK_DROP 134 #define TK_UNION 135 #define TK_ALL 136 #define TK_EXCEPT 137 #define TK_INTERSECT 138 #define TK_SELECT 139 #define TK_VALUES 140 #define TK_DISTINCT 141 #define TK_DOT 142 #define TK_FROM 143 #define TK_JOIN 144 #define TK_USING 145 #define TK_ORDER 146 #define TK_GROUP 147 #define TK_HAVING 148 #define TK_LIMIT 149 #define TK_WHERE 150 #define TK_RETURNING 151 #define TK_INTO 152 #define TK_NOTHING 153 #define TK_FLOAT 154 #define TK_BLOB 155 #define TK_INTEGER 156 #define TK_VARIABLE 157 #define TK_CASE 158 #define TK_WHEN 159 #define TK_THEN 160 #define TK_ELSE 161 #define TK_INDEX 162 #define TK_ALTER 163 #define TK_ADD 164 #define TK_WINDOW 165 #define TK_OVER 166 #define TK_FILTER 167 #define TK_COLUMN 168 #define TK_AGG_FUNCTION 169 #define TK_AGG_COLUMN 170 #define TK_TRUEFALSE 171 #define TK_FUNCTION 172 #define TK_UPLUS 173 #define TK_UMINUS 174 #define TK_TRUTH 175 #define TK_REGISTER 176 #define TK_VECTOR 177 #define TK_SELECT_COLUMN 178 |
︙ | ︙ | |||
172946 172947 172948 172949 172950 172951 172952 | #ifndef INTERFACE # define INTERFACE 1 #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int #define YYNOCODE 322 #define YYACTIONTYPE unsigned short int | | | 174164 174165 174166 174167 174168 174169 174170 174171 174172 174173 174174 174175 174176 174177 174178 | #ifndef INTERFACE # define INTERFACE 1 #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int #define YYNOCODE 322 #define YYACTIONTYPE unsigned short int #define YYWILDCARD 102 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; ExprList* yy14; With* yy59; Cte* yy67; |
︙ | ︙ | |||
173083 173084 173085 173086 173087 173088 173089 | ** yy_shift_ofst[] For each state, the offset into yy_action for ** shifting terminals. ** yy_reduce_ofst[] For each state, the offset into yy_action for ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ | | | | | | | | | | | | | | | | | | | | | | | < < < | < < < | | > > > | > > | > | | | | | | | | | | | | | | | | | | | | | | < < | | > > | | | | | | | | | | | | | | | | | | | | > | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > > > > > | < | | | | > | < | | | | | | | | | | | > > > > | > > | | | | < < | | < | | > | | | < | < | | > | < | < < | < > | | | | | | | | | | > < < < < < < < < < < < | | | | | | | | | | | | | | | | | | | | > > > > | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | < < < < | > | | | < | | | > | > | | < | | | > | | > > | | | | | | < < | < < < < < | < < | < | | | | | | | | | | | | | | | | > | > > > | | | > < | | | > > > > | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | | | | | | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 174301 174302 174303 174304 174305 174306 174307 174308 174309 174310 174311 174312 174313 174314 174315 174316 174317 174318 174319 174320 174321 174322 174323 174324 174325 174326 174327 174328 174329 174330 174331 174332 174333 174334 174335 174336 174337 174338 174339 174340 174341 174342 174343 174344 174345 174346 174347 174348 174349 174350 174351 174352 174353 174354 174355 174356 174357 174358 174359 174360 174361 174362 174363 174364 174365 174366 174367 174368 174369 174370 174371 174372 174373 174374 174375 174376 174377 174378 174379 174380 174381 174382 174383 174384 174385 174386 174387 174388 174389 174390 174391 174392 174393 174394 174395 174396 174397 174398 174399 174400 174401 174402 174403 174404 174405 174406 174407 174408 174409 174410 174411 174412 174413 174414 174415 174416 174417 174418 174419 174420 174421 174422 174423 174424 174425 174426 174427 174428 174429 174430 174431 174432 174433 174434 174435 174436 174437 174438 174439 174440 174441 174442 174443 174444 174445 174446 174447 174448 174449 174450 174451 174452 174453 174454 174455 174456 174457 174458 174459 174460 174461 174462 174463 174464 174465 174466 174467 174468 174469 174470 174471 174472 174473 174474 174475 174476 174477 174478 174479 174480 174481 174482 174483 174484 174485 174486 174487 174488 174489 174490 174491 174492 174493 174494 174495 174496 174497 174498 174499 174500 174501 174502 174503 174504 174505 174506 174507 174508 174509 174510 174511 174512 174513 174514 174515 174516 174517 174518 174519 174520 174521 174522 174523 174524 174525 174526 174527 174528 174529 174530 174531 174532 174533 174534 174535 174536 174537 174538 174539 174540 174541 174542 174543 174544 174545 174546 174547 174548 174549 174550 174551 174552 174553 174554 174555 174556 174557 174558 174559 174560 174561 174562 174563 174564 174565 174566 174567 174568 174569 174570 174571 174572 174573 174574 174575 174576 174577 174578 174579 174580 174581 174582 174583 174584 174585 174586 174587 174588 174589 174590 174591 174592 174593 174594 174595 174596 174597 174598 174599 174600 174601 174602 174603 174604 174605 174606 174607 174608 174609 174610 174611 174612 174613 174614 174615 174616 174617 174618 174619 174620 174621 174622 174623 174624 174625 174626 174627 174628 174629 174630 174631 174632 174633 174634 174635 174636 174637 174638 174639 174640 174641 174642 174643 174644 174645 174646 174647 174648 174649 174650 174651 174652 174653 174654 174655 174656 174657 174658 174659 174660 174661 174662 174663 174664 174665 174666 174667 174668 174669 174670 174671 174672 174673 174674 174675 174676 174677 174678 174679 174680 174681 174682 174683 174684 174685 174686 174687 174688 174689 174690 174691 174692 174693 174694 174695 174696 174697 174698 174699 174700 174701 174702 174703 174704 174705 174706 174707 174708 174709 174710 174711 174712 174713 174714 174715 174716 174717 174718 174719 174720 174721 174722 174723 174724 174725 174726 174727 174728 174729 174730 174731 174732 174733 174734 174735 174736 174737 174738 174739 174740 174741 174742 174743 174744 174745 174746 174747 174748 174749 174750 174751 174752 174753 174754 174755 174756 174757 174758 174759 174760 174761 174762 174763 174764 174765 174766 174767 174768 174769 174770 174771 174772 174773 174774 174775 174776 174777 174778 174779 174780 174781 174782 174783 174784 174785 174786 174787 174788 174789 174790 174791 174792 174793 174794 174795 174796 174797 174798 174799 174800 174801 174802 174803 174804 174805 174806 174807 174808 174809 174810 174811 174812 174813 174814 174815 174816 174817 174818 174819 174820 174821 174822 174823 174824 174825 174826 174827 174828 174829 174830 174831 174832 174833 174834 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 174864 174865 174866 174867 174868 174869 174870 174871 174872 174873 174874 174875 174876 174877 174878 174879 174880 174881 174882 174883 174884 174885 174886 174887 174888 174889 174890 174891 174892 174893 174894 174895 174896 174897 174898 174899 174900 174901 174902 174903 174904 174905 174906 174907 174908 174909 174910 174911 174912 174913 174914 174915 174916 174917 174918 174919 174920 174921 174922 174923 174924 174925 174926 174927 174928 174929 174930 174931 174932 174933 174934 174935 174936 174937 174938 174939 174940 174941 174942 174943 174944 174945 174946 174947 174948 174949 | ** yy_shift_ofst[] For each state, the offset into yy_action for ** shifting terminals. ** yy_reduce_ofst[] For each state, the offset into yy_action for ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ #define YY_ACTTAB_COUNT (2207) static const YYACTIONTYPE yy_action[] = { /* 0 */ 130, 127, 234, 282, 282, 1328, 576, 1307, 460, 289, /* 10 */ 289, 576, 1622, 381, 576, 1328, 573, 576, 562, 413, /* 20 */ 1300, 1542, 573, 481, 562, 524, 460, 459, 558, 82, /* 30 */ 82, 983, 294, 375, 51, 51, 498, 61, 61, 984, /* 40 */ 82, 82, 1577, 137, 138, 91, 7, 1228, 1228, 1063, /* 50 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 413, /* 60 */ 288, 288, 182, 288, 288, 481, 536, 288, 288, 130, /* 70 */ 127, 234, 432, 573, 525, 562, 573, 557, 562, 1290, /* 80 */ 573, 421, 562, 137, 138, 91, 559, 1228, 1228, 1063, /* 90 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 296, /* 100 */ 460, 398, 1249, 134, 134, 134, 134, 133, 133, 132, /* 110 */ 132, 132, 131, 128, 451, 44, 1050, 1050, 1064, 1067, /* 120 */ 1255, 1, 1, 582, 2, 1259, 581, 1174, 1259, 1174, /* 130 */ 321, 413, 155, 321, 1584, 155, 379, 112, 498, 1341, /* 140 */ 456, 299, 1341, 134, 134, 134, 134, 133, 133, 132, /* 150 */ 132, 132, 131, 128, 451, 137, 138, 91, 1105, 1228, /* 160 */ 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, /* 170 */ 136, 1204, 320, 567, 288, 288, 283, 288, 288, 523, /* 180 */ 523, 1250, 139, 1541, 7, 214, 503, 573, 1169, 562, /* 190 */ 573, 1054, 562, 136, 136, 136, 136, 129, 401, 547, /* 200 */ 487, 1169, 245, 1568, 1169, 245, 133, 133, 132, 132, /* 210 */ 132, 131, 128, 451, 261, 134, 134, 134, 134, 133, /* 220 */ 133, 132, 132, 132, 131, 128, 451, 451, 1204, 1205, /* 230 */ 1204, 130, 127, 234, 455, 413, 182, 455, 130, 127, /* 240 */ 234, 134, 134, 134, 134, 133, 133, 132, 132, 132, /* 250 */ 131, 128, 451, 136, 136, 136, 136, 538, 576, 137, /* 260 */ 138, 91, 261, 1228, 1228, 1063, 1066, 1053, 1053, 135, /* 270 */ 135, 136, 136, 136, 136, 44, 472, 346, 1204, 472, /* 280 */ 346, 51, 51, 418, 93, 157, 134, 134, 134, 134, /* 290 */ 133, 133, 132, 132, 132, 131, 128, 451, 166, 363, /* 300 */ 298, 134, 134, 134, 134, 133, 133, 132, 132, 132, /* 310 */ 131, 128, 451, 1293, 461, 1570, 423, 377, 275, 134, /* 320 */ 134, 134, 134, 133, 133, 132, 132, 132, 131, 128, /* 330 */ 451, 418, 320, 567, 1292, 1204, 1205, 1204, 257, 413, /* 340 */ 483, 511, 508, 507, 94, 132, 132, 132, 131, 128, /* 350 */ 451, 506, 1204, 548, 548, 388, 576, 384, 7, 413, /* 360 */ 550, 229, 522, 137, 138, 91, 530, 1228, 1228, 1063, /* 370 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 51, /* 380 */ 51, 1582, 380, 137, 138, 91, 331, 1228, 1228, 1063, /* 390 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 320, /* 400 */ 567, 288, 288, 320, 567, 1602, 582, 2, 1259, 1204, /* 410 */ 1205, 1204, 1628, 321, 573, 155, 562, 576, 1511, 264, /* 420 */ 231, 520, 1341, 134, 134, 134, 134, 133, 133, 132, /* 430 */ 132, 132, 131, 128, 451, 519, 1511, 1513, 1333, 1333, /* 440 */ 82, 82, 498, 134, 134, 134, 134, 133, 133, 132, /* 450 */ 132, 132, 131, 128, 451, 1435, 257, 288, 288, 511, /* 460 */ 508, 507, 944, 1568, 413, 1019, 1204, 943, 360, 506, /* 470 */ 573, 1598, 562, 44, 575, 551, 551, 557, 1107, 1582, /* 480 */ 544, 576, 1107, 40, 417, 245, 531, 1505, 137, 138, /* 490 */ 91, 219, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, /* 500 */ 136, 136, 136, 136, 81, 81, 1281, 1204, 413, 553, /* 510 */ 1511, 48, 512, 448, 447, 493, 578, 455, 578, 344, /* 520 */ 45, 1204, 1233, 1204, 1205, 1204, 428, 1235, 158, 882, /* 530 */ 320, 567, 137, 138, 91, 1234, 1228, 1228, 1063, 1066, /* 540 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 134, 134, /* 550 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451, /* 560 */ 1236, 576, 1236, 329, 1204, 1205, 1204, 387, 492, 403, /* 570 */ 1040, 382, 489, 123, 568, 1569, 4, 377, 1204, 1205, /* 580 */ 1204, 570, 570, 570, 82, 82, 882, 1029, 1331, 1331, /* 590 */ 571, 1028, 134, 134, 134, 134, 133, 133, 132, 132, /* 600 */ 132, 131, 128, 451, 288, 288, 1281, 1204, 576, 423, /* 610 */ 576, 1568, 413, 423, 452, 378, 886, 573, 1279, 562, /* 620 */ 46, 557, 532, 1028, 1028, 1030, 565, 130, 127, 234, /* 630 */ 556, 82, 82, 82, 82, 479, 137, 138, 91, 462, /* 640 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, /* 650 */ 136, 136, 1188, 487, 1506, 1040, 413, 6, 1204, 50, /* 660 */ 879, 121, 121, 948, 1204, 1205, 1204, 358, 557, 122, /* 670 */ 316, 452, 577, 452, 535, 1204, 1028, 439, 303, 212, /* 680 */ 137, 138, 91, 213, 1228, 1228, 1063, 1066, 1053, 1053, /* 690 */ 135, 135, 136, 136, 136, 136, 134, 134, 134, 134, /* 700 */ 133, 133, 132, 132, 132, 131, 128, 451, 1028, 1028, /* 710 */ 1030, 1031, 35, 288, 288, 1204, 1205, 1204, 1040, 1339, /* 720 */ 533, 123, 568, 1569, 4, 377, 573, 1019, 562, 353, /* 730 */ 1277, 356, 1204, 1205, 1204, 1029, 488, 1188, 571, 1028, /* 740 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, /* 750 */ 128, 451, 576, 343, 288, 288, 449, 449, 449, 971, /* 760 */ 413, 1627, 452, 911, 1187, 288, 288, 573, 464, 562, /* 770 */ 238, 1028, 1028, 1030, 565, 82, 82, 498, 573, 411, /* 780 */ 562, 344, 467, 332, 137, 138, 91, 197, 1228, 1228, /* 790 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, /* 800 */ 1188, 528, 1169, 1040, 413, 1110, 1110, 495, 1041, 121, /* 810 */ 121, 1204, 317, 540, 862, 1169, 1244, 122, 1169, 452, /* 820 */ 577, 452, 1340, 198, 1028, 1204, 481, 526, 137, 138, /* 830 */ 91, 560, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, /* 840 */ 136, 136, 136, 136, 134, 134, 134, 134, 133, 133, /* 850 */ 132, 132, 132, 131, 128, 451, 1028, 1028, 1030, 1031, /* 860 */ 35, 1204, 288, 288, 1204, 477, 288, 288, 1204, 1205, /* 870 */ 1204, 539, 481, 437, 470, 573, 1451, 562, 364, 573, /* 880 */ 1153, 562, 1204, 1205, 1204, 1188, 5, 576, 134, 134, /* 890 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451, /* 900 */ 221, 214, 302, 96, 1149, 1657, 232, 1657, 413, 392, /* 910 */ 19, 19, 1024, 949, 406, 373, 1595, 1085, 1204, 1205, /* 920 */ 1204, 1204, 1205, 1204, 1204, 426, 1149, 1658, 413, 1658, /* 930 */ 1659, 399, 137, 138, 91, 3, 1228, 1228, 1063, 1066, /* 940 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 304, 1311, /* 950 */ 514, 1204, 137, 138, 91, 1498, 1228, 1228, 1063, 1066, /* 960 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 434, 131, /* 970 */ 128, 451, 375, 1204, 274, 291, 372, 517, 367, 516, /* 980 */ 262, 1204, 1205, 1204, 1147, 227, 363, 448, 447, 1435, /* 990 */ 1568, 1310, 134, 134, 134, 134, 133, 133, 132, 132, /* 1000 */ 132, 131, 128, 451, 1568, 576, 1147, 487, 1204, 1205, /* 1010 */ 1204, 442, 134, 134, 134, 134, 133, 133, 132, 132, /* 1020 */ 132, 131, 128, 451, 386, 576, 485, 576, 19, 19, /* 1030 */ 1204, 1205, 1204, 1345, 1236, 970, 1236, 574, 47, 936, /* 1040 */ 936, 473, 413, 431, 1552, 573, 1125, 562, 19, 19, /* 1050 */ 19, 19, 49, 336, 850, 851, 852, 111, 1368, 315, /* 1060 */ 429, 576, 413, 433, 341, 306, 137, 138, 91, 115, /* 1070 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, /* 1080 */ 136, 136, 576, 1309, 82, 82, 137, 138, 91, 529, /* 1090 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, /* 1100 */ 136, 136, 1569, 222, 377, 19, 19, 305, 1126, 1169, /* 1110 */ 398, 1148, 22, 22, 498, 333, 1569, 335, 377, 576, /* 1120 */ 438, 445, 1169, 1127, 486, 1169, 134, 134, 134, 134, /* 1130 */ 133, 133, 132, 132, 132, 131, 128, 451, 1128, 576, /* 1140 */ 902, 576, 145, 145, 6, 576, 134, 134, 134, 134, /* 1150 */ 133, 133, 132, 132, 132, 131, 128, 451, 214, 1336, /* 1160 */ 922, 576, 19, 19, 19, 19, 1282, 419, 19, 19, /* 1170 */ 923, 412, 515, 141, 576, 1169, 413, 206, 465, 207, /* 1180 */ 903, 215, 1575, 552, 147, 147, 7, 227, 1169, 411, /* 1190 */ 1250, 1169, 120, 307, 117, 307, 413, 66, 66, 334, /* 1200 */ 137, 138, 91, 119, 1228, 1228, 1063, 1066, 1053, 1053, /* 1210 */ 135, 135, 136, 136, 136, 136, 413, 285, 209, 969, /* 1220 */ 137, 138, 91, 471, 1228, 1228, 1063, 1066, 1053, 1053, /* 1230 */ 135, 135, 136, 136, 136, 136, 435, 10, 1450, 267, /* 1240 */ 137, 126, 91, 1435, 1228, 1228, 1063, 1066, 1053, 1053, /* 1250 */ 135, 135, 136, 136, 136, 136, 1435, 1435, 410, 409, /* 1260 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, /* 1270 */ 128, 451, 576, 969, 576, 1224, 498, 373, 1595, 1554, /* 1280 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, /* 1290 */ 128, 451, 532, 457, 576, 82, 82, 82, 82, 111, /* 1300 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, /* 1310 */ 128, 451, 109, 233, 430, 1576, 546, 67, 67, 7, /* 1320 */ 413, 351, 550, 1550, 260, 259, 258, 494, 443, 569, /* 1330 */ 419, 983, 446, 1224, 450, 545, 1207, 576, 969, 984, /* 1340 */ 413, 475, 1449, 1574, 1180, 138, 91, 7, 1228, 1228, /* 1350 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, /* 1360 */ 21, 21, 267, 576, 300, 1126, 91, 233, 1228, 1228, /* 1370 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, /* 1380 */ 1127, 373, 1595, 161, 1573, 16, 53, 53, 7, 108, /* 1390 */ 533, 38, 969, 125, 1207, 1128, 1180, 576, 1224, 123, /* 1400 */ 568, 893, 4, 324, 134, 134, 134, 134, 133, 133, /* 1410 */ 132, 132, 132, 131, 128, 451, 571, 564, 534, 576, /* 1420 */ 68, 68, 576, 39, 134, 134, 134, 134, 133, 133, /* 1430 */ 132, 132, 132, 131, 128, 451, 576, 160, 1571, 1223, /* 1440 */ 452, 576, 54, 54, 576, 69, 69, 576, 1366, 576, /* 1450 */ 420, 184, 565, 463, 297, 576, 1224, 463, 297, 70, /* 1460 */ 70, 576, 44, 474, 71, 71, 576, 72, 72, 576, /* 1470 */ 73, 73, 55, 55, 411, 874, 242, 576, 56, 56, /* 1480 */ 576, 1040, 576, 478, 57, 57, 576, 121, 121, 59, /* 1490 */ 59, 23, 60, 60, 411, 122, 319, 452, 577, 452, /* 1500 */ 74, 74, 1028, 75, 75, 76, 76, 411, 290, 20, /* 1510 */ 20, 108, 287, 231, 553, 123, 568, 325, 4, 320, /* 1520 */ 567, 97, 218, 944, 1144, 328, 400, 576, 943, 576, /* 1530 */ 1380, 424, 571, 874, 1028, 1028, 1030, 1031, 35, 293, /* 1540 */ 534, 576, 1104, 576, 1104, 9, 576, 342, 576, 111, /* 1550 */ 77, 77, 143, 143, 576, 205, 452, 222, 1379, 889, /* 1560 */ 576, 901, 900, 1188, 144, 144, 78, 78, 565, 62, /* 1570 */ 62, 79, 79, 323, 1021, 576, 266, 63, 63, 908, /* 1580 */ 909, 1589, 542, 80, 80, 576, 371, 541, 123, 568, /* 1590 */ 480, 4, 266, 482, 244, 266, 370, 1040, 64, 64, /* 1600 */ 576, 466, 576, 121, 121, 571, 1557, 576, 170, 170, /* 1610 */ 576, 122, 576, 452, 577, 452, 576, 889, 1028, 576, /* 1620 */ 165, 576, 111, 171, 171, 87, 87, 337, 1616, 452, /* 1630 */ 65, 65, 1530, 83, 83, 146, 146, 986, 987, 84, /* 1640 */ 84, 565, 168, 168, 148, 148, 1092, 347, 1032, 111, /* 1650 */ 1028, 1028, 1030, 1031, 35, 542, 1103, 576, 1103, 576, /* 1660 */ 543, 123, 568, 504, 4, 263, 576, 361, 1529, 111, /* 1670 */ 1040, 1088, 576, 263, 576, 490, 121, 121, 571, 1188, /* 1680 */ 142, 142, 169, 169, 122, 576, 452, 577, 452, 162, /* 1690 */ 162, 1028, 576, 563, 576, 152, 152, 151, 151, 348, /* 1700 */ 1376, 974, 452, 266, 1092, 942, 1032, 125, 149, 149, /* 1710 */ 939, 576, 125, 576, 565, 150, 150, 86, 86, 872, /* 1720 */ 352, 159, 576, 1028, 1028, 1030, 1031, 35, 542, 941, /* 1730 */ 576, 125, 355, 541, 88, 88, 85, 85, 357, 359, /* 1740 */ 1324, 1308, 366, 1040, 376, 52, 52, 499, 1389, 121, /* 1750 */ 121, 1434, 1188, 58, 58, 1362, 1374, 122, 1439, 452, /* 1760 */ 577, 452, 1289, 167, 1028, 1280, 280, 1268, 1267, 1269, /* 1770 */ 1609, 1359, 312, 313, 12, 314, 397, 1421, 224, 1416, /* 1780 */ 295, 237, 1409, 339, 340, 1426, 301, 345, 484, 228, /* 1790 */ 1371, 1307, 1372, 1370, 1425, 404, 1028, 1028, 1030, 1031, /* 1800 */ 35, 1601, 1192, 454, 509, 369, 292, 1502, 210, 1501, /* 1810 */ 1369, 396, 396, 395, 277, 393, 211, 566, 859, 1612, /* 1820 */ 1244, 123, 568, 391, 4, 1188, 223, 270, 1549, 1547, /* 1830 */ 1241, 239, 186, 327, 422, 96, 195, 220, 571, 235, /* 1840 */ 180, 326, 188, 468, 190, 1507, 191, 192, 92, 193, /* 1850 */ 469, 95, 1422, 13, 502, 247, 1430, 109, 199, 402, /* 1860 */ 476, 405, 452, 1496, 1428, 1427, 14, 491, 251, 102, /* 1870 */ 497, 1518, 241, 281, 565, 253, 203, 354, 500, 254, /* 1880 */ 175, 1270, 407, 43, 350, 518, 1327, 436, 255, 1326, /* 1890 */ 1325, 1318, 104, 893, 1626, 229, 408, 440, 1625, 441, /* 1900 */ 240, 310, 1296, 1040, 311, 1317, 527, 1594, 1297, 121, /* 1910 */ 121, 368, 1295, 1624, 268, 269, 1580, 122, 1579, 452, /* 1920 */ 577, 452, 374, 444, 1028, 1394, 1393, 140, 553, 90, /* 1930 */ 568, 11, 4, 1483, 383, 414, 385, 110, 116, 216, /* 1940 */ 320, 567, 1350, 555, 42, 318, 571, 537, 1349, 389, /* 1950 */ 390, 579, 1198, 276, 279, 278, 1028, 1028, 1030, 1031, /* 1960 */ 35, 580, 415, 1265, 458, 1260, 416, 185, 1534, 172, /* 1970 */ 452, 1535, 173, 156, 308, 846, 1533, 1532, 453, 217, /* 1980 */ 225, 89, 565, 174, 322, 1188, 226, 236, 1102, 154, /* 1990 */ 1100, 330, 176, 187, 1223, 189, 925, 338, 243, 1116, /* 2000 */ 246, 194, 177, 178, 425, 427, 98, 99, 196, 100, /* 2010 */ 101, 1040, 179, 1119, 248, 1115, 249, 121, 121, 24, /* 2020 */ 163, 250, 349, 1108, 266, 122, 1238, 452, 577, 452, /* 2030 */ 1192, 454, 1028, 200, 292, 496, 252, 201, 861, 396, /* 2040 */ 396, 395, 277, 393, 15, 501, 859, 370, 292, 256, /* 2050 */ 202, 554, 505, 396, 396, 395, 277, 393, 103, 239, /* 2060 */ 859, 327, 25, 26, 1028, 1028, 1030, 1031, 35, 326, /* 2070 */ 362, 510, 891, 239, 365, 327, 513, 904, 105, 309, /* 2080 */ 164, 181, 27, 326, 106, 521, 107, 1185, 1069, 1155, /* 2090 */ 17, 1154, 284, 1188, 286, 978, 265, 204, 125, 1171, /* 2100 */ 241, 230, 972, 1175, 28, 1160, 29, 1179, 175, 1173, /* 2110 */ 30, 43, 31, 1178, 241, 32, 41, 549, 8, 33, /* 2120 */ 208, 111, 175, 1083, 1070, 43, 113, 1068, 240, 114, /* 2130 */ 1072, 34, 1073, 561, 1124, 118, 271, 36, 18, 1194, /* 2140 */ 1033, 873, 240, 935, 124, 37, 272, 273, 1617, 572, /* 2150 */ 183, 153, 394, 1193, 1256, 1256, 1256, 1256, 1256, 1256, /* 2160 */ 1256, 1256, 1256, 414, 1256, 1256, 1256, 1256, 320, 567, /* 2170 */ 1256, 1256, 1256, 1256, 1256, 1256, 1256, 414, 1256, 1256, /* 2180 */ 1256, 1256, 320, 567, 1256, 1256, 1256, 1256, 1256, 1256, /* 2190 */ 1256, 1256, 458, 1256, 1256, 1256, 1256, 1256, 1256, 1256, /* 2200 */ 1256, 1256, 1256, 1256, 1256, 1256, 458, }; static const YYCODETYPE yy_lookahead[] = { /* 0 */ 276, 277, 278, 240, 241, 224, 194, 226, 194, 240, /* 10 */ 241, 194, 216, 220, 194, 234, 253, 194, 255, 19, /* 20 */ 224, 297, 253, 194, 255, 205, 212, 213, 205, 217, /* 30 */ 218, 31, 205, 194, 217, 218, 194, 217, 218, 39, /* 40 */ 217, 218, 312, 43, 44, 45, 316, 47, 48, 49, /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 19, /* 60 */ 240, 241, 194, 240, 241, 194, 254, 240, 241, 276, /* 70 */ 277, 278, 233, 253, 254, 255, 253, 254, 255, 217, /* 80 */ 253, 239, 255, 43, 44, 45, 263, 47, 48, 49, /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 270, /* 100 */ 286, 22, 23, 103, 104, 105, 106, 107, 108, 109, /* 110 */ 110, 111, 112, 113, 114, 82, 47, 48, 49, 50, /* 120 */ 186, 187, 188, 189, 190, 191, 189, 87, 191, 89, /* 130 */ 196, 19, 198, 196, 317, 198, 319, 25, 194, 205, /* 140 */ 298, 270, 205, 103, 104, 105, 106, 107, 108, 109, /* 150 */ 110, 111, 112, 113, 114, 43, 44, 45, 11, 47, /* 160 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, /* 170 */ 58, 60, 139, 140, 240, 241, 214, 240, 241, 311, /* 180 */ 312, 102, 70, 239, 316, 194, 19, 253, 77, 255, /* 190 */ 253, 122, 255, 55, 56, 57, 58, 59, 207, 88, /* 200 */ 194, 90, 268, 194, 93, 268, 107, 108, 109, 110, /* 210 */ 111, 112, 113, 114, 47, 103, 104, 105, 106, 107, /* 220 */ 108, 109, 110, 111, 112, 113, 114, 114, 117, 118, /* 230 */ 119, 276, 277, 278, 300, 19, 194, 300, 276, 277, /* 240 */ 278, 103, 104, 105, 106, 107, 108, 109, 110, 111, /* 250 */ 112, 113, 114, 55, 56, 57, 58, 146, 194, 43, /* 260 */ 44, 45, 47, 47, 48, 49, 50, 51, 52, 53, /* 270 */ 54, 55, 56, 57, 58, 82, 129, 130, 60, 129, /* 280 */ 130, 217, 218, 116, 68, 25, 103, 104, 105, 106, /* 290 */ 107, 108, 109, 110, 111, 112, 113, 114, 23, 132, /* 300 */ 294, 103, 104, 105, 106, 107, 108, 109, 110, 111, /* 310 */ 112, 113, 114, 217, 121, 306, 194, 308, 26, 103, /* 320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, /* 330 */ 114, 116, 139, 140, 217, 117, 118, 119, 120, 19, /* 340 */ 194, 123, 124, 125, 24, 109, 110, 111, 112, 113, /* 350 */ 114, 133, 60, 311, 312, 250, 194, 252, 316, 19, /* 360 */ 194, 166, 167, 43, 44, 45, 205, 47, 48, 49, /* 370 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 217, /* 380 */ 218, 317, 318, 43, 44, 45, 264, 47, 48, 49, /* 390 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 139, /* 400 */ 140, 240, 241, 139, 140, 188, 189, 190, 191, 117, /* 410 */ 118, 119, 231, 196, 253, 198, 255, 194, 194, 258, /* 420 */ 259, 146, 205, 103, 104, 105, 106, 107, 108, 109, /* 430 */ 110, 111, 112, 113, 114, 109, 212, 213, 236, 237, /* 440 */ 217, 218, 194, 103, 104, 105, 106, 107, 108, 109, /* 450 */ 110, 111, 112, 113, 114, 194, 120, 240, 241, 123, /* 460 */ 124, 125, 136, 194, 19, 74, 60, 141, 23, 133, /* 470 */ 253, 194, 255, 82, 194, 309, 310, 254, 29, 317, /* 480 */ 318, 194, 33, 22, 199, 268, 263, 239, 43, 44, /* 490 */ 45, 151, 47, 48, 49, 50, 51, 52, 53, 54, /* 500 */ 55, 56, 57, 58, 217, 218, 194, 60, 19, 146, /* 510 */ 286, 242, 23, 107, 108, 66, 204, 300, 206, 128, /* 520 */ 73, 60, 116, 117, 118, 119, 265, 121, 165, 60, /* 530 */ 139, 140, 43, 44, 45, 129, 47, 48, 49, 50, /* 540 */ 51, 52, 53, 54, 55, 56, 57, 58, 103, 104, /* 550 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, /* 560 */ 154, 194, 156, 194, 117, 118, 119, 280, 283, 205, /* 570 */ 101, 220, 287, 19, 20, 306, 22, 308, 117, 118, /* 580 */ 119, 211, 212, 213, 217, 218, 117, 118, 236, 237, /* 590 */ 36, 122, 103, 104, 105, 106, 107, 108, 109, 110, /* 600 */ 111, 112, 113, 114, 240, 241, 194, 60, 194, 194, /* 610 */ 194, 194, 19, 194, 60, 194, 23, 253, 206, 255, /* 620 */ 73, 254, 19, 154, 155, 156, 72, 276, 277, 278, /* 630 */ 263, 217, 218, 217, 218, 271, 43, 44, 45, 271, /* 640 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, /* 650 */ 57, 58, 183, 194, 285, 101, 19, 214, 60, 242, /* 660 */ 23, 107, 108, 109, 117, 118, 119, 16, 254, 115, /* 670 */ 254, 117, 118, 119, 194, 60, 122, 263, 205, 264, /* 680 */ 43, 44, 45, 264, 47, 48, 49, 50, 51, 52, /* 690 */ 53, 54, 55, 56, 57, 58, 103, 104, 105, 106, /* 700 */ 107, 108, 109, 110, 111, 112, 113, 114, 154, 155, /* 710 */ 156, 157, 158, 240, 241, 117, 118, 119, 101, 205, /* 720 */ 117, 19, 20, 306, 22, 308, 253, 74, 255, 78, /* 730 */ 205, 80, 117, 118, 119, 118, 293, 183, 36, 122, /* 740 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, /* 750 */ 113, 114, 194, 294, 240, 241, 211, 212, 213, 144, /* 760 */ 19, 23, 60, 25, 23, 240, 241, 253, 245, 255, /* 770 */ 15, 154, 155, 156, 72, 217, 218, 194, 253, 256, /* 780 */ 255, 128, 129, 130, 43, 44, 45, 22, 47, 48, /* 790 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, /* 800 */ 183, 19, 77, 101, 19, 128, 129, 130, 23, 107, /* 810 */ 108, 60, 254, 88, 21, 90, 61, 115, 93, 117, /* 820 */ 118, 119, 239, 22, 122, 60, 194, 205, 43, 44, /* 830 */ 45, 205, 47, 48, 49, 50, 51, 52, 53, 54, /* 840 */ 55, 56, 57, 58, 103, 104, 105, 106, 107, 108, /* 850 */ 109, 110, 111, 112, 113, 114, 154, 155, 156, 157, /* 860 */ 158, 60, 240, 241, 60, 116, 240, 241, 117, 118, /* 870 */ 119, 146, 194, 19, 81, 253, 275, 255, 24, 253, /* 880 */ 98, 255, 117, 118, 119, 183, 22, 194, 103, 104, /* 890 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, /* 900 */ 151, 194, 270, 152, 22, 23, 194, 25, 19, 202, /* 910 */ 217, 218, 23, 109, 207, 314, 315, 124, 117, 118, /* 920 */ 119, 117, 118, 119, 60, 232, 22, 23, 19, 25, /* 930 */ 303, 304, 43, 44, 45, 22, 47, 48, 49, 50, /* 940 */ 51, 52, 53, 54, 55, 56, 57, 58, 270, 227, /* 950 */ 96, 60, 43, 44, 45, 162, 47, 48, 49, 50, /* 960 */ 51, 52, 53, 54, 55, 56, 57, 58, 114, 112, /* 970 */ 113, 114, 194, 60, 120, 121, 122, 123, 124, 125, /* 980 */ 126, 117, 118, 119, 102, 25, 132, 107, 108, 194, /* 990 */ 194, 227, 103, 104, 105, 106, 107, 108, 109, 110, /* 1000 */ 111, 112, 113, 114, 194, 194, 102, 194, 117, 118, /* 1010 */ 119, 233, 103, 104, 105, 106, 107, 108, 109, 110, /* 1020 */ 111, 112, 113, 114, 194, 194, 19, 194, 217, 218, /* 1030 */ 117, 118, 119, 241, 154, 144, 156, 135, 242, 137, /* 1040 */ 138, 130, 19, 232, 194, 253, 23, 255, 217, 218, /* 1050 */ 217, 218, 242, 16, 7, 8, 9, 25, 261, 262, /* 1060 */ 265, 194, 19, 232, 153, 232, 43, 44, 45, 160, /* 1070 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, /* 1080 */ 57, 58, 194, 227, 217, 218, 43, 44, 45, 194, /* 1090 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, /* 1100 */ 57, 58, 306, 143, 308, 217, 218, 294, 12, 77, /* 1110 */ 22, 23, 217, 218, 194, 78, 306, 80, 308, 194, /* 1120 */ 232, 254, 90, 27, 117, 93, 103, 104, 105, 106, /* 1130 */ 107, 108, 109, 110, 111, 112, 113, 114, 42, 194, /* 1140 */ 35, 194, 217, 218, 214, 194, 103, 104, 105, 106, /* 1150 */ 107, 108, 109, 110, 111, 112, 113, 114, 194, 239, /* 1160 */ 64, 194, 217, 218, 217, 218, 209, 210, 217, 218, /* 1170 */ 74, 207, 67, 22, 194, 77, 19, 232, 245, 232, /* 1180 */ 75, 24, 312, 232, 217, 218, 316, 25, 90, 256, /* 1190 */ 102, 93, 159, 229, 161, 231, 19, 217, 218, 162, /* 1200 */ 43, 44, 45, 160, 47, 48, 49, 50, 51, 52, /* 1210 */ 53, 54, 55, 56, 57, 58, 19, 23, 288, 25, /* 1220 */ 43, 44, 45, 293, 47, 48, 49, 50, 51, 52, /* 1230 */ 53, 54, 55, 56, 57, 58, 131, 22, 275, 24, /* 1240 */ 43, 44, 45, 194, 47, 48, 49, 50, 51, 52, /* 1250 */ 53, 54, 55, 56, 57, 58, 194, 194, 107, 108, /* 1260 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, /* 1270 */ 113, 114, 194, 25, 194, 60, 194, 314, 315, 194, /* 1280 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, /* 1290 */ 113, 114, 19, 194, 194, 217, 218, 217, 218, 25, /* 1300 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, /* 1310 */ 113, 114, 150, 119, 265, 312, 67, 217, 218, 316, /* 1320 */ 19, 239, 194, 194, 128, 129, 130, 265, 265, 209, /* 1330 */ 210, 31, 254, 118, 254, 86, 60, 194, 144, 39, /* 1340 */ 19, 130, 275, 312, 95, 44, 45, 316, 47, 48, /* 1350 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, /* 1360 */ 217, 218, 24, 194, 153, 12, 45, 119, 47, 48, /* 1370 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, /* 1380 */ 27, 314, 315, 22, 312, 24, 217, 218, 316, 116, /* 1390 */ 117, 22, 144, 25, 118, 42, 147, 194, 60, 19, /* 1400 */ 20, 127, 22, 194, 103, 104, 105, 106, 107, 108, /* 1410 */ 109, 110, 111, 112, 113, 114, 36, 64, 145, 194, /* 1420 */ 217, 218, 194, 54, 103, 104, 105, 106, 107, 108, /* 1430 */ 109, 110, 111, 112, 113, 114, 194, 22, 310, 25, /* 1440 */ 60, 194, 217, 218, 194, 217, 218, 194, 260, 194, /* 1450 */ 301, 302, 72, 262, 262, 194, 118, 266, 266, 217, /* 1460 */ 218, 194, 82, 245, 217, 218, 194, 217, 218, 194, /* 1470 */ 217, 218, 217, 218, 256, 60, 24, 194, 217, 218, /* 1480 */ 194, 101, 194, 245, 217, 218, 194, 107, 108, 217, /* 1490 */ 218, 22, 217, 218, 256, 115, 245, 117, 118, 119, /* 1500 */ 217, 218, 122, 217, 218, 217, 218, 256, 22, 217, /* 1510 */ 218, 116, 258, 259, 146, 19, 20, 194, 22, 139, /* 1520 */ 140, 150, 151, 136, 23, 194, 25, 194, 141, 194, /* 1530 */ 194, 62, 36, 118, 154, 155, 156, 157, 158, 100, /* 1540 */ 145, 194, 154, 194, 156, 49, 194, 23, 194, 25, /* 1550 */ 217, 218, 217, 218, 194, 257, 60, 143, 194, 60, /* 1560 */ 194, 121, 122, 183, 217, 218, 217, 218, 72, 217, /* 1570 */ 218, 217, 218, 134, 23, 194, 25, 217, 218, 7, /* 1580 */ 8, 321, 86, 217, 218, 194, 122, 91, 19, 20, /* 1590 */ 23, 22, 25, 23, 142, 25, 132, 101, 217, 218, /* 1600 */ 194, 194, 194, 107, 108, 36, 194, 194, 217, 218, /* 1610 */ 194, 115, 194, 117, 118, 119, 194, 118, 122, 194, /* 1620 */ 23, 194, 25, 217, 218, 217, 218, 194, 142, 60, /* 1630 */ 217, 218, 194, 217, 218, 217, 218, 84, 85, 217, /* 1640 */ 218, 72, 217, 218, 217, 218, 60, 23, 60, 25, /* 1650 */ 154, 155, 156, 157, 158, 86, 154, 194, 156, 194, /* 1660 */ 91, 19, 20, 23, 22, 25, 194, 23, 194, 25, /* 1670 */ 101, 23, 194, 25, 194, 194, 107, 108, 36, 183, /* 1680 */ 217, 218, 217, 218, 115, 194, 117, 118, 119, 217, /* 1690 */ 218, 122, 194, 237, 194, 217, 218, 217, 218, 194, /* 1700 */ 194, 23, 60, 25, 118, 23, 118, 25, 217, 218, /* 1710 */ 23, 194, 25, 194, 72, 217, 218, 217, 218, 23, /* 1720 */ 194, 25, 194, 154, 155, 156, 157, 158, 86, 23, /* 1730 */ 194, 25, 194, 91, 217, 218, 217, 218, 194, 194, /* 1740 */ 194, 194, 194, 101, 194, 217, 218, 290, 194, 107, /* 1750 */ 108, 194, 183, 217, 218, 194, 194, 115, 194, 117, /* 1760 */ 118, 119, 194, 243, 122, 194, 289, 194, 194, 194, /* 1770 */ 194, 257, 257, 257, 244, 257, 192, 273, 215, 269, /* 1780 */ 246, 299, 269, 295, 247, 273, 247, 246, 295, 230, /* 1790 */ 261, 226, 261, 261, 273, 273, 154, 155, 156, 157, /* 1800 */ 158, 0, 1, 2, 221, 220, 5, 220, 250, 220, /* 1810 */ 261, 10, 11, 12, 13, 14, 250, 282, 17, 197, /* 1820 */ 61, 19, 20, 246, 22, 183, 244, 142, 201, 201, /* 1830 */ 38, 30, 299, 32, 201, 152, 22, 151, 36, 299, /* 1840 */ 43, 40, 235, 18, 238, 285, 238, 238, 296, 238, /* 1850 */ 201, 296, 274, 272, 18, 200, 235, 150, 235, 247, /* 1860 */ 247, 247, 60, 247, 274, 274, 272, 201, 200, 159, /* 1870 */ 63, 292, 71, 201, 72, 200, 22, 201, 222, 200, /* 1880 */ 79, 201, 222, 82, 291, 116, 219, 65, 200, 219, /* 1890 */ 219, 228, 22, 127, 225, 166, 222, 24, 225, 114, /* 1900 */ 99, 284, 221, 101, 284, 228, 307, 315, 219, 107, /* 1910 */ 108, 219, 219, 219, 201, 92, 320, 115, 320, 117, /* 1920 */ 118, 119, 222, 83, 122, 267, 267, 149, 146, 19, /* 1930 */ 20, 22, 22, 279, 250, 134, 201, 148, 159, 249, /* 1940 */ 139, 140, 251, 141, 25, 281, 36, 147, 251, 248, /* 1950 */ 247, 203, 13, 195, 6, 195, 154, 155, 156, 157, /* 1960 */ 158, 193, 305, 193, 163, 193, 305, 302, 214, 208, /* 1970 */ 60, 214, 208, 223, 223, 4, 214, 214, 3, 22, /* 1980 */ 215, 214, 72, 208, 164, 183, 215, 15, 23, 16, /* 1990 */ 23, 140, 131, 152, 25, 143, 20, 16, 24, 1, /* 2000 */ 145, 143, 131, 131, 62, 37, 54, 54, 152, 54, /* 2010 */ 54, 101, 131, 117, 34, 1, 142, 107, 108, 22, /* 2020 */ 5, 116, 162, 69, 25, 115, 76, 117, 118, 119, /* 2030 */ 1, 2, 122, 69, 5, 41, 142, 116, 20, 10, /* 2040 */ 11, 12, 13, 14, 24, 19, 17, 132, 5, 126, /* 2050 */ 22, 141, 68, 10, 11, 12, 13, 14, 22, 30, /* 2060 */ 17, 32, 22, 22, 154, 155, 156, 157, 158, 40, /* 2070 */ 23, 68, 60, 30, 24, 32, 97, 28, 22, 68, /* 2080 */ 23, 37, 34, 40, 150, 22, 25, 23, 23, 23, /* 2090 */ 22, 98, 23, 183, 23, 117, 34, 22, 25, 89, /* 2100 */ 71, 142, 144, 76, 34, 23, 34, 76, 79, 87, /* 2110 */ 34, 82, 34, 94, 71, 34, 22, 24, 44, 34, /* 2120 */ 25, 25, 79, 23, 23, 82, 143, 23, 99, 143, /* 2130 */ 23, 22, 11, 25, 23, 25, 22, 22, 22, 1, /* 2140 */ 23, 23, 99, 136, 22, 22, 142, 142, 142, 25, /* 2150 */ 25, 23, 15, 1, 322, 322, 322, 322, 322, 322, /* 2160 */ 322, 322, 322, 134, 322, 322, 322, 322, 139, 140, /* 2170 */ 322, 322, 322, 322, 322, 322, 322, 134, 322, 322, /* 2180 */ 322, 322, 139, 140, 322, 322, 322, 322, 322, 322, /* 2190 */ 322, 322, 163, 322, 322, 322, 322, 322, 322, 322, /* 2200 */ 322, 322, 322, 322, 322, 322, 163, 322, 322, 322, /* 2210 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2220 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2230 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2240 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2250 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2260 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2270 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2280 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2290 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2300 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2310 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2320 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2330 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2340 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, /* 2350 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, /* 2360 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, /* 2370 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, /* 2380 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, /* 2390 */ 186, 186, 186, }; #define YY_SHIFT_COUNT (582) #define YY_SHIFT_MIN (0) #define YY_SHIFT_MAX (2152) static const unsigned short int yy_shift_ofst[] = { /* 0 */ 2029, 1801, 2043, 1380, 1380, 33, 391, 1496, 1569, 1642, /* 10 */ 702, 702, 702, 193, 33, 33, 33, 33, 33, 0, /* 20 */ 0, 216, 1177, 702, 702, 702, 702, 702, 702, 702, /* 30 */ 702, 702, 702, 702, 702, 702, 702, 702, 406, 406, /* 40 */ 111, 111, 218, 447, 547, 598, 598, 260, 260, 260, /* 50 */ 260, 40, 112, 320, 340, 445, 489, 593, 637, 741, /* 60 */ 785, 889, 909, 1023, 1043, 1157, 1177, 1177, 1177, 1177, /* 70 */ 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, /* 80 */ 1177, 1177, 1177, 1177, 1197, 1177, 1301, 1321, 1321, 554, /* 90 */ 1802, 1910, 702, 702, 702, 702, 702, 702, 702, 702, /* 100 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, /* 110 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, /* 120 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, /* 130 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, /* 140 */ 702, 702, 138, 198, 198, 198, 198, 198, 198, 198, /* 150 */ 183, 99, 236, 292, 598, 793, 167, 598, 598, 880, /* 160 */ 880, 598, 857, 150, 195, 195, 195, 264, 113, 113, /* 170 */ 2207, 2207, 854, 854, 854, 751, 765, 765, 765, 765, /* 180 */ 1096, 1096, 725, 292, 882, 904, 598, 598, 598, 598, /* 190 */ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, /* 200 */ 598, 598, 598, 598, 598, 1273, 1032, 1032, 598, 147, /* 210 */ 1098, 1098, 603, 603, 1276, 1276, 363, 2207, 2207, 2207, /* 220 */ 2207, 2207, 2207, 2207, 469, 617, 617, 801, 336, 461, /* 230 */ 804, 864, 615, 891, 913, 598, 598, 598, 598, 598, /* 240 */ 598, 598, 598, 598, 598, 653, 598, 598, 598, 598, /* 250 */ 598, 598, 598, 598, 598, 598, 598, 598, 1105, 1105, /* 260 */ 1105, 598, 598, 598, 1194, 598, 598, 598, 1215, 1249, /* 270 */ 598, 1353, 598, 598, 598, 598, 598, 598, 598, 598, /* 280 */ 677, 449, 902, 1338, 1338, 1338, 1338, 1248, 902, 902, /* 290 */ 326, 1151, 1047, 755, 749, 1371, 960, 1371, 1007, 1162, /* 300 */ 749, 749, 1162, 749, 960, 1007, 1274, 738, 215, 1300, /* 310 */ 1300, 1300, 1395, 1395, 1395, 1395, 1368, 1368, 1033, 1414, /* 320 */ 1387, 1361, 1759, 1759, 1685, 1685, 1792, 1792, 1685, 1683, /* 330 */ 1686, 1814, 1797, 1825, 1825, 1825, 1825, 1685, 1836, 1707, /* 340 */ 1686, 1686, 1707, 1814, 1797, 1707, 1797, 1707, 1685, 1836, /* 350 */ 1710, 1807, 1685, 1836, 1854, 1685, 1836, 1685, 1836, 1854, /* 360 */ 1769, 1769, 1769, 1822, 1870, 1870, 1854, 1769, 1766, 1769, /* 370 */ 1822, 1769, 1769, 1729, 1873, 1785, 1785, 1854, 1685, 1823, /* 380 */ 1823, 1840, 1840, 1778, 1782, 1909, 1685, 1779, 1778, 1789, /* 390 */ 1800, 1707, 1919, 1939, 1939, 1948, 1948, 1948, 2207, 2207, /* 400 */ 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, /* 410 */ 2207, 2207, 2207, 69, 1037, 79, 1088, 651, 1196, 1415, /* 420 */ 1501, 1439, 1369, 1452, 911, 1211, 1524, 1469, 1551, 1567, /* 430 */ 1570, 1624, 1640, 1644, 1499, 1440, 1572, 1464, 1597, 275, /* 440 */ 782, 1586, 1648, 1678, 1553, 1682, 1687, 1388, 1502, 1696, /* 450 */ 1706, 1588, 1486, 1971, 1975, 1957, 1820, 1972, 1973, 1965, /* 460 */ 1967, 1851, 1841, 1861, 1969, 1969, 1974, 1852, 1976, 1855, /* 470 */ 1981, 1998, 1858, 1871, 1969, 1872, 1942, 1968, 1969, 1856, /* 480 */ 1952, 1953, 1955, 1956, 1881, 1896, 1980, 1874, 2014, 2015, /* 490 */ 1997, 1905, 1860, 1954, 1999, 1964, 1950, 1994, 1894, 1921, /* 500 */ 2020, 2018, 2026, 1915, 1923, 2028, 1984, 2036, 2040, 2047, /* 510 */ 2041, 2003, 2012, 2050, 1979, 2049, 2056, 2011, 2044, 2057, /* 520 */ 2048, 1934, 2063, 2064, 2065, 2061, 2066, 2068, 1993, 1959, /* 530 */ 2069, 2071, 1978, 2062, 2075, 1958, 2073, 2070, 2072, 2076, /* 540 */ 2078, 2010, 2027, 2022, 2074, 2031, 2019, 2081, 2082, 2094, /* 550 */ 2093, 2095, 2096, 2085, 1983, 1986, 2100, 2073, 2101, 2104, /* 560 */ 2107, 2109, 2108, 2110, 2111, 2114, 2121, 2115, 2116, 2117, /* 570 */ 2118, 2122, 2123, 2124, 2007, 2004, 2005, 2006, 2125, 2128, /* 580 */ 2137, 2138, 2152, }; #define YY_REDUCE_COUNT (412) #define YY_REDUCE_MIN (-276) #define YY_REDUCE_MAX (1775) static const short yy_reduce_ofst[] = { /* 0 */ -66, 217, -63, -177, -180, 161, 364, 64, -183, 162, /* 10 */ 223, 367, 414, -173, 473, 514, 525, 622, 626, -207, /* 20 */ 351, -276, -38, 693, 811, 831, 833, 888, -188, 945, /* 30 */ 947, 416, 558, 951, 867, 287, 1078, 1080, -186, 224, /* 40 */ -132, 42, 964, 269, 417, 796, 810, -237, -231, -237, /* 50 */ -231, -45, -45, -45, -45, -45, -45, -45, -45, -45, /* 60 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, /* 70 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, /* 80 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, 895, /* 90 */ 925, 967, 980, 1100, 1143, 1169, 1203, 1225, 1228, 1242, /* 100 */ 1247, 1250, 1253, 1255, 1261, 1267, 1272, 1275, 1283, 1286, /* 110 */ 1288, 1292, 1333, 1335, 1347, 1349, 1352, 1354, 1360, 1366, /* 120 */ 1381, 1391, 1406, 1408, 1413, 1416, 1418, 1422, 1425, 1427, /* 130 */ 1463, 1465, 1472, 1478, 1480, 1491, 1498, 1500, 1517, 1519, /* 140 */ 1528, 1536, -45, -45, -45, -45, -45, -45, -45, -45, /* 150 */ -45, -45, -45, 312, -158, 285, -219, 9, 166, 370, /* 160 */ 545, 707, -45, 930, 601, 963, 1067, 792, -45, -45, /* 170 */ -45, -45, -204, -204, -204, 369, -171, -129, 632, 678, /* 180 */ 202, 352, -270, 412, 627, 627, -9, 122, 415, 419, /* 190 */ -56, 248, 583, 920, 6, 261, 459, 795, 1049, 813, /* 200 */ 1062, 1082, -161, 778, 1063, 797, 870, 1003, 1128, 443, /* 210 */ 1031, 1072, 1191, 1192, 957, 1120, 105, 1149, 523, 933, /* 220 */ 1218, 1238, 1254, 1251, -138, 96, 117, 146, 181, 277, /* 230 */ 280, 421, 480, 712, 830, 850, 1085, 1099, 1129, 1209, /* 240 */ 1323, 1331, 1336, 1364, 1407, 368, 1412, 1433, 1438, 1474, /* 250 */ 1481, 1505, 1506, 1526, 1538, 1544, 1545, 1546, 722, 764, /* 260 */ 856, 1547, 1548, 1550, 1188, 1554, 1557, 1561, 1298, 1260, /* 270 */ 1562, 1456, 1564, 280, 1568, 1571, 1573, 1574, 1575, 1576, /* 280 */ 1457, 1477, 1520, 1514, 1515, 1516, 1518, 1188, 1520, 1520, /* 290 */ 1530, 1563, 1584, 1482, 1504, 1510, 1534, 1513, 1488, 1537, /* 300 */ 1512, 1521, 1539, 1522, 1541, 1493, 1583, 1559, 1565, 1585, /* 310 */ 1587, 1589, 1529, 1531, 1532, 1549, 1558, 1566, 1535, 1577, /* 320 */ 1582, 1622, 1533, 1540, 1627, 1628, 1552, 1555, 1633, 1560, /* 330 */ 1578, 1581, 1607, 1606, 1608, 1609, 1611, 1649, 1655, 1612, /* 340 */ 1590, 1591, 1613, 1594, 1621, 1614, 1623, 1616, 1666, 1668, /* 350 */ 1579, 1593, 1672, 1675, 1656, 1676, 1679, 1680, 1688, 1660, /* 360 */ 1667, 1670, 1671, 1663, 1669, 1673, 1674, 1689, 1681, 1692, /* 370 */ 1677, 1693, 1694, 1592, 1599, 1617, 1620, 1700, 1713, 1596, /* 380 */ 1598, 1658, 1659, 1691, 1684, 1654, 1735, 1664, 1697, 1690, /* 390 */ 1701, 1703, 1748, 1758, 1760, 1768, 1770, 1772, 1657, 1661, /* 400 */ 1665, 1761, 1754, 1757, 1762, 1763, 1764, 1750, 1751, 1765, /* 410 */ 1771, 1767, 1775, }; static const YYACTIONTYPE yy_default[] = { /* 0 */ 1663, 1663, 1663, 1491, 1254, 1367, 1254, 1254, 1254, 1254, /* 10 */ 1491, 1491, 1491, 1254, 1254, 1254, 1254, 1254, 1254, 1397, /* 20 */ 1397, 1544, 1287, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 30 */ 1254, 1254, 1254, 1254, 1254, 1490, 1254, 1254, 1254, 1254, /* 40 */ 1578, 1578, 1254, 1254, 1254, 1254, 1254, 1563, 1562, 1254, /* 50 */ 1254, 1254, 1406, 1254, 1413, 1254, 1254, 1254, 1254, 1254, /* 60 */ 1492, 1493, 1254, 1254, 1254, 1254, 1543, 1545, 1508, 1420, /* 70 */ 1419, 1418, 1417, 1526, 1385, 1411, 1404, 1408, 1487, 1488, /* 80 */ 1486, 1641, 1493, 1492, 1254, 1407, 1455, 1471, 1454, 1254, /* 90 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 100 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 110 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 120 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 130 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 140 */ 1254, 1254, 1463, 1470, 1469, 1468, 1477, 1467, 1464, 1457, /* 150 */ 1456, 1458, 1459, 1278, 1254, 1275, 1329, 1254, 1254, 1254, /* 160 */ 1254, 1254, 1460, 1287, 1448, 1447, 1446, 1254, 1474, 1461, /* 170 */ 1473, 1472, 1551, 1615, 1614, 1509, 1254, 1254, 1254, 1254, /* 180 */ 1254, 1254, 1578, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 190 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 200 */ 1254, 1254, 1254, 1254, 1254, 1387, 1578, 1578, 1254, 1287, /* 210 */ 1578, 1578, 1388, 1388, 1283, 1283, 1391, 1558, 1358, 1358, /* 220 */ 1358, 1358, 1367, 1358, 1254, 1254, 1254, 1254, 1254, 1254, /* 230 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1548, /* 240 */ 1546, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 250 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 260 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1363, 1254, /* 270 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1608, /* 280 */ 1254, 1521, 1343, 1363, 1363, 1363, 1363, 1365, 1344, 1342, /* 290 */ 1357, 1288, 1261, 1655, 1423, 1412, 1364, 1412, 1652, 1410, /* 300 */ 1423, 1423, 1410, 1423, 1364, 1652, 1304, 1630, 1299, 1397, /* 310 */ 1397, 1397, 1387, 1387, 1387, 1387, 1391, 1391, 1489, 1364, /* 320 */ 1357, 1254, 1655, 1655, 1373, 1373, 1654, 1654, 1373, 1509, /* 330 */ 1638, 1432, 1332, 1338, 1338, 1338, 1338, 1373, 1272, 1410, /* 340 */ 1638, 1638, 1410, 1432, 1332, 1410, 1332, 1410, 1373, 1272, /* 350 */ 1525, 1649, 1373, 1272, 1499, 1373, 1272, 1373, 1272, 1499, /* 360 */ 1330, 1330, 1330, 1319, 1254, 1254, 1499, 1330, 1304, 1330, /* 370 */ 1319, 1330, 1330, 1596, 1254, 1503, 1503, 1499, 1373, 1588, /* 380 */ 1588, 1400, 1400, 1405, 1391, 1494, 1373, 1254, 1405, 1403, /* 390 */ 1401, 1410, 1322, 1611, 1611, 1607, 1607, 1607, 1660, 1660, /* 400 */ 1558, 1623, 1287, 1287, 1287, 1287, 1623, 1306, 1306, 1288, /* 410 */ 1288, 1287, 1623, 1254, 1254, 1254, 1254, 1254, 1254, 1618, /* 420 */ 1254, 1553, 1510, 1377, 1254, 1254, 1254, 1254, 1254, 1254, /* 430 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 440 */ 1564, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 450 */ 1254, 1254, 1437, 1254, 1257, 1555, 1254, 1254, 1254, 1254, /* 460 */ 1254, 1254, 1254, 1254, 1414, 1415, 1378, 1254, 1254, 1254, /* 470 */ 1254, 1254, 1254, 1254, 1429, 1254, 1254, 1254, 1424, 1254, /* 480 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1651, 1254, 1254, /* 490 */ 1254, 1254, 1254, 1254, 1524, 1523, 1254, 1254, 1375, 1254, /* 500 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 510 */ 1254, 1254, 1302, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 520 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 530 */ 1254, 1254, 1254, 1254, 1254, 1254, 1402, 1254, 1254, 1254, /* 540 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 550 */ 1254, 1593, 1392, 1254, 1254, 1254, 1254, 1642, 1254, 1254, /* 560 */ 1254, 1254, 1352, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 570 */ 1254, 1254, 1254, 1634, 1346, 1438, 1254, 1441, 1276, 1254, /* 580 */ 1266, 1254, 1254, }; /********** End of lemon-generated parsing tables *****************************/ /* The next table maps tokens (terminal symbols) into fallback tokens. ** If a construct like the following: |
︙ | ︙ | |||
173728 173729 173730 173731 173732 173733 173734 | ** to revert to identifiers if they keyword does not apply in the context where ** it appears. */ #ifdef YYFALLBACK static const YYCODETYPE yyFallback[] = { 0, /* $ => nothing */ 0, /* SEMI => nothing */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 174959 174960 174961 174962 174963 174964 174965 174966 174967 174968 174969 174970 174971 174972 174973 174974 174975 174976 174977 174978 174979 174980 174981 174982 174983 174984 174985 174986 174987 174988 174989 174990 174991 174992 174993 174994 174995 174996 174997 174998 174999 175000 175001 175002 175003 175004 175005 175006 175007 175008 175009 175010 175011 175012 175013 175014 175015 175016 175017 175018 175019 175020 175021 175022 175023 175024 175025 175026 175027 175028 175029 175030 175031 175032 175033 175034 175035 175036 175037 175038 175039 175040 175041 175042 175043 175044 175045 175046 175047 175048 175049 175050 175051 175052 175053 175054 175055 175056 175057 175058 175059 175060 175061 175062 175063 175064 175065 175066 175067 175068 175069 175070 175071 175072 | ** to revert to identifiers if they keyword does not apply in the context where ** it appears. */ #ifdef YYFALLBACK static const YYCODETYPE yyFallback[] = { 0, /* $ => nothing */ 0, /* SEMI => nothing */ 60, /* EXPLAIN => ID */ 60, /* QUERY => ID */ 60, /* PLAN => ID */ 60, /* BEGIN => ID */ 0, /* TRANSACTION => nothing */ 60, /* DEFERRED => ID */ 60, /* IMMEDIATE => ID */ 60, /* EXCLUSIVE => ID */ 0, /* COMMIT => nothing */ 60, /* END => ID */ 60, /* ROLLBACK => ID */ 60, /* SAVEPOINT => ID */ 60, /* RELEASE => ID */ 0, /* TO => nothing */ 0, /* TABLE => nothing */ 0, /* CREATE => nothing */ 60, /* IF => ID */ 0, /* NOT => nothing */ 0, /* EXISTS => nothing */ 60, /* TEMP => ID */ 0, /* LP => nothing */ 0, /* RP => nothing */ 0, /* AS => nothing */ 0, /* COMMA => nothing */ 60, /* WITHOUT => ID */ 60, /* ABORT => ID */ 60, /* ACTION => ID */ 60, /* AFTER => ID */ 60, /* ANALYZE => ID */ 60, /* ASC => ID */ 60, /* ATTACH => ID */ 60, /* BEFORE => ID */ 60, /* BY => ID */ 60, /* CASCADE => ID */ 60, /* CAST => ID */ 60, /* CONFLICT => ID */ 60, /* DATABASE => ID */ 60, /* DESC => ID */ 60, /* DETACH => ID */ 60, /* EACH => ID */ 60, /* FAIL => ID */ 0, /* OR => nothing */ 0, /* AND => nothing */ 0, /* IS => nothing */ 0, /* ISNOT => nothing */ 60, /* MATCH => ID */ 60, /* LIKE_KW => ID */ 0, /* BETWEEN => nothing */ 0, /* IN => nothing */ 0, /* ISNULL => nothing */ 0, /* NOTNULL => nothing */ 0, /* NE => nothing */ 0, /* EQ => nothing */ 0, /* GT => nothing */ 0, /* LE => nothing */ 0, /* LT => nothing */ 0, /* GE => nothing */ 0, /* ESCAPE => nothing */ 0, /* ID => nothing */ 60, /* COLUMNKW => ID */ 60, /* DO => ID */ 60, /* FOR => ID */ 60, /* IGNORE => ID */ 60, /* INITIALLY => ID */ 60, /* INSTEAD => ID */ 60, /* NO => ID */ 60, /* KEY => ID */ 60, /* OF => ID */ 60, /* OFFSET => ID */ 60, /* PRAGMA => ID */ 60, /* RAISE => ID */ 60, /* RECURSIVE => ID */ 60, /* REPLACE => ID */ 60, /* RESTRICT => ID */ 60, /* ROW => ID */ 60, /* ROWS => ID */ 60, /* TRIGGER => ID */ 60, /* VACUUM => ID */ 60, /* VIEW => ID */ 60, /* VIRTUAL => ID */ 60, /* WITH => ID */ 60, /* NULLS => ID */ 60, /* FIRST => ID */ 60, /* LAST => ID */ 60, /* CURRENT => ID */ 60, /* FOLLOWING => ID */ 60, /* PARTITION => ID */ 60, /* PRECEDING => ID */ 60, /* RANGE => ID */ 60, /* UNBOUNDED => ID */ 60, /* EXCLUDE => ID */ 60, /* GROUPS => ID */ 60, /* OTHERS => ID */ 60, /* TIES => ID */ 60, /* GENERATED => ID */ 60, /* ALWAYS => ID */ 60, /* MATERIALIZED => ID */ 60, /* REINDEX => ID */ 60, /* RENAME => ID */ 60, /* CTIME_KW => ID */ 0, /* ANY => nothing */ 0, /* BITAND => nothing */ 0, /* BITOR => nothing */ 0, /* LSHIFT => nothing */ 0, /* RSHIFT => nothing */ 0, /* PLUS => nothing */ 0, /* MINUS => nothing */ |
︙ | ︙ | |||
173897 173898 173899 173900 173901 173902 173903 | 0, /* WINDOW => nothing */ 0, /* OVER => nothing */ 0, /* FILTER => nothing */ 0, /* COLUMN => nothing */ 0, /* AGG_FUNCTION => nothing */ 0, /* AGG_COLUMN => nothing */ 0, /* TRUEFALSE => nothing */ | < | 175129 175130 175131 175132 175133 175134 175135 175136 175137 175138 175139 175140 175141 175142 | 0, /* WINDOW => nothing */ 0, /* OVER => nothing */ 0, /* FILTER => nothing */ 0, /* COLUMN => nothing */ 0, /* AGG_FUNCTION => nothing */ 0, /* AGG_COLUMN => nothing */ 0, /* TRUEFALSE => nothing */ 0, /* FUNCTION => nothing */ 0, /* UPLUS => nothing */ 0, /* UMINUS => nothing */ 0, /* TRUTH => nothing */ 0, /* REGISTER => nothing */ 0, /* VECTOR => nothing */ 0, /* SELECT_COLUMN => nothing */ |
︙ | ︙ | |||
174041 174042 174043 174044 174045 174046 174047 | /* 39 */ "DESC", /* 40 */ "DETACH", /* 41 */ "EACH", /* 42 */ "FAIL", /* 43 */ "OR", /* 44 */ "AND", /* 45 */ "IS", | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 175272 175273 175274 175275 175276 175277 175278 175279 175280 175281 175282 175283 175284 175285 175286 175287 175288 175289 175290 175291 175292 175293 175294 175295 175296 175297 175298 175299 175300 175301 175302 175303 175304 175305 175306 175307 175308 175309 175310 175311 175312 175313 175314 175315 175316 175317 175318 175319 175320 175321 175322 175323 175324 175325 175326 175327 175328 175329 175330 175331 175332 175333 175334 175335 175336 175337 175338 175339 175340 175341 175342 175343 175344 175345 175346 175347 175348 175349 175350 175351 175352 175353 175354 175355 175356 175357 175358 175359 175360 175361 175362 175363 175364 175365 175366 175367 175368 175369 175370 175371 175372 175373 175374 175375 175376 175377 175378 175379 175380 175381 175382 175383 175384 175385 175386 175387 175388 175389 175390 175391 175392 175393 175394 175395 175396 175397 175398 175399 175400 175401 175402 175403 175404 175405 175406 175407 175408 175409 175410 175411 | /* 39 */ "DESC", /* 40 */ "DETACH", /* 41 */ "EACH", /* 42 */ "FAIL", /* 43 */ "OR", /* 44 */ "AND", /* 45 */ "IS", /* 46 */ "ISNOT", /* 47 */ "MATCH", /* 48 */ "LIKE_KW", /* 49 */ "BETWEEN", /* 50 */ "IN", /* 51 */ "ISNULL", /* 52 */ "NOTNULL", /* 53 */ "NE", /* 54 */ "EQ", /* 55 */ "GT", /* 56 */ "LE", /* 57 */ "LT", /* 58 */ "GE", /* 59 */ "ESCAPE", /* 60 */ "ID", /* 61 */ "COLUMNKW", /* 62 */ "DO", /* 63 */ "FOR", /* 64 */ "IGNORE", /* 65 */ "INITIALLY", /* 66 */ "INSTEAD", /* 67 */ "NO", /* 68 */ "KEY", /* 69 */ "OF", /* 70 */ "OFFSET", /* 71 */ "PRAGMA", /* 72 */ "RAISE", /* 73 */ "RECURSIVE", /* 74 */ "REPLACE", /* 75 */ "RESTRICT", /* 76 */ "ROW", /* 77 */ "ROWS", /* 78 */ "TRIGGER", /* 79 */ "VACUUM", /* 80 */ "VIEW", /* 81 */ "VIRTUAL", /* 82 */ "WITH", /* 83 */ "NULLS", /* 84 */ "FIRST", /* 85 */ "LAST", /* 86 */ "CURRENT", /* 87 */ "FOLLOWING", /* 88 */ "PARTITION", /* 89 */ "PRECEDING", /* 90 */ "RANGE", /* 91 */ "UNBOUNDED", /* 92 */ "EXCLUDE", /* 93 */ "GROUPS", /* 94 */ "OTHERS", /* 95 */ "TIES", /* 96 */ "GENERATED", /* 97 */ "ALWAYS", /* 98 */ "MATERIALIZED", /* 99 */ "REINDEX", /* 100 */ "RENAME", /* 101 */ "CTIME_KW", /* 102 */ "ANY", /* 103 */ "BITAND", /* 104 */ "BITOR", /* 105 */ "LSHIFT", /* 106 */ "RSHIFT", /* 107 */ "PLUS", /* 108 */ "MINUS", /* 109 */ "STAR", /* 110 */ "SLASH", /* 111 */ "REM", /* 112 */ "CONCAT", /* 113 */ "PTR", /* 114 */ "COLLATE", /* 115 */ "BITNOT", /* 116 */ "ON", /* 117 */ "INDEXED", /* 118 */ "STRING", /* 119 */ "JOIN_KW", /* 120 */ "CONSTRAINT", /* 121 */ "DEFAULT", /* 122 */ "NULL", /* 123 */ "PRIMARY", /* 124 */ "UNIQUE", /* 125 */ "CHECK", /* 126 */ "REFERENCES", /* 127 */ "AUTOINCR", /* 128 */ "INSERT", /* 129 */ "DELETE", /* 130 */ "UPDATE", /* 131 */ "SET", /* 132 */ "DEFERRABLE", /* 133 */ "FOREIGN", /* 134 */ "DROP", /* 135 */ "UNION", /* 136 */ "ALL", /* 137 */ "EXCEPT", /* 138 */ "INTERSECT", /* 139 */ "SELECT", /* 140 */ "VALUES", /* 141 */ "DISTINCT", /* 142 */ "DOT", /* 143 */ "FROM", /* 144 */ "JOIN", /* 145 */ "USING", /* 146 */ "ORDER", /* 147 */ "GROUP", /* 148 */ "HAVING", /* 149 */ "LIMIT", /* 150 */ "WHERE", /* 151 */ "RETURNING", /* 152 */ "INTO", /* 153 */ "NOTHING", /* 154 */ "FLOAT", /* 155 */ "BLOB", /* 156 */ "INTEGER", /* 157 */ "VARIABLE", /* 158 */ "CASE", /* 159 */ "WHEN", /* 160 */ "THEN", /* 161 */ "ELSE", /* 162 */ "INDEX", /* 163 */ "ALTER", /* 164 */ "ADD", /* 165 */ "WINDOW", /* 166 */ "OVER", /* 167 */ "FILTER", /* 168 */ "COLUMN", /* 169 */ "AGG_FUNCTION", /* 170 */ "AGG_COLUMN", /* 171 */ "TRUEFALSE", /* 172 */ "FUNCTION", /* 173 */ "UPLUS", /* 174 */ "UMINUS", /* 175 */ "TRUTH", /* 176 */ "REGISTER", /* 177 */ "VECTOR", /* 178 */ "SELECT_COLUMN", |
︙ | ︙ | |||
174604 174605 174606 174607 174608 174609 174610 | /* 273 */ "tridxby ::= INDEXED BY nm", /* 274 */ "tridxby ::= NOT INDEXED", /* 275 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", /* 276 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", /* 277 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", /* 278 */ "trigger_cmd ::= scanpt select scanpt", /* 279 */ "expr ::= RAISE LP IGNORE RP", | | | 175835 175836 175837 175838 175839 175840 175841 175842 175843 175844 175845 175846 175847 175848 175849 | /* 273 */ "tridxby ::= INDEXED BY nm", /* 274 */ "tridxby ::= NOT INDEXED", /* 275 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", /* 276 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", /* 277 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", /* 278 */ "trigger_cmd ::= scanpt select scanpt", /* 279 */ "expr ::= RAISE LP IGNORE RP", /* 280 */ "expr ::= RAISE LP raisetype COMMA expr RP", /* 281 */ "raisetype ::= ROLLBACK", /* 282 */ "raisetype ::= ABORT", /* 283 */ "raisetype ::= FAIL", /* 284 */ "cmd ::= DROP TRIGGER ifexists fullname", /* 285 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", /* 286 */ "cmd ::= DETACH database_kw_opt expr", /* 287 */ "key_opt ::=", |
︙ | ︙ | |||
175529 175530 175531 175532 175533 175534 175535 | 295, /* (273) tridxby ::= INDEXED BY nm */ 295, /* (274) tridxby ::= NOT INDEXED */ 293, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ 293, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ 293, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ 293, /* (278) trigger_cmd ::= scanpt select scanpt */ 218, /* (279) expr ::= RAISE LP IGNORE RP */ | | | 176760 176761 176762 176763 176764 176765 176766 176767 176768 176769 176770 176771 176772 176773 176774 | 295, /* (273) tridxby ::= INDEXED BY nm */ 295, /* (274) tridxby ::= NOT INDEXED */ 293, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ 293, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ 293, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ 293, /* (278) trigger_cmd ::= scanpt select scanpt */ 218, /* (279) expr ::= RAISE LP IGNORE RP */ 218, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ 237, /* (281) raisetype ::= ROLLBACK */ 237, /* (282) raisetype ::= ABORT */ 237, /* (283) raisetype ::= FAIL */ 191, /* (284) cmd ::= DROP TRIGGER ifexists fullname */ 191, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ 191, /* (286) cmd ::= DETACH database_kw_opt expr */ 297, /* (287) key_opt ::= */ |
︙ | ︙ | |||
175943 175944 175945 175946 175947 175948 175949 | -3, /* (273) tridxby ::= INDEXED BY nm */ -2, /* (274) tridxby ::= NOT INDEXED */ -9, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ -8, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ -6, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -3, /* (278) trigger_cmd ::= scanpt select scanpt */ -4, /* (279) expr ::= RAISE LP IGNORE RP */ | | | 177174 177175 177176 177177 177178 177179 177180 177181 177182 177183 177184 177185 177186 177187 177188 | -3, /* (273) tridxby ::= INDEXED BY nm */ -2, /* (274) tridxby ::= NOT INDEXED */ -9, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ -8, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ -6, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -3, /* (278) trigger_cmd ::= scanpt select scanpt */ -4, /* (279) expr ::= RAISE LP IGNORE RP */ -6, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ -1, /* (281) raisetype ::= ROLLBACK */ -1, /* (282) raisetype ::= ABORT */ -1, /* (283) raisetype ::= FAIL */ -4, /* (284) cmd ::= DROP TRIGGER ifexists fullname */ -6, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ -3, /* (286) cmd ::= DETACH database_kw_opt expr */ 0, /* (287) key_opt ::= */ |
︙ | ︙ | |||
176581 176582 176583 176584 176585 176586 176587 176588 | if( yymsp[-5].minor.yy203==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy269.pOn==0 && yymsp[0].minor.yy269.pUsing==0 ){ yymsp[-5].minor.yy203 = yymsp[-3].minor.yy203; }else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){ yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); if( yymsp[-5].minor.yy203 ){ SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1]; SrcItem *pOld = yymsp[-3].minor.yy203->a; pNew->zName = pOld->zName; | > > | > | > > > | | > > > > | < | 177812 177813 177814 177815 177816 177817 177818 177819 177820 177821 177822 177823 177824 177825 177826 177827 177828 177829 177830 177831 177832 177833 177834 177835 177836 177837 177838 177839 177840 177841 177842 177843 177844 177845 177846 177847 177848 | if( yymsp[-5].minor.yy203==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy269.pOn==0 && yymsp[0].minor.yy269.pUsing==0 ){ yymsp[-5].minor.yy203 = yymsp[-3].minor.yy203; }else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){ yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); if( yymsp[-5].minor.yy203 ){ SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1]; SrcItem *pOld = yymsp[-3].minor.yy203->a; assert( pOld->fg.fixedSchema==0 ); pNew->zName = pOld->zName; assert( pOld->fg.fixedSchema==0 ); if( pOld->fg.isSubquery ){ pNew->fg.isSubquery = 1; pNew->u4.pSubq = pOld->u4.pSubq; pOld->u4.pSubq = 0; pOld->fg.isSubquery = 0; assert( pNew->u4.pSubq!=0 && pNew->u4.pSubq->pSelect!=0 ); if( (pNew->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 ){ pNew->fg.isNestedFrom = 1; } }else{ pNew->u4.zDatabase = pOld->u4.zDatabase; pOld->u4.zDatabase = 0; } if( pOld->fg.isTabFunc ){ pNew->u1.pFuncArg = pOld->u1.pFuncArg; pOld->u1.pFuncArg = 0; pOld->fg.isTabFunc = 0; pNew->fg.isTabFunc = 1; } pOld->zName = 0; } sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203); }else{ Select *pSubquery; sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203); pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy203,0,0,0,0,SF_NestedFrom,0); yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy269); |
︙ | ︙ | |||
177328 177329 177330 177331 177332 177333 177334 | { yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); if( yymsp[-3].minor.yy454 ){ yymsp[-3].minor.yy454->affExpr = OE_Ignore; } } break; | | | | 178568 178569 178570 178571 178572 178573 178574 178575 178576 178577 178578 178579 178580 178581 178582 178583 178584 | { yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); if( yymsp[-3].minor.yy454 ){ yymsp[-3].minor.yy454->affExpr = OE_Ignore; } } break; case 280: /* expr ::= RAISE LP raisetype COMMA expr RP */ { yymsp[-5].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy454, 0); if( yymsp[-5].minor.yy454 ) { yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144; } } break; case 281: /* raisetype ::= ROLLBACK */ {yymsp[0].minor.yy144 = OE_Rollback;} |
︙ | ︙ | |||
181688 181689 181690 181691 181692 181693 181694 | ){ return SQLITE_MISUSE_BKPT; } assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| | | > | 182928 182929 182930 182931 182932 182933 182934 182935 182936 182937 182938 182939 182940 182941 182942 182943 | ){ return SQLITE_MISUSE_BKPT; } assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| SQLITE_SUBTYPE|SQLITE_INNOCUOUS| SQLITE_RESULT_SUBTYPE|SQLITE_SELFORDER1); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But ** the meaning is inverted. So flip the bit. */ assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS ); extraFlags ^= SQLITE_FUNC_UNSAFE; /* tag-20230109-1 */ |
︙ | ︙ | |||
183243 183244 183245 183246 183247 183248 183249 183250 183251 183252 183253 183254 183255 183256 | assert( SQLITE_OPEN_CREATE == 0x04 ); testcase( (1<<(flags&7))==0x02 ); /* READONLY */ testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ if( ((1<<(flags&7)) & 0x46)==0 ){ rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */ }else{ 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; | > | 184484 184485 184486 184487 184488 184489 184490 184491 184492 184493 184494 184495 184496 184497 184498 | assert( SQLITE_OPEN_CREATE == 0x04 ); testcase( (1<<(flags&7))==0x02 ); /* READONLY */ testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ if( ((1<<(flags&7)) & 0x46)==0 ){ rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */ }else{ if( zFilename==0 ) zFilename = ":memory:"; 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; |
︙ | ︙ | |||
184154 184155 184156 184157 184158 184159 184160 184161 184162 184163 184164 184165 184166 184167 | ** is obtained in every case. */ case SQLITE_TESTCTRL_OPTIMIZATIONS: { sqlite3 *db = va_arg(ap, sqlite3*); db->dbOptFlags = va_arg(ap, u32); break; } /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt); ** ** If parameter onoff is 1, subsequent calls to localtime() fail. ** If 2, then invoke xAlt() instead of localtime(). If 0, normal ** processing. ** | > > > > > > > > > > > > | 185396 185397 185398 185399 185400 185401 185402 185403 185404 185405 185406 185407 185408 185409 185410 185411 185412 185413 185414 185415 185416 185417 185418 185419 185420 185421 | ** is obtained in every case. */ case SQLITE_TESTCTRL_OPTIMIZATIONS: { sqlite3 *db = va_arg(ap, sqlite3*); db->dbOptFlags = va_arg(ap, u32); break; } /* sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, sqlite3 *db, int *N) ** ** Write the current optimization settings into *N. A zero bit means that ** the optimization is on, and a 1 bit means that the optimization is off. */ case SQLITE_TESTCTRL_GETOPT: { sqlite3 *db = va_arg(ap, sqlite3*); int *pN = va_arg(ap, int*); *pN = db->dbOptFlags; break; } /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt); ** ** If parameter onoff is 1, subsequent calls to localtime() fail. ** If 2, then invoke xAlt() instead of localtime(). If 0, normal ** processing. ** |
︙ | ︙ | |||
195482 195483 195484 195485 195486 195487 195488 | sqlite3_free(zCopy); return rc; } #ifdef SQLITE_TEST | < < < | < | 196736 196737 196738 196739 196740 196741 196742 196743 196744 196745 196746 196747 196748 196749 196750 | sqlite3_free(zCopy); return rc; } #ifdef SQLITE_TEST #include "tclsqlite.h" /* #include <string.h> */ /* ** Implementation of a special SQL scalar function for testing tokenizers ** designed to be used in concert with the Tcl testing framework. This ** function must be called with two or more arguments: ** |
︙ | ︙ | |||
202713 202714 202715 202716 202717 202718 202719 202720 202721 202722 202723 202724 202725 202726 | iEnd = pPhrase->iHead; } } if( iEnd==0x7FFFFFFF ){ return 1; } pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; for(i=0; i<pIter->nPhrase; i++){ SnippetPhrase *pPhrase = &pIter->aPhrase[i]; fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, iEnd+1); fts3SnippetAdvance(&pPhrase->pTail, &pPhrase->iTail, iStart); } } | > | 203963 203964 203965 203966 203967 203968 203969 203970 203971 203972 203973 203974 203975 203976 203977 | iEnd = pPhrase->iHead; } } if( iEnd==0x7FFFFFFF ){ return 1; } assert( pIter->nSnippet>=0 ); pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; for(i=0; i<pIter->nPhrase; i++){ SnippetPhrase *pPhrase = &pIter->aPhrase[i]; fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, iEnd+1); fts3SnippetAdvance(&pPhrase->pTail, &pPhrase->iTail, iStart); } } |
︙ | ︙ | |||
207706 207707 207708 207709 207710 207711 207712 | } if( zPath[0]=='.' ){ int rawKey = 1; x = pParse->aBlob[iRoot]; zPath++; if( zPath[0]=='"' ){ zKey = zPath + 1; | | > > | 208957 208958 208959 208960 208961 208962 208963 208964 208965 208966 208967 208968 208969 208970 208971 208972 208973 | } if( zPath[0]=='.' ){ int rawKey = 1; x = pParse->aBlob[iRoot]; zPath++; if( zPath[0]=='"' ){ zKey = zPath + 1; for(i=1; zPath[i] && zPath[i]!='"'; i++){ if( zPath[i]=='\\' && zPath[i+1]!=0 ) i++; } nKey = i-1; if( zPath[i] ){ i++; }else{ return JSON_LOOKUP_PATHERROR; } testcase( nKey==0 ); |
︙ | ︙ | |||
208716 208717 208718 208719 208720 208721 208722 208723 208724 208725 208726 208727 208728 208729 208730 208731 208732 208733 | /* The -> and ->> operators accept abbreviated PATH arguments. This ** is mostly for compatibility with PostgreSQL, but also for ** convenience. ** ** NUMBER ==> $[NUMBER] // PG compatible ** LABEL ==> $.LABEL // PG compatible ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience */ jsonStringInit(&jx, ctx); if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){ jsonAppendRawNZ(&jx, "[", 1); jsonAppendRaw(&jx, zPath, nPath); jsonAppendRawNZ(&jx, "]", 2); }else if( jsonAllAlphanum(zPath, nPath) ){ jsonAppendRawNZ(&jx, ".", 1); jsonAppendRaw(&jx, zPath, nPath); }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){ jsonAppendRaw(&jx, zPath, nPath); | > > > > > > | 209969 209970 209971 209972 209973 209974 209975 209976 209977 209978 209979 209980 209981 209982 209983 209984 209985 209986 209987 209988 209989 209990 209991 209992 | /* The -> and ->> operators accept abbreviated PATH arguments. This ** is mostly for compatibility with PostgreSQL, but also for ** convenience. ** ** NUMBER ==> $[NUMBER] // PG compatible ** LABEL ==> $.LABEL // PG compatible ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience ** ** Updated 2024-05-27: If the NUMBER is negative, then PG counts from ** the right of the array. Hence for negative NUMBER: ** ** NUMBER ==> $[#NUMBER] // PG compatible */ jsonStringInit(&jx, ctx); if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){ jsonAppendRawNZ(&jx, "[", 1); if( zPath[0]=='-' ) jsonAppendRawNZ(&jx,"#",1); jsonAppendRaw(&jx, zPath, nPath); jsonAppendRawNZ(&jx, "]", 2); }else if( jsonAllAlphanum(zPath, nPath) ){ jsonAppendRawNZ(&jx, ".", 1); jsonAppendRaw(&jx, zPath, nPath); }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){ jsonAppendRaw(&jx, zPath, nPath); |
︙ | ︙ | |||
218461 218462 218463 218464 218465 218466 218467 218468 218469 218470 218471 218472 218473 218474 | ** file should be copied to page iDbPage of the database file. */ struct RbuFrame { u32 iDbPage; u32 iWalFrame; }; /* ** RBU handle. ** ** nPhaseOneStep: ** If the RBU database contains an rbu_count table, this value is set to ** a running estimate of the number of b-tree operations required to ** finish populating the *-oal file. This allows the sqlite3_bp_progress() | > > > > > > > > > > > > > > > > > > > > > | 219720 219721 219722 219723 219724 219725 219726 219727 219728 219729 219730 219731 219732 219733 219734 219735 219736 219737 219738 219739 219740 219741 219742 219743 219744 219745 219746 219747 219748 219749 219750 219751 219752 219753 219754 | ** file should be copied to page iDbPage of the database file. */ struct RbuFrame { u32 iDbPage; u32 iWalFrame; }; #ifndef UNUSED_PARAMETER /* ** The following macros are used to suppress compiler warnings and to ** make it clear to human readers when a function parameter is deliberately ** left unused within the body of a function. This usually happens when ** a function is called via a function pointer. For example the ** implementation of an SQL aggregate step callback may not use the ** parameter indicating the number of arguments passed to the aggregate, ** if it knows that this is enforced elsewhere. ** ** When a function parameter is not used at all within the body of a function, ** it is generally named "NotUsed" or "NotUsed2" to make things even clearer. ** However, these macros may also be used to suppress warnings related to ** parameters that may or may not be used depending on compilation options. ** For example those parameters only used in assert() statements. In these ** cases the parameters are named as per the usual conventions. */ #define UNUSED_PARAMETER(x) (void)(x) #define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y) #endif /* ** RBU handle. ** ** nPhaseOneStep: ** If the RBU database contains an rbu_count table, this value is set to ** a running estimate of the number of b-tree operations required to ** finish populating the *-oal file. This allows the sqlite3_bp_progress() |
︙ | ︙ | |||
218512 218513 218514 218515 218516 218517 218518 | char *zTarget; /* Path to target db */ char *zRbu; /* Path to rbu db */ char *zState; /* Path to state db (or NULL if zRbu) */ char zStateDb[5]; /* Db name for state ("stat" or "main") */ int rc; /* Value returned by last rbu_step() call */ char *zErrmsg; /* Error message if rc!=SQLITE_OK */ int nStep; /* Rows processed for current object */ | | | 219792 219793 219794 219795 219796 219797 219798 219799 219800 219801 219802 219803 219804 219805 219806 | char *zTarget; /* Path to target db */ char *zRbu; /* Path to rbu db */ char *zState; /* Path to state db (or NULL if zRbu) */ char zStateDb[5]; /* Db name for state ("stat" or "main") */ int rc; /* Value returned by last rbu_step() call */ char *zErrmsg; /* Error message if rc!=SQLITE_OK */ int nStep; /* Rows processed for current object */ sqlite3_int64 nProgress; /* Rows processed for all objects */ RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ const char *zVfsName; /* Name of automatically created rbu vfs */ rbu_file *pTargetFd; /* File handle open on target db */ int nPagePerSector; /* Pages per sector for pTargetFd */ i64 iOalSz; i64 nPhaseOneStep; void *pRenameArg; |
︙ | ︙ | |||
218629 218630 218631 218632 218633 218634 218635 | int c; unsigned char *z = (unsigned char*)*pz; unsigned char *zStart = z; while( (c = zValue[0x7f&*(z++)])>=0 ){ v = (v<<6) + c; } z--; | | | 219909 219910 219911 219912 219913 219914 219915 219916 219917 219918 219919 219920 219921 219922 219923 | int c; unsigned char *z = (unsigned char*)*pz; unsigned char *zStart = z; while( (c = zValue[0x7f&*(z++)])>=0 ){ v = (v<<6) + c; } z--; *pLen -= (int)(z - zStart); *pz = (char*)z; return v; } #if RBU_ENABLE_DELTA_CKSUM /* ** Compute a 32-bit checksum on the N-byte buffer. Return the result. |
︙ | ︙ | |||
218814 218815 218816 218817 218818 218819 218820 218821 218822 218823 218824 218825 218826 218827 | int nOrig; int nOut; int nOut2; char *aOut; assert( argc==2 ); nOrig = sqlite3_value_bytes(argv[0]); aOrig = (const char*)sqlite3_value_blob(argv[0]); nDelta = sqlite3_value_bytes(argv[1]); aDelta = (const char*)sqlite3_value_blob(argv[1]); /* Figure out the size of the output */ | > | 220094 220095 220096 220097 220098 220099 220100 220101 220102 220103 220104 220105 220106 220107 220108 | int nOrig; int nOut; int nOut2; char *aOut; assert( argc==2 ); UNUSED_PARAMETER(argc); nOrig = sqlite3_value_bytes(argv[0]); aOrig = (const char*)sqlite3_value_blob(argv[0]); nDelta = sqlite3_value_bytes(argv[1]); aDelta = (const char*)sqlite3_value_blob(argv[1]); /* Figure out the size of the output */ |
︙ | ︙ | |||
220393 220394 220395 220396 220397 220398 220399 | pIter->aIdxCol[0].zSpan = &zSql[i+1]; } nParen++; } else if( c==')' ){ nParen--; if( nParen==0 ){ | | | | 221674 221675 221676 221677 221678 221679 221680 221681 221682 221683 221684 221685 221686 221687 221688 221689 221690 221691 221692 221693 221694 | pIter->aIdxCol[0].zSpan = &zSql[i+1]; } nParen++; } else if( c==')' ){ nParen--; if( nParen==0 ){ int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan); pIter->aIdxCol[iIdxCol++].nSpan = nSpan; i++; break; } }else if( c==',' && nParen==1 ){ int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan); pIter->aIdxCol[iIdxCol++].nSpan = nSpan; pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1]; }else if( c=='"' || c=='\'' || c=='`' ){ for(i++; 1; i++){ if( zSql[i]==c ){ if( zSql[i+1]!=c ) break; i++; |
︙ | ︙ | |||
221089 221090 221091 221092 221093 221094 221095 221096 221097 221098 221099 221100 221101 221102 | #endif { int i, sz; sz = (int)strlen(z)&0xffffff; for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4); } #endif } /* ** Return the current wal-index header checksum for the target database ** as a 64-bit integer. ** | > > | 222370 222371 222372 222373 222374 222375 222376 222377 222378 222379 222380 222381 222382 222383 222384 222385 | #endif { int i, sz; sz = (int)strlen(z)&0xffffff; for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4); } #else UNUSED_PARAMETER2(zBase,z); #endif } /* ** Return the current wal-index header checksum for the target database ** as a 64-bit integer. ** |
︙ | ︙ | |||
221673 221674 221675 221676 221677 221678 221679 | rc = prepareFreeAndCollectError(p->dbRbu, &pInsert, &p->zErrmsg, sqlite3_mprintf( "INSERT OR REPLACE INTO %s.rbu_state(k, v) VALUES " "(%d, %d), " "(%d, %Q), " "(%d, %Q), " "(%d, %d), " | | | 222956 222957 222958 222959 222960 222961 222962 222963 222964 222965 222966 222967 222968 222969 222970 | rc = prepareFreeAndCollectError(p->dbRbu, &pInsert, &p->zErrmsg, sqlite3_mprintf( "INSERT OR REPLACE INTO %s.rbu_state(k, v) VALUES " "(%d, %d), " "(%d, %Q), " "(%d, %Q), " "(%d, %d), " "(%d, %lld), " "(%d, %lld), " "(%d, %lld), " "(%d, %lld), " "(%d, %lld), " "(%d, %Q) ", p->zStateDb, RBU_STATE_STAGE, eStage, |
︙ | ︙ | |||
222031 222032 222033 222034 222035 222036 222037 222038 222039 222040 222041 222042 222043 222044 | sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx); sqlite3_stmt *pStmt = 0; char *zErrmsg = 0; int rc; sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); assert( nVal==1 ); rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg, sqlite3_mprintf("SELECT count(*) FROM sqlite_schema " "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0])) ); if( rc!=SQLITE_OK ){ sqlite3_result_error(pCtx, zErrmsg, -1); | > | 223314 223315 223316 223317 223318 223319 223320 223321 223322 223323 223324 223325 223326 223327 223328 | sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx); sqlite3_stmt *pStmt = 0; char *zErrmsg = 0; int rc; sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); assert( nVal==1 ); UNUSED_PARAMETER(nVal); rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg, sqlite3_mprintf("SELECT count(*) FROM sqlite_schema " "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0])) ); if( rc!=SQLITE_OK ){ sqlite3_result_error(pCtx, zErrmsg, -1); |
︙ | ︙ | |||
222306 222307 222308 222309 222310 222311 222312 | */ SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( const char *zTarget, const char *zState ){ if( zTarget==0 ){ return rbuMisuseError(); } if( zState ){ | | | 223590 223591 223592 223593 223594 223595 223596 223597 223598 223599 223600 223601 223602 223603 223604 | */ SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( const char *zTarget, const char *zState ){ if( zTarget==0 ){ return rbuMisuseError(); } if( zState ){ size_t n = strlen(zState); if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){ return rbuMisuseError(); } } /* TODO: Check that both arguments are non-NULL */ return openRbuHandle(0, zTarget, zState); } |
︙ | ︙ | |||
222523 222524 222525 222526 222527 222528 222529 222530 222531 222532 222533 222534 222535 222536 | } /* ** Default xRename callback for RBU. */ static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){ int rc = SQLITE_OK; #if defined(_WIN32_WCE) { LPWSTR zWideOld; LPWSTR zWideNew; zWideOld = rbuWinUtf8ToUnicode(zOld); if( zWideOld ){ | > | 223807 223808 223809 223810 223811 223812 223813 223814 223815 223816 223817 223818 223819 223820 223821 | } /* ** Default xRename callback for RBU. */ static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){ int rc = SQLITE_OK; UNUSED_PARAMETER(pArg); #if defined(_WIN32_WCE) { LPWSTR zWideOld; LPWSTR zWideNew; zWideOld = rbuWinUtf8ToUnicode(zOld); if( zWideOld ){ |
︙ | ︙ | |||
223427 223428 223429 223430 223431 223432 223433 223434 223435 223436 223437 223438 223439 223440 | return pRealVfs->xCurrentTime(pRealVfs, pTimeOut); } /* ** No-op. */ static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){ return 0; } /* ** Deregister and destroy an RBU vfs created by an earlier call to ** sqlite3rbu_create_vfs(). */ | > > > | 224712 224713 224714 224715 224716 224717 224718 224719 224720 224721 224722 224723 224724 224725 224726 224727 224728 | return pRealVfs->xCurrentTime(pRealVfs, pTimeOut); } /* ** No-op. */ static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){ UNUSED_PARAMETER(pVfs); UNUSED_PARAMETER(a); UNUSED_PARAMETER(b); return 0; } /* ** Deregister and destroy an RBU vfs created by an earlier call to ** sqlite3rbu_create_vfs(). */ |
︙ | ︙ | |||
223825 223826 223827 223828 223829 223830 223831 223832 223833 223834 223835 223836 223837 223838 | && pIdxInfo->aOrderBy[1].iColumn==1 && pIdxInfo->aOrderBy[1].desc==0 ) ){ pIdxInfo->orderByConsumed = 1; pIdxInfo->idxNum |= 0x08; } return SQLITE_OK; } /* ** Open a new DBSTAT cursor. */ | > | 225113 225114 225115 225116 225117 225118 225119 225120 225121 225122 225123 225124 225125 225126 225127 | && pIdxInfo->aOrderBy[1].iColumn==1 && pIdxInfo->aOrderBy[1].desc==0 ) ){ pIdxInfo->orderByConsumed = 1; pIdxInfo->idxNum |= 0x08; } pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_HEX; return SQLITE_OK; } /* ** Open a new DBSTAT cursor. */ |
︙ | ︙ | |||
224482 224483 224484 224485 224486 224487 224488 | ** This is an eponymous virtual table so it does not need to be created before ** use. The optional argument to the sqlite_dbpage() table name is the ** schema for the database file that is to be read. The default schema is ** "main". ** ** The data field of sqlite_dbpage table can be updated. The new ** value must be a BLOB which is the correct page size, otherwise the | > > > > | > > | 225771 225772 225773 225774 225775 225776 225777 225778 225779 225780 225781 225782 225783 225784 225785 225786 225787 225788 225789 225790 225791 | ** This is an eponymous virtual table so it does not need to be created before ** use. The optional argument to the sqlite_dbpage() table name is the ** schema for the database file that is to be read. The default schema is ** "main". ** ** The data field of sqlite_dbpage table can be updated. The new ** value must be a BLOB which is the correct page size, otherwise the ** update fails. INSERT operations also work, and operate as if they ** where REPLACE. The size of the database can be extended by INSERT-ing ** new pages on the end. ** ** Rows may not be deleted. However, doing an INSERT to page number N ** with NULL page data causes the N-th page and all subsequent pages to be ** deleted and the database to be truncated. */ /* #include "sqliteInt.h" ** Requires access to internal data structures ** */ #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ && !defined(SQLITE_OMIT_VIRTUALTABLE) typedef struct DbpageTable DbpageTable; |
︙ | ︙ | |||
224505 224506 224507 224508 224509 224510 224511 224512 224513 224514 224515 224516 224517 | int iDb; /* Index of database to analyze */ int szPage; /* Size of each page in bytes */ }; struct DbpageTable { sqlite3_vtab base; /* Base class. Must be first */ sqlite3 *db; /* The database */ }; /* Columns */ #define DBPAGE_COLUMN_PGNO 0 #define DBPAGE_COLUMN_DATA 1 #define DBPAGE_COLUMN_SCHEMA 2 | > > < | 225800 225801 225802 225803 225804 225805 225806 225807 225808 225809 225810 225811 225812 225813 225814 225815 225816 225817 225818 225819 225820 225821 | int iDb; /* Index of database to analyze */ int szPage; /* Size of each page in bytes */ }; struct DbpageTable { sqlite3_vtab base; /* Base class. Must be first */ sqlite3 *db; /* The database */ int nTrunc; /* Entries in aTrunc[] */ Pgno *aTrunc; /* Truncation size for each database */ }; /* Columns */ #define DBPAGE_COLUMN_PGNO 0 #define DBPAGE_COLUMN_DATA 1 #define DBPAGE_COLUMN_SCHEMA 2 /* ** Connect to or create a dbpagevfs virtual table. */ static int dbpageConnect( sqlite3 *db, |
︙ | ︙ | |||
224554 224555 224556 224557 224558 224559 224560 224561 224562 224563 224564 224565 224566 224567 | return rc; } /* ** Disconnect from or destroy a dbpagevfs virtual table. */ static int dbpageDisconnect(sqlite3_vtab *pVtab){ sqlite3_free(pVtab); return SQLITE_OK; } /* ** idxNum: ** | > > | 225850 225851 225852 225853 225854 225855 225856 225857 225858 225859 225860 225861 225862 225863 225864 225865 | return rc; } /* ** Disconnect from or destroy a dbpagevfs virtual table. */ static int dbpageDisconnect(sqlite3_vtab *pVtab){ DbpageTable *pTab = (DbpageTable *)pVtab; sqlite3_free(pTab->aTrunc); sqlite3_free(pVtab); return SQLITE_OK; } /* ** idxNum: ** |
︙ | ︙ | |||
224775 224776 224777 224778 224779 224780 224781 | sqlite_int64 *pRowid ){ DbpageTable *pTab = (DbpageTable *)pVtab; Pgno pgno; DbPage *pDbPage = 0; int rc = SQLITE_OK; char *zErr = 0; | < > > > > > | < | < | | | > > > > > | | | | | | > | > > > > > > > > > > > > > > | | > < < | < | > | 226073 226074 226075 226076 226077 226078 226079 226080 226081 226082 226083 226084 226085 226086 226087 226088 226089 226090 226091 226092 226093 226094 226095 226096 226097 226098 226099 226100 226101 226102 226103 226104 226105 226106 226107 226108 226109 226110 226111 226112 226113 226114 226115 226116 226117 226118 226119 226120 226121 226122 226123 226124 226125 226126 226127 226128 226129 226130 226131 226132 226133 226134 226135 226136 226137 226138 226139 226140 226141 226142 226143 226144 226145 226146 226147 226148 226149 226150 226151 226152 226153 226154 226155 226156 | sqlite_int64 *pRowid ){ DbpageTable *pTab = (DbpageTable *)pVtab; Pgno pgno; DbPage *pDbPage = 0; int rc = SQLITE_OK; char *zErr = 0; int iDb; Btree *pBt; Pager *pPager; int szPage; int isInsert; (void)pRowid; if( pTab->db->flags & SQLITE_Defensive ){ zErr = "read-only"; goto update_fail; } if( argc==1 ){ zErr = "cannot delete"; goto update_fail; } if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ pgno = (Pgno)sqlite3_value_int(argv[2]); isInsert = 1; }else{ pgno = sqlite3_value_int(argv[0]); if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ zErr = "cannot insert"; goto update_fail; } isInsert = 0; } if( sqlite3_value_type(argv[4])==SQLITE_NULL ){ iDb = 0; }else{ const char *zSchema = (const char*)sqlite3_value_text(argv[4]); iDb = sqlite3FindDbName(pTab->db, zSchema); if( iDb<0 ){ zErr = "no such schema"; goto update_fail; } } pBt = pTab->db->aDb[iDb].pBt; if( pgno<1 || NEVER(pBt==0) ){ zErr = "bad page number"; goto update_fail; } szPage = sqlite3BtreeGetPageSize(pBt); if( sqlite3_value_type(argv[3])!=SQLITE_BLOB || sqlite3_value_bytes(argv[3])!=szPage ){ if( sqlite3_value_type(argv[3])==SQLITE_NULL && isInsert ){ if( iDb>=pTab->nTrunc ){ testcase( pTab->aTrunc!=0 ); pTab->aTrunc = sqlite3_realloc(pTab->aTrunc, (iDb+1)*sizeof(Pgno)); if( pTab->aTrunc ){ int j; for(j=pTab->nTrunc; j<iDb; j++) pTab->aTrunc[j] = 0; pTab->nTrunc = iDb+1; }else{ return SQLITE_NOMEM; } } pTab->aTrunc[iDb] = pgno; }else{ zErr = "bad page value"; goto update_fail; } } pPager = sqlite3BtreePager(pBt); rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); if( rc==SQLITE_OK ){ const void *pData = sqlite3_value_blob(argv[3]); if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){ unsigned char *aPage = sqlite3PagerGetData(pDbPage); memcpy(aPage, pData, szPage); } } sqlite3PagerUnref(pDbPage); return rc; update_fail: sqlite3_free(pVtab->zErrMsg); |
︙ | ︙ | |||
224846 224847 224848 224849 224850 224851 224852 224853 224854 224855 224856 224857 224858 224859 | static int dbpageBegin(sqlite3_vtab *pVtab){ DbpageTable *pTab = (DbpageTable *)pVtab; sqlite3 *db = pTab->db; int i; for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0); } return SQLITE_OK; } /* ** Invoke this routine to register the "dbpage" virtual table module | > > > > > > > > > > > > > > > > > > > > | 226165 226166 226167 226168 226169 226170 226171 226172 226173 226174 226175 226176 226177 226178 226179 226180 226181 226182 226183 226184 226185 226186 226187 226188 226189 226190 226191 226192 226193 226194 226195 226196 226197 226198 | static int dbpageBegin(sqlite3_vtab *pVtab){ DbpageTable *pTab = (DbpageTable *)pVtab; sqlite3 *db = pTab->db; int i; for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0); } if( pTab->nTrunc>0 ){ memset(pTab->aTrunc, 0, sizeof(pTab->aTrunc[0])*pTab->nTrunc); } return SQLITE_OK; } /* Invoke sqlite3PagerTruncate() as necessary, just prior to COMMIT */ static int dbpageSync(sqlite3_vtab *pVtab){ int iDb; DbpageTable *pTab = (DbpageTable *)pVtab; for(iDb=0; iDb<pTab->nTrunc; iDb++){ if( pTab->aTrunc[iDb]>0 ){ Btree *pBt = pTab->db->aDb[iDb].pBt; Pager *pPager = sqlite3BtreePager(pBt); sqlite3PagerTruncateImage(pPager, pTab->aTrunc[iDb]); pTab->aTrunc[iDb] = 0; } } return SQLITE_OK; } /* ** Invoke this routine to register the "dbpage" virtual table module |
︙ | ︙ | |||
224871 224872 224873 224874 224875 224876 224877 | dbpageFilter, /* xFilter - configure scan constraints */ dbpageNext, /* xNext - advance a cursor */ dbpageEof, /* xEof - check for end of scan */ dbpageColumn, /* xColumn - read data */ dbpageRowid, /* xRowid - read data */ dbpageUpdate, /* xUpdate */ dbpageBegin, /* xBegin */ | | | 226210 226211 226212 226213 226214 226215 226216 226217 226218 226219 226220 226221 226222 226223 226224 | dbpageFilter, /* xFilter - configure scan constraints */ dbpageNext, /* xNext - advance a cursor */ dbpageEof, /* xEof - check for end of scan */ dbpageColumn, /* xColumn - read data */ dbpageRowid, /* xRowid - read data */ dbpageUpdate, /* xUpdate */ dbpageBegin, /* xBegin */ dbpageSync, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ |
︙ | ︙ | |||
224966 224967 224968 224969 224970 224971 224972 224973 224974 224975 224976 224977 224978 224979 | }; /* ** An object of this type is used internally as an abstraction for ** input data. Input data may be supplied either as a single large buffer ** (e.g. sqlite3changeset_start()) or using a stream function (e.g. ** sqlite3changeset_start_strm()). */ struct SessionInput { int bNoDiscard; /* If true, do not discard in InputBuffer() */ int iCurrent; /* Offset in aData[] of current change */ int iNext; /* Offset in aData[] of next change */ u8 *aData; /* Pointer to buffer containing changeset */ int nData; /* Number of bytes in aData */ | > > > > | 226305 226306 226307 226308 226309 226310 226311 226312 226313 226314 226315 226316 226317 226318 226319 226320 226321 226322 | }; /* ** An object of this type is used internally as an abstraction for ** input data. Input data may be supplied either as a single large buffer ** (e.g. sqlite3changeset_start()) or using a stream function (e.g. ** sqlite3changeset_start_strm()). ** ** bNoDiscard: ** If true, then the only time data is discarded is as a result of explicit ** sessionDiscardData() calls. Not within every sessionInputBuffer() call. */ struct SessionInput { int bNoDiscard; /* If true, do not discard in InputBuffer() */ int iCurrent; /* Offset in aData[] of current change */ int iNext; /* Offset in aData[] of next change */ u8 *aData; /* Pointer to buffer containing changeset */ int nData; /* Number of bytes in aData */ |
︙ | ︙ | |||
226649 226650 226651 226652 226653 226654 226655 | pTab->nEntry++; /* Figure out how large an allocation is required */ nByte = sizeof(SessionChange); for(i=0; i<(pTab->nCol-pTab->bRowid); i++){ sqlite3_value *p = 0; if( op!=SQLITE_INSERT ){ | > > | < > | | | > | 227992 227993 227994 227995 227996 227997 227998 227999 228000 228001 228002 228003 228004 228005 228006 228007 228008 228009 228010 228011 228012 228013 228014 228015 228016 228017 228018 | pTab->nEntry++; /* Figure out how large an allocation is required */ nByte = sizeof(SessionChange); for(i=0; i<(pTab->nCol-pTab->bRowid); i++){ sqlite3_value *p = 0; if( op!=SQLITE_INSERT ){ /* This may fail if the column has a non-NULL default and was added ** using ALTER TABLE ADD COLUMN after this record was created. */ rc = pSession->hook.xOld(pSession->hook.pCtx, i, &p); }else if( pTab->abPK[i] ){ TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p); assert( trc==SQLITE_OK ); } if( rc==SQLITE_OK ){ /* This may fail if SQLite value p contains a utf-16 string that must ** be converted to utf-8 and an OOM error occurs while doing so. */ rc = sessionSerializeValue(0, p, &nByte); } if( rc!=SQLITE_OK ) goto error_out; } if( pTab->bRowid ){ nByte += 9; /* Size of rowid field - an integer */ } /* Allocate the change object */ |
︙ | ︙ | |||
230016 230017 230018 230019 230020 230021 230022 230023 230024 230025 230026 230027 230028 230029 230030 | ){ int schemaMismatch = 0; int rc = SQLITE_OK; /* Return code */ const char *zTab = 0; /* Name of current table */ int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ SessionApplyCtx sApply; /* changeset_apply() context object */ int bPatchset; assert( xConflict!=0 ); pIter->in.bNoDiscard = 1; memset(&sApply, 0, sizeof(sApply)); sApply.bRebase = (ppRebase && pnRebase); sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP); | > > > > > > > < | 231362 231363 231364 231365 231366 231367 231368 231369 231370 231371 231372 231373 231374 231375 231376 231377 231378 231379 231380 231381 231382 231383 231384 231385 231386 231387 231388 231389 231390 | ){ int schemaMismatch = 0; int rc = SQLITE_OK; /* Return code */ const char *zTab = 0; /* Name of current table */ int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ SessionApplyCtx sApply; /* changeset_apply() context object */ int bPatchset; u64 savedFlag = db->flags & SQLITE_FkNoAction; assert( xConflict!=0 ); sqlite3_mutex_enter(sqlite3_db_mutex(db)); if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ db->flags |= ((u64)SQLITE_FkNoAction); db->aDb[0].pSchema->schema_cookie -= 32; } pIter->in.bNoDiscard = 1; memset(&sApply, 0, sizeof(sApply)); sApply.bRebase = (ppRebase && pnRebase); sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); } if( rc==SQLITE_OK ){ rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0); } while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){ |
︙ | ︙ | |||
230186 230187 230188 230189 230190 230191 230192 230193 230194 230195 230196 230197 230198 230199 | sessionUpdateFree(&sApply); sqlite3_finalize(sApply.pInsert); sqlite3_finalize(sApply.pDelete); sqlite3_finalize(sApply.pSelect); sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_free((char*)sApply.constraints.aBuf); sqlite3_free((char*)sApply.rebase.aBuf); sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } /* ** Apply the changeset passed via pChangeset/nChangeset to the main ** database attached to handle "db". | > > > > > > | 231538 231539 231540 231541 231542 231543 231544 231545 231546 231547 231548 231549 231550 231551 231552 231553 231554 231555 231556 231557 | sessionUpdateFree(&sApply); sqlite3_finalize(sApply.pInsert); sqlite3_finalize(sApply.pDelete); sqlite3_finalize(sApply.pSelect); sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_free((char*)sApply.constraints.aBuf); sqlite3_free((char*)sApply.rebase.aBuf); if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){ assert( db->flags & SQLITE_FkNoAction ); db->flags &= ~((u64)SQLITE_FkNoAction); db->aDb[0].pSchema->schema_cookie -= 32; } sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } /* ** Apply the changeset passed via pChangeset/nChangeset to the main ** database attached to handle "db". |
︙ | ︙ | |||
230214 230215 230216 230217 230218 230219 230220 | void *pCtx, /* First argument passed to xConflict */ void **ppRebase, int *pnRebase, int flags ){ sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1); | < < < < < < < < < < < | 231572 231573 231574 231575 231576 231577 231578 231579 231580 231581 231582 231583 231584 231585 231586 231587 231588 231589 231590 231591 231592 | void *pCtx, /* First argument passed to xConflict */ void **ppRebase, int *pnRebase, int flags ){ sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1); if( rc==SQLITE_OK ){ rc = sessionChangesetApply( db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags ); } return rc; } /* ** Apply the changeset passed via pChangeset/nChangeset to the main database ** attached to handle "db". Invoke the supplied conflict handler callback ** to resolve any conflicts encountered while applying the change. |
︙ | ︙ | |||
230552 230553 230554 230555 230556 230557 230558 230559 230560 230561 230562 230563 230564 230565 230566 230567 230568 230569 230570 230571 230572 230573 230574 230575 230576 230577 230578 230579 230580 230581 | pOut->nBuf = 0; if( op==SQLITE_INSERT || (op==SQLITE_DELETE && pGrp->bPatch==0) ){ /* Append the missing default column values to the record. */ sessionAppendBlob(pOut, aRec, nRec, &rc); if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){ rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt); } for(ii=nCol; rc==SQLITE_OK && ii<pTab->nCol; ii++){ int eType = sqlite3_column_type(pTab->pDfltStmt, ii); sessionAppendByte(pOut, eType, &rc); switch( eType ){ case SQLITE_FLOAT: case SQLITE_INTEGER: { i64 iVal; if( eType==SQLITE_INTEGER ){ iVal = sqlite3_column_int64(pTab->pDfltStmt, ii); }else{ double rVal = sqlite3_column_int64(pTab->pDfltStmt, ii); memcpy(&iVal, &rVal, sizeof(i64)); } if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){ sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); } break; } case SQLITE_BLOB: case SQLITE_TEXT: { int n = sqlite3_column_bytes(pTab->pDfltStmt, ii); | > > > > | 231899 231900 231901 231902 231903 231904 231905 231906 231907 231908 231909 231910 231911 231912 231913 231914 231915 231916 231917 231918 231919 231920 231921 231922 231923 231924 231925 231926 231927 231928 231929 231930 231931 231932 | pOut->nBuf = 0; if( op==SQLITE_INSERT || (op==SQLITE_DELETE && pGrp->bPatch==0) ){ /* Append the missing default column values to the record. */ sessionAppendBlob(pOut, aRec, nRec, &rc); if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){ rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt); if( rc==SQLITE_OK && SQLITE_ROW!=sqlite3_step(pTab->pDfltStmt) ){ rc = sqlite3_errcode(pGrp->db); } } for(ii=nCol; rc==SQLITE_OK && ii<pTab->nCol; ii++){ int eType = sqlite3_column_type(pTab->pDfltStmt, ii); sessionAppendByte(pOut, eType, &rc); switch( eType ){ case SQLITE_FLOAT: case SQLITE_INTEGER: { i64 iVal; if( eType==SQLITE_INTEGER ){ iVal = sqlite3_column_int64(pTab->pDfltStmt, ii); }else{ double rVal = sqlite3_column_int64(pTab->pDfltStmt, ii); memcpy(&iVal, &rVal, sizeof(i64)); } if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){ sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); pOut->nBuf += 8; } break; } case SQLITE_BLOB: case SQLITE_TEXT: { int n = sqlite3_column_bytes(pTab->pDfltStmt, ii); |
︙ | ︙ | |||
230706 230707 230708 230709 230710 230711 230712 230713 230714 230715 230716 230717 230718 230719 | int bIndirect = 0; SessionChange *pChange = 0; SessionChange *pExist = 0; SessionChange **pp = 0; SessionTable *pTab = 0; u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2]; int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2; /* Ensure that only changesets, or only patchsets, but not a mixture ** of both, are being combined. It is an error to try to combine a ** changeset and a patchset. */ if( pGrp->pList==0 ){ pGrp->bPatch = pIter->bPatchset; }else if( pIter->bPatchset!=pGrp->bPatch ){ | > > | 232057 232058 232059 232060 232061 232062 232063 232064 232065 232066 232067 232068 232069 232070 232071 232072 | int bIndirect = 0; SessionChange *pChange = 0; SessionChange *pExist = 0; SessionChange **pp = 0; SessionTable *pTab = 0; u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2]; int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2; assert( nRec>0 ); /* Ensure that only changesets, or only patchsets, but not a mixture ** of both, are being combined. It is an error to try to combine a ** changeset and a patchset. */ if( pGrp->pList==0 ){ pGrp->bPatch = pIter->bPatchset; }else if( pIter->bPatchset!=pGrp->bPatch ){ |
︙ | ︙ | |||
230784 230785 230786 230787 230788 230789 230790 230791 230792 230793 230794 230795 230796 230797 | sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */ int bRebase /* True if hash table is for rebasing */ ){ u8 *aRec; int nRec; int rc = SQLITE_OK; while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){ rc = sessionOneChangeToHash(pGrp, pIter, bRebase); if( rc!=SQLITE_OK ) break; } if( rc==SQLITE_OK ) rc = pIter->rc; return rc; | > | 232137 232138 232139 232140 232141 232142 232143 232144 232145 232146 232147 232148 232149 232150 232151 | sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */ int bRebase /* True if hash table is for rebasing */ ){ u8 *aRec; int nRec; int rc = SQLITE_OK; pIter->in.bNoDiscard = 1; while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){ rc = sessionOneChangeToHash(pGrp, pIter, bRebase); if( rc!=SQLITE_OK ) break; } if( rc==SQLITE_OK ) rc = pIter->rc; return rc; |
︙ | ︙ | |||
231665 231666 231667 231668 231669 231670 231671 231672 231673 231674 231675 231676 231677 231678 | ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. If the FTS5 table is created ** with either "detail=none" or "detail=column" and "content=" option ** (i.e. if it is a contentless table), then this API always iterates ** through an empty set (all calls to xPhraseFirst() set iCol to -1). ** ** xPhraseNext() ** See xPhraseFirst above. ** ** xPhraseFirstColumn() ** This function and xPhraseNextColumn() are similar to the xPhraseFirst() ** and xPhraseNext() APIs described above. The difference is that instead ** of iterating through all instances of a phrase in the current row, these | > > > > | 233019 233020 233021 233022 233023 233024 233025 233026 233027 233028 233029 233030 233031 233032 233033 233034 233035 233036 | ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. If the FTS5 table is created ** with either "detail=none" or "detail=column" and "content=" option ** (i.e. if it is a contentless table), then this API always iterates ** through an empty set (all calls to xPhraseFirst() set iCol to -1). ** ** In all cases, matches are visited in (column ASC, offset ASC) order. ** i.e. all those in column 0, sorted by offset, followed by those in ** column 1, etc. ** ** xPhraseNext() ** See xPhraseFirst above. ** ** xPhraseFirstColumn() ** This function and xPhraseNextColumn() are similar to the xPhraseFirst() ** and xPhraseNext() APIs described above. The difference is that instead ** of iterating through all instances of a phrase in the current row, these |
︙ | ︙ | |||
231731 231732 231733 231734 231735 231736 231737 231738 231739 | ** ** The output text is not a copy of the document text that was tokenized. ** It is the output of the tokenizer module. For tokendata=1 tables, this ** includes any embedded 0x00 and trailing data. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. */ struct Fts5ExtensionApi { | > > > > > > > > > > > > > > > > > > > > > > > | | 233089 233090 233091 233092 233093 233094 233095 233096 233097 233098 233099 233100 233101 233102 233103 233104 233105 233106 233107 233108 233109 233110 233111 233112 233113 233114 233115 233116 233117 233118 233119 233120 233121 233122 233123 233124 233125 233126 233127 233128 | ** ** The output text is not a copy of the document text that was tokenized. ** It is the output of the tokenizer module. For tokendata=1 tables, this ** includes any embedded 0x00 and trailing data. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. ** ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) ** If parameter iCol is less than zero, or greater than or equal to the ** number of columns in the table, SQLITE_RANGE is returned. ** ** Otherwise, this function attempts to retrieve the locale associated ** with column iCol of the current row. Usually, there is no associated ** locale, and output parameters (*pzLocale) and (*pnLocale) are set ** to NULL and 0, respectively. However, if the fts5_locale() function ** was used to associate a locale with the value when it was inserted ** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated ** buffer containing the name of the locale in utf-8 encoding. (*pnLocale) ** is set to the size in bytes of the buffer, not including the ** nul-terminator. ** ** If successful, SQLITE_OK is returned. Or, if an error occurs, an ** SQLite error code is returned. The final value of the output parameters ** is undefined in this case. ** ** xTokenize_v2: ** Tokenize text using the tokenizer belonging to the FTS5 table. This ** API is the same as the xTokenize() API, except that it allows a tokenizer ** locale to be specified. */ struct Fts5ExtensionApi { int iVersion; /* Currently always set to 4 */ void *(*xUserData)(Fts5Context*); int (*xColumnCount)(Fts5Context*); int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow); int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken); |
︙ | ︙ | |||
231775 231776 231777 231778 231779 231780 231781 231782 231783 231784 231785 231786 231787 231788 231789 231790 231791 231792 231793 231794 231795 231796 231797 231798 231799 231800 231801 | /* Below this point are iVersion>=3 only */ int (*xQueryToken)(Fts5Context*, int iPhrase, int iToken, const char **ppToken, int *pnToken ); int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); }; /* ** CUSTOM AUXILIARY FUNCTIONS *************************************************************************/ /************************************************************************* ** CUSTOM TOKENIZERS ** ** Applications may also register custom tokenizer types. A tokenizer ** is registered by providing fts5 with a populated instance of the ** following structure. All structure methods must be defined, setting ** any member of the fts5_tokenizer struct to NULL leads to undefined ** behaviour. The structure methods are expected to function as follows: ** ** xCreate: ** This function is used to allocate and initialize a tokenizer instance. ** A tokenizer instance is required to actually tokenize text. ** ** The first argument passed to this function is a copy of the (void*) | > > > > > > > > > > | | 233156 233157 233158 233159 233160 233161 233162 233163 233164 233165 233166 233167 233168 233169 233170 233171 233172 233173 233174 233175 233176 233177 233178 233179 233180 233181 233182 233183 233184 233185 233186 233187 233188 233189 233190 233191 233192 233193 233194 233195 233196 233197 233198 233199 233200 | /* Below this point are iVersion>=3 only */ int (*xQueryToken)(Fts5Context*, int iPhrase, int iToken, const char **ppToken, int *pnToken ); int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); /* Below this point are iVersion>=4 only */ int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); int (*xTokenize_v2)(Fts5Context*, const char *pText, int nText, /* Text to tokenize */ const char *pLocale, int nLocale, /* Locale to pass to tokenizer */ void *pCtx, /* Context passed to xToken() */ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ ); }; /* ** CUSTOM AUXILIARY FUNCTIONS *************************************************************************/ /************************************************************************* ** CUSTOM TOKENIZERS ** ** Applications may also register custom tokenizer types. A tokenizer ** is registered by providing fts5 with a populated instance of the ** following structure. All structure methods must be defined, setting ** ** any member of the fts5_tokenizer struct to NULL leads to undefined ** behaviour. The structure methods are expected to function as follows: ** ** xCreate: ** This function is used to allocate and initialize a tokenizer instance. ** A tokenizer instance is required to actually tokenize text. ** ** The first argument passed to this function is a copy of the (void*) ** pointer provided by the application when the fts5_tokenizer_v2 object ** was registered with FTS5 (the third argument to xCreateTokenizer()). ** The second and third arguments are an array of nul-terminated strings ** containing the tokenizer arguments, if any, specified following the ** tokenizer name as part of the CREATE VIRTUAL TABLE statement used ** to create the FTS5 table. ** ** The final argument is an output variable. If successful, (*ppOut) |
︙ | ︙ | |||
231819 231820 231821 231822 231823 231824 231825 | ** ** xTokenize: ** This function is expected to tokenize the nText byte string indicated ** by argument pText. pText may or may not be nul-terminated. The first ** argument passed to this function is a pointer to an Fts5Tokenizer object ** returned by an earlier call to xCreate(). ** | | | 233210 233211 233212 233213 233214 233215 233216 233217 233218 233219 233220 233221 233222 233223 233224 | ** ** xTokenize: ** This function is expected to tokenize the nText byte string indicated ** by argument pText. pText may or may not be nul-terminated. The first ** argument passed to this function is a pointer to an Fts5Tokenizer object ** returned by an earlier call to xCreate(). ** ** The third argument indicates the reason that FTS5 is requesting ** tokenization of the supplied text. This is always one of the following ** four values: ** ** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into ** or removed from the FTS table. The tokenizer is being invoked to ** determine the set of tokens to add to (or delete from) the ** FTS index. |
︙ | ︙ | |||
231842 231843 231844 231845 231846 231847 231848 231849 231850 231851 231852 231853 231854 231855 | ** returned by the tokenizer will be treated as a token prefix. ** ** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to ** satisfy an fts5_api.xTokenize() request made by an auxiliary ** function. Or an fts5_api.xColumnSize() request made by the same ** on a columnsize=0 database. ** </ul> ** ** For each token in the input string, the supplied callback xToken() must ** be invoked. The first argument to it should be a copy of the pointer ** passed as the second argument to xTokenize(). The third and fourth ** arguments are a pointer to a buffer containing the token text, and the ** size of the token in bytes. The 4th and 5th arguments are the byte offsets ** of the first byte of and first byte immediately following the text from | > > > > > > > | 233233 233234 233235 233236 233237 233238 233239 233240 233241 233242 233243 233244 233245 233246 233247 233248 233249 233250 233251 233252 233253 | ** returned by the tokenizer will be treated as a token prefix. ** ** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to ** satisfy an fts5_api.xTokenize() request made by an auxiliary ** function. Or an fts5_api.xColumnSize() request made by the same ** on a columnsize=0 database. ** </ul> ** ** The sixth and seventh arguments passed to xTokenize() - pLocale and ** nLocale - are a pointer to a buffer containing the locale to use for ** tokenization (e.g. "en_US") and its size in bytes, respectively. The ** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in ** which case nLocale is always 0) to indicate that the tokenizer should ** use its default locale. ** ** For each token in the input string, the supplied callback xToken() must ** be invoked. The first argument to it should be a copy of the pointer ** passed as the second argument to xTokenize(). The third and fourth ** arguments are a pointer to a buffer containing the token text, and the ** size of the token in bytes. The 4th and 5th arguments are the byte offsets ** of the first byte of and first byte immediately following the text from |
︙ | ︙ | |||
231865 231866 231867 231868 231869 231870 231871 231872 231873 231874 231875 231876 231877 231878 | ** If an xToken() callback returns any value other than SQLITE_OK, then ** the tokenization should be abandoned and the xTokenize() method should ** immediately return a copy of the xToken() return value. Or, if the ** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally, ** if an error occurs with the xTokenize() implementation itself, it ** may abandon the tokenization and return any error code other than ** SQLITE_OK or SQLITE_DONE. ** ** SYNONYM SUPPORT ** ** Custom tokenizers may also support synonyms. Consider a case in which a ** user wishes to query for a phrase such as "first place". Using the ** built-in tokenizers, the FTS5 query 'first + place' will match instances ** of "first place" within the document set, but not alternative forms | > > > > > > > > > > > > > > > > > > > > > > > > | 233263 233264 233265 233266 233267 233268 233269 233270 233271 233272 233273 233274 233275 233276 233277 233278 233279 233280 233281 233282 233283 233284 233285 233286 233287 233288 233289 233290 233291 233292 233293 233294 233295 233296 233297 233298 233299 233300 | ** If an xToken() callback returns any value other than SQLITE_OK, then ** the tokenization should be abandoned and the xTokenize() method should ** immediately return a copy of the xToken() return value. Or, if the ** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally, ** if an error occurs with the xTokenize() implementation itself, it ** may abandon the tokenization and return any error code other than ** SQLITE_OK or SQLITE_DONE. ** ** If the tokenizer is registered using an fts5_tokenizer_v2 object, ** then the xTokenize() method has two additional arguments - pLocale ** and nLocale. These specify the locale that the tokenizer should use ** for the current request. If pLocale and nLocale are both 0, then the ** tokenizer should use its default locale. Otherwise, pLocale points to ** an nLocale byte buffer containing the name of the locale to use as utf-8 ** text. pLocale is not nul-terminated. ** ** FTS5_TOKENIZER ** ** There is also an fts5_tokenizer object. This is an older, deprecated, ** version of fts5_tokenizer_v2. It is similar except that: ** ** <ul> ** <li> There is no "iVersion" field, and ** <li> The xTokenize() method does not take a locale argument. ** </ul> ** ** Legacy fts5_tokenizer tokenizers must be registered using the ** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). ** ** Tokenizer implementations registered using either API may be retrieved ** using both xFindTokenizer() and xFindTokenizer_v2(). ** ** SYNONYM SUPPORT ** ** Custom tokenizers may also support synonyms. Consider a case in which a ** user wishes to query for a phrase such as "first place". Using the ** built-in tokenizers, the FTS5 query 'first + place' will match instances ** of "first place" within the document set, but not alternative forms |
︙ | ︙ | |||
231974 231975 231976 231977 231978 231979 231980 231981 231982 231983 231984 231985 231986 231987 231988 231989 231990 231991 231992 231993 231994 231995 231996 231997 231998 231999 232000 232001 232002 232003 232004 232005 232006 232007 232008 232009 232010 232011 232012 232013 232014 232015 232016 232017 232018 | ** ** When using methods (2) or (3), it is important that the tokenizer only ** provide synonyms when tokenizing document text (method (3)) or query ** text (method (2)), not both. Doing so will not cause any errors, but is ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; typedef struct fts5_tokenizer fts5_tokenizer; struct fts5_tokenizer { int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); void (*xDelete)(Fts5Tokenizer*); int (*xTokenize)(Fts5Tokenizer*, void *pCtx, int flags, /* Mask of FTS5_TOKENIZE_* flags */ const char *pText, int nText, int (*xToken)( void *pCtx, /* Copy of 2nd argument to xTokenize() */ int tflags, /* Mask of FTS5_TOKEN_* flags */ const char *pToken, /* Pointer to buffer containing token */ int nToken, /* Size of token in bytes */ int iStart, /* Byte offset of token within input text */ int iEnd /* Byte offset of end of token within input text */ ) ); }; /* Flags that may be passed as the third argument to xTokenize() */ #define FTS5_TOKENIZE_QUERY 0x0001 #define FTS5_TOKENIZE_PREFIX 0x0002 #define FTS5_TOKENIZE_DOCUMENT 0x0004 #define FTS5_TOKENIZE_AUX 0x0008 /* Flags that may be passed by the tokenizer implementation back to FTS5 ** as the third argument to the supplied xToken callback. */ #define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */ /* ** END OF CUSTOM TOKENIZERS *************************************************************************/ /************************************************************************* ** FTS5 EXTENSION REGISTRATION API */ typedef struct fts5_api fts5_api; struct fts5_api { | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 233396 233397 233398 233399 233400 233401 233402 233403 233404 233405 233406 233407 233408 233409 233410 233411 233412 233413 233414 233415 233416 233417 233418 233419 233420 233421 233422 233423 233424 233425 233426 233427 233428 233429 233430 233431 233432 233433 233434 233435 233436 233437 233438 233439 233440 233441 233442 233443 233444 233445 233446 233447 233448 233449 233450 233451 233452 233453 233454 233455 233456 233457 233458 233459 233460 233461 233462 233463 233464 233465 233466 233467 233468 233469 233470 233471 233472 233473 233474 233475 233476 | ** ** When using methods (2) or (3), it is important that the tokenizer only ** provide synonyms when tokenizing document text (method (3)) or query ** text (method (2)), not both. Doing so will not cause any errors, but is ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; struct fts5_tokenizer_v2 { int iVersion; /* Currently always 2 */ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); void (*xDelete)(Fts5Tokenizer*); int (*xTokenize)(Fts5Tokenizer*, void *pCtx, int flags, /* Mask of FTS5_TOKENIZE_* flags */ const char *pText, int nText, const char *pLocale, int nLocale, int (*xToken)( void *pCtx, /* Copy of 2nd argument to xTokenize() */ int tflags, /* Mask of FTS5_TOKEN_* flags */ const char *pToken, /* Pointer to buffer containing token */ int nToken, /* Size of token in bytes */ int iStart, /* Byte offset of token within input text */ int iEnd /* Byte offset of end of token within input text */ ) ); }; /* ** New code should use the fts5_tokenizer_v2 type to define tokenizer ** implementations. The following type is included for legacy applications ** that still use it. */ typedef struct fts5_tokenizer fts5_tokenizer; struct fts5_tokenizer { int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); void (*xDelete)(Fts5Tokenizer*); int (*xTokenize)(Fts5Tokenizer*, void *pCtx, int flags, /* Mask of FTS5_TOKENIZE_* flags */ const char *pText, int nText, int (*xToken)( void *pCtx, /* Copy of 2nd argument to xTokenize() */ int tflags, /* Mask of FTS5_TOKEN_* flags */ const char *pToken, /* Pointer to buffer containing token */ int nToken, /* Size of token in bytes */ int iStart, /* Byte offset of token within input text */ int iEnd /* Byte offset of end of token within input text */ ) ); }; /* Flags that may be passed as the third argument to xTokenize() */ #define FTS5_TOKENIZE_QUERY 0x0001 #define FTS5_TOKENIZE_PREFIX 0x0002 #define FTS5_TOKENIZE_DOCUMENT 0x0004 #define FTS5_TOKENIZE_AUX 0x0008 /* Flags that may be passed by the tokenizer implementation back to FTS5 ** as the third argument to the supplied xToken callback. */ #define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */ /* ** END OF CUSTOM TOKENIZERS *************************************************************************/ /************************************************************************* ** FTS5 EXTENSION REGISTRATION API */ typedef struct fts5_api fts5_api; struct fts5_api { int iVersion; /* Currently always set to 3 */ /* Create a new tokenizer */ int (*xCreateTokenizer)( fts5_api *pApi, const char *zName, void *pUserData, fts5_tokenizer *pTokenizer, |
︙ | ︙ | |||
232039 232040 232041 232042 232043 232044 232045 232046 232047 232048 232049 232050 232051 232052 | int (*xCreateFunction)( fts5_api *pApi, const char *zName, void *pUserData, fts5_extension_function xFunction, void (*xDestroy)(void*) ); }; /* ** END OF REGISTRATION API *************************************************************************/ #if 0 | > > > > > > > > > > > > > > > > > > > | 233489 233490 233491 233492 233493 233494 233495 233496 233497 233498 233499 233500 233501 233502 233503 233504 233505 233506 233507 233508 233509 233510 233511 233512 233513 233514 233515 233516 233517 233518 233519 233520 233521 | int (*xCreateFunction)( fts5_api *pApi, const char *zName, void *pUserData, fts5_extension_function xFunction, void (*xDestroy)(void*) ); /* APIs below this point are only available if iVersion>=3 */ /* Create a new tokenizer */ int (*xCreateTokenizer_v2)( fts5_api *pApi, const char *zName, void *pUserData, fts5_tokenizer_v2 *pTokenizer, void (*xDestroy)(void*) ); /* Find an existing tokenizer */ int (*xFindTokenizer_v2)( fts5_api *pApi, const char *zName, void **ppUserData, fts5_tokenizer_v2 **ppTokenizer ); }; /* ** END OF REGISTRATION API *************************************************************************/ #if 0 |
︙ | ︙ | |||
232111 232112 232113 232114 232115 232116 232117 232118 232119 232120 232121 232122 232123 232124 | #define MAX(x,y) (((x) > (y)) ? (x) : (y)) /* ** Constants for the largest and smallest possible 64-bit signed integers. */ # define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) # define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) #endif /* Truncate very long tokens to this many bytes. Hard limit is ** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset ** field that occurs at the start of each leaf page (see fts5_index.c). */ #define FTS5_MAX_TOKEN_SIZE 32768 | > > > > > > > > > > > > > > > > | 233580 233581 233582 233583 233584 233585 233586 233587 233588 233589 233590 233591 233592 233593 233594 233595 233596 233597 233598 233599 233600 233601 233602 233603 233604 233605 233606 233607 233608 233609 | #define MAX(x,y) (((x) > (y)) ? (x) : (y)) /* ** Constants for the largest and smallest possible 64-bit signed integers. */ # define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) # define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) /* The uptr type is an unsigned integer large enough to hold a pointer */ #if defined(HAVE_STDINT_H) typedef uintptr_t uptr; #elif SQLITE_PTRSIZE==4 typedef u32 uptr; #else typedef u64 uptr; #endif #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0) #else # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) #endif #endif /* Truncate very long tokens to this many bytes. Hard limit is ** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset ** field that occurs at the start of each leaf page (see fts5_index.c). */ #define FTS5_MAX_TOKEN_SIZE 32768 |
︙ | ︙ | |||
232195 232196 232197 232198 232199 232200 232201 232202 232203 232204 232205 232206 232207 232208 | /************************************************************************** ** Interface to code in fts5_config.c. fts5_config.c contains contains code ** to parse the arguments passed to the CREATE VIRTUAL TABLE statement. */ typedef struct Fts5Config Fts5Config; /* ** An instance of the following structure encodes all information that can ** be gleaned from the CREATE VIRTUAL TABLE statement. ** ** And all information loaded from the %_config table. ** | > > > > > > > > > > > > | 233680 233681 233682 233683 233684 233685 233686 233687 233688 233689 233690 233691 233692 233693 233694 233695 233696 233697 233698 233699 233700 233701 233702 233703 233704 233705 | /************************************************************************** ** Interface to code in fts5_config.c. fts5_config.c contains contains code ** to parse the arguments passed to the CREATE VIRTUAL TABLE statement. */ typedef struct Fts5Config Fts5Config; typedef struct Fts5TokenizerConfig Fts5TokenizerConfig; struct Fts5TokenizerConfig { Fts5Tokenizer *pTok; fts5_tokenizer_v2 *pApi2; fts5_tokenizer *pApi1; const char **azArg; int nArg; int ePattern; /* FTS_PATTERN_XXX constant */ const char *pLocale; /* Current locale to use */ int nLocale; /* Size of pLocale in bytes */ }; /* ** An instance of the following structure encodes all information that can ** be gleaned from the CREATE VIRTUAL TABLE statement. ** ** And all information loaded from the %_config table. ** |
︙ | ︙ | |||
232234 232235 232236 232237 232238 232239 232240 232241 232242 232243 232244 232245 232246 232247 232248 232249 232250 232251 232252 232253 232254 232255 232256 232257 232258 | ** ** bPrefixIndex: ** This is only used for debugging. If set to false, any prefix indexes ** are ignored. This value is configured using: ** ** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex); ** */ struct Fts5Config { sqlite3 *db; /* Database handle */ char *zDb; /* Database holding FTS index (e.g. "main") */ char *zName; /* Name of FTS index */ int nCol; /* Number of columns */ char **azCol; /* Column names */ u8 *abUnindexed; /* True for unindexed columns */ int nPrefix; /* Number of prefix indexes */ int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */ int eContent; /* An FTS5_CONTENT value */ int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */ char *zContent; /* content table */ char *zContentRowid; /* "content_rowid=" option value */ int bColumnsize; /* "columnsize=" option value (dflt==1) */ int bTokendata; /* "tokendata=" option value (dflt==0) */ int eDetail; /* FTS5_DETAIL_XXX value */ char *zContentExprlist; | > > > > | < | | 233731 233732 233733 233734 233735 233736 233737 233738 233739 233740 233741 233742 233743 233744 233745 233746 233747 233748 233749 233750 233751 233752 233753 233754 233755 233756 233757 233758 233759 233760 233761 233762 233763 233764 233765 233766 233767 233768 233769 | ** ** bPrefixIndex: ** This is only used for debugging. If set to false, any prefix indexes ** are ignored. This value is configured using: ** ** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex); ** ** bLocale: ** Set to true if locale=1 was specified when the table was created. */ struct Fts5Config { sqlite3 *db; /* Database handle */ Fts5Global *pGlobal; /* Global fts5 object for handle db */ char *zDb; /* Database holding FTS index (e.g. "main") */ char *zName; /* Name of FTS index */ int nCol; /* Number of columns */ char **azCol; /* Column names */ u8 *abUnindexed; /* True for unindexed columns */ int nPrefix; /* Number of prefix indexes */ int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */ int eContent; /* An FTS5_CONTENT value */ int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */ char *zContent; /* content table */ char *zContentRowid; /* "content_rowid=" option value */ int bColumnsize; /* "columnsize=" option value (dflt==1) */ int bTokendata; /* "tokendata=" option value (dflt==0) */ int bLocale; /* "locale=" option value (dflt==0) */ int eDetail; /* FTS5_DETAIL_XXX value */ char *zContentExprlist; Fts5TokenizerConfig t; int bLock; /* True when table is preparing statement */ /* Values loaded from the %_config table */ int iVersion; /* fts5 file format 'version' */ int iCookie; /* Incremented when %_config is modified */ int pgsz; /* Approximate page size used in %_data */ int nAutomerge; /* 'automerge' setting */ int nCrisisMerge; /* Maximum allowed segments per level */ |
︙ | ︙ | |||
232321 232322 232323 232324 232325 232326 232327 232328 232329 232330 232331 232332 232333 232334 | static int sqlite3Fts5ConfigLoad(Fts5Config*, int); /* Set the value of a single config attribute */ static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, int*); static int sqlite3Fts5ConfigParseRank(const char*, char**, char**); /* ** End of interface to code in fts5_config.c. **************************************************************************/ /************************************************************************** ** Interface to code in fts5_buffer.c. */ | > > | 233821 233822 233823 233824 233825 233826 233827 233828 233829 233830 233831 233832 233833 233834 233835 233836 | static int sqlite3Fts5ConfigLoad(Fts5Config*, int); /* Set the value of a single config attribute */ static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, int*); static int sqlite3Fts5ConfigParseRank(const char*, char**, char**); static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...); /* ** End of interface to code in fts5_config.c. **************************************************************************/ /************************************************************************** ** Interface to code in fts5_buffer.c. */ |
︙ | ︙ | |||
232365 232366 232367 232368 232369 232370 232371 | 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*); | | | 233867 233868 233869 233870 233871 233872 233873 233874 233875 233876 233877 233878 233879 233880 233881 | 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*); #define FTS5_POS2COLUMN(iPos) (int)((iPos >> 32) & 0x7FFFFFFF) #define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF) typedef struct Fts5PoslistReader Fts5PoslistReader; struct Fts5PoslistReader { /* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */ const u8 *a; /* Position list to iterate through */ int n; /* Size of buffer at a[] in bytes */ |
︙ | ︙ | |||
232650 232651 232652 232653 232654 232655 232656 | typedef struct Fts5Table Fts5Table; struct Fts5Table { sqlite3_vtab base; /* Base class used by SQLite core */ Fts5Config *pConfig; /* Virtual table configuration */ Fts5Index *pIndex; /* Full-text index */ }; | | < < < < < < > > > > > > > > | 234152 234153 234154 234155 234156 234157 234158 234159 234160 234161 234162 234163 234164 234165 234166 234167 234168 234169 234170 234171 234172 234173 234174 234175 234176 234177 234178 | typedef struct Fts5Table Fts5Table; struct Fts5Table { sqlite3_vtab base; /* Base class used by SQLite core */ Fts5Config *pConfig; /* Virtual table configuration */ Fts5Index *pIndex; /* Full-text index */ }; static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig); static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64); static int sqlite3Fts5FlushToDisk(Fts5Table*); static void sqlite3Fts5ClearLocale(Fts5Config *pConfig); static void sqlite3Fts5SetLocale(Fts5Config *pConfig, const char *pLoc, int nLoc); static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal); static int sqlite3Fts5DecodeLocaleValue(sqlite3_value *pVal, const char **ppText, int *pnText, const char **ppLoc, int *pnLoc ); /* ** End of interface to code in fts5.c. **************************************************************************/ /************************************************************************** ** Interface to code in fts5_hash.c. |
︙ | ︙ | |||
232741 232742 232743 232744 232745 232746 232747 | static int sqlite3Fts5StorageOpen(Fts5Config*, Fts5Index*, int, Fts5Storage**, char**); static int sqlite3Fts5StorageClose(Fts5Storage *p); static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName); static int sqlite3Fts5DropAll(Fts5Config*); static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **); | | | 234245 234246 234247 234248 234249 234250 234251 234252 234253 234254 234255 234256 234257 234258 234259 | static int sqlite3Fts5StorageOpen(Fts5Config*, Fts5Index*, int, Fts5Storage**, char**); static int sqlite3Fts5StorageClose(Fts5Storage *p); static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName); static int sqlite3Fts5DropAll(Fts5Config*); static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **); static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**, int); static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*); static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64); static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg); static int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt**, char**); static void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*); |
︙ | ︙ | |||
232767 232768 232769 232770 232771 232772 232773 232774 232775 232776 232777 232778 232779 232780 | static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p); static int sqlite3Fts5StorageRebuild(Fts5Storage *p); static int sqlite3Fts5StorageOptimize(Fts5Storage *p); static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge); static int sqlite3Fts5StorageReset(Fts5Storage *p); /* ** End of interface to code in fts5_storage.c. **************************************************************************/ /************************************************************************** ** Interface to code in fts5_expr.c. | > > > | 234271 234272 234273 234274 234275 234276 234277 234278 234279 234280 234281 234282 234283 234284 234285 234286 234287 | static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p); static int sqlite3Fts5StorageRebuild(Fts5Storage *p); static int sqlite3Fts5StorageOptimize(Fts5Storage *p); static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge); static int sqlite3Fts5StorageReset(Fts5Storage *p); static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage*); static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel); /* ** End of interface to code in fts5_storage.c. **************************************************************************/ /************************************************************************** ** Interface to code in fts5_expr.c. |
︙ | ︙ | |||
232919 232920 232921 232922 232923 232924 232925 232926 232927 232928 232929 232930 232931 232932 | */ static int sqlite3Fts5TokenizerInit(fts5_api*); static int sqlite3Fts5TokenizerPattern( int (*xCreate)(void*, const char**, int, Fts5Tokenizer**), Fts5Tokenizer *pTok ); /* ** End of interface to code in fts5_tokenizer.c. **************************************************************************/ /************************************************************************** ** Interface to code in fts5_vocab.c. */ | > | 234426 234427 234428 234429 234430 234431 234432 234433 234434 234435 234436 234437 234438 234439 234440 | */ static int sqlite3Fts5TokenizerInit(fts5_api*); static int sqlite3Fts5TokenizerPattern( int (*xCreate)(void*, const char**, int, Fts5Tokenizer**), Fts5Tokenizer *pTok ); static int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig*); /* ** End of interface to code in fts5_tokenizer.c. **************************************************************************/ /************************************************************************** ** Interface to code in fts5_vocab.c. */ |
︙ | ︙ | |||
234695 234696 234697 234698 234699 234700 234701 234702 234703 234704 234705 234706 234707 234708 | } fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); p->iOff = iEndOff; } return rc; } /* ** Implementation of highlight() function. */ static void fts5HighlightFunction( const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ Fts5Context *pFts, /* First arg to pass to pApi functions */ | > | 236203 236204 236205 236206 236207 236208 236209 236210 236211 236212 236213 236214 236215 236216 236217 | } fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); p->iOff = iEndOff; } return rc; } /* ** Implementation of highlight() function. */ static void fts5HighlightFunction( const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ Fts5Context *pFts, /* First arg to pass to pApi functions */ |
︙ | ︙ | |||
234726 234727 234728 234729 234730 234731 234732 234733 234734 234735 234736 234737 | ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); ctx.iRangeEnd = -1; rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn); if( rc==SQLITE_RANGE ){ sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); rc = SQLITE_OK; }else if( ctx.zIn ){ if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter); } if( rc==SQLITE_OK ){ | > > > > > | > > | 236235 236236 236237 236238 236239 236240 236241 236242 236243 236244 236245 236246 236247 236248 236249 236250 236251 236252 236253 236254 236255 236256 236257 236258 236259 236260 236261 | ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); ctx.iRangeEnd = -1; rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn); if( rc==SQLITE_RANGE ){ sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); rc = SQLITE_OK; }else if( ctx.zIn ){ const char *pLoc = 0; /* Locale of column iCol */ int nLoc = 0; /* Size of pLoc in bytes */ if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter); } if( rc==SQLITE_OK ){ rc = pApi->xColumnLocale(pFts, iCol, &pLoc, &nLoc); } if( rc==SQLITE_OK ){ rc = pApi->xTokenize_v2( pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx, fts5HighlightCb ); } if( ctx.bOpen ){ fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); } fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff); if( rc==SQLITE_OK ){ |
︙ | ︙ | |||
234928 234929 234930 234931 234932 234933 234934 234935 234936 234937 234938 234939 234940 234941 | if( rc==SQLITE_OK ){ rc = pApi->xInstCount(pFts, &nInst); } memset(&sFinder, 0, sizeof(Fts5SFinder)); for(i=0; i<nCol; i++){ if( iCol<0 || iCol==i ){ int nDoc; int nDocsize; int ii; sFinder.iPos = 0; sFinder.nFirst = 0; rc = pApi->xColumnText(pFts, i, &sFinder.zDoc, &nDoc); if( rc!=SQLITE_OK ) break; | > > > > | | | 236444 236445 236446 236447 236448 236449 236450 236451 236452 236453 236454 236455 236456 236457 236458 236459 236460 236461 236462 236463 236464 236465 236466 236467 236468 236469 236470 | if( rc==SQLITE_OK ){ rc = pApi->xInstCount(pFts, &nInst); } memset(&sFinder, 0, sizeof(Fts5SFinder)); for(i=0; i<nCol; i++){ if( iCol<0 || iCol==i ){ const char *pLoc = 0; /* Locale of column iCol */ int nLoc = 0; /* Size of pLoc in bytes */ int nDoc; int nDocsize; int ii; sFinder.iPos = 0; sFinder.nFirst = 0; rc = pApi->xColumnText(pFts, i, &sFinder.zDoc, &nDoc); if( rc!=SQLITE_OK ) break; rc = pApi->xColumnLocale(pFts, i, &pLoc, &nLoc); if( rc!=SQLITE_OK ) break; rc = pApi->xTokenize_v2(pFts, sFinder.zDoc, nDoc, pLoc, nLoc, (void*)&sFinder, fts5SentenceFinderCb ); if( rc!=SQLITE_OK ) break; rc = pApi->xColumnSize(pFts, i, &nDocsize); if( rc!=SQLITE_OK ) break; for(ii=0; rc==SQLITE_OK && ii<nInst; ii++){ int ip, ic, io; |
︙ | ︙ | |||
234994 234995 234996 234997 234998 234999 235000 235001 235002 235003 235004 235005 235006 235007 235008 235009 235010 235011 235012 235013 235014 235015 235016 235017 235018 | if( rc==SQLITE_OK ){ rc = pApi->xColumnText(pFts, iBestCol, &ctx.zIn, &ctx.nIn); } if( rc==SQLITE_OK && nColSize==0 ){ rc = pApi->xColumnSize(pFts, iBestCol, &nColSize); } if( ctx.zIn ){ if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter); } ctx.iRangeStart = iBestStart; ctx.iRangeEnd = iBestStart + nToken - 1; if( iBestStart>0 ){ fts5HighlightAppend(&rc, &ctx, zEllips, -1); } /* Advance iterator ctx.iter so that it points to the first coalesced ** phrase instance at or following position iBestStart. */ while( ctx.iter.iStart>=0 && ctx.iter.iStart<iBestStart && rc==SQLITE_OK ){ rc = fts5CInstIterNext(&ctx.iter); } if( rc==SQLITE_OK ){ | > > > > > > | > > | 236514 236515 236516 236517 236518 236519 236520 236521 236522 236523 236524 236525 236526 236527 236528 236529 236530 236531 236532 236533 236534 236535 236536 236537 236538 236539 236540 236541 236542 236543 236544 236545 236546 236547 236548 236549 236550 236551 236552 236553 236554 | if( rc==SQLITE_OK ){ rc = pApi->xColumnText(pFts, iBestCol, &ctx.zIn, &ctx.nIn); } if( rc==SQLITE_OK && nColSize==0 ){ rc = pApi->xColumnSize(pFts, iBestCol, &nColSize); } if( ctx.zIn ){ const char *pLoc = 0; /* Locale of column iBestCol */ int nLoc = 0; /* Bytes in pLoc */ if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter); } ctx.iRangeStart = iBestStart; ctx.iRangeEnd = iBestStart + nToken - 1; if( iBestStart>0 ){ fts5HighlightAppend(&rc, &ctx, zEllips, -1); } /* Advance iterator ctx.iter so that it points to the first coalesced ** phrase instance at or following position iBestStart. */ while( ctx.iter.iStart>=0 && ctx.iter.iStart<iBestStart && rc==SQLITE_OK ){ rc = fts5CInstIterNext(&ctx.iter); } if( rc==SQLITE_OK ){ rc = pApi->xColumnLocale(pFts, iBestCol, &pLoc, &nLoc); } if( rc==SQLITE_OK ){ rc = pApi->xTokenize_v2( pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx,fts5HighlightCb ); } if( ctx.bOpen ){ fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); } if( ctx.iRangeEnd>=(nColSize-1) ){ fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff); }else{ |
︙ | ︙ | |||
235195 235196 235197 235198 235199 235200 235201 235202 235203 235204 235205 235206 235207 235208 235209 | ); } sqlite3_result_double(pCtx, -1.0 * score); }else{ sqlite3_result_error_code(pCtx, rc); } } static int sqlite3Fts5AuxInit(fts5_api *pApi){ struct Builtin { const char *zFunc; /* Function name (nul-terminated) */ void *pUserData; /* User-data pointer */ fts5_extension_function xFunc;/* Callback function */ void (*xDestroy)(void*); /* Destructor function */ } aBuiltin [] = { | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > | 236723 236724 236725 236726 236727 236728 236729 236730 236731 236732 236733 236734 236735 236736 236737 236738 236739 236740 236741 236742 236743 236744 236745 236746 236747 236748 236749 236750 236751 236752 236753 236754 236755 236756 236757 236758 236759 236760 236761 236762 236763 236764 236765 236766 236767 236768 236769 236770 236771 236772 236773 236774 236775 236776 236777 236778 236779 236780 236781 236782 236783 236784 236785 236786 236787 236788 236789 236790 236791 236792 236793 236794 236795 | ); } sqlite3_result_double(pCtx, -1.0 * score); }else{ sqlite3_result_error_code(pCtx, rc); } } /* ** Implementation of fts5_get_locale() function. */ static void fts5GetLocaleFunction( const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ Fts5Context *pFts, /* First arg to pass to pApi functions */ sqlite3_context *pCtx, /* Context for returning result/error */ int nVal, /* Number of values in apVal[] array */ sqlite3_value **apVal /* Array of trailing arguments */ ){ int iCol = 0; int eType = 0; int rc = SQLITE_OK; const char *zLocale = 0; int nLocale = 0; /* xColumnLocale() must be available */ assert( pApi->iVersion>=4 ); if( nVal!=1 ){ const char *z = "wrong number of arguments to function fts5_get_locale()"; sqlite3_result_error(pCtx, z, -1); return; } eType = sqlite3_value_numeric_type(apVal[0]); if( eType!=SQLITE_INTEGER ){ const char *z = "non-integer argument passed to function fts5_get_locale()"; sqlite3_result_error(pCtx, z, -1); return; } iCol = sqlite3_value_int(apVal[0]); if( iCol<0 || iCol>=pApi->xColumnCount(pFts) ){ sqlite3_result_error_code(pCtx, SQLITE_RANGE); return; } rc = pApi->xColumnLocale(pFts, iCol, &zLocale, &nLocale); if( rc!=SQLITE_OK ){ sqlite3_result_error_code(pCtx, rc); return; } sqlite3_result_text(pCtx, zLocale, nLocale, SQLITE_TRANSIENT); } static int sqlite3Fts5AuxInit(fts5_api *pApi){ struct Builtin { const char *zFunc; /* Function name (nul-terminated) */ void *pUserData; /* User-data pointer */ fts5_extension_function xFunc;/* Callback function */ void (*xDestroy)(void*); /* Destructor function */ } aBuiltin [] = { { "snippet", 0, fts5SnippetFunction, 0 }, { "highlight", 0, fts5HighlightFunction, 0 }, { "bm25", 0, fts5Bm25Function, 0 }, { "fts5_get_locale", 0, fts5GetLocaleFunction, 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, |
︙ | ︙ | |||
235870 235871 235872 235873 235874 235875 235876 | ** ** If successful, object pConfig is updated and SQLITE_OK returned. If ** an error occurs, an SQLite error code is returned and an error message ** may be left in *pzErr. It is the responsibility of the caller to ** eventually free any such error message using sqlite3_free(). */ static int fts5ConfigParseSpecial( | < | 237446 237447 237448 237449 237450 237451 237452 237453 237454 237455 237456 237457 237458 237459 | ** ** If successful, object pConfig is updated and SQLITE_OK returned. If ** an error occurs, an SQLite error code is returned and an error message ** may be left in *pzErr. It is the responsibility of the caller to ** eventually free any such error message using sqlite3_free(). */ static int fts5ConfigParseSpecial( Fts5Config *pConfig, /* Configuration object to update */ const char *zCmd, /* Special command to parse */ const char *zArg, /* Argument to parse */ char **pzErr /* OUT: Error message */ ){ int rc = SQLITE_OK; int nCmd = (int)strlen(zCmd); |
︙ | ︙ | |||
235934 235935 235936 235937 235938 235939 235940 | assert( pConfig->nPrefix<=FTS5_MAX_PREFIX_INDEXES ); return rc; } if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){ const char *p = (const char*)zArg; sqlite3_int64 nArg = strlen(zArg) + 1; | | < < | > | | 237509 237510 237511 237512 237513 237514 237515 237516 237517 237518 237519 237520 237521 237522 237523 237524 237525 237526 237527 | assert( pConfig->nPrefix<=FTS5_MAX_PREFIX_INDEXES ); return rc; } if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){ const char *p = (const char*)zArg; sqlite3_int64 nArg = strlen(zArg) + 1; char **azArg = sqlite3Fts5MallocZero(&rc, (sizeof(char*) + 2) * nArg); if( azArg ){ char *pSpace = (char*)&azArg[nArg]; if( pConfig->t.azArg ){ *pzErr = sqlite3_mprintf("multiple tokenize=... directives"); rc = SQLITE_ERROR; }else{ for(nArg=0; p && *p; nArg++){ const char *p2 = fts5ConfigSkipWhitespace(p); if( *p2=='\'' ){ p = fts5ConfigSkipLiteral(p2); |
︙ | ︙ | |||
235962 235963 235964 235965 235966 235967 235968 | p = fts5ConfigSkipWhitespace(p); } } if( p==0 ){ *pzErr = sqlite3_mprintf("parse error in tokenize directive"); rc = SQLITE_ERROR; }else{ | < | > | < < | | 237536 237537 237538 237539 237540 237541 237542 237543 237544 237545 237546 237547 237548 237549 237550 237551 237552 237553 237554 237555 237556 237557 | p = fts5ConfigSkipWhitespace(p); } } if( p==0 ){ *pzErr = sqlite3_mprintf("parse error in tokenize directive"); rc = SQLITE_ERROR; }else{ pConfig->t.azArg = (const char**)azArg; pConfig->t.nArg = nArg; azArg = 0; } } } sqlite3_free(azArg); return rc; } if( sqlite3_strnicmp("content", zCmd, nCmd)==0 ){ if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){ *pzErr = sqlite3_mprintf("multiple content=... directives"); rc = SQLITE_ERROR; |
︙ | ︙ | |||
236019 236020 236021 236022 236023 236024 236025 236026 236027 236028 236029 236030 236031 236032 | *pzErr = sqlite3_mprintf("malformed columnsize=... directive"); rc = SQLITE_ERROR; }else{ pConfig->bColumnsize = (zArg[0]=='1'); } return rc; } if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){ const Fts5Enum aDetail[] = { { "none", FTS5_DETAIL_NONE }, { "full", FTS5_DETAIL_FULL }, { "columns", FTS5_DETAIL_COLUMNS }, { 0, 0 } | > > > > > > > > > > | 237591 237592 237593 237594 237595 237596 237597 237598 237599 237600 237601 237602 237603 237604 237605 237606 237607 237608 237609 237610 237611 237612 237613 237614 | *pzErr = sqlite3_mprintf("malformed columnsize=... directive"); rc = SQLITE_ERROR; }else{ pConfig->bColumnsize = (zArg[0]=='1'); } return rc; } if( sqlite3_strnicmp("locale", zCmd, nCmd)==0 ){ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ *pzErr = sqlite3_mprintf("malformed locale=... directive"); rc = SQLITE_ERROR; }else{ pConfig->bLocale = (zArg[0]=='1'); } return rc; } if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){ const Fts5Enum aDetail[] = { { "none", FTS5_DETAIL_NONE }, { "full", FTS5_DETAIL_FULL }, { "columns", FTS5_DETAIL_COLUMNS }, { 0, 0 } |
︙ | ︙ | |||
236048 236049 236050 236051 236052 236053 236054 | return rc; } *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd); return SQLITE_ERROR; } | < < < < < < < < < < | 237630 237631 237632 237633 237634 237635 237636 237637 237638 237639 237640 237641 237642 237643 | return rc; } *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd); return SQLITE_ERROR; } /* ** Gobble up the first bareword or quoted word from the input buffer zIn. ** Return a pointer to the character immediately following the last in ** the gobbled word if successful, or a NULL pointer otherwise (failed ** to find close-quote character). ** ** Before returning, set pzOut to point to a new buffer containing a |
︙ | ︙ | |||
236156 236157 236158 236159 236160 236161 236162 236163 236164 236165 236166 236167 236168 236169 | if( p->eContent==FTS5_CONTENT_EXTERNAL ){ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]); }else{ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i); } } } assert( p->zContentExprlist==0 ); p->zContentExprlist = (char*)buf.p; return rc; } /* | > > > > > > > > > | 237728 237729 237730 237731 237732 237733 237734 237735 237736 237737 237738 237739 237740 237741 237742 237743 237744 237745 237746 237747 237748 237749 237750 | if( p->eContent==FTS5_CONTENT_EXTERNAL ){ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]); }else{ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i); } } } if( p->eContent==FTS5_CONTENT_NORMAL && p->bLocale ){ for(i=0; i<p->nCol; i++){ if( p->abUnindexed[i]==0 ){ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.l%d", i); }else{ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", NULL"); } } } assert( p->zContentExprlist==0 ); p->zContentExprlist = (char*)buf.p; return rc; } /* |
︙ | ︙ | |||
236190 236191 236192 236193 236194 236195 236196 236197 236198 236199 236200 236201 236202 236203 | Fts5Config *pRet; /* New object to return */ int i; sqlite3_int64 nByte; *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config)); if( pRet==0 ) return SQLITE_NOMEM; memset(pRet, 0, sizeof(Fts5Config)); pRet->db = db; pRet->iCookie = -1; nByte = nArg * (sizeof(char*) + sizeof(u8)); pRet->azCol = (char**)sqlite3Fts5MallocZero(&rc, nByte); pRet->abUnindexed = pRet->azCol ? (u8*)&pRet->azCol[nArg] : 0; pRet->zDb = sqlite3Fts5Strndup(&rc, azArg[1], -1); | > | 237771 237772 237773 237774 237775 237776 237777 237778 237779 237780 237781 237782 237783 237784 237785 | Fts5Config *pRet; /* New object to return */ int i; sqlite3_int64 nByte; *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config)); if( pRet==0 ) return SQLITE_NOMEM; memset(pRet, 0, sizeof(Fts5Config)); pRet->pGlobal = pGlobal; pRet->db = db; pRet->iCookie = -1; nByte = nArg * (sizeof(char*) + sizeof(u8)); pRet->azCol = (char**)sqlite3Fts5MallocZero(&rc, nByte); pRet->abUnindexed = pRet->azCol ? (u8*)&pRet->azCol[nArg] : 0; pRet->zDb = sqlite3Fts5Strndup(&rc, azArg[1], -1); |
︙ | ︙ | |||
236238 236239 236240 236241 236242 236243 236244 | if( rc==SQLITE_OK ){ if( z==0 ){ *pzErr = sqlite3_mprintf("parse error in \"%s\"", zOrig); rc = SQLITE_ERROR; }else{ if( bOption ){ | | | 237820 237821 237822 237823 237824 237825 237826 237827 237828 237829 237830 237831 237832 237833 237834 | if( rc==SQLITE_OK ){ if( z==0 ){ *pzErr = sqlite3_mprintf("parse error in \"%s\"", zOrig); rc = SQLITE_ERROR; }else{ if( bOption ){ rc = fts5ConfigParseSpecial(pRet, ALWAYS(zOne)?zOne:"", zTwo?zTwo:"", pzErr ); }else{ rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr); zOne = 0; |
︙ | ︙ | |||
236276 236277 236278 236279 236280 236281 236282 | if( rc==SQLITE_OK && pRet->bContentlessDelete && pRet->bColumnsize==0 ){ *pzErr = sqlite3_mprintf( "contentless_delete=1 is incompatible with columnsize=0" ); rc = SQLITE_ERROR; } | < < < < < < < | 237858 237859 237860 237861 237862 237863 237864 237865 237866 237867 237868 237869 237870 237871 | if( rc==SQLITE_OK && pRet->bContentlessDelete && pRet->bColumnsize==0 ){ *pzErr = sqlite3_mprintf( "contentless_delete=1 is incompatible with columnsize=0" ); rc = SQLITE_ERROR; } /* If no zContent option was specified, fill in the default values. */ if( rc==SQLITE_OK && pRet->zContent==0 ){ const char *zTail = 0; assert( pRet->eContent==FTS5_CONTENT_NORMAL || pRet->eContent==FTS5_CONTENT_NONE ); if( pRet->eContent==FTS5_CONTENT_NORMAL ){ |
︙ | ︙ | |||
236324 236325 236326 236327 236328 236329 236330 | /* ** Free the configuration object passed as the only argument. */ static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){ if( pConfig ){ int i; | | > | > > | > > | 237899 237900 237901 237902 237903 237904 237905 237906 237907 237908 237909 237910 237911 237912 237913 237914 237915 237916 237917 237918 237919 237920 | /* ** Free the configuration object passed as the only argument. */ static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){ if( pConfig ){ int i; if( pConfig->t.pTok ){ if( pConfig->t.pApi1 ){ pConfig->t.pApi1->xDelete(pConfig->t.pTok); }else{ pConfig->t.pApi2->xDelete(pConfig->t.pTok); } } sqlite3_free((char*)pConfig->t.azArg); sqlite3_free(pConfig->zDb); sqlite3_free(pConfig->zName); for(i=0; i<pConfig->nCol; i++){ sqlite3_free(pConfig->azCol[i]); } sqlite3_free(pConfig->azCol); sqlite3_free(pConfig->aPrefix); |
︙ | ︙ | |||
236401 236402 236403 236404 236405 236406 236407 | static int sqlite3Fts5Tokenize( Fts5Config *pConfig, /* FTS5 Configuration object */ int flags, /* FTS5_TOKENIZE_* flags */ const char *pText, int nText, /* Text to tokenize */ void *pCtx, /* Context passed to xToken() */ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ ){ | > | > > > > | > | | > > > > > > > > | 237981 237982 237983 237984 237985 237986 237987 237988 237989 237990 237991 237992 237993 237994 237995 237996 237997 237998 237999 238000 238001 238002 238003 238004 238005 238006 238007 238008 238009 238010 238011 238012 | static int sqlite3Fts5Tokenize( Fts5Config *pConfig, /* FTS5 Configuration object */ int flags, /* FTS5_TOKENIZE_* flags */ const char *pText, int nText, /* Text to tokenize */ void *pCtx, /* Context passed to xToken() */ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ ){ int rc = SQLITE_OK; if( pText ){ if( pConfig->t.pTok==0 ){ rc = sqlite3Fts5LoadTokenizer(pConfig); } if( rc==SQLITE_OK ){ if( pConfig->t.pApi1 ){ rc = pConfig->t.pApi1->xTokenize( pConfig->t.pTok, pCtx, flags, pText, nText, xToken ); }else{ rc = pConfig->t.pApi2->xTokenize(pConfig->t.pTok, pCtx, flags, pText, nText, pConfig->t.pLocale, pConfig->t.nLocale, xToken ); } } } return rc; } /* ** Argument pIn points to the first character in what is expected to be ** a comma-separated list of SQL literals followed by a ')' character. ** If it actually is this, return a pointer to the ')'. Otherwise, return ** NULL to indicate a parse error. |
︙ | ︙ | |||
236658 236659 236660 236661 236662 236663 236664 | } if( rc==SQLITE_OK && iVersion!=FTS5_CURRENT_VERSION && iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE ){ rc = SQLITE_ERROR; | < < | | | | < > > > > > > > > > > > > > > > > > > > > > > > | 238252 238253 238254 238255 238256 238257 238258 238259 238260 238261 238262 238263 238264 238265 238266 238267 238268 238269 238270 238271 238272 238273 238274 238275 238276 238277 238278 238279 238280 238281 238282 238283 238284 238285 238286 238287 238288 238289 238290 238291 238292 238293 238294 238295 238296 238297 238298 238299 238300 238301 | } if( rc==SQLITE_OK && iVersion!=FTS5_CURRENT_VERSION && iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE ){ rc = SQLITE_ERROR; sqlite3Fts5ConfigErrmsg(pConfig, "invalid fts5 file format " "(found %d, expected %d or %d) - run 'rebuild'", iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE ); }else{ pConfig->iVersion = iVersion; } if( rc==SQLITE_OK ){ pConfig->iCookie = iCookie; } return rc; } /* ** Set (*pConfig->pzErrmsg) to point to an sqlite3_malloc()ed buffer ** containing the error message created using printf() style formatting ** string zFmt and its trailing arguments. */ static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...){ va_list ap; /* ... printf arguments */ char *zMsg = 0; va_start(ap, zFmt); zMsg = sqlite3_vmprintf(zFmt, ap); if( pConfig->pzErrmsg ){ assert( *pConfig->pzErrmsg==0 ); *pConfig->pzErrmsg = zMsg; }else{ sqlite3_free(zMsg); } va_end(ap); } /* ** 2014 May 31 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** |
︙ | ︙ | |||
236731 236732 236733 236734 236735 236736 236737 | int bDesc; /* Iterate in descending rowid order */ int nPhrase; /* Number of phrases in expression */ Fts5ExprPhrase **apExprPhrase; /* Pointers to phrase objects */ }; /* ** eType: | | > > > > | 238345 238346 238347 238348 238349 238350 238351 238352 238353 238354 238355 238356 238357 238358 238359 238360 238361 238362 238363 238364 238365 238366 238367 238368 238369 | int bDesc; /* Iterate in descending rowid order */ int nPhrase; /* Number of phrases in expression */ Fts5ExprPhrase **apExprPhrase; /* Pointers to phrase objects */ }; /* ** eType: ** Expression node type. Usually one of: ** ** FTS5_AND (nChild, apChild valid) ** FTS5_OR (nChild, apChild valid) ** FTS5_NOT (nChild, apChild valid) ** FTS5_STRING (pNear valid) ** FTS5_TERM (pNear valid) ** ** An expression node with eType==0 may also exist. It always matches zero ** rows. This is created when a phrase containing no tokens is parsed. ** e.g. "". ** ** iHeight: ** Distance from this node to furthest leaf. This is always 0 for nodes ** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one ** greater than the largest child value. */ struct Fts5ExprNode { |
︙ | ︙ | |||
236959 236960 236961 236962 236963 236964 236965 236966 236967 236968 236969 | do { t = fts5ExprGetToken(&sParse, &z, &token); sqlite3Fts5Parser(pEngine, t, token, &sParse); }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); sqlite3Fts5ParserFree(pEngine, fts5ParseFree); assert_expr_depth_ok(sParse.rc, sParse.pExpr); /* If the LHS of the MATCH expression was a user column, apply the ** implicit column-filter. */ | > | < < < < < < < | < > | > > > | 238577 238578 238579 238580 238581 238582 238583 238584 238585 238586 238587 238588 238589 238590 238591 238592 238593 238594 238595 238596 238597 238598 238599 238600 238601 238602 238603 238604 238605 238606 238607 238608 238609 238610 238611 238612 238613 238614 238615 238616 238617 238618 238619 238620 238621 238622 238623 238624 238625 238626 238627 238628 238629 238630 | do { t = fts5ExprGetToken(&sParse, &z, &token); sqlite3Fts5Parser(pEngine, t, token, &sParse); }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); sqlite3Fts5ParserFree(pEngine, fts5ParseFree); assert( sParse.pExpr || sParse.rc!=SQLITE_OK ); assert_expr_depth_ok(sParse.rc, sParse.pExpr); /* If the LHS of the MATCH expression was a user column, apply the ** implicit column-filter. */ if( sParse.rc==SQLITE_OK && iCol<pConfig->nCol ){ int n = sizeof(Fts5Colset); Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n); if( pColset ){ pColset->nCol = 1; pColset->aiCol[0] = iCol; sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset); } } 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{ pNew->pRoot = sParse.pExpr; pNew->pIndex = 0; pNew->pConfig = pConfig; pNew->apExprPhrase = sParse.apPhrase; pNew->nPhrase = sParse.nPhrase; pNew->bDesc = 0; sParse.apPhrase = 0; } }else{ sqlite3Fts5ParseNodeFree(sParse.pExpr); } sqlite3_free(sParse.apPhrase); if( 0==*pzErr ){ *pzErr = sParse.zErr; }else{ sqlite3_free(sParse.zErr); } return sParse.rc; } /* ** Assuming that buffer z is at least nByte bytes in size and contains a ** valid utf-8 string, return the number of characters in the string. */ |
︙ | ︙ | |||
237802 237803 237804 237805 237806 237807 237808 | if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){ pNode->bNomatch = 0; pNode->bEof = 1; return rc; } }else{ Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter; | | | 239417 239418 239419 239420 239421 239422 239423 239424 239425 239426 239427 239428 239429 239430 239431 | 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; } } } } |
︙ | ︙ | |||
238324 238325 238326 238327 238328 238329 238330 | Fts5ExprNearset *pNear, /* Existing nearset, or NULL */ Fts5ExprPhrase *pPhrase /* Recently parsed phrase */ ){ const int SZALLOC = 8; Fts5ExprNearset *pRet = 0; if( pParse->rc==SQLITE_OK ){ | < < < | 239939 239940 239941 239942 239943 239944 239945 239946 239947 239948 239949 239950 239951 239952 | Fts5ExprNearset *pNear, /* Existing nearset, or NULL */ Fts5ExprPhrase *pPhrase /* Recently parsed phrase */ ){ const int SZALLOC = 8; Fts5ExprNearset *pRet = 0; if( pParse->rc==SQLITE_OK ){ if( pNear==0 ){ sqlite3_int64 nByte; nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*); pRet = sqlite3_malloc64(nByte); if( pRet==0 ){ pParse->rc = SQLITE_NOMEM; }else{ |
︙ | ︙ | |||
238548 238549 238550 238551 238552 238553 238554 238555 238556 238557 238558 238559 238560 238561 238562 238563 238564 238565 238566 238567 238568 238569 238570 238571 238572 238573 | if( sCtx.pPhrase==0 ){ /* This happens when parsing a token or quoted phrase that contains ** no token characters at all. (e.g ... MATCH '""'). */ sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase)); }else if( sCtx.pPhrase->nTerm ){ sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; } pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase; } return sCtx.pPhrase; } /* ** Create a new FTS5 expression by cloning phrase iPhrase of the ** expression passed as the second argument. */ static int sqlite3Fts5ExprClonePhrase( Fts5Expr *pExpr, int iPhrase, Fts5Expr **ppNew ){ int rc = SQLITE_OK; /* Return code */ Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */ Fts5Expr *pNew = 0; /* Expression to return via *ppNew */ TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */ | > | | 240160 240161 240162 240163 240164 240165 240166 240167 240168 240169 240170 240171 240172 240173 240174 240175 240176 240177 240178 240179 240180 240181 240182 240183 240184 240185 240186 240187 240188 240189 240190 240191 240192 240193 240194 | if( sCtx.pPhrase==0 ){ /* This happens when parsing a token or quoted phrase that contains ** no token characters at all. (e.g ... MATCH '""'). */ sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase)); }else if( sCtx.pPhrase->nTerm ){ sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; } assert( pParse->apPhrase!=0 ); pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase; } return sCtx.pPhrase; } /* ** Create a new FTS5 expression by cloning phrase iPhrase of the ** expression passed as the second argument. */ static int sqlite3Fts5ExprClonePhrase( Fts5Expr *pExpr, int iPhrase, Fts5Expr **ppNew ){ int rc = SQLITE_OK; /* Return code */ Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */ Fts5Expr *pNew = 0; /* Expression to return via *ppNew */ TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */ if( !pExpr || iPhrase<0 || iPhrase>=pExpr->nPhrase ){ rc = SQLITE_RANGE; }else{ pOrig = pExpr->apExprPhrase[iPhrase]; pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr)); } if( rc==SQLITE_OK ){ pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc, |
︙ | ︙ | |||
238935 238936 238937 238938 238939 238940 238941 238942 238943 238944 238945 238946 238947 238948 | default: assert( pNode->eType==FTS5_NOT ); { pNode->xNext = fts5ExprNodeNext_NOT; break; }; } } static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ int ii = p->nChild; 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); | > > > | 240548 240549 240550 240551 240552 240553 240554 240555 240556 240557 240558 240559 240560 240561 240562 240563 240564 | default: assert( pNode->eType==FTS5_NOT ); { pNode->xNext = fts5ExprNodeNext_NOT; break; }; } } /* ** Add pSub as a child of p. */ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ int ii = p->nChild; 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); |
︙ | ︙ | |||
239079 239080 239081 239082 239083 239084 239085 | || pPhrase->nTerm>1 || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst) ){ sqlite3Fts5ParseError(pParse, "fts5: %s queries are not supported (detail!=full)", pNear->nPhrase==1 ? "phrase": "NEAR" ); | | > > > > | | 240695 240696 240697 240698 240699 240700 240701 240702 240703 240704 240705 240706 240707 240708 240709 240710 240711 240712 240713 240714 240715 240716 240717 240718 240719 240720 240721 240722 240723 240724 240725 | || pPhrase->nTerm>1 || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst) ){ sqlite3Fts5ParseError(pParse, "fts5: %s queries are not supported (detail!=full)", pNear->nPhrase==1 ? "phrase": "NEAR" ); sqlite3Fts5ParseNodeFree(pRet); pRet = 0; pNear = 0; assert( pLeft==0 && pRight==0 ); } } }else{ assert( pNear==0 ); fts5ExprAddChildren(pRet, pLeft); fts5ExprAddChildren(pRet, pRight); pLeft = pRight = 0; if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){ sqlite3Fts5ParseError(pParse, "fts5 expression tree is too large (maximum depth %d)", SQLITE_FTS5_MAX_EXPR_DEPTH ); sqlite3Fts5ParseNodeFree(pRet); pRet = 0; } } } } } |
︙ | ︙ | |||
239129 239130 239131 239132 239133 239134 239135 239136 239137 239138 239139 239140 239141 239142 239143 239144 239145 239146 239147 239148 239149 239150 239151 239152 239153 239154 239155 | || pLeft->eType==FTS5_TERM || pLeft->eType==FTS5_EOF || pLeft->eType==FTS5_AND ); assert( pRight->eType==FTS5_STRING || pRight->eType==FTS5_TERM || pRight->eType==FTS5_EOF ); if( pLeft->eType==FTS5_AND ){ pPrev = pLeft->apChild[pLeft->nChild-1]; }else{ pPrev = pLeft; } assert( pPrev->eType==FTS5_STRING || pPrev->eType==FTS5_TERM || pPrev->eType==FTS5_EOF ); if( pRight->eType==FTS5_EOF ){ assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] ); sqlite3Fts5ParseNodeFree(pRight); pRet = pLeft; pParse->nPhrase--; } else if( pPrev->eType==FTS5_EOF ){ Fts5ExprPhrase **ap; | > > > | 240749 240750 240751 240752 240753 240754 240755 240756 240757 240758 240759 240760 240761 240762 240763 240764 240765 240766 240767 240768 240769 240770 240771 240772 240773 240774 240775 240776 240777 240778 | || pLeft->eType==FTS5_TERM || pLeft->eType==FTS5_EOF || pLeft->eType==FTS5_AND ); assert( pRight->eType==FTS5_STRING || pRight->eType==FTS5_TERM || pRight->eType==FTS5_EOF || (pRight->eType==FTS5_AND && pParse->bPhraseToAnd) ); if( pLeft->eType==FTS5_AND ){ pPrev = pLeft->apChild[pLeft->nChild-1]; }else{ pPrev = pLeft; } assert( pPrev->eType==FTS5_STRING || pPrev->eType==FTS5_TERM || pPrev->eType==FTS5_EOF ); if( pRight->eType==FTS5_EOF ){ assert( pParse->apPhrase!=0 ); assert( pParse->nPhrase>0 ); assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] ); sqlite3Fts5ParseNodeFree(pRight); pRet = pLeft; pParse->nPhrase--; } else if( pPrev->eType==FTS5_EOF ){ Fts5ExprPhrase **ap; |
︙ | ︙ | |||
239774 239775 239776 239777 239778 239779 239780 239781 239782 239783 239784 239785 239786 239787 | } } static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){ pNode->iRowid = iRowid; pNode->bEof = 0; switch( pNode->eType ){ case FTS5_TERM: case FTS5_STRING: return (pNode->pNear->apPhrase[0]->poslist.n>0); case FTS5_AND: { int i; for(i=0; i<pNode->nChild; i++){ | > | 241397 241398 241399 241400 241401 241402 241403 241404 241405 241406 241407 241408 241409 241410 241411 | } } static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){ pNode->iRowid = iRowid; pNode->bEof = 0; switch( pNode->eType ){ case 0: case FTS5_TERM: case FTS5_STRING: return (pNode->pNear->apPhrase[0]->poslist.n>0); case FTS5_AND: { int i; for(i=0; i<pNode->nChild; i++){ |
︙ | ︙ | |||
241357 241358 241359 241360 241361 241362 241363 | ** table, missing row, non-blob/text in block column - indicate ** backing store corruption. */ if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT; if( rc==SQLITE_OK ){ u8 *aOut = 0; /* Read blob data into this buffer */ int nByte = sqlite3_blob_bytes(p->pReader); | > | | | 242981 242982 242983 242984 242985 242986 242987 242988 242989 242990 242991 242992 242993 242994 242995 242996 242997 242998 242999 243000 | ** table, missing row, non-blob/text in block column - indicate ** backing store corruption. */ if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT; if( rc==SQLITE_OK ){ u8 *aOut = 0; /* Read blob data into this buffer */ int nByte = sqlite3_blob_bytes(p->pReader); int szData = (sizeof(Fts5Data) + 7) & ~7; sqlite3_int64 nAlloc = szData + nByte + FTS5_DATA_PADDING; pRet = (Fts5Data*)sqlite3_malloc64(nAlloc); if( pRet ){ pRet->nn = nByte; aOut = pRet->p = (u8*)pRet + szData; }else{ rc = SQLITE_NOMEM; } if( rc==SQLITE_OK ){ rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0); } |
︙ | ︙ | |||
241384 241385 241386 241387 241388 241389 241390 241391 241392 241393 241394 241395 241396 241397 | } } p->rc = rc; p->nRead++; } assert( (pRet==0)==(p->rc!=SQLITE_OK) ); return pRet; } /* ** Release a reference to data record returned by an earlier call to ** fts5DataRead(). | > | 243009 243010 243011 243012 243013 243014 243015 243016 243017 243018 243019 243020 243021 243022 243023 | } } p->rc = rc; p->nRead++; } assert( (pRet==0)==(p->rc!=SQLITE_OK) ); assert( pRet==0 || EIGHT_BYTE_ALIGNMENT( pRet->p ) ); return pRet; } /* ** Release a reference to data record returned by an earlier call to ** fts5DataRead(). |
︙ | ︙ | |||
242709 242710 242711 242712 242713 242714 242715 | if( p->rc || pIter->pLeaf==0 ) return; pIter->iRowid = 0; iOff = 4; } if( iOff<pIter->iEndofDoclist ){ /* Next entry is on the current page */ | | | 244335 244336 244337 244338 244339 244340 244341 244342 244343 244344 244345 244346 244347 244348 244349 | if( p->rc || pIter->pLeaf==0 ) return; pIter->iRowid = 0; iOff = 4; } if( iOff<pIter->iEndofDoclist ){ /* Next entry is on the current page */ u64 iDelta; iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta); pIter->iLeafOffset = iOff; pIter->iRowid += iDelta; }else if( (pIter->flags & FTS5_SEGITER_ONETERM)==0 ){ if( pIter->pSeg ){ int nKeep = 0; if( iOff!=fts5LeafFirstTermOff(pIter->pLeaf) ){ |
︙ | ︙ | |||
249679 249680 249681 249682 249683 249684 249685 249686 249687 249688 249689 249690 249691 249692 249693 249694 249695 249696 249697 249698 249699 249700 249701 249702 249703 249704 249705 249706 249707 249708 249709 | fts5_api api; /* User visible part of object (see fts5.h) */ sqlite3 *db; /* Associated database connection */ i64 iNextId; /* Used to allocate unique cursor ids */ Fts5Auxiliary *pAux; /* First in list of all aux. functions */ Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */ Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */ Fts5Cursor *pCsr; /* First in list of all open cursors */ }; /* ** Each auxiliary function registered with the FTS5 module is represented ** by an object of the following type. All such objects are stored as part ** of the Fts5Global.pAux list. */ struct Fts5Auxiliary { Fts5Global *pGlobal; /* Global context for this function */ char *zFunc; /* Function name (nul-terminated) */ void *pUserData; /* User-data pointer */ fts5_extension_function xFunc; /* Callback function */ void (*xDestroy)(void*); /* Destructor function */ Fts5Auxiliary *pNext; /* Next registered auxiliary function */ }; /* ** Each tokenizer module registered with the FTS5 module is represented ** by an object of the following type. All such objects are stored as part ** of the Fts5Global.pTok list. */ struct Fts5TokenizerModule { char *zName; /* Name of tokenizer */ void *pUserData; /* User pointer passed to xCreate() */ | > > > > > > > > > > > > > > > > > > > > > > > > > | > | 251305 251306 251307 251308 251309 251310 251311 251312 251313 251314 251315 251316 251317 251318 251319 251320 251321 251322 251323 251324 251325 251326 251327 251328 251329 251330 251331 251332 251333 251334 251335 251336 251337 251338 251339 251340 251341 251342 251343 251344 251345 251346 251347 251348 251349 251350 251351 251352 251353 251354 251355 251356 251357 251358 251359 251360 251361 251362 251363 251364 251365 251366 251367 251368 251369 | fts5_api api; /* User visible part of object (see fts5.h) */ sqlite3 *db; /* Associated database connection */ i64 iNextId; /* Used to allocate unique cursor ids */ Fts5Auxiliary *pAux; /* First in list of all aux. functions */ Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */ Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */ Fts5Cursor *pCsr; /* First in list of all open cursors */ u32 aLocaleHdr[4]; }; /* ** Size of header on fts5_locale() values. And macro to access a buffer ** containing a copy of the header from an Fts5Config pointer. */ #define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr )) #define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr)) /* ** Each auxiliary function registered with the FTS5 module is represented ** by an object of the following type. All such objects are stored as part ** of the Fts5Global.pAux list. */ struct Fts5Auxiliary { Fts5Global *pGlobal; /* Global context for this function */ char *zFunc; /* Function name (nul-terminated) */ void *pUserData; /* User-data pointer */ fts5_extension_function xFunc; /* Callback function */ void (*xDestroy)(void*); /* Destructor function */ Fts5Auxiliary *pNext; /* Next registered auxiliary function */ }; /* ** Each tokenizer module registered with the FTS5 module is represented ** by an object of the following type. All such objects are stored as part ** of the Fts5Global.pTok list. ** ** bV2Native: ** True if the tokenizer was registered using xCreateTokenizer_v2(), false ** for xCreateTokenizer(). If this variable is true, then x2 is populated ** with the routines as supplied by the caller and x1 contains synthesized ** wrapper routines. In this case the user-data pointer passed to ** x1.xCreate should be a pointer to the Fts5TokenizerModule structure, ** not a copy of pUserData. ** ** Of course, if bV2Native is false, then x1 contains the real routines and ** x2 the synthesized ones. In this case a pointer to the Fts5TokenizerModule ** object should be passed to x2.xCreate. ** ** The synthesized wrapper routines are necessary for xFindTokenizer(_v2) ** calls. */ struct Fts5TokenizerModule { char *zName; /* Name of tokenizer */ void *pUserData; /* User pointer passed to xCreate() */ int bV2Native; /* True if v2 native tokenizer */ fts5_tokenizer x1; /* Tokenizer functions */ fts5_tokenizer_v2 x2; /* V2 tokenizer functions */ void (*xDestroy)(void*); /* Destructor function */ Fts5TokenizerModule *pNext; /* Next registered tokenizer module */ }; struct Fts5FullTable { Fts5Table p; /* Public class members from fts5Int.h */ Fts5Storage *pStorage; /* Document store */ |
︙ | ︙ | |||
249791 249792 249793 249794 249795 249796 249797 | sqlite3_value **apRankArg; /* Array of trailing arguments */ sqlite3_stmt *pRankArgStmt; /* Origin of objects in apRankArg[] */ /* Auxiliary data storage */ Fts5Auxiliary *pAux; /* Currently executing extension function */ Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */ | | | 251443 251444 251445 251446 251447 251448 251449 251450 251451 251452 251453 251454 251455 251456 251457 | sqlite3_value **apRankArg; /* Array of trailing arguments */ sqlite3_stmt *pRankArgStmt; /* Origin of objects in apRankArg[] */ /* Auxiliary data storage */ Fts5Auxiliary *pAux; /* Currently executing extension function */ Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */ /* Cache used by auxiliary API functions xInst() and xInstCount() */ Fts5PoslistReader *aInstIter; /* One for each phrase */ int nInstAlloc; /* Size of aInst[] array (entries / 3) */ int nInstCount; /* Number of phrase instances */ int *aInst; /* 3 integers per phrase instance */ }; /* |
︙ | ︙ | |||
249973 249974 249975 249976 249977 249978 249979 249980 249981 249982 249983 249984 249985 249986 249987 249988 | /* Allocate the new vtab object and parse the configuration */ pTab = (Fts5FullTable*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5FullTable)); if( rc==SQLITE_OK ){ rc = sqlite3Fts5ConfigParse(pGlobal, db, argc, azConfig, &pConfig, pzErr); assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 ); } if( rc==SQLITE_OK ){ pTab->p.pConfig = pConfig; pTab->pGlobal = pGlobal; } /* Open the index sub-system */ if( rc==SQLITE_OK ){ rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->p.pIndex, pzErr); } | > > > > | 251625 251626 251627 251628 251629 251630 251631 251632 251633 251634 251635 251636 251637 251638 251639 251640 251641 251642 251643 251644 | /* Allocate the new vtab object and parse the configuration */ pTab = (Fts5FullTable*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5FullTable)); if( rc==SQLITE_OK ){ rc = sqlite3Fts5ConfigParse(pGlobal, db, argc, azConfig, &pConfig, pzErr); assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 ); } if( rc==SQLITE_OK ){ pConfig->pzErrmsg = pzErr; pTab->p.pConfig = pConfig; pTab->pGlobal = pGlobal; if( bCreate || sqlite3Fts5TokenizerPreload(&pConfig->t) ){ rc = sqlite3Fts5LoadTokenizer(pConfig); } } /* Open the index sub-system */ if( rc==SQLITE_OK ){ rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->p.pIndex, pzErr); } |
︙ | ︙ | |||
249996 249997 249998 249999 250000 250001 250002 | /* Call sqlite3_declare_vtab() */ if( rc==SQLITE_OK ){ rc = sqlite3Fts5ConfigDeclareVtab(pConfig); } /* Load the initial configuration */ if( rc==SQLITE_OK ){ | < < | < < > | 251652 251653 251654 251655 251656 251657 251658 251659 251660 251661 251662 251663 251664 251665 251666 251667 251668 251669 251670 251671 251672 251673 251674 251675 251676 | /* Call sqlite3_declare_vtab() */ if( rc==SQLITE_OK ){ rc = sqlite3Fts5ConfigDeclareVtab(pConfig); } /* Load the initial configuration */ if( rc==SQLITE_OK ){ rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie-1); } if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ rc = sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, (int)1); } if( rc==SQLITE_OK ){ rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); } if( pConfig ) pConfig->pzErrmsg = 0; if( rc!=SQLITE_OK ){ fts5FreeVtab(pTab); pTab = 0; }else if( bCreate ){ fts5CheckTransactionState(pTab, FTS5_BEGIN, 0); } *ppVTab = (sqlite3_vtab*)pTab; |
︙ | ︙ | |||
250077 250078 250079 250080 250081 250082 250083 | static int fts5UsePatternMatch( Fts5Config *pConfig, struct sqlite3_index_constraint *p ){ assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB ); assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE ); | | | | 251730 251731 251732 251733 251734 251735 251736 251737 251738 251739 251740 251741 251742 251743 251744 251745 251746 251747 | static int fts5UsePatternMatch( Fts5Config *pConfig, struct sqlite3_index_constraint *p ){ assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB ); assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE ); if( pConfig->t.ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){ return 1; } if( pConfig->t.ePattern==FTS5_PATTERN_LIKE && (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB) ){ return 1; } return 0; } |
︙ | ︙ | |||
250127 250128 250129 250130 250131 250132 250133 | ** Equality constraint against the rowid: "=" ** A < or <= against the rowid: "<" ** A > or >= against the rowid: ">" ** ** This function ensures that there is at most one "r" or "=". And that if ** there exists an "=" then there is no "<" or ">". ** | | > < | | 251780 251781 251782 251783 251784 251785 251786 251787 251788 251789 251790 251791 251792 251793 251794 251795 251796 251797 251798 | ** Equality constraint against the rowid: "=" ** A < or <= against the rowid: "<" ** A > or >= against the rowid: ">" ** ** This function ensures that there is at most one "r" or "=". And that if ** there exists an "=" then there is no "<" or ">". ** ** If an unusable MATCH operator is present in the WHERE clause, then ** SQLITE_CONSTRAINT is returned. ** ** Costs are assigned as follows: ** ** a) If a MATCH operator is present, the cost depends on the other ** constraints also present. As follows: ** ** * No other constraints: cost=1000.0 ** * One rowid range constraint: cost=750.0 ** * Both rowid range constraints: cost=500.0 ** * An == rowid constraint: cost=100.0 |
︙ | ︙ | |||
250163 250164 250165 250166 250167 250168 250169 | char *idxStr; int iIdxStr = 0; int iCons = 0; int bSeenEq = 0; int bSeenGt = 0; int bSeenLt = 0; | | | 251816 251817 251818 251819 251820 251821 251822 251823 251824 251825 251826 251827 251828 251829 251830 | char *idxStr; int iIdxStr = 0; int iCons = 0; int bSeenEq = 0; int bSeenGt = 0; int bSeenLt = 0; int nSeenMatch = 0; int bSeenRank = 0; assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH ); assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH ); assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH ); assert( SQLITE_INDEX_CONSTRAINT_GE<SQLITE_INDEX_CONSTRAINT_MATCH ); |
︙ | ︙ | |||
250194 250195 250196 250197 250198 250199 250200 | int iCol = p->iColumn; if( p->op==SQLITE_INDEX_CONSTRAINT_MATCH || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol>=nCol) ){ /* A MATCH operator or equivalent */ if( p->usable==0 || iCol<0 ){ /* As there exists an unusable MATCH constraint this is an | | < < < | | | > | 251847 251848 251849 251850 251851 251852 251853 251854 251855 251856 251857 251858 251859 251860 251861 251862 251863 251864 251865 251866 251867 251868 251869 251870 251871 251872 251873 251874 251875 251876 251877 251878 251879 251880 251881 251882 251883 251884 251885 251886 | int iCol = p->iColumn; if( p->op==SQLITE_INDEX_CONSTRAINT_MATCH || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol>=nCol) ){ /* A MATCH operator or equivalent */ if( p->usable==0 || iCol<0 ){ /* As there exists an unusable MATCH constraint this is an ** unusable plan. Return SQLITE_CONSTRAINT. */ return SQLITE_CONSTRAINT; }else{ if( iCol==nCol+1 ){ if( bSeenRank ) continue; idxStr[iIdxStr++] = 'r'; bSeenRank = 1; }else{ nSeenMatch++; idxStr[iIdxStr++] = 'M'; sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol); idxStr += strlen(&idxStr[iIdxStr]); assert( idxStr[iIdxStr]=='\0' ); } pInfo->aConstraintUsage[i].argvIndex = ++iCons; pInfo->aConstraintUsage[i].omit = 1; } }else if( p->usable ){ if( iCol>=0 && iCol<nCol && fts5UsePatternMatch(pConfig, p) ){ assert( p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB ); idxStr[iIdxStr++] = p->op==FTS5_PATTERN_LIKE ? 'L' : 'G'; sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol); idxStr += strlen(&idxStr[iIdxStr]); pInfo->aConstraintUsage[i].argvIndex = ++iCons; assert( idxStr[iIdxStr]=='\0' ); nSeenMatch++; }else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){ idxStr[iIdxStr++] = '='; bSeenEq = 1; pInfo->aConstraintUsage[i].argvIndex = ++iCons; } } } |
︙ | ︙ | |||
250258 250259 250260 250261 250262 250263 250264 | /* Set idxFlags flags for the ORDER BY clause ** ** Note that tokendata=1 tables cannot currently handle "ORDER BY rowid DESC". */ if( pInfo->nOrderBy==1 ){ int iSort = pInfo->aOrderBy[0].iColumn; | | | | | | > > > | | 251909 251910 251911 251912 251913 251914 251915 251916 251917 251918 251919 251920 251921 251922 251923 251924 251925 251926 251927 251928 251929 251930 251931 251932 251933 251934 251935 251936 251937 251938 251939 251940 251941 251942 251943 251944 251945 251946 251947 251948 | /* Set idxFlags flags for the ORDER BY clause ** ** Note that tokendata=1 tables cannot currently handle "ORDER BY rowid DESC". */ if( pInfo->nOrderBy==1 ){ int iSort = pInfo->aOrderBy[0].iColumn; if( iSort==(pConfig->nCol+1) && nSeenMatch>0 ){ idxFlags |= FTS5_BI_ORDER_RANK; }else if( iSort==-1 && (!pInfo->aOrderBy[0].desc || !pConfig->bTokendata) ){ idxFlags |= FTS5_BI_ORDER_ROWID; } if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){ pInfo->orderByConsumed = 1; if( pInfo->aOrderBy[0].desc ){ idxFlags |= FTS5_BI_ORDER_DESC; } } } /* Calculate the estimated cost based on the flags set in idxFlags. */ if( bSeenEq ){ pInfo->estimatedCost = nSeenMatch ? 1000.0 : 10.0; if( nSeenMatch==0 ) fts5SetUniqueFlag(pInfo); }else if( bSeenLt && bSeenGt ){ pInfo->estimatedCost = nSeenMatch ? 5000.0 : 250000.0; }else if( bSeenLt || bSeenGt ){ pInfo->estimatedCost = nSeenMatch ? 7500.0 : 750000.0; }else{ pInfo->estimatedCost = nSeenMatch ? 10000.0 : 1000000.0; } for(i=1; i<nSeenMatch; i++){ pInfo->estimatedCost *= 0.4; } pInfo->idxNum = idxFlags; return SQLITE_OK; } static int fts5NewTransaction(Fts5FullTable *pTab){ |
︙ | ︙ | |||
250556 250557 250558 250559 250560 250561 250562 250563 250564 250565 250566 250567 250568 250569 | if( rc!=SQLITE_OK ){ pCursor->pVtab->zErrMsg = sqlite3_mprintf( "%s", sqlite3_errmsg(pConfig->db) ); } }else{ rc = SQLITE_OK; } break; } } } return rc; | > | 252210 252211 252212 252213 252214 252215 252216 252217 252218 252219 252220 252221 252222 252223 252224 | if( rc!=SQLITE_OK ){ pCursor->pVtab->zErrMsg = sqlite3_mprintf( "%s", sqlite3_errmsg(pConfig->db) ); } }else{ rc = SQLITE_OK; CsrFlagSet(pCsr, FTS5CSR_REQUIRE_DOCSIZE); } break; } } } return rc; |
︙ | ︙ | |||
250585 250586 250587 250588 250589 250590 250591 | zSql = sqlite3_vmprintf(zFmt, ap); if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ rc = sqlite3_prepare_v3(pConfig->db, zSql, -1, SQLITE_PREPARE_PERSISTENT, &pRet, 0); if( rc!=SQLITE_OK ){ | | | 252240 252241 252242 252243 252244 252245 252246 252247 252248 252249 252250 252251 252252 252253 252254 | zSql = sqlite3_vmprintf(zFmt, ap); if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ rc = sqlite3_prepare_v3(pConfig->db, zSql, -1, SQLITE_PREPARE_PERSISTENT, &pRet, 0); if( rc!=SQLITE_OK ){ sqlite3Fts5ConfigErrmsg(pConfig, "%s", sqlite3_errmsg(pConfig->db)); } sqlite3_free(zSql); } va_end(ap); *ppStmt = pRet; return rc; |
︙ | ︙ | |||
250808 250809 250810 250811 250812 250813 250814 250815 250816 250817 250818 250819 250820 250821 | int eType = sqlite3_value_numeric_type(pVal); if( eType==SQLITE_INTEGER ){ return sqlite3_value_int64(pVal); } } return iDefault; } /* ** This is the xFilter interface for the virtual table. See ** the virtual table xFilter method documentation for additional ** information. ** ** There are three possible query strategies: | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 252463 252464 252465 252466 252467 252468 252469 252470 252471 252472 252473 252474 252475 252476 252477 252478 252479 252480 252481 252482 252483 252484 252485 252486 252487 252488 252489 252490 252491 252492 252493 252494 252495 252496 252497 252498 252499 252500 252501 252502 252503 252504 252505 252506 252507 252508 252509 252510 252511 252512 252513 252514 252515 252516 252517 252518 252519 252520 252521 252522 252523 252524 252525 252526 252527 252528 252529 252530 252531 252532 252533 252534 252535 252536 252537 252538 252539 252540 252541 252542 252543 252544 252545 252546 252547 252548 252549 252550 252551 252552 252553 252554 252555 252556 252557 252558 252559 252560 252561 252562 252563 252564 252565 252566 252567 252568 252569 252570 252571 252572 252573 252574 252575 252576 252577 252578 252579 252580 252581 252582 252583 252584 252585 252586 252587 252588 252589 252590 252591 252592 252593 252594 252595 252596 252597 252598 252599 252600 252601 252602 252603 252604 252605 252606 252607 252608 252609 252610 252611 252612 252613 252614 252615 | int eType = sqlite3_value_numeric_type(pVal); if( eType==SQLITE_INTEGER ){ return sqlite3_value_int64(pVal); } } return iDefault; } /* ** Set the error message on the virtual table passed as the first argument. */ static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ va_list ap; /* ... printf arguments */ va_start(ap, zFormat); sqlite3_free(p->p.base.zErrMsg); p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap); va_end(ap); } /* ** Arrange for subsequent calls to sqlite3Fts5Tokenize() to use the locale ** specified by pLocale/nLocale. The buffer indicated by pLocale must remain ** valid until after the final call to sqlite3Fts5Tokenize() that will use ** the locale. */ static void sqlite3Fts5SetLocale( Fts5Config *pConfig, const char *zLocale, int nLocale ){ Fts5TokenizerConfig *pT = &pConfig->t; pT->pLocale = zLocale; pT->nLocale = nLocale; } /* ** Clear any locale configured by an earlier call to sqlite3Fts5SetLocale(). */ static void sqlite3Fts5ClearLocale(Fts5Config *pConfig){ sqlite3Fts5SetLocale(pConfig, 0, 0); } /* ** Return true if the value passed as the only argument is an ** fts5_locale() value. */ static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal){ int ret = 0; if( sqlite3_value_type(pVal)==SQLITE_BLOB ){ /* Call sqlite3_value_bytes() after sqlite3_value_blob() in this case. ** If the blob was created using zeroblob(), then sqlite3_value_blob() ** may call malloc(). If this malloc() fails, then the values returned ** by both value_blob() and value_bytes() will be 0. If value_bytes() were ** called first, then the NULL pointer returned by value_blob() might ** be dereferenced. */ const u8 *pBlob = sqlite3_value_blob(pVal); int nBlob = sqlite3_value_bytes(pVal); if( nBlob>FTS5_LOCALE_HDR_SIZE && 0==memcmp(pBlob, FTS5_LOCALE_HDR(pConfig), FTS5_LOCALE_HDR_SIZE) ){ ret = 1; } } return ret; } /* ** Value pVal is guaranteed to be an fts5_locale() value, according to ** sqlite3Fts5IsLocaleValue(). This function extracts the text and locale ** from the value and returns them separately. ** ** If successful, SQLITE_OK is returned and (*ppText) and (*ppLoc) set ** to point to buffers containing the text and locale, as utf-8, ** respectively. In this case output parameters (*pnText) and (*pnLoc) are ** set to the sizes in bytes of these two buffers. ** ** Or, if an error occurs, then an SQLite error code is returned. The final ** value of the four output parameters is undefined in this case. */ static int sqlite3Fts5DecodeLocaleValue( sqlite3_value *pVal, const char **ppText, int *pnText, const char **ppLoc, int *pnLoc ){ const char *p = sqlite3_value_blob(pVal); int n = sqlite3_value_bytes(pVal); int nLoc = 0; assert( sqlite3_value_type(pVal)==SQLITE_BLOB ); assert( n>FTS5_LOCALE_HDR_SIZE ); for(nLoc=FTS5_LOCALE_HDR_SIZE; p[nLoc]; nLoc++){ if( nLoc==(n-1) ){ return SQLITE_MISMATCH; } } *ppLoc = &p[FTS5_LOCALE_HDR_SIZE]; *pnLoc = nLoc - FTS5_LOCALE_HDR_SIZE; *ppText = &p[nLoc+1]; *pnText = n - nLoc - 1; return SQLITE_OK; } /* ** Argument pVal is the text of a full-text search expression. It may or ** may not have been wrapped by fts5_locale(). This function extracts ** the text of the expression, and sets output variable (*pzText) to ** point to a nul-terminated buffer containing the expression. ** ** If pVal was an fts5_locale() value, then sqlite3Fts5SetLocale() is called ** to set the tokenizer to use the specified locale. ** ** If output variable (*pbFreeAndReset) is set to true, then the caller ** is required to (a) call sqlite3Fts5ClearLocale() to reset the tokenizer ** locale, and (b) call sqlite3_free() to free (*pzText). */ static int fts5ExtractExprText( Fts5Config *pConfig, /* Fts5 configuration */ sqlite3_value *pVal, /* Value to extract expression text from */ char **pzText, /* OUT: nul-terminated buffer of text */ int *pbFreeAndReset /* OUT: Free (*pzText) and clear locale */ ){ int rc = SQLITE_OK; if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ const char *pText = 0; int nText = 0; const char *pLoc = 0; int nLoc = 0; rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); *pzText = sqlite3Fts5Mprintf(&rc, "%.*s", nText, pText); if( rc==SQLITE_OK ){ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); } *pbFreeAndReset = 1; }else{ *pzText = (char*)sqlite3_value_text(pVal); *pbFreeAndReset = 0; } return rc; } /* ** This is the xFilter interface for the virtual table. See ** the virtual table xFilter method documentation for additional ** information. ** ** There are three possible query strategies: |
︙ | ︙ | |||
250843 250844 250845 250846 250847 250848 250849 | sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */ int iCol; /* Column on LHS of MATCH operator */ char **pzErrmsg = pConfig->pzErrmsg; int i; int iIdxStr = 0; Fts5Expr *pExpr = 0; | | < < < < < < | 252637 252638 252639 252640 252641 252642 252643 252644 252645 252646 252647 252648 252649 252650 252651 | sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */ int iCol; /* Column on LHS of MATCH operator */ char **pzErrmsg = pConfig->pzErrmsg; int i; int iIdxStr = 0; Fts5Expr *pExpr = 0; assert( pConfig->bLock==0 ); if( pCsr->ePlan ){ fts5FreeCursorComponents(pCsr); memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr)); } assert( pCsr->pStmt==0 ); assert( pCsr->pExpr==0 ); |
︙ | ︙ | |||
250873 250874 250875 250876 250877 250878 250879 | /* Decode the arguments passed through to this function. */ for(i=0; i<nVal; i++){ switch( idxStr[iIdxStr++] ){ case 'r': pRank = apVal[i]; break; case 'M': { | | > > > > > > | > | > > > > > | 252661 252662 252663 252664 252665 252666 252667 252668 252669 252670 252671 252672 252673 252674 252675 252676 252677 252678 252679 252680 252681 252682 252683 252684 252685 252686 252687 252688 252689 252690 252691 252692 252693 252694 252695 252696 252697 252698 252699 252700 252701 252702 252703 252704 252705 252706 252707 252708 252709 252710 | /* Decode the arguments passed through to this function. */ for(i=0; i<nVal; i++){ switch( idxStr[iIdxStr++] ){ case 'r': pRank = apVal[i]; break; case 'M': { char *zText = 0; int bFreeAndReset = 0; int bInternal = 0; rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset); if( rc!=SQLITE_OK ) goto filter_out; if( zText==0 ) zText = ""; iCol = 0; do{ iCol = iCol*10 + (idxStr[iIdxStr]-'0'); iIdxStr++; }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ); if( zText[0]=='*' ){ /* The user has issued a query of the form "MATCH '*...'". This ** indicates that the MATCH expression is not a full text query, ** but a request for an internal parameter. */ rc = fts5SpecialMatch(pTab, pCsr, &zText[1]); bInternal = 1; }else{ char **pzErr = &pTab->p.base.zErrMsg; rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr); if( rc==SQLITE_OK ){ rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); pExpr = 0; } } if( bFreeAndReset ){ sqlite3_free(zText); sqlite3Fts5ClearLocale(pConfig); } if( bInternal || rc!=SQLITE_OK ) goto filter_out; break; } case 'L': case 'G': { int bGlob = (idxStr[iIdxStr-1]=='G'); const char *zText = (const char*)sqlite3_value_text(apVal[i]); iCol = 0; |
︙ | ︙ | |||
250984 250985 250986 250987 250988 250989 250990 | rc = fts5CursorFirstSorted(pTab, pCsr, bDesc); }else{ pCsr->ePlan = FTS5_PLAN_MATCH; rc = fts5CursorFirst(pTab, pCsr, bDesc); } } }else if( pConfig->zContent==0 ){ | < | < | 252784 252785 252786 252787 252788 252789 252790 252791 252792 252793 252794 252795 252796 252797 252798 | rc = fts5CursorFirstSorted(pTab, pCsr, bDesc); }else{ pCsr->ePlan = FTS5_PLAN_MATCH; rc = fts5CursorFirst(pTab, pCsr, bDesc); } } }else if( pConfig->zContent==0 ){ fts5SetVtabError(pTab,"%s: table does not support scanning",pConfig->zName); rc = SQLITE_ERROR; }else{ /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup ** by rowid (ePlan==FTS5_PLAN_ROWID). */ pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN); rc = sqlite3Fts5StorageStmt( pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg |
︙ | ︙ | |||
251029 251030 251031 251032 251033 251034 251035 251036 251037 251038 251039 251040 251041 251042 251043 251044 251045 251046 251047 251048 251049 251050 251051 251052 251053 251054 | /* ** Return the rowid that the cursor currently points to. */ static i64 fts5CursorRowid(Fts5Cursor *pCsr){ assert( pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE ); if( pCsr->pSorter ){ return pCsr->pSorter->iRowid; }else{ return sqlite3Fts5ExprRowid(pCsr->pExpr); } } /* ** This is the xRowid method. The SQLite core calls this routine to ** retrieve the rowid for the current row of the result set. fts5 ** exposes %_content.rowid as the rowid for the virtual table. The ** rowid should be written to *pRowid. */ static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; int ePlan = pCsr->ePlan; assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 ); | > > > > < | | < | < < < | < < < < < > | 252827 252828 252829 252830 252831 252832 252833 252834 252835 252836 252837 252838 252839 252840 252841 252842 252843 252844 252845 252846 252847 252848 252849 252850 252851 252852 252853 252854 252855 252856 252857 252858 252859 252860 252861 252862 252863 252864 252865 252866 252867 252868 252869 252870 252871 252872 | /* ** Return the rowid that the cursor currently points to. */ static i64 fts5CursorRowid(Fts5Cursor *pCsr){ assert( pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE || pCsr->ePlan==FTS5_PLAN_SCAN || pCsr->ePlan==FTS5_PLAN_ROWID ); if( pCsr->pSorter ){ return pCsr->pSorter->iRowid; }else if( pCsr->ePlan>=FTS5_PLAN_SCAN ){ return sqlite3_column_int64(pCsr->pStmt, 0); }else{ return sqlite3Fts5ExprRowid(pCsr->pExpr); } } /* ** This is the xRowid method. The SQLite core calls this routine to ** retrieve the rowid for the current row of the result set. fts5 ** exposes %_content.rowid as the rowid for the virtual table. The ** rowid should be written to *pRowid. */ static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; int ePlan = pCsr->ePlan; assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 ); if( ePlan==FTS5_PLAN_SPECIAL ){ *pRowid = 0; }else{ *pRowid = fts5CursorRowid(pCsr); } return SQLITE_OK; } /* ** If the cursor requires seeking (bSeekRequired flag is set), seek it. ** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise. ** ** If argument bErrormsg is true and an error occurs, an error message may ** be left in sqlite3_vtab.zErrMsg. |
︙ | ︙ | |||
251103 251104 251105 251106 251107 251108 251109 251110 | if( rc==SQLITE_ROW ){ rc = SQLITE_OK; CsrFlagClear(pCsr, FTS5CSR_REQUIRE_CONTENT); }else{ rc = sqlite3_reset(pCsr->pStmt); if( rc==SQLITE_OK ){ rc = FTS5_CORRUPT; }else if( pTab->pConfig->pzErrmsg ){ | > > > > > | < < < < < < < < | 252896 252897 252898 252899 252900 252901 252902 252903 252904 252905 252906 252907 252908 252909 252910 252911 252912 252913 252914 252915 252916 252917 252918 252919 252920 252921 252922 252923 252924 | if( rc==SQLITE_ROW ){ rc = SQLITE_OK; CsrFlagClear(pCsr, FTS5CSR_REQUIRE_CONTENT); }else{ rc = sqlite3_reset(pCsr->pStmt); if( rc==SQLITE_OK ){ rc = FTS5_CORRUPT; fts5SetVtabError((Fts5FullTable*)pTab, "fts5: missing row %lld from content table %s", fts5CursorRowid(pCsr), pTab->pConfig->zContent ); }else if( pTab->pConfig->pzErrmsg ){ fts5SetVtabError((Fts5FullTable*)pTab, "%s", sqlite3_errmsg(pTab->pConfig->db) ); } } } return rc; } /* ** This function is called to handle an FTS INSERT command. In other words, ** an INSERT statement of the form: ** ** INSERT INTO fts(fts) VALUES($pCmd) ** INSERT INTO fts(fts, rank) VALUES($pCmd, $pVal) ** |
︙ | ︙ | |||
251214 251215 251216 251217 251218 251219 251220 | Fts5FullTable *pTab, sqlite3_value **apVal ){ int rc = SQLITE_OK; int eType1 = sqlite3_value_type(apVal[1]); if( eType1==SQLITE_INTEGER ){ sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]); | | | 253004 253005 253006 253007 253008 253009 253010 253011 253012 253013 253014 253015 253016 253017 253018 | Fts5FullTable *pTab, sqlite3_value **apVal ){ int rc = SQLITE_OK; int eType1 = sqlite3_value_type(apVal[1]); if( eType1==SQLITE_INTEGER ){ sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]); rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2], 0); } return rc; } static void fts5StorageInsert( int *pRc, Fts5FullTable *pTab, |
︙ | ︙ | |||
251296 251297 251298 251299 251300 251301 251302 251303 251304 251305 251306 251307 251308 251309 | if( pConfig->bContentlessDelete ){ fts5SetVtabError(pTab, "'delete' may not be used with a contentless_delete=1 table" ); rc = SQLITE_ERROR; }else{ rc = fts5SpecialDelete(pTab, apVal); } }else{ rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]); } }else{ /* A regular INSERT, UPDATE or DELETE statement. The trick here is that ** any conflict on the rowid value must be detected before any | > | 253086 253087 253088 253089 253090 253091 253092 253093 253094 253095 253096 253097 253098 253099 253100 | if( pConfig->bContentlessDelete ){ fts5SetVtabError(pTab, "'delete' may not be used with a contentless_delete=1 table" ); rc = SQLITE_ERROR; }else{ rc = fts5SpecialDelete(pTab, apVal); bUpdateOrDelete = 1; } }else{ rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]); } }else{ /* A regular INSERT, UPDATE or DELETE statement. The trick here is that ** any conflict on the rowid value must be detected before any |
︙ | ︙ | |||
251337 251338 251339 251340 251341 251342 251343 | ); rc = SQLITE_ERROR; } /* DELETE */ else if( nArg==1 ){ i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ | | > > | > > > > > | > | | > > | | | > > | | > > | > | | > > > | 253128 253129 253130 253131 253132 253133 253134 253135 253136 253137 253138 253139 253140 253141 253142 253143 253144 253145 253146 253147 253148 253149 253150 253151 253152 253153 253154 253155 253156 253157 253158 253159 253160 253161 253162 253163 253164 253165 253166 253167 253168 253169 253170 253171 253172 253173 253174 253175 253176 253177 253178 253179 253180 253181 253182 253183 253184 253185 253186 253187 253188 253189 253190 253191 253192 253193 253194 253195 253196 253197 253198 253199 253200 253201 253202 253203 253204 253205 253206 253207 253208 253209 253210 253211 253212 253213 253214 253215 253216 253217 253218 253219 253220 253221 253222 253223 253224 | ); rc = SQLITE_ERROR; } /* DELETE */ else if( nArg==1 ){ i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0); bUpdateOrDelete = 1; } /* INSERT or UPDATE */ else{ int eType1 = sqlite3_value_numeric_type(apVal[1]); /* It is an error to write an fts5_locale() value to a table without ** the locale=1 option. */ if( pConfig->bLocale==0 ){ int ii; for(ii=0; ii<pConfig->nCol; ii++){ sqlite3_value *pVal = apVal[ii+2]; if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ fts5SetVtabError(pTab, "fts5_locale() requires locale=1"); rc = SQLITE_MISMATCH; goto update_out; } } } if( eType0!=SQLITE_INTEGER ){ /* An INSERT statement. If the conflict-mode is REPLACE, first remove ** the current entry (if any). */ if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0); bUpdateOrDelete = 1; } fts5StorageInsert(&rc, pTab, apVal, pRowid); } /* UPDATE */ else{ i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */ i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */ if( eType1!=SQLITE_INTEGER ){ rc = SQLITE_MISMATCH; }else if( iOld!=iNew ){ if( eConflict==SQLITE_REPLACE ){ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0, 1); if( rc==SQLITE_OK ){ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0); } fts5StorageInsert(&rc, pTab, apVal, pRowid); }else{ rc = sqlite3Fts5StorageFindDeleteRow(pTab->pStorage, iOld); if( rc==SQLITE_OK ){ rc = sqlite3Fts5StorageContentInsert(pTab->pStorage,apVal,pRowid); } if( rc==SQLITE_OK ){ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0, 1); } if( rc==SQLITE_OK ){ rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid); } } }else{ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0, 1); fts5StorageInsert(&rc, pTab, apVal, pRowid); } bUpdateOrDelete = 1; sqlite3Fts5StorageReleaseDeleteRow(pTab->pStorage); } } } if( rc==SQLITE_OK && bUpdateOrDelete && pConfig->bSecureDelete && pConfig->iVersion==FTS5_CURRENT_VERSION ){ rc = sqlite3Fts5StorageConfigValue( pTab->pStorage, "version", 0, FTS5_CURRENT_VERSION_SECUREDELETE ); if( rc==SQLITE_OK ){ pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE; } } update_out: pTab->p.pConfig->pzErrmsg = 0; return rc; } /* ** Implementation of xSync() method. */ |
︙ | ︙ | |||
251423 251424 251425 251426 251427 251428 251429 | return rc; } /* ** Implementation of xBegin() method. */ static int fts5BeginMethod(sqlite3_vtab *pVtab){ | > > | < > | | 253232 253233 253234 253235 253236 253237 253238 253239 253240 253241 253242 253243 253244 253245 253246 253247 253248 253249 253250 | return rc; } /* ** Implementation of xBegin() method. */ static int fts5BeginMethod(sqlite3_vtab *pVtab){ int rc = fts5NewTransaction((Fts5FullTable*)pVtab); if( rc==SQLITE_OK ){ fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0); } return rc; } /* ** Implementation of xCommit() method. This is a no-op. The contents of ** the pending-terms hash-table have already been flushed into the database ** by fts5SyncMethod(). */ |
︙ | ︙ | |||
251479 251480 251481 251482 251483 251484 251485 251486 251487 251488 251489 251490 251491 | static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow); } static int fts5ApiTokenize( Fts5Context *pCtx, const char *pText, int nText, void *pUserData, int (*xToken)(void*, int, const char*, int, int, int) ){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < | | > > > > > > > | | | | > > > > > > > > > > | > | > | 253290 253291 253292 253293 253294 253295 253296 253297 253298 253299 253300 253301 253302 253303 253304 253305 253306 253307 253308 253309 253310 253311 253312 253313 253314 253315 253316 253317 253318 253319 253320 253321 253322 253323 253324 253325 253326 253327 253328 253329 253330 253331 253332 253333 253334 253335 253336 253337 253338 253339 253340 253341 253342 253343 253344 253345 253346 253347 253348 253349 253350 253351 253352 253353 253354 253355 253356 253357 253358 253359 253360 253361 253362 253363 253364 253365 253366 253367 253368 253369 253370 253371 253372 253373 253374 253375 253376 253377 253378 253379 253380 253381 253382 253383 253384 253385 253386 253387 253388 253389 253390 253391 253392 253393 253394 253395 253396 253397 253398 253399 253400 253401 253402 253403 253404 253405 253406 253407 253408 253409 253410 253411 253412 253413 253414 253415 253416 253417 253418 253419 253420 253421 253422 253423 253424 253425 253426 253427 253428 253429 253430 253431 253432 253433 253434 253435 253436 253437 253438 253439 253440 253441 253442 253443 253444 253445 253446 253447 253448 253449 253450 253451 253452 253453 253454 253455 253456 253457 253458 253459 253460 253461 253462 253463 | static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow); } /* ** Implementation of xTokenize_v2() API. */ static int fts5ApiTokenize_v2( Fts5Context *pCtx, const char *pText, int nText, const char *pLoc, int nLoc, void *pUserData, int (*xToken)(void*, int, const char*, int, int, int) ){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); int rc = SQLITE_OK; sqlite3Fts5SetLocale(pTab->pConfig, pLoc, nLoc); rc = sqlite3Fts5Tokenize(pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken ); sqlite3Fts5SetLocale(pTab->pConfig, 0, 0); return rc; } /* ** Implementation of xTokenize() API. This is just xTokenize_v2() with NULL/0 ** passed as the locale. */ static int fts5ApiTokenize( Fts5Context *pCtx, const char *pText, int nText, void *pUserData, int (*xToken)(void*, int, const char*, int, int, int) ){ return fts5ApiTokenize_v2(pCtx, pText, nText, 0, 0, pUserData, xToken); } static int fts5ApiPhraseCount(Fts5Context *pCtx){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; return sqlite3Fts5ExprPhraseCount(pCsr->pExpr); } static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase); } /* ** Argument pStmt is an SQL statement of the type used by Fts5Cursor. This ** function extracts the text value of column iCol of the current row. ** Additionally, if there is an associated locale, it invokes ** sqlite3Fts5SetLocale() to configure the tokenizer. In all cases the caller ** should invoke sqlite3Fts5ClearLocale() to clear the locale at some point ** after this function returns. ** ** If successful, (*ppText) is set to point to a buffer containing the text ** value as utf-8 and SQLITE_OK returned. (*pnText) is set to the size of that ** buffer in bytes. It is not guaranteed to be nul-terminated. If an error ** occurs, an SQLite error code is returned. The final values of the two ** output parameters are undefined in this case. */ static int fts5TextFromStmt( Fts5Config *pConfig, sqlite3_stmt *pStmt, int iCol, const char **ppText, int *pnText ){ sqlite3_value *pVal = sqlite3_column_value(pStmt, iCol+1); const char *pLoc = 0; int nLoc = 0; int rc = SQLITE_OK; if( pConfig->bLocale && pConfig->eContent==FTS5_CONTENT_EXTERNAL && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ rc = sqlite3Fts5DecodeLocaleValue(pVal, ppText, pnText, &pLoc, &nLoc); }else{ *ppText = (const char*)sqlite3_value_text(pVal); *pnText = sqlite3_value_bytes(pVal); if( pConfig->bLocale && pConfig->eContent==FTS5_CONTENT_NORMAL ){ pLoc = (const char*)sqlite3_column_text(pStmt, iCol+1+pConfig->nCol); nLoc = sqlite3_column_bytes(pStmt, iCol+1+pConfig->nCol); } } sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); return rc; } static int fts5ApiColumnText( Fts5Context *pCtx, int iCol, const char **pz, int *pn ){ int rc = SQLITE_OK; Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); if( iCol<0 || iCol>=pTab->pConfig->nCol ){ rc = SQLITE_RANGE; }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) ){ *pz = 0; *pn = 0; }else{ rc = fts5SeekCursor(pCsr, 0); if( rc==SQLITE_OK ){ rc = fts5TextFromStmt(pTab->pConfig, pCsr->pStmt, iCol, pz, pn); sqlite3Fts5ClearLocale(pTab->pConfig); } } return rc; } /* ** This is called by various API functions - xInst, xPhraseFirst, ** xPhraseFirstColumn etc. - to obtain the position list for phrase iPhrase ** of the current row. This function works for both detail=full tables (in ** which case the position-list was read from the fts index) or for other ** detail= modes if the row content is available. */ static int fts5CsrPoslist( Fts5Cursor *pCsr, /* Fts5 cursor object */ int iPhrase, /* Phrase to find position list for */ const u8 **pa, /* OUT: Pointer to position list buffer */ int *pn /* OUT: Size of (*pa) in bytes */ ){ Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig; int rc = SQLITE_OK; int bLive = (pCsr->pSorter==0); if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){ rc = SQLITE_RANGE; }else if( pConfig->eDetail!=FTS5_DETAIL_FULL && pConfig->eContent==FTS5_CONTENT_NONE ){ *pa = 0; *pn = 0; return SQLITE_OK; }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){ if( pConfig->eDetail!=FTS5_DETAIL_FULL ){ Fts5PoslistPopulator *aPopulator; int i; aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive); if( aPopulator==0 ) rc = SQLITE_NOMEM; if( rc==SQLITE_OK ){ rc = fts5SeekCursor(pCsr, 0); } for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){ const char *z = 0; int n = 0; rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n); if( rc==SQLITE_OK ){ rc = sqlite3Fts5ExprPopulatePoslists( pConfig, pCsr->pExpr, aPopulator, i, z, n ); } sqlite3Fts5ClearLocale(pConfig); } sqlite3_free(aPopulator); if( pCsr->pSorter ){ sqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid); } } |
︙ | ︙ | |||
251577 251578 251579 251580 251581 251582 251583 | }else{ *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa); } }else{ *pa = 0; *pn = 0; } | < | 253473 253474 253475 253476 253477 253478 253479 253480 253481 253482 253483 253484 253485 253486 | }else{ *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa); } }else{ *pa = 0; *pn = 0; } return rc; } /* ** Ensure that the Fts5Cursor.nInstCount and aInst[] variables are populated ** correctly for the current view. Return SQLITE_OK if successful, or an |
︙ | ︙ | |||
251647 251648 251649 251650 251651 251652 251653 | } } aInst = &pCsr->aInst[3 * (nInst-1)]; aInst[0] = iBest; aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos); aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos); | > | | 253542 253543 253544 253545 253546 253547 253548 253549 253550 253551 253552 253553 253554 253555 253556 253557 | } } aInst = &pCsr->aInst[3 * (nInst-1)]; aInst[0] = iBest; aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos); aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos); assert( aInst[1]>=0 ); if( aInst[1]>=nCol ){ rc = FTS5_CORRUPT; break; } sqlite3Fts5PoslistReaderNext(&aIter[iBest]); } } |
︙ | ︙ | |||
251734 251735 251736 251737 251738 251739 251740 251741 251742 | for(i=0; i<pConfig->nCol; i++){ if( pConfig->abUnindexed[i]==0 ){ pCsr->aColumnSize[i] = -1; } } }else{ int i; for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){ if( pConfig->abUnindexed[i]==0 ){ | > | | | | | > | 253630 253631 253632 253633 253634 253635 253636 253637 253638 253639 253640 253641 253642 253643 253644 253645 253646 253647 253648 253649 253650 253651 253652 253653 253654 253655 253656 | for(i=0; i<pConfig->nCol; i++){ if( pConfig->abUnindexed[i]==0 ){ pCsr->aColumnSize[i] = -1; } } }else{ int i; rc = fts5SeekCursor(pCsr, 0); for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){ if( pConfig->abUnindexed[i]==0 ){ const char *z = 0; int n = 0; pCsr->aColumnSize[i] = 0; rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n); if( rc==SQLITE_OK ){ rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_AUX, z, n, (void*)&pCsr->aColumnSize[i], fts5ColumnSizeCb ); } sqlite3Fts5ClearLocale(pConfig); } } } CsrFlagClear(pCsr, FTS5CSR_REQUIRE_DOCSIZE); } if( iCol<0 ){ int i; |
︙ | ︙ | |||
251824 251825 251826 251827 251828 251829 251830 | } } return pRet; } static void fts5ApiPhraseNext( | | < > > > > | | 253722 253723 253724 253725 253726 253727 253728 253729 253730 253731 253732 253733 253734 253735 253736 253737 253738 253739 253740 253741 253742 253743 253744 253745 253746 253747 253748 253749 253750 253751 253752 | } } return pRet; } static void fts5ApiPhraseNext( Fts5Context *pCtx, Fts5PhraseIter *pIter, int *piCol, int *piOff ){ if( pIter->a>=pIter->b ){ *piCol = -1; *piOff = -1; }else{ int iVal; pIter->a += fts5GetVarint32(pIter->a, iVal); if( iVal==1 ){ /* Avoid returning a (*piCol) value that is too large for the table, ** even if the position-list is corrupt. The caller might not be ** expecting it. */ int nCol = ((Fts5Table*)(((Fts5Cursor*)pCtx)->base.pVtab))->pConfig->nCol; pIter->a += fts5GetVarint32(pIter->a, iVal); *piCol = (iVal>=nCol ? nCol-1 : iVal); *piOff = 0; pIter->a += fts5GetVarint32(pIter->a, iVal); } *piOff += (iVal-2); } } |
︙ | ︙ | |||
251986 251987 251988 251989 251990 251991 251992 251993 251994 | return rc; } static int fts5ApiQueryPhrase(Fts5Context*, int, void*, int(*)(const Fts5ExtensionApi*, Fts5Context*, void*) ); static const Fts5ExtensionApi sFts5Api = { | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > | 253887 253888 253889 253890 253891 253892 253893 253894 253895 253896 253897 253898 253899 253900 253901 253902 253903 253904 253905 253906 253907 253908 253909 253910 253911 253912 253913 253914 253915 253916 253917 253918 253919 253920 253921 253922 253923 253924 253925 253926 253927 253928 253929 253930 253931 253932 253933 253934 253935 253936 253937 253938 253939 253940 253941 253942 253943 253944 253945 253946 253947 253948 253949 253950 253951 253952 253953 253954 253955 253956 253957 253958 253959 253960 253961 253962 253963 253964 253965 253966 | return rc; } static int fts5ApiQueryPhrase(Fts5Context*, int, void*, int(*)(const Fts5ExtensionApi*, Fts5Context*, void*) ); /* ** The xColumnLocale() API. */ static int fts5ApiColumnLocale( Fts5Context *pCtx, int iCol, const char **pzLocale, int *pnLocale ){ int rc = SQLITE_OK; Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig; *pzLocale = 0; *pnLocale = 0; assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); if( iCol<0 || iCol>=pConfig->nCol ){ rc = SQLITE_RANGE; }else if( pConfig->abUnindexed[iCol]==0 && pConfig->eContent!=FTS5_CONTENT_NONE && pConfig->bLocale ){ rc = fts5SeekCursor(pCsr, 0); if( rc==SQLITE_OK ){ const char *zDummy = 0; int nDummy = 0; rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &zDummy, &nDummy); if( rc==SQLITE_OK ){ *pzLocale = pConfig->t.pLocale; *pnLocale = pConfig->t.nLocale; } sqlite3Fts5ClearLocale(pConfig); } } return rc; } static const Fts5ExtensionApi sFts5Api = { 4, /* iVersion */ fts5ApiUserData, fts5ApiColumnCount, fts5ApiRowCount, fts5ApiColumnTotalSize, fts5ApiTokenize, fts5ApiPhraseCount, fts5ApiPhraseSize, fts5ApiInstCount, fts5ApiInst, fts5ApiRowid, fts5ApiColumnText, fts5ApiColumnSize, fts5ApiQueryPhrase, fts5ApiSetAuxdata, fts5ApiGetAuxdata, fts5ApiPhraseFirst, fts5ApiPhraseNext, fts5ApiPhraseFirstColumn, fts5ApiPhraseNextColumn, fts5ApiQueryToken, fts5ApiInstToken, fts5ApiColumnLocale, fts5ApiTokenize_v2 }; /* ** Implementation of API function xQueryPhrase(). */ static int fts5ApiQueryPhrase( Fts5Context *pCtx, |
︙ | ︙ | |||
252060 252061 252062 252063 252064 252065 252066 252067 252068 252069 252070 252071 252072 252073 252074 252075 252076 252077 252078 252079 252080 252081 252082 252083 252084 252085 252086 252087 252088 252089 252090 252091 252092 252093 252094 | Fts5Auxiliary *pAux, Fts5Cursor *pCsr, sqlite3_context *context, int argc, sqlite3_value **argv ){ assert( pCsr->pAux==0 ); pCsr->pAux = pAux; pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv); pCsr->pAux = 0; } static Fts5Cursor *fts5CursorFromCsrid(Fts5Global *pGlobal, i64 iCsrId){ Fts5Cursor *pCsr; for(pCsr=pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){ if( pCsr->iCsrId==iCsrId ) break; } return pCsr; } static void fts5ApiCallback( sqlite3_context *context, int argc, sqlite3_value **argv ){ Fts5Auxiliary *pAux; Fts5Cursor *pCsr; i64 iCsrId; assert( argc>=1 ); pAux = (Fts5Auxiliary*)sqlite3_user_data(context); iCsrId = sqlite3_value_int64(argv[0]); pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId); | > > > > > > > > > > > > > > > > | | < < > > > | 254003 254004 254005 254006 254007 254008 254009 254010 254011 254012 254013 254014 254015 254016 254017 254018 254019 254020 254021 254022 254023 254024 254025 254026 254027 254028 254029 254030 254031 254032 254033 254034 254035 254036 254037 254038 254039 254040 254041 254042 254043 254044 254045 254046 254047 254048 254049 254050 254051 254052 254053 254054 254055 254056 254057 254058 254059 254060 254061 254062 254063 254064 254065 254066 254067 | Fts5Auxiliary *pAux, Fts5Cursor *pCsr, sqlite3_context *context, int argc, sqlite3_value **argv ){ assert( pCsr->pAux==0 ); assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); pCsr->pAux = pAux; pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv); pCsr->pAux = 0; } static Fts5Cursor *fts5CursorFromCsrid(Fts5Global *pGlobal, i64 iCsrId){ Fts5Cursor *pCsr; for(pCsr=pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){ if( pCsr->iCsrId==iCsrId ) break; } return pCsr; } /* ** Parameter zFmt is a printf() style formatting string. This function ** formats it using the trailing arguments and returns the result as ** an error message to the context passed as the first argument. */ static void fts5ResultError(sqlite3_context *pCtx, const char *zFmt, ...){ char *zErr = 0; va_list ap; va_start(ap, zFmt); zErr = sqlite3_vmprintf(zFmt, ap); sqlite3_result_error(pCtx, zErr, -1); sqlite3_free(zErr); va_end(ap); } static void fts5ApiCallback( sqlite3_context *context, int argc, sqlite3_value **argv ){ Fts5Auxiliary *pAux; Fts5Cursor *pCsr; i64 iCsrId; assert( argc>=1 ); pAux = (Fts5Auxiliary*)sqlite3_user_data(context); iCsrId = sqlite3_value_int64(argv[0]); pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId); if( pCsr==0 || (pCsr->ePlan==0 || pCsr->ePlan==FTS5_PLAN_SPECIAL) ){ fts5ResultError(context, "no such cursor: %lld", iCsrId); }else{ sqlite3_vtab *pTab = pCsr->base.pVtab; fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]); sqlite3_free(pTab->zErrMsg); pTab->zErrMsg = 0; } } /* ** Given cursor id iId, return a pointer to the corresponding Fts5Table ** object. Or NULL If the cursor id does not exist. |
︙ | ︙ | |||
252211 252212 252213 252214 252215 252216 252217 | if( iCol==pConfig->nCol ){ /* User is requesting the value of the special column with the same name ** as the table. Return the cursor integer id number. This value is only ** useful in that it may be passed as the first argument to an FTS5 ** auxiliary function. */ sqlite3_result_int64(pCtx, pCsr->iCsrId); }else if( iCol==pConfig->nCol+1 ){ | < > > > > > | > > > > > > | | | > > > > > > > > > > > > > | | > > | < < < < < < | > > | 254171 254172 254173 254174 254175 254176 254177 254178 254179 254180 254181 254182 254183 254184 254185 254186 254187 254188 254189 254190 254191 254192 254193 254194 254195 254196 254197 254198 254199 254200 254201 254202 254203 254204 254205 254206 254207 254208 254209 254210 254211 254212 254213 254214 254215 254216 254217 254218 254219 254220 254221 254222 254223 254224 254225 254226 254227 254228 254229 254230 254231 | if( iCol==pConfig->nCol ){ /* User is requesting the value of the special column with the same name ** as the table. Return the cursor integer id number. This value is only ** useful in that it may be passed as the first argument to an FTS5 ** auxiliary function. */ sqlite3_result_int64(pCtx, pCsr->iCsrId); }else if( iCol==pConfig->nCol+1 ){ /* The value of the "rank" column. */ if( pCsr->ePlan==FTS5_PLAN_SOURCE ){ fts5PoslistBlob(pCtx, pCsr); }else if( pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH ){ if( pCsr->pRank || SQLITE_OK==(rc = fts5FindRankFunction(pCsr)) ){ fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg); } } }else{ /* A column created by the user containing values. */ int bNochange = sqlite3_vtab_nochange(pCtx); if( fts5IsContentless(pTab) ){ if( bNochange && pConfig->bContentlessDelete ){ fts5ResultError(pCtx, "cannot UPDATE a subset of " "columns on fts5 contentless-delete table: %s", pConfig->zName ); } }else if( bNochange==0 || pConfig->eContent!=FTS5_CONTENT_NORMAL ){ pConfig->pzErrmsg = &pTab->p.base.zErrMsg; rc = fts5SeekCursor(pCsr, 1); if( rc==SQLITE_OK ){ sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1); if( pConfig->bLocale && pConfig->eContent==FTS5_CONTENT_EXTERNAL && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ const char *z = 0; int n = 0; rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &z, &n); if( rc==SQLITE_OK ){ sqlite3_result_text(pCtx, z, n, SQLITE_TRANSIENT); } sqlite3Fts5ClearLocale(pConfig); }else{ sqlite3_result_value(pCtx, pVal); } } pConfig->pzErrmsg = 0; } } return rc; } /* ** This routine implements the xFindFunction method for the FTS3 ** virtual table. |
︙ | ︙ | |||
252374 252375 252376 252377 252378 252379 252380 252381 252382 252383 | }else{ rc = SQLITE_NOMEM; } } return rc; } /* ** Register a new tokenizer. This is the implementation of the | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < | < < < | | > < < < < | | | < | < | < < < < > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > > > > | > > > > | < | | < < < | | | > > | > > > > > > > | | > | > | | | | | > > > > > > > > > > > | 254355 254356 254357 254358 254359 254360 254361 254362 254363 254364 254365 254366 254367 254368 254369 254370 254371 254372 254373 254374 254375 254376 254377 254378 254379 254380 254381 254382 254383 254384 254385 254386 254387 254388 254389 254390 254391 254392 254393 254394 254395 254396 254397 254398 254399 254400 254401 254402 254403 254404 254405 254406 254407 254408 254409 254410 254411 254412 254413 254414 254415 254416 254417 254418 254419 254420 254421 254422 254423 254424 254425 254426 254427 254428 254429 254430 254431 254432 254433 254434 254435 254436 254437 254438 254439 254440 254441 254442 254443 254444 254445 254446 254447 254448 254449 254450 254451 254452 254453 254454 254455 254456 254457 254458 254459 254460 254461 254462 254463 254464 254465 254466 254467 254468 254469 254470 254471 254472 254473 254474 254475 254476 254477 254478 254479 254480 254481 254482 254483 254484 254485 254486 254487 254488 254489 254490 254491 254492 254493 254494 254495 254496 254497 254498 254499 254500 254501 254502 254503 254504 254505 254506 254507 254508 254509 254510 254511 254512 254513 254514 254515 254516 254517 254518 254519 254520 254521 254522 254523 254524 254525 254526 254527 254528 254529 254530 254531 254532 254533 254534 254535 254536 254537 254538 254539 254540 254541 254542 254543 254544 254545 254546 254547 254548 254549 254550 254551 254552 254553 254554 254555 254556 254557 254558 254559 254560 254561 254562 254563 254564 254565 254566 254567 254568 254569 254570 254571 254572 254573 254574 254575 254576 254577 254578 254579 254580 254581 254582 254583 254584 254585 254586 254587 254588 254589 254590 254591 254592 254593 254594 254595 254596 254597 254598 254599 254600 254601 254602 254603 254604 254605 254606 254607 254608 254609 254610 254611 254612 254613 254614 254615 254616 254617 254618 254619 254620 254621 254622 254623 254624 254625 254626 254627 254628 254629 254630 254631 254632 254633 254634 254635 254636 254637 254638 254639 254640 254641 254642 254643 254644 254645 254646 254647 254648 254649 254650 254651 254652 254653 254654 254655 254656 254657 254658 254659 254660 254661 254662 254663 254664 254665 254666 254667 254668 254669 254670 254671 254672 254673 254674 254675 254676 254677 254678 254679 254680 254681 254682 254683 254684 254685 254686 254687 254688 254689 254690 254691 254692 254693 254694 254695 254696 254697 254698 254699 254700 254701 254702 254703 254704 254705 254706 254707 254708 254709 254710 254711 254712 254713 254714 254715 254716 254717 254718 254719 254720 254721 254722 254723 254724 254725 254726 | }else{ rc = SQLITE_NOMEM; } } return rc; } /* ** This function is used by xCreateTokenizer_v2() and xCreateTokenizer(). ** It allocates and partially populates a new Fts5TokenizerModule object. ** The new object is already linked into the Fts5Global context before ** returning. ** ** If successful, SQLITE_OK is returned and a pointer to the new ** Fts5TokenizerModule object returned via output parameter (*ppNew). All ** that is required is for the caller to fill in the methods in ** Fts5TokenizerModule.x1 and x2, and to set Fts5TokenizerModule.bV2Native ** as appropriate. ** ** If an error occurs, an SQLite error code is returned and the final value ** of (*ppNew) undefined. */ static int fts5NewTokenizerModule( Fts5Global *pGlobal, /* Global context (one per db handle) */ const char *zName, /* Name of new function */ void *pUserData, /* User data for aux. function */ void(*xDestroy)(void*), /* Destructor for pUserData */ Fts5TokenizerModule **ppNew ){ int rc = SQLITE_OK; Fts5TokenizerModule *pNew; sqlite3_int64 nName; /* Size of zName and its \0 terminator */ sqlite3_int64 nByte; /* Bytes of space to allocate */ nName = strlen(zName) + 1; nByte = sizeof(Fts5TokenizerModule) + nName; *ppNew = pNew = (Fts5TokenizerModule*)sqlite3Fts5MallocZero(&rc, nByte); if( pNew ){ pNew->zName = (char*)&pNew[1]; memcpy(pNew->zName, zName, nName); pNew->pUserData = pUserData; pNew->xDestroy = xDestroy; pNew->pNext = pGlobal->pTok; pGlobal->pTok = pNew; if( pNew->pNext==0 ){ pGlobal->pDfltTok = pNew; } } return rc; } /* ** An instance of this type is used as the Fts5Tokenizer object for ** wrapper tokenizers - those that provide access to a v1 tokenizer via ** the fts5_tokenizer_v2 API, and those that provide access to a v2 tokenizer ** via the fts5_tokenizer API. */ typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer; struct Fts5VtoVTokenizer { int bV2Native; /* True if v2 native tokenizer */ fts5_tokenizer x1; /* Tokenizer functions */ fts5_tokenizer_v2 x2; /* V2 tokenizer functions */ Fts5Tokenizer *pReal; }; /* ** Create a wrapper tokenizer. The context argument pCtx points to the ** Fts5TokenizerModule object. */ static int fts5VtoVCreate( void *pCtx, const char **azArg, int nArg, Fts5Tokenizer **ppOut ){ Fts5TokenizerModule *pMod = (Fts5TokenizerModule*)pCtx; Fts5VtoVTokenizer *pNew = 0; int rc = SQLITE_OK; pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew)); if( rc==SQLITE_OK ){ pNew->x1 = pMod->x1; pNew->x2 = pMod->x2; pNew->bV2Native = pMod->bV2Native; if( pMod->bV2Native ){ rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal); }else{ rc = pMod->x1.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal); } if( rc!=SQLITE_OK ){ sqlite3_free(pNew); pNew = 0; } } *ppOut = (Fts5Tokenizer*)pNew; return rc; } /* ** Delete an Fts5VtoVTokenizer wrapper tokenizer. */ static void fts5VtoVDelete(Fts5Tokenizer *pTok){ Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; if( p ){ if( p->bV2Native ){ p->x2.xDelete(p->pReal); }else{ p->x1.xDelete(p->pReal); } sqlite3_free(p); } } /* ** xTokenizer method for a wrapper tokenizer that offers the v1 interface ** (no support for locales). */ static int fts5V1toV2Tokenize( Fts5Tokenizer *pTok, void *pCtx, int flags, const char *pText, int nText, int (*xToken)(void*, int, const char*, int, int, int) ){ Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; assert( p->bV2Native ); return p->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken); } /* ** xTokenizer method for a wrapper tokenizer that offers the v2 interface ** (with locale support). */ static int fts5V2toV1Tokenize( Fts5Tokenizer *pTok, void *pCtx, int flags, const char *pText, int nText, const char *pLocale, int nLocale, int (*xToken)(void*, int, const char*, int, int, int) ){ Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; assert( p->bV2Native==0 ); UNUSED_PARAM2(pLocale,nLocale); return p->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken); } /* ** Register a new tokenizer. This is the implementation of the ** fts5_api.xCreateTokenizer_v2() method. */ static int fts5CreateTokenizer_v2( fts5_api *pApi, /* Global context (one per db handle) */ const char *zName, /* Name of new function */ void *pUserData, /* User data for aux. function */ fts5_tokenizer_v2 *pTokenizer, /* Tokenizer implementation */ void(*xDestroy)(void*) /* Destructor for pUserData */ ){ Fts5Global *pGlobal = (Fts5Global*)pApi; int rc = SQLITE_OK; if( pTokenizer->iVersion>2 ){ rc = SQLITE_ERROR; }else{ Fts5TokenizerModule *pNew = 0; rc = fts5NewTokenizerModule(pGlobal, zName, pUserData, xDestroy, &pNew); if( pNew ){ pNew->x2 = *pTokenizer; pNew->bV2Native = 1; pNew->x1.xCreate = fts5VtoVCreate; pNew->x1.xTokenize = fts5V1toV2Tokenize; pNew->x1.xDelete = fts5VtoVDelete; } } return rc; } /* ** The fts5_api.xCreateTokenizer() method. */ static int fts5CreateTokenizer( fts5_api *pApi, /* Global context (one per db handle) */ const char *zName, /* Name of new function */ void *pUserData, /* User data for aux. function */ fts5_tokenizer *pTokenizer, /* Tokenizer implementation */ void(*xDestroy)(void*) /* Destructor for pUserData */ ){ Fts5TokenizerModule *pNew = 0; int rc = SQLITE_OK; rc = fts5NewTokenizerModule( (Fts5Global*)pApi, zName, pUserData, xDestroy, &pNew ); if( pNew ){ pNew->x1 = *pTokenizer; pNew->x2.xCreate = fts5VtoVCreate; pNew->x2.xTokenize = fts5V2toV1Tokenize; pNew->x2.xDelete = fts5VtoVDelete; } return rc; } /* ** Search the global context passed as the first argument for a tokenizer ** module named zName. If found, return a pointer to the Fts5TokenizerModule ** object. Otherwise, return NULL. */ static Fts5TokenizerModule *fts5LocateTokenizer( Fts5Global *pGlobal, /* Global (one per db handle) object */ const char *zName /* Name of tokenizer module to find */ ){ Fts5TokenizerModule *pMod = 0; if( zName==0 ){ pMod = pGlobal->pDfltTok; }else{ for(pMod=pGlobal->pTok; pMod; pMod=pMod->pNext){ if( sqlite3_stricmp(zName, pMod->zName)==0 ) break; } } return pMod; } /* ** Find a tokenizer. This is the implementation of the ** fts5_api.xFindTokenizer_v2() method. */ static int fts5FindTokenizer_v2( fts5_api *pApi, /* Global context (one per db handle) */ const char *zName, /* Name of tokenizer */ void **ppUserData, fts5_tokenizer_v2 **ppTokenizer /* Populate this object */ ){ int rc = SQLITE_OK; Fts5TokenizerModule *pMod; pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName); if( pMod ){ if( pMod->bV2Native ){ *ppUserData = pMod->pUserData; }else{ *ppUserData = (void*)pMod; } *ppTokenizer = &pMod->x2; }else{ *ppTokenizer = 0; *ppUserData = 0; rc = SQLITE_ERROR; } return rc; } /* ** Find a tokenizer. This is the implementation of the ** fts5_api.xFindTokenizer() method. */ static int fts5FindTokenizer( fts5_api *pApi, /* Global context (one per db handle) */ const char *zName, /* Name of new function */ void **ppUserData, fts5_tokenizer *pTokenizer /* Populate this object */ ){ int rc = SQLITE_OK; Fts5TokenizerModule *pMod; pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName); if( pMod ){ if( pMod->bV2Native==0 ){ *ppUserData = pMod->pUserData; }else{ *ppUserData = (void*)pMod; } *pTokenizer = pMod->x1; }else{ memset(pTokenizer, 0, sizeof(*pTokenizer)); *ppUserData = 0; rc = SQLITE_ERROR; } return rc; } /* ** Attempt to instantiate the tokenizer. */ static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig){ const char **azArg = pConfig->t.azArg; const int nArg = pConfig->t.nArg; Fts5TokenizerModule *pMod = 0; int rc = SQLITE_OK; pMod = fts5LocateTokenizer(pConfig->pGlobal, nArg==0 ? 0 : azArg[0]); if( pMod==0 ){ assert( nArg>0 ); rc = SQLITE_ERROR; sqlite3Fts5ConfigErrmsg(pConfig, "no such tokenizer: %s", azArg[0]); }else{ int (*xCreate)(void*, const char**, int, Fts5Tokenizer**) = 0; if( pMod->bV2Native ){ xCreate = pMod->x2.xCreate; pConfig->t.pApi2 = &pMod->x2; }else{ pConfig->t.pApi1 = &pMod->x1; xCreate = pMod->x1.xCreate; } rc = xCreate(pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->t.pTok ); if( rc!=SQLITE_OK ){ if( rc!=SQLITE_NOMEM ){ sqlite3Fts5ConfigErrmsg(pConfig, "error in tokenizer constructor"); } }else if( pMod->bV2Native==0 ){ pConfig->t.ePattern = sqlite3Fts5TokenizerPattern( pMod->x1.xCreate, pConfig->t.pTok ); } } if( rc!=SQLITE_OK ){ pConfig->t.pApi1 = 0; pConfig->t.pApi2 = 0; pConfig->t.pTok = 0; } return rc; } /* ** xDestroy callback passed to sqlite3_create_module(). This is invoked ** when the db handle is being closed. Free memory associated with ** tokenizers and aux functions registered with this db handle. */ static void fts5ModuleDestroy(void *pCtx){ Fts5TokenizerModule *pTok, *pNextTok; Fts5Auxiliary *pAux, *pNextAux; Fts5Global *pGlobal = (Fts5Global*)pCtx; for(pAux=pGlobal->pAux; pAux; pAux=pNextAux){ pNextAux = pAux->pNext; if( pAux->xDestroy ) pAux->xDestroy(pAux->pUserData); sqlite3_free(pAux); } for(pTok=pGlobal->pTok; pTok; pTok=pNextTok){ pNextTok = pTok->pNext; if( pTok->xDestroy ) pTok->xDestroy(pTok->pUserData); sqlite3_free(pTok); } sqlite3_free(pGlobal); } /* ** Implementation of the fts5() function used by clients to obtain the ** API pointer. */ static void fts5Fts5Func( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ sqlite3_value **apArg /* Function arguments */ ){ Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx); fts5_api **ppApi; |
︙ | ︙ | |||
252536 252537 252538 252539 252540 252541 252542 | static void fts5SourceIdFunc( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ sqlite3_value **apUnused /* Function arguments */ ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 254736 254737 254738 254739 254740 254741 254742 254743 254744 254745 254746 254747 254748 254749 254750 254751 254752 254753 254754 254755 254756 254757 254758 254759 254760 254761 254762 254763 254764 254765 254766 254767 254768 254769 254770 254771 254772 254773 254774 254775 254776 254777 254778 254779 254780 254781 254782 254783 254784 254785 254786 254787 254788 254789 254790 254791 254792 254793 254794 254795 254796 254797 254798 254799 254800 254801 254802 254803 254804 254805 254806 254807 254808 254809 254810 254811 | static void fts5SourceIdFunc( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ sqlite3_value **apUnused /* Function arguments */ ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); sqlite3_result_text(pCtx, "fts5: 2024-09-26 19:38:34 f97f9944b829a49da12786f934da0a5ad51591afd6d8a19a4a0835f51bbdbff2", -1, SQLITE_TRANSIENT); } /* ** Implementation of fts5_locale(LOCALE, TEXT) function. ** ** If parameter LOCALE is NULL, or a zero-length string, then a copy of ** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as ** text, and the value returned is a blob consisting of: ** ** * The 4 bytes 0x00, 0xE0, 0xB2, 0xEb (FTS5_LOCALE_HEADER). ** * The LOCALE, as utf-8 text, followed by ** * 0x00, followed by ** * The TEXT, as utf-8 text. ** ** There is no final nul-terminator following the TEXT value. */ static void fts5LocaleFunc( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ sqlite3_value **apArg /* Function arguments */ ){ const char *zLocale = 0; int nLocale = 0; const char *zText = 0; int nText = 0; assert( nArg==2 ); UNUSED_PARAM(nArg); zLocale = (const char*)sqlite3_value_text(apArg[0]); nLocale = sqlite3_value_bytes(apArg[0]); zText = (const char*)sqlite3_value_text(apArg[1]); nText = sqlite3_value_bytes(apArg[1]); if( zLocale==0 || zLocale[0]=='\0' ){ sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT); }else{ Fts5Global *p = (Fts5Global*)sqlite3_user_data(pCtx); u8 *pBlob = 0; u8 *pCsr = 0; int nBlob = 0; nBlob = FTS5_LOCALE_HDR_SIZE + nLocale + 1 + nText; pBlob = (u8*)sqlite3_malloc(nBlob); if( pBlob==0 ){ sqlite3_result_error_nomem(pCtx); return; } pCsr = pBlob; memcpy(pCsr, (const u8*)p->aLocaleHdr, FTS5_LOCALE_HDR_SIZE); pCsr += FTS5_LOCALE_HDR_SIZE; memcpy(pCsr, zLocale, nLocale); pCsr += nLocale; (*pCsr++) = 0x00; if( zText ) memcpy(pCsr, zText, nText); assert( &pCsr[nText]==&pBlob[nBlob] ); sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free); } } /* ** Return true if zName is the extension on one of the shadow tables used ** by this module. */ static int fts5ShadowName(const char *zName){ |
︙ | ︙ | |||
252571 252572 252573 252574 252575 252576 252577 252578 | char **pzErr /* Write error message here */ ){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; int rc; assert( pzErr!=0 && *pzErr==0 ); UNUSED_PARAM(isQuick); rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0); | > > > | | | | | | | | | > > > | 254832 254833 254834 254835 254836 254837 254838 254839 254840 254841 254842 254843 254844 254845 254846 254847 254848 254849 254850 254851 254852 254853 254854 254855 254856 254857 254858 254859 254860 254861 254862 | char **pzErr /* Write error message here */ ){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; int rc; assert( pzErr!=0 && *pzErr==0 ); UNUSED_PARAM(isQuick); assert( pTab->p.pConfig->pzErrmsg==0 ); pTab->p.pConfig->pzErrmsg = pzErr; rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0); if( *pzErr==0 && rc!=SQLITE_OK ){ if( (rc&0xff)==SQLITE_CORRUPT ){ *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s", zSchema, zTabname); rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM; }else{ *pzErr = sqlite3_mprintf("unable to validate the inverted index for" " FTS5 table %s.%s: %s", zSchema, zTabname, sqlite3_errstr(rc)); } } sqlite3Fts5IndexCloseReader(pTab->p.pIndex); pTab->p.pConfig->pzErrmsg = 0; return rc; } static int fts5Init(sqlite3 *db){ static const sqlite3_module fts5Mod = { /* iVersion */ 4, |
︙ | ︙ | |||
252625 252626 252627 252628 252629 252630 252631 | pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global)); if( pGlobal==0 ){ rc = SQLITE_NOMEM; }else{ void *p = (void*)pGlobal; memset(pGlobal, 0, sizeof(Fts5Global)); pGlobal->db = db; | | > > > > > > > > > > > > > > > > > > > | 254892 254893 254894 254895 254896 254897 254898 254899 254900 254901 254902 254903 254904 254905 254906 254907 254908 254909 254910 254911 254912 254913 254914 254915 254916 254917 254918 254919 254920 254921 254922 254923 254924 254925 254926 254927 254928 254929 254930 254931 254932 254933 254934 254935 254936 254937 254938 254939 254940 254941 254942 254943 254944 254945 | pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global)); if( pGlobal==0 ){ rc = SQLITE_NOMEM; }else{ void *p = (void*)pGlobal; memset(pGlobal, 0, sizeof(Fts5Global)); pGlobal->db = db; pGlobal->api.iVersion = 3; pGlobal->api.xCreateFunction = fts5CreateAux; pGlobal->api.xCreateTokenizer = fts5CreateTokenizer; pGlobal->api.xFindTokenizer = fts5FindTokenizer; pGlobal->api.xCreateTokenizer_v2 = fts5CreateTokenizer_v2; pGlobal->api.xFindTokenizer_v2 = fts5FindTokenizer_v2; /* Initialize pGlobal->aLocaleHdr[] to a 128-bit pseudo-random vector. ** The constants below were generated randomly. */ sqlite3_randomness(sizeof(pGlobal->aLocaleHdr), pGlobal->aLocaleHdr); pGlobal->aLocaleHdr[0] ^= 0xF924976D; pGlobal->aLocaleHdr[1] ^= 0x16596E13; pGlobal->aLocaleHdr[2] ^= 0x7C80BEAA; pGlobal->aLocaleHdr[3] ^= 0x9B03A67F; assert( sizeof(pGlobal->aLocaleHdr)==16 ); rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy); if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db); if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db); if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api); if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api); if( rc==SQLITE_OK ) rc = sqlite3Fts5VocabInit(pGlobal, db); if( rc==SQLITE_OK ){ rc = sqlite3_create_function( db, "fts5", 1, SQLITE_UTF8, p, fts5Fts5Func, 0, 0 ); } if( rc==SQLITE_OK ){ rc = sqlite3_create_function( db, "fts5_source_id", 0, SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS, p, fts5SourceIdFunc, 0, 0 ); } if( rc==SQLITE_OK ){ rc = sqlite3_create_function( db, "fts5_locale", 2, SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE, p, fts5LocaleFunc, 0, 0 ); } } /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file ** fts5_test_mi.c is compiled and linked into the executable. And call ** its entry point to enable the matchinfo() demo. */ #ifdef SQLITE_FTS5_ENABLE_TEST_MI |
︙ | ︙ | |||
252721 252722 252723 252724 252725 252726 252727 252728 252729 252730 252731 252732 252733 | ** */ /* #include "fts5Int.h" */ struct Fts5Storage { Fts5Config *pConfig; Fts5Index *pIndex; int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */ i64 nTotalRow; /* Total number of rows in FTS table */ i64 *aTotalSize; /* Total sizes of each column */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > | 255007 255008 255009 255010 255011 255012 255013 255014 255015 255016 255017 255018 255019 255020 255021 255022 255023 255024 255025 255026 255027 255028 255029 255030 255031 255032 255033 255034 255035 255036 255037 255038 255039 255040 255041 255042 255043 255044 255045 255046 255047 255048 255049 255050 255051 255052 255053 255054 255055 255056 255057 255058 255059 255060 255061 255062 255063 255064 255065 255066 255067 255068 255069 255070 255071 255072 255073 255074 255075 255076 255077 255078 255079 255080 255081 255082 255083 255084 255085 255086 255087 255088 255089 255090 255091 255092 255093 255094 255095 255096 255097 255098 255099 255100 | ** */ /* #include "fts5Int.h" */ /* ** pSavedRow: ** SQL statement FTS5_STMT_LOOKUP2 is a copy of FTS5_STMT_LOOKUP, it ** does a by-rowid lookup to retrieve a single row from the %_content ** table or equivalent external-content table/view. ** ** However, FTS5_STMT_LOOKUP2 is only used when retrieving the original ** values for a row being UPDATEd. In that case, the SQL statement is ** not reset and pSavedRow is set to point at it. This is so that the ** insert operation that follows the delete may access the original ** row values for any new values for which sqlite3_value_nochange() returns ** true. i.e. if the user executes: ** ** CREATE VIRTUAL TABLE ft USING fts5(a, b, c, locale=1); ** ... ** UPDATE fts SET a=?, b=? WHERE rowid=?; ** ** then the value passed to the xUpdate() method of this table as the ** new.c value is an sqlite3_value_nochange() value. So in this case it ** must be read from the saved row stored in Fts5Storage.pSavedRow. ** ** This is necessary - using sqlite3_value_nochange() instead of just having ** SQLite pass the original value back via xUpdate() - so as not to discard ** any locale information associated with such values. ** */ struct Fts5Storage { Fts5Config *pConfig; Fts5Index *pIndex; int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */ i64 nTotalRow; /* Total number of rows in FTS table */ i64 *aTotalSize; /* Total sizes of each column */ sqlite3_stmt *pSavedRow; sqlite3_stmt *aStmt[12]; }; #if FTS5_STMT_SCAN_ASC!=0 # error "FTS5_STMT_SCAN_ASC mismatch" #endif #if FTS5_STMT_SCAN_DESC!=1 # error "FTS5_STMT_SCAN_DESC mismatch" #endif #if FTS5_STMT_LOOKUP!=2 # error "FTS5_STMT_LOOKUP mismatch" #endif #define FTS5_STMT_LOOKUP2 3 #define FTS5_STMT_INSERT_CONTENT 4 #define FTS5_STMT_REPLACE_CONTENT 5 #define FTS5_STMT_DELETE_CONTENT 6 #define FTS5_STMT_REPLACE_DOCSIZE 7 #define FTS5_STMT_DELETE_DOCSIZE 8 #define FTS5_STMT_LOOKUP_DOCSIZE 9 #define FTS5_STMT_REPLACE_CONFIG 10 #define FTS5_STMT_SCAN 11 /* ** Return a pointer to a buffer obtained from sqlite3_malloc() that contains ** nBind comma-separated question marks. e.g. if nBind is passed 5, this ** function returns "?,?,?,?,?". ** ** If *pRc is not SQLITE_OK when this function is called, it is a no-op and ** NULL is returned immediately. Or, if the attempt to malloc a buffer ** fails, then *pRc is set to SQLITE_NOMEM and NULL is returned. Otherwise, ** if it is SQLITE_OK when this function is called and the malloc() succeeds, ** *pRc is left unchanged. */ static char *fts5BindingsList(int *pRc, int nBind){ char *zBind = sqlite3Fts5MallocZero(pRc, 1 + nBind*2); if( zBind ){ int ii; for(ii=0; ii<nBind; ii++){ zBind[ii*2] = '?'; zBind[ii*2 + 1] = ','; } zBind[ii*2-1] = '\0'; } return zBind; } /* ** Prepare the two insert statements - Fts5Storage.pInsertContent and ** Fts5Storage.pInsertDocsize - if they have not already been prepared. ** Return SQLITE_OK if successful, or an SQLite error code if an error ** occurs. */ |
︙ | ︙ | |||
252778 252779 252780 252781 252782 252783 252784 252785 252786 252787 252788 252789 252790 252791 252792 252793 252794 252795 252796 252797 252798 252799 252800 252801 252802 252803 252804 252805 252806 252807 252808 252809 252810 252811 252812 252813 252814 252815 252816 252817 252818 252819 252820 | assert( eStmt>=0 && eStmt<ArraySize(p->aStmt) ); if( p->aStmt[eStmt]==0 ){ const char *azStmt[] = { "SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC", "SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC", "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */ "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */ "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */ "DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?%s)", /* REPLACE_DOCSIZE */ "DELETE FROM %Q.'%q_docsize' WHERE id=?", /* DELETE_DOCSIZE */ "SELECT sz%s FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */ "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */ "SELECT %s FROM %s AS T", /* SCAN */ }; Fts5Config *pC = p->pConfig; char *zSql = 0; switch( eStmt ){ case FTS5_STMT_SCAN: zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, pC->zContent ); break; case FTS5_STMT_SCAN_ASC: case FTS5_STMT_SCAN_DESC: zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, pC->zContent, pC->zContentRowid, pC->zContentRowid, pC->zContentRowid ); break; case FTS5_STMT_LOOKUP: zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, pC->zContent, pC->zContentRowid ); break; | > > > > | < | | | | | < > | > > | 255116 255117 255118 255119 255120 255121 255122 255123 255124 255125 255126 255127 255128 255129 255130 255131 255132 255133 255134 255135 255136 255137 255138 255139 255140 255141 255142 255143 255144 255145 255146 255147 255148 255149 255150 255151 255152 255153 255154 255155 255156 255157 255158 255159 255160 255161 255162 255163 255164 255165 255166 255167 255168 255169 255170 255171 255172 255173 255174 255175 255176 255177 255178 255179 255180 255181 255182 255183 | assert( eStmt>=0 && eStmt<ArraySize(p->aStmt) ); if( p->aStmt[eStmt]==0 ){ const char *azStmt[] = { "SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC", "SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC", "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */ "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP2 */ "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */ "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */ "DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?%s)", /* REPLACE_DOCSIZE */ "DELETE FROM %Q.'%q_docsize' WHERE id=?", /* DELETE_DOCSIZE */ "SELECT sz%s FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */ "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */ "SELECT %s FROM %s AS T", /* SCAN */ }; Fts5Config *pC = p->pConfig; char *zSql = 0; assert( ArraySize(azStmt)==ArraySize(p->aStmt) ); switch( eStmt ){ case FTS5_STMT_SCAN: zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, pC->zContent ); break; case FTS5_STMT_SCAN_ASC: case FTS5_STMT_SCAN_DESC: zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, pC->zContent, pC->zContentRowid, pC->zContentRowid, pC->zContentRowid ); break; case FTS5_STMT_LOOKUP: case FTS5_STMT_LOOKUP2: zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, pC->zContent, pC->zContentRowid ); break; case FTS5_STMT_INSERT_CONTENT: { int nCol = 0; char *zBind; int i; nCol = 1 + pC->nCol; if( pC->bLocale ){ for(i=0; i<pC->nCol; i++){ if( pC->abUnindexed[i]==0 ) nCol++; } } zBind = fts5BindingsList(&rc, nCol); if( zBind ){ zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind); sqlite3_free(zBind); } break; } case FTS5_STMT_REPLACE_DOCSIZE: |
︙ | ︙ | |||
252855 252856 252857 252858 252859 252860 252861 | break; } if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ int f = SQLITE_PREPARE_PERSISTENT; | | | 255198 255199 255200 255201 255202 255203 255204 255205 255206 255207 255208 255209 255210 255211 255212 | break; } if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ int f = SQLITE_PREPARE_PERSISTENT; if( eStmt>FTS5_STMT_LOOKUP2 ) f |= SQLITE_PREPARE_NO_VTAB; p->pConfig->bLock++; rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0); p->pConfig->bLock--; sqlite3_free(zSql); if( rc!=SQLITE_OK && pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db)); } |
︙ | ︙ | |||
253017 253018 253019 253020 253021 253022 253023 | p->aTotalSize = (i64*)&p[1]; p->pConfig = pConfig; p->pIndex = pIndex; if( bCreate ){ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ int nDefn = 32 + pConfig->nCol*10; | | > > > > > > > > | 255360 255361 255362 255363 255364 255365 255366 255367 255368 255369 255370 255371 255372 255373 255374 255375 255376 255377 255378 255379 255380 255381 255382 255383 255384 255385 255386 255387 255388 255389 255390 255391 255392 | p->aTotalSize = (i64*)&p[1]; p->pConfig = pConfig; p->pIndex = pIndex; if( bCreate ){ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ int nDefn = 32 + pConfig->nCol*10; char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 20); if( zDefn==0 ){ rc = SQLITE_NOMEM; }else{ int i; int iOff; sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY"); iOff = (int)strlen(zDefn); for(i=0; i<pConfig->nCol; i++){ sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); iOff += (int)strlen(&zDefn[iOff]); } if( pConfig->bLocale ){ for(i=0; i<pConfig->nCol; i++){ if( pConfig->abUnindexed[i]==0 ){ sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", l%d", i); iOff += (int)strlen(&zDefn[iOff]); } } } rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr); } sqlite3_free(zDefn); } if( rc==SQLITE_OK && pConfig->bColumnsize ){ |
︙ | ︙ | |||
253103 253104 253105 253106 253107 253108 253109 253110 253111 253112 253113 253114 253115 253116 253117 253118 | UNUSED_PARAM2(iUnused1, iUnused2); if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){ pCtx->szCol++; } return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken); } /* ** If a row with rowid iDel is present in the %_content table, add the ** delete-markers to the FTS index necessary to delete it. Do not actually ** remove the %_content row at this time though. */ static int fts5StorageDeleteFromIndex( Fts5Storage *p, i64 iDel, | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > | | | | | > > | | > > > | > > > | > > | | | < | > > | > > > > | | | | | | | > > > > > > | | > > > > > > > > > > > > > > | 255454 255455 255456 255457 255458 255459 255460 255461 255462 255463 255464 255465 255466 255467 255468 255469 255470 255471 255472 255473 255474 255475 255476 255477 255478 255479 255480 255481 255482 255483 255484 255485 255486 255487 255488 255489 255490 255491 255492 255493 255494 255495 255496 255497 255498 255499 255500 255501 255502 255503 255504 255505 255506 255507 255508 255509 255510 255511 255512 255513 255514 255515 255516 255517 255518 255519 255520 255521 255522 255523 255524 255525 255526 255527 255528 255529 255530 255531 255532 255533 255534 255535 255536 255537 255538 255539 255540 255541 255542 255543 255544 255545 255546 255547 255548 255549 255550 255551 255552 255553 255554 255555 255556 255557 255558 255559 255560 255561 255562 255563 255564 255565 255566 255567 255568 255569 255570 255571 255572 255573 255574 255575 255576 255577 255578 255579 255580 255581 255582 255583 255584 255585 255586 255587 255588 255589 255590 255591 255592 255593 255594 255595 255596 255597 255598 255599 255600 255601 255602 255603 255604 255605 255606 255607 255608 | UNUSED_PARAM2(iUnused1, iUnused2); if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){ pCtx->szCol++; } return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken); } /* ** This function is used as part of an UPDATE statement that modifies the ** rowid of a row. In that case, this function is called first to set ** Fts5Storage.pSavedRow to point to a statement that may be used to ** access the original values of the row being deleted - iDel. ** ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. ** It is not considered an error if row iDel does not exist. In this case ** pSavedRow is not set and SQLITE_OK returned. */ static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel){ int rc = SQLITE_OK; sqlite3_stmt *pSeek = 0; assert( p->pSavedRow==0 ); rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+1, &pSeek, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int64(pSeek, 1, iDel); if( sqlite3_step(pSeek)!=SQLITE_ROW ){ rc = sqlite3_reset(pSeek); }else{ p->pSavedRow = pSeek; } } return rc; } /* ** If a row with rowid iDel is present in the %_content table, add the ** delete-markers to the FTS index necessary to delete it. Do not actually ** remove the %_content row at this time though. ** ** If parameter bSaveRow is true, then Fts5Storage.pSavedRow is left ** pointing to a statement (FTS5_STMT_LOOKUP2) that may be used to access ** the original values of the row being deleted. This is used by UPDATE ** statements. */ static int fts5StorageDeleteFromIndex( Fts5Storage *p, i64 iDel, sqlite3_value **apVal, int bSaveRow /* True to set pSavedRow */ ){ Fts5Config *pConfig = p->pConfig; sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */ int rc = SQLITE_OK; /* Return code */ int rc2; /* sqlite3_reset() return code */ int iCol; Fts5InsertCtx ctx; assert( bSaveRow==0 || apVal==0 ); assert( bSaveRow==0 || bSaveRow==1 ); assert( FTS5_STMT_LOOKUP2==FTS5_STMT_LOOKUP+1 ); if( apVal==0 ){ if( p->pSavedRow && bSaveRow ){ pSeek = p->pSavedRow; p->pSavedRow = 0; }else{ rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+bSaveRow, &pSeek, 0); if( rc!=SQLITE_OK ) return rc; sqlite3_bind_int64(pSeek, 1, iDel); if( sqlite3_step(pSeek)!=SQLITE_ROW ){ return sqlite3_reset(pSeek); } } } ctx.pStorage = p; ctx.iCol = -1; for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ if( pConfig->abUnindexed[iCol-1]==0 ){ sqlite3_value *pVal = 0; const char *pText = 0; int nText = 0; const char *pLoc = 0; int nLoc = 0; assert( pSeek==0 || apVal==0 ); assert( pSeek!=0 || apVal!=0 ); if( pSeek ){ pVal = sqlite3_column_value(pSeek, iCol); }else{ pVal = apVal[iCol-1]; } if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); }else{ pText = (const char*)sqlite3_value_text(pVal); nText = sqlite3_value_bytes(pVal); if( pConfig->bLocale && pSeek ){ pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol); nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); } } if( rc==SQLITE_OK ){ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); ctx.szCol = 0; rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx, fts5StorageInsertCallback ); p->aTotalSize[iCol-1] -= (i64)ctx.szCol; if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){ rc = FTS5_CORRUPT; } sqlite3Fts5ClearLocale(pConfig); } } } if( rc==SQLITE_OK && p->nTotalRow<1 ){ rc = FTS5_CORRUPT; }else{ p->nTotalRow--; } if( rc==SQLITE_OK && bSaveRow ){ assert( p->pSavedRow==0 ); p->pSavedRow = pSeek; }else{ rc2 = sqlite3_reset(pSeek); if( rc==SQLITE_OK ) rc = rc2; } return rc; } /* ** Reset any saved statement pSavedRow. Zero pSavedRow as well. This ** should be called by the xUpdate() method of the fts5 table before ** returning from any operation that may have set Fts5Storage.pSavedRow. */ static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage *pStorage){ assert( pStorage->pSavedRow==0 || pStorage->pSavedRow==pStorage->aStmt[FTS5_STMT_LOOKUP2] ); sqlite3_reset(pStorage->pSavedRow); pStorage->pSavedRow = 0; } /* ** This function is called to process a DELETE on a contentless_delete=1 ** table. It adds the tombstone required to delete the entry with rowid ** iDel. If successful, SQLITE_OK is returned. Or, if an error occurs, ** an SQLite error code. */ |
︙ | ︙ | |||
253224 253225 253226 253227 253228 253229 253230 | if( rc==SQLITE_OK ){ sqlite3_bind_int64(pReplace, 1, iRowid); if( p->pConfig->bContentlessDelete ){ i64 iOrigin = 0; rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin); sqlite3_bind_int64(pReplace, 3, iOrigin); } | > | | | | | < | 255652 255653 255654 255655 255656 255657 255658 255659 255660 255661 255662 255663 255664 255665 255666 255667 255668 255669 255670 255671 | if( rc==SQLITE_OK ){ sqlite3_bind_int64(pReplace, 1, iRowid); if( p->pConfig->bContentlessDelete ){ i64 iOrigin = 0; rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin); sqlite3_bind_int64(pReplace, 3, iOrigin); } } if( rc==SQLITE_OK ){ sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); sqlite3_step(pReplace); rc = sqlite3_reset(pReplace); sqlite3_bind_null(pReplace, 2); } } return rc; } /* ** Load the contents of the "averages" record from disk into the |
︙ | ︙ | |||
253283 253284 253285 253286 253287 253288 253289 | return rc; } /* ** Remove a row from the FTS table. */ | | > > > > > | | 255711 255712 255713 255714 255715 255716 255717 255718 255719 255720 255721 255722 255723 255724 255725 255726 255727 255728 255729 255730 255731 255732 255733 255734 255735 255736 255737 255738 255739 255740 255741 255742 255743 255744 255745 255746 255747 | return rc; } /* ** Remove a row from the FTS table. */ static int sqlite3Fts5StorageDelete( Fts5Storage *p, /* Storage object */ i64 iDel, /* Rowid to delete from table */ sqlite3_value **apVal, /* Optional - values to remove from index */ int bSaveRow /* If true, set pSavedRow for deleted row */ ){ Fts5Config *pConfig = p->pConfig; int rc; sqlite3_stmt *pDel = 0; assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 ); rc = fts5StorageLoadTotals(p, 1); /* Delete the index records */ if( rc==SQLITE_OK ){ rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel); } if( rc==SQLITE_OK ){ if( p->pConfig->bContentlessDelete ){ rc = fts5StorageContentlessDelete(p, iDel); }else{ rc = fts5StorageDeleteFromIndex(p, iDel, apVal, bSaveRow); } } /* Delete the %_docsize record */ if( rc==SQLITE_OK && pConfig->bColumnsize ){ rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0); if( rc==SQLITE_OK ){ |
︙ | ︙ | |||
253389 253390 253391 253392 253393 253394 253395 | i64 iRowid = sqlite3_column_int64(pScan, 0); sqlite3Fts5BufferZero(&buf); rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid); for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ | > > > > > > > > > > > > > > > | | > > > > > | | | | | | > > | 255822 255823 255824 255825 255826 255827 255828 255829 255830 255831 255832 255833 255834 255835 255836 255837 255838 255839 255840 255841 255842 255843 255844 255845 255846 255847 255848 255849 255850 255851 255852 255853 255854 255855 255856 255857 255858 255859 255860 255861 255862 255863 255864 255865 | i64 iRowid = sqlite3_column_int64(pScan, 0); sqlite3Fts5BufferZero(&buf); rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid); for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ int nText = 0; /* Size of pText in bytes */ const char *pText = 0; /* Pointer to buffer containing text value */ int nLoc = 0; /* Size of pLoc in bytes */ const char *pLoc = 0; /* Pointer to buffer containing text value */ sqlite3_value *pVal = sqlite3_column_value(pScan, ctx.iCol+1); if( pConfig->eContent==FTS5_CONTENT_EXTERNAL && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); }else{ pText = (const char*)sqlite3_value_text(pVal); nText = sqlite3_value_bytes(pVal); if( pConfig->bLocale ){ int iCol = ctx.iCol + 1 + pConfig->nCol; pLoc = (const char*)sqlite3_column_text(pScan, iCol); nLoc = sqlite3_column_bytes(pScan, iCol); } } if( rc==SQLITE_OK ){ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx, fts5StorageInsertCallback ); sqlite3Fts5ClearLocale(pConfig); } } sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; } p->nTotalRow++; if( rc==SQLITE_OK ){ |
︙ | ︙ | |||
253478 253479 253480 253481 253482 253483 253484 253485 | *piRowid = sqlite3_value_int64(apVal[1]); }else{ rc = fts5StorageNewRowid(p, piRowid); } }else{ sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */ int i; /* Counter variable */ rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0); | > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 255933 255934 255935 255936 255937 255938 255939 255940 255941 255942 255943 255944 255945 255946 255947 255948 255949 255950 255951 255952 255953 255954 255955 255956 255957 255958 255959 255960 255961 255962 255963 255964 255965 255966 255967 255968 255969 255970 255971 255972 255973 255974 255975 255976 255977 255978 255979 255980 255981 255982 255983 255984 255985 255986 255987 255988 255989 | *piRowid = sqlite3_value_int64(apVal[1]); }else{ rc = fts5StorageNewRowid(p, piRowid); } }else{ sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */ int i; /* Counter variable */ int nIndexed = 0; /* Number indexed columns seen */ rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0); if( pInsert ) sqlite3_clear_bindings(pInsert); /* Bind the rowid value */ sqlite3_bind_value(pInsert, 1, apVal[1]); /* Loop through values for user-defined columns. i=2 is the leftmost ** user-defined column. As is column 1 of pSavedRow. */ for(i=2; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){ int bUnindexed = pConfig->abUnindexed[i-2]; sqlite3_value *pVal = apVal[i]; nIndexed += !bUnindexed; if( sqlite3_value_nochange(pVal) && p->pSavedRow ){ /* This is an UPDATE statement, and column (i-2) was not modified. ** Retrieve the value from Fts5Storage.pSavedRow instead. */ pVal = sqlite3_column_value(p->pSavedRow, i-1); if( pConfig->bLocale && bUnindexed==0 ){ sqlite3_bind_value(pInsert, pConfig->nCol + 1 + nIndexed, sqlite3_column_value(p->pSavedRow, pConfig->nCol + i - 1) ); } }else if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ const char *pText = 0; const char *pLoc = 0; int nText = 0; int nLoc = 0; assert( pConfig->bLocale ); rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); if( rc==SQLITE_OK ){ sqlite3_bind_text(pInsert, i, pText, nText, SQLITE_TRANSIENT); if( bUnindexed==0 ){ int iLoc = pConfig->nCol + 1 + nIndexed; sqlite3_bind_text(pInsert, iLoc, pLoc, nLoc, SQLITE_TRANSIENT); } } continue; } rc = sqlite3_bind_value(pInsert, i, pVal); } if( rc==SQLITE_OK ){ sqlite3_step(pInsert); rc = sqlite3_reset(pInsert); } *piRowid = sqlite3_last_insert_rowid(pConfig->db); } |
︙ | ︙ | |||
253515 253516 253517 253518 253519 253520 253521 | if( rc==SQLITE_OK ){ rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid); } for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ | > > > > > > > > > > > > > > > > > > > > | | > > > > | | < < | | > > | 256010 256011 256012 256013 256014 256015 256016 256017 256018 256019 256020 256021 256022 256023 256024 256025 256026 256027 256028 256029 256030 256031 256032 256033 256034 256035 256036 256037 256038 256039 256040 256041 256042 256043 256044 256045 256046 256047 256048 256049 256050 256051 256052 256053 256054 256055 | if( rc==SQLITE_OK ){ rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid); } for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ int nText = 0; /* Size of pText in bytes */ const char *pText = 0; /* Pointer to buffer containing text value */ int nLoc = 0; /* Size of pText in bytes */ const char *pLoc = 0; /* Pointer to buffer containing text value */ sqlite3_value *pVal = apVal[ctx.iCol+2]; if( p->pSavedRow && sqlite3_value_nochange(pVal) ){ pVal = sqlite3_column_value(p->pSavedRow, ctx.iCol+1); if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){ int iCol = ctx.iCol + 1 + pConfig->nCol; pLoc = (const char*)sqlite3_column_text(p->pSavedRow, iCol); nLoc = sqlite3_column_bytes(p->pSavedRow, iCol); } }else{ pVal = apVal[ctx.iCol+2]; } if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); }else{ pText = (const char*)sqlite3_value_text(pVal); nText = sqlite3_value_bytes(pVal); } if( rc==SQLITE_OK ){ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx, fts5StorageInsertCallback ); sqlite3Fts5ClearLocale(pConfig); } } sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; } p->nTotalRow++; /* Write the %_docsize record */ |
︙ | ︙ | |||
253686 253687 253688 253689 253690 253691 253692 | if( pConfig->bColumnsize ){ rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize); } if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){ rc = sqlite3Fts5TermsetNew(&ctx.pTermset); } for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){ | | > > > > > > > > > > > > > > > > > > > > > > | | > | | | > | < | | | | | | | > | > > > > | > > > | | | | | | > | 256205 256206 256207 256208 256209 256210 256211 256212 256213 256214 256215 256216 256217 256218 256219 256220 256221 256222 256223 256224 256225 256226 256227 256228 256229 256230 256231 256232 256233 256234 256235 256236 256237 256238 256239 256240 256241 256242 256243 256244 256245 256246 256247 256248 256249 256250 256251 256252 256253 256254 256255 256256 256257 256258 256259 256260 256261 256262 256263 256264 256265 256266 256267 256268 256269 256270 256271 256272 256273 | if( pConfig->bColumnsize ){ rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize); } if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){ rc = sqlite3Fts5TermsetNew(&ctx.pTermset); } for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){ if( pConfig->abUnindexed[i]==0 ){ const char *pText = 0; int nText = 0; const char *pLoc = 0; int nLoc = 0; sqlite3_value *pVal = sqlite3_column_value(pScan, i+1); if( pConfig->eContent==FTS5_CONTENT_EXTERNAL && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ rc = sqlite3Fts5DecodeLocaleValue( pVal, &pText, &nText, &pLoc, &nLoc ); }else{ if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){ int iCol = i + 1 + pConfig->nCol; pLoc = (const char*)sqlite3_column_text(pScan, iCol); nLoc = sqlite3_column_bytes(pScan, iCol); } pText = (const char*)sqlite3_value_text(pVal); nText = sqlite3_value_bytes(pVal); } ctx.iCol = i; ctx.szCol = 0; if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ rc = sqlite3Fts5TermsetNew(&ctx.pTermset); } if( rc==SQLITE_OK ){ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx, fts5StorageIntegrityCallback ); sqlite3Fts5ClearLocale(pConfig); } /* If this is not a columnsize=0 database, check that the number ** of tokens in the value matches the aColSize[] value read from ** the %_docsize table. */ if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){ rc = FTS5_CORRUPT; } aTotalSize[i] += ctx.szCol; if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ sqlite3Fts5TermsetFree(ctx.pTermset); ctx.pTermset = 0; } } } sqlite3Fts5TermsetFree(ctx.pTermset); ctx.pTermset = 0; if( rc!=SQLITE_OK ) break; } |
︙ | ︙ | |||
254322 254323 254324 254325 254326 254327 254328 | /* Search for a "categories" argument */ for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ if( 0==sqlite3_stricmp(azArg[i], "categories") ){ zCat = azArg[i+1]; } } | < | 256873 256874 256875 256876 256877 256878 256879 256880 256881 256882 256883 256884 256885 256886 | /* Search for a "categories" argument */ for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ if( 0==sqlite3_stricmp(azArg[i], "categories") ){ zCat = azArg[i+1]; } } if( rc==SQLITE_OK ){ rc = unicodeSetCategories(p, zCat); } for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ const char *zArg = azArg[i+1]; if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ |
︙ | ︙ | |||
254352 254353 254354 254355 254356 254357 254358 | }else if( 0==sqlite3_stricmp(azArg[i], "categories") ){ /* no-op */ }else{ rc = SQLITE_ERROR; } } | < | 256902 256903 256904 256905 256906 256907 256908 256909 256910 256911 256912 256913 256914 256915 | }else if( 0==sqlite3_stricmp(azArg[i], "categories") ){ /* no-op */ }else{ rc = SQLITE_ERROR; } } }else{ rc = SQLITE_NOMEM; } if( rc!=SQLITE_OK ){ fts5UnicodeDelete((Fts5Tokenizer*)p); p = 0; } |
︙ | ︙ | |||
254491 254492 254493 254494 254495 254496 254497 | /* Any tokens larger than this (in bytes) are passed through without ** stemming. */ #define FTS5_PORTER_MAX_TOKEN 64 typedef struct PorterTokenizer PorterTokenizer; struct PorterTokenizer { | | | > | | > | | 257040 257041 257042 257043 257044 257045 257046 257047 257048 257049 257050 257051 257052 257053 257054 257055 257056 257057 257058 257059 257060 257061 257062 257063 257064 257065 257066 257067 257068 257069 257070 257071 257072 257073 257074 257075 257076 257077 257078 257079 257080 257081 257082 257083 257084 257085 257086 257087 257088 257089 257090 257091 257092 257093 257094 257095 257096 257097 257098 257099 257100 257101 257102 | /* Any tokens larger than this (in bytes) are passed through without ** stemming. */ #define FTS5_PORTER_MAX_TOKEN 64 typedef struct PorterTokenizer PorterTokenizer; struct PorterTokenizer { fts5_tokenizer_v2 tokenizer_v2; /* Parent tokenizer module */ Fts5Tokenizer *pTokenizer; /* Parent tokenizer instance */ char aBuf[FTS5_PORTER_MAX_TOKEN + 64]; }; /* ** Delete a "porter" tokenizer. */ static void fts5PorterDelete(Fts5Tokenizer *pTok){ if( pTok ){ PorterTokenizer *p = (PorterTokenizer*)pTok; if( p->pTokenizer ){ p->tokenizer_v2.xDelete(p->pTokenizer); } sqlite3_free(p); } } /* ** Create a "porter" tokenizer. */ static int fts5PorterCreate( void *pCtx, const char **azArg, int nArg, Fts5Tokenizer **ppOut ){ fts5_api *pApi = (fts5_api*)pCtx; int rc = SQLITE_OK; PorterTokenizer *pRet; void *pUserdata = 0; const char *zBase = "unicode61"; fts5_tokenizer_v2 *pV2 = 0; if( nArg>0 ){ zBase = azArg[0]; } pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer)); if( pRet ){ memset(pRet, 0, sizeof(PorterTokenizer)); rc = pApi->xFindTokenizer_v2(pApi, zBase, &pUserdata, &pV2); }else{ rc = SQLITE_NOMEM; } if( rc==SQLITE_OK ){ int nArg2 = (nArg>0 ? nArg-1 : 0); const char **az2 = (nArg2 ? &azArg[1] : 0); memcpy(&pRet->tokenizer_v2, pV2, sizeof(fts5_tokenizer_v2)); rc = pRet->tokenizer_v2.xCreate(pUserdata, az2, nArg2, &pRet->pTokenizer); } if( rc!=SQLITE_OK ){ fts5PorterDelete((Fts5Tokenizer*)pRet); pRet = 0; } *ppOut = (Fts5Tokenizer*)pRet; |
︙ | ︙ | |||
255188 255189 255190 255191 255192 255193 255194 255195 255196 255197 255198 255199 255200 255201 | ** Tokenize using the porter tokenizer. */ static int fts5PorterTokenize( Fts5Tokenizer *pTokenizer, void *pCtx, int flags, const char *pText, int nText, int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd) ){ PorterTokenizer *p = (PorterTokenizer*)pTokenizer; PorterContext sCtx; sCtx.xToken = xToken; sCtx.pCtx = pCtx; sCtx.aBuf = p->aBuf; | > | | | 257739 257740 257741 257742 257743 257744 257745 257746 257747 257748 257749 257750 257751 257752 257753 257754 257755 257756 257757 257758 257759 257760 257761 257762 | ** Tokenize using the porter tokenizer. */ static int fts5PorterTokenize( Fts5Tokenizer *pTokenizer, void *pCtx, int flags, const char *pText, int nText, const char *pLoc, int nLoc, int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd) ){ PorterTokenizer *p = (PorterTokenizer*)pTokenizer; PorterContext sCtx; sCtx.xToken = xToken; sCtx.pCtx = pCtx; sCtx.aBuf = p->aBuf; return p->tokenizer_v2.xTokenize( p->pTokenizer, (void*)&sCtx, flags, pText, nText, pLoc, nLoc, fts5PorterCb ); } /************************************************************************** ** Start of trigram implementation. */ typedef struct TrigramTokenizer TrigramTokenizer; |
︙ | ︙ | |||
255226 255227 255228 255229 255230 255231 255232 | static int fts5TriCreate( void *pUnused, const char **azArg, int nArg, Fts5Tokenizer **ppOut ){ int rc = SQLITE_OK; | | | | > > > > | | > | | | | | | | | | | | | | | | | | | | | | | | | > | 257778 257779 257780 257781 257782 257783 257784 257785 257786 257787 257788 257789 257790 257791 257792 257793 257794 257795 257796 257797 257798 257799 257800 257801 257802 257803 257804 257805 257806 257807 257808 257809 257810 257811 257812 257813 257814 257815 257816 257817 257818 257819 257820 257821 257822 257823 257824 257825 257826 257827 257828 257829 257830 257831 | static int fts5TriCreate( void *pUnused, const char **azArg, int nArg, Fts5Tokenizer **ppOut ){ int rc = SQLITE_OK; TrigramTokenizer *pNew = 0; UNUSED_PARAM(pUnused); if( nArg%2 ){ rc = SQLITE_ERROR; }else{ int i; pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew)); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ pNew->bFold = 1; pNew->iFoldParam = 0; for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ const char *zArg = azArg[i+1]; if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){ rc = SQLITE_ERROR; }else{ pNew->bFold = (zArg[0]=='0'); } }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ rc = SQLITE_ERROR; }else{ pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0; } }else{ rc = SQLITE_ERROR; } } if( pNew->iFoldParam!=0 && pNew->bFold==0 ){ rc = SQLITE_ERROR; } if( rc!=SQLITE_OK ){ fts5TriDelete((Fts5Tokenizer*)pNew); pNew = 0; } } } *ppOut = (Fts5Tokenizer*)pNew; return rc; } /* |
︙ | ︙ | |||
255363 255364 255365 255366 255367 255368 255369 255370 255371 255372 255373 255374 255375 255376 255377 255378 255379 255380 | TrigramTokenizer *p = (TrigramTokenizer*)pTok; if( p->iFoldParam==0 ){ return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB; } } return FTS5_PATTERN_NONE; } /* ** Register all built-in tokenizers with FTS5. */ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ struct BuiltinTokenizer { const char *zName; fts5_tokenizer x; } aBuiltin[] = { { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}}, { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }}, | > > > > > > > > > > < > > > > > > > > > > > | > > | 257921 257922 257923 257924 257925 257926 257927 257928 257929 257930 257931 257932 257933 257934 257935 257936 257937 257938 257939 257940 257941 257942 257943 257944 257945 257946 257947 257948 257949 257950 257951 257952 257953 257954 257955 257956 257957 257958 257959 257960 257961 257962 257963 257964 257965 257966 257967 257968 257969 257970 257971 257972 257973 257974 257975 257976 257977 257978 257979 257980 257981 257982 257983 | TrigramTokenizer *p = (TrigramTokenizer*)pTok; if( p->iFoldParam==0 ){ return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB; } } return FTS5_PATTERN_NONE; } /* ** Return true if the tokenizer described by p->azArg[] is the trigram ** tokenizer. This tokenizer needs to be loaded before xBestIndex is ** called for the first time in order to correctly handle LIKE/GLOB. */ static int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig *p){ return (p->nArg>=1 && 0==sqlite3_stricmp(p->azArg[0], "trigram")); } /* ** Register all built-in tokenizers with FTS5. */ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ struct BuiltinTokenizer { const char *zName; fts5_tokenizer x; } aBuiltin[] = { { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}}, { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }}, { "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}}, }; 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 ); } if( rc==SQLITE_OK ){ fts5_tokenizer_v2 sPorter = { 2, fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }; rc = pApi->xCreateTokenizer_v2(pApi, "porter", (void*)pApi, &sPorter, 0 ); } return rc; } /* ** 2012-05-25 ** ** The author disclaims copyright to this source code. In place of |
︙ | ︙ | |||
255759 255760 255761 255762 255763 255764 255765 255766 255767 255768 255769 255770 255771 255772 | aArray[27] = 1; aArray[28] = 1; aArray[29] = 1; break; default: return 1; } break; } return 0; } static u16 aFts5UnicodeBlock[] = { 0, 1471, 1753, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1763, 1765, | > > > | 258339 258340 258341 258342 258343 258344 258345 258346 258347 258348 258349 258350 258351 258352 258353 258354 258355 | aArray[27] = 1; aArray[28] = 1; aArray[29] = 1; break; default: return 1; } break; default: return 1; } return 0; } static u16 aFts5UnicodeBlock[] = { 0, 1471, 1753, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1763, 1765, |
︙ | ︙ | |||
256583 256584 256585 256586 256587 256588 256589 256590 256591 256592 256593 256594 256595 256596 | int bEof; /* True if this cursor is at EOF */ Fts5IndexIter *pIter; /* Term/rowid iterator object */ void *pStruct; /* From sqlite3Fts5StructureRef() */ int nLeTerm; /* Size of zLeTerm in bytes */ char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */ /* These are used by 'col' tables only */ int iCol; i64 *aCnt; i64 *aDoc; /* Output values used by all tables. */ | > | 259166 259167 259168 259169 259170 259171 259172 259173 259174 259175 259176 259177 259178 259179 259180 | int bEof; /* True if this cursor is at EOF */ Fts5IndexIter *pIter; /* Term/rowid iterator object */ void *pStruct; /* From sqlite3Fts5StructureRef() */ int nLeTerm; /* Size of zLeTerm in bytes */ char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */ int colUsed; /* Copy of sqlite3_index_info.colUsed */ /* These are used by 'col' tables only */ int iCol; i64 *aCnt; i64 *aDoc; /* Output values used by all tables. */ |
︙ | ︙ | |||
256609 256610 256611 256612 256613 256614 256615 | #define FTS5_VOCAB_COL_SCHEMA "term, col, doc, cnt" #define FTS5_VOCAB_ROW_SCHEMA "term, doc, cnt" #define FTS5_VOCAB_INST_SCHEMA "term, doc, col, offset" /* ** Bits for the mask used as the idxNum value by xBestIndex/xFilter. */ | | | | > > | 259193 259194 259195 259196 259197 259198 259199 259200 259201 259202 259203 259204 259205 259206 259207 259208 259209 259210 259211 | #define FTS5_VOCAB_COL_SCHEMA "term, col, doc, cnt" #define FTS5_VOCAB_ROW_SCHEMA "term, doc, cnt" #define FTS5_VOCAB_INST_SCHEMA "term, doc, col, offset" /* ** Bits for the mask used as the idxNum value by xBestIndex/xFilter. */ #define FTS5_VOCAB_TERM_EQ 0x0100 #define FTS5_VOCAB_TERM_GE 0x0200 #define FTS5_VOCAB_TERM_LE 0x0400 #define FTS5_VOCAB_COLUSED_MASK 0xFF /* ** Translate a string containing an fts5vocab table type to an ** FTS5_VOCAB_XXX constant. If successful, set *peType to the output ** value and return SQLITE_OK. Otherwise, set *pzErr to an error message ** and return SQLITE_ERROR. |
︙ | ︙ | |||
256788 256789 256790 256791 256792 256793 256794 | sqlite3_vtab *pUnused, sqlite3_index_info *pInfo ){ int i; int iTermEq = -1; int iTermGe = -1; int iTermLe = -1; | | > > | 259374 259375 259376 259377 259378 259379 259380 259381 259382 259383 259384 259385 259386 259387 259388 259389 259390 259391 259392 259393 | sqlite3_vtab *pUnused, sqlite3_index_info *pInfo ){ int i; int iTermEq = -1; int iTermGe = -1; int iTermLe = -1; int idxNum = (int)pInfo->colUsed; int nArg = 0; UNUSED_PARAM(pUnused); assert( (pInfo->colUsed & FTS5_VOCAB_COLUSED_MASK)==pInfo->colUsed ); for(i=0; i<pInfo->nConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; if( p->usable==0 ) continue; if( p->iColumn==0 ){ /* term column */ if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i; if( p->op==SQLITE_INDEX_CONSTRAINT_LE ) iTermLe = i; |
︙ | ︙ | |||
256884 256885 256886 256887 256888 256889 256890 | if( rc==SQLITE_OK ){ if( pFts5==0 ){ rc = sqlite3_finalize(pStmt); pStmt = 0; if( rc==SQLITE_OK ){ pVTab->zErrMsg = sqlite3_mprintf( "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl | | | 259472 259473 259474 259475 259476 259477 259478 259479 259480 259481 259482 259483 259484 259485 259486 | if( rc==SQLITE_OK ){ if( pFts5==0 ){ rc = sqlite3_finalize(pStmt); pStmt = 0; if( rc==SQLITE_OK ){ pVTab->zErrMsg = sqlite3_mprintf( "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl ); rc = SQLITE_ERROR; } }else{ rc = sqlite3Fts5FlushToDisk(pFts5); } } |
︙ | ︙ | |||
257044 257045 257046 257047 257048 257049 257050 | int iOff = 0; /* Current offset within position list */ pPos = pCsr->pIter->pData; nPos = pCsr->pIter->nData; switch( pTab->eType ){ case FTS5_VOCAB_ROW: | > > | | > > > > > > > | > | 259632 259633 259634 259635 259636 259637 259638 259639 259640 259641 259642 259643 259644 259645 259646 259647 259648 259649 259650 259651 259652 259653 259654 259655 259656 259657 259658 | int iOff = 0; /* Current offset within position list */ pPos = pCsr->pIter->pData; nPos = pCsr->pIter->nData; switch( pTab->eType ){ case FTS5_VOCAB_ROW: /* Do not bother counting the number of instances if the "cnt" ** column is not being read (according to colUsed). */ if( eDetail==FTS5_DETAIL_FULL && (pCsr->colUsed & 0x04) ){ while( iPos<nPos ){ u32 ii; fts5FastGetVarint32(pPos, iPos, ii); if( ii==1 ){ /* New column in the position list */ fts5FastGetVarint32(pPos, iPos, ii); }else{ /* An instance - increment pCsr->aCnt[] */ pCsr->aCnt[0]++; } } } pCsr->aDoc[0]++; break; case FTS5_VOCAB_COL: if( eDetail==FTS5_DETAIL_FULL ){ |
︙ | ︙ | |||
257144 257145 257146 257147 257148 257149 257150 257151 257152 257153 257154 257155 257156 257157 | UNUSED_PARAM2(zUnused, nUnused); fts5VocabResetCursor(pCsr); if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++]; if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++]; if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; if( pEq ){ zTerm = (const char *)sqlite3_value_text(pEq); nTerm = sqlite3_value_bytes(pEq); f = FTS5INDEX_QUERY_NOTOKENDATA; }else{ if( pGe ){ | > | 259742 259743 259744 259745 259746 259747 259748 259749 259750 259751 259752 259753 259754 259755 259756 | UNUSED_PARAM2(zUnused, nUnused); fts5VocabResetCursor(pCsr); if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++]; if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++]; if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; pCsr->colUsed = (idxNum & FTS5_VOCAB_COLUSED_MASK); if( pEq ){ zTerm = (const char *)sqlite3_value_text(pEq); nTerm = sqlite3_value_bytes(pEq); f = FTS5INDEX_QUERY_NOTOKENDATA; }else{ if( pGe ){ |
︙ | ︙ | |||
257706 257707 257708 257709 257710 257711 257712 257713 | /* ** If requested, include the SQLite compiler options file for MSVC. */ #if defined(INCLUDE_MSVC_H) # include "msvc.h" #endif #if defined(INCLUDE_SQLITE_TCL_H) | > | | | > > > > > > > > | 260305 260306 260307 260308 260309 260310 260311 260312 260313 260314 260315 260316 260317 260318 260319 260320 260321 260322 260323 260324 260325 260326 260327 260328 260329 260330 260331 260332 260333 260334 260335 | /* ** If requested, include the SQLite compiler options file for MSVC. */ #if defined(INCLUDE_MSVC_H) # include "msvc.h" #endif /****** Copy of tclsqlite.h ******/ #if defined(INCLUDE_SQLITE_TCL_H) # include "sqlite_tcl.h" /* Special case for Windows using STDCALL */ #else # include <tcl.h> /* All normal cases */ # ifndef SQLITE_TCLAPI # define SQLITE_TCLAPI # endif #endif /* Compatability between Tcl8.6 and Tcl9.0 */ #if TCL_MAJOR_VERSION==9 # define CONST const #else typedef int Tcl_Size; #endif /**** End copy of tclsqlite.h ****/ #include <errno.h> /* ** Some additional include files are needed if this file is not ** appended to the amalgamation. */ #ifndef SQLITE_AMALGAMATION |
︙ | ︙ | |||
257880 257881 257882 257883 257884 257885 257886 | int bLegacyPrepare; /* True to use sqlite3_prepare() */ #endif }; struct IncrblobChannel { sqlite3_blob *pBlob; /* sqlite3 blob handle */ SqliteDb *pDb; /* Associated database connection */ | | > | 260488 260489 260490 260491 260492 260493 260494 260495 260496 260497 260498 260499 260500 260501 260502 260503 | int bLegacyPrepare; /* True to use sqlite3_prepare() */ #endif }; struct IncrblobChannel { sqlite3_blob *pBlob; /* sqlite3 blob handle */ SqliteDb *pDb; /* Associated database connection */ sqlite3_int64 iSeek; /* Current seek offset */ unsigned int isClosed; /* TCL_CLOSE_READ or TCL_CLOSE_WRITE */ Tcl_Channel channel; /* Channel identifier */ IncrblobChannel *pNext; /* Linked list of all open incrblob channels */ IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */ }; /* ** Compute a string length that is limited to what can be stored in |
︙ | ︙ | |||
257920 257921 257922 257923 257924 257925 257926 | Tcl_UnregisterChannel(pDb->interp, p->channel); } } /* ** Close an incremental blob channel. */ | | | > | > > > > > > > > > > > > > > > | | | | | | | | > > > > > > > | | | 260529 260530 260531 260532 260533 260534 260535 260536 260537 260538 260539 260540 260541 260542 260543 260544 260545 260546 260547 260548 260549 260550 260551 260552 260553 260554 260555 260556 260557 260558 260559 260560 260561 260562 260563 260564 260565 260566 260567 260568 260569 260570 260571 260572 260573 260574 260575 260576 260577 260578 260579 260580 260581 260582 260583 260584 260585 260586 260587 260588 260589 260590 260591 260592 260593 260594 260595 260596 260597 260598 260599 260600 260601 260602 260603 260604 260605 260606 260607 260608 260609 260610 260611 260612 260613 260614 260615 260616 260617 260618 260619 260620 260621 260622 260623 260624 260625 260626 260627 260628 260629 260630 260631 260632 260633 260634 260635 260636 260637 260638 260639 260640 260641 260642 260643 260644 260645 260646 260647 260648 260649 260650 260651 260652 260653 260654 260655 260656 260657 260658 260659 260660 260661 260662 260663 260664 260665 | Tcl_UnregisterChannel(pDb->interp, p->channel); } } /* ** Close an incremental blob channel. */ static int SQLITE_TCLAPI incrblobClose2( ClientData instanceData, Tcl_Interp *interp, int flags ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; int rc; sqlite3 *db = p->pDb->db; if( flags ){ p->isClosed |= flags; return TCL_OK; } /* If we reach this point, then we really do need to close the channel */ rc = sqlite3_blob_close(p->pBlob); /* Remove the channel from the SqliteDb.pIncrblob list. */ if( p->pNext ){ p->pNext->pPrev = p->pPrev; } if( p->pPrev ){ p->pPrev->pNext = p->pNext; } if( p->pDb->pIncrblob==p ){ p->pDb->pIncrblob = p->pNext; } /* Free the IncrblobChannel structure */ Tcl_Free((char *)p); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; } static int SQLITE_TCLAPI incrblobClose( ClientData instanceData, Tcl_Interp *interp ){ return incrblobClose2(instanceData, interp, 0); } /* ** Read data from an incremental blob channel. */ static int SQLITE_TCLAPI incrblobInput( ClientData instanceData, char *buf, int bufSize, int *errorCodePtr ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; sqlite3_int64 nRead = bufSize; /* Number of bytes to read */ sqlite3_int64 nBlob; /* Total size of the blob */ int rc; /* sqlite error code */ nBlob = sqlite3_blob_bytes(p->pBlob); if( (p->iSeek+nRead)>nBlob ){ nRead = nBlob-p->iSeek; } if( nRead<=0 ){ return 0; } rc = sqlite3_blob_read(p->pBlob, (void *)buf, (int)nRead, (int)p->iSeek); if( rc!=SQLITE_OK ){ *errorCodePtr = rc; return -1; } p->iSeek += nRead; return nRead; } /* ** Write data to an incremental blob channel. */ static int SQLITE_TCLAPI incrblobOutput( ClientData instanceData, CONST char *buf, int toWrite, int *errorCodePtr ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; sqlite3_int64 nWrite = toWrite; /* Number of bytes to write */ sqlite3_int64 nBlob; /* Total size of the blob */ int rc; /* sqlite error code */ nBlob = sqlite3_blob_bytes(p->pBlob); if( (p->iSeek+nWrite)>nBlob ){ *errorCodePtr = EINVAL; return -1; } if( nWrite<=0 ){ return 0; } rc = sqlite3_blob_write(p->pBlob, (void*)buf,(int)nWrite, (int)p->iSeek); if( rc!=SQLITE_OK ){ *errorCodePtr = EIO; return -1; } p->iSeek += nWrite; return nWrite; } /* The datatype of Tcl_DriverWideSeekProc changes between tcl8.6 and tcl9.0 */ #if TCL_MAJOR_VERSION==9 # define WideSeekProcType long long #else # define WideSeekProcType Tcl_WideInt #endif /* ** Seek an incremental blob channel. */ static WideSeekProcType SQLITE_TCLAPI incrblobWideSeek( ClientData instanceData, WideSeekProcType offset, int seekMode, int *errorCodePtr ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; switch( seekMode ){ case SEEK_SET: |
︙ | ︙ | |||
258041 258042 258043 258044 258045 258046 258047 258048 258049 258050 258051 258052 258053 258054 258055 258056 258057 258058 258059 258060 258061 258062 258063 258064 258065 | break; default: assert(!"Bad seekMode"); } return p->iSeek; } static void SQLITE_TCLAPI incrblobWatch( ClientData instanceData, int mode ){ /* NO-OP */ } static int SQLITE_TCLAPI incrblobHandle( ClientData instanceData, int dir, ClientData *hPtr ){ return TCL_ERROR; } static Tcl_ChannelType IncrblobChannelType = { "incrblob", /* typeName */ | > > > > > > > > | | | | 260673 260674 260675 260676 260677 260678 260679 260680 260681 260682 260683 260684 260685 260686 260687 260688 260689 260690 260691 260692 260693 260694 260695 260696 260697 260698 260699 260700 260701 260702 260703 260704 260705 260706 260707 260708 260709 260710 260711 260712 260713 260714 260715 260716 260717 260718 260719 260720 260721 260722 260723 260724 260725 260726 | break; default: assert(!"Bad seekMode"); } return p->iSeek; } static int SQLITE_TCLAPI incrblobSeek( ClientData instanceData, long offset, int seekMode, int *errorCodePtr ){ return incrblobWideSeek(instanceData,offset,seekMode,errorCodePtr); } static void SQLITE_TCLAPI incrblobWatch( ClientData instanceData, int mode ){ /* NO-OP */ } static int SQLITE_TCLAPI incrblobHandle( ClientData instanceData, int dir, ClientData *hPtr ){ return TCL_ERROR; } static Tcl_ChannelType IncrblobChannelType = { "incrblob", /* typeName */ TCL_CHANNEL_VERSION_5, /* version */ incrblobClose, /* closeProc */ incrblobInput, /* inputProc */ incrblobOutput, /* outputProc */ incrblobSeek, /* seekProc */ 0, /* setOptionProc */ 0, /* getOptionProc */ incrblobWatch, /* watchProc (this is a no-op) */ incrblobHandle, /* getHandleProc (always returns error) */ incrblobClose2, /* close2Proc */ 0, /* blockModeProc */ 0, /* flushProc */ 0, /* handlerProc */ incrblobWideSeek, /* wideSeekProc */ }; /* ** Create a new incrblob channel. */ static int createIncrblobChannel( Tcl_Interp *interp, |
︙ | ︙ | |||
258104 258105 258106 258107 258108 258109 258110 | rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); return TCL_ERROR; } p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel)); | | > | 260744 260745 260746 260747 260748 260749 260750 260751 260752 260753 260754 260755 260756 260757 260758 260759 260760 | rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); return TCL_ERROR; } p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel)); memset(p, 0, sizeof(*p)); p->pBlob = pBlob; if( (flags & TCL_WRITABLE)==0 ) p->isClosed |= TCL_CLOSE_WRITE; sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count); p->channel = Tcl_CreateChannel(&IncrblobChannelType, zChannel, p, flags); Tcl_RegisterChannel(interp, p->channel); /* Link the new channel into the SqliteDb.pIncrblob list. */ p->pNext = pDb->pIncrblob; |
︙ | ︙ | |||
258145 258146 258147 258148 258149 258150 258151 | */ static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){ /* We could try to do something with Tcl_Parse(). But we will instead ** just do a search for forbidden characters. If any of the forbidden ** characters appear in pCmd, we will report the string as unsafe. */ const char *z; | | | 260786 260787 260788 260789 260790 260791 260792 260793 260794 260795 260796 260797 260798 260799 260800 | */ static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){ /* We could try to do something with Tcl_Parse(). But we will instead ** just do a search for forbidden characters. If any of the forbidden ** characters appear in pCmd, we will report the string as unsafe. */ const char *z; Tcl_Size n; z = Tcl_GetStringFromObj(pCmd, &n); while( n-- > 0 ){ int c = *(z++); if( c=='$' || c=='[' || c==';' ) return 0; } return 1; } |
︙ | ︙ | |||
258652 258653 258654 258655 258656 258657 258658 | ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated. ** The new Tcl_Obj contains pointers to the original list elements. ** That way, when Tcl_EvalObjv() is run and shimmers the first element ** of the list to tclCmdNameType, that alternate representation will ** be preserved and reused on the next invocation. */ Tcl_Obj **aArg; | | | 261293 261294 261295 261296 261297 261298 261299 261300 261301 261302 261303 261304 261305 261306 261307 | ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated. ** The new Tcl_Obj contains pointers to the original list elements. ** That way, when Tcl_EvalObjv() is run and shimmers the first element ** of the list to tclCmdNameType, that alternate representation will ** be preserved and reused on the next invocation. */ Tcl_Obj **aArg; Tcl_Size nArg; if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){ sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); return; } pCmd = Tcl_NewListObj(nArg, aArg); Tcl_IncrRefCount(pCmd); for(i=0; i<argc; i++){ |
︙ | ︙ | |||
258715 258716 258717 258718 258719 258720 258721 | Tcl_DecrRefCount(pCmd); } if( rc && rc!=TCL_RETURN ){ sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); }else{ Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); | | | 261356 261357 261358 261359 261360 261361 261362 261363 261364 261365 261366 261367 261368 261369 261370 | Tcl_DecrRefCount(pCmd); } if( rc && rc!=TCL_RETURN ){ sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); }else{ Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); Tcl_Size n; u8 *data; const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); char c = zType[0]; int eType = p->eType; if( eType==SQLITE_NULL ){ if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){ |
︙ | ︙ | |||
259126 259127 259128 259129 259130 259131 259132 | rc = TCL_ERROR; break; }else{ pVar = 0; } } if( pVar ){ | | > | | | 261767 261768 261769 261770 261771 261772 261773 261774 261775 261776 261777 261778 261779 261780 261781 261782 261783 261784 261785 261786 261787 261788 261789 261790 261791 261792 261793 261794 261795 261796 261797 | rc = TCL_ERROR; break; }else{ pVar = 0; } } if( pVar ){ Tcl_Size n; u8 *data; const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); c = zType[0]; if( zVar[0]=='@' || (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){ /* Load a BLOB type if the Tcl variable is a bytearray and ** it has no string representation or the host ** parameter name begins with "@". */ data = Tcl_GetByteArrayFromObj(pVar, &n); sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC); Tcl_IncrRefCount(pVar); pPreStmt->apParm[iParm++] = pVar; }else if( c=='b' && strcmp(zType,"boolean")==0 ){ int nn; Tcl_GetIntFromObj(interp, pVar, &nn); sqlite3_bind_int(pStmt, i, nn); }else if( c=='d' && strcmp(zType,"double")==0 ){ double r; Tcl_GetDoubleFromObj(interp, pVar, &r); sqlite3_bind_double(pStmt, i, r); }else if( (c=='w' && strcmp(zType,"wideInt")==0) || (c=='i' && strcmp(zType,"int")==0) ){ Tcl_WideInt v; |
︙ | ︙ | |||
259705 259706 259707 259708 259709 259710 259711 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zAuth ){ Tcl_AppendResult(interp, pDb->zAuth, (char*)0); } }else{ char *zAuth; | | | 262347 262348 262349 262350 262351 262352 262353 262354 262355 262356 262357 262358 262359 262360 262361 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zAuth ){ Tcl_AppendResult(interp, pDb->zAuth, (char*)0); } }else{ char *zAuth; Tcl_Size len; if( pDb->zAuth ){ Tcl_Free(pDb->zAuth); } zAuth = Tcl_GetStringFromObj(objv[2], &len); if( zAuth && len>0 ){ pDb->zAuth = Tcl_Alloc( len + 1 ); memcpy(pDb->zAuth, zAuth, len+1); |
︙ | ︙ | |||
259808 259809 259810 259811 259812 259813 259814 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zBindFallback ){ Tcl_AppendResult(interp, pDb->zBindFallback, (char*)0); } }else{ char *zCallback; | | | 262450 262451 262452 262453 262454 262455 262456 262457 262458 262459 262460 262461 262462 262463 262464 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zBindFallback ){ Tcl_AppendResult(interp, pDb->zBindFallback, (char*)0); } }else{ char *zCallback; Tcl_Size len; if( pDb->zBindFallback ){ Tcl_Free(pDb->zBindFallback); } zCallback = Tcl_GetStringFromObj(objv[2], &len); if( zCallback && len>0 ){ pDb->zBindFallback = Tcl_Alloc( len + 1 ); memcpy(pDb->zBindFallback, zCallback, len+1); |
︙ | ︙ | |||
259838 259839 259840 259841 259842 259843 259844 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zBusy ){ Tcl_AppendResult(interp, pDb->zBusy, (char*)0); } }else{ char *zBusy; | | | 262480 262481 262482 262483 262484 262485 262486 262487 262488 262489 262490 262491 262492 262493 262494 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zBusy ){ Tcl_AppendResult(interp, pDb->zBusy, (char*)0); } }else{ char *zBusy; Tcl_Size len; if( pDb->zBusy ){ Tcl_Free(pDb->zBusy); } zBusy = Tcl_GetStringFromObj(objv[2], &len); if( zBusy && len>0 ){ pDb->zBusy = Tcl_Alloc( len + 1 ); memcpy(pDb->zBusy, zBusy, len+1); |
︙ | ︙ | |||
259945 259946 259947 259948 259949 259950 259951 | ** Create a new SQL collation function called NAME. Whenever ** that function is called, invoke SCRIPT to evaluate the function. */ case DB_COLLATE: { SqlCollate *pCollate; char *zName; char *zScript; | | | 262587 262588 262589 262590 262591 262592 262593 262594 262595 262596 262597 262598 262599 262600 262601 | ** Create a new SQL collation function called NAME. Whenever ** that function is called, invoke SCRIPT to evaluate the function. */ case DB_COLLATE: { SqlCollate *pCollate; char *zName; char *zScript; Tcl_Size nScript; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT"); return TCL_ERROR; } zName = Tcl_GetStringFromObj(objv[2], 0); zScript = Tcl_GetStringFromObj(objv[3], &nScript); pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 ); |
︙ | ︙ | |||
260004 260005 260006 260007 260008 260009 260010 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zCommit ){ Tcl_AppendResult(interp, pDb->zCommit, (char*)0); } }else{ const char *zCommit; | | | 262646 262647 262648 262649 262650 262651 262652 262653 262654 262655 262656 262657 262658 262659 262660 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zCommit ){ Tcl_AppendResult(interp, pDb->zCommit, (char*)0); } }else{ const char *zCommit; Tcl_Size len; if( pDb->zCommit ){ Tcl_Free(pDb->zCommit); } zCommit = Tcl_GetStringFromObj(objv[2], &len); if( zCommit && len>0 ){ pDb->zCommit = Tcl_Alloc( len + 1 ); memcpy(pDb->zCommit, zCommit, len+1); |
︙ | ︙ | |||
260324 260325 260326 260327 260328 260329 260330 | (char*)0); rc = TCL_ERROR; #else const char *zSchema = 0; Tcl_Obj *pValue = 0; unsigned char *pBA; unsigned char *pData; | > | | 262966 262967 262968 262969 262970 262971 262972 262973 262974 262975 262976 262977 262978 262979 262980 262981 | (char*)0); rc = TCL_ERROR; #else const char *zSchema = 0; Tcl_Obj *pValue = 0; unsigned char *pBA; unsigned char *pData; Tcl_Size len; int xrc; sqlite3_int64 mxSize = 0; int i; int isReadonly = 0; if( objc<3 ){ Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE"); |
︙ | ︙ | |||
260695 260696 260697 260698 260699 260700 260701 | */ case DB_NULLVALUE: { if( objc!=2 && objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE"); return TCL_ERROR; } if( objc==3 ){ | | | 263338 263339 263340 263341 263342 263343 263344 263345 263346 263347 263348 263349 263350 263351 263352 | */ case DB_NULLVALUE: { if( objc!=2 && objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE"); return TCL_ERROR; } if( objc==3 ){ Tcl_Size len; char *zNull = Tcl_GetStringFromObj(objv[2], &len); if( pDb->zNull ){ Tcl_Free(pDb->zNull); } if( zNull && len>0 ){ pDb->zNull = Tcl_Alloc( len + 1 ); memcpy(pDb->zNull, zNull, len); |
︙ | ︙ | |||
260749 260750 260751 260752 260753 260754 260755 | Tcl_AppendResult(interp, pDb->zProgress, (char*)0); } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK sqlite3_progress_handler(pDb->db, 0, 0, 0); #endif }else if( objc==4 ){ char *zProgress; | | | 263392 263393 263394 263395 263396 263397 263398 263399 263400 263401 263402 263403 263404 263405 263406 | Tcl_AppendResult(interp, pDb->zProgress, (char*)0); } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK sqlite3_progress_handler(pDb->db, 0, 0, 0); #endif }else if( objc==4 ){ char *zProgress; Tcl_Size len; int N; if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){ return TCL_ERROR; }; if( pDb->zProgress ){ Tcl_Free(pDb->zProgress); } |
︙ | ︙ | |||
260795 260796 260797 260798 260799 260800 260801 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zProfile ){ Tcl_AppendResult(interp, pDb->zProfile, (char*)0); } }else{ char *zProfile; | | | 263438 263439 263440 263441 263442 263443 263444 263445 263446 263447 263448 263449 263450 263451 263452 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zProfile ){ Tcl_AppendResult(interp, pDb->zProfile, (char*)0); } }else{ char *zProfile; Tcl_Size len; if( pDb->zProfile ){ Tcl_Free(pDb->zProfile); } zProfile = Tcl_GetStringFromObj(objv[2], &len); if( zProfile && len>0 ){ pDb->zProfile = Tcl_Alloc( len + 1 ); memcpy(pDb->zProfile, zProfile, len+1); |
︙ | ︙ | |||
261006 261007 261008 261009 261010 261011 261012 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zTrace ){ Tcl_AppendResult(interp, pDb->zTrace, (char*)0); } }else{ char *zTrace; | | | 263649 263650 263651 263652 263653 263654 263655 263656 263657 263658 263659 263660 263661 263662 263663 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zTrace ){ Tcl_AppendResult(interp, pDb->zTrace, (char*)0); } }else{ char *zTrace; Tcl_Size len; if( pDb->zTrace ){ Tcl_Free(pDb->zTrace); } zTrace = Tcl_GetStringFromObj(objv[2], &len); if( zTrace && len>0 ){ pDb->zTrace = Tcl_Alloc( len + 1 ); memcpy(pDb->zTrace, zTrace, len+1); |
︙ | ︙ | |||
261046 261047 261048 261049 261050 261051 261052 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zTraceV2 ){ Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0); } }else{ char *zTraceV2; | | | 263689 263690 263691 263692 263693 263694 263695 263696 263697 263698 263699 263700 263701 263702 263703 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zTraceV2 ){ Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0); } }else{ char *zTraceV2; Tcl_Size len; Tcl_WideInt wMask = 0; if( objc==4 ){ static const char *TTYPE_strs[] = { "statement", "profile", "row", "close", 0 }; enum TTYPE_enum { TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE |
︙ | ︙ | |||
261632 261633 261634 261635 261636 261637 261638 | /* Because it accesses the file-system and uses persistent state, SQLite ** is not considered appropriate for safe interpreters. Hence, we cause ** the _SafeInit() interfaces return TCL_ERROR. */ EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; } EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;} | | | | > > > > > | | | | > > | > > > > | 264275 264276 264277 264278 264279 264280 264281 264282 264283 264284 264285 264286 264287 264288 264289 264290 264291 264292 264293 264294 264295 264296 264297 264298 264299 264300 264301 264302 264303 264304 264305 264306 264307 | /* Because it accesses the file-system and uses persistent state, SQLite ** is not considered appropriate for safe interpreters. Hence, we cause ** the _SafeInit() interfaces return TCL_ERROR. */ EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; } EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;} /* ** Versions of all of the above entry points that omit the "3" at the end ** of the name. Years ago (circa 2004) the "3" was necessary to distinguish ** SQLite version 3 from Sqlite version 2. But two decades have elapsed. ** SQLite2 is not longer a conflict. So it is ok to omit the "3". ** ** Omitting the "3" helps TCL find the entry point. */ EXTERN int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} EXTERN int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } EXTERN int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } EXTERN int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } EXTERN int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; } EXTERN int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;} /* Also variants with a lowercase "s" */ EXTERN int sqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} EXTERN int sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} /* ** If the TCLSH macro is defined, add code to make a stand-alone program. */ #if defined(TCLSH) /* This is the main routine for an ordinary TCL shell. If there are |
︙ | ︙ |