Fossil SCM
Update the built-in SQLite to the lastest 3.8.5 beta from trunk.
Commit
85d2a1120e32a41df622f3ebf0ad2578e43f8c33
Parent
a74d100a121219b…
2 files changed
+2003
-1274
+94
-10
+2003
-1274
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -222,11 +222,11 @@ | ||
| 222 | 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | 224 | */ |
| 225 | 225 | #define SQLITE_VERSION "3.8.5" |
| 226 | 226 | #define SQLITE_VERSION_NUMBER 3008005 |
| 227 | -#define SQLITE_SOURCE_ID "2014-04-18 22:20:31 9a5d38c79d2482a23bcfbc3ff35ca4fa269c768d" | |
| 227 | +#define SQLITE_SOURCE_ID "2014-05-24 17:15:15 ebfb51fe40756713d269b4c0ade752666910bb6e" | |
| 228 | 228 | |
| 229 | 229 | /* |
| 230 | 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | 232 | ** |
| @@ -673,11 +673,14 @@ | ||
| 673 | 673 | ** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that |
| 674 | 674 | ** after reboot following a crash or power loss, the only bytes in a |
| 675 | 675 | ** file that were written at the application level might have changed |
| 676 | 676 | ** and that adjacent bytes, even bytes within the same sector are |
| 677 | 677 | ** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
| 678 | -** flag indicate that a file cannot be deleted when open. | |
| 678 | +** flag indicate that a file cannot be deleted when open. The | |
| 679 | +** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on | |
| 680 | +** read-only media and cannot be changed even by processes with | |
| 681 | +** elevated privileges. | |
| 679 | 682 | */ |
| 680 | 683 | #define SQLITE_IOCAP_ATOMIC 0x00000001 |
| 681 | 684 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 |
| 682 | 685 | #define SQLITE_IOCAP_ATOMIC1K 0x00000004 |
| 683 | 686 | #define SQLITE_IOCAP_ATOMIC2K 0x00000008 |
| @@ -688,10 +691,11 @@ | ||
| 688 | 691 | #define SQLITE_IOCAP_ATOMIC64K 0x00000100 |
| 689 | 692 | #define SQLITE_IOCAP_SAFE_APPEND 0x00000200 |
| 690 | 693 | #define SQLITE_IOCAP_SEQUENTIAL 0x00000400 |
| 691 | 694 | #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 |
| 692 | 695 | #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 |
| 696 | +#define SQLITE_IOCAP_IMMUTABLE 0x00002000 | |
| 693 | 697 | |
| 694 | 698 | /* |
| 695 | 699 | ** CAPI3REF: File Locking Levels |
| 696 | 700 | ** |
| 697 | 701 | ** SQLite uses one of these integer values as the second |
| @@ -2892,10 +2896,34 @@ | ||
| 2892 | 2896 | ** sqlite3_open_v2(). ^Setting the cache parameter to "private" is |
| 2893 | 2897 | ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. |
| 2894 | 2898 | ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in |
| 2895 | 2899 | ** a URI filename, its value overrides any behavior requested by setting |
| 2896 | 2900 | ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. |
| 2901 | +** | |
| 2902 | +** <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or | |
| 2903 | +** "1") or "false" (or "off" or "no" or "0") to indicate that the | |
| 2904 | +** [powersafe overwrite] property does or does not apply to the | |
| 2905 | +** storage media on which the database file resides. ^The psow query | |
| 2906 | +** parameter only works for the built-in unix and Windows VFSes. | |
| 2907 | +** | |
| 2908 | +** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter | |
| 2909 | +** which if set disables file locking in rollback journal modes. This | |
| 2910 | +** is useful for accessing a database on a filesystem that does not | |
| 2911 | +** support locking. Caution: Database corruption might result if two | |
| 2912 | +** or more processes write to the same database and any one of those | |
| 2913 | +** processes uses nolock=1. | |
| 2914 | +** | |
| 2915 | +** <li> <b>immutable</b>: ^The immutable parameter is a boolean query | |
| 2916 | +** parameter that indicates that the database file is stored on | |
| 2917 | +** read-only media. ^When immutable is set, SQLite assumes that the | |
| 2918 | +** database file cannot be changed, even by a process with higher | |
| 2919 | +** privilege, and so the database is opened read-only and all locking | |
| 2920 | +** and change detection is disabled. Caution: Setting the immutable | |
| 2921 | +** property on a database file that does in fact change can result | |
| 2922 | +** in incorrect query results and/or [SQLITE_CORRUPT] errors. | |
| 2923 | +** See also: [SQLITE_IOCAP_IMMUTABLE]. | |
| 2924 | +** | |
| 2897 | 2925 | ** </ul> |
| 2898 | 2926 | ** |
| 2899 | 2927 | ** ^Specifying an unknown parameter in the query component of a URI is not an |
| 2900 | 2928 | ** error. Future versions of SQLite might understand additional query |
| 2901 | 2929 | ** parameters. See "[query parameters with special meaning to SQLite]" for |
| @@ -2921,12 +2949,13 @@ | ||
| 2921 | 2949 | ** in URI filenames. |
| 2922 | 2950 | ** <tr><td> file:data.db?mode=ro&cache=private <td> |
| 2923 | 2951 | ** Open file "data.db" in the current directory for read-only access. |
| 2924 | 2952 | ** Regardless of whether or not shared-cache mode is enabled by |
| 2925 | 2953 | ** default, use a private cache. |
| 2926 | -** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td> | |
| 2927 | -** Open file "/home/fred/data.db". Use the special VFS "unix-nolock". | |
| 2954 | +** <tr><td> file:/home/fred/data.db?vfs=unix-dotfile <td> | |
| 2955 | +** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile" | |
| 2956 | +** that uses dot-files in place of posix advisory locking. | |
| 2928 | 2957 | ** <tr><td> file:data.db?mode=readonly <td> |
| 2929 | 2958 | ** An error. "readonly" is not a valid option for the "mode" parameter. |
| 2930 | 2959 | ** </table> |
| 2931 | 2960 | ** |
| 2932 | 2961 | ** ^URI hexadecimal escape sequences (%HH) are supported within the path and |
| @@ -7460,10 +7489,20 @@ | ||
| 7460 | 7489 | #if 0 |
| 7461 | 7490 | extern "C" { |
| 7462 | 7491 | #endif |
| 7463 | 7492 | |
| 7464 | 7493 | typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; |
| 7494 | +typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; | |
| 7495 | + | |
| 7496 | +/* The double-precision datatype used by RTree depends on the | |
| 7497 | +** SQLITE_RTREE_INT_ONLY compile-time option. | |
| 7498 | +*/ | |
| 7499 | +#ifdef SQLITE_RTREE_INT_ONLY | |
| 7500 | + typedef sqlite3_int64 sqlite3_rtree_dbl; | |
| 7501 | +#else | |
| 7502 | + typedef double sqlite3_rtree_dbl; | |
| 7503 | +#endif | |
| 7465 | 7504 | |
| 7466 | 7505 | /* |
| 7467 | 7506 | ** Register a geometry callback named zGeom that can be used as part of an |
| 7468 | 7507 | ** R-Tree geometry query as follows: |
| 7469 | 7508 | ** |
| @@ -7470,15 +7509,11 @@ | ||
| 7470 | 7509 | ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) |
| 7471 | 7510 | */ |
| 7472 | 7511 | SQLITE_API int sqlite3_rtree_geometry_callback( |
| 7473 | 7512 | sqlite3 *db, |
| 7474 | 7513 | const char *zGeom, |
| 7475 | -#ifdef SQLITE_RTREE_INT_ONLY | |
| 7476 | - int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes), | |
| 7477 | -#else | |
| 7478 | - int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes), | |
| 7479 | -#endif | |
| 7514 | + int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), | |
| 7480 | 7515 | void *pContext |
| 7481 | 7516 | ); |
| 7482 | 7517 | |
| 7483 | 7518 | |
| 7484 | 7519 | /* |
| @@ -7486,15 +7521,64 @@ | ||
| 7486 | 7521 | ** argument to callbacks registered using rtree_geometry_callback(). |
| 7487 | 7522 | */ |
| 7488 | 7523 | struct sqlite3_rtree_geometry { |
| 7489 | 7524 | void *pContext; /* Copy of pContext passed to s_r_g_c() */ |
| 7490 | 7525 | int nParam; /* Size of array aParam[] */ |
| 7491 | - double *aParam; /* Parameters passed to SQL geom function */ | |
| 7526 | + sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */ | |
| 7492 | 7527 | void *pUser; /* Callback implementation user data */ |
| 7493 | 7528 | void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ |
| 7494 | 7529 | }; |
| 7495 | 7530 | |
| 7531 | +/* | |
| 7532 | +** Register a 2nd-generation geometry callback named zScore that can be | |
| 7533 | +** used as part of an R-Tree geometry query as follows: | |
| 7534 | +** | |
| 7535 | +** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...) | |
| 7536 | +*/ | |
| 7537 | +SQLITE_API int sqlite3_rtree_query_callback( | |
| 7538 | + sqlite3 *db, | |
| 7539 | + const char *zQueryFunc, | |
| 7540 | + int (*xQueryFunc)(sqlite3_rtree_query_info*), | |
| 7541 | + void *pContext, | |
| 7542 | + void (*xDestructor)(void*) | |
| 7543 | +); | |
| 7544 | + | |
| 7545 | + | |
| 7546 | +/* | |
| 7547 | +** A pointer to a structure of the following type is passed as the | |
| 7548 | +** argument to scored geometry callback registered using | |
| 7549 | +** sqlite3_rtree_query_callback(). | |
| 7550 | +** | |
| 7551 | +** Note that the first 5 fields of this structure are identical to | |
| 7552 | +** sqlite3_rtree_geometry. This structure is a subclass of | |
| 7553 | +** sqlite3_rtree_geometry. | |
| 7554 | +*/ | |
| 7555 | +struct sqlite3_rtree_query_info { | |
| 7556 | + void *pContext; /* pContext from when function registered */ | |
| 7557 | + int nParam; /* Number of function parameters */ | |
| 7558 | + sqlite3_rtree_dbl *aParam; /* value of function parameters */ | |
| 7559 | + void *pUser; /* callback can use this, if desired */ | |
| 7560 | + void (*xDelUser)(void*); /* function to free pUser */ | |
| 7561 | + sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */ | |
| 7562 | + unsigned int *anQueue; /* Number of pending entries in the queue */ | |
| 7563 | + int nCoord; /* Number of coordinates */ | |
| 7564 | + int iLevel; /* Level of current node or entry */ | |
| 7565 | + int mxLevel; /* The largest iLevel value in the tree */ | |
| 7566 | + sqlite3_int64 iRowid; /* Rowid for current entry */ | |
| 7567 | + sqlite3_rtree_dbl rParentScore; /* Score of parent node */ | |
| 7568 | + int eParentWithin; /* Visibility of parent node */ | |
| 7569 | + int eWithin; /* OUT: Visiblity */ | |
| 7570 | + sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ | |
| 7571 | +}; | |
| 7572 | + | |
| 7573 | +/* | |
| 7574 | +** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin. | |
| 7575 | +*/ | |
| 7576 | +#define NOT_WITHIN 0 /* Object completely outside of query region */ | |
| 7577 | +#define PARTLY_WITHIN 1 /* Object partially overlaps query region */ | |
| 7578 | +#define FULLY_WITHIN 2 /* Object fully contained within query region */ | |
| 7579 | + | |
| 7496 | 7580 | |
| 7497 | 7581 | #if 0 |
| 7498 | 7582 | } /* end of the 'extern "C"' block */ |
| 7499 | 7583 | #endif |
| 7500 | 7584 | |
| @@ -8417,14 +8501,14 @@ | ||
| 8417 | 8501 | ** Estimated quantities used for query planning are stored as 16-bit |
| 8418 | 8502 | ** logarithms. For quantity X, the value stored is 10*log2(X). This |
| 8419 | 8503 | ** gives a possible range of values of approximately 1.0e986 to 1e-986. |
| 8420 | 8504 | ** But the allowed values are "grainy". Not every value is representable. |
| 8421 | 8505 | ** For example, quantities 16 and 17 are both represented by a LogEst |
| 8422 | -** of 40. However, since LogEst quantatites are suppose to be estimates, | |
| 8506 | +** of 40. However, since LogEst quantaties are suppose to be estimates, | |
| 8423 | 8507 | ** not exact values, this imprecision is not a problem. |
| 8424 | 8508 | ** |
| 8425 | -** "LogEst" is short for "Logarithimic Estimate". | |
| 8509 | +** "LogEst" is short for "Logarithmic Estimate". | |
| 8426 | 8510 | ** |
| 8427 | 8511 | ** Examples: |
| 8428 | 8512 | ** 1 -> 0 20 -> 43 10000 -> 132 |
| 8429 | 8513 | ** 2 -> 10 25 -> 46 25000 -> 146 |
| 8430 | 8514 | ** 3 -> 16 100 -> 66 1000000 -> 199 |
| @@ -8916,10 +9000,11 @@ | ||
| 8916 | 9000 | SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); |
| 8917 | 9001 | SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *); |
| 8918 | 9002 | SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); |
| 8919 | 9003 | SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); |
| 8920 | 9004 | SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask); |
| 9005 | +SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt); | |
| 8921 | 9006 | |
| 8922 | 9007 | #ifndef NDEBUG |
| 8923 | 9008 | SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); |
| 8924 | 9009 | #endif |
| 8925 | 9010 | |
| @@ -9870,87 +9955,75 @@ | ||
| 9870 | 9955 | */ |
| 9871 | 9956 | #ifndef _SQLITE_OS_H_ |
| 9872 | 9957 | #define _SQLITE_OS_H_ |
| 9873 | 9958 | |
| 9874 | 9959 | /* |
| 9875 | -** Figure out if we are dealing with Unix, Windows, or some other | |
| 9876 | -** operating system. After the following block of preprocess macros, | |
| 9877 | -** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER | |
| 9878 | -** will defined to either 1 or 0. One of the four will be 1. The other | |
| 9879 | -** three will be 0. | |
| 9960 | +** Attempt to automatically detect the operating system and setup the | |
| 9961 | +** necessary pre-processor macros for it. | |
| 9962 | +*/ | |
| 9963 | +/************** Include os_setup.h in the middle of os.h *********************/ | |
| 9964 | +/************** Begin file os_setup.h ****************************************/ | |
| 9965 | +/* | |
| 9966 | +** 2013 November 25 | |
| 9967 | +** | |
| 9968 | +** The author disclaims copyright to this source code. In place of | |
| 9969 | +** a legal notice, here is a blessing: | |
| 9970 | +** | |
| 9971 | +** May you do good and not evil. | |
| 9972 | +** May you find forgiveness for yourself and forgive others. | |
| 9973 | +** May you share freely, never taking more than you give. | |
| 9974 | +** | |
| 9975 | +****************************************************************************** | |
| 9976 | +** | |
| 9977 | +** This file contains pre-processor directives related to operating system | |
| 9978 | +** detection and/or setup. | |
| 9979 | +*/ | |
| 9980 | +#ifndef _OS_SETUP_H_ | |
| 9981 | +#define _OS_SETUP_H_ | |
| 9982 | + | |
| 9983 | +/* | |
| 9984 | +** Figure out if we are dealing with Unix, Windows, or some other operating | |
| 9985 | +** system. | |
| 9986 | +** | |
| 9987 | +** After the following block of preprocess macros, all of SQLITE_OS_UNIX, | |
| 9988 | +** SQLITE_OS_WIN, and SQLITE_OS_OTHER will defined to either 1 or 0. One of | |
| 9989 | +** the three will be 1. The other two will be 0. | |
| 9880 | 9990 | */ |
| 9881 | 9991 | #if defined(SQLITE_OS_OTHER) |
| 9882 | -# if SQLITE_OS_OTHER==1 | |
| 9883 | -# undef SQLITE_OS_UNIX | |
| 9884 | -# define SQLITE_OS_UNIX 0 | |
| 9885 | -# undef SQLITE_OS_WIN | |
| 9886 | -# define SQLITE_OS_WIN 0 | |
| 9887 | -# else | |
| 9888 | -# undef SQLITE_OS_OTHER | |
| 9889 | -# endif | |
| 9992 | +# if SQLITE_OS_OTHER==1 | |
| 9993 | +# undef SQLITE_OS_UNIX | |
| 9994 | +# define SQLITE_OS_UNIX 0 | |
| 9995 | +# undef SQLITE_OS_WIN | |
| 9996 | +# define SQLITE_OS_WIN 0 | |
| 9997 | +# else | |
| 9998 | +# undef SQLITE_OS_OTHER | |
| 9999 | +# endif | |
| 9890 | 10000 | #endif |
| 9891 | 10001 | #if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) |
| 9892 | -# define SQLITE_OS_OTHER 0 | |
| 9893 | -# ifndef SQLITE_OS_WIN | |
| 9894 | -# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) | |
| 9895 | -# define SQLITE_OS_WIN 1 | |
| 9896 | -# define SQLITE_OS_UNIX 0 | |
| 9897 | -# else | |
| 9898 | -# define SQLITE_OS_WIN 0 | |
| 9899 | -# define SQLITE_OS_UNIX 1 | |
| 10002 | +# define SQLITE_OS_OTHER 0 | |
| 10003 | +# ifndef SQLITE_OS_WIN | |
| 10004 | +# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ | |
| 10005 | + defined(__MINGW32__) || defined(__BORLANDC__) | |
| 10006 | +# define SQLITE_OS_WIN 1 | |
| 10007 | +# define SQLITE_OS_UNIX 0 | |
| 10008 | +# else | |
| 10009 | +# define SQLITE_OS_WIN 0 | |
| 10010 | +# define SQLITE_OS_UNIX 1 | |
| 10011 | +# endif | |
| 10012 | +# else | |
| 10013 | +# define SQLITE_OS_UNIX 0 | |
| 10014 | +# endif | |
| 10015 | +#else | |
| 10016 | +# ifndef SQLITE_OS_WIN | |
| 10017 | +# define SQLITE_OS_WIN 0 | |
| 9900 | 10018 | # endif |
| 9901 | -# else | |
| 9902 | -# define SQLITE_OS_UNIX 0 | |
| 9903 | -# endif | |
| 9904 | -#else | |
| 9905 | -# ifndef SQLITE_OS_WIN | |
| 9906 | -# define SQLITE_OS_WIN 0 | |
| 9907 | -# endif | |
| 9908 | -#endif | |
| 9909 | - | |
| 9910 | -#if SQLITE_OS_WIN | |
| 9911 | -# include <windows.h> | |
| 9912 | -#endif | |
| 9913 | - | |
| 9914 | -/* | |
| 9915 | -** Determine if we are dealing with Windows NT. | |
| 9916 | -** | |
| 9917 | -** We ought to be able to determine if we are compiling for win98 or winNT | |
| 9918 | -** using the _WIN32_WINNT macro as follows: | |
| 9919 | -** | |
| 9920 | -** #if defined(_WIN32_WINNT) | |
| 9921 | -** # define SQLITE_OS_WINNT 1 | |
| 9922 | -** #else | |
| 9923 | -** # define SQLITE_OS_WINNT 0 | |
| 9924 | -** #endif | |
| 9925 | -** | |
| 9926 | -** However, vs2005 does not set _WIN32_WINNT by default, as it ought to, | |
| 9927 | -** so the above test does not work. We'll just assume that everything is | |
| 9928 | -** winNT unless the programmer explicitly says otherwise by setting | |
| 9929 | -** SQLITE_OS_WINNT to 0. | |
| 9930 | -*/ | |
| 9931 | -#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT) | |
| 9932 | -# define SQLITE_OS_WINNT 1 | |
| 9933 | -#endif | |
| 9934 | - | |
| 9935 | -/* | |
| 9936 | -** Determine if we are dealing with WindowsCE - which has a much | |
| 9937 | -** reduced API. | |
| 9938 | -*/ | |
| 9939 | -#if defined(_WIN32_WCE) | |
| 9940 | -# define SQLITE_OS_WINCE 1 | |
| 9941 | -#else | |
| 9942 | -# define SQLITE_OS_WINCE 0 | |
| 9943 | -#endif | |
| 9944 | - | |
| 9945 | -/* | |
| 9946 | -** Determine if we are dealing with WinRT, which provides only a subset of | |
| 9947 | -** the full Win32 API. | |
| 9948 | -*/ | |
| 9949 | -#if !defined(SQLITE_OS_WINRT) | |
| 9950 | -# define SQLITE_OS_WINRT 0 | |
| 9951 | -#endif | |
| 10019 | +#endif | |
| 10020 | + | |
| 10021 | +#endif /* _OS_SETUP_H_ */ | |
| 10022 | + | |
| 10023 | +/************** End of os_setup.h ********************************************/ | |
| 10024 | +/************** Continuing where we left off in os.h *************************/ | |
| 9952 | 10025 | |
| 9953 | 10026 | /* If the SET_FULLSYNC macro is not defined above, then make it |
| 9954 | 10027 | ** a no-op |
| 9955 | 10028 | */ |
| 9956 | 10029 | #ifndef SET_FULLSYNC |
| @@ -10845,11 +10918,11 @@ | ||
| 10845 | 10918 | FKey *pFKey; /* Linked list of all foreign keys in this table */ |
| 10846 | 10919 | char *zColAff; /* String defining the affinity of each column */ |
| 10847 | 10920 | #ifndef SQLITE_OMIT_CHECK |
| 10848 | 10921 | ExprList *pCheck; /* All CHECK constraints */ |
| 10849 | 10922 | #endif |
| 10850 | - tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */ | |
| 10923 | + LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */ | |
| 10851 | 10924 | int tnum; /* Root BTree node for this table (see note above) */ |
| 10852 | 10925 | i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */ |
| 10853 | 10926 | i16 nCol; /* Number of columns in this table */ |
| 10854 | 10927 | u16 nRef; /* Number of pointers to this Table */ |
| 10855 | 10928 | LogEst szTabRow; /* Estimated size of each table row in bytes */ |
| @@ -11054,11 +11127,11 @@ | ||
| 11054 | 11127 | ** element. |
| 11055 | 11128 | */ |
| 11056 | 11129 | struct Index { |
| 11057 | 11130 | char *zName; /* Name of this index */ |
| 11058 | 11131 | i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */ |
| 11059 | - tRowcnt *aiRowEst; /* From ANALYZE: Est. rows selected by each column */ | |
| 11132 | + LogEst *aiRowLogEst; /* From ANALYZE: Est. rows selected by each column */ | |
| 11060 | 11133 | Table *pTable; /* The SQL table being indexed */ |
| 11061 | 11134 | char *zColAff; /* String defining the affinity of each column */ |
| 11062 | 11135 | Index *pNext; /* The next index associated with the same table */ |
| 11063 | 11136 | Schema *pSchema; /* Schema containing this index */ |
| 11064 | 11137 | u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ |
| @@ -11499,10 +11572,11 @@ | ||
| 11499 | 11572 | #define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */ |
| 11500 | 11573 | #define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */ |
| 11501 | 11574 | #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ |
| 11502 | 11575 | #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ |
| 11503 | 11576 | #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ |
| 11577 | +#define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */ | |
| 11504 | 11578 | |
| 11505 | 11579 | /* Allowed return values from sqlite3WhereIsDistinct() |
| 11506 | 11580 | */ |
| 11507 | 11581 | #define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ |
| 11508 | 11582 | #define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ |
| @@ -12082,15 +12156,14 @@ | ||
| 12082 | 12156 | int isInit; /* True after initialization has finished */ |
| 12083 | 12157 | int inProgress; /* True while initialization in progress */ |
| 12084 | 12158 | int isMutexInit; /* True after mutexes are initialized */ |
| 12085 | 12159 | int isMallocInit; /* True after malloc is initialized */ |
| 12086 | 12160 | int isPCacheInit; /* True after malloc is initialized */ |
| 12087 | - sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ | |
| 12088 | 12161 | int nRefInitMutex; /* Number of users of pInitMutex */ |
| 12162 | + sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ | |
| 12089 | 12163 | void (*xLog)(void*,int,const char*); /* Function for logging */ |
| 12090 | 12164 | void *pLogArg; /* First argument to xLog() */ |
| 12091 | - int bLocaltimeFault; /* True to fail localtime() calls */ | |
| 12092 | 12165 | #ifdef SQLITE_ENABLE_SQLLOG |
| 12093 | 12166 | void(*xSqllog)(void*,sqlite3*,const char*, int); |
| 12094 | 12167 | void *pSqllogArg; |
| 12095 | 12168 | #endif |
| 12096 | 12169 | #ifdef SQLITE_VDBE_COVERAGE |
| @@ -12098,10 +12171,14 @@ | ||
| 12098 | 12171 | ** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE. |
| 12099 | 12172 | */ |
| 12100 | 12173 | void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */ |
| 12101 | 12174 | void *pVdbeBranchArg; /* 1st argument */ |
| 12102 | 12175 | #endif |
| 12176 | +#ifndef SQLITE_OMIT_BUILTIN_TEST | |
| 12177 | + int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ | |
| 12178 | +#endif | |
| 12179 | + int bLocaltimeFault; /* True to fail localtime() calls */ | |
| 12103 | 12180 | }; |
| 12104 | 12181 | |
| 12105 | 12182 | /* |
| 12106 | 12183 | ** This macro is used inside of assert() statements to indicate that |
| 12107 | 12184 | ** the assert is only valid on a well-formed database. Instead of: |
| @@ -12398,10 +12475,16 @@ | ||
| 12398 | 12475 | SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); |
| 12399 | 12476 | SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, |
| 12400 | 12477 | sqlite3_vfs**,char**,char **); |
| 12401 | 12478 | SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*); |
| 12402 | 12479 | SQLITE_PRIVATE int sqlite3CodeOnce(Parse *); |
| 12480 | + | |
| 12481 | +#ifdef SQLITE_OMIT_BUILTIN_TEST | |
| 12482 | +# define sqlite3FaultSim(X) SQLITE_OK | |
| 12483 | +#else | |
| 12484 | +SQLITE_PRIVATE int sqlite3FaultSim(int); | |
| 12485 | +#endif | |
| 12403 | 12486 | |
| 12404 | 12487 | SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32); |
| 12405 | 12488 | SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32); |
| 12406 | 12489 | SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32); |
| 12407 | 12490 | SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*); |
| @@ -12466,10 +12549,11 @@ | ||
| 12466 | 12549 | SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); |
| 12467 | 12550 | SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); |
| 12468 | 12551 | SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo*); |
| 12469 | 12552 | SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*); |
| 12470 | 12553 | SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*); |
| 12554 | +SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*); | |
| 12471 | 12555 | SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*); |
| 12472 | 12556 | SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*); |
| 12473 | 12557 | SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*); |
| 12474 | 12558 | SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); |
| 12475 | 12559 | SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); |
| @@ -13203,19 +13287,26 @@ | ||
| 13203 | 13287 | 0, /* isInit */ |
| 13204 | 13288 | 0, /* inProgress */ |
| 13205 | 13289 | 0, /* isMutexInit */ |
| 13206 | 13290 | 0, /* isMallocInit */ |
| 13207 | 13291 | 0, /* isPCacheInit */ |
| 13208 | - 0, /* pInitMutex */ | |
| 13209 | 13292 | 0, /* nRefInitMutex */ |
| 13293 | + 0, /* pInitMutex */ | |
| 13210 | 13294 | 0, /* xLog */ |
| 13211 | 13295 | 0, /* pLogArg */ |
| 13212 | - 0, /* bLocaltimeFault */ | |
| 13213 | 13296 | #ifdef SQLITE_ENABLE_SQLLOG |
| 13214 | 13297 | 0, /* xSqllog */ |
| 13215 | - 0 /* pSqllogArg */ | |
| 13298 | + 0, /* pSqllogArg */ | |
| 13216 | 13299 | #endif |
| 13300 | +#ifdef SQLITE_VDBE_COVERAGE | |
| 13301 | + 0, /* xVdbeBranch */ | |
| 13302 | + 0, /* pVbeBranchArg */ | |
| 13303 | +#endif | |
| 13304 | +#ifndef SQLITE_OMIT_BUILTIN_TEST | |
| 13305 | + 0, /* xTestCallback */ | |
| 13306 | +#endif | |
| 13307 | + 0 /* bLocaltimeFault */ | |
| 13217 | 13308 | }; |
| 13218 | 13309 | |
| 13219 | 13310 | /* |
| 13220 | 13311 | ** Hash table for global functions - functions common to all |
| 13221 | 13312 | ** database connections. After initialization, this table is |
| @@ -18934,10 +19025,88 @@ | ||
| 18934 | 19025 | ** |
| 18935 | 19026 | ************************************************************************* |
| 18936 | 19027 | ** This file contains the C functions that implement mutexes for win32 |
| 18937 | 19028 | */ |
| 18938 | 19029 | |
| 19030 | +#if SQLITE_OS_WIN | |
| 19031 | +/* | |
| 19032 | +** Include the header file for the Windows VFS. | |
| 19033 | +*/ | |
| 19034 | +/************** Include os_win.h in the middle of mutex_w32.c ****************/ | |
| 19035 | +/************** Begin file os_win.h ******************************************/ | |
| 19036 | +/* | |
| 19037 | +** 2013 November 25 | |
| 19038 | +** | |
| 19039 | +** The author disclaims copyright to this source code. In place of | |
| 19040 | +** a legal notice, here is a blessing: | |
| 19041 | +** | |
| 19042 | +** May you do good and not evil. | |
| 19043 | +** May you find forgiveness for yourself and forgive others. | |
| 19044 | +** May you share freely, never taking more than you give. | |
| 19045 | +** | |
| 19046 | +****************************************************************************** | |
| 19047 | +** | |
| 19048 | +** This file contains code that is specific to Windows. | |
| 19049 | +*/ | |
| 19050 | +#ifndef _OS_WIN_H_ | |
| 19051 | +#define _OS_WIN_H_ | |
| 19052 | + | |
| 19053 | +/* | |
| 19054 | +** Include the primary Windows SDK header file. | |
| 19055 | +*/ | |
| 19056 | +#include "windows.h" | |
| 19057 | + | |
| 19058 | +#ifdef __CYGWIN__ | |
| 19059 | +# include <sys/cygwin.h> | |
| 19060 | +# include <errno.h> /* amalgamator: dontcache */ | |
| 19061 | +#endif | |
| 19062 | + | |
| 19063 | +/* | |
| 19064 | +** Determine if we are dealing with Windows NT. | |
| 19065 | +** | |
| 19066 | +** We ought to be able to determine if we are compiling for Windows 9x or | |
| 19067 | +** Windows NT using the _WIN32_WINNT macro as follows: | |
| 19068 | +** | |
| 19069 | +** #if defined(_WIN32_WINNT) | |
| 19070 | +** # define SQLITE_OS_WINNT 1 | |
| 19071 | +** #else | |
| 19072 | +** # define SQLITE_OS_WINNT 0 | |
| 19073 | +** #endif | |
| 19074 | +** | |
| 19075 | +** However, Visual Studio 2005 does not set _WIN32_WINNT by default, as | |
| 19076 | +** it ought to, so the above test does not work. We'll just assume that | |
| 19077 | +** everything is Windows NT unless the programmer explicitly says otherwise | |
| 19078 | +** by setting SQLITE_OS_WINNT to 0. | |
| 19079 | +*/ | |
| 19080 | +#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT) | |
| 19081 | +# define SQLITE_OS_WINNT 1 | |
| 19082 | +#endif | |
| 19083 | + | |
| 19084 | +/* | |
| 19085 | +** Determine if we are dealing with Windows CE - which has a much reduced | |
| 19086 | +** API. | |
| 19087 | +*/ | |
| 19088 | +#if defined(_WIN32_WCE) | |
| 19089 | +# define SQLITE_OS_WINCE 1 | |
| 19090 | +#else | |
| 19091 | +# define SQLITE_OS_WINCE 0 | |
| 19092 | +#endif | |
| 19093 | + | |
| 19094 | +/* | |
| 19095 | +** Determine if we are dealing with WinRT, which provides only a subset of | |
| 19096 | +** the full Win32 API. | |
| 19097 | +*/ | |
| 19098 | +#if !defined(SQLITE_OS_WINRT) | |
| 19099 | +# define SQLITE_OS_WINRT 0 | |
| 19100 | +#endif | |
| 19101 | + | |
| 19102 | +#endif /* _OS_WIN_H_ */ | |
| 19103 | + | |
| 19104 | +/************** End of os_win.h **********************************************/ | |
| 19105 | +/************** Continuing where we left off in mutex_w32.c ******************/ | |
| 19106 | +#endif | |
| 19107 | + | |
| 18939 | 19108 | /* |
| 18940 | 19109 | ** The code in this file is only used if we are compiling multithreaded |
| 18941 | 19110 | ** on a win32 system. |
| 18942 | 19111 | */ |
| 18943 | 19112 | #ifdef SQLITE_MUTEX_W32 |
| @@ -21789,10 +21958,28 @@ | ||
| 21789 | 21958 | static unsigned dummy = 0; |
| 21790 | 21959 | dummy += (unsigned)x; |
| 21791 | 21960 | } |
| 21792 | 21961 | #endif |
| 21793 | 21962 | |
| 21963 | +/* | |
| 21964 | +** Give a callback to the test harness that can be used to simulate faults | |
| 21965 | +** in places where it is difficult or expensive to do so purely by means | |
| 21966 | +** of inputs. | |
| 21967 | +** | |
| 21968 | +** The intent of the integer argument is to let the fault simulator know | |
| 21969 | +** which of multiple sqlite3FaultSim() calls has been hit. | |
| 21970 | +** | |
| 21971 | +** Return whatever integer value the test callback returns, or return | |
| 21972 | +** SQLITE_OK if no test callback is installed. | |
| 21973 | +*/ | |
| 21974 | +#ifndef SQLITE_OMIT_BUILTIN_TEST | |
| 21975 | +SQLITE_PRIVATE int sqlite3FaultSim(int iTest){ | |
| 21976 | + int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback; | |
| 21977 | + return xCallback ? xCallback(iTest) : SQLITE_OK; | |
| 21978 | +} | |
| 21979 | +#endif | |
| 21980 | + | |
| 21794 | 21981 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 21795 | 21982 | /* |
| 21796 | 21983 | ** Return true if the floating point value is Not a Number (NaN). |
| 21797 | 21984 | ** |
| 21798 | 21985 | ** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. |
| @@ -23004,12 +23191,12 @@ | ||
| 23004 | 23191 | return b+x[b-a]; |
| 23005 | 23192 | } |
| 23006 | 23193 | } |
| 23007 | 23194 | |
| 23008 | 23195 | /* |
| 23009 | -** Convert an integer into a LogEst. In other words, compute a | |
| 23010 | -** good approximatation for 10*log2(x). | |
| 23196 | +** Convert an integer into a LogEst. In other words, compute an | |
| 23197 | +** approximation for 10*log2(x). | |
| 23011 | 23198 | */ |
| 23012 | 23199 | SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){ |
| 23013 | 23200 | static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 }; |
| 23014 | 23201 | LogEst y = 40; |
| 23015 | 23202 | if( x<8 ){ |
| @@ -31226,15 +31413,10 @@ | ||
| 31226 | 31413 | ** |
| 31227 | 31414 | ** This file contains code that is specific to Windows. |
| 31228 | 31415 | */ |
| 31229 | 31416 | #if SQLITE_OS_WIN /* This file is used for Windows only */ |
| 31230 | 31417 | |
| 31231 | -#ifdef __CYGWIN__ | |
| 31232 | -# include <sys/cygwin.h> | |
| 31233 | -# include <errno.h> /* amalgamator: keep */ | |
| 31234 | -#endif | |
| 31235 | - | |
| 31236 | 31418 | /* |
| 31237 | 31419 | ** Include code that is common to all os_*.c files |
| 31238 | 31420 | */ |
| 31239 | 31421 | /************** Include os_common.h in the middle of os_win.c ****************/ |
| 31240 | 31422 | /************** Begin file os_common.h ***************************************/ |
| @@ -31443,10 +31625,14 @@ | ||
| 31443 | 31625 | |
| 31444 | 31626 | #endif /* !defined(_OS_COMMON_H_) */ |
| 31445 | 31627 | |
| 31446 | 31628 | /************** End of os_common.h *******************************************/ |
| 31447 | 31629 | /************** Continuing where we left off in os_win.c *********************/ |
| 31630 | + | |
| 31631 | +/* | |
| 31632 | +** Include the header file for the Windows VFS. | |
| 31633 | +*/ | |
| 31448 | 31634 | |
| 31449 | 31635 | /* |
| 31450 | 31636 | ** Compiling and using WAL mode requires several APIs that are only |
| 31451 | 31637 | ** available in Windows platforms based on the NT kernel. |
| 31452 | 31638 | */ |
| @@ -33255,10 +33441,36 @@ | ||
| 33255 | 33441 | # define SQLITE_WIN32_IOERR_RETRY_DELAY 25 |
| 33256 | 33442 | #endif |
| 33257 | 33443 | static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY; |
| 33258 | 33444 | static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; |
| 33259 | 33445 | |
| 33446 | +/* | |
| 33447 | +** The "winIoerrCanRetry1" macro is used to determine if a particular I/O | |
| 33448 | +** error code obtained via GetLastError() is eligible to be retried. It | |
| 33449 | +** must accept the error code DWORD as its only argument and should return | |
| 33450 | +** non-zero if the error code is transient in nature and the operation | |
| 33451 | +** responsible for generating the original error might succeed upon being | |
| 33452 | +** retried. The argument to this macro should be a variable. | |
| 33453 | +** | |
| 33454 | +** Additionally, a macro named "winIoerrCanRetry2" may be defined. If it | |
| 33455 | +** is defined, it will be consulted only when the macro "winIoerrCanRetry1" | |
| 33456 | +** returns zero. The "winIoerrCanRetry2" macro is completely optional and | |
| 33457 | +** may be used to include additional error codes in the set that should | |
| 33458 | +** result in the failing I/O operation being retried by the caller. If | |
| 33459 | +** defined, the "winIoerrCanRetry2" macro must exhibit external semantics | |
| 33460 | +** identical to those of the "winIoerrCanRetry1" macro. | |
| 33461 | +*/ | |
| 33462 | +#if !defined(winIoerrCanRetry1) | |
| 33463 | +#define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED) || \ | |
| 33464 | + ((a)==ERROR_SHARING_VIOLATION) || \ | |
| 33465 | + ((a)==ERROR_LOCK_VIOLATION) || \ | |
| 33466 | + ((a)==ERROR_DEV_NOT_EXIST) || \ | |
| 33467 | + ((a)==ERROR_NETNAME_DELETED) || \ | |
| 33468 | + ((a)==ERROR_SEM_TIMEOUT) || \ | |
| 33469 | + ((a)==ERROR_NETWORK_UNREACHABLE)) | |
| 33470 | +#endif | |
| 33471 | + | |
| 33260 | 33472 | /* |
| 33261 | 33473 | ** If a ReadFile() or WriteFile() error occurs, invoke this routine |
| 33262 | 33474 | ** to see if it should be retried. Return TRUE to retry. Return FALSE |
| 33263 | 33475 | ** to give up with an error. |
| 33264 | 33476 | */ |
| @@ -33268,17 +33480,22 @@ | ||
| 33268 | 33480 | if( pError ){ |
| 33269 | 33481 | *pError = e; |
| 33270 | 33482 | } |
| 33271 | 33483 | return 0; |
| 33272 | 33484 | } |
| 33273 | - if( e==ERROR_ACCESS_DENIED || | |
| 33274 | - e==ERROR_LOCK_VIOLATION || | |
| 33275 | - e==ERROR_SHARING_VIOLATION ){ | |
| 33485 | + if( winIoerrCanRetry1(e) ){ | |
| 33486 | + sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); | |
| 33487 | + ++*pnRetry; | |
| 33488 | + return 1; | |
| 33489 | + } | |
| 33490 | +#if defined(winIoerrCanRetry2) | |
| 33491 | + else if( winIoerrCanRetry2(e) ){ | |
| 33276 | 33492 | sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); |
| 33277 | 33493 | ++*pnRetry; |
| 33278 | 33494 | return 1; |
| 33279 | 33495 | } |
| 33496 | +#endif | |
| 33280 | 33497 | if( pError ){ |
| 33281 | 33498 | *pError = e; |
| 33282 | 33499 | } |
| 33283 | 33500 | return 0; |
| 33284 | 33501 | } |
| @@ -40231,11 +40448,12 @@ | ||
| 40231 | 40448 | u8 noSync; /* Do not sync the journal if true */ |
| 40232 | 40449 | u8 fullSync; /* Do extra syncs of the journal for robustness */ |
| 40233 | 40450 | u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ |
| 40234 | 40451 | u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ |
| 40235 | 40452 | u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ |
| 40236 | - u8 tempFile; /* zFilename is a temporary file */ | |
| 40453 | + u8 tempFile; /* zFilename is a temporary or immutable file */ | |
| 40454 | + u8 noLock; /* Do not lock (except in WAL mode) */ | |
| 40237 | 40455 | u8 readOnly; /* True for a read-only database */ |
| 40238 | 40456 | u8 memDb; /* True to inhibit all file I/O */ |
| 40239 | 40457 | |
| 40240 | 40458 | /************************************************************************** |
| 40241 | 40459 | ** The following block contains those class members that change during |
| @@ -40696,11 +40914,11 @@ | ||
| 40696 | 40914 | assert( !pPager->exclusiveMode || pPager->eLock==eLock ); |
| 40697 | 40915 | assert( eLock==NO_LOCK || eLock==SHARED_LOCK ); |
| 40698 | 40916 | assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 ); |
| 40699 | 40917 | if( isOpen(pPager->fd) ){ |
| 40700 | 40918 | assert( pPager->eLock>=eLock ); |
| 40701 | - rc = sqlite3OsUnlock(pPager->fd, eLock); | |
| 40919 | + rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock); | |
| 40702 | 40920 | if( pPager->eLock!=UNKNOWN_LOCK ){ |
| 40703 | 40921 | pPager->eLock = (u8)eLock; |
| 40704 | 40922 | } |
| 40705 | 40923 | IOTRACE(("UNLOCK %p %d\n", pPager, eLock)) |
| 40706 | 40924 | } |
| @@ -40720,11 +40938,11 @@ | ||
| 40720 | 40938 | static int pagerLockDb(Pager *pPager, int eLock){ |
| 40721 | 40939 | int rc = SQLITE_OK; |
| 40722 | 40940 | |
| 40723 | 40941 | assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK ); |
| 40724 | 40942 | if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){ |
| 40725 | - rc = sqlite3OsLock(pPager->fd, eLock); | |
| 40943 | + rc = pPager->noLock ? SQLITE_OK : sqlite3OsLock(pPager->fd, eLock); | |
| 40726 | 40944 | if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){ |
| 40727 | 40945 | pPager->eLock = (u8)eLock; |
| 40728 | 40946 | IOTRACE(("LOCK %p %d\n", pPager, eLock)) |
| 40729 | 40947 | } |
| 40730 | 40948 | } |
| @@ -44279,47 +44497,59 @@ | ||
| 44279 | 44497 | ** |
| 44280 | 44498 | ** + SQLITE_DEFAULT_PAGE_SIZE, |
| 44281 | 44499 | ** + The value returned by sqlite3OsSectorSize() |
| 44282 | 44500 | ** + The largest page size that can be written atomically. |
| 44283 | 44501 | */ |
| 44284 | - if( rc==SQLITE_OK && !readOnly ){ | |
| 44285 | - setSectorSize(pPager); | |
| 44286 | - assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE); | |
| 44287 | - if( szPageDflt<pPager->sectorSize ){ | |
| 44288 | - if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ | |
| 44289 | - szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; | |
| 44290 | - }else{ | |
| 44291 | - szPageDflt = (u32)pPager->sectorSize; | |
| 44292 | - } | |
| 44293 | - } | |
| 44502 | + if( rc==SQLITE_OK ){ | |
| 44503 | + int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); | |
| 44504 | + if( !readOnly ){ | |
| 44505 | + setSectorSize(pPager); | |
| 44506 | + assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE); | |
| 44507 | + if( szPageDflt<pPager->sectorSize ){ | |
| 44508 | + if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ | |
| 44509 | + szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; | |
| 44510 | + }else{ | |
| 44511 | + szPageDflt = (u32)pPager->sectorSize; | |
| 44512 | + } | |
| 44513 | + } | |
| 44294 | 44514 | #ifdef SQLITE_ENABLE_ATOMIC_WRITE |
| 44295 | - { | |
| 44296 | - int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); | |
| 44297 | - int ii; | |
| 44298 | - assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); | |
| 44299 | - assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); | |
| 44300 | - assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); | |
| 44301 | - for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ | |
| 44302 | - if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){ | |
| 44303 | - szPageDflt = ii; | |
| 44515 | + { | |
| 44516 | + int ii; | |
| 44517 | + assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); | |
| 44518 | + assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); | |
| 44519 | + assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); | |
| 44520 | + for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ | |
| 44521 | + if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){ | |
| 44522 | + szPageDflt = ii; | |
| 44523 | + } | |
| 44304 | 44524 | } |
| 44305 | 44525 | } |
| 44526 | +#endif | |
| 44306 | 44527 | } |
| 44307 | -#endif | |
| 44528 | + pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0); | |
| 44529 | + if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 | |
| 44530 | + || sqlite3_uri_boolean(zFilename, "immutable", 0) ){ | |
| 44531 | + vfsFlags |= SQLITE_OPEN_READONLY; | |
| 44532 | + goto act_like_temp_file; | |
| 44533 | + } | |
| 44308 | 44534 | } |
| 44309 | 44535 | }else{ |
| 44310 | 44536 | /* If a temporary file is requested, it is not opened immediately. |
| 44311 | 44537 | ** In this case we accept the default page size and delay actually |
| 44312 | 44538 | ** opening the file until the first call to OsWrite(). |
| 44313 | 44539 | ** |
| 44314 | 44540 | ** This branch is also run for an in-memory database. An in-memory |
| 44315 | 44541 | ** database is the same as a temp-file that is never written out to |
| 44316 | 44542 | ** disk and uses an in-memory rollback journal. |
| 44543 | + ** | |
| 44544 | + ** This branch also runs for files marked as immutable. | |
| 44317 | 44545 | */ |
| 44546 | +act_like_temp_file: | |
| 44318 | 44547 | tempFile = 1; |
| 44319 | - pPager->eState = PAGER_READER; | |
| 44320 | - pPager->eLock = EXCLUSIVE_LOCK; | |
| 44548 | + pPager->eState = PAGER_READER; /* Pretend we already have a lock */ | |
| 44549 | + pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE locking mode */ | |
| 44550 | + pPager->noLock = 1; /* Do no locking */ | |
| 44321 | 44551 | readOnly = (vfsFlags&SQLITE_OPEN_READONLY); |
| 44322 | 44552 | } |
| 44323 | 44553 | |
| 44324 | 44554 | /* The following call to PagerSetPagesize() serves to set the value of |
| 44325 | 44555 | ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. |
| @@ -44356,13 +44586,10 @@ | ||
| 44356 | 44586 | /* pPager->stmtSize = 0; */ |
| 44357 | 44587 | /* pPager->stmtJSize = 0; */ |
| 44358 | 44588 | /* pPager->nPage = 0; */ |
| 44359 | 44589 | pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; |
| 44360 | 44590 | /* pPager->state = PAGER_UNLOCK; */ |
| 44361 | -#if 0 | |
| 44362 | - assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) ); | |
| 44363 | -#endif | |
| 44364 | 44591 | /* pPager->errMask = 0; */ |
| 44365 | 44592 | pPager->tempFile = (u8)tempFile; |
| 44366 | 44593 | assert( tempFile==PAGER_LOCKINGMODE_NORMAL |
| 44367 | 44594 | || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); |
| 44368 | 44595 | assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); |
| @@ -59414,10 +59641,17 @@ | ||
| 59414 | 59641 | */ |
| 59415 | 59642 | SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){ |
| 59416 | 59643 | assert( mask==BTREE_BULKLOAD || mask==0 ); |
| 59417 | 59644 | pCsr->hints = mask; |
| 59418 | 59645 | } |
| 59646 | + | |
| 59647 | +/* | |
| 59648 | +** Return true if the given Btree is read-only. | |
| 59649 | +*/ | |
| 59650 | +SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){ | |
| 59651 | + return (p->pBt->btsFlags & BTS_READ_ONLY)!=0; | |
| 59652 | +} | |
| 59419 | 59653 | |
| 59420 | 59654 | /************** End of btree.c ***********************************************/ |
| 59421 | 59655 | /************** Begin file backup.c ******************************************/ |
| 59422 | 59656 | /* |
| 59423 | 59657 | ** 2009 January 28 |
| @@ -70686,11 +70920,11 @@ | ||
| 70686 | 70920 | ** |
| 70687 | 70921 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 70688 | 70922 | ** is greater than or equal to the key value. If there are no records |
| 70689 | 70923 | ** greater than or equal to the key and P2 is not zero, then jump to P2. |
| 70690 | 70924 | ** |
| 70691 | -** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe | |
| 70925 | +** See also: Found, NotFound, SeekLt, SeekGt, SeekLe | |
| 70692 | 70926 | */ |
| 70693 | 70927 | /* Opcode: SeekGt P1 P2 P3 P4 * |
| 70694 | 70928 | ** Synopsis: key=r[P3@P4] |
| 70695 | 70929 | ** |
| 70696 | 70930 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| @@ -70700,11 +70934,11 @@ | ||
| 70700 | 70934 | ** |
| 70701 | 70935 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 70702 | 70936 | ** is greater than the key value. If there are no records greater than |
| 70703 | 70937 | ** the key and P2 is not zero, then jump to P2. |
| 70704 | 70938 | ** |
| 70705 | -** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe | |
| 70939 | +** See also: Found, NotFound, SeekLt, SeekGe, SeekLe | |
| 70706 | 70940 | */ |
| 70707 | 70941 | /* Opcode: SeekLt P1 P2 P3 P4 * |
| 70708 | 70942 | ** Synopsis: key=r[P3@P4] |
| 70709 | 70943 | ** |
| 70710 | 70944 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| @@ -70714,11 +70948,11 @@ | ||
| 70714 | 70948 | ** |
| 70715 | 70949 | ** Reposition cursor P1 so that it points to the largest entry that |
| 70716 | 70950 | ** is less than the key value. If there are no records less than |
| 70717 | 70951 | ** the key and P2 is not zero, then jump to P2. |
| 70718 | 70952 | ** |
| 70719 | -** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe | |
| 70953 | +** See also: Found, NotFound, SeekGt, SeekGe, SeekLe | |
| 70720 | 70954 | */ |
| 70721 | 70955 | /* Opcode: SeekLe P1 P2 P3 P4 * |
| 70722 | 70956 | ** Synopsis: key=r[P3@P4] |
| 70723 | 70957 | ** |
| 70724 | 70958 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| @@ -70728,11 +70962,11 @@ | ||
| 70728 | 70962 | ** |
| 70729 | 70963 | ** Reposition cursor P1 so that it points to the largest entry that |
| 70730 | 70964 | ** is less than or equal to the key value. If there are no records |
| 70731 | 70965 | ** less than or equal to the key and P2 is not zero, then jump to P2. |
| 70732 | 70966 | ** |
| 70733 | -** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt | |
| 70967 | +** See also: Found, NotFound, SeekGt, SeekGe, SeekLt | |
| 70734 | 70968 | */ |
| 70735 | 70969 | case OP_SeekLT: /* jump, in3 */ |
| 70736 | 70970 | case OP_SeekLE: /* jump, in3 */ |
| 70737 | 70971 | case OP_SeekGE: /* jump, in3 */ |
| 70738 | 70972 | case OP_SeekGT: { /* jump, in3 */ |
| @@ -71454,10 +71688,11 @@ | ||
| 71454 | 71688 | |
| 71455 | 71689 | pOut = &aMem[pOp->p2]; |
| 71456 | 71690 | pC = p->apCsr[pOp->p1]; |
| 71457 | 71691 | assert( isSorter(pC) ); |
| 71458 | 71692 | rc = sqlite3VdbeSorterRowkey(pC, pOut); |
| 71693 | + assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) ); | |
| 71459 | 71694 | break; |
| 71460 | 71695 | } |
| 71461 | 71696 | |
| 71462 | 71697 | /* Opcode: RowData P1 P2 * * * |
| 71463 | 71698 | ** Synopsis: r[P2]=data |
| @@ -73545,12 +73780,12 @@ | ||
| 73545 | 73780 | *****************************************************************************/ |
| 73546 | 73781 | } |
| 73547 | 73782 | |
| 73548 | 73783 | #ifdef VDBE_PROFILE |
| 73549 | 73784 | { |
| 73550 | - u64 elapsed = sqlite3Hwtime() - start; | |
| 73551 | - pOp->cycles += elapsed; | |
| 73785 | + u64 endTime = sqlite3Hwtime(); | |
| 73786 | + if( endTime>start ) pOp->cycles += endTime - start; | |
| 73552 | 73787 | pOp->cnt++; |
| 73553 | 73788 | } |
| 73554 | 73789 | #endif |
| 73555 | 73790 | |
| 73556 | 73791 | /* The following code adds nothing to the actual functionality |
| @@ -83789,10 +84024,11 @@ | ||
| 83789 | 84024 | */ |
| 83790 | 84025 | static void decodeIntArray( |
| 83791 | 84026 | char *zIntArray, /* String containing int array to decode */ |
| 83792 | 84027 | int nOut, /* Number of slots in aOut[] */ |
| 83793 | 84028 | tRowcnt *aOut, /* Store integers here */ |
| 84029 | + LogEst *aLog, /* Or, if aOut==0, here */ | |
| 83794 | 84030 | Index *pIndex /* Handle extra flags for this index, if not NULL */ |
| 83795 | 84031 | ){ |
| 83796 | 84032 | char *z = zIntArray; |
| 83797 | 84033 | int c; |
| 83798 | 84034 | int i; |
| @@ -83807,11 +84043,21 @@ | ||
| 83807 | 84043 | v = 0; |
| 83808 | 84044 | while( (c=z[0])>='0' && c<='9' ){ |
| 83809 | 84045 | v = v*10 + c - '0'; |
| 83810 | 84046 | z++; |
| 83811 | 84047 | } |
| 83812 | - aOut[i] = v; | |
| 84048 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 84049 | + if( aOut ){ | |
| 84050 | + aOut[i] = v; | |
| 84051 | + }else | |
| 84052 | +#else | |
| 84053 | + assert( aOut==0 ); | |
| 84054 | + UNUSED_PARAMETER(aOut); | |
| 84055 | +#endif | |
| 84056 | + { | |
| 84057 | + aLog[i] = sqlite3LogEst(v); | |
| 84058 | + } | |
| 83813 | 84059 | if( *z==' ' ) z++; |
| 83814 | 84060 | } |
| 83815 | 84061 | #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 83816 | 84062 | assert( pIndex!=0 ); |
| 83817 | 84063 | #else |
| @@ -83863,16 +84109,16 @@ | ||
| 83863 | 84109 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 83864 | 84110 | } |
| 83865 | 84111 | z = argv[2]; |
| 83866 | 84112 | |
| 83867 | 84113 | if( pIndex ){ |
| 83868 | - decodeIntArray((char*)z, pIndex->nKeyCol+1, pIndex->aiRowEst, pIndex); | |
| 83869 | - if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0]; | |
| 84114 | + decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex); | |
| 84115 | + if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; | |
| 83870 | 84116 | }else{ |
| 83871 | 84117 | Index fakeIdx; |
| 83872 | 84118 | fakeIdx.szIdxRow = pTable->szTabRow; |
| 83873 | - decodeIntArray((char*)z, 1, &pTable->nRowEst, &fakeIdx); | |
| 84119 | + decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); | |
| 83874 | 84120 | pTable->szTabRow = fakeIdx.szIdxRow; |
| 83875 | 84121 | } |
| 83876 | 84122 | |
| 83877 | 84123 | return 0; |
| 83878 | 84124 | } |
| @@ -84060,13 +84306,13 @@ | ||
| 84060 | 84306 | if( pIdx!=pPrevIdx ){ |
| 84061 | 84307 | initAvgEq(pPrevIdx); |
| 84062 | 84308 | pPrevIdx = pIdx; |
| 84063 | 84309 | } |
| 84064 | 84310 | pSample = &pIdx->aSample[pIdx->nSample]; |
| 84065 | - decodeIntArray((char*)sqlite3_column_text(pStmt,1), nCol, pSample->anEq, 0); | |
| 84066 | - decodeIntArray((char*)sqlite3_column_text(pStmt,2), nCol, pSample->anLt, 0); | |
| 84067 | - decodeIntArray((char*)sqlite3_column_text(pStmt,3), nCol, pSample->anDLt,0); | |
| 84311 | + decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0); | |
| 84312 | + decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); | |
| 84313 | + decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); | |
| 84068 | 84314 | |
| 84069 | 84315 | /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. |
| 84070 | 84316 | ** This is in case the sample record is corrupted. In that case, the |
| 84071 | 84317 | ** sqlite3VdbeRecordCompare() may read up to two varints past the |
| 84072 | 84318 | ** end of the allocated buffer before it realizes it is dealing with |
| @@ -85924,11 +86170,11 @@ | ||
| 85924 | 86170 | } |
| 85925 | 86171 | pTable->zName = zName; |
| 85926 | 86172 | pTable->iPKey = -1; |
| 85927 | 86173 | pTable->pSchema = db->aDb[iDb].pSchema; |
| 85928 | 86174 | pTable->nRef = 1; |
| 85929 | - pTable->nRowEst = 1048576; | |
| 86175 | + pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); | |
| 85930 | 86176 | assert( pParse->pNewTable==0 ); |
| 85931 | 86177 | pParse->pNewTable = pTable; |
| 85932 | 86178 | |
| 85933 | 86179 | /* If this is the magic sqlite_sequence table used by autoincrement, |
| 85934 | 86180 | ** then record a pointer to this table in the main database structure |
| @@ -86325,11 +86571,14 @@ | ||
| 86325 | 86571 | Parse *pParse, /* Parsing context */ |
| 86326 | 86572 | Expr *pCheckExpr /* The check expression */ |
| 86327 | 86573 | ){ |
| 86328 | 86574 | #ifndef SQLITE_OMIT_CHECK |
| 86329 | 86575 | Table *pTab = pParse->pNewTable; |
| 86330 | - if( pTab && !IN_DECLARE_VTAB ){ | |
| 86576 | + sqlite3 *db = pParse->db; | |
| 86577 | + if( pTab && !IN_DECLARE_VTAB | |
| 86578 | + && !sqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt) | |
| 86579 | + ){ | |
| 86331 | 86580 | pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); |
| 86332 | 86581 | if( pParse->constraintName.n ){ |
| 86333 | 86582 | sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1); |
| 86334 | 86583 | } |
| 86335 | 86584 | }else |
| @@ -87749,19 +87998,19 @@ | ||
| 87749 | 87998 | Index *p; /* Allocated index object */ |
| 87750 | 87999 | int nByte; /* Bytes of space for Index object + arrays */ |
| 87751 | 88000 | |
| 87752 | 88001 | nByte = ROUND8(sizeof(Index)) + /* Index structure */ |
| 87753 | 88002 | ROUND8(sizeof(char*)*nCol) + /* Index.azColl */ |
| 87754 | - ROUND8(sizeof(tRowcnt)*(nCol+1) + /* Index.aiRowEst */ | |
| 88003 | + ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */ | |
| 87755 | 88004 | sizeof(i16)*nCol + /* Index.aiColumn */ |
| 87756 | 88005 | sizeof(u8)*nCol); /* Index.aSortOrder */ |
| 87757 | 88006 | p = sqlite3DbMallocZero(db, nByte + nExtra); |
| 87758 | 88007 | if( p ){ |
| 87759 | 88008 | char *pExtra = ((char*)p)+ROUND8(sizeof(Index)); |
| 87760 | - p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol); | |
| 87761 | - p->aiRowEst = (tRowcnt*)pExtra; pExtra += sizeof(tRowcnt)*(nCol+1); | |
| 87762 | - p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol; | |
| 88009 | + p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol); | |
| 88010 | + p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1); | |
| 88011 | + p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol; | |
| 87763 | 88012 | p->aSortOrder = (u8*)pExtra; |
| 87764 | 88013 | p->nColumn = nCol; |
| 87765 | 88014 | p->nKeyCol = nCol - 1; |
| 87766 | 88015 | *ppExtra = ((char*)p) + nByte; |
| 87767 | 88016 | } |
| @@ -87987,11 +88236,11 @@ | ||
| 87987 | 88236 | pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol, |
| 87988 | 88237 | nName + nExtra + 1, &zExtra); |
| 87989 | 88238 | if( db->mallocFailed ){ |
| 87990 | 88239 | goto exit_create_index; |
| 87991 | 88240 | } |
| 87992 | - assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) ); | |
| 88241 | + assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowLogEst) ); | |
| 87993 | 88242 | assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) ); |
| 87994 | 88243 | pIndex->zName = zExtra; |
| 87995 | 88244 | zExtra += nName + 1; |
| 87996 | 88245 | memcpy(pIndex->zName, zName, nName+1); |
| 87997 | 88246 | pIndex->pTable = pTab; |
| @@ -88268,11 +88517,11 @@ | ||
| 88268 | 88517 | ** |
| 88269 | 88518 | ** aiRowEst[0] is suppose to contain the number of elements in the index. |
| 88270 | 88519 | ** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the |
| 88271 | 88520 | ** number of rows in the table that match any particular value of the |
| 88272 | 88521 | ** first column of the index. aiRowEst[2] is an estimate of the number |
| 88273 | -** of rows that match any particular combiniation of the first 2 columns | |
| 88522 | +** of rows that match any particular combination of the first 2 columns | |
| 88274 | 88523 | ** of the index. And so forth. It must always be the case that |
| 88275 | 88524 | * |
| 88276 | 88525 | ** aiRowEst[N]<=aiRowEst[N-1] |
| 88277 | 88526 | ** aiRowEst[N]>=1 |
| 88278 | 88527 | ** |
| @@ -88279,24 +88528,31 @@ | ||
| 88279 | 88528 | ** Apart from that, we have little to go on besides intuition as to |
| 88280 | 88529 | ** how aiRowEst[] should be initialized. The numbers generated here |
| 88281 | 88530 | ** are based on typical values found in actual indices. |
| 88282 | 88531 | */ |
| 88283 | 88532 | SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){ |
| 88284 | - tRowcnt *a = pIdx->aiRowEst; | |
| 88533 | + /* 10, 9, 8, 7, 6 */ | |
| 88534 | + LogEst aVal[] = { 33, 32, 30, 28, 26 }; | |
| 88535 | + LogEst *a = pIdx->aiRowLogEst; | |
| 88536 | + int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol); | |
| 88285 | 88537 | int i; |
| 88286 | - tRowcnt n; | |
| 88287 | - assert( a!=0 ); | |
| 88288 | - a[0] = pIdx->pTable->nRowEst; | |
| 88289 | - if( a[0]<10 ) a[0] = 10; | |
| 88290 | - n = 10; | |
| 88291 | - for(i=1; i<=pIdx->nKeyCol; i++){ | |
| 88292 | - a[i] = n; | |
| 88293 | - if( n>5 ) n--; | |
| 88294 | - } | |
| 88295 | - if( pIdx->onError!=OE_None ){ | |
| 88296 | - a[pIdx->nKeyCol] = 1; | |
| 88297 | - } | |
| 88538 | + | |
| 88539 | + /* Set the first entry (number of rows in the index) to the estimated | |
| 88540 | + ** number of rows in the table. Or 10, if the estimated number of rows | |
| 88541 | + ** in the table is less than that. */ | |
| 88542 | + a[0] = pIdx->pTable->nRowLogEst; | |
| 88543 | + if( a[0]<33 ) a[0] = 33; assert( 33==sqlite3LogEst(10) ); | |
| 88544 | + | |
| 88545 | + /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is | |
| 88546 | + ** 6 and each subsequent value (if any) is 5. */ | |
| 88547 | + memcpy(&a[1], aVal, nCopy*sizeof(LogEst)); | |
| 88548 | + for(i=nCopy+1; i<=pIdx->nKeyCol; i++){ | |
| 88549 | + a[i] = 23; assert( 23==sqlite3LogEst(5) ); | |
| 88550 | + } | |
| 88551 | + | |
| 88552 | + assert( 0==sqlite3LogEst(1) ); | |
| 88553 | + if( pIdx->onError!=OE_None ) a[pIdx->nKeyCol] = 0; | |
| 88298 | 88554 | } |
| 88299 | 88555 | |
| 88300 | 88556 | /* |
| 88301 | 88557 | ** This routine will drop an existing named index. This routine |
| 88302 | 88558 | ** implements the DROP INDEX statement. |
| @@ -92116,11 +92372,11 @@ | ||
| 92116 | 92372 | } |
| 92117 | 92373 | if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); |
| 92118 | 92374 | } |
| 92119 | 92375 | zVal = (char*)sqlite3_value_text(argv[0]); |
| 92120 | 92376 | nVal = sqlite3_value_bytes(argv[0]); |
| 92121 | - if( nVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal); | |
| 92377 | + if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal); | |
| 92122 | 92378 | } |
| 92123 | 92379 | } |
| 92124 | 92380 | static void groupConcatFinalize(sqlite3_context *context){ |
| 92125 | 92381 | StrAccum *pAccum; |
| 92126 | 92382 | pAccum = sqlite3_aggregate_context(context, 0); |
| @@ -94306,10 +94562,11 @@ | ||
| 94306 | 94562 | } |
| 94307 | 94563 | } |
| 94308 | 94564 | if( j>=pTab->nCol ){ |
| 94309 | 94565 | if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){ |
| 94310 | 94566 | ipkColumn = i; |
| 94567 | + bIdListInOrder = 0; | |
| 94311 | 94568 | }else{ |
| 94312 | 94569 | sqlite3ErrorMsg(pParse, "table %S has no column named %s", |
| 94313 | 94570 | pTabList, 0, pColumn->a[i].zName); |
| 94314 | 94571 | pParse->checkSchema = 1; |
| 94315 | 94572 | goto insert_cleanup; |
| @@ -95557,18 +95814,27 @@ | ||
| 95557 | 95814 | } |
| 95558 | 95815 | if( pDest->iPKey!=pSrc->iPKey ){ |
| 95559 | 95816 | return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ |
| 95560 | 95817 | } |
| 95561 | 95818 | for(i=0; i<pDest->nCol; i++){ |
| 95562 | - if( pDest->aCol[i].affinity!=pSrc->aCol[i].affinity ){ | |
| 95819 | + Column *pDestCol = &pDest->aCol[i]; | |
| 95820 | + Column *pSrcCol = &pSrc->aCol[i]; | |
| 95821 | + if( pDestCol->affinity!=pSrcCol->affinity ){ | |
| 95563 | 95822 | return 0; /* Affinity must be the same on all columns */ |
| 95564 | 95823 | } |
| 95565 | - if( !xferCompatibleCollation(pDest->aCol[i].zColl, pSrc->aCol[i].zColl) ){ | |
| 95824 | + if( !xferCompatibleCollation(pDestCol->zColl, pSrcCol->zColl) ){ | |
| 95566 | 95825 | return 0; /* Collating sequence must be the same on all columns */ |
| 95567 | 95826 | } |
| 95568 | - if( pDest->aCol[i].notNull && !pSrc->aCol[i].notNull ){ | |
| 95827 | + if( pDestCol->notNull && !pSrcCol->notNull ){ | |
| 95569 | 95828 | return 0; /* tab2 must be NOT NULL if tab1 is */ |
| 95829 | + } | |
| 95830 | + /* Default values for second and subsequent columns need to match. */ | |
| 95831 | + if( i>0 | |
| 95832 | + && ((pDestCol->zDflt==0)!=(pSrcCol->zDflt==0) | |
| 95833 | + || (pDestCol->zDflt && strcmp(pDestCol->zDflt, pSrcCol->zDflt)!=0)) | |
| 95834 | + ){ | |
| 95835 | + return 0; /* Default values must be the same for all columns */ | |
| 95570 | 95836 | } |
| 95571 | 95837 | } |
| 95572 | 95838 | for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ |
| 95573 | 95839 | if( pDestIdx->onError!=OE_None ){ |
| 95574 | 95840 | destHasUniqueIdx = 1; |
| @@ -98583,17 +98849,19 @@ | ||
| 98583 | 98849 | Table *pTab = sqliteHashData(i); |
| 98584 | 98850 | sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, pTab->zName, 0); |
| 98585 | 98851 | sqlite3VdbeAddOp2(v, OP_Null, 0, 2); |
| 98586 | 98852 | sqlite3VdbeAddOp2(v, OP_Integer, |
| 98587 | 98853 | (int)sqlite3LogEstToInt(pTab->szTabRow), 3); |
| 98588 | - sqlite3VdbeAddOp2(v, OP_Integer, (int)pTab->nRowEst, 4); | |
| 98854 | + sqlite3VdbeAddOp2(v, OP_Integer, | |
| 98855 | + (int)sqlite3LogEstToInt(pTab->nRowLogEst), 4); | |
| 98589 | 98856 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); |
| 98590 | 98857 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 98591 | 98858 | sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); |
| 98592 | 98859 | sqlite3VdbeAddOp2(v, OP_Integer, |
| 98593 | 98860 | (int)sqlite3LogEstToInt(pIdx->szIdxRow), 3); |
| 98594 | - sqlite3VdbeAddOp2(v, OP_Integer, (int)pIdx->aiRowEst[0], 4); | |
| 98861 | + sqlite3VdbeAddOp2(v, OP_Integer, | |
| 98862 | + (int)sqlite3LogEstToInt(pIdx->aiRowLogEst[0]), 4); | |
| 98595 | 98863 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); |
| 98596 | 98864 | } |
| 98597 | 98865 | } |
| 98598 | 98866 | } |
| 98599 | 98867 | break; |
| @@ -100760,19 +101028,21 @@ | ||
| 100760 | 101028 | Select *pSelect, /* The whole SELECT statement */ |
| 100761 | 101029 | int regData /* Register holding data to be sorted */ |
| 100762 | 101030 | ){ |
| 100763 | 101031 | Vdbe *v = pParse->pVdbe; |
| 100764 | 101032 | int nExpr = pSort->pOrderBy->nExpr; |
| 100765 | - int regBase = sqlite3GetTempRange(pParse, nExpr+2); | |
| 100766 | - int regRecord = sqlite3GetTempReg(pParse); | |
| 101033 | + int regRecord = ++pParse->nMem; | |
| 101034 | + int regBase = pParse->nMem+1; | |
| 100767 | 101035 | int nOBSat = pSort->nOBSat; |
| 100768 | 101036 | int op; |
| 101037 | + | |
| 101038 | + pParse->nMem += nExpr+2; /* nExpr+2 registers allocated at regBase */ | |
| 100769 | 101039 | sqlite3ExprCacheClear(pParse); |
| 100770 | 101040 | sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, 0); |
| 100771 | 101041 | sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); |
| 100772 | 101042 | sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); |
| 100773 | - sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nExpr+2-nOBSat, regRecord); | |
| 101043 | + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nExpr+2-nOBSat,regRecord); | |
| 100774 | 101044 | if( nOBSat>0 ){ |
| 100775 | 101045 | int regPrevKey; /* The first nOBSat columns of the previous row */ |
| 100776 | 101046 | int addrFirst; /* Address of the OP_IfNot opcode */ |
| 100777 | 101047 | int addrJmp; /* Address of the OP_Jump opcode */ |
| 100778 | 101048 | VdbeOp *pOp; /* Opcode that opens the sorter */ |
| @@ -100805,14 +101075,10 @@ | ||
| 100805 | 101075 | op = OP_SorterInsert; |
| 100806 | 101076 | }else{ |
| 100807 | 101077 | op = OP_IdxInsert; |
| 100808 | 101078 | } |
| 100809 | 101079 | sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord); |
| 100810 | - if( nOBSat==0 ){ | |
| 100811 | - sqlite3ReleaseTempReg(pParse, regRecord); | |
| 100812 | - sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); | |
| 100813 | - } | |
| 100814 | 101080 | if( pSelect->iLimit ){ |
| 100815 | 101081 | int addr1, addr2; |
| 100816 | 101082 | int iLimit; |
| 100817 | 101083 | if( pSelect->iOffset ){ |
| 100818 | 101084 | iLimit = pSelect->iOffset+1; |
| @@ -101984,11 +102250,11 @@ | ||
| 101984 | 102250 | /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside |
| 101985 | 102251 | ** is disabled */ |
| 101986 | 102252 | assert( db->lookaside.bEnabled==0 ); |
| 101987 | 102253 | pTab->nRef = 1; |
| 101988 | 102254 | pTab->zName = 0; |
| 101989 | - pTab->nRowEst = 1048576; | |
| 102255 | + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); | |
| 101990 | 102256 | selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); |
| 101991 | 102257 | selectAddColumnTypeAndCollation(pParse, pTab, pSelect); |
| 101992 | 102258 | pTab->iPKey = -1; |
| 101993 | 102259 | if( db->mallocFailed ){ |
| 101994 | 102260 | sqlite3DeleteTable(db, pTab); |
| @@ -104123,11 +104389,11 @@ | ||
| 104123 | 104389 | pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); |
| 104124 | 104390 | if( pTab==0 ) return WRC_Abort; |
| 104125 | 104391 | pTab->nRef = 1; |
| 104126 | 104392 | pTab->zName = sqlite3DbStrDup(db, pCte->zName); |
| 104127 | 104393 | pTab->iPKey = -1; |
| 104128 | - pTab->nRowEst = 1048576; | |
| 104394 | + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); | |
| 104129 | 104395 | pTab->tabFlags |= TF_Ephemeral; |
| 104130 | 104396 | pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); |
| 104131 | 104397 | if( db->mallocFailed ) return SQLITE_NOMEM; |
| 104132 | 104398 | assert( pFrom->pSelect ); |
| 104133 | 104399 | |
| @@ -104299,11 +104565,11 @@ | ||
| 104299 | 104565 | pTab->nRef = 1; |
| 104300 | 104566 | pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); |
| 104301 | 104567 | while( pSel->pPrior ){ pSel = pSel->pPrior; } |
| 104302 | 104568 | selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); |
| 104303 | 104569 | pTab->iPKey = -1; |
| 104304 | - pTab->nRowEst = 1048576; | |
| 104570 | + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); | |
| 104305 | 104571 | pTab->tabFlags |= TF_Ephemeral; |
| 104306 | 104572 | #endif |
| 104307 | 104573 | }else{ |
| 104308 | 104574 | /* An ordinary table or view name in the FROM clause */ |
| 104309 | 104575 | assert( pFrom->pTab==0 ); |
| @@ -104794,14 +105060,15 @@ | ||
| 104794 | 105060 | Parse *pParse, /* Parse context */ |
| 104795 | 105061 | Table *pTab, /* Table being queried */ |
| 104796 | 105062 | Index *pIdx /* Index used to optimize scan, or NULL */ |
| 104797 | 105063 | ){ |
| 104798 | 105064 | if( pParse->explain==2 ){ |
| 105065 | + int bCover = (pIdx!=0 && (HasRowid(pTab) || pIdx->autoIndex!=2)); | |
| 104799 | 105066 | char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s", |
| 104800 | - pTab->zName, | |
| 104801 | - pIdx ? " USING COVERING INDEX " : "", | |
| 104802 | - pIdx ? pIdx->zName : "" | |
| 105067 | + pTab->zName, | |
| 105068 | + bCover ? " USING COVERING INDEX " : "", | |
| 105069 | + bCover ? pIdx->zName : "" | |
| 104803 | 105070 | ); |
| 104804 | 105071 | sqlite3VdbeAddOp4( |
| 104805 | 105072 | pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC |
| 104806 | 105073 | ); |
| 104807 | 105074 | } |
| @@ -104949,11 +105216,11 @@ | ||
| 104949 | 105216 | VdbeComment((v, "%s", pItem->pTab->zName)); |
| 104950 | 105217 | pItem->addrFillSub = addrTop; |
| 104951 | 105218 | sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); |
| 104952 | 105219 | explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); |
| 104953 | 105220 | sqlite3Select(pParse, pSub, &dest); |
| 104954 | - pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; | |
| 105221 | + pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow); | |
| 104955 | 105222 | pItem->viaCoroutine = 1; |
| 104956 | 105223 | pItem->regResult = dest.iSdst; |
| 104957 | 105224 | sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn); |
| 104958 | 105225 | sqlite3VdbeJumpHere(v, addrTop-1); |
| 104959 | 105226 | sqlite3ClearTempRegCache(pParse); |
| @@ -104980,11 +105247,11 @@ | ||
| 104980 | 105247 | VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName)); |
| 104981 | 105248 | } |
| 104982 | 105249 | sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); |
| 104983 | 105250 | explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); |
| 104984 | 105251 | sqlite3Select(pParse, pSub, &dest); |
| 104985 | - pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; | |
| 105252 | + pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow); | |
| 104986 | 105253 | if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); |
| 104987 | 105254 | retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); |
| 104988 | 105255 | VdbeComment((v, "end %s", pItem->pTab->zName)); |
| 104989 | 105256 | sqlite3VdbeChangeP1(v, topAddr, retAddr); |
| 104990 | 105257 | sqlite3ClearTempRegCache(pParse); |
| @@ -105013,22 +105280,10 @@ | ||
| 105013 | 105280 | explainSetInteger(pParse->iSelectId, iRestoreSelectId); |
| 105014 | 105281 | return rc; |
| 105015 | 105282 | } |
| 105016 | 105283 | #endif |
| 105017 | 105284 | |
| 105018 | - /* If there is both a GROUP BY and an ORDER BY clause and they are | |
| 105019 | - ** identical, then disable the ORDER BY clause since the GROUP BY | |
| 105020 | - ** will cause elements to come out in the correct order. This is | |
| 105021 | - ** an optimization - the correct answer should result regardless. | |
| 105022 | - ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER | |
| 105023 | - ** to disable this optimization for testing purposes. | |
| 105024 | - */ | |
| 105025 | - if( sqlite3ExprListCompare(p->pGroupBy, sSort.pOrderBy, -1)==0 | |
| 105026 | - && OptimizationEnabled(db, SQLITE_GroupByOrder) ){ | |
| 105027 | - sSort.pOrderBy = 0; | |
| 105028 | - } | |
| 105029 | - | |
| 105030 | 105285 | /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and |
| 105031 | 105286 | ** if the select-list is the same as the ORDER BY list, then this query |
| 105032 | 105287 | ** can be rewritten as a GROUP BY. In other words, this: |
| 105033 | 105288 | ** |
| 105034 | 105289 | ** SELECT DISTINCT xyz FROM ... ORDER BY xyz |
| @@ -105153,10 +105408,11 @@ | ||
| 105153 | 105408 | int iAbortFlag; /* Mem address which causes query abort if positive */ |
| 105154 | 105409 | int groupBySort; /* Rows come from source in GROUP BY order */ |
| 105155 | 105410 | int addrEnd; /* End of processing for this SELECT */ |
| 105156 | 105411 | int sortPTab = 0; /* Pseudotable used to decode sorting results */ |
| 105157 | 105412 | int sortOut = 0; /* Output register from the sorter */ |
| 105413 | + int orderByGrp = 0; /* True if the GROUP BY and ORDER BY are the same */ | |
| 105158 | 105414 | |
| 105159 | 105415 | /* Remove any and all aliases between the result set and the |
| 105160 | 105416 | ** GROUP BY clause. |
| 105161 | 105417 | */ |
| 105162 | 105418 | if( pGroupBy ){ |
| @@ -105172,10 +105428,22 @@ | ||
| 105172 | 105428 | if( p->nSelectRow>100 ) p->nSelectRow = 100; |
| 105173 | 105429 | }else{ |
| 105174 | 105430 | p->nSelectRow = 1; |
| 105175 | 105431 | } |
| 105176 | 105432 | |
| 105433 | + | |
| 105434 | + /* If there is both a GROUP BY and an ORDER BY clause and they are | |
| 105435 | + ** identical, then it may be possible to disable the ORDER BY clause | |
| 105436 | + ** on the grounds that the GROUP BY will cause elements to come out | |
| 105437 | + ** in the correct order. It also may not - the GROUP BY may use a | |
| 105438 | + ** database index that causes rows to be grouped together as required | |
| 105439 | + ** but not actually sorted. Either way, record the fact that the | |
| 105440 | + ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp | |
| 105441 | + ** variable. */ | |
| 105442 | + if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){ | |
| 105443 | + orderByGrp = 1; | |
| 105444 | + } | |
| 105177 | 105445 | |
| 105178 | 105446 | /* Create a label to jump to when we want to abort the query */ |
| 105179 | 105447 | addrEnd = sqlite3VdbeMakeLabel(v); |
| 105180 | 105448 | |
| 105181 | 105449 | /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in |
| @@ -105252,11 +105520,12 @@ | ||
| 105252 | 105520 | ** it might be a single loop that uses an index to extract information |
| 105253 | 105521 | ** in the right order to begin with. |
| 105254 | 105522 | */ |
| 105255 | 105523 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); |
| 105256 | 105524 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, |
| 105257 | - WHERE_GROUPBY, 0); | |
| 105525 | + WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 | |
| 105526 | + ); | |
| 105258 | 105527 | if( pWInfo==0 ) goto select_end; |
| 105259 | 105528 | if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ |
| 105260 | 105529 | /* The optimizer is able to deliver rows in group by order so |
| 105261 | 105530 | ** we do not have to sort. The OP_OpenEphemeral table will be |
| 105262 | 105531 | ** cancelled later because we still need to use the pKeyInfo |
| @@ -105317,10 +105586,25 @@ | ||
| 105317 | 105586 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); |
| 105318 | 105587 | sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); |
| 105319 | 105588 | VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); |
| 105320 | 105589 | sAggInfo.useSortingIdx = 1; |
| 105321 | 105590 | sqlite3ExprCacheClear(pParse); |
| 105591 | + | |
| 105592 | + } | |
| 105593 | + | |
| 105594 | + /* If the index or temporary table used by the GROUP BY sort | |
| 105595 | + ** will naturally deliver rows in the order required by the ORDER BY | |
| 105596 | + ** clause, cancel the ephemeral table open coded earlier. | |
| 105597 | + ** | |
| 105598 | + ** This is an optimization - the correct answer should result regardless. | |
| 105599 | + ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER to | |
| 105600 | + ** disable this optimization for testing purposes. */ | |
| 105601 | + if( orderByGrp && OptimizationEnabled(db, SQLITE_GroupByOrder) | |
| 105602 | + && (groupBySort || sqlite3WhereIsSorted(pWInfo)) | |
| 105603 | + ){ | |
| 105604 | + sSort.pOrderBy = 0; | |
| 105605 | + sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); | |
| 105322 | 105606 | } |
| 105323 | 105607 | |
| 105324 | 105608 | /* Evaluate the current GROUP BY terms and store in b0, b1, b2... |
| 105325 | 105609 | ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth) |
| 105326 | 105610 | ** Then compare the current GROUP BY terms against the GROUP BY terms |
| @@ -109680,10 +109964,11 @@ | ||
| 109680 | 109964 | WhereLoop *pLoops; /* List of all WhereLoop objects */ |
| 109681 | 109965 | Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ |
| 109682 | 109966 | LogEst nRowOut; /* Estimated number of output rows */ |
| 109683 | 109967 | u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ |
| 109684 | 109968 | i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ |
| 109969 | + u8 sorted; /* True if really sorted (not just grouped) */ | |
| 109685 | 109970 | u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */ |
| 109686 | 109971 | u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ |
| 109687 | 109972 | u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ |
| 109688 | 109973 | u8 nLevel; /* Number of nested loop */ |
| 109689 | 109974 | int iTop; /* The very beginning of the WHERE loop */ |
| @@ -109739,10 +110024,11 @@ | ||
| 109739 | 110024 | #define WHERE_ONEROW 0x00001000 /* Selects no more than one row */ |
| 109740 | 110025 | #define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */ |
| 109741 | 110026 | #define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */ |
| 109742 | 110027 | #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ |
| 109743 | 110028 | #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ |
| 110029 | +#define WHERE_LIKELIHOOD 0x00020000 /* A likelihood() is affecting nOut */ | |
| 109744 | 110030 | |
| 109745 | 110031 | /************** End of whereInt.h ********************************************/ |
| 109746 | 110032 | /************** Continuing where we left off in where.c **********************/ |
| 109747 | 110033 | |
| 109748 | 110034 | /* |
| @@ -109951,11 +110237,11 @@ | ||
| 109951 | 110237 | } |
| 109952 | 110238 | pTerm = &pWC->a[idx = pWC->nTerm++]; |
| 109953 | 110239 | if( p && ExprHasProperty(p, EP_Unlikely) ){ |
| 109954 | 110240 | pTerm->truthProb = sqlite3LogEst(p->iTable) - 99; |
| 109955 | 110241 | }else{ |
| 109956 | - pTerm->truthProb = -1; | |
| 110242 | + pTerm->truthProb = 1; | |
| 109957 | 110243 | } |
| 109958 | 110244 | pTerm->pExpr = sqlite3ExprSkipCollate(p); |
| 109959 | 110245 | pTerm->wtFlags = wtFlags; |
| 109960 | 110246 | pTerm->pWC = pWC; |
| 109961 | 110247 | pTerm->iParent = -1; |
| @@ -111680,11 +111966,12 @@ | ||
| 111680 | 111966 | tRowcnt iLower, iUpper, iGap; |
| 111681 | 111967 | if( i==0 ){ |
| 111682 | 111968 | iLower = 0; |
| 111683 | 111969 | iUpper = aSample[0].anLt[iCol]; |
| 111684 | 111970 | }else{ |
| 111685 | - iUpper = i>=pIdx->nSample ? pIdx->aiRowEst[0] : aSample[i].anLt[iCol]; | |
| 111971 | + i64 nRow0 = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]); | |
| 111972 | + iUpper = i>=pIdx->nSample ? nRow0 : aSample[i].anLt[iCol]; | |
| 111686 | 111973 | iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol]; |
| 111687 | 111974 | } |
| 111688 | 111975 | aStat[1] = (pIdx->nKeyCol>iCol ? pIdx->aAvgEq[iCol] : 1); |
| 111689 | 111976 | if( iLower>=iUpper ){ |
| 111690 | 111977 | iGap = 0; |
| @@ -111698,10 +111985,33 @@ | ||
| 111698 | 111985 | } |
| 111699 | 111986 | aStat[0] = iLower + iGap; |
| 111700 | 111987 | } |
| 111701 | 111988 | } |
| 111702 | 111989 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 111990 | + | |
| 111991 | +/* | |
| 111992 | +** If it is not NULL, pTerm is a term that provides an upper or lower | |
| 111993 | +** bound on a range scan. Without considering pTerm, it is estimated | |
| 111994 | +** that the scan will visit nNew rows. This function returns the number | |
| 111995 | +** estimated to be visited after taking pTerm into account. | |
| 111996 | +** | |
| 111997 | +** If the user explicitly specified a likelihood() value for this term, | |
| 111998 | +** then the return value is the likelihood multiplied by the number of | |
| 111999 | +** input rows. Otherwise, this function assumes that an "IS NOT NULL" term | |
| 112000 | +** has a likelihood of 0.50, and any other term a likelihood of 0.25. | |
| 112001 | +*/ | |
| 112002 | +static LogEst whereRangeAdjust(WhereTerm *pTerm, LogEst nNew){ | |
| 112003 | + LogEst nRet = nNew; | |
| 112004 | + if( pTerm ){ | |
| 112005 | + if( pTerm->truthProb<=0 ){ | |
| 112006 | + nRet += pTerm->truthProb; | |
| 112007 | + }else if( (pTerm->wtFlags & TERM_VNULL)==0 ){ | |
| 112008 | + nRet -= 20; assert( 20==sqlite3LogEst(4) ); | |
| 112009 | + } | |
| 112010 | + } | |
| 112011 | + return nRet; | |
| 112012 | +} | |
| 111703 | 112013 | |
| 111704 | 112014 | /* |
| 111705 | 112015 | ** This function is used to estimate the number of rows that will be visited |
| 111706 | 112016 | ** by scanning an index for a range of values. The range may have an upper |
| 111707 | 112017 | ** bound, a lower bound, or both. The WHERE clause terms that set the upper |
| @@ -111791,11 +112101,11 @@ | ||
| 111791 | 112101 | aff = p->pTable->aCol[p->aiColumn[nEq]].affinity; |
| 111792 | 112102 | } |
| 111793 | 112103 | /* Determine iLower and iUpper using ($P) only. */ |
| 111794 | 112104 | if( nEq==0 ){ |
| 111795 | 112105 | iLower = 0; |
| 111796 | - iUpper = p->aiRowEst[0]; | |
| 112106 | + iUpper = sqlite3LogEstToInt(p->aiRowLogEst[0]); | |
| 111797 | 112107 | }else{ |
| 111798 | 112108 | /* Note: this call could be optimized away - since the same values must |
| 111799 | 112109 | ** have been requested when testing key $P in whereEqualScanEst(). */ |
| 111800 | 112110 | whereKeyStats(pParse, p, pRec, 0, a); |
| 111801 | 112111 | iLower = a[0]; |
| @@ -111851,21 +112161,22 @@ | ||
| 111851 | 112161 | #else |
| 111852 | 112162 | UNUSED_PARAMETER(pParse); |
| 111853 | 112163 | UNUSED_PARAMETER(pBuilder); |
| 111854 | 112164 | #endif |
| 111855 | 112165 | assert( pLower || pUpper ); |
| 111856 | - /* TUNING: Each inequality constraint reduces the search space 4-fold. | |
| 111857 | - ** A BETWEEN operator, therefore, reduces the search space 16-fold */ | |
| 111858 | - nNew = nOut; | |
| 111859 | - if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){ | |
| 111860 | - nNew -= 20; assert( 20==sqlite3LogEst(4) ); | |
| 111861 | - nOut--; | |
| 111862 | - } | |
| 111863 | - if( pUpper ){ | |
| 111864 | - nNew -= 20; assert( 20==sqlite3LogEst(4) ); | |
| 111865 | - nOut--; | |
| 111866 | - } | |
| 112166 | + assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 ); | |
| 112167 | + nNew = whereRangeAdjust(pLower, nOut); | |
| 112168 | + nNew = whereRangeAdjust(pUpper, nNew); | |
| 112169 | + | |
| 112170 | + /* TUNING: If there is both an upper and lower limit, assume the range is | |
| 112171 | + ** reduced by an additional 75%. This means that, by default, an open-ended | |
| 112172 | + ** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the | |
| 112173 | + ** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to | |
| 112174 | + ** match 1/64 of the index. */ | |
| 112175 | + if( pLower && pUpper ) nNew -= 20; | |
| 112176 | + | |
| 112177 | + nOut -= (pLower!=0) + (pUpper!=0); | |
| 111867 | 112178 | if( nNew<10 ) nNew = 10; |
| 111868 | 112179 | if( nNew<nOut ) nOut = nNew; |
| 111869 | 112180 | pLoop->nOut = (LogEst)nOut; |
| 111870 | 112181 | return rc; |
| 111871 | 112182 | } |
| @@ -111958,26 +112269,27 @@ | ||
| 111958 | 112269 | WhereLoopBuilder *pBuilder, |
| 111959 | 112270 | ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ |
| 111960 | 112271 | tRowcnt *pnRow /* Write the revised row estimate here */ |
| 111961 | 112272 | ){ |
| 111962 | 112273 | Index *p = pBuilder->pNew->u.btree.pIndex; |
| 112274 | + i64 nRow0 = sqlite3LogEstToInt(p->aiRowLogEst[0]); | |
| 111963 | 112275 | int nRecValid = pBuilder->nRecValid; |
| 111964 | 112276 | int rc = SQLITE_OK; /* Subfunction return code */ |
| 111965 | 112277 | tRowcnt nEst; /* Number of rows for a single term */ |
| 111966 | 112278 | tRowcnt nRowEst = 0; /* New estimate of the number of rows */ |
| 111967 | 112279 | int i; /* Loop counter */ |
| 111968 | 112280 | |
| 111969 | 112281 | assert( p->aSample!=0 ); |
| 111970 | 112282 | for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){ |
| 111971 | - nEst = p->aiRowEst[0]; | |
| 112283 | + nEst = nRow0; | |
| 111972 | 112284 | rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst); |
| 111973 | 112285 | nRowEst += nEst; |
| 111974 | 112286 | pBuilder->nRecValid = nRecValid; |
| 111975 | 112287 | } |
| 111976 | 112288 | |
| 111977 | 112289 | if( rc==SQLITE_OK ){ |
| 111978 | - if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0]; | |
| 112290 | + if( nRowEst > nRow0 ) nRowEst = nRow0; | |
| 111979 | 112291 | *pnRow = nRowEst; |
| 111980 | 112292 | WHERETRACE(0x10,("IN row estimate: est=%g\n", nRowEst)); |
| 111981 | 112293 | } |
| 111982 | 112294 | assert( pBuilder->nRecValid==nRecValid ); |
| 111983 | 112295 | return rc; |
| @@ -112416,17 +112728,24 @@ | ||
| 112416 | 112728 | zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias); |
| 112417 | 112729 | } |
| 112418 | 112730 | if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 |
| 112419 | 112731 | && ALWAYS(pLoop->u.btree.pIndex!=0) |
| 112420 | 112732 | ){ |
| 112733 | + const char *zFmt; | |
| 112734 | + Index *pIdx = pLoop->u.btree.pIndex; | |
| 112421 | 112735 | char *zWhere = explainIndexRange(db, pLoop, pItem->pTab); |
| 112422 | - zMsg = sqlite3MAppendf(db, zMsg, | |
| 112423 | - ((flags & WHERE_AUTO_INDEX) ? | |
| 112424 | - "%s USING AUTOMATIC %sINDEX%.0s%s" : | |
| 112425 | - "%s USING %sINDEX %s%s"), | |
| 112426 | - zMsg, ((flags & WHERE_IDX_ONLY) ? "COVERING " : ""), | |
| 112427 | - pLoop->u.btree.pIndex->zName, zWhere); | |
| 112736 | + assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); | |
| 112737 | + if( !HasRowid(pItem->pTab) && pIdx->autoIndex==2 ){ | |
| 112738 | + zFmt = zWhere ? "%s USING PRIMARY KEY%.0s%s" : "%s%.0s%s"; | |
| 112739 | + }else if( flags & WHERE_AUTO_INDEX ){ | |
| 112740 | + zFmt = "%s USING AUTOMATIC COVERING INDEX%.0s%s"; | |
| 112741 | + }else if( flags & WHERE_IDX_ONLY ){ | |
| 112742 | + zFmt = "%s USING COVERING INDEX %s%s"; | |
| 112743 | + }else{ | |
| 112744 | + zFmt = "%s USING INDEX %s%s"; | |
| 112745 | + } | |
| 112746 | + zMsg = sqlite3MAppendf(db, zMsg, zFmt, zMsg, pIdx->zName, zWhere); | |
| 112428 | 112747 | sqlite3DbFree(db, zWhere); |
| 112429 | 112748 | }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ |
| 112430 | 112749 | zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg); |
| 112431 | 112750 | |
| 112432 | 112751 | if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ |
| @@ -113459,11 +113778,11 @@ | ||
| 113459 | 113778 | if( pX->nLTerm >= pY->nLTerm ) return 0; /* X is not a subset of Y */ |
| 113460 | 113779 | if( pX->rRun >= pY->rRun ){ |
| 113461 | 113780 | if( pX->rRun > pY->rRun ) return 0; /* X costs more than Y */ |
| 113462 | 113781 | if( pX->nOut > pY->nOut ) return 0; /* X costs more than Y */ |
| 113463 | 113782 | } |
| 113464 | - for(j=0, i=pX->nLTerm-1; i>=0; i--){ | |
| 113783 | + for(i=pX->nLTerm-1; i>=0; i--){ | |
| 113465 | 113784 | for(j=pY->nLTerm-1; j>=0; j--){ |
| 113466 | 113785 | if( pY->aLTerm[j]==pX->aLTerm[i] ) break; |
| 113467 | 113786 | } |
| 113468 | 113787 | if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */ |
| 113469 | 113788 | } |
| @@ -113481,16 +113800,29 @@ | ||
| 113481 | 113800 | ** is a proper subset. |
| 113482 | 113801 | ** |
| 113483 | 113802 | ** To say "WhereLoop X is a proper subset of Y" means that X uses fewer |
| 113484 | 113803 | ** WHERE clause terms than Y and that every WHERE clause term used by X is |
| 113485 | 113804 | ** also used by Y. |
| 113805 | +** | |
| 113806 | +** This adjustment is omitted for SKIPSCAN loops. In a SKIPSCAN loop, the | |
| 113807 | +** WhereLoop.nLTerm field is not an accurate measure of the number of WHERE | |
| 113808 | +** clause terms covered, since some of the first nLTerm entries in aLTerm[] | |
| 113809 | +** will be NULL (because they are skipped). That makes it more difficult | |
| 113810 | +** to compare the loops. We could add extra code to do the comparison, and | |
| 113811 | +** perhaps we will someday. But SKIPSCAN is sufficiently uncommon, and this | |
| 113812 | +** adjustment is sufficient minor, that it is very difficult to construct | |
| 113813 | +** a test case where the extra code would improve the query plan. Better | |
| 113814 | +** to avoid the added complexity and just omit cost adjustments to SKIPSCAN | |
| 113815 | +** loops. | |
| 113486 | 113816 | */ |
| 113487 | 113817 | static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){ |
| 113488 | 113818 | if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return; |
| 113819 | + if( (pTemplate->wsFlags & WHERE_SKIPSCAN)!=0 ) return; | |
| 113489 | 113820 | for(; p; p=p->pNextLoop){ |
| 113490 | 113821 | if( p->iTab!=pTemplate->iTab ) continue; |
| 113491 | 113822 | if( (p->wsFlags & WHERE_INDEXED)==0 ) continue; |
| 113823 | + if( (p->wsFlags & WHERE_SKIPSCAN)!=0 ) continue; | |
| 113492 | 113824 | if( whereLoopCheaperProperSubset(p, pTemplate) ){ |
| 113493 | 113825 | /* Adjust pTemplate cost downward so that it is cheaper than its |
| 113494 | 113826 | ** subset p */ |
| 113495 | 113827 | pTemplate->rRun = p->rRun; |
| 113496 | 113828 | pTemplate->nOut = p->nOut - 1; |
| @@ -113711,17 +114043,24 @@ | ||
| 113711 | 114043 | pX = pLoop->aLTerm[j]; |
| 113712 | 114044 | if( pX==0 ) continue; |
| 113713 | 114045 | if( pX==pTerm ) break; |
| 113714 | 114046 | if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; |
| 113715 | 114047 | } |
| 113716 | - if( j<0 ) pLoop->nOut += pTerm->truthProb; | |
| 114048 | + if( j<0 ){ | |
| 114049 | + pLoop->nOut += (pTerm->truthProb<=0 ? pTerm->truthProb : -1); | |
| 114050 | + } | |
| 113717 | 114051 | } |
| 113718 | 114052 | } |
| 113719 | 114053 | |
| 113720 | 114054 | /* |
| 113721 | -** We have so far matched pBuilder->pNew->u.btree.nEq terms of the index pIndex. | |
| 113722 | -** Try to match one more. | |
| 114055 | +** We have so far matched pBuilder->pNew->u.btree.nEq terms of the | |
| 114056 | +** index pIndex. Try to match one more. | |
| 114057 | +** | |
| 114058 | +** When this function is called, pBuilder->pNew->nOut contains the | |
| 114059 | +** number of rows expected to be visited by filtering using the nEq | |
| 114060 | +** terms only. If it is modified, this value is restored before this | |
| 114061 | +** function returns. | |
| 113723 | 114062 | ** |
| 113724 | 114063 | ** If pProbe->tnum==0, that means pIndex is a fake index used for the |
| 113725 | 114064 | ** INTEGER PRIMARY KEY. |
| 113726 | 114065 | */ |
| 113727 | 114066 | static int whereLoopAddBtreeIndex( |
| @@ -113743,11 +114082,10 @@ | ||
| 113743 | 114082 | u16 saved_nSkip; /* Original value of pNew->u.btree.nSkip */ |
| 113744 | 114083 | u32 saved_wsFlags; /* Original value of pNew->wsFlags */ |
| 113745 | 114084 | LogEst saved_nOut; /* Original value of pNew->nOut */ |
| 113746 | 114085 | int iCol; /* Index of the column in the table */ |
| 113747 | 114086 | int rc = SQLITE_OK; /* Return code */ |
| 113748 | - LogEst nRowEst; /* Estimated index selectivity */ | |
| 113749 | 114087 | LogEst rLogSize; /* Logarithm of table size */ |
| 113750 | 114088 | WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ |
| 113751 | 114089 | |
| 113752 | 114090 | pNew = pBuilder->pNew; |
| 113753 | 114091 | if( db->mallocFailed ) return SQLITE_NOMEM; |
| @@ -113764,15 +114102,12 @@ | ||
| 113764 | 114102 | if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); |
| 113765 | 114103 | |
| 113766 | 114104 | assert( pNew->u.btree.nEq<=pProbe->nKeyCol ); |
| 113767 | 114105 | if( pNew->u.btree.nEq < pProbe->nKeyCol ){ |
| 113768 | 114106 | iCol = pProbe->aiColumn[pNew->u.btree.nEq]; |
| 113769 | - nRowEst = sqlite3LogEst(pProbe->aiRowEst[pNew->u.btree.nEq+1]); | |
| 113770 | - if( nRowEst==0 && pProbe->onError==OE_None ) nRowEst = 1; | |
| 113771 | 114107 | }else{ |
| 113772 | 114108 | iCol = -1; |
| 113773 | - nRowEst = 0; | |
| 113774 | 114109 | } |
| 113775 | 114110 | pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol, |
| 113776 | 114111 | opMask, pProbe); |
| 113777 | 114112 | saved_nEq = pNew->u.btree.nEq; |
| 113778 | 114113 | saved_nSkip = pNew->u.btree.nSkip; |
| @@ -113779,57 +114114,68 @@ | ||
| 113779 | 114114 | saved_nLTerm = pNew->nLTerm; |
| 113780 | 114115 | saved_wsFlags = pNew->wsFlags; |
| 113781 | 114116 | saved_prereq = pNew->prereq; |
| 113782 | 114117 | saved_nOut = pNew->nOut; |
| 113783 | 114118 | pNew->rSetup = 0; |
| 113784 | - rLogSize = estLog(sqlite3LogEst(pProbe->aiRowEst[0])); | |
| 114119 | + rLogSize = estLog(pProbe->aiRowLogEst[0]); | |
| 113785 | 114120 | |
| 113786 | 114121 | /* Consider using a skip-scan if there are no WHERE clause constraints |
| 113787 | 114122 | ** available for the left-most terms of the index, and if the average |
| 113788 | - ** number of repeats in the left-most terms is at least 18. The magic | |
| 113789 | - ** number 18 was found by experimentation to be the payoff point where | |
| 113790 | - ** skip-scan become faster than a full-scan. | |
| 113791 | - */ | |
| 114123 | + ** number of repeats in the left-most terms is at least 18. | |
| 114124 | + ** | |
| 114125 | + ** The magic number 18 is selected on the basis that scanning 17 rows | |
| 114126 | + ** is almost always quicker than an index seek (even though if the index | |
| 114127 | + ** contains fewer than 2^17 rows we assume otherwise in other parts of | |
| 114128 | + ** the code). And, even if it is not, it should not be too much slower. | |
| 114129 | + ** On the other hand, the extra seeks could end up being significantly | |
| 114130 | + ** more expensive. */ | |
| 114131 | + assert( 42==sqlite3LogEst(18) ); | |
| 113792 | 114132 | if( pTerm==0 |
| 113793 | 114133 | && saved_nEq==saved_nSkip |
| 113794 | 114134 | && saved_nEq+1<pProbe->nKeyCol |
| 113795 | - && pProbe->aiRowEst[saved_nEq+1]>=18 /* TUNING: Minimum for skip-scan */ | |
| 114135 | + && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ | |
| 113796 | 114136 | && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK |
| 113797 | 114137 | ){ |
| 113798 | 114138 | LogEst nIter; |
| 113799 | 114139 | pNew->u.btree.nEq++; |
| 113800 | 114140 | pNew->u.btree.nSkip++; |
| 113801 | 114141 | pNew->aLTerm[pNew->nLTerm++] = 0; |
| 113802 | 114142 | pNew->wsFlags |= WHERE_SKIPSCAN; |
| 113803 | - nIter = sqlite3LogEst(pProbe->aiRowEst[0]/pProbe->aiRowEst[saved_nEq+1]); | |
| 113804 | - pNew->rRun = rLogSize + nIter; | |
| 113805 | - pNew->nOut += nIter; | |
| 113806 | - whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter); | |
| 114143 | + nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1]; | |
| 114144 | + pNew->nOut -= nIter; | |
| 114145 | + whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul); | |
| 113807 | 114146 | pNew->nOut = saved_nOut; |
| 113808 | 114147 | } |
| 113809 | 114148 | for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ |
| 114149 | + u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */ | |
| 114150 | + LogEst rCostIdx; | |
| 114151 | + LogEst nOutUnadjusted; /* nOut before IN() and WHERE adjustments */ | |
| 113810 | 114152 | int nIn = 0; |
| 113811 | 114153 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 113812 | 114154 | int nRecValid = pBuilder->nRecValid; |
| 113813 | 114155 | #endif |
| 113814 | - if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) | |
| 114156 | + if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) | |
| 113815 | 114157 | && (iCol<0 || pSrc->pTab->aCol[iCol].notNull) |
| 113816 | 114158 | ){ |
| 113817 | 114159 | continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */ |
| 113818 | 114160 | } |
| 113819 | 114161 | if( pTerm->prereqRight & pNew->maskSelf ) continue; |
| 113820 | 114162 | |
| 113821 | - assert( pNew->nOut==saved_nOut ); | |
| 113822 | - | |
| 113823 | 114163 | pNew->wsFlags = saved_wsFlags; |
| 113824 | 114164 | pNew->u.btree.nEq = saved_nEq; |
| 113825 | 114165 | pNew->nLTerm = saved_nLTerm; |
| 113826 | 114166 | if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ |
| 113827 | 114167 | pNew->aLTerm[pNew->nLTerm++] = pTerm; |
| 113828 | 114168 | pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf; |
| 113829 | - pNew->rRun = rLogSize; /* Baseline cost is log2(N). Adjustments below */ | |
| 113830 | - if( pTerm->eOperator & WO_IN ){ | |
| 114169 | + | |
| 114170 | + assert( nInMul==0 | |
| 114171 | + || (pNew->wsFlags & WHERE_COLUMN_NULL)!=0 | |
| 114172 | + || (pNew->wsFlags & WHERE_COLUMN_IN)!=0 | |
| 114173 | + || (pNew->wsFlags & WHERE_SKIPSCAN)!=0 | |
| 114174 | + ); | |
| 114175 | + | |
| 114176 | + if( eOp & WO_IN ){ | |
| 113831 | 114177 | Expr *pExpr = pTerm->pExpr; |
| 113832 | 114178 | pNew->wsFlags |= WHERE_COLUMN_IN; |
| 113833 | 114179 | if( ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 113834 | 114180 | /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ |
| 113835 | 114181 | nIn = 46; assert( 46==sqlite3LogEst(25) ); |
| @@ -113837,87 +114183,122 @@ | ||
| 113837 | 114183 | /* "x IN (value, value, ...)" */ |
| 113838 | 114184 | nIn = sqlite3LogEst(pExpr->x.pList->nExpr); |
| 113839 | 114185 | } |
| 113840 | 114186 | assert( nIn>0 ); /* RHS always has 2 or more terms... The parser |
| 113841 | 114187 | ** changes "x IN (?)" into "x=?". */ |
| 113842 | - pNew->rRun += nIn; | |
| 113843 | - pNew->u.btree.nEq++; | |
| 113844 | - pNew->nOut = nRowEst + nInMul + nIn; | |
| 113845 | - }else if( pTerm->eOperator & (WO_EQ) ){ | |
| 113846 | - assert( | |
| 113847 | - (pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN|WHERE_SKIPSCAN))!=0 | |
| 113848 | - || nInMul==0 | |
| 113849 | - ); | |
| 114188 | + | |
| 114189 | + }else if( eOp & (WO_EQ) ){ | |
| 113850 | 114190 | pNew->wsFlags |= WHERE_COLUMN_EQ; |
| 113851 | - if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1)){ | |
| 113852 | - assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 ); | |
| 114191 | + if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){ | |
| 113853 | 114192 | if( iCol>=0 && pProbe->onError==OE_None ){ |
| 113854 | 114193 | pNew->wsFlags |= WHERE_UNQ_WANTED; |
| 113855 | 114194 | }else{ |
| 113856 | 114195 | pNew->wsFlags |= WHERE_ONEROW; |
| 113857 | 114196 | } |
| 113858 | 114197 | } |
| 113859 | - pNew->u.btree.nEq++; | |
| 113860 | - pNew->nOut = nRowEst + nInMul; | |
| 113861 | - }else if( pTerm->eOperator & (WO_ISNULL) ){ | |
| 114198 | + }else if( eOp & WO_ISNULL ){ | |
| 113862 | 114199 | pNew->wsFlags |= WHERE_COLUMN_NULL; |
| 113863 | - pNew->u.btree.nEq++; | |
| 113864 | - /* TUNING: IS NULL selects 2 rows */ | |
| 113865 | - nIn = 10; assert( 10==sqlite3LogEst(2) ); | |
| 113866 | - pNew->nOut = nRowEst + nInMul + nIn; | |
| 113867 | - }else if( pTerm->eOperator & (WO_GT|WO_GE) ){ | |
| 113868 | - testcase( pTerm->eOperator & WO_GT ); | |
| 113869 | - testcase( pTerm->eOperator & WO_GE ); | |
| 114200 | + }else if( eOp & (WO_GT|WO_GE) ){ | |
| 114201 | + testcase( eOp & WO_GT ); | |
| 114202 | + testcase( eOp & WO_GE ); | |
| 113870 | 114203 | pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; |
| 113871 | 114204 | pBtm = pTerm; |
| 113872 | 114205 | pTop = 0; |
| 113873 | 114206 | }else{ |
| 113874 | - assert( pTerm->eOperator & (WO_LT|WO_LE) ); | |
| 113875 | - testcase( pTerm->eOperator & WO_LT ); | |
| 113876 | - testcase( pTerm->eOperator & WO_LE ); | |
| 114207 | + assert( eOp & (WO_LT|WO_LE) ); | |
| 114208 | + testcase( eOp & WO_LT ); | |
| 114209 | + testcase( eOp & WO_LE ); | |
| 113877 | 114210 | pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; |
| 113878 | 114211 | pTop = pTerm; |
| 113879 | 114212 | pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? |
| 113880 | 114213 | pNew->aLTerm[pNew->nLTerm-2] : 0; |
| 113881 | 114214 | } |
| 114215 | + | |
| 114216 | + /* At this point pNew->nOut is set to the number of rows expected to | |
| 114217 | + ** be visited by the index scan before considering term pTerm, or the | |
| 114218 | + ** values of nIn and nInMul. In other words, assuming that all | |
| 114219 | + ** "x IN(...)" terms are replaced with "x = ?". This block updates | |
| 114220 | + ** the value of pNew->nOut to account for pTerm (but not nIn/nInMul). */ | |
| 114221 | + assert( pNew->nOut==saved_nOut ); | |
| 113882 | 114222 | if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ |
| 113883 | - /* Adjust nOut and rRun for STAT3 range values */ | |
| 113884 | - assert( pNew->nOut==saved_nOut ); | |
| 114223 | + /* Adjust nOut using stat3/stat4 data. Or, if there is no stat3/stat4 | |
| 114224 | + ** data, using some other estimate. */ | |
| 113885 | 114225 | whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew); |
| 113886 | - } | |
| 114226 | + }else{ | |
| 114227 | + int nEq = ++pNew->u.btree.nEq; | |
| 114228 | + assert( eOp & (WO_ISNULL|WO_EQ|WO_IN) ); | |
| 114229 | + | |
| 114230 | + assert( pNew->nOut==saved_nOut ); | |
| 114231 | + if( pTerm->truthProb<=0 && iCol>=0 ){ | |
| 114232 | + assert( (eOp & WO_IN) || nIn==0 ); | |
| 114233 | + testcase( eOp & WO_IN ); | |
| 114234 | + pNew->nOut += pTerm->truthProb; | |
| 114235 | + pNew->nOut -= nIn; | |
| 114236 | + pNew->wsFlags |= WHERE_LIKELIHOOD; | |
| 114237 | + }else{ | |
| 113887 | 114238 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 113888 | - if( nInMul==0 | |
| 113889 | - && pProbe->nSample | |
| 113890 | - && pNew->u.btree.nEq<=pProbe->nSampleCol | |
| 113891 | - && OptimizationEnabled(db, SQLITE_Stat3) | |
| 113892 | - ){ | |
| 113893 | - Expr *pExpr = pTerm->pExpr; | |
| 113894 | - tRowcnt nOut = 0; | |
| 113895 | - if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){ | |
| 113896 | - testcase( pTerm->eOperator & WO_EQ ); | |
| 113897 | - testcase( pTerm->eOperator & WO_ISNULL ); | |
| 113898 | - rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); | |
| 113899 | - }else if( (pTerm->eOperator & WO_IN) | |
| 113900 | - && !ExprHasProperty(pExpr, EP_xIsSelect) ){ | |
| 113901 | - rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); | |
| 113902 | - } | |
| 113903 | - assert( nOut==0 || rc==SQLITE_OK ); | |
| 113904 | - if( nOut ){ | |
| 113905 | - pNew->nOut = sqlite3LogEst(nOut); | |
| 113906 | - if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; | |
| 113907 | - } | |
| 113908 | - } | |
| 113909 | -#endif | |
| 114239 | + tRowcnt nOut = 0; | |
| 114240 | + if( nInMul==0 | |
| 114241 | + && pProbe->nSample | |
| 114242 | + && pNew->u.btree.nEq<=pProbe->nSampleCol | |
| 114243 | + && OptimizationEnabled(db, SQLITE_Stat3) | |
| 114244 | + && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect)) | |
| 114245 | + && (pNew->wsFlags & WHERE_LIKELIHOOD)==0 | |
| 114246 | + ){ | |
| 114247 | + Expr *pExpr = pTerm->pExpr; | |
| 114248 | + if( (eOp & (WO_EQ|WO_ISNULL))!=0 ){ | |
| 114249 | + testcase( eOp & WO_EQ ); | |
| 114250 | + testcase( eOp & WO_ISNULL ); | |
| 114251 | + rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); | |
| 114252 | + }else{ | |
| 114253 | + rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); | |
| 114254 | + } | |
| 114255 | + assert( rc!=SQLITE_OK || nOut>0 ); | |
| 114256 | + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; | |
| 114257 | + if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ | |
| 114258 | + if( nOut ){ | |
| 114259 | + pNew->nOut = sqlite3LogEst(nOut); | |
| 114260 | + if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; | |
| 114261 | + pNew->nOut -= nIn; | |
| 114262 | + } | |
| 114263 | + } | |
| 114264 | + if( nOut==0 ) | |
| 114265 | +#endif | |
| 114266 | + { | |
| 114267 | + pNew->nOut += (pProbe->aiRowLogEst[nEq] - pProbe->aiRowLogEst[nEq-1]); | |
| 114268 | + if( eOp & WO_ISNULL ){ | |
| 114269 | + /* TUNING: If there is no likelihood() value, assume that a | |
| 114270 | + ** "col IS NULL" expression matches twice as many rows | |
| 114271 | + ** as (col=?). */ | |
| 114272 | + pNew->nOut += 10; | |
| 114273 | + } | |
| 114274 | + } | |
| 114275 | + } | |
| 114276 | + } | |
| 114277 | + | |
| 114278 | + /* Set rCostIdx to the cost of visiting selected rows in index. Add | |
| 114279 | + ** it to pNew->rRun, which is currently set to the cost of the index | |
| 114280 | + ** seek only. Then, if this is a non-covering index, add the cost of | |
| 114281 | + ** visiting the rows in the main table. */ | |
| 114282 | + rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; | |
| 114283 | + pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); | |
| 113910 | 114284 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 113911 | - /* Each row involves a step of the index, then a binary search of | |
| 113912 | - ** the main table */ | |
| 113913 | - pNew->rRun = sqlite3LogEstAdd(pNew->rRun,rLogSize>27 ? rLogSize-17 : 10); | |
| 114285 | + pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); | |
| 113914 | 114286 | } |
| 113915 | - /* Step cost for each output row */ | |
| 113916 | - pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut); | |
| 114287 | + | |
| 114288 | + nOutUnadjusted = pNew->nOut; | |
| 114289 | + pNew->rRun += nInMul + nIn; | |
| 114290 | + pNew->nOut += nInMul + nIn; | |
| 113917 | 114291 | whereLoopOutputAdjust(pBuilder->pWC, pNew); |
| 113918 | 114292 | rc = whereLoopInsert(pBuilder, pNew); |
| 114293 | + | |
| 114294 | + if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ | |
| 114295 | + pNew->nOut = saved_nOut; | |
| 114296 | + }else{ | |
| 114297 | + pNew->nOut = nOutUnadjusted; | |
| 114298 | + } | |
| 114299 | + | |
| 113919 | 114300 | if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 |
| 113920 | 114301 | && pNew->u.btree.nEq<(pProbe->nKeyCol + (pProbe->zName!=0)) |
| 113921 | 114302 | ){ |
| 113922 | 114303 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); |
| 113923 | 114304 | } |
| @@ -113997,19 +114378,42 @@ | ||
| 113997 | 114378 | |
| 113998 | 114379 | /* |
| 113999 | 114380 | ** Add all WhereLoop objects for a single table of the join where the table |
| 114000 | 114381 | ** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be |
| 114001 | 114382 | ** a b-tree table, not a virtual table. |
| 114383 | +** | |
| 114384 | +** The costs (WhereLoop.rRun) of the b-tree loops added by this function | |
| 114385 | +** are calculated as follows: | |
| 114386 | +** | |
| 114387 | +** For a full scan, assuming the table (or index) contains nRow rows: | |
| 114388 | +** | |
| 114389 | +** cost = nRow * 3.0 // full-table scan | |
| 114390 | +** cost = nRow * K // scan of covering index | |
| 114391 | +** cost = nRow * (K+3.0) // scan of non-covering index | |
| 114392 | +** | |
| 114393 | +** where K is a value between 1.1 and 3.0 set based on the relative | |
| 114394 | +** estimated average size of the index and table records. | |
| 114395 | +** | |
| 114396 | +** For an index scan, where nVisit is the number of index rows visited | |
| 114397 | +** by the scan, and nSeek is the number of seek operations required on | |
| 114398 | +** the index b-tree: | |
| 114399 | +** | |
| 114400 | +** cost = nSeek * (log(nRow) + K * nVisit) // covering index | |
| 114401 | +** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index | |
| 114402 | +** | |
| 114403 | +** Normally, nSeek is 1. nSeek values greater than 1 come about if the | |
| 114404 | +** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when | |
| 114405 | +** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. | |
| 114002 | 114406 | */ |
| 114003 | 114407 | static int whereLoopAddBtree( |
| 114004 | 114408 | WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
| 114005 | 114409 | Bitmask mExtra /* Extra prerequesites for using this table */ |
| 114006 | 114410 | ){ |
| 114007 | 114411 | WhereInfo *pWInfo; /* WHERE analysis context */ |
| 114008 | 114412 | Index *pProbe; /* An index we are evaluating */ |
| 114009 | 114413 | Index sPk; /* A fake index object for the primary key */ |
| 114010 | - tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */ | |
| 114414 | + LogEst aiRowEstPk[2]; /* The aiRowLogEst[] value for the sPk index */ | |
| 114011 | 114415 | i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */ |
| 114012 | 114416 | SrcList *pTabList; /* The FROM clause */ |
| 114013 | 114417 | struct SrcList_item *pSrc; /* The FROM clause btree term to add */ |
| 114014 | 114418 | WhereLoop *pNew; /* Template WhereLoop object */ |
| 114015 | 114419 | int rc = SQLITE_OK; /* Return code */ |
| @@ -114040,24 +114444,25 @@ | ||
| 114040 | 114444 | ** indices to follow */ |
| 114041 | 114445 | Index *pFirst; /* First of real indices on the table */ |
| 114042 | 114446 | memset(&sPk, 0, sizeof(Index)); |
| 114043 | 114447 | sPk.nKeyCol = 1; |
| 114044 | 114448 | sPk.aiColumn = &aiColumnPk; |
| 114045 | - sPk.aiRowEst = aiRowEstPk; | |
| 114449 | + sPk.aiRowLogEst = aiRowEstPk; | |
| 114046 | 114450 | sPk.onError = OE_Replace; |
| 114047 | 114451 | sPk.pTable = pTab; |
| 114048 | - aiRowEstPk[0] = pTab->nRowEst; | |
| 114049 | - aiRowEstPk[1] = 1; | |
| 114452 | + sPk.szIdxRow = pTab->szTabRow; | |
| 114453 | + aiRowEstPk[0] = pTab->nRowLogEst; | |
| 114454 | + aiRowEstPk[1] = 0; | |
| 114050 | 114455 | pFirst = pSrc->pTab->pIndex; |
| 114051 | 114456 | if( pSrc->notIndexed==0 ){ |
| 114052 | 114457 | /* The real indices of the table are only considered if the |
| 114053 | 114458 | ** NOT INDEXED qualifier is omitted from the FROM clause */ |
| 114054 | 114459 | sPk.pNext = pFirst; |
| 114055 | 114460 | } |
| 114056 | 114461 | pProbe = &sPk; |
| 114057 | 114462 | } |
| 114058 | - rSize = sqlite3LogEst(pTab->nRowEst); | |
| 114463 | + rSize = pTab->nRowLogEst; | |
| 114059 | 114464 | rLogSize = estLog(rSize); |
| 114060 | 114465 | |
| 114061 | 114466 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 114062 | 114467 | /* Automatic indexes */ |
| 114063 | 114468 | if( !pBuilder->pOrSet |
| @@ -114103,10 +114508,11 @@ | ||
| 114103 | 114508 | for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){ |
| 114104 | 114509 | if( pProbe->pPartIdxWhere!=0 |
| 114105 | 114510 | && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){ |
| 114106 | 114511 | continue; /* Partial index inappropriate for this query */ |
| 114107 | 114512 | } |
| 114513 | + rSize = pProbe->aiRowLogEst[0]; | |
| 114108 | 114514 | pNew->u.btree.nEq = 0; |
| 114109 | 114515 | pNew->u.btree.nSkip = 0; |
| 114110 | 114516 | pNew->nLTerm = 0; |
| 114111 | 114517 | pNew->iSortIdx = 0; |
| 114112 | 114518 | pNew->rSetup = 0; |
| @@ -114120,14 +114526,12 @@ | ||
| 114120 | 114526 | /* Integer primary key index */ |
| 114121 | 114527 | pNew->wsFlags = WHERE_IPK; |
| 114122 | 114528 | |
| 114123 | 114529 | /* Full table scan */ |
| 114124 | 114530 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 114125 | - /* TUNING: Cost of full table scan is 3*(N + log2(N)). | |
| 114126 | - ** + The extra 3 factor is to encourage the use of indexed lookups | |
| 114127 | - ** over full scans. FIXME */ | |
| 114128 | - pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 16; | |
| 114531 | + /* TUNING: Cost of full table scan is (N*3.0). */ | |
| 114532 | + pNew->rRun = rSize + 16; | |
| 114129 | 114533 | whereLoopOutputAdjust(pWC, pNew); |
| 114130 | 114534 | rc = whereLoopInsert(pBuilder, pNew); |
| 114131 | 114535 | pNew->nOut = rSize; |
| 114132 | 114536 | if( rc ) break; |
| 114133 | 114537 | }else{ |
| @@ -114150,39 +114554,20 @@ | ||
| 114150 | 114554 | && sqlite3GlobalConfig.bUseCis |
| 114151 | 114555 | && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan) |
| 114152 | 114556 | ) |
| 114153 | 114557 | ){ |
| 114154 | 114558 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 114155 | - /* TUNING: The base cost of an index scan is N + log2(N). | |
| 114156 | - ** The log2(N) is for the initial seek to the beginning and the N | |
| 114157 | - ** is for the scan itself. */ | |
| 114158 | - pNew->rRun = sqlite3LogEstAdd(rSize, rLogSize); | |
| 114159 | - if( m==0 ){ | |
| 114160 | - /* TUNING: Cost of a covering index scan is K*(N + log2(N)). | |
| 114161 | - ** + The extra factor K of between 1.1 and 3.0 that depends | |
| 114162 | - ** on the relative sizes of the table and the index. K | |
| 114163 | - ** is smaller for smaller indices, thus favoring them. | |
| 114164 | - ** The upper bound on K (3.0) matches the penalty factor | |
| 114165 | - ** on a full table scan that tries to encourage the use of | |
| 114166 | - ** indexed lookups over full scans. | |
| 114167 | - */ | |
| 114168 | - pNew->rRun += 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; | |
| 114169 | - }else{ | |
| 114170 | - /* TUNING: The cost of scanning a non-covering index is multiplied | |
| 114171 | - ** by log2(N) to account for the binary search of the main table | |
| 114172 | - ** that must happen for each row of the index. | |
| 114173 | - ** TODO: Should there be a multiplier here, analogous to the 3x | |
| 114174 | - ** multiplier for a fulltable scan or covering index scan, to | |
| 114175 | - ** further discourage the use of an index scan? Or is the log2(N) | |
| 114176 | - ** term sufficient discouragement? | |
| 114177 | - ** TODO: What if some or all of the WHERE clause terms can be | |
| 114178 | - ** computed without reference to the original table. Then the | |
| 114179 | - ** penality should reduce to logK where K is the number of output | |
| 114180 | - ** rows. | |
| 114181 | - */ | |
| 114182 | - pNew->rRun += rLogSize; | |
| 114183 | - } | |
| 114559 | + | |
| 114560 | + /* The cost of visiting the index rows is N*K, where K is | |
| 114561 | + ** between 1.1 and 3.0, depending on the relative sizes of the | |
| 114562 | + ** index and table rows. If this is a non-covering index scan, | |
| 114563 | + ** also add the cost of visiting table rows (N*3.0). */ | |
| 114564 | + pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; | |
| 114565 | + if( m!=0 ){ | |
| 114566 | + pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16); | |
| 114567 | + } | |
| 114568 | + | |
| 114184 | 114569 | whereLoopOutputAdjust(pWC, pNew); |
| 114185 | 114570 | rc = whereLoopInsert(pBuilder, pNew); |
| 114186 | 114571 | pNew->nOut = rSize; |
| 114187 | 114572 | if( rc ) break; |
| 114188 | 114573 | } |
| @@ -114382,11 +114767,11 @@ | ||
| 114382 | 114767 | WhereTerm *pTerm, *pWCEnd; |
| 114383 | 114768 | int rc = SQLITE_OK; |
| 114384 | 114769 | int iCur; |
| 114385 | 114770 | WhereClause tempWC; |
| 114386 | 114771 | WhereLoopBuilder sSubBuild; |
| 114387 | - WhereOrSet sSum, sCur, sPrev; | |
| 114772 | + WhereOrSet sSum, sCur; | |
| 114388 | 114773 | struct SrcList_item *pItem; |
| 114389 | 114774 | |
| 114390 | 114775 | pWC = pBuilder->pWC; |
| 114391 | 114776 | if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK; |
| 114392 | 114777 | pWCEnd = pWC->a + pWC->nTerm; |
| @@ -114438,10 +114823,11 @@ | ||
| 114438 | 114823 | break; |
| 114439 | 114824 | }else if( once ){ |
| 114440 | 114825 | whereOrMove(&sSum, &sCur); |
| 114441 | 114826 | once = 0; |
| 114442 | 114827 | }else{ |
| 114828 | + WhereOrSet sPrev; | |
| 114443 | 114829 | whereOrMove(&sPrev, &sSum); |
| 114444 | 114830 | sSum.n = 0; |
| 114445 | 114831 | for(i=0; i<sPrev.n; i++){ |
| 114446 | 114832 | for(j=0; j<sCur.n; j++){ |
| 114447 | 114833 | whereOrInsert(&sSum, sPrev.a[i].prereq | sCur.a[j].prereq, |
| @@ -114456,12 +114842,23 @@ | ||
| 114456 | 114842 | pNew->wsFlags = WHERE_MULTI_OR; |
| 114457 | 114843 | pNew->rSetup = 0; |
| 114458 | 114844 | pNew->iSortIdx = 0; |
| 114459 | 114845 | memset(&pNew->u, 0, sizeof(pNew->u)); |
| 114460 | 114846 | for(i=0; rc==SQLITE_OK && i<sSum.n; i++){ |
| 114461 | - /* TUNING: Multiple by 3.5 for the secondary table lookup */ | |
| 114462 | - pNew->rRun = sSum.a[i].rRun + 18; | |
| 114847 | + /* TUNING: Currently sSum.a[i].rRun is set to the sum of the costs | |
| 114848 | + ** of all sub-scans required by the OR-scan. However, due to rounding | |
| 114849 | + ** errors, it may be that the cost of the OR-scan is equal to its | |
| 114850 | + ** most expensive sub-scan. Add the smallest possible penalty | |
| 114851 | + ** (equivalent to multiplying the cost by 1.07) to ensure that | |
| 114852 | + ** this does not happen. Otherwise, for WHERE clauses such as the | |
| 114853 | + ** following where there is an index on "y": | |
| 114854 | + ** | |
| 114855 | + ** WHERE likelihood(x=?, 0.99) OR y=? | |
| 114856 | + ** | |
| 114857 | + ** the planner may elect to "OR" together a full-table scan and an | |
| 114858 | + ** index lookup. And other similarly odd results. */ | |
| 114859 | + pNew->rRun = sSum.a[i].rRun + 1; | |
| 114463 | 114860 | pNew->nOut = sSum.a[i].nOut; |
| 114464 | 114861 | pNew->prereq = sSum.a[i].prereq; |
| 114465 | 114862 | rc = whereLoopInsert(pBuilder, pNew); |
| 114466 | 114863 | } |
| 114467 | 114864 | } |
| @@ -114520,11 +114917,11 @@ | ||
| 114520 | 114917 | ** N<0: Unknown yet how many terms of ORDER BY might be satisfied. |
| 114521 | 114918 | ** |
| 114522 | 114919 | ** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as |
| 114523 | 114920 | ** strict. With GROUP BY and DISTINCT the only requirement is that |
| 114524 | 114921 | ** equivalent rows appear immediately adjacent to one another. GROUP BY |
| 114525 | -** and DISTINT do not require rows to appear in any particular order as long | |
| 114922 | +** and DISTINCT do not require rows to appear in any particular order as long | |
| 114526 | 114923 | ** as equivelent rows are grouped together. Thus for GROUP BY and DISTINCT |
| 114527 | 114924 | ** the pOrderBy terms can be matched in any order. With ORDER BY, the |
| 114528 | 114925 | ** pOrderBy terms must be matched in strict left-to-right order. |
| 114529 | 114926 | */ |
| 114530 | 114927 | static i8 wherePathSatisfiesOrderBy( |
| @@ -114581,18 +114978,10 @@ | ||
| 114581 | 114978 | ** rowid appears in the ORDER BY clause, the corresponding WhereLoop is |
| 114582 | 114979 | ** automatically order-distinct. |
| 114583 | 114980 | */ |
| 114584 | 114981 | |
| 114585 | 114982 | assert( pOrderBy!=0 ); |
| 114586 | - | |
| 114587 | - /* Sortability of virtual tables is determined by the xBestIndex method | |
| 114588 | - ** of the virtual table itself */ | |
| 114589 | - if( pLast->wsFlags & WHERE_VIRTUALTABLE ){ | |
| 114590 | - testcase( nLoop>0 ); /* True when outer loops are one-row and match | |
| 114591 | - ** no ORDER BY terms */ | |
| 114592 | - return pLast->u.vtab.isOrdered; | |
| 114593 | - } | |
| 114594 | 114983 | if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0; |
| 114595 | 114984 | |
| 114596 | 114985 | nOrderBy = pOrderBy->nExpr; |
| 114597 | 114986 | testcase( nOrderBy==BMS-1 ); |
| 114598 | 114987 | if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */ |
| @@ -114601,11 +114990,14 @@ | ||
| 114601 | 114990 | orderDistinctMask = 0; |
| 114602 | 114991 | ready = 0; |
| 114603 | 114992 | for(iLoop=0; isOrderDistinct && obSat<obDone && iLoop<=nLoop; iLoop++){ |
| 114604 | 114993 | if( iLoop>0 ) ready |= pLoop->maskSelf; |
| 114605 | 114994 | pLoop = iLoop<nLoop ? pPath->aLoop[iLoop] : pLast; |
| 114606 | - assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ); | |
| 114995 | + if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ | |
| 114996 | + if( pLoop->u.vtab.isOrdered ) obSat = obDone; | |
| 114997 | + break; | |
| 114998 | + } | |
| 114607 | 114999 | iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor; |
| 114608 | 115000 | |
| 114609 | 115001 | /* Mark off any ORDER BY term X that is a column in the table of |
| 114610 | 115002 | ** the current loop for which there is term in the WHERE |
| 114611 | 115003 | ** clause of the form X IS NULL or X=? that reference only outer |
| @@ -114689,11 +115081,11 @@ | ||
| 114689 | 115081 | ){ |
| 114690 | 115082 | isOrderDistinct = 0; |
| 114691 | 115083 | } |
| 114692 | 115084 | |
| 114693 | 115085 | /* Find the ORDER BY term that corresponds to the j-th column |
| 114694 | - ** of the index and and mark that ORDER BY term off | |
| 115086 | + ** of the index and mark that ORDER BY term off | |
| 114695 | 115087 | */ |
| 114696 | 115088 | bOnce = 1; |
| 114697 | 115089 | isMatch = 0; |
| 114698 | 115090 | for(i=0; bOnce && i<nOrderBy; i++){ |
| 114699 | 115091 | if( MASKBIT(i) & obSat ) continue; |
| @@ -114769,10 +115161,40 @@ | ||
| 114769 | 115161 | return 0; |
| 114770 | 115162 | } |
| 114771 | 115163 | return -1; |
| 114772 | 115164 | } |
| 114773 | 115165 | |
| 115166 | + | |
| 115167 | +/* | |
| 115168 | +** If the WHERE_GROUPBY flag is set in the mask passed to sqlite3WhereBegin(), | |
| 115169 | +** the planner assumes that the specified pOrderBy list is actually a GROUP | |
| 115170 | +** BY clause - and so any order that groups rows as required satisfies the | |
| 115171 | +** request. | |
| 115172 | +** | |
| 115173 | +** Normally, in this case it is not possible for the caller to determine | |
| 115174 | +** whether or not the rows are really being delivered in sorted order, or | |
| 115175 | +** just in some other order that provides the required grouping. However, | |
| 115176 | +** if the WHERE_SORTBYGROUP flag is also passed to sqlite3WhereBegin(), then | |
| 115177 | +** this function may be called on the returned WhereInfo object. It returns | |
| 115178 | +** true if the rows really will be sorted in the specified order, or false | |
| 115179 | +** otherwise. | |
| 115180 | +** | |
| 115181 | +** For example, assuming: | |
| 115182 | +** | |
| 115183 | +** CREATE INDEX i1 ON t1(x, Y); | |
| 115184 | +** | |
| 115185 | +** then | |
| 115186 | +** | |
| 115187 | +** SELECT * FROM t1 GROUP BY x,y ORDER BY x,y; -- IsSorted()==1 | |
| 115188 | +** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0 | |
| 115189 | +*/ | |
| 115190 | +SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){ | |
| 115191 | + assert( pWInfo->wctrlFlags & WHERE_GROUPBY ); | |
| 115192 | + assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP ); | |
| 115193 | + return pWInfo->sorted; | |
| 115194 | +} | |
| 115195 | + | |
| 114774 | 115196 | #ifdef WHERETRACE_ENABLED |
| 114775 | 115197 | /* For debugging use only: */ |
| 114776 | 115198 | static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){ |
| 114777 | 115199 | static char zName[65]; |
| 114778 | 115200 | int i; |
| @@ -114780,11 +115202,10 @@ | ||
| 114780 | 115202 | if( pLast ) zName[i++] = pLast->cId; |
| 114781 | 115203 | zName[i] = 0; |
| 114782 | 115204 | return zName; |
| 114783 | 115205 | } |
| 114784 | 115206 | #endif |
| 114785 | - | |
| 114786 | 115207 | |
| 114787 | 115208 | /* |
| 114788 | 115209 | ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine |
| 114789 | 115210 | ** attempts to find the lowest cost path that visits each WhereLoop |
| 114790 | 115211 | ** once. This path is then loaded into the pWInfo->a[].pWLoop fields. |
| @@ -114879,26 +115300,31 @@ | ||
| 114879 | 115300 | if( isOrdered<0 ){ |
| 114880 | 115301 | isOrdered = wherePathSatisfiesOrderBy(pWInfo, |
| 114881 | 115302 | pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, |
| 114882 | 115303 | iLoop, pWLoop, &revMask); |
| 114883 | 115304 | if( isOrdered>=0 && isOrdered<nOrderBy ){ |
| 114884 | - /* TUNING: Estimated cost of sorting is N*log(N). | |
| 114885 | - ** If the order-by clause has X terms but only the last Y terms | |
| 114886 | - ** are out of order, then block-sorting will reduce the sorting | |
| 114887 | - ** cost to N*log(N)*log(Y/X). The log(Y/X) term is computed | |
| 114888 | - ** by rScale. | |
| 114889 | - ** TODO: Should the sorting cost get a small multiplier to help | |
| 114890 | - ** discourage the use of sorting and encourage the use of index | |
| 114891 | - ** scans instead? | |
| 114892 | - */ | |
| 115305 | + /* TUNING: Estimated cost of a full external sort, where N is | |
| 115306 | + ** the number of rows to sort is: | |
| 115307 | + ** | |
| 115308 | + ** cost = (3.0 * N * log(N)). | |
| 115309 | + ** | |
| 115310 | + ** Or, if the order-by clause has X terms but only the last Y | |
| 115311 | + ** terms are out of order, then block-sorting will reduce the | |
| 115312 | + ** sorting cost to: | |
| 115313 | + ** | |
| 115314 | + ** cost = (3.0 * N * log(N)) * (Y/X) | |
| 115315 | + ** | |
| 115316 | + ** The (Y/X) term is implemented using stack variable rScale | |
| 115317 | + ** below. */ | |
| 114893 | 115318 | LogEst rScale, rSortCost; |
| 114894 | - assert( nOrderBy>0 ); | |
| 115319 | + assert( nOrderBy>0 && 66==sqlite3LogEst(100) ); | |
| 114895 | 115320 | rScale = sqlite3LogEst((nOrderBy-isOrdered)*100/nOrderBy) - 66; |
| 114896 | - rSortCost = nRowEst + estLog(nRowEst) + rScale; | |
| 115321 | + rSortCost = nRowEst + estLog(nRowEst) + rScale + 16; | |
| 115322 | + | |
| 114897 | 115323 | /* TUNING: The cost of implementing DISTINCT using a B-TREE is |
| 114898 | - ** also N*log(N) but it has a larger constant of proportionality. | |
| 114899 | - ** Multiply by 3.0. */ | |
| 115324 | + ** similar but with a larger constant of proportionality. | |
| 115325 | + ** Multiply by an additional factor of 3.0. */ | |
| 114900 | 115326 | if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 114901 | 115327 | rSortCost += 16; |
| 114902 | 115328 | } |
| 114903 | 115329 | WHERETRACE(0x002, |
| 114904 | 115330 | ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", |
| @@ -115062,11 +115488,23 @@ | ||
| 115062 | 115488 | }else{ |
| 115063 | 115489 | pWInfo->nOBSat = pFrom->isOrdered; |
| 115064 | 115490 | if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0; |
| 115065 | 115491 | pWInfo->revMask = pFrom->revLoop; |
| 115066 | 115492 | } |
| 115493 | + if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP) | |
| 115494 | + && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr | |
| 115495 | + ){ | |
| 115496 | + Bitmask notUsed = 0; | |
| 115497 | + int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, | |
| 115498 | + pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used | |
| 115499 | + ); | |
| 115500 | + assert( pWInfo->sorted==0 ); | |
| 115501 | + pWInfo->sorted = (nOrder==pWInfo->pOrderBy->nExpr); | |
| 115502 | + } | |
| 115067 | 115503 | } |
| 115504 | + | |
| 115505 | + | |
| 115068 | 115506 | pWInfo->nRowOut = pFrom->nRow; |
| 115069 | 115507 | |
| 115070 | 115508 | /* Free temporary memory and return success */ |
| 115071 | 115509 | sqlite3DbFree(db, pSpace); |
| 115072 | 115510 | return SQLITE_OK; |
| @@ -123654,10 +124092,32 @@ | ||
| 123654 | 124092 | int sz = va_arg(ap, int); |
| 123655 | 124093 | int *aProg = va_arg(ap, int*); |
| 123656 | 124094 | rc = sqlite3BitvecBuiltinTest(sz, aProg); |
| 123657 | 124095 | break; |
| 123658 | 124096 | } |
| 124097 | + | |
| 124098 | + /* | |
| 124099 | + ** sqlite3_test_control(FAULT_INSTALL, xCallback) | |
| 124100 | + ** | |
| 124101 | + ** Arrange to invoke xCallback() whenever sqlite3FaultSim() is called, | |
| 124102 | + ** if xCallback is not NULL. | |
| 124103 | + ** | |
| 124104 | + ** As a test of the fault simulator mechanism itself, sqlite3FaultSim(0) | |
| 124105 | + ** is called immediately after installing the new callback and the return | |
| 124106 | + ** value from sqlite3FaultSim(0) becomes the return from | |
| 124107 | + ** sqlite3_test_control(). | |
| 124108 | + */ | |
| 124109 | + case SQLITE_TESTCTRL_FAULT_INSTALL: { | |
| 124110 | + /* MSVC is picky about pulling func ptrs from va lists. | |
| 124111 | + ** http://support.microsoft.com/kb/47961 | |
| 124112 | + ** sqlite3Config.xTestCallback = va_arg(ap, int(*)(int)); | |
| 124113 | + */ | |
| 124114 | + typedef int(*TESTCALLBACKFUNC_t)(int); | |
| 124115 | + sqlite3Config.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t); | |
| 124116 | + rc = sqlite3FaultSim(0); | |
| 124117 | + break; | |
| 124118 | + } | |
| 123659 | 124119 | |
| 123660 | 124120 | /* |
| 123661 | 124121 | ** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) |
| 123662 | 124122 | ** |
| 123663 | 124123 | ** Register hooks to call to indicate which malloc() failures |
| @@ -123964,11 +124424,11 @@ | ||
| 123964 | 124424 | ** Return 1 if database is read-only or 0 if read/write. Return -1 if |
| 123965 | 124425 | ** no such database exists. |
| 123966 | 124426 | */ |
| 123967 | 124427 | SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){ |
| 123968 | 124428 | Btree *pBt = sqlite3DbNameToBtree(db, zDbName); |
| 123969 | - return pBt ? sqlite3PagerIsreadonly(sqlite3BtreePager(pBt)) : -1; | |
| 124429 | + return pBt ? sqlite3BtreeIsReadonly(pBt) : -1; | |
| 123970 | 124430 | } |
| 123971 | 124431 | |
| 123972 | 124432 | /************** End of main.c ************************************************/ |
| 123973 | 124433 | /************** Begin file notify.c ******************************************/ |
| 123974 | 124434 | /* |
| @@ -125084,17 +125544,17 @@ | ||
| 125084 | 125544 | char **azColumn; /* column names. malloced */ |
| 125085 | 125545 | u8 *abNotindexed; /* True for 'notindexed' columns */ |
| 125086 | 125546 | sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ |
| 125087 | 125547 | char *zContentTbl; /* content=xxx option, or NULL */ |
| 125088 | 125548 | char *zLanguageid; /* languageid=xxx option, or NULL */ |
| 125089 | - u8 bAutoincrmerge; /* True if automerge=1 */ | |
| 125549 | + int nAutoincrmerge; /* Value configured by 'automerge' */ | |
| 125090 | 125550 | u32 nLeafAdd; /* Number of leaf blocks added this trans */ |
| 125091 | 125551 | |
| 125092 | 125552 | /* Precompiled statements used by the implementation. Each of these |
| 125093 | 125553 | ** statements is run and reset within a single virtual table API call. |
| 125094 | 125554 | */ |
| 125095 | - sqlite3_stmt *aStmt[37]; | |
| 125555 | + sqlite3_stmt *aStmt[40]; | |
| 125096 | 125556 | |
| 125097 | 125557 | char *zReadExprlist; |
| 125098 | 125558 | char *zWriteExprlist; |
| 125099 | 125559 | |
| 125100 | 125560 | int nNodeSize; /* Soft limit for node size */ |
| @@ -126512,11 +126972,11 @@ | ||
| 126512 | 126972 | p->nMaxPendingData = FTS3_MAX_PENDING_DATA; |
| 126513 | 126973 | p->bHasDocsize = (isFts4 && bNoDocsize==0); |
| 126514 | 126974 | p->bHasStat = isFts4; |
| 126515 | 126975 | p->bFts4 = isFts4; |
| 126516 | 126976 | p->bDescIdx = bDescIdx; |
| 126517 | - p->bAutoincrmerge = 0xff; /* 0xff means setting unknown */ | |
| 126977 | + p->nAutoincrmerge = 0xff; /* 0xff means setting unknown */ | |
| 126518 | 126978 | p->zContentTbl = zContent; |
| 126519 | 126979 | p->zLanguageid = zLanguageid; |
| 126520 | 126980 | zContent = 0; |
| 126521 | 126981 | zLanguageid = 0; |
| 126522 | 126982 | TESTONLY( p->inTransaction = -1 ); |
| @@ -128481,19 +128941,22 @@ | ||
| 128481 | 128941 | const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */ |
| 128482 | 128942 | |
| 128483 | 128943 | Fts3Table *p = (Fts3Table*)pVtab; |
| 128484 | 128944 | int rc = sqlite3Fts3PendingTermsFlush(p); |
| 128485 | 128945 | |
| 128486 | - if( rc==SQLITE_OK && p->bAutoincrmerge==1 && p->nLeafAdd>(nMinMerge/16) ){ | |
| 128946 | + if( rc==SQLITE_OK | |
| 128947 | + && p->nLeafAdd>(nMinMerge/16) | |
| 128948 | + && p->nAutoincrmerge && p->nAutoincrmerge!=0xff | |
| 128949 | + ){ | |
| 128487 | 128950 | int mxLevel = 0; /* Maximum relative level value in db */ |
| 128488 | 128951 | int A; /* Incr-merge parameter A */ |
| 128489 | 128952 | |
| 128490 | 128953 | rc = sqlite3Fts3MaxLevel(p, &mxLevel); |
| 128491 | 128954 | assert( rc==SQLITE_OK || mxLevel==0 ); |
| 128492 | 128955 | A = p->nLeafAdd * mxLevel; |
| 128493 | 128956 | A += (A/2); |
| 128494 | - if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, 8); | |
| 128957 | + if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge); | |
| 128495 | 128958 | } |
| 128496 | 128959 | sqlite3Fts3SegmentsClose(p); |
| 128497 | 128960 | return rc; |
| 128498 | 128961 | } |
| 128499 | 128962 | |
| @@ -131712,44 +132175,27 @@ | ||
| 131712 | 132175 | sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; |
| 131713 | 132176 | sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; |
| 131714 | 132177 | int rc; |
| 131715 | 132178 | sqlite3_tokenizer_cursor *pCursor; |
| 131716 | 132179 | Fts3Expr *pRet = 0; |
| 131717 | - int nConsumed = 0; | |
| 132180 | + int i = 0; | |
| 131718 | 132181 | |
| 131719 | - rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor); | |
| 132182 | + /* Set variable i to the maximum number of bytes of input to tokenize. */ | |
| 132183 | + for(i=0; i<n; i++){ | |
| 132184 | + if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break; | |
| 132185 | + if( z[i]=='*' || z[i]=='"' ) break; | |
| 132186 | + } | |
| 132187 | + | |
| 132188 | + *pnConsumed = i; | |
| 132189 | + rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor); | |
| 131720 | 132190 | if( rc==SQLITE_OK ){ |
| 131721 | 132191 | const char *zToken; |
| 131722 | 132192 | int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; |
| 131723 | 132193 | int nByte; /* total space to allocate */ |
| 131724 | 132194 | |
| 131725 | 132195 | rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); |
| 131726 | - | |
| 131727 | - if( (rc==SQLITE_OK || rc==SQLITE_DONE) && sqlite3_fts3_enable_parentheses ){ | |
| 131728 | - int i; | |
| 131729 | - if( rc==SQLITE_DONE ) iStart = n; | |
| 131730 | - for(i=0; i<iStart; i++){ | |
| 131731 | - if( z[i]=='(' ){ | |
| 131732 | - pParse->nNest++; | |
| 131733 | - rc = fts3ExprParse(pParse, &z[i+1], n-i-1, &pRet, &nConsumed); | |
| 131734 | - if( rc==SQLITE_OK && !pRet ){ | |
| 131735 | - rc = SQLITE_DONE; | |
| 131736 | - } | |
| 131737 | - nConsumed = (int)(i + 1 + nConsumed); | |
| 131738 | - break; | |
| 131739 | - } | |
| 131740 | - | |
| 131741 | - if( z[i]==')' ){ | |
| 131742 | - rc = SQLITE_DONE; | |
| 131743 | - pParse->nNest--; | |
| 131744 | - nConsumed = i+1; | |
| 131745 | - break; | |
| 131746 | - } | |
| 131747 | - } | |
| 131748 | - } | |
| 131749 | - | |
| 131750 | - if( nConsumed==0 && rc==SQLITE_OK ){ | |
| 132196 | + if( rc==SQLITE_OK ){ | |
| 131751 | 132197 | nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; |
| 131752 | 132198 | pRet = (Fts3Expr *)fts3MallocZero(nByte); |
| 131753 | 132199 | if( !pRet ){ |
| 131754 | 132200 | rc = SQLITE_NOMEM; |
| 131755 | 132201 | }else{ |
| @@ -131779,17 +132225,18 @@ | ||
| 131779 | 132225 | break; |
| 131780 | 132226 | } |
| 131781 | 132227 | } |
| 131782 | 132228 | |
| 131783 | 132229 | } |
| 131784 | - nConsumed = iEnd; | |
| 132230 | + *pnConsumed = iEnd; | |
| 132231 | + }else if( i && rc==SQLITE_DONE ){ | |
| 132232 | + rc = SQLITE_OK; | |
| 131785 | 132233 | } |
| 131786 | 132234 | |
| 131787 | 132235 | pModule->xClose(pCursor); |
| 131788 | 132236 | } |
| 131789 | 132237 | |
| 131790 | - *pnConsumed = nConsumed; | |
| 131791 | 132238 | *ppExpr = pRet; |
| 131792 | 132239 | return rc; |
| 131793 | 132240 | } |
| 131794 | 132241 | |
| 131795 | 132242 | |
| @@ -132035,10 +132482,25 @@ | ||
| 132035 | 132482 | return SQLITE_ERROR; |
| 132036 | 132483 | } |
| 132037 | 132484 | return getNextString(pParse, &zInput[1], ii-1, ppExpr); |
| 132038 | 132485 | } |
| 132039 | 132486 | |
| 132487 | + if( sqlite3_fts3_enable_parentheses ){ | |
| 132488 | + if( *zInput=='(' ){ | |
| 132489 | + int nConsumed = 0; | |
| 132490 | + pParse->nNest++; | |
| 132491 | + rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed); | |
| 132492 | + if( rc==SQLITE_OK && !*ppExpr ){ rc = SQLITE_DONE; } | |
| 132493 | + *pnConsumed = (int)(zInput - z) + 1 + nConsumed; | |
| 132494 | + return rc; | |
| 132495 | + }else if( *zInput==')' ){ | |
| 132496 | + pParse->nNest--; | |
| 132497 | + *pnConsumed = (zInput - z) + 1; | |
| 132498 | + *ppExpr = 0; | |
| 132499 | + return SQLITE_DONE; | |
| 132500 | + } | |
| 132501 | + } | |
| 132040 | 132502 | |
| 132041 | 132503 | /* If control flows to this point, this must be a regular token, or |
| 132042 | 132504 | ** the end of the input. Read a regular token using the sqlite3_tokenizer |
| 132043 | 132505 | ** interface. Before doing so, figure out if there is an explicit |
| 132044 | 132506 | ** column specifier for the token. |
| @@ -132153,100 +132615,104 @@ | ||
| 132153 | 132615 | int isRequirePhrase = 1; |
| 132154 | 132616 | |
| 132155 | 132617 | while( rc==SQLITE_OK ){ |
| 132156 | 132618 | Fts3Expr *p = 0; |
| 132157 | 132619 | int nByte = 0; |
| 132158 | - rc = getNextNode(pParse, zIn, nIn, &p, &nByte); | |
| 132159 | - if( rc==SQLITE_OK ){ | |
| 132160 | - int isPhrase; | |
| 132161 | - | |
| 132162 | - if( !sqlite3_fts3_enable_parentheses | |
| 132163 | - && p->eType==FTSQUERY_PHRASE && pParse->isNot | |
| 132164 | - ){ | |
| 132165 | - /* Create an implicit NOT operator. */ | |
| 132166 | - Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr)); | |
| 132167 | - if( !pNot ){ | |
| 132168 | - sqlite3Fts3ExprFree(p); | |
| 132169 | - rc = SQLITE_NOMEM; | |
| 132170 | - goto exprparse_out; | |
| 132171 | - } | |
| 132172 | - pNot->eType = FTSQUERY_NOT; | |
| 132173 | - pNot->pRight = p; | |
| 132174 | - p->pParent = pNot; | |
| 132175 | - if( pNotBranch ){ | |
| 132176 | - pNot->pLeft = pNotBranch; | |
| 132177 | - pNotBranch->pParent = pNot; | |
| 132178 | - } | |
| 132179 | - pNotBranch = pNot; | |
| 132180 | - p = pPrev; | |
| 132181 | - }else{ | |
| 132182 | - int eType = p->eType; | |
| 132183 | - isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); | |
| 132184 | - | |
| 132185 | - /* The isRequirePhrase variable is set to true if a phrase or | |
| 132186 | - ** an expression contained in parenthesis is required. If a | |
| 132187 | - ** binary operator (AND, OR, NOT or NEAR) is encounted when | |
| 132188 | - ** isRequirePhrase is set, this is a syntax error. | |
| 132189 | - */ | |
| 132190 | - if( !isPhrase && isRequirePhrase ){ | |
| 132191 | - sqlite3Fts3ExprFree(p); | |
| 132192 | - rc = SQLITE_ERROR; | |
| 132193 | - goto exprparse_out; | |
| 132194 | - } | |
| 132195 | - | |
| 132196 | - if( isPhrase && !isRequirePhrase ){ | |
| 132197 | - /* Insert an implicit AND operator. */ | |
| 132198 | - Fts3Expr *pAnd; | |
| 132199 | - assert( pRet && pPrev ); | |
| 132200 | - pAnd = fts3MallocZero(sizeof(Fts3Expr)); | |
| 132201 | - if( !pAnd ){ | |
| 132202 | - sqlite3Fts3ExprFree(p); | |
| 132203 | - rc = SQLITE_NOMEM; | |
| 132204 | - goto exprparse_out; | |
| 132205 | - } | |
| 132206 | - pAnd->eType = FTSQUERY_AND; | |
| 132207 | - insertBinaryOperator(&pRet, pPrev, pAnd); | |
| 132208 | - pPrev = pAnd; | |
| 132209 | - } | |
| 132210 | - | |
| 132211 | - /* This test catches attempts to make either operand of a NEAR | |
| 132212 | - ** operator something other than a phrase. For example, either of | |
| 132213 | - ** the following: | |
| 132214 | - ** | |
| 132215 | - ** (bracketed expression) NEAR phrase | |
| 132216 | - ** phrase NEAR (bracketed expression) | |
| 132217 | - ** | |
| 132218 | - ** Return an error in either case. | |
| 132219 | - */ | |
| 132220 | - if( pPrev && ( | |
| 132221 | - (eType==FTSQUERY_NEAR && !isPhrase && pPrev->eType!=FTSQUERY_PHRASE) | |
| 132222 | - || (eType!=FTSQUERY_PHRASE && isPhrase && pPrev->eType==FTSQUERY_NEAR) | |
| 132223 | - )){ | |
| 132224 | - sqlite3Fts3ExprFree(p); | |
| 132225 | - rc = SQLITE_ERROR; | |
| 132226 | - goto exprparse_out; | |
| 132227 | - } | |
| 132228 | - | |
| 132229 | - if( isPhrase ){ | |
| 132230 | - if( pRet ){ | |
| 132231 | - assert( pPrev && pPrev->pLeft && pPrev->pRight==0 ); | |
| 132232 | - pPrev->pRight = p; | |
| 132233 | - p->pParent = pPrev; | |
| 132234 | - }else{ | |
| 132235 | - pRet = p; | |
| 132236 | - } | |
| 132237 | - }else{ | |
| 132238 | - insertBinaryOperator(&pRet, pPrev, p); | |
| 132239 | - } | |
| 132240 | - isRequirePhrase = !isPhrase; | |
| 132620 | + | |
| 132621 | + rc = getNextNode(pParse, zIn, nIn, &p, &nByte); | |
| 132622 | + assert( nByte>0 || (rc!=SQLITE_OK && p==0) ); | |
| 132623 | + if( rc==SQLITE_OK ){ | |
| 132624 | + if( p ){ | |
| 132625 | + int isPhrase; | |
| 132626 | + | |
| 132627 | + if( !sqlite3_fts3_enable_parentheses | |
| 132628 | + && p->eType==FTSQUERY_PHRASE && pParse->isNot | |
| 132629 | + ){ | |
| 132630 | + /* Create an implicit NOT operator. */ | |
| 132631 | + Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr)); | |
| 132632 | + if( !pNot ){ | |
| 132633 | + sqlite3Fts3ExprFree(p); | |
| 132634 | + rc = SQLITE_NOMEM; | |
| 132635 | + goto exprparse_out; | |
| 132636 | + } | |
| 132637 | + pNot->eType = FTSQUERY_NOT; | |
| 132638 | + pNot->pRight = p; | |
| 132639 | + p->pParent = pNot; | |
| 132640 | + if( pNotBranch ){ | |
| 132641 | + pNot->pLeft = pNotBranch; | |
| 132642 | + pNotBranch->pParent = pNot; | |
| 132643 | + } | |
| 132644 | + pNotBranch = pNot; | |
| 132645 | + p = pPrev; | |
| 132646 | + }else{ | |
| 132647 | + int eType = p->eType; | |
| 132648 | + isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); | |
| 132649 | + | |
| 132650 | + /* The isRequirePhrase variable is set to true if a phrase or | |
| 132651 | + ** an expression contained in parenthesis is required. If a | |
| 132652 | + ** binary operator (AND, OR, NOT or NEAR) is encounted when | |
| 132653 | + ** isRequirePhrase is set, this is a syntax error. | |
| 132654 | + */ | |
| 132655 | + if( !isPhrase && isRequirePhrase ){ | |
| 132656 | + sqlite3Fts3ExprFree(p); | |
| 132657 | + rc = SQLITE_ERROR; | |
| 132658 | + goto exprparse_out; | |
| 132659 | + } | |
| 132660 | + | |
| 132661 | + if( isPhrase && !isRequirePhrase ){ | |
| 132662 | + /* Insert an implicit AND operator. */ | |
| 132663 | + Fts3Expr *pAnd; | |
| 132664 | + assert( pRet && pPrev ); | |
| 132665 | + pAnd = fts3MallocZero(sizeof(Fts3Expr)); | |
| 132666 | + if( !pAnd ){ | |
| 132667 | + sqlite3Fts3ExprFree(p); | |
| 132668 | + rc = SQLITE_NOMEM; | |
| 132669 | + goto exprparse_out; | |
| 132670 | + } | |
| 132671 | + pAnd->eType = FTSQUERY_AND; | |
| 132672 | + insertBinaryOperator(&pRet, pPrev, pAnd); | |
| 132673 | + pPrev = pAnd; | |
| 132674 | + } | |
| 132675 | + | |
| 132676 | + /* This test catches attempts to make either operand of a NEAR | |
| 132677 | + ** operator something other than a phrase. For example, either of | |
| 132678 | + ** the following: | |
| 132679 | + ** | |
| 132680 | + ** (bracketed expression) NEAR phrase | |
| 132681 | + ** phrase NEAR (bracketed expression) | |
| 132682 | + ** | |
| 132683 | + ** Return an error in either case. | |
| 132684 | + */ | |
| 132685 | + if( pPrev && ( | |
| 132686 | + (eType==FTSQUERY_NEAR && !isPhrase && pPrev->eType!=FTSQUERY_PHRASE) | |
| 132687 | + || (eType!=FTSQUERY_PHRASE && isPhrase && pPrev->eType==FTSQUERY_NEAR) | |
| 132688 | + )){ | |
| 132689 | + sqlite3Fts3ExprFree(p); | |
| 132690 | + rc = SQLITE_ERROR; | |
| 132691 | + goto exprparse_out; | |
| 132692 | + } | |
| 132693 | + | |
| 132694 | + if( isPhrase ){ | |
| 132695 | + if( pRet ){ | |
| 132696 | + assert( pPrev && pPrev->pLeft && pPrev->pRight==0 ); | |
| 132697 | + pPrev->pRight = p; | |
| 132698 | + p->pParent = pPrev; | |
| 132699 | + }else{ | |
| 132700 | + pRet = p; | |
| 132701 | + } | |
| 132702 | + }else{ | |
| 132703 | + insertBinaryOperator(&pRet, pPrev, p); | |
| 132704 | + } | |
| 132705 | + isRequirePhrase = !isPhrase; | |
| 132706 | + } | |
| 132707 | + pPrev = p; | |
| 132241 | 132708 | } |
| 132242 | 132709 | assert( nByte>0 ); |
| 132243 | 132710 | } |
| 132244 | 132711 | assert( rc!=SQLITE_OK || (nByte>0 && nByte<=nIn) ); |
| 132245 | 132712 | nIn -= nByte; |
| 132246 | 132713 | zIn += nByte; |
| 132247 | - pPrev = p; | |
| 132248 | 132714 | } |
| 132249 | 132715 | |
| 132250 | 132716 | if( rc==SQLITE_DONE && pRet && isRequirePhrase ){ |
| 132251 | 132717 | rc = SQLITE_ERROR; |
| 132252 | 132718 | } |
| @@ -135230,10 +135696,11 @@ | ||
| 135230 | 135696 | int nMalloc; /* Size of malloc'd buffer at zMalloc */ |
| 135231 | 135697 | char *zMalloc; /* Malloc'd space (possibly) used for zTerm */ |
| 135232 | 135698 | int nSize; /* Size of allocation at aData */ |
| 135233 | 135699 | int nData; /* Bytes of data in aData */ |
| 135234 | 135700 | char *aData; /* Pointer to block from malloc() */ |
| 135701 | + i64 nLeafData; /* Number of bytes of leaf data written */ | |
| 135235 | 135702 | }; |
| 135236 | 135703 | |
| 135237 | 135704 | /* |
| 135238 | 135705 | ** Type SegmentNode is used by the following three functions to create |
| 135239 | 135706 | ** the interior part of the segment b+-tree structures (everything except |
| @@ -135304,10 +135771,14 @@ | ||
| 135304 | 135771 | #define SQL_SELECT_SEGDIR 32 |
| 135305 | 135772 | #define SQL_CHOMP_SEGDIR 33 |
| 135306 | 135773 | #define SQL_SEGMENT_IS_APPENDABLE 34 |
| 135307 | 135774 | #define SQL_SELECT_INDEXES 35 |
| 135308 | 135775 | #define SQL_SELECT_MXLEVEL 36 |
| 135776 | + | |
| 135777 | +#define SQL_SELECT_LEVEL_RANGE2 37 | |
| 135778 | +#define SQL_UPDATE_LEVEL_IDX 38 | |
| 135779 | +#define SQL_UPDATE_LEVEL 39 | |
| 135309 | 135780 | |
| 135310 | 135781 | /* |
| 135311 | 135782 | ** This function is used to obtain an SQLite prepared statement handle |
| 135312 | 135783 | ** for the statement identified by the second argument. If successful, |
| 135313 | 135784 | ** *pp is set to the requested statement handle and SQLITE_OK returned. |
| @@ -135406,11 +135877,22 @@ | ||
| 135406 | 135877 | ** Return the list of valid segment indexes for absolute level ? */ |
| 135407 | 135878 | /* 35 */ "SELECT idx FROM %Q.'%q_segdir' WHERE level=? ORDER BY 1 ASC", |
| 135408 | 135879 | |
| 135409 | 135880 | /* SQL_SELECT_MXLEVEL |
| 135410 | 135881 | ** Return the largest relative level in the FTS index or indexes. */ |
| 135411 | -/* 36 */ "SELECT max( level %% 1024 ) FROM %Q.'%q_segdir'" | |
| 135882 | +/* 36 */ "SELECT max( level %% 1024 ) FROM %Q.'%q_segdir'", | |
| 135883 | + | |
| 135884 | + /* Return segments in order from oldest to newest.*/ | |
| 135885 | +/* 37 */ "SELECT level, idx, end_block " | |
| 135886 | + "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? " | |
| 135887 | + "ORDER BY level DESC, idx ASC", | |
| 135888 | + | |
| 135889 | + /* Update statements used while promoting segments */ | |
| 135890 | +/* 38 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=-1,idx=? " | |
| 135891 | + "WHERE level=? AND idx=?", | |
| 135892 | +/* 39 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=? WHERE level=-1" | |
| 135893 | + | |
| 135412 | 135894 | }; |
| 135413 | 135895 | int rc = SQLITE_OK; |
| 135414 | 135896 | sqlite3_stmt *pStmt; |
| 135415 | 135897 | |
| 135416 | 135898 | assert( SizeofArray(azSql)==SizeofArray(p->aStmt) ); |
| @@ -136947,10 +137429,11 @@ | ||
| 136947 | 137429 | sqlite3_int64 iLevel, /* Value for "level" field (absolute level) */ |
| 136948 | 137430 | int iIdx, /* Value for "idx" field */ |
| 136949 | 137431 | sqlite3_int64 iStartBlock, /* Value for "start_block" field */ |
| 136950 | 137432 | sqlite3_int64 iLeafEndBlock, /* Value for "leaves_end_block" field */ |
| 136951 | 137433 | sqlite3_int64 iEndBlock, /* Value for "end_block" field */ |
| 137434 | + sqlite3_int64 nLeafData, /* Bytes of leaf data in segment */ | |
| 136952 | 137435 | char *zRoot, /* Blob value for "root" field */ |
| 136953 | 137436 | int nRoot /* Number of bytes in buffer zRoot */ |
| 136954 | 137437 | ){ |
| 136955 | 137438 | sqlite3_stmt *pStmt; |
| 136956 | 137439 | int rc = fts3SqlStmt(p, SQL_INSERT_SEGDIR, &pStmt, 0); |
| @@ -136957,11 +137440,17 @@ | ||
| 136957 | 137440 | if( rc==SQLITE_OK ){ |
| 136958 | 137441 | sqlite3_bind_int64(pStmt, 1, iLevel); |
| 136959 | 137442 | sqlite3_bind_int(pStmt, 2, iIdx); |
| 136960 | 137443 | sqlite3_bind_int64(pStmt, 3, iStartBlock); |
| 136961 | 137444 | sqlite3_bind_int64(pStmt, 4, iLeafEndBlock); |
| 136962 | - sqlite3_bind_int64(pStmt, 5, iEndBlock); | |
| 137445 | + if( nLeafData==0 ){ | |
| 137446 | + sqlite3_bind_int64(pStmt, 5, iEndBlock); | |
| 137447 | + }else{ | |
| 137448 | + char *zEnd = sqlite3_mprintf("%lld %lld", iEndBlock, nLeafData); | |
| 137449 | + if( !zEnd ) return SQLITE_NOMEM; | |
| 137450 | + sqlite3_bind_text(pStmt, 5, zEnd, -1, sqlite3_free); | |
| 137451 | + } | |
| 136963 | 137452 | sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC); |
| 136964 | 137453 | sqlite3_step(pStmt); |
| 136965 | 137454 | rc = sqlite3_reset(pStmt); |
| 136966 | 137455 | } |
| 136967 | 137456 | return rc; |
| @@ -137282,10 +137771,13 @@ | ||
| 137282 | 137771 | sqlite3Fts3VarintLen(nTerm) + /* varint containing suffix size */ |
| 137283 | 137772 | nTerm + /* Term suffix */ |
| 137284 | 137773 | sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ |
| 137285 | 137774 | nDoclist; /* Doclist data */ |
| 137286 | 137775 | } |
| 137776 | + | |
| 137777 | + /* Increase the total number of bytes written to account for the new entry. */ | |
| 137778 | + pWriter->nLeafData += nReq; | |
| 137287 | 137779 | |
| 137288 | 137780 | /* If the buffer currently allocated is too small for this entry, realloc |
| 137289 | 137781 | ** the buffer to make it large enough. |
| 137290 | 137782 | */ |
| 137291 | 137783 | if( nReq>pWriter->nSize ){ |
| @@ -137354,17 +137846,17 @@ | ||
| 137354 | 137846 | if( rc==SQLITE_OK ){ |
| 137355 | 137847 | rc = fts3NodeWrite(p, pWriter->pTree, 1, |
| 137356 | 137848 | pWriter->iFirst, pWriter->iFree, &iLast, &zRoot, &nRoot); |
| 137357 | 137849 | } |
| 137358 | 137850 | if( rc==SQLITE_OK ){ |
| 137359 | - rc = fts3WriteSegdir( | |
| 137360 | - p, iLevel, iIdx, pWriter->iFirst, iLastLeaf, iLast, zRoot, nRoot); | |
| 137851 | + rc = fts3WriteSegdir(p, iLevel, iIdx, | |
| 137852 | + pWriter->iFirst, iLastLeaf, iLast, pWriter->nLeafData, zRoot, nRoot); | |
| 137361 | 137853 | } |
| 137362 | 137854 | }else{ |
| 137363 | 137855 | /* The entire tree fits on the root node. Write it to the segdir table. */ |
| 137364 | - rc = fts3WriteSegdir( | |
| 137365 | - p, iLevel, iIdx, 0, 0, 0, pWriter->aData, pWriter->nData); | |
| 137856 | + rc = fts3WriteSegdir(p, iLevel, iIdx, | |
| 137857 | + 0, 0, 0, pWriter->nLeafData, pWriter->aData, pWriter->nData); | |
| 137366 | 137858 | } |
| 137367 | 137859 | p->nLeafAdd++; |
| 137368 | 137860 | return rc; |
| 137369 | 137861 | } |
| 137370 | 137862 | |
| @@ -137443,10 +137935,41 @@ | ||
| 137443 | 137935 | if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 137444 | 137936 | *pnMax = sqlite3_column_int64(pStmt, 0); |
| 137445 | 137937 | } |
| 137446 | 137938 | return sqlite3_reset(pStmt); |
| 137447 | 137939 | } |
| 137940 | + | |
| 137941 | +/* | |
| 137942 | +** iAbsLevel is an absolute level that may be assumed to exist within | |
| 137943 | +** the database. This function checks if it is the largest level number | |
| 137944 | +** within its index. Assuming no error occurs, *pbMax is set to 1 if | |
| 137945 | +** iAbsLevel is indeed the largest level, or 0 otherwise, and SQLITE_OK | |
| 137946 | +** is returned. If an error occurs, an error code is returned and the | |
| 137947 | +** final value of *pbMax is undefined. | |
| 137948 | +*/ | |
| 137949 | +static int fts3SegmentIsMaxLevel(Fts3Table *p, i64 iAbsLevel, int *pbMax){ | |
| 137950 | + | |
| 137951 | + /* Set pStmt to the compiled version of: | |
| 137952 | + ** | |
| 137953 | + ** SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? | |
| 137954 | + ** | |
| 137955 | + ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR). | |
| 137956 | + */ | |
| 137957 | + sqlite3_stmt *pStmt; | |
| 137958 | + int rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); | |
| 137959 | + if( rc!=SQLITE_OK ) return rc; | |
| 137960 | + sqlite3_bind_int64(pStmt, 1, iAbsLevel+1); | |
| 137961 | + sqlite3_bind_int64(pStmt, 2, | |
| 137962 | + ((iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL | |
| 137963 | + ); | |
| 137964 | + | |
| 137965 | + *pbMax = 0; | |
| 137966 | + if( SQLITE_ROW==sqlite3_step(pStmt) ){ | |
| 137967 | + *pbMax = sqlite3_column_type(pStmt, 0)==SQLITE_NULL; | |
| 137968 | + } | |
| 137969 | + return sqlite3_reset(pStmt); | |
| 137970 | +} | |
| 137448 | 137971 | |
| 137449 | 137972 | /* |
| 137450 | 137973 | ** Delete all entries in the %_segments table associated with the segment |
| 137451 | 137974 | ** opened with seg-reader pSeg. This function does not affect the contents |
| 137452 | 137975 | ** of the %_segdir table. |
| @@ -137978,10 +138501,144 @@ | ||
| 137978 | 138501 | pCsr->nSegment = 0; |
| 137979 | 138502 | pCsr->apSegment = 0; |
| 137980 | 138503 | pCsr->aBuffer = 0; |
| 137981 | 138504 | } |
| 137982 | 138505 | } |
| 138506 | + | |
| 138507 | +/* | |
| 138508 | +** Decode the "end_block" field, selected by column iCol of the SELECT | |
| 138509 | +** statement passed as the first argument. | |
| 138510 | +** | |
| 138511 | +** The "end_block" field may contain either an integer, or a text field | |
| 138512 | +** containing the text representation of two non-negative integers separated | |
| 138513 | +** by one or more space (0x20) characters. In the first case, set *piEndBlock | |
| 138514 | +** to the integer value and *pnByte to zero before returning. In the second, | |
| 138515 | +** set *piEndBlock to the first value and *pnByte to the second. | |
| 138516 | +*/ | |
| 138517 | +static void fts3ReadEndBlockField( | |
| 138518 | + sqlite3_stmt *pStmt, | |
| 138519 | + int iCol, | |
| 138520 | + i64 *piEndBlock, | |
| 138521 | + i64 *pnByte | |
| 138522 | +){ | |
| 138523 | + const unsigned char *zText = sqlite3_column_text(pStmt, iCol); | |
| 138524 | + if( zText ){ | |
| 138525 | + int i; | |
| 138526 | + int iMul = 1; | |
| 138527 | + i64 iVal = 0; | |
| 138528 | + for(i=0; zText[i]>='0' && zText[i]<='9'; i++){ | |
| 138529 | + iVal = iVal*10 + (zText[i] - '0'); | |
| 138530 | + } | |
| 138531 | + *piEndBlock = iVal; | |
| 138532 | + while( zText[i]==' ' ) i++; | |
| 138533 | + iVal = 0; | |
| 138534 | + if( zText[i]=='-' ){ | |
| 138535 | + i++; | |
| 138536 | + iMul = -1; | |
| 138537 | + } | |
| 138538 | + for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){ | |
| 138539 | + iVal = iVal*10 + (zText[i] - '0'); | |
| 138540 | + } | |
| 138541 | + *pnByte = (iVal * (i64)iMul); | |
| 138542 | + } | |
| 138543 | +} | |
| 138544 | + | |
| 138545 | + | |
| 138546 | +/* | |
| 138547 | +** A segment of size nByte bytes has just been written to absolute level | |
| 138548 | +** iAbsLevel. Promote any segments that should be promoted as a result. | |
| 138549 | +*/ | |
| 138550 | +static int fts3PromoteSegments( | |
| 138551 | + Fts3Table *p, /* FTS table handle */ | |
| 138552 | + sqlite3_int64 iAbsLevel, /* Absolute level just updated */ | |
| 138553 | + sqlite3_int64 nByte /* Size of new segment at iAbsLevel */ | |
| 138554 | +){ | |
| 138555 | + int rc = SQLITE_OK; | |
| 138556 | + sqlite3_stmt *pRange; | |
| 138557 | + | |
| 138558 | + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE2, &pRange, 0); | |
| 138559 | + | |
| 138560 | + if( rc==SQLITE_OK ){ | |
| 138561 | + int bOk = 0; | |
| 138562 | + i64 iLast = (iAbsLevel/FTS3_SEGDIR_MAXLEVEL + 1) * FTS3_SEGDIR_MAXLEVEL - 1; | |
| 138563 | + i64 nLimit = (nByte*3)/2; | |
| 138564 | + | |
| 138565 | + /* Loop through all entries in the %_segdir table corresponding to | |
| 138566 | + ** segments in this index on levels greater than iAbsLevel. If there is | |
| 138567 | + ** at least one such segment, and it is possible to determine that all | |
| 138568 | + ** such segments are smaller than nLimit bytes in size, they will be | |
| 138569 | + ** promoted to level iAbsLevel. */ | |
| 138570 | + sqlite3_bind_int64(pRange, 1, iAbsLevel+1); | |
| 138571 | + sqlite3_bind_int64(pRange, 2, iLast); | |
| 138572 | + while( SQLITE_ROW==sqlite3_step(pRange) ){ | |
| 138573 | + i64 nSize, dummy; | |
| 138574 | + fts3ReadEndBlockField(pRange, 2, &dummy, &nSize); | |
| 138575 | + if( nSize<=0 || nSize>nLimit ){ | |
| 138576 | + /* If nSize==0, then the %_segdir.end_block field does not not | |
| 138577 | + ** contain a size value. This happens if it was written by an | |
| 138578 | + ** old version of FTS. In this case it is not possible to determine | |
| 138579 | + ** the size of the segment, and so segment promotion does not | |
| 138580 | + ** take place. */ | |
| 138581 | + bOk = 0; | |
| 138582 | + break; | |
| 138583 | + } | |
| 138584 | + bOk = 1; | |
| 138585 | + } | |
| 138586 | + rc = sqlite3_reset(pRange); | |
| 138587 | + | |
| 138588 | + if( bOk ){ | |
| 138589 | + int iIdx = 0; | |
| 138590 | + sqlite3_stmt *pUpdate1; | |
| 138591 | + sqlite3_stmt *pUpdate2; | |
| 138592 | + | |
| 138593 | + if( rc==SQLITE_OK ){ | |
| 138594 | + rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0); | |
| 138595 | + } | |
| 138596 | + if( rc==SQLITE_OK ){ | |
| 138597 | + rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL, &pUpdate2, 0); | |
| 138598 | + } | |
| 138599 | + | |
| 138600 | + if( rc==SQLITE_OK ){ | |
| 138601 | + | |
| 138602 | + /* Loop through all %_segdir entries for segments in this index with | |
| 138603 | + ** levels equal to or greater than iAbsLevel. As each entry is visited, | |
| 138604 | + ** updated it to set (level = -1) and (idx = N), where N is 0 for the | |
| 138605 | + ** oldest segment in the range, 1 for the next oldest, and so on. | |
| 138606 | + ** | |
| 138607 | + ** In other words, move all segments being promoted to level -1, | |
| 138608 | + ** setting the "idx" fields as appropriate to keep them in the same | |
| 138609 | + ** order. The contents of level -1 (which is never used, except | |
| 138610 | + ** transiently here), will be moved back to level iAbsLevel below. */ | |
| 138611 | + sqlite3_bind_int64(pRange, 1, iAbsLevel); | |
| 138612 | + while( SQLITE_ROW==sqlite3_step(pRange) ){ | |
| 138613 | + sqlite3_bind_int(pUpdate1, 1, iIdx++); | |
| 138614 | + sqlite3_bind_int(pUpdate1, 2, sqlite3_column_int(pRange, 0)); | |
| 138615 | + sqlite3_bind_int(pUpdate1, 3, sqlite3_column_int(pRange, 1)); | |
| 138616 | + sqlite3_step(pUpdate1); | |
| 138617 | + rc = sqlite3_reset(pUpdate1); | |
| 138618 | + if( rc!=SQLITE_OK ){ | |
| 138619 | + sqlite3_reset(pRange); | |
| 138620 | + break; | |
| 138621 | + } | |
| 138622 | + } | |
| 138623 | + } | |
| 138624 | + if( rc==SQLITE_OK ){ | |
| 138625 | + rc = sqlite3_reset(pRange); | |
| 138626 | + } | |
| 138627 | + | |
| 138628 | + /* Move level -1 to level iAbsLevel */ | |
| 138629 | + if( rc==SQLITE_OK ){ | |
| 138630 | + sqlite3_bind_int64(pUpdate2, 1, iAbsLevel); | |
| 138631 | + sqlite3_step(pUpdate2); | |
| 138632 | + rc = sqlite3_reset(pUpdate2); | |
| 138633 | + } | |
| 138634 | + } | |
| 138635 | + } | |
| 138636 | + | |
| 138637 | + | |
| 138638 | + return rc; | |
| 138639 | +} | |
| 137983 | 138640 | |
| 137984 | 138641 | /* |
| 137985 | 138642 | ** Merge all level iLevel segments in the database into a single |
| 137986 | 138643 | ** iLevel+1 segment. Or, if iLevel<0, merge all segments into a |
| 137987 | 138644 | ** single segment with a level equal to the numerically largest level |
| @@ -138003,10 +138660,11 @@ | ||
| 138003 | 138660 | sqlite3_int64 iNewLevel = 0; /* Level/index to create new segment at */ |
| 138004 | 138661 | SegmentWriter *pWriter = 0; /* Used to write the new, merged, segment */ |
| 138005 | 138662 | Fts3SegFilter filter; /* Segment term filter condition */ |
| 138006 | 138663 | Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */ |
| 138007 | 138664 | int bIgnoreEmpty = 0; /* True to ignore empty segments */ |
| 138665 | + i64 iMaxLevel = 0; /* Max level number for this index/langid */ | |
| 138008 | 138666 | |
| 138009 | 138667 | assert( iLevel==FTS3_SEGCURSOR_ALL |
| 138010 | 138668 | || iLevel==FTS3_SEGCURSOR_PENDING |
| 138011 | 138669 | || iLevel>=0 |
| 138012 | 138670 | ); |
| @@ -138013,10 +138671,15 @@ | ||
| 138013 | 138671 | assert( iLevel<FTS3_SEGDIR_MAXLEVEL ); |
| 138014 | 138672 | assert( iIndex>=0 && iIndex<p->nIndex ); |
| 138015 | 138673 | |
| 138016 | 138674 | rc = sqlite3Fts3SegReaderCursor(p, iLangid, iIndex, iLevel, 0, 0, 1, 0, &csr); |
| 138017 | 138675 | if( rc!=SQLITE_OK || csr.nSegment==0 ) goto finished; |
| 138676 | + | |
| 138677 | + if( iLevel!=FTS3_SEGCURSOR_PENDING ){ | |
| 138678 | + rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iMaxLevel); | |
| 138679 | + if( rc!=SQLITE_OK ) goto finished; | |
| 138680 | + } | |
| 138018 | 138681 | |
| 138019 | 138682 | if( iLevel==FTS3_SEGCURSOR_ALL ){ |
| 138020 | 138683 | /* This call is to merge all segments in the database to a single |
| 138021 | 138684 | ** segment. The level of the new segment is equal to the numerically |
| 138022 | 138685 | ** greatest segment level currently present in the database for this |
| @@ -138023,25 +138686,25 @@ | ||
| 138023 | 138686 | ** index. The idx of the new segment is always 0. */ |
| 138024 | 138687 | if( csr.nSegment==1 ){ |
| 138025 | 138688 | rc = SQLITE_DONE; |
| 138026 | 138689 | goto finished; |
| 138027 | 138690 | } |
| 138028 | - rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iNewLevel); | |
| 138691 | + iNewLevel = iMaxLevel; | |
| 138029 | 138692 | bIgnoreEmpty = 1; |
| 138030 | 138693 | |
| 138031 | - }else if( iLevel==FTS3_SEGCURSOR_PENDING ){ | |
| 138032 | - iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, 0); | |
| 138033 | - rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, 0, &iIdx); | |
| 138034 | 138694 | }else{ |
| 138035 | 138695 | /* This call is to merge all segments at level iLevel. find the next |
| 138036 | 138696 | ** available segment index at level iLevel+1. The call to |
| 138037 | 138697 | ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to |
| 138038 | 138698 | ** a single iLevel+2 segment if necessary. */ |
| 138039 | - rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, iLevel+1, &iIdx); | |
| 138699 | + assert( FTS3_SEGCURSOR_PENDING==-1 ); | |
| 138040 | 138700 | iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, iLevel+1); |
| 138701 | + rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, iLevel+1, &iIdx); | |
| 138702 | + bIgnoreEmpty = (iLevel!=FTS3_SEGCURSOR_PENDING) && (iNewLevel>iMaxLevel); | |
| 138041 | 138703 | } |
| 138042 | 138704 | if( rc!=SQLITE_OK ) goto finished; |
| 138705 | + | |
| 138043 | 138706 | assert( csr.nSegment>0 ); |
| 138044 | 138707 | assert( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) ); |
| 138045 | 138708 | assert( iNewLevel<getAbsoluteLevel(p, iLangid, iIndex,FTS3_SEGDIR_MAXLEVEL) ); |
| 138046 | 138709 | |
| 138047 | 138710 | memset(&filter, 0, sizeof(Fts3SegFilter)); |
| @@ -138054,29 +138717,36 @@ | ||
| 138054 | 138717 | if( rc!=SQLITE_ROW ) break; |
| 138055 | 138718 | rc = fts3SegWriterAdd(p, &pWriter, 1, |
| 138056 | 138719 | csr.zTerm, csr.nTerm, csr.aDoclist, csr.nDoclist); |
| 138057 | 138720 | } |
| 138058 | 138721 | if( rc!=SQLITE_OK ) goto finished; |
| 138059 | - assert( pWriter ); | |
| 138722 | + assert( pWriter || bIgnoreEmpty ); | |
| 138060 | 138723 | |
| 138061 | 138724 | if( iLevel!=FTS3_SEGCURSOR_PENDING ){ |
| 138062 | 138725 | rc = fts3DeleteSegdir( |
| 138063 | 138726 | p, iLangid, iIndex, iLevel, csr.apSegment, csr.nSegment |
| 138064 | 138727 | ); |
| 138065 | 138728 | if( rc!=SQLITE_OK ) goto finished; |
| 138066 | 138729 | } |
| 138067 | - rc = fts3SegWriterFlush(p, pWriter, iNewLevel, iIdx); | |
| 138730 | + if( pWriter ){ | |
| 138731 | + rc = fts3SegWriterFlush(p, pWriter, iNewLevel, iIdx); | |
| 138732 | + if( rc==SQLITE_OK ){ | |
| 138733 | + if( iLevel==FTS3_SEGCURSOR_PENDING || iNewLevel<iMaxLevel ){ | |
| 138734 | + rc = fts3PromoteSegments(p, iNewLevel, pWriter->nLeafData); | |
| 138735 | + } | |
| 138736 | + } | |
| 138737 | + } | |
| 138068 | 138738 | |
| 138069 | 138739 | finished: |
| 138070 | 138740 | fts3SegWriterFree(pWriter); |
| 138071 | 138741 | sqlite3Fts3SegReaderFinish(&csr); |
| 138072 | 138742 | return rc; |
| 138073 | 138743 | } |
| 138074 | 138744 | |
| 138075 | 138745 | |
| 138076 | 138746 | /* |
| 138077 | -** Flush the contents of pendingTerms to level 0 segments. | |
| 138747 | +** Flush the contents of pendingTerms to level 0 segments. | |
| 138078 | 138748 | */ |
| 138079 | 138749 | SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ |
| 138080 | 138750 | int rc = SQLITE_OK; |
| 138081 | 138751 | int i; |
| 138082 | 138752 | |
| @@ -138088,18 +138758,23 @@ | ||
| 138088 | 138758 | |
| 138089 | 138759 | /* Determine the auto-incr-merge setting if unknown. If enabled, |
| 138090 | 138760 | ** estimate the number of leaf blocks of content to be written |
| 138091 | 138761 | */ |
| 138092 | 138762 | if( rc==SQLITE_OK && p->bHasStat |
| 138093 | - && p->bAutoincrmerge==0xff && p->nLeafAdd>0 | |
| 138763 | + && p->nAutoincrmerge==0xff && p->nLeafAdd>0 | |
| 138094 | 138764 | ){ |
| 138095 | 138765 | sqlite3_stmt *pStmt = 0; |
| 138096 | 138766 | rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); |
| 138097 | 138767 | if( rc==SQLITE_OK ){ |
| 138098 | 138768 | sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); |
| 138099 | 138769 | rc = sqlite3_step(pStmt); |
| 138100 | - p->bAutoincrmerge = (rc==SQLITE_ROW && sqlite3_column_int(pStmt, 0)); | |
| 138770 | + if( rc==SQLITE_ROW ){ | |
| 138771 | + p->nAutoincrmerge = sqlite3_column_int(pStmt, 0); | |
| 138772 | + if( p->nAutoincrmerge==1 ) p->nAutoincrmerge = 8; | |
| 138773 | + }else if( rc==SQLITE_DONE ){ | |
| 138774 | + p->nAutoincrmerge = 0; | |
| 138775 | + } | |
| 138101 | 138776 | rc = sqlite3_reset(pStmt); |
| 138102 | 138777 | } |
| 138103 | 138778 | } |
| 138104 | 138779 | return rc; |
| 138105 | 138780 | } |
| @@ -138463,10 +139138,12 @@ | ||
| 138463 | 139138 | int nWork; /* Number of leaf pages flushed */ |
| 138464 | 139139 | sqlite3_int64 iAbsLevel; /* Absolute level of input segments */ |
| 138465 | 139140 | int iIdx; /* Index of *output* segment in iAbsLevel+1 */ |
| 138466 | 139141 | sqlite3_int64 iStart; /* Block number of first allocated block */ |
| 138467 | 139142 | sqlite3_int64 iEnd; /* Block number of last allocated block */ |
| 139143 | + sqlite3_int64 nLeafData; /* Bytes of leaf page data so far */ | |
| 139144 | + u8 bNoLeafData; /* If true, store 0 for segment size */ | |
| 138468 | 139145 | NodeWriter aNodeWriter[FTS_MAX_APPENDABLE_HEIGHT]; |
| 138469 | 139146 | }; |
| 138470 | 139147 | |
| 138471 | 139148 | /* |
| 138472 | 139149 | ** An object of the following type is used to read data from a single |
| @@ -138801,12 +139478,12 @@ | ||
| 138801 | 139478 | nSpace = 1; |
| 138802 | 139479 | nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; |
| 138803 | 139480 | nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; |
| 138804 | 139481 | } |
| 138805 | 139482 | |
| 139483 | + pWriter->nLeafData += nSpace; | |
| 138806 | 139484 | blobGrowBuffer(&pLeaf->block, pLeaf->block.n + nSpace, &rc); |
| 138807 | - | |
| 138808 | 139485 | if( rc==SQLITE_OK ){ |
| 138809 | 139486 | if( pLeaf->block.n==0 ){ |
| 138810 | 139487 | pLeaf->block.n = 1; |
| 138811 | 139488 | pLeaf->block.a[0] = '\0'; |
| 138812 | 139489 | } |
| @@ -138901,10 +139578,11 @@ | ||
| 138901 | 139578 | pWriter->iAbsLevel+1, /* level */ |
| 138902 | 139579 | pWriter->iIdx, /* idx */ |
| 138903 | 139580 | pWriter->iStart, /* start_block */ |
| 138904 | 139581 | pWriter->aNodeWriter[0].iBlock, /* leaves_end_block */ |
| 138905 | 139582 | pWriter->iEnd, /* end_block */ |
| 139583 | + (pWriter->bNoLeafData==0 ? pWriter->nLeafData : 0), /* end_block */ | |
| 138906 | 139584 | pRoot->block.a, pRoot->block.n /* root */ |
| 138907 | 139585 | ); |
| 138908 | 139586 | } |
| 138909 | 139587 | sqlite3_free(pRoot->block.a); |
| 138910 | 139588 | sqlite3_free(pRoot->key.a); |
| @@ -139002,11 +139680,15 @@ | ||
| 139002 | 139680 | sqlite3_bind_int64(pSelect, 1, iAbsLevel+1); |
| 139003 | 139681 | sqlite3_bind_int(pSelect, 2, iIdx); |
| 139004 | 139682 | if( sqlite3_step(pSelect)==SQLITE_ROW ){ |
| 139005 | 139683 | iStart = sqlite3_column_int64(pSelect, 1); |
| 139006 | 139684 | iLeafEnd = sqlite3_column_int64(pSelect, 2); |
| 139007 | - iEnd = sqlite3_column_int64(pSelect, 3); | |
| 139685 | + fts3ReadEndBlockField(pSelect, 3, &iEnd, &pWriter->nLeafData); | |
| 139686 | + if( pWriter->nLeafData<0 ){ | |
| 139687 | + pWriter->nLeafData = pWriter->nLeafData * -1; | |
| 139688 | + } | |
| 139689 | + pWriter->bNoLeafData = (pWriter->nLeafData==0); | |
| 139008 | 139690 | nRoot = sqlite3_column_bytes(pSelect, 4); |
| 139009 | 139691 | aRoot = sqlite3_column_blob(pSelect, 4); |
| 139010 | 139692 | }else{ |
| 139011 | 139693 | return sqlite3_reset(pSelect); |
| 139012 | 139694 | } |
| @@ -139603,15 +140285,15 @@ | ||
| 139603 | 140285 | |
| 139604 | 140286 | |
| 139605 | 140287 | /* |
| 139606 | 140288 | ** Attempt an incremental merge that writes nMerge leaf blocks. |
| 139607 | 140289 | ** |
| 139608 | -** Incremental merges happen nMin segments at a time. The two | |
| 139609 | -** segments to be merged are the nMin oldest segments (the ones with | |
| 139610 | -** the smallest indexes) in the highest level that contains at least | |
| 139611 | -** nMin segments. Multiple merges might occur in an attempt to write the | |
| 139612 | -** quota of nMerge leaf blocks. | |
| 140290 | +** Incremental merges happen nMin segments at a time. The segments | |
| 140291 | +** to be merged are the nMin oldest segments (the ones with the smallest | |
| 140292 | +** values for the _segdir.idx field) in the highest level that contains | |
| 140293 | +** at least nMin segments. Multiple merges might occur in an attempt to | |
| 140294 | +** write the quota of nMerge leaf blocks. | |
| 139613 | 140295 | */ |
| 139614 | 140296 | SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ |
| 139615 | 140297 | int rc; /* Return code */ |
| 139616 | 140298 | int nRem = nMerge; /* Number of leaf pages yet to be written */ |
| 139617 | 140299 | Fts3MultiSegReader *pCsr; /* Cursor used to read input data */ |
| @@ -139632,10 +140314,11 @@ | ||
| 139632 | 140314 | rc = fts3IncrmergeHintLoad(p, &hint); |
| 139633 | 140315 | while( rc==SQLITE_OK && nRem>0 ){ |
| 139634 | 140316 | const i64 nMod = FTS3_SEGDIR_MAXLEVEL * p->nIndex; |
| 139635 | 140317 | sqlite3_stmt *pFindLevel = 0; /* SQL used to determine iAbsLevel */ |
| 139636 | 140318 | int bUseHint = 0; /* True if attempting to append */ |
| 140319 | + int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */ | |
| 139637 | 140320 | |
| 139638 | 140321 | /* Search the %_segdir table for the absolute level with the smallest |
| 139639 | 140322 | ** relative level number that contains at least nMin segments, if any. |
| 139640 | 140323 | ** If one is found, set iAbsLevel to the absolute level number and |
| 139641 | 140324 | ** nSeg to nMin. If no level with at least nMin segments can be found, |
| @@ -139685,27 +140368,36 @@ | ||
| 139685 | 140368 | ** segments available in level iAbsLevel. In this case, no work is |
| 139686 | 140369 | ** done on iAbsLevel - fall through to the next iteration of the loop |
| 139687 | 140370 | ** to start work on some other level. */ |
| 139688 | 140371 | memset(pWriter, 0, nAlloc); |
| 139689 | 140372 | pFilter->flags = FTS3_SEGMENT_REQUIRE_POS; |
| 140373 | + | |
| 140374 | + if( rc==SQLITE_OK ){ | |
| 140375 | + rc = fts3IncrmergeOutputIdx(p, iAbsLevel, &iIdx); | |
| 140376 | + assert( bUseHint==1 || bUseHint==0 ); | |
| 140377 | + if( iIdx==0 || (bUseHint && iIdx==1) ){ | |
| 140378 | + int bIgnore; | |
| 140379 | + rc = fts3SegmentIsMaxLevel(p, iAbsLevel+1, &bIgnore); | |
| 140380 | + if( bIgnore ){ | |
| 140381 | + pFilter->flags |= FTS3_SEGMENT_IGNORE_EMPTY; | |
| 140382 | + } | |
| 140383 | + } | |
| 140384 | + } | |
| 140385 | + | |
| 139690 | 140386 | if( rc==SQLITE_OK ){ |
| 139691 | 140387 | rc = fts3IncrmergeCsr(p, iAbsLevel, nSeg, pCsr); |
| 139692 | 140388 | } |
| 139693 | 140389 | if( SQLITE_OK==rc && pCsr->nSegment==nSeg |
| 139694 | 140390 | && SQLITE_OK==(rc = sqlite3Fts3SegReaderStart(p, pCsr, pFilter)) |
| 139695 | 140391 | && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pCsr)) |
| 139696 | 140392 | ){ |
| 139697 | - int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */ | |
| 139698 | - rc = fts3IncrmergeOutputIdx(p, iAbsLevel, &iIdx); | |
| 139699 | - if( rc==SQLITE_OK ){ | |
| 139700 | - if( bUseHint && iIdx>0 ){ | |
| 139701 | - const char *zKey = pCsr->zTerm; | |
| 139702 | - int nKey = pCsr->nTerm; | |
| 139703 | - rc = fts3IncrmergeLoad(p, iAbsLevel, iIdx-1, zKey, nKey, pWriter); | |
| 139704 | - }else{ | |
| 139705 | - rc = fts3IncrmergeWriter(p, iAbsLevel, iIdx, pCsr, pWriter); | |
| 139706 | - } | |
| 140393 | + if( bUseHint && iIdx>0 ){ | |
| 140394 | + const char *zKey = pCsr->zTerm; | |
| 140395 | + int nKey = pCsr->nTerm; | |
| 140396 | + rc = fts3IncrmergeLoad(p, iAbsLevel, iIdx-1, zKey, nKey, pWriter); | |
| 140397 | + }else{ | |
| 140398 | + rc = fts3IncrmergeWriter(p, iAbsLevel, iIdx, pCsr, pWriter); | |
| 139707 | 140399 | } |
| 139708 | 140400 | |
| 139709 | 140401 | if( rc==SQLITE_OK && pWriter->nLeafEst ){ |
| 139710 | 140402 | fts3LogMerge(nSeg, iAbsLevel); |
| 139711 | 140403 | do { |
| @@ -139723,11 +140415,17 @@ | ||
| 139723 | 140415 | fts3IncrmergeHintPush(&hint, iAbsLevel, nSeg, &rc); |
| 139724 | 140416 | } |
| 139725 | 140417 | } |
| 139726 | 140418 | } |
| 139727 | 140419 | |
| 140420 | + if( nSeg!=0 ){ | |
| 140421 | + pWriter->nLeafData = pWriter->nLeafData * -1; | |
| 140422 | + } | |
| 139728 | 140423 | fts3IncrmergeRelease(p, pWriter, &rc); |
| 140424 | + if( nSeg==0 && pWriter->bNoLeafData==0 ){ | |
| 140425 | + fts3PromoteSegments(p, iAbsLevel+1, pWriter->nLeafData); | |
| 140426 | + } | |
| 139729 | 140427 | } |
| 139730 | 140428 | |
| 139731 | 140429 | sqlite3Fts3SegReaderFinish(pCsr); |
| 139732 | 140430 | } |
| 139733 | 140431 | |
| @@ -139810,20 +140508,23 @@ | ||
| 139810 | 140508 | Fts3Table *p, /* FTS3 table handle */ |
| 139811 | 140509 | const char *zParam /* Nul-terminated string containing boolean */ |
| 139812 | 140510 | ){ |
| 139813 | 140511 | int rc = SQLITE_OK; |
| 139814 | 140512 | sqlite3_stmt *pStmt = 0; |
| 139815 | - p->bAutoincrmerge = fts3Getint(&zParam)!=0; | |
| 140513 | + p->nAutoincrmerge = fts3Getint(&zParam); | |
| 140514 | + if( p->nAutoincrmerge==1 || p->nAutoincrmerge>FTS3_MERGE_COUNT ){ | |
| 140515 | + p->nAutoincrmerge = 8; | |
| 140516 | + } | |
| 139816 | 140517 | if( !p->bHasStat ){ |
| 139817 | 140518 | assert( p->bFts4==0 ); |
| 139818 | 140519 | sqlite3Fts3CreateStatTable(&rc, p); |
| 139819 | 140520 | if( rc ) return rc; |
| 139820 | 140521 | } |
| 139821 | 140522 | rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); |
| 139822 | 140523 | if( rc ) return rc; |
| 139823 | 140524 | sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); |
| 139824 | - sqlite3_bind_int(pStmt, 2, p->bAutoincrmerge); | |
| 140525 | + sqlite3_bind_int(pStmt, 2, p->nAutoincrmerge); | |
| 139825 | 140526 | sqlite3_step(pStmt); |
| 139826 | 140527 | rc = sqlite3_reset(pStmt); |
| 139827 | 140528 | return rc; |
| 139828 | 140529 | } |
| 139829 | 140530 | |
| @@ -142802,64 +143503,24 @@ | ||
| 142802 | 143503 | ** child page. |
| 142803 | 143504 | */ |
| 142804 | 143505 | |
| 142805 | 143506 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) |
| 142806 | 143507 | |
| 142807 | -/* | |
| 142808 | -** This file contains an implementation of a couple of different variants | |
| 142809 | -** of the r-tree algorithm. See the README file for further details. The | |
| 142810 | -** same data-structure is used for all, but the algorithms for insert and | |
| 142811 | -** delete operations vary. The variants used are selected at compile time | |
| 142812 | -** by defining the following symbols: | |
| 142813 | -*/ | |
| 142814 | - | |
| 142815 | -/* Either, both or none of the following may be set to activate | |
| 142816 | -** r*tree variant algorithms. | |
| 142817 | -*/ | |
| 142818 | -#define VARIANT_RSTARTREE_CHOOSESUBTREE 0 | |
| 142819 | -#define VARIANT_RSTARTREE_REINSERT 1 | |
| 142820 | - | |
| 142821 | -/* | |
| 142822 | -** Exactly one of the following must be set to 1. | |
| 142823 | -*/ | |
| 142824 | -#define VARIANT_GUTTMAN_QUADRATIC_SPLIT 0 | |
| 142825 | -#define VARIANT_GUTTMAN_LINEAR_SPLIT 0 | |
| 142826 | -#define VARIANT_RSTARTREE_SPLIT 1 | |
| 142827 | - | |
| 142828 | -#define VARIANT_GUTTMAN_SPLIT \ | |
| 142829 | - (VARIANT_GUTTMAN_LINEAR_SPLIT||VARIANT_GUTTMAN_QUADRATIC_SPLIT) | |
| 142830 | - | |
| 142831 | -#if VARIANT_GUTTMAN_QUADRATIC_SPLIT | |
| 142832 | - #define PickNext QuadraticPickNext | |
| 142833 | - #define PickSeeds QuadraticPickSeeds | |
| 142834 | - #define AssignCells splitNodeGuttman | |
| 142835 | -#endif | |
| 142836 | -#if VARIANT_GUTTMAN_LINEAR_SPLIT | |
| 142837 | - #define PickNext LinearPickNext | |
| 142838 | - #define PickSeeds LinearPickSeeds | |
| 142839 | - #define AssignCells splitNodeGuttman | |
| 142840 | -#endif | |
| 142841 | -#if VARIANT_RSTARTREE_SPLIT | |
| 142842 | - #define AssignCells splitNodeStartree | |
| 142843 | -#endif | |
| 142844 | - | |
| 142845 | -#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) | |
| 142846 | -# define NDEBUG 1 | |
| 142847 | -#endif | |
| 142848 | - | |
| 142849 | 143508 | #ifndef SQLITE_CORE |
| 142850 | 143509 | SQLITE_EXTENSION_INIT1 |
| 142851 | 143510 | #else |
| 142852 | 143511 | #endif |
| 142853 | 143512 | |
| 142854 | 143513 | /* #include <string.h> */ |
| 142855 | 143514 | /* #include <assert.h> */ |
| 143515 | +/* #include <stdio.h> */ | |
| 142856 | 143516 | |
| 142857 | 143517 | #ifndef SQLITE_AMALGAMATION |
| 142858 | 143518 | #include "sqlite3rtree.h" |
| 142859 | 143519 | typedef sqlite3_int64 i64; |
| 142860 | 143520 | typedef unsigned char u8; |
| 143521 | +typedef unsigned short u16; | |
| 142861 | 143522 | typedef unsigned int u32; |
| 142862 | 143523 | #endif |
| 142863 | 143524 | |
| 142864 | 143525 | /* The following macro is used to suppress compiler warnings. |
| 142865 | 143526 | */ |
| @@ -142873,19 +143534,20 @@ | ||
| 142873 | 143534 | typedef struct RtreeCell RtreeCell; |
| 142874 | 143535 | typedef struct RtreeConstraint RtreeConstraint; |
| 142875 | 143536 | typedef struct RtreeMatchArg RtreeMatchArg; |
| 142876 | 143537 | typedef struct RtreeGeomCallback RtreeGeomCallback; |
| 142877 | 143538 | typedef union RtreeCoord RtreeCoord; |
| 143539 | +typedef struct RtreeSearchPoint RtreeSearchPoint; | |
| 142878 | 143540 | |
| 142879 | 143541 | /* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */ |
| 142880 | 143542 | #define RTREE_MAX_DIMENSIONS 5 |
| 142881 | 143543 | |
| 142882 | 143544 | /* Size of hash table Rtree.aHash. This hash table is not expected to |
| 142883 | 143545 | ** ever contain very many entries, so a fixed number of buckets is |
| 142884 | 143546 | ** used. |
| 142885 | 143547 | */ |
| 142886 | -#define HASHSIZE 128 | |
| 143548 | +#define HASHSIZE 97 | |
| 142887 | 143549 | |
| 142888 | 143550 | /* The xBestIndex method of this virtual table requires an estimate of |
| 142889 | 143551 | ** the number of rows in the virtual table to calculate the costs of |
| 142890 | 143552 | ** various strategies. If possible, this estimate is loaded from the |
| 142891 | 143553 | ** sqlite_stat1 table (with RTREE_MIN_ROWEST as a hard-coded minimum). |
| @@ -142897,19 +143559,19 @@ | ||
| 142897 | 143559 | |
| 142898 | 143560 | /* |
| 142899 | 143561 | ** An rtree virtual-table object. |
| 142900 | 143562 | */ |
| 142901 | 143563 | struct Rtree { |
| 142902 | - sqlite3_vtab base; | |
| 143564 | + sqlite3_vtab base; /* Base class. Must be first */ | |
| 142903 | 143565 | sqlite3 *db; /* Host database connection */ |
| 142904 | 143566 | int iNodeSize; /* Size in bytes of each node in the node table */ |
| 142905 | - int nDim; /* Number of dimensions */ | |
| 142906 | - int nBytesPerCell; /* Bytes consumed per cell */ | |
| 143567 | + u8 nDim; /* Number of dimensions */ | |
| 143568 | + u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ | |
| 143569 | + u8 nBytesPerCell; /* Bytes consumed per cell */ | |
| 142907 | 143570 | int iDepth; /* Current depth of the r-tree structure */ |
| 142908 | 143571 | char *zDb; /* Name of database containing r-tree table */ |
| 142909 | 143572 | char *zName; /* Name of r-tree table */ |
| 142910 | - RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ | |
| 142911 | 143573 | int nBusy; /* Current number of users of this structure */ |
| 142912 | 143574 | i64 nRowEst; /* Estimated number of rows in this table */ |
| 142913 | 143575 | |
| 142914 | 143576 | /* List of nodes removed during a CondenseTree operation. List is |
| 142915 | 143577 | ** linked together via the pointer normally used for hash chains - |
| @@ -142932,14 +143594,14 @@ | ||
| 142932 | 143594 | /* Statements to read/write/delete a record from xxx_parent */ |
| 142933 | 143595 | sqlite3_stmt *pReadParent; |
| 142934 | 143596 | sqlite3_stmt *pWriteParent; |
| 142935 | 143597 | sqlite3_stmt *pDeleteParent; |
| 142936 | 143598 | |
| 142937 | - int eCoordType; | |
| 143599 | + RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ | |
| 142938 | 143600 | }; |
| 142939 | 143601 | |
| 142940 | -/* Possible values for eCoordType: */ | |
| 143602 | +/* Possible values for Rtree.eCoordType: */ | |
| 142941 | 143603 | #define RTREE_COORD_REAL32 0 |
| 142942 | 143604 | #define RTREE_COORD_INT32 1 |
| 142943 | 143605 | |
| 142944 | 143606 | /* |
| 142945 | 143607 | ** If SQLITE_RTREE_INT_ONLY is defined, then this virtual table will |
| @@ -142947,14 +143609,33 @@ | ||
| 142947 | 143609 | ** will be done. |
| 142948 | 143610 | */ |
| 142949 | 143611 | #ifdef SQLITE_RTREE_INT_ONLY |
| 142950 | 143612 | typedef sqlite3_int64 RtreeDValue; /* High accuracy coordinate */ |
| 142951 | 143613 | typedef int RtreeValue; /* Low accuracy coordinate */ |
| 143614 | +# define RTREE_ZERO 0 | |
| 142952 | 143615 | #else |
| 142953 | 143616 | typedef double RtreeDValue; /* High accuracy coordinate */ |
| 142954 | 143617 | typedef float RtreeValue; /* Low accuracy coordinate */ |
| 143618 | +# define RTREE_ZERO 0.0 | |
| 142955 | 143619 | #endif |
| 143620 | + | |
| 143621 | +/* | |
| 143622 | +** When doing a search of an r-tree, instances of the following structure | |
| 143623 | +** record intermediate results from the tree walk. | |
| 143624 | +** | |
| 143625 | +** The id is always a node-id. For iLevel>=1 the id is the node-id of | |
| 143626 | +** the node that the RtreeSearchPoint represents. When iLevel==0, however, | |
| 143627 | +** the id is of the parent node and the cell that RtreeSearchPoint | |
| 143628 | +** represents is the iCell-th entry in the parent node. | |
| 143629 | +*/ | |
| 143630 | +struct RtreeSearchPoint { | |
| 143631 | + RtreeDValue rScore; /* The score for this node. Smallest goes first. */ | |
| 143632 | + sqlite3_int64 id; /* Node ID */ | |
| 143633 | + u8 iLevel; /* 0=entries. 1=leaf node. 2+ for higher */ | |
| 143634 | + u8 eWithin; /* PARTLY_WITHIN or FULLY_WITHIN */ | |
| 143635 | + u8 iCell; /* Cell index within the node */ | |
| 143636 | +}; | |
| 142956 | 143637 | |
| 142957 | 143638 | /* |
| 142958 | 143639 | ** The minimum number of cells allowed for a node is a third of the |
| 142959 | 143640 | ** maximum. In Gutman's notation: |
| 142960 | 143641 | ** |
| @@ -142974,25 +143655,48 @@ | ||
| 142974 | 143655 | ** 2^40 is greater than 2^64, an r-tree structure always has a depth of |
| 142975 | 143656 | ** 40 or less. |
| 142976 | 143657 | */ |
| 142977 | 143658 | #define RTREE_MAX_DEPTH 40 |
| 142978 | 143659 | |
| 143660 | + | |
| 143661 | +/* | |
| 143662 | +** Number of entries in the cursor RtreeNode cache. The first entry is | |
| 143663 | +** used to cache the RtreeNode for RtreeCursor.sPoint. The remaining | |
| 143664 | +** entries cache the RtreeNode for the first elements of the priority queue. | |
| 143665 | +*/ | |
| 143666 | +#define RTREE_CACHE_SZ 5 | |
| 143667 | + | |
| 142979 | 143668 | /* |
| 142980 | 143669 | ** An rtree cursor object. |
| 142981 | 143670 | */ |
| 142982 | 143671 | struct RtreeCursor { |
| 142983 | - sqlite3_vtab_cursor base; | |
| 142984 | - RtreeNode *pNode; /* Node cursor is currently pointing at */ | |
| 142985 | - int iCell; /* Index of current cell in pNode */ | |
| 143672 | + sqlite3_vtab_cursor base; /* Base class. Must be first */ | |
| 143673 | + u8 atEOF; /* True if at end of search */ | |
| 143674 | + u8 bPoint; /* True if sPoint is valid */ | |
| 142986 | 143675 | int iStrategy; /* Copy of idxNum search parameter */ |
| 142987 | 143676 | int nConstraint; /* Number of entries in aConstraint */ |
| 142988 | 143677 | RtreeConstraint *aConstraint; /* Search constraints. */ |
| 143678 | + int nPointAlloc; /* Number of slots allocated for aPoint[] */ | |
| 143679 | + int nPoint; /* Number of slots used in aPoint[] */ | |
| 143680 | + int mxLevel; /* iLevel value for root of the tree */ | |
| 143681 | + RtreeSearchPoint *aPoint; /* Priority queue for search points */ | |
| 143682 | + RtreeSearchPoint sPoint; /* Cached next search point */ | |
| 143683 | + RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */ | |
| 143684 | + u32 anQueue[RTREE_MAX_DEPTH+1]; /* Number of queued entries by iLevel */ | |
| 142989 | 143685 | }; |
| 142990 | 143686 | |
| 143687 | +/* Return the Rtree of a RtreeCursor */ | |
| 143688 | +#define RTREE_OF_CURSOR(X) ((Rtree*)((X)->base.pVtab)) | |
| 143689 | + | |
| 143690 | +/* | |
| 143691 | +** A coordinate can be either a floating point number or a integer. All | |
| 143692 | +** coordinates within a single R-Tree are always of the same time. | |
| 143693 | +*/ | |
| 142991 | 143694 | union RtreeCoord { |
| 142992 | - RtreeValue f; | |
| 142993 | - int i; | |
| 143695 | + RtreeValue f; /* Floating point value */ | |
| 143696 | + int i; /* Integer value */ | |
| 143697 | + u32 u; /* Unsigned for byte-order conversions */ | |
| 142994 | 143698 | }; |
| 142995 | 143699 | |
| 142996 | 143700 | /* |
| 142997 | 143701 | ** The argument is an RtreeCoord. Return the value stored within the RtreeCoord |
| 142998 | 143702 | ** formatted as a RtreeDValue (double or int64). This macro assumes that local |
| @@ -143013,42 +143717,71 @@ | ||
| 143013 | 143717 | ** A search constraint. |
| 143014 | 143718 | */ |
| 143015 | 143719 | struct RtreeConstraint { |
| 143016 | 143720 | int iCoord; /* Index of constrained coordinate */ |
| 143017 | 143721 | int op; /* Constraining operation */ |
| 143018 | - RtreeDValue rValue; /* Constraint value. */ | |
| 143019 | - int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); | |
| 143020 | - sqlite3_rtree_geometry *pGeom; /* Constraint callback argument for a MATCH */ | |
| 143722 | + union { | |
| 143723 | + RtreeDValue rValue; /* Constraint value. */ | |
| 143724 | + int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*); | |
| 143725 | + int (*xQueryFunc)(sqlite3_rtree_query_info*); | |
| 143726 | + } u; | |
| 143727 | + sqlite3_rtree_query_info *pInfo; /* xGeom and xQueryFunc argument */ | |
| 143021 | 143728 | }; |
| 143022 | 143729 | |
| 143023 | 143730 | /* Possible values for RtreeConstraint.op */ |
| 143024 | -#define RTREE_EQ 0x41 | |
| 143025 | -#define RTREE_LE 0x42 | |
| 143026 | -#define RTREE_LT 0x43 | |
| 143027 | -#define RTREE_GE 0x44 | |
| 143028 | -#define RTREE_GT 0x45 | |
| 143029 | -#define RTREE_MATCH 0x46 | |
| 143731 | +#define RTREE_EQ 0x41 /* A */ | |
| 143732 | +#define RTREE_LE 0x42 /* B */ | |
| 143733 | +#define RTREE_LT 0x43 /* C */ | |
| 143734 | +#define RTREE_GE 0x44 /* D */ | |
| 143735 | +#define RTREE_GT 0x45 /* E */ | |
| 143736 | +#define RTREE_MATCH 0x46 /* F: Old-style sqlite3_rtree_geometry_callback() */ | |
| 143737 | +#define RTREE_QUERY 0x47 /* G: New-style sqlite3_rtree_query_callback() */ | |
| 143738 | + | |
| 143030 | 143739 | |
| 143031 | 143740 | /* |
| 143032 | 143741 | ** An rtree structure node. |
| 143033 | 143742 | */ |
| 143034 | 143743 | struct RtreeNode { |
| 143035 | - RtreeNode *pParent; /* Parent node */ | |
| 143036 | - i64 iNode; | |
| 143037 | - int nRef; | |
| 143038 | - int isDirty; | |
| 143039 | - u8 *zData; | |
| 143040 | - RtreeNode *pNext; /* Next node in this hash chain */ | |
| 143744 | + RtreeNode *pParent; /* Parent node */ | |
| 143745 | + i64 iNode; /* The node number */ | |
| 143746 | + int nRef; /* Number of references to this node */ | |
| 143747 | + int isDirty; /* True if the node needs to be written to disk */ | |
| 143748 | + u8 *zData; /* Content of the node, as should be on disk */ | |
| 143749 | + RtreeNode *pNext; /* Next node in this hash collision chain */ | |
| 143041 | 143750 | }; |
| 143751 | + | |
| 143752 | +/* Return the number of cells in a node */ | |
| 143042 | 143753 | #define NCELL(pNode) readInt16(&(pNode)->zData[2]) |
| 143043 | 143754 | |
| 143044 | 143755 | /* |
| 143045 | -** Structure to store a deserialized rtree record. | |
| 143756 | +** A single cell from a node, deserialized | |
| 143046 | 143757 | */ |
| 143047 | 143758 | struct RtreeCell { |
| 143048 | - i64 iRowid; | |
| 143049 | - RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; | |
| 143759 | + i64 iRowid; /* Node or entry ID */ | |
| 143760 | + RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; /* Bounding box coordinates */ | |
| 143761 | +}; | |
| 143762 | + | |
| 143763 | + | |
| 143764 | +/* | |
| 143765 | +** This object becomes the sqlite3_user_data() for the SQL functions | |
| 143766 | +** that are created by sqlite3_rtree_geometry_callback() and | |
| 143767 | +** sqlite3_rtree_query_callback() and which appear on the right of MATCH | |
| 143768 | +** operators in order to constrain a search. | |
| 143769 | +** | |
| 143770 | +** xGeom and xQueryFunc are the callback functions. Exactly one of | |
| 143771 | +** xGeom and xQueryFunc fields is non-NULL, depending on whether the | |
| 143772 | +** SQL function was created using sqlite3_rtree_geometry_callback() or | |
| 143773 | +** sqlite3_rtree_query_callback(). | |
| 143774 | +** | |
| 143775 | +** This object is deleted automatically by the destructor mechanism in | |
| 143776 | +** sqlite3_create_function_v2(). | |
| 143777 | +*/ | |
| 143778 | +struct RtreeGeomCallback { | |
| 143779 | + int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); | |
| 143780 | + int (*xQueryFunc)(sqlite3_rtree_query_info*); | |
| 143781 | + void (*xDestructor)(void*); | |
| 143782 | + void *pContext; | |
| 143050 | 143783 | }; |
| 143051 | 143784 | |
| 143052 | 143785 | |
| 143053 | 143786 | /* |
| 143054 | 143787 | ** Value for the first field of every RtreeMatchArg object. The MATCH |
| @@ -143056,33 +143789,20 @@ | ||
| 143056 | 143789 | ** value to avoid operating on invalid blobs (which could cause a segfault). |
| 143057 | 143790 | */ |
| 143058 | 143791 | #define RTREE_GEOMETRY_MAGIC 0x891245AB |
| 143059 | 143792 | |
| 143060 | 143793 | /* |
| 143061 | -** An instance of this structure must be supplied as a blob argument to | |
| 143062 | -** the right-hand-side of an SQL MATCH operator used to constrain an | |
| 143063 | -** r-tree query. | |
| 143794 | +** An instance of this structure (in the form of a BLOB) is returned by | |
| 143795 | +** the SQL functions that sqlite3_rtree_geometry_callback() and | |
| 143796 | +** sqlite3_rtree_query_callback() create, and is read as the right-hand | |
| 143797 | +** operand to the MATCH operator of an R-Tree. | |
| 143064 | 143798 | */ |
| 143065 | 143799 | struct RtreeMatchArg { |
| 143066 | - u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ | |
| 143067 | - int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue*, int *); | |
| 143068 | - void *pContext; | |
| 143069 | - int nParam; | |
| 143070 | - RtreeDValue aParam[1]; | |
| 143071 | -}; | |
| 143072 | - | |
| 143073 | -/* | |
| 143074 | -** When a geometry callback is created (see sqlite3_rtree_geometry_callback), | |
| 143075 | -** a single instance of the following structure is allocated. It is used | |
| 143076 | -** as the context for the user-function created by by s_r_g_c(). The object | |
| 143077 | -** is eventually deleted by the destructor mechanism provided by | |
| 143078 | -** sqlite3_create_function_v2() (which is called by s_r_g_c() to create | |
| 143079 | -** the geometry callback function). | |
| 143080 | -*/ | |
| 143081 | -struct RtreeGeomCallback { | |
| 143082 | - int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); | |
| 143083 | - void *pContext; | |
| 143800 | + u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ | |
| 143801 | + RtreeGeomCallback cb; /* Info about the callback functions */ | |
| 143802 | + int nParam; /* Number of parameters to the SQL function */ | |
| 143803 | + RtreeDValue aParam[1]; /* Values for parameters to the SQL function */ | |
| 143084 | 143804 | }; |
| 143085 | 143805 | |
| 143086 | 143806 | #ifndef MAX |
| 143087 | 143807 | # define MAX(x,y) ((x) < (y) ? (y) : (x)) |
| 143088 | 143808 | #endif |
| @@ -143172,14 +143892,11 @@ | ||
| 143172 | 143892 | /* |
| 143173 | 143893 | ** Given a node number iNode, return the corresponding key to use |
| 143174 | 143894 | ** in the Rtree.aHash table. |
| 143175 | 143895 | */ |
| 143176 | 143896 | static int nodeHash(i64 iNode){ |
| 143177 | - return ( | |
| 143178 | - (iNode>>56) ^ (iNode>>48) ^ (iNode>>40) ^ (iNode>>32) ^ | |
| 143179 | - (iNode>>24) ^ (iNode>>16) ^ (iNode>> 8) ^ (iNode>> 0) | |
| 143180 | - ) % HASHSIZE; | |
| 143897 | + return iNode % HASHSIZE; | |
| 143181 | 143898 | } |
| 143182 | 143899 | |
| 143183 | 143900 | /* |
| 143184 | 143901 | ** Search the node hash table for node iNode. If found, return a pointer |
| 143185 | 143902 | ** to it. Otherwise, return 0. |
| @@ -143235,12 +143952,11 @@ | ||
| 143235 | 143952 | } |
| 143236 | 143953 | |
| 143237 | 143954 | /* |
| 143238 | 143955 | ** Obtain a reference to an r-tree node. |
| 143239 | 143956 | */ |
| 143240 | -static int | |
| 143241 | -nodeAcquire( | |
| 143957 | +static int nodeAcquire( | |
| 143242 | 143958 | Rtree *pRtree, /* R-tree structure */ |
| 143243 | 143959 | i64 iNode, /* Node number to load */ |
| 143244 | 143960 | RtreeNode *pParent, /* Either the parent node or NULL */ |
| 143245 | 143961 | RtreeNode **ppNode /* OUT: Acquired node */ |
| 143246 | 143962 | ){ |
| @@ -143325,14 +144041,14 @@ | ||
| 143325 | 144041 | |
| 143326 | 144042 | /* |
| 143327 | 144043 | ** Overwrite cell iCell of node pNode with the contents of pCell. |
| 143328 | 144044 | */ |
| 143329 | 144045 | static void nodeOverwriteCell( |
| 143330 | - Rtree *pRtree, | |
| 143331 | - RtreeNode *pNode, | |
| 143332 | - RtreeCell *pCell, | |
| 143333 | - int iCell | |
| 144046 | + Rtree *pRtree, /* The overall R-Tree */ | |
| 144047 | + RtreeNode *pNode, /* The node into which the cell is to be written */ | |
| 144048 | + RtreeCell *pCell, /* The cell to write */ | |
| 144049 | + int iCell /* Index into pNode into which pCell is written */ | |
| 143334 | 144050 | ){ |
| 143335 | 144051 | int ii; |
| 143336 | 144052 | u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; |
| 143337 | 144053 | p += writeInt64(p, pCell->iRowid); |
| 143338 | 144054 | for(ii=0; ii<(pRtree->nDim*2); ii++){ |
| @@ -143340,11 +144056,11 @@ | ||
| 143340 | 144056 | } |
| 143341 | 144057 | pNode->isDirty = 1; |
| 143342 | 144058 | } |
| 143343 | 144059 | |
| 143344 | 144060 | /* |
| 143345 | -** Remove cell the cell with index iCell from node pNode. | |
| 144061 | +** Remove the cell with index iCell from node pNode. | |
| 143346 | 144062 | */ |
| 143347 | 144063 | static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){ |
| 143348 | 144064 | u8 *pDst = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; |
| 143349 | 144065 | u8 *pSrc = &pDst[pRtree->nBytesPerCell]; |
| 143350 | 144066 | int nByte = (NCELL(pNode) - iCell - 1) * pRtree->nBytesPerCell; |
| @@ -143357,15 +144073,14 @@ | ||
| 143357 | 144073 | ** Insert the contents of cell pCell into node pNode. If the insert |
| 143358 | 144074 | ** is successful, return SQLITE_OK. |
| 143359 | 144075 | ** |
| 143360 | 144076 | ** If there is not enough free space in pNode, return SQLITE_FULL. |
| 143361 | 144077 | */ |
| 143362 | -static int | |
| 143363 | -nodeInsertCell( | |
| 143364 | - Rtree *pRtree, | |
| 143365 | - RtreeNode *pNode, | |
| 143366 | - RtreeCell *pCell | |
| 144078 | +static int nodeInsertCell( | |
| 144079 | + Rtree *pRtree, /* The overall R-Tree */ | |
| 144080 | + RtreeNode *pNode, /* Write new cell into this node */ | |
| 144081 | + RtreeCell *pCell /* The cell to be inserted */ | |
| 143367 | 144082 | ){ |
| 143368 | 144083 | int nCell; /* Current number of cells in pNode */ |
| 143369 | 144084 | int nMaxCell; /* Maximum number of cells for pNode */ |
| 143370 | 144085 | |
| 143371 | 144086 | nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell; |
| @@ -143382,12 +144097,11 @@ | ||
| 143382 | 144097 | } |
| 143383 | 144098 | |
| 143384 | 144099 | /* |
| 143385 | 144100 | ** If the node is dirty, write it out to the database. |
| 143386 | 144101 | */ |
| 143387 | -static int | |
| 143388 | -nodeWrite(Rtree *pRtree, RtreeNode *pNode){ | |
| 144102 | +static int nodeWrite(Rtree *pRtree, RtreeNode *pNode){ | |
| 143389 | 144103 | int rc = SQLITE_OK; |
| 143390 | 144104 | if( pNode->isDirty ){ |
| 143391 | 144105 | sqlite3_stmt *p = pRtree->pWriteNode; |
| 143392 | 144106 | if( pNode->iNode ){ |
| 143393 | 144107 | sqlite3_bind_int64(p, 1, pNode->iNode); |
| @@ -143408,12 +144122,11 @@ | ||
| 143408 | 144122 | |
| 143409 | 144123 | /* |
| 143410 | 144124 | ** Release a reference to a node. If the node is dirty and the reference |
| 143411 | 144125 | ** count drops to zero, the node data is written to the database. |
| 143412 | 144126 | */ |
| 143413 | -static int | |
| 143414 | -nodeRelease(Rtree *pRtree, RtreeNode *pNode){ | |
| 144127 | +static int nodeRelease(Rtree *pRtree, RtreeNode *pNode){ | |
| 143415 | 144128 | int rc = SQLITE_OK; |
| 143416 | 144129 | if( pNode ){ |
| 143417 | 144130 | assert( pNode->nRef>0 ); |
| 143418 | 144131 | pNode->nRef--; |
| 143419 | 144132 | if( pNode->nRef==0 ){ |
| @@ -143437,45 +144150,50 @@ | ||
| 143437 | 144150 | ** Return the 64-bit integer value associated with cell iCell of |
| 143438 | 144151 | ** node pNode. If pNode is a leaf node, this is a rowid. If it is |
| 143439 | 144152 | ** an internal node, then the 64-bit integer is a child page number. |
| 143440 | 144153 | */ |
| 143441 | 144154 | static i64 nodeGetRowid( |
| 143442 | - Rtree *pRtree, | |
| 143443 | - RtreeNode *pNode, | |
| 143444 | - int iCell | |
| 144155 | + Rtree *pRtree, /* The overall R-Tree */ | |
| 144156 | + RtreeNode *pNode, /* The node from which to extract the ID */ | |
| 144157 | + int iCell /* The cell index from which to extract the ID */ | |
| 143445 | 144158 | ){ |
| 143446 | 144159 | assert( iCell<NCELL(pNode) ); |
| 143447 | 144160 | return readInt64(&pNode->zData[4 + pRtree->nBytesPerCell*iCell]); |
| 143448 | 144161 | } |
| 143449 | 144162 | |
| 143450 | 144163 | /* |
| 143451 | 144164 | ** Return coordinate iCoord from cell iCell in node pNode. |
| 143452 | 144165 | */ |
| 143453 | 144166 | static void nodeGetCoord( |
| 143454 | - Rtree *pRtree, | |
| 143455 | - RtreeNode *pNode, | |
| 143456 | - int iCell, | |
| 143457 | - int iCoord, | |
| 143458 | - RtreeCoord *pCoord /* Space to write result to */ | |
| 144167 | + Rtree *pRtree, /* The overall R-Tree */ | |
| 144168 | + RtreeNode *pNode, /* The node from which to extract a coordinate */ | |
| 144169 | + int iCell, /* The index of the cell within the node */ | |
| 144170 | + int iCoord, /* Which coordinate to extract */ | |
| 144171 | + RtreeCoord *pCoord /* OUT: Space to write result to */ | |
| 143459 | 144172 | ){ |
| 143460 | 144173 | readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord); |
| 143461 | 144174 | } |
| 143462 | 144175 | |
| 143463 | 144176 | /* |
| 143464 | 144177 | ** Deserialize cell iCell of node pNode. Populate the structure pointed |
| 143465 | 144178 | ** to by pCell with the results. |
| 143466 | 144179 | */ |
| 143467 | 144180 | static void nodeGetCell( |
| 143468 | - Rtree *pRtree, | |
| 143469 | - RtreeNode *pNode, | |
| 143470 | - int iCell, | |
| 143471 | - RtreeCell *pCell | |
| 144181 | + Rtree *pRtree, /* The overall R-Tree */ | |
| 144182 | + RtreeNode *pNode, /* The node containing the cell to be read */ | |
| 144183 | + int iCell, /* Index of the cell within the node */ | |
| 144184 | + RtreeCell *pCell /* OUT: Write the cell contents here */ | |
| 143472 | 144185 | ){ |
| 143473 | - int ii; | |
| 144186 | + u8 *pData; | |
| 144187 | + u8 *pEnd; | |
| 144188 | + RtreeCoord *pCoord; | |
| 143474 | 144189 | pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); |
| 143475 | - for(ii=0; ii<pRtree->nDim*2; ii++){ | |
| 143476 | - nodeGetCoord(pRtree, pNode, iCell, ii, &pCell->aCoord[ii]); | |
| 144190 | + pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell); | |
| 144191 | + pEnd = pData + pRtree->nDim*8; | |
| 144192 | + pCoord = pCell->aCoord; | |
| 144193 | + for(; pData<pEnd; pData+=4, pCoord++){ | |
| 144194 | + readCoord(pData, pCoord); | |
| 143477 | 144195 | } |
| 143478 | 144196 | } |
| 143479 | 144197 | |
| 143480 | 144198 | |
| 143481 | 144199 | /* Forward declaration for the function that does the work of |
| @@ -143597,14 +144315,14 @@ | ||
| 143597 | 144315 | */ |
| 143598 | 144316 | static void freeCursorConstraints(RtreeCursor *pCsr){ |
| 143599 | 144317 | if( pCsr->aConstraint ){ |
| 143600 | 144318 | int i; /* Used to iterate through constraint array */ |
| 143601 | 144319 | for(i=0; i<pCsr->nConstraint; i++){ |
| 143602 | - sqlite3_rtree_geometry *pGeom = pCsr->aConstraint[i].pGeom; | |
| 143603 | - if( pGeom ){ | |
| 143604 | - if( pGeom->xDelUser ) pGeom->xDelUser(pGeom->pUser); | |
| 143605 | - sqlite3_free(pGeom); | |
| 144320 | + sqlite3_rtree_query_info *pInfo = pCsr->aConstraint[i].pInfo; | |
| 144321 | + if( pInfo ){ | |
| 144322 | + if( pInfo->xDelUser ) pInfo->xDelUser(pInfo->pUser); | |
| 144323 | + sqlite3_free(pInfo); | |
| 143606 | 144324 | } |
| 143607 | 144325 | } |
| 143608 | 144326 | sqlite3_free(pCsr->aConstraint); |
| 143609 | 144327 | pCsr->aConstraint = 0; |
| 143610 | 144328 | } |
| @@ -143613,16 +144331,17 @@ | ||
| 143613 | 144331 | /* |
| 143614 | 144332 | ** Rtree virtual table module xClose method. |
| 143615 | 144333 | */ |
| 143616 | 144334 | static int rtreeClose(sqlite3_vtab_cursor *cur){ |
| 143617 | 144335 | Rtree *pRtree = (Rtree *)(cur->pVtab); |
| 143618 | - int rc; | |
| 144336 | + int ii; | |
| 143619 | 144337 | RtreeCursor *pCsr = (RtreeCursor *)cur; |
| 143620 | 144338 | freeCursorConstraints(pCsr); |
| 143621 | - rc = nodeRelease(pRtree, pCsr->pNode); | |
| 144339 | + sqlite3_free(pCsr->aPoint); | |
| 144340 | + for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]); | |
| 143622 | 144341 | sqlite3_free(pCsr); |
| 143623 | - return rc; | |
| 144342 | + return SQLITE_OK; | |
| 143624 | 144343 | } |
| 143625 | 144344 | |
| 143626 | 144345 | /* |
| 143627 | 144346 | ** Rtree virtual table module xEof method. |
| 143628 | 144347 | ** |
| @@ -143629,198 +144348,168 @@ | ||
| 143629 | 144348 | ** Return non-zero if the cursor does not currently point to a valid |
| 143630 | 144349 | ** record (i.e if the scan has finished), or zero otherwise. |
| 143631 | 144350 | */ |
| 143632 | 144351 | static int rtreeEof(sqlite3_vtab_cursor *cur){ |
| 143633 | 144352 | RtreeCursor *pCsr = (RtreeCursor *)cur; |
| 143634 | - return (pCsr->pNode==0); | |
| 143635 | -} | |
| 143636 | - | |
| 143637 | -/* | |
| 143638 | -** The r-tree constraint passed as the second argument to this function is | |
| 143639 | -** guaranteed to be a MATCH constraint. | |
| 143640 | -*/ | |
| 143641 | -static int testRtreeGeom( | |
| 143642 | - Rtree *pRtree, /* R-Tree object */ | |
| 143643 | - RtreeConstraint *pConstraint, /* MATCH constraint to test */ | |
| 143644 | - RtreeCell *pCell, /* Cell to test */ | |
| 143645 | - int *pbRes /* OUT: Test result */ | |
| 143646 | -){ | |
| 143647 | - int i; | |
| 143648 | - RtreeDValue aCoord[RTREE_MAX_DIMENSIONS*2]; | |
| 143649 | - int nCoord = pRtree->nDim*2; | |
| 143650 | - | |
| 143651 | - assert( pConstraint->op==RTREE_MATCH ); | |
| 143652 | - assert( pConstraint->pGeom ); | |
| 143653 | - | |
| 143654 | - for(i=0; i<nCoord; i++){ | |
| 143655 | - aCoord[i] = DCOORD(pCell->aCoord[i]); | |
| 143656 | - } | |
| 143657 | - return pConstraint->xGeom(pConstraint->pGeom, nCoord, aCoord, pbRes); | |
| 143658 | -} | |
| 143659 | - | |
| 143660 | -/* | |
| 143661 | -** Cursor pCursor currently points to a cell in a non-leaf page. | |
| 143662 | -** Set *pbEof to true if the sub-tree headed by the cell is filtered | |
| 143663 | -** (excluded) by the constraints in the pCursor->aConstraint[] | |
| 143664 | -** array, or false otherwise. | |
| 143665 | -** | |
| 143666 | -** Return SQLITE_OK if successful or an SQLite error code if an error | |
| 143667 | -** occurs within a geometry callback. | |
| 143668 | -*/ | |
| 143669 | -static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){ | |
| 143670 | - RtreeCell cell; | |
| 143671 | - int ii; | |
| 143672 | - int bRes = 0; | |
| 143673 | - int rc = SQLITE_OK; | |
| 143674 | - | |
| 143675 | - nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); | |
| 143676 | - for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){ | |
| 143677 | - RtreeConstraint *p = &pCursor->aConstraint[ii]; | |
| 143678 | - RtreeDValue cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]); | |
| 143679 | - RtreeDValue cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]); | |
| 143680 | - | |
| 143681 | - assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE | |
| 143682 | - || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH | |
| 143683 | - ); | |
| 143684 | - | |
| 143685 | - switch( p->op ){ | |
| 143686 | - case RTREE_LE: case RTREE_LT: | |
| 143687 | - bRes = p->rValue<cell_min; | |
| 143688 | - break; | |
| 143689 | - | |
| 143690 | - case RTREE_GE: case RTREE_GT: | |
| 143691 | - bRes = p->rValue>cell_max; | |
| 143692 | - break; | |
| 143693 | - | |
| 143694 | - case RTREE_EQ: | |
| 143695 | - bRes = (p->rValue>cell_max || p->rValue<cell_min); | |
| 143696 | - break; | |
| 143697 | - | |
| 143698 | - default: { | |
| 143699 | - assert( p->op==RTREE_MATCH ); | |
| 143700 | - rc = testRtreeGeom(pRtree, p, &cell, &bRes); | |
| 143701 | - bRes = !bRes; | |
| 143702 | - break; | |
| 143703 | - } | |
| 143704 | - } | |
| 143705 | - } | |
| 143706 | - | |
| 143707 | - *pbEof = bRes; | |
| 143708 | - return rc; | |
| 143709 | -} | |
| 143710 | - | |
| 143711 | -/* | |
| 143712 | -** Test if the cell that cursor pCursor currently points to | |
| 143713 | -** would be filtered (excluded) by the constraints in the | |
| 143714 | -** pCursor->aConstraint[] array. If so, set *pbEof to true before | |
| 143715 | -** returning. If the cell is not filtered (excluded) by the constraints, | |
| 143716 | -** set pbEof to zero. | |
| 143717 | -** | |
| 143718 | -** Return SQLITE_OK if successful or an SQLite error code if an error | |
| 143719 | -** occurs within a geometry callback. | |
| 143720 | -** | |
| 143721 | -** This function assumes that the cell is part of a leaf node. | |
| 143722 | -*/ | |
| 143723 | -static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){ | |
| 143724 | - RtreeCell cell; | |
| 143725 | - int ii; | |
| 143726 | - *pbEof = 0; | |
| 143727 | - | |
| 143728 | - nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); | |
| 143729 | - for(ii=0; ii<pCursor->nConstraint; ii++){ | |
| 143730 | - RtreeConstraint *p = &pCursor->aConstraint[ii]; | |
| 143731 | - RtreeDValue coord = DCOORD(cell.aCoord[p->iCoord]); | |
| 143732 | - int res; | |
| 143733 | - assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE | |
| 143734 | - || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH | |
| 143735 | - ); | |
| 143736 | - switch( p->op ){ | |
| 143737 | - case RTREE_LE: res = (coord<=p->rValue); break; | |
| 143738 | - case RTREE_LT: res = (coord<p->rValue); break; | |
| 143739 | - case RTREE_GE: res = (coord>=p->rValue); break; | |
| 143740 | - case RTREE_GT: res = (coord>p->rValue); break; | |
| 143741 | - case RTREE_EQ: res = (coord==p->rValue); break; | |
| 143742 | - default: { | |
| 143743 | - int rc; | |
| 143744 | - assert( p->op==RTREE_MATCH ); | |
| 143745 | - rc = testRtreeGeom(pRtree, p, &cell, &res); | |
| 143746 | - if( rc!=SQLITE_OK ){ | |
| 143747 | - return rc; | |
| 143748 | - } | |
| 143749 | - break; | |
| 143750 | - } | |
| 143751 | - } | |
| 143752 | - | |
| 143753 | - if( !res ){ | |
| 143754 | - *pbEof = 1; | |
| 143755 | - return SQLITE_OK; | |
| 143756 | - } | |
| 143757 | - } | |
| 143758 | - | |
| 143759 | - return SQLITE_OK; | |
| 143760 | -} | |
| 143761 | - | |
| 143762 | -/* | |
| 143763 | -** Cursor pCursor currently points at a node that heads a sub-tree of | |
| 143764 | -** height iHeight (if iHeight==0, then the node is a leaf). Descend | |
| 143765 | -** to point to the left-most cell of the sub-tree that matches the | |
| 143766 | -** configured constraints. | |
| 143767 | -*/ | |
| 143768 | -static int descendToCell( | |
| 143769 | - Rtree *pRtree, | |
| 143770 | - RtreeCursor *pCursor, | |
| 143771 | - int iHeight, | |
| 143772 | - int *pEof /* OUT: Set to true if cannot descend */ | |
| 143773 | -){ | |
| 143774 | - int isEof; | |
| 143775 | - int rc; | |
| 143776 | - int ii; | |
| 143777 | - RtreeNode *pChild; | |
| 143778 | - sqlite3_int64 iRowid; | |
| 143779 | - | |
| 143780 | - RtreeNode *pSavedNode = pCursor->pNode; | |
| 143781 | - int iSavedCell = pCursor->iCell; | |
| 143782 | - | |
| 143783 | - assert( iHeight>=0 ); | |
| 143784 | - | |
| 143785 | - if( iHeight==0 ){ | |
| 143786 | - rc = testRtreeEntry(pRtree, pCursor, &isEof); | |
| 143787 | - }else{ | |
| 143788 | - rc = testRtreeCell(pRtree, pCursor, &isEof); | |
| 143789 | - } | |
| 143790 | - if( rc!=SQLITE_OK || isEof || iHeight==0 ){ | |
| 143791 | - goto descend_to_cell_out; | |
| 143792 | - } | |
| 143793 | - | |
| 143794 | - iRowid = nodeGetRowid(pRtree, pCursor->pNode, pCursor->iCell); | |
| 143795 | - rc = nodeAcquire(pRtree, iRowid, pCursor->pNode, &pChild); | |
| 143796 | - if( rc!=SQLITE_OK ){ | |
| 143797 | - goto descend_to_cell_out; | |
| 143798 | - } | |
| 143799 | - | |
| 143800 | - nodeRelease(pRtree, pCursor->pNode); | |
| 143801 | - pCursor->pNode = pChild; | |
| 143802 | - isEof = 1; | |
| 143803 | - for(ii=0; isEof && ii<NCELL(pChild); ii++){ | |
| 143804 | - pCursor->iCell = ii; | |
| 143805 | - rc = descendToCell(pRtree, pCursor, iHeight-1, &isEof); | |
| 143806 | - if( rc!=SQLITE_OK ){ | |
| 143807 | - goto descend_to_cell_out; | |
| 143808 | - } | |
| 143809 | - } | |
| 143810 | - | |
| 143811 | - if( isEof ){ | |
| 143812 | - assert( pCursor->pNode==pChild ); | |
| 143813 | - nodeReference(pSavedNode); | |
| 143814 | - nodeRelease(pRtree, pChild); | |
| 143815 | - pCursor->pNode = pSavedNode; | |
| 143816 | - pCursor->iCell = iSavedCell; | |
| 143817 | - } | |
| 143818 | - | |
| 143819 | -descend_to_cell_out: | |
| 143820 | - *pEof = isEof; | |
| 143821 | - return rc; | |
| 144353 | + return pCsr->atEOF; | |
| 144354 | +} | |
| 144355 | + | |
| 144356 | +/* | |
| 144357 | +** Convert raw bits from the on-disk RTree record into a coordinate value. | |
| 144358 | +** The on-disk format is big-endian and needs to be converted for little- | |
| 144359 | +** endian platforms. The on-disk record stores integer coordinates if | |
| 144360 | +** eInt is true and it stores 32-bit floating point records if eInt is | |
| 144361 | +** false. a[] is the four bytes of the on-disk record to be decoded. | |
| 144362 | +** Store the results in "r". | |
| 144363 | +** | |
| 144364 | +** There are three versions of this macro, one each for little-endian and | |
| 144365 | +** big-endian processors and a third generic implementation. The endian- | |
| 144366 | +** specific implementations are much faster and are preferred if the | |
| 144367 | +** processor endianness is known at compile-time. The SQLITE_BYTEORDER | |
| 144368 | +** macro is part of sqliteInt.h and hence the endian-specific | |
| 144369 | +** implementation will only be used if this module is compiled as part | |
| 144370 | +** of the amalgamation. | |
| 144371 | +*/ | |
| 144372 | +#if defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==1234 | |
| 144373 | +#define RTREE_DECODE_COORD(eInt, a, r) { \ | |
| 144374 | + RtreeCoord c; /* Coordinate decoded */ \ | |
| 144375 | + memcpy(&c.u,a,4); \ | |
| 144376 | + c.u = ((c.u>>24)&0xff)|((c.u>>8)&0xff00)| \ | |
| 144377 | + ((c.u&0xff)<<24)|((c.u&0xff00)<<8); \ | |
| 144378 | + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ | |
| 144379 | +} | |
| 144380 | +#elif defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==4321 | |
| 144381 | +#define RTREE_DECODE_COORD(eInt, a, r) { \ | |
| 144382 | + RtreeCoord c; /* Coordinate decoded */ \ | |
| 144383 | + memcpy(&c.u,a,4); \ | |
| 144384 | + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ | |
| 144385 | +} | |
| 144386 | +#else | |
| 144387 | +#define RTREE_DECODE_COORD(eInt, a, r) { \ | |
| 144388 | + RtreeCoord c; /* Coordinate decoded */ \ | |
| 144389 | + c.u = ((u32)a[0]<<24) + ((u32)a[1]<<16) \ | |
| 144390 | + +((u32)a[2]<<8) + a[3]; \ | |
| 144391 | + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ | |
| 144392 | +} | |
| 144393 | +#endif | |
| 144394 | + | |
| 144395 | +/* | |
| 144396 | +** Check the RTree node or entry given by pCellData and p against the MATCH | |
| 144397 | +** constraint pConstraint. | |
| 144398 | +*/ | |
| 144399 | +static int rtreeCallbackConstraint( | |
| 144400 | + RtreeConstraint *pConstraint, /* The constraint to test */ | |
| 144401 | + int eInt, /* True if RTree holding integer coordinates */ | |
| 144402 | + u8 *pCellData, /* Raw cell content */ | |
| 144403 | + RtreeSearchPoint *pSearch, /* Container of this cell */ | |
| 144404 | + sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */ | |
| 144405 | + int *peWithin /* OUT: visibility of the cell */ | |
| 144406 | +){ | |
| 144407 | + int i; /* Loop counter */ | |
| 144408 | + sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */ | |
| 144409 | + int nCoord = pInfo->nCoord; /* No. of coordinates */ | |
| 144410 | + int rc; /* Callback return code */ | |
| 144411 | + sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */ | |
| 144412 | + | |
| 144413 | + assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY ); | |
| 144414 | + assert( nCoord==2 || nCoord==4 || nCoord==6 || nCoord==8 || nCoord==10 ); | |
| 144415 | + | |
| 144416 | + if( pConstraint->op==RTREE_QUERY && pSearch->iLevel==1 ){ | |
| 144417 | + pInfo->iRowid = readInt64(pCellData); | |
| 144418 | + } | |
| 144419 | + pCellData += 8; | |
| 144420 | + for(i=0; i<nCoord; i++, pCellData += 4){ | |
| 144421 | + RTREE_DECODE_COORD(eInt, pCellData, aCoord[i]); | |
| 144422 | + } | |
| 144423 | + if( pConstraint->op==RTREE_MATCH ){ | |
| 144424 | + rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo, | |
| 144425 | + nCoord, aCoord, &i); | |
| 144426 | + if( i==0 ) *peWithin = NOT_WITHIN; | |
| 144427 | + *prScore = RTREE_ZERO; | |
| 144428 | + }else{ | |
| 144429 | + pInfo->aCoord = aCoord; | |
| 144430 | + pInfo->iLevel = pSearch->iLevel - 1; | |
| 144431 | + pInfo->rScore = pInfo->rParentScore = pSearch->rScore; | |
| 144432 | + pInfo->eWithin = pInfo->eParentWithin = pSearch->eWithin; | |
| 144433 | + rc = pConstraint->u.xQueryFunc(pInfo); | |
| 144434 | + if( pInfo->eWithin<*peWithin ) *peWithin = pInfo->eWithin; | |
| 144435 | + if( pInfo->rScore<*prScore || *prScore<RTREE_ZERO ){ | |
| 144436 | + *prScore = pInfo->rScore; | |
| 144437 | + } | |
| 144438 | + } | |
| 144439 | + return rc; | |
| 144440 | +} | |
| 144441 | + | |
| 144442 | +/* | |
| 144443 | +** Check the internal RTree node given by pCellData against constraint p. | |
| 144444 | +** If this constraint cannot be satisfied by any child within the node, | |
| 144445 | +** set *peWithin to NOT_WITHIN. | |
| 144446 | +*/ | |
| 144447 | +static void rtreeNonleafConstraint( | |
| 144448 | + RtreeConstraint *p, /* The constraint to test */ | |
| 144449 | + int eInt, /* True if RTree holds integer coordinates */ | |
| 144450 | + u8 *pCellData, /* Raw cell content as appears on disk */ | |
| 144451 | + int *peWithin /* Adjust downward, as appropriate */ | |
| 144452 | +){ | |
| 144453 | + sqlite3_rtree_dbl val; /* Coordinate value convert to a double */ | |
| 144454 | + | |
| 144455 | + /* p->iCoord might point to either a lower or upper bound coordinate | |
| 144456 | + ** in a coordinate pair. But make pCellData point to the lower bound. | |
| 144457 | + */ | |
| 144458 | + pCellData += 8 + 4*(p->iCoord&0xfe); | |
| 144459 | + | |
| 144460 | + assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE | |
| 144461 | + || p->op==RTREE_GT || p->op==RTREE_EQ ); | |
| 144462 | + switch( p->op ){ | |
| 144463 | + case RTREE_LE: | |
| 144464 | + case RTREE_LT: | |
| 144465 | + case RTREE_EQ: | |
| 144466 | + RTREE_DECODE_COORD(eInt, pCellData, val); | |
| 144467 | + /* val now holds the lower bound of the coordinate pair */ | |
| 144468 | + if( p->u.rValue>=val ) return; | |
| 144469 | + if( p->op!=RTREE_EQ ) break; /* RTREE_LE and RTREE_LT end here */ | |
| 144470 | + /* Fall through for the RTREE_EQ case */ | |
| 144471 | + | |
| 144472 | + default: /* RTREE_GT or RTREE_GE, or fallthrough of RTREE_EQ */ | |
| 144473 | + pCellData += 4; | |
| 144474 | + RTREE_DECODE_COORD(eInt, pCellData, val); | |
| 144475 | + /* val now holds the upper bound of the coordinate pair */ | |
| 144476 | + if( p->u.rValue<=val ) return; | |
| 144477 | + } | |
| 144478 | + *peWithin = NOT_WITHIN; | |
| 144479 | +} | |
| 144480 | + | |
| 144481 | +/* | |
| 144482 | +** Check the leaf RTree cell given by pCellData against constraint p. | |
| 144483 | +** If this constraint is not satisfied, set *peWithin to NOT_WITHIN. | |
| 144484 | +** If the constraint is satisfied, leave *peWithin unchanged. | |
| 144485 | +** | |
| 144486 | +** The constraint is of the form: xN op $val | |
| 144487 | +** | |
| 144488 | +** The op is given by p->op. The xN is p->iCoord-th coordinate in | |
| 144489 | +** pCellData. $val is given by p->u.rValue. | |
| 144490 | +*/ | |
| 144491 | +static void rtreeLeafConstraint( | |
| 144492 | + RtreeConstraint *p, /* The constraint to test */ | |
| 144493 | + int eInt, /* True if RTree holds integer coordinates */ | |
| 144494 | + u8 *pCellData, /* Raw cell content as appears on disk */ | |
| 144495 | + int *peWithin /* Adjust downward, as appropriate */ | |
| 144496 | +){ | |
| 144497 | + RtreeDValue xN; /* Coordinate value converted to a double */ | |
| 144498 | + | |
| 144499 | + assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE | |
| 144500 | + || p->op==RTREE_GT || p->op==RTREE_EQ ); | |
| 144501 | + pCellData += 8 + p->iCoord*4; | |
| 144502 | + RTREE_DECODE_COORD(eInt, pCellData, xN); | |
| 144503 | + switch( p->op ){ | |
| 144504 | + case RTREE_LE: if( xN <= p->u.rValue ) return; break; | |
| 144505 | + case RTREE_LT: if( xN < p->u.rValue ) return; break; | |
| 144506 | + case RTREE_GE: if( xN >= p->u.rValue ) return; break; | |
| 144507 | + case RTREE_GT: if( xN > p->u.rValue ) return; break; | |
| 144508 | + default: if( xN == p->u.rValue ) return; break; | |
| 144509 | + } | |
| 144510 | + *peWithin = NOT_WITHIN; | |
| 143822 | 144511 | } |
| 143823 | 144512 | |
| 143824 | 144513 | /* |
| 143825 | 144514 | ** One of the cells in node pNode is guaranteed to have a 64-bit |
| 143826 | 144515 | ** integer value equal to iRowid. Return the index of this cell. |
| @@ -143831,10 +144520,11 @@ | ||
| 143831 | 144520 | i64 iRowid, |
| 143832 | 144521 | int *piIndex |
| 143833 | 144522 | ){ |
| 143834 | 144523 | int ii; |
| 143835 | 144524 | int nCell = NCELL(pNode); |
| 144525 | + assert( nCell<200 ); | |
| 143836 | 144526 | for(ii=0; ii<nCell; ii++){ |
| 143837 | 144527 | if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){ |
| 143838 | 144528 | *piIndex = ii; |
| 143839 | 144529 | return SQLITE_OK; |
| 143840 | 144530 | } |
| @@ -143852,82 +144542,342 @@ | ||
| 143852 | 144542 | return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex); |
| 143853 | 144543 | } |
| 143854 | 144544 | *piIndex = -1; |
| 143855 | 144545 | return SQLITE_OK; |
| 143856 | 144546 | } |
| 144547 | + | |
| 144548 | +/* | |
| 144549 | +** Compare two search points. Return negative, zero, or positive if the first | |
| 144550 | +** is less than, equal to, or greater than the second. | |
| 144551 | +** | |
| 144552 | +** The rScore is the primary key. Smaller rScore values come first. | |
| 144553 | +** If the rScore is a tie, then use iLevel as the tie breaker with smaller | |
| 144554 | +** iLevel values coming first. In this way, if rScore is the same for all | |
| 144555 | +** SearchPoints, then iLevel becomes the deciding factor and the result | |
| 144556 | +** is a depth-first search, which is the desired default behavior. | |
| 144557 | +*/ | |
| 144558 | +static int rtreeSearchPointCompare( | |
| 144559 | + const RtreeSearchPoint *pA, | |
| 144560 | + const RtreeSearchPoint *pB | |
| 144561 | +){ | |
| 144562 | + if( pA->rScore<pB->rScore ) return -1; | |
| 144563 | + if( pA->rScore>pB->rScore ) return +1; | |
| 144564 | + if( pA->iLevel<pB->iLevel ) return -1; | |
| 144565 | + if( pA->iLevel>pB->iLevel ) return +1; | |
| 144566 | + return 0; | |
| 144567 | +} | |
| 144568 | + | |
| 144569 | +/* | |
| 144570 | +** Interchange to search points in a cursor. | |
| 144571 | +*/ | |
| 144572 | +static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){ | |
| 144573 | + RtreeSearchPoint t = p->aPoint[i]; | |
| 144574 | + assert( i<j ); | |
| 144575 | + p->aPoint[i] = p->aPoint[j]; | |
| 144576 | + p->aPoint[j] = t; | |
| 144577 | + i++; j++; | |
| 144578 | + if( i<RTREE_CACHE_SZ ){ | |
| 144579 | + if( j>=RTREE_CACHE_SZ ){ | |
| 144580 | + nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); | |
| 144581 | + p->aNode[i] = 0; | |
| 144582 | + }else{ | |
| 144583 | + RtreeNode *pTemp = p->aNode[i]; | |
| 144584 | + p->aNode[i] = p->aNode[j]; | |
| 144585 | + p->aNode[j] = pTemp; | |
| 144586 | + } | |
| 144587 | + } | |
| 144588 | +} | |
| 144589 | + | |
| 144590 | +/* | |
| 144591 | +** Return the search point with the lowest current score. | |
| 144592 | +*/ | |
| 144593 | +static RtreeSearchPoint *rtreeSearchPointFirst(RtreeCursor *pCur){ | |
| 144594 | + return pCur->bPoint ? &pCur->sPoint : pCur->nPoint ? pCur->aPoint : 0; | |
| 144595 | +} | |
| 144596 | + | |
| 144597 | +/* | |
| 144598 | +** Get the RtreeNode for the search point with the lowest score. | |
| 144599 | +*/ | |
| 144600 | +static RtreeNode *rtreeNodeOfFirstSearchPoint(RtreeCursor *pCur, int *pRC){ | |
| 144601 | + sqlite3_int64 id; | |
| 144602 | + int ii = 1 - pCur->bPoint; | |
| 144603 | + assert( ii==0 || ii==1 ); | |
| 144604 | + assert( pCur->bPoint || pCur->nPoint ); | |
| 144605 | + if( pCur->aNode[ii]==0 ){ | |
| 144606 | + assert( pRC!=0 ); | |
| 144607 | + id = ii ? pCur->aPoint[0].id : pCur->sPoint.id; | |
| 144608 | + *pRC = nodeAcquire(RTREE_OF_CURSOR(pCur), id, 0, &pCur->aNode[ii]); | |
| 144609 | + } | |
| 144610 | + return pCur->aNode[ii]; | |
| 144611 | +} | |
| 144612 | + | |
| 144613 | +/* | |
| 144614 | +** Push a new element onto the priority queue | |
| 144615 | +*/ | |
| 144616 | +static RtreeSearchPoint *rtreeEnqueue( | |
| 144617 | + RtreeCursor *pCur, /* The cursor */ | |
| 144618 | + RtreeDValue rScore, /* Score for the new search point */ | |
| 144619 | + u8 iLevel /* Level for the new search point */ | |
| 144620 | +){ | |
| 144621 | + int i, j; | |
| 144622 | + RtreeSearchPoint *pNew; | |
| 144623 | + if( pCur->nPoint>=pCur->nPointAlloc ){ | |
| 144624 | + int nNew = pCur->nPointAlloc*2 + 8; | |
| 144625 | + pNew = sqlite3_realloc(pCur->aPoint, nNew*sizeof(pCur->aPoint[0])); | |
| 144626 | + if( pNew==0 ) return 0; | |
| 144627 | + pCur->aPoint = pNew; | |
| 144628 | + pCur->nPointAlloc = nNew; | |
| 144629 | + } | |
| 144630 | + i = pCur->nPoint++; | |
| 144631 | + pNew = pCur->aPoint + i; | |
| 144632 | + pNew->rScore = rScore; | |
| 144633 | + pNew->iLevel = iLevel; | |
| 144634 | + assert( iLevel>=0 && iLevel<=RTREE_MAX_DEPTH ); | |
| 144635 | + while( i>0 ){ | |
| 144636 | + RtreeSearchPoint *pParent; | |
| 144637 | + j = (i-1)/2; | |
| 144638 | + pParent = pCur->aPoint + j; | |
| 144639 | + if( rtreeSearchPointCompare(pNew, pParent)>=0 ) break; | |
| 144640 | + rtreeSearchPointSwap(pCur, j, i); | |
| 144641 | + i = j; | |
| 144642 | + pNew = pParent; | |
| 144643 | + } | |
| 144644 | + return pNew; | |
| 144645 | +} | |
| 144646 | + | |
| 144647 | +/* | |
| 144648 | +** Allocate a new RtreeSearchPoint and return a pointer to it. Return | |
| 144649 | +** NULL if malloc fails. | |
| 144650 | +*/ | |
| 144651 | +static RtreeSearchPoint *rtreeSearchPointNew( | |
| 144652 | + RtreeCursor *pCur, /* The cursor */ | |
| 144653 | + RtreeDValue rScore, /* Score for the new search point */ | |
| 144654 | + u8 iLevel /* Level for the new search point */ | |
| 144655 | +){ | |
| 144656 | + RtreeSearchPoint *pNew, *pFirst; | |
| 144657 | + pFirst = rtreeSearchPointFirst(pCur); | |
| 144658 | + pCur->anQueue[iLevel]++; | |
| 144659 | + if( pFirst==0 | |
| 144660 | + || pFirst->rScore>rScore | |
| 144661 | + || (pFirst->rScore==rScore && pFirst->iLevel>iLevel) | |
| 144662 | + ){ | |
| 144663 | + if( pCur->bPoint ){ | |
| 144664 | + int ii; | |
| 144665 | + pNew = rtreeEnqueue(pCur, rScore, iLevel); | |
| 144666 | + if( pNew==0 ) return 0; | |
| 144667 | + ii = (int)(pNew - pCur->aPoint) + 1; | |
| 144668 | + if( ii<RTREE_CACHE_SZ ){ | |
| 144669 | + assert( pCur->aNode[ii]==0 ); | |
| 144670 | + pCur->aNode[ii] = pCur->aNode[0]; | |
| 144671 | + }else{ | |
| 144672 | + nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]); | |
| 144673 | + } | |
| 144674 | + pCur->aNode[0] = 0; | |
| 144675 | + *pNew = pCur->sPoint; | |
| 144676 | + } | |
| 144677 | + pCur->sPoint.rScore = rScore; | |
| 144678 | + pCur->sPoint.iLevel = iLevel; | |
| 144679 | + pCur->bPoint = 1; | |
| 144680 | + return &pCur->sPoint; | |
| 144681 | + }else{ | |
| 144682 | + return rtreeEnqueue(pCur, rScore, iLevel); | |
| 144683 | + } | |
| 144684 | +} | |
| 144685 | + | |
| 144686 | +#if 0 | |
| 144687 | +/* Tracing routines for the RtreeSearchPoint queue */ | |
| 144688 | +static void tracePoint(RtreeSearchPoint *p, int idx, RtreeCursor *pCur){ | |
| 144689 | + if( idx<0 ){ printf(" s"); }else{ printf("%2d", idx); } | |
| 144690 | + printf(" %d.%05lld.%02d %g %d", | |
| 144691 | + p->iLevel, p->id, p->iCell, p->rScore, p->eWithin | |
| 144692 | + ); | |
| 144693 | + idx++; | |
| 144694 | + if( idx<RTREE_CACHE_SZ ){ | |
| 144695 | + printf(" %p\n", pCur->aNode[idx]); | |
| 144696 | + }else{ | |
| 144697 | + printf("\n"); | |
| 144698 | + } | |
| 144699 | +} | |
| 144700 | +static void traceQueue(RtreeCursor *pCur, const char *zPrefix){ | |
| 144701 | + int ii; | |
| 144702 | + printf("=== %9s ", zPrefix); | |
| 144703 | + if( pCur->bPoint ){ | |
| 144704 | + tracePoint(&pCur->sPoint, -1, pCur); | |
| 144705 | + } | |
| 144706 | + for(ii=0; ii<pCur->nPoint; ii++){ | |
| 144707 | + if( ii>0 || pCur->bPoint ) printf(" "); | |
| 144708 | + tracePoint(&pCur->aPoint[ii], ii, pCur); | |
| 144709 | + } | |
| 144710 | +} | |
| 144711 | +# define RTREE_QUEUE_TRACE(A,B) traceQueue(A,B) | |
| 144712 | +#else | |
| 144713 | +# define RTREE_QUEUE_TRACE(A,B) /* no-op */ | |
| 144714 | +#endif | |
| 144715 | + | |
| 144716 | +/* Remove the search point with the lowest current score. | |
| 144717 | +*/ | |
| 144718 | +static void rtreeSearchPointPop(RtreeCursor *p){ | |
| 144719 | + int i, j, k, n; | |
| 144720 | + i = 1 - p->bPoint; | |
| 144721 | + assert( i==0 || i==1 ); | |
| 144722 | + if( p->aNode[i] ){ | |
| 144723 | + nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); | |
| 144724 | + p->aNode[i] = 0; | |
| 144725 | + } | |
| 144726 | + if( p->bPoint ){ | |
| 144727 | + p->anQueue[p->sPoint.iLevel]--; | |
| 144728 | + p->bPoint = 0; | |
| 144729 | + }else if( p->nPoint ){ | |
| 144730 | + p->anQueue[p->aPoint[0].iLevel]--; | |
| 144731 | + n = --p->nPoint; | |
| 144732 | + p->aPoint[0] = p->aPoint[n]; | |
| 144733 | + if( n<RTREE_CACHE_SZ-1 ){ | |
| 144734 | + p->aNode[1] = p->aNode[n+1]; | |
| 144735 | + p->aNode[n+1] = 0; | |
| 144736 | + } | |
| 144737 | + i = 0; | |
| 144738 | + while( (j = i*2+1)<n ){ | |
| 144739 | + k = j+1; | |
| 144740 | + if( k<n && rtreeSearchPointCompare(&p->aPoint[k], &p->aPoint[j])<0 ){ | |
| 144741 | + if( rtreeSearchPointCompare(&p->aPoint[k], &p->aPoint[i])<0 ){ | |
| 144742 | + rtreeSearchPointSwap(p, i, k); | |
| 144743 | + i = k; | |
| 144744 | + }else{ | |
| 144745 | + break; | |
| 144746 | + } | |
| 144747 | + }else{ | |
| 144748 | + if( rtreeSearchPointCompare(&p->aPoint[j], &p->aPoint[i])<0 ){ | |
| 144749 | + rtreeSearchPointSwap(p, i, j); | |
| 144750 | + i = j; | |
| 144751 | + }else{ | |
| 144752 | + break; | |
| 144753 | + } | |
| 144754 | + } | |
| 144755 | + } | |
| 144756 | + } | |
| 144757 | +} | |
| 144758 | + | |
| 144759 | + | |
| 144760 | +/* | |
| 144761 | +** Continue the search on cursor pCur until the front of the queue | |
| 144762 | +** contains an entry suitable for returning as a result-set row, | |
| 144763 | +** or until the RtreeSearchPoint queue is empty, indicating that the | |
| 144764 | +** query has completed. | |
| 144765 | +*/ | |
| 144766 | +static int rtreeStepToLeaf(RtreeCursor *pCur){ | |
| 144767 | + RtreeSearchPoint *p; | |
| 144768 | + Rtree *pRtree = RTREE_OF_CURSOR(pCur); | |
| 144769 | + RtreeNode *pNode; | |
| 144770 | + int eWithin; | |
| 144771 | + int rc = SQLITE_OK; | |
| 144772 | + int nCell; | |
| 144773 | + int nConstraint = pCur->nConstraint; | |
| 144774 | + int ii; | |
| 144775 | + int eInt; | |
| 144776 | + RtreeSearchPoint x; | |
| 144777 | + | |
| 144778 | + eInt = pRtree->eCoordType==RTREE_COORD_INT32; | |
| 144779 | + while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){ | |
| 144780 | + pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc); | |
| 144781 | + if( rc ) return rc; | |
| 144782 | + nCell = NCELL(pNode); | |
| 144783 | + assert( nCell<200 ); | |
| 144784 | + while( p->iCell<nCell ){ | |
| 144785 | + sqlite3_rtree_dbl rScore = (sqlite3_rtree_dbl)-1; | |
| 144786 | + u8 *pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell); | |
| 144787 | + eWithin = FULLY_WITHIN; | |
| 144788 | + for(ii=0; ii<nConstraint; ii++){ | |
| 144789 | + RtreeConstraint *pConstraint = pCur->aConstraint + ii; | |
| 144790 | + if( pConstraint->op>=RTREE_MATCH ){ | |
| 144791 | + rc = rtreeCallbackConstraint(pConstraint, eInt, pCellData, p, | |
| 144792 | + &rScore, &eWithin); | |
| 144793 | + if( rc ) return rc; | |
| 144794 | + }else if( p->iLevel==1 ){ | |
| 144795 | + rtreeLeafConstraint(pConstraint, eInt, pCellData, &eWithin); | |
| 144796 | + }else{ | |
| 144797 | + rtreeNonleafConstraint(pConstraint, eInt, pCellData, &eWithin); | |
| 144798 | + } | |
| 144799 | + if( eWithin==NOT_WITHIN ) break; | |
| 144800 | + } | |
| 144801 | + p->iCell++; | |
| 144802 | + if( eWithin==NOT_WITHIN ) continue; | |
| 144803 | + x.iLevel = p->iLevel - 1; | |
| 144804 | + if( x.iLevel ){ | |
| 144805 | + x.id = readInt64(pCellData); | |
| 144806 | + x.iCell = 0; | |
| 144807 | + }else{ | |
| 144808 | + x.id = p->id; | |
| 144809 | + x.iCell = p->iCell - 1; | |
| 144810 | + } | |
| 144811 | + if( p->iCell>=nCell ){ | |
| 144812 | + RTREE_QUEUE_TRACE(pCur, "POP-S:"); | |
| 144813 | + rtreeSearchPointPop(pCur); | |
| 144814 | + } | |
| 144815 | + if( rScore<RTREE_ZERO ) rScore = RTREE_ZERO; | |
| 144816 | + p = rtreeSearchPointNew(pCur, rScore, x.iLevel); | |
| 144817 | + if( p==0 ) return SQLITE_NOMEM; | |
| 144818 | + p->eWithin = eWithin; | |
| 144819 | + p->id = x.id; | |
| 144820 | + p->iCell = x.iCell; | |
| 144821 | + RTREE_QUEUE_TRACE(pCur, "PUSH-S:"); | |
| 144822 | + break; | |
| 144823 | + } | |
| 144824 | + if( p->iCell>=nCell ){ | |
| 144825 | + RTREE_QUEUE_TRACE(pCur, "POP-Se:"); | |
| 144826 | + rtreeSearchPointPop(pCur); | |
| 144827 | + } | |
| 144828 | + } | |
| 144829 | + pCur->atEOF = p==0; | |
| 144830 | + return SQLITE_OK; | |
| 144831 | +} | |
| 143857 | 144832 | |
| 143858 | 144833 | /* |
| 143859 | 144834 | ** Rtree virtual table module xNext method. |
| 143860 | 144835 | */ |
| 143861 | 144836 | static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ |
| 143862 | - Rtree *pRtree = (Rtree *)(pVtabCursor->pVtab); | |
| 143863 | 144837 | RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |
| 143864 | 144838 | int rc = SQLITE_OK; |
| 143865 | 144839 | |
| 143866 | - /* RtreeCursor.pNode must not be NULL. If is is NULL, then this cursor is | |
| 143867 | - ** already at EOF. It is against the rules to call the xNext() method of | |
| 143868 | - ** a cursor that has already reached EOF. | |
| 143869 | - */ | |
| 143870 | - assert( pCsr->pNode ); | |
| 143871 | - | |
| 143872 | - if( pCsr->iStrategy==1 ){ | |
| 143873 | - /* This "scan" is a direct lookup by rowid. There is no next entry. */ | |
| 143874 | - nodeRelease(pRtree, pCsr->pNode); | |
| 143875 | - pCsr->pNode = 0; | |
| 143876 | - }else{ | |
| 143877 | - /* Move to the next entry that matches the configured constraints. */ | |
| 143878 | - int iHeight = 0; | |
| 143879 | - while( pCsr->pNode ){ | |
| 143880 | - RtreeNode *pNode = pCsr->pNode; | |
| 143881 | - int nCell = NCELL(pNode); | |
| 143882 | - for(pCsr->iCell++; pCsr->iCell<nCell; pCsr->iCell++){ | |
| 143883 | - int isEof; | |
| 143884 | - rc = descendToCell(pRtree, pCsr, iHeight, &isEof); | |
| 143885 | - if( rc!=SQLITE_OK || !isEof ){ | |
| 143886 | - return rc; | |
| 143887 | - } | |
| 143888 | - } | |
| 143889 | - pCsr->pNode = pNode->pParent; | |
| 143890 | - rc = nodeParentIndex(pRtree, pNode, &pCsr->iCell); | |
| 143891 | - if( rc!=SQLITE_OK ){ | |
| 143892 | - return rc; | |
| 143893 | - } | |
| 143894 | - nodeReference(pCsr->pNode); | |
| 143895 | - nodeRelease(pRtree, pNode); | |
| 143896 | - iHeight++; | |
| 143897 | - } | |
| 143898 | - } | |
| 143899 | - | |
| 144840 | + /* Move to the next entry that matches the configured constraints. */ | |
| 144841 | + RTREE_QUEUE_TRACE(pCsr, "POP-Nx:"); | |
| 144842 | + rtreeSearchPointPop(pCsr); | |
| 144843 | + rc = rtreeStepToLeaf(pCsr); | |
| 143900 | 144844 | return rc; |
| 143901 | 144845 | } |
| 143902 | 144846 | |
| 143903 | 144847 | /* |
| 143904 | 144848 | ** Rtree virtual table module xRowid method. |
| 143905 | 144849 | */ |
| 143906 | 144850 | static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ |
| 143907 | - Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; | |
| 143908 | 144851 | RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |
| 143909 | - | |
| 143910 | - assert(pCsr->pNode); | |
| 143911 | - *pRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell); | |
| 143912 | - | |
| 143913 | - return SQLITE_OK; | |
| 144852 | + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); | |
| 144853 | + int rc = SQLITE_OK; | |
| 144854 | + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); | |
| 144855 | + if( rc==SQLITE_OK && p ){ | |
| 144856 | + *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); | |
| 144857 | + } | |
| 144858 | + return rc; | |
| 143914 | 144859 | } |
| 143915 | 144860 | |
| 143916 | 144861 | /* |
| 143917 | 144862 | ** Rtree virtual table module xColumn method. |
| 143918 | 144863 | */ |
| 143919 | 144864 | static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ |
| 143920 | 144865 | Rtree *pRtree = (Rtree *)cur->pVtab; |
| 143921 | 144866 | RtreeCursor *pCsr = (RtreeCursor *)cur; |
| 144867 | + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); | |
| 144868 | + RtreeCoord c; | |
| 144869 | + int rc = SQLITE_OK; | |
| 144870 | + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); | |
| 143922 | 144871 | |
| 144872 | + if( rc ) return rc; | |
| 144873 | + if( p==0 ) return SQLITE_OK; | |
| 143923 | 144874 | if( i==0 ){ |
| 143924 | - i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell); | |
| 143925 | - sqlite3_result_int64(ctx, iRowid); | |
| 144875 | + sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); | |
| 143926 | 144876 | }else{ |
| 143927 | - RtreeCoord c; | |
| 143928 | - nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c); | |
| 144877 | + if( rc ) return rc; | |
| 144878 | + nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c); | |
| 143929 | 144879 | #ifndef SQLITE_RTREE_INT_ONLY |
| 143930 | 144880 | if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ |
| 143931 | 144881 | sqlite3_result_double(ctx, c.f); |
| 143932 | 144882 | }else |
| 143933 | 144883 | #endif |
| @@ -143934,11 +144884,10 @@ | ||
| 143934 | 144884 | { |
| 143935 | 144885 | assert( pRtree->eCoordType==RTREE_COORD_INT32 ); |
| 143936 | 144886 | sqlite3_result_int(ctx, c.i); |
| 143937 | 144887 | } |
| 143938 | 144888 | } |
| 143939 | - | |
| 143940 | 144889 | return SQLITE_OK; |
| 143941 | 144890 | } |
| 143942 | 144891 | |
| 143943 | 144892 | /* |
| 143944 | 144893 | ** Use nodeAcquire() to obtain the leaf node containing the record with |
| @@ -143945,16 +144894,22 @@ | ||
| 143945 | 144894 | ** rowid iRowid. If successful, set *ppLeaf to point to the node and |
| 143946 | 144895 | ** return SQLITE_OK. If there is no such record in the table, set |
| 143947 | 144896 | ** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf |
| 143948 | 144897 | ** to zero and return an SQLite error code. |
| 143949 | 144898 | */ |
| 143950 | -static int findLeafNode(Rtree *pRtree, i64 iRowid, RtreeNode **ppLeaf){ | |
| 144899 | +static int findLeafNode( | |
| 144900 | + Rtree *pRtree, /* RTree to search */ | |
| 144901 | + i64 iRowid, /* The rowid searching for */ | |
| 144902 | + RtreeNode **ppLeaf, /* Write the node here */ | |
| 144903 | + sqlite3_int64 *piNode /* Write the node-id here */ | |
| 144904 | +){ | |
| 143951 | 144905 | int rc; |
| 143952 | 144906 | *ppLeaf = 0; |
| 143953 | 144907 | sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid); |
| 143954 | 144908 | if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){ |
| 143955 | 144909 | i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0); |
| 144910 | + if( piNode ) *piNode = iNode; | |
| 143956 | 144911 | rc = nodeAcquire(pRtree, iNode, 0, ppLeaf); |
| 143957 | 144912 | sqlite3_reset(pRtree->pReadRowid); |
| 143958 | 144913 | }else{ |
| 143959 | 144914 | rc = sqlite3_reset(pRtree->pReadRowid); |
| 143960 | 144915 | } |
| @@ -143966,13 +144921,14 @@ | ||
| 143966 | 144921 | ** as the second argument for a MATCH constraint. The value passed as the |
| 143967 | 144922 | ** first argument to this function is the right-hand operand to the MATCH |
| 143968 | 144923 | ** operator. |
| 143969 | 144924 | */ |
| 143970 | 144925 | static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ |
| 143971 | - RtreeMatchArg *p; | |
| 143972 | - sqlite3_rtree_geometry *pGeom; | |
| 143973 | - int nBlob; | |
| 144926 | + RtreeMatchArg *pBlob; /* BLOB returned by geometry function */ | |
| 144927 | + sqlite3_rtree_query_info *pInfo; /* Callback information */ | |
| 144928 | + int nBlob; /* Size of the geometry function blob */ | |
| 144929 | + int nExpected; /* Expected size of the BLOB */ | |
| 143974 | 144930 | |
| 143975 | 144931 | /* Check that value is actually a blob. */ |
| 143976 | 144932 | if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR; |
| 143977 | 144933 | |
| 143978 | 144934 | /* Check that the blob is roughly the right size. */ |
| @@ -143981,31 +144937,33 @@ | ||
| 143981 | 144937 | || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0 |
| 143982 | 144938 | ){ |
| 143983 | 144939 | return SQLITE_ERROR; |
| 143984 | 144940 | } |
| 143985 | 144941 | |
| 143986 | - pGeom = (sqlite3_rtree_geometry *)sqlite3_malloc( | |
| 143987 | - sizeof(sqlite3_rtree_geometry) + nBlob | |
| 143988 | - ); | |
| 143989 | - if( !pGeom ) return SQLITE_NOMEM; | |
| 143990 | - memset(pGeom, 0, sizeof(sqlite3_rtree_geometry)); | |
| 143991 | - p = (RtreeMatchArg *)&pGeom[1]; | |
| 143992 | - | |
| 143993 | - memcpy(p, sqlite3_value_blob(pValue), nBlob); | |
| 143994 | - if( p->magic!=RTREE_GEOMETRY_MAGIC | |
| 143995 | - || nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(RtreeDValue)) | |
| 143996 | - ){ | |
| 143997 | - sqlite3_free(pGeom); | |
| 144942 | + pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob ); | |
| 144943 | + if( !pInfo ) return SQLITE_NOMEM; | |
| 144944 | + memset(pInfo, 0, sizeof(*pInfo)); | |
| 144945 | + pBlob = (RtreeMatchArg*)&pInfo[1]; | |
| 144946 | + | |
| 144947 | + memcpy(pBlob, sqlite3_value_blob(pValue), nBlob); | |
| 144948 | + nExpected = (int)(sizeof(RtreeMatchArg) + | |
| 144949 | + (pBlob->nParam-1)*sizeof(RtreeDValue)); | |
| 144950 | + if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){ | |
| 144951 | + sqlite3_free(pInfo); | |
| 143998 | 144952 | return SQLITE_ERROR; |
| 143999 | 144953 | } |
| 144954 | + pInfo->pContext = pBlob->cb.pContext; | |
| 144955 | + pInfo->nParam = pBlob->nParam; | |
| 144956 | + pInfo->aParam = pBlob->aParam; | |
| 144000 | 144957 | |
| 144001 | - pGeom->pContext = p->pContext; | |
| 144002 | - pGeom->nParam = p->nParam; | |
| 144003 | - pGeom->aParam = p->aParam; | |
| 144004 | - | |
| 144005 | - pCons->xGeom = p->xGeom; | |
| 144006 | - pCons->pGeom = pGeom; | |
| 144958 | + if( pBlob->cb.xGeom ){ | |
| 144959 | + pCons->u.xGeom = pBlob->cb.xGeom; | |
| 144960 | + }else{ | |
| 144961 | + pCons->op = RTREE_QUERY; | |
| 144962 | + pCons->u.xQueryFunc = pBlob->cb.xQueryFunc; | |
| 144963 | + } | |
| 144964 | + pCons->pInfo = pInfo; | |
| 144007 | 144965 | return SQLITE_OK; |
| 144008 | 144966 | } |
| 144009 | 144967 | |
| 144010 | 144968 | /* |
| 144011 | 144969 | ** Rtree virtual table module xFilter method. |
| @@ -144015,91 +144973,96 @@ | ||
| 144015 | 144973 | int idxNum, const char *idxStr, |
| 144016 | 144974 | int argc, sqlite3_value **argv |
| 144017 | 144975 | ){ |
| 144018 | 144976 | Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; |
| 144019 | 144977 | RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |
| 144020 | - | |
| 144021 | 144978 | RtreeNode *pRoot = 0; |
| 144022 | 144979 | int ii; |
| 144023 | 144980 | int rc = SQLITE_OK; |
| 144981 | + int iCell = 0; | |
| 144024 | 144982 | |
| 144025 | 144983 | rtreeReference(pRtree); |
| 144026 | 144984 | |
| 144027 | 144985 | freeCursorConstraints(pCsr); |
| 144028 | 144986 | pCsr->iStrategy = idxNum; |
| 144029 | 144987 | |
| 144030 | 144988 | if( idxNum==1 ){ |
| 144031 | 144989 | /* Special case - lookup by rowid. */ |
| 144032 | 144990 | RtreeNode *pLeaf; /* Leaf on which the required cell resides */ |
| 144991 | + RtreeSearchPoint *p; /* Search point for the the leaf */ | |
| 144033 | 144992 | i64 iRowid = sqlite3_value_int64(argv[0]); |
| 144034 | - rc = findLeafNode(pRtree, iRowid, &pLeaf); | |
| 144035 | - pCsr->pNode = pLeaf; | |
| 144036 | - if( pLeaf ){ | |
| 144037 | - assert( rc==SQLITE_OK ); | |
| 144038 | - rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &pCsr->iCell); | |
| 144993 | + i64 iNode = 0; | |
| 144994 | + rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); | |
| 144995 | + if( rc==SQLITE_OK && pLeaf!=0 ){ | |
| 144996 | + p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); | |
| 144997 | + assert( p!=0 ); /* Always returns pCsr->sPoint */ | |
| 144998 | + pCsr->aNode[0] = pLeaf; | |
| 144999 | + p->id = iNode; | |
| 145000 | + p->eWithin = PARTLY_WITHIN; | |
| 145001 | + rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); | |
| 145002 | + p->iCell = iCell; | |
| 145003 | + RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); | |
| 145004 | + }else{ | |
| 145005 | + pCsr->atEOF = 1; | |
| 144039 | 145006 | } |
| 144040 | 145007 | }else{ |
| 144041 | 145008 | /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array |
| 144042 | 145009 | ** with the configured constraints. |
| 144043 | 145010 | */ |
| 144044 | - if( argc>0 ){ | |
| 145011 | + rc = nodeAcquire(pRtree, 1, 0, &pRoot); | |
| 145012 | + if( rc==SQLITE_OK && argc>0 ){ | |
| 144045 | 145013 | pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc); |
| 144046 | 145014 | pCsr->nConstraint = argc; |
| 144047 | 145015 | if( !pCsr->aConstraint ){ |
| 144048 | 145016 | rc = SQLITE_NOMEM; |
| 144049 | 145017 | }else{ |
| 144050 | 145018 | memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc); |
| 145019 | + memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1)); | |
| 144051 | 145020 | assert( (idxStr==0 && argc==0) |
| 144052 | 145021 | || (idxStr && (int)strlen(idxStr)==argc*2) ); |
| 144053 | 145022 | for(ii=0; ii<argc; ii++){ |
| 144054 | 145023 | RtreeConstraint *p = &pCsr->aConstraint[ii]; |
| 144055 | 145024 | p->op = idxStr[ii*2]; |
| 144056 | - p->iCoord = idxStr[ii*2+1]-'a'; | |
| 144057 | - if( p->op==RTREE_MATCH ){ | |
| 145025 | + p->iCoord = idxStr[ii*2+1]-'0'; | |
| 145026 | + if( p->op>=RTREE_MATCH ){ | |
| 144058 | 145027 | /* A MATCH operator. The right-hand-side must be a blob that |
| 144059 | 145028 | ** can be cast into an RtreeMatchArg object. One created using |
| 144060 | 145029 | ** an sqlite3_rtree_geometry_callback() SQL user function. |
| 144061 | 145030 | */ |
| 144062 | 145031 | rc = deserializeGeometry(argv[ii], p); |
| 144063 | 145032 | if( rc!=SQLITE_OK ){ |
| 144064 | 145033 | break; |
| 144065 | 145034 | } |
| 145035 | + p->pInfo->nCoord = pRtree->nDim*2; | |
| 145036 | + p->pInfo->anQueue = pCsr->anQueue; | |
| 145037 | + p->pInfo->mxLevel = pRtree->iDepth + 1; | |
| 144066 | 145038 | }else{ |
| 144067 | 145039 | #ifdef SQLITE_RTREE_INT_ONLY |
| 144068 | - p->rValue = sqlite3_value_int64(argv[ii]); | |
| 145040 | + p->u.rValue = sqlite3_value_int64(argv[ii]); | |
| 144069 | 145041 | #else |
| 144070 | - p->rValue = sqlite3_value_double(argv[ii]); | |
| 145042 | + p->u.rValue = sqlite3_value_double(argv[ii]); | |
| 144071 | 145043 | #endif |
| 144072 | 145044 | } |
| 144073 | 145045 | } |
| 144074 | 145046 | } |
| 144075 | 145047 | } |
| 144076 | - | |
| 144077 | - if( rc==SQLITE_OK ){ | |
| 144078 | - pCsr->pNode = 0; | |
| 144079 | - rc = nodeAcquire(pRtree, 1, 0, &pRoot); | |
| 144080 | - } | |
| 144081 | - if( rc==SQLITE_OK ){ | |
| 144082 | - int isEof = 1; | |
| 144083 | - int nCell = NCELL(pRoot); | |
| 144084 | - pCsr->pNode = pRoot; | |
| 144085 | - for(pCsr->iCell=0; rc==SQLITE_OK && pCsr->iCell<nCell; pCsr->iCell++){ | |
| 144086 | - assert( pCsr->pNode==pRoot ); | |
| 144087 | - rc = descendToCell(pRtree, pCsr, pRtree->iDepth, &isEof); | |
| 144088 | - if( !isEof ){ | |
| 144089 | - break; | |
| 144090 | - } | |
| 144091 | - } | |
| 144092 | - if( rc==SQLITE_OK && isEof ){ | |
| 144093 | - assert( pCsr->pNode==pRoot ); | |
| 144094 | - nodeRelease(pRtree, pRoot); | |
| 144095 | - pCsr->pNode = 0; | |
| 144096 | - } | |
| 144097 | - assert( rc!=SQLITE_OK || !pCsr->pNode || pCsr->iCell<NCELL(pCsr->pNode) ); | |
| 144098 | - } | |
| 144099 | - } | |
| 144100 | - | |
| 145048 | + if( rc==SQLITE_OK ){ | |
| 145049 | + RtreeSearchPoint *pNew; | |
| 145050 | + pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, pRtree->iDepth+1); | |
| 145051 | + if( pNew==0 ) return SQLITE_NOMEM; | |
| 145052 | + pNew->id = 1; | |
| 145053 | + pNew->iCell = 0; | |
| 145054 | + pNew->eWithin = PARTLY_WITHIN; | |
| 145055 | + assert( pCsr->bPoint==1 ); | |
| 145056 | + pCsr->aNode[0] = pRoot; | |
| 145057 | + pRoot = 0; | |
| 145058 | + RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); | |
| 145059 | + rc = rtreeStepToLeaf(pCsr); | |
| 145060 | + } | |
| 145061 | + } | |
| 145062 | + | |
| 145063 | + nodeRelease(pRtree, pRoot); | |
| 144101 | 145064 | rtreeRelease(pRtree); |
| 144102 | 145065 | return rc; |
| 144103 | 145066 | } |
| 144104 | 145067 | |
| 144105 | 145068 | /* |
| @@ -144197,11 +145160,11 @@ | ||
| 144197 | 145160 | assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH ); |
| 144198 | 145161 | op = RTREE_MATCH; |
| 144199 | 145162 | break; |
| 144200 | 145163 | } |
| 144201 | 145164 | zIdxStr[iIdx++] = op; |
| 144202 | - zIdxStr[iIdx++] = p->iColumn - 1 + 'a'; | |
| 145165 | + zIdxStr[iIdx++] = p->iColumn - 1 + '0'; | |
| 144203 | 145166 | pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); |
| 144204 | 145167 | pIdxInfo->aConstraintUsage[ii].omit = 1; |
| 144205 | 145168 | } |
| 144206 | 145169 | } |
| 144207 | 145170 | |
| @@ -144290,66 +145253,36 @@ | ||
| 144290 | 145253 | area = cellArea(pRtree, &cell); |
| 144291 | 145254 | cellUnion(pRtree, &cell, pCell); |
| 144292 | 145255 | return (cellArea(pRtree, &cell)-area); |
| 144293 | 145256 | } |
| 144294 | 145257 | |
| 144295 | -#if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT | |
| 144296 | 145258 | static RtreeDValue cellOverlap( |
| 144297 | 145259 | Rtree *pRtree, |
| 144298 | 145260 | RtreeCell *p, |
| 144299 | 145261 | RtreeCell *aCell, |
| 144300 | - int nCell, | |
| 144301 | - int iExclude | |
| 145262 | + int nCell | |
| 144302 | 145263 | ){ |
| 144303 | 145264 | int ii; |
| 144304 | - RtreeDValue overlap = 0.0; | |
| 145265 | + RtreeDValue overlap = RTREE_ZERO; | |
| 144305 | 145266 | for(ii=0; ii<nCell; ii++){ |
| 144306 | -#if VARIANT_RSTARTREE_CHOOSESUBTREE | |
| 144307 | - if( ii!=iExclude ) | |
| 144308 | -#else | |
| 144309 | - assert( iExclude==-1 ); | |
| 144310 | - UNUSED_PARAMETER(iExclude); | |
| 144311 | -#endif | |
| 144312 | - { | |
| 144313 | - int jj; | |
| 144314 | - RtreeDValue o = (RtreeDValue)1; | |
| 144315 | - for(jj=0; jj<(pRtree->nDim*2); jj+=2){ | |
| 144316 | - RtreeDValue x1, x2; | |
| 144317 | - | |
| 144318 | - x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); | |
| 144319 | - x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); | |
| 144320 | - | |
| 144321 | - if( x2<x1 ){ | |
| 144322 | - o = 0.0; | |
| 144323 | - break; | |
| 144324 | - }else{ | |
| 144325 | - o = o * (x2-x1); | |
| 144326 | - } | |
| 144327 | - } | |
| 144328 | - overlap += o; | |
| 144329 | - } | |
| 145267 | + int jj; | |
| 145268 | + RtreeDValue o = (RtreeDValue)1; | |
| 145269 | + for(jj=0; jj<(pRtree->nDim*2); jj+=2){ | |
| 145270 | + RtreeDValue x1, x2; | |
| 145271 | + x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); | |
| 145272 | + x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); | |
| 145273 | + if( x2<x1 ){ | |
| 145274 | + o = (RtreeDValue)0; | |
| 145275 | + break; | |
| 145276 | + }else{ | |
| 145277 | + o = o * (x2-x1); | |
| 145278 | + } | |
| 145279 | + } | |
| 145280 | + overlap += o; | |
| 144330 | 145281 | } |
| 144331 | 145282 | return overlap; |
| 144332 | 145283 | } |
| 144333 | -#endif | |
| 144334 | - | |
| 144335 | -#if VARIANT_RSTARTREE_CHOOSESUBTREE | |
| 144336 | -static RtreeDValue cellOverlapEnlargement( | |
| 144337 | - Rtree *pRtree, | |
| 144338 | - RtreeCell *p, | |
| 144339 | - RtreeCell *pInsert, | |
| 144340 | - RtreeCell *aCell, | |
| 144341 | - int nCell, | |
| 144342 | - int iExclude | |
| 144343 | -){ | |
| 144344 | - RtreeDValue before, after; | |
| 144345 | - before = cellOverlap(pRtree, p, aCell, nCell, iExclude); | |
| 144346 | - cellUnion(pRtree, p, pInsert); | |
| 144347 | - after = cellOverlap(pRtree, p, aCell, nCell, iExclude); | |
| 144348 | - return (after-before); | |
| 144349 | -} | |
| 144350 | -#endif | |
| 144351 | 145284 | |
| 144352 | 145285 | |
| 144353 | 145286 | /* |
| 144354 | 145287 | ** This function implements the ChooseLeaf algorithm from Gutman[84]. |
| 144355 | 145288 | ** ChooseSubTree in r*tree terminology. |
| @@ -144367,39 +145300,19 @@ | ||
| 144367 | 145300 | |
| 144368 | 145301 | for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ |
| 144369 | 145302 | int iCell; |
| 144370 | 145303 | sqlite3_int64 iBest = 0; |
| 144371 | 145304 | |
| 144372 | - RtreeDValue fMinGrowth = 0.0; | |
| 144373 | - RtreeDValue fMinArea = 0.0; | |
| 144374 | -#if VARIANT_RSTARTREE_CHOOSESUBTREE | |
| 144375 | - RtreeDValue fMinOverlap = 0.0; | |
| 144376 | - RtreeDValue overlap; | |
| 144377 | -#endif | |
| 145305 | + RtreeDValue fMinGrowth = RTREE_ZERO; | |
| 145306 | + RtreeDValue fMinArea = RTREE_ZERO; | |
| 144378 | 145307 | |
| 144379 | 145308 | int nCell = NCELL(pNode); |
| 144380 | 145309 | RtreeCell cell; |
| 144381 | 145310 | RtreeNode *pChild; |
| 144382 | 145311 | |
| 144383 | 145312 | RtreeCell *aCell = 0; |
| 144384 | 145313 | |
| 144385 | -#if VARIANT_RSTARTREE_CHOOSESUBTREE | |
| 144386 | - if( ii==(pRtree->iDepth-1) ){ | |
| 144387 | - int jj; | |
| 144388 | - aCell = sqlite3_malloc(sizeof(RtreeCell)*nCell); | |
| 144389 | - if( !aCell ){ | |
| 144390 | - rc = SQLITE_NOMEM; | |
| 144391 | - nodeRelease(pRtree, pNode); | |
| 144392 | - pNode = 0; | |
| 144393 | - continue; | |
| 144394 | - } | |
| 144395 | - for(jj=0; jj<nCell; jj++){ | |
| 144396 | - nodeGetCell(pRtree, pNode, jj, &aCell[jj]); | |
| 144397 | - } | |
| 144398 | - } | |
| 144399 | -#endif | |
| 144400 | - | |
| 144401 | 145314 | /* Select the child node which will be enlarged the least if pCell |
| 144402 | 145315 | ** is inserted into it. Resolve ties by choosing the entry with |
| 144403 | 145316 | ** the smallest area. |
| 144404 | 145317 | */ |
| 144405 | 145318 | for(iCell=0; iCell<nCell; iCell++){ |
| @@ -144407,30 +145320,13 @@ | ||
| 144407 | 145320 | RtreeDValue growth; |
| 144408 | 145321 | RtreeDValue area; |
| 144409 | 145322 | nodeGetCell(pRtree, pNode, iCell, &cell); |
| 144410 | 145323 | growth = cellGrowth(pRtree, &cell, pCell); |
| 144411 | 145324 | area = cellArea(pRtree, &cell); |
| 144412 | - | |
| 144413 | -#if VARIANT_RSTARTREE_CHOOSESUBTREE | |
| 144414 | - if( ii==(pRtree->iDepth-1) ){ | |
| 144415 | - overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell); | |
| 144416 | - }else{ | |
| 144417 | - overlap = 0.0; | |
| 144418 | - } | |
| 144419 | - if( (iCell==0) | |
| 144420 | - || (overlap<fMinOverlap) | |
| 144421 | - || (overlap==fMinOverlap && growth<fMinGrowth) | |
| 144422 | - || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea) | |
| 144423 | - ){ | |
| 144424 | - bBest = 1; | |
| 144425 | - fMinOverlap = overlap; | |
| 144426 | - } | |
| 144427 | -#else | |
| 144428 | 145325 | if( iCell==0||growth<fMinGrowth||(growth==fMinGrowth && area<fMinArea) ){ |
| 144429 | 145326 | bBest = 1; |
| 144430 | 145327 | } |
| 144431 | -#endif | |
| 144432 | 145328 | if( bBest ){ |
| 144433 | 145329 | fMinGrowth = growth; |
| 144434 | 145330 | fMinArea = area; |
| 144435 | 145331 | iBest = cell.iRowid; |
| 144436 | 145332 | } |
| @@ -144497,159 +145393,10 @@ | ||
| 144497 | 145393 | return sqlite3_reset(pRtree->pWriteParent); |
| 144498 | 145394 | } |
| 144499 | 145395 | |
| 144500 | 145396 | static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int); |
| 144501 | 145397 | |
| 144502 | -#if VARIANT_GUTTMAN_LINEAR_SPLIT | |
| 144503 | -/* | |
| 144504 | -** Implementation of the linear variant of the PickNext() function from | |
| 144505 | -** Guttman[84]. | |
| 144506 | -*/ | |
| 144507 | -static RtreeCell *LinearPickNext( | |
| 144508 | - Rtree *pRtree, | |
| 144509 | - RtreeCell *aCell, | |
| 144510 | - int nCell, | |
| 144511 | - RtreeCell *pLeftBox, | |
| 144512 | - RtreeCell *pRightBox, | |
| 144513 | - int *aiUsed | |
| 144514 | -){ | |
| 144515 | - int ii; | |
| 144516 | - for(ii=0; aiUsed[ii]; ii++); | |
| 144517 | - aiUsed[ii] = 1; | |
| 144518 | - return &aCell[ii]; | |
| 144519 | -} | |
| 144520 | - | |
| 144521 | -/* | |
| 144522 | -** Implementation of the linear variant of the PickSeeds() function from | |
| 144523 | -** Guttman[84]. | |
| 144524 | -*/ | |
| 144525 | -static void LinearPickSeeds( | |
| 144526 | - Rtree *pRtree, | |
| 144527 | - RtreeCell *aCell, | |
| 144528 | - int nCell, | |
| 144529 | - int *piLeftSeed, | |
| 144530 | - int *piRightSeed | |
| 144531 | -){ | |
| 144532 | - int i; | |
| 144533 | - int iLeftSeed = 0; | |
| 144534 | - int iRightSeed = 1; | |
| 144535 | - RtreeDValue maxNormalInnerWidth = (RtreeDValue)0; | |
| 144536 | - | |
| 144537 | - /* Pick two "seed" cells from the array of cells. The algorithm used | |
| 144538 | - ** here is the LinearPickSeeds algorithm from Gutman[1984]. The | |
| 144539 | - ** indices of the two seed cells in the array are stored in local | |
| 144540 | - ** variables iLeftSeek and iRightSeed. | |
| 144541 | - */ | |
| 144542 | - for(i=0; i<pRtree->nDim; i++){ | |
| 144543 | - RtreeDValue x1 = DCOORD(aCell[0].aCoord[i*2]); | |
| 144544 | - RtreeDValue x2 = DCOORD(aCell[0].aCoord[i*2+1]); | |
| 144545 | - RtreeDValue x3 = x1; | |
| 144546 | - RtreeDValue x4 = x2; | |
| 144547 | - int jj; | |
| 144548 | - | |
| 144549 | - int iCellLeft = 0; | |
| 144550 | - int iCellRight = 0; | |
| 144551 | - | |
| 144552 | - for(jj=1; jj<nCell; jj++){ | |
| 144553 | - RtreeDValue left = DCOORD(aCell[jj].aCoord[i*2]); | |
| 144554 | - RtreeDValue right = DCOORD(aCell[jj].aCoord[i*2+1]); | |
| 144555 | - | |
| 144556 | - if( left<x1 ) x1 = left; | |
| 144557 | - if( right>x4 ) x4 = right; | |
| 144558 | - if( left>x3 ){ | |
| 144559 | - x3 = left; | |
| 144560 | - iCellRight = jj; | |
| 144561 | - } | |
| 144562 | - if( right<x2 ){ | |
| 144563 | - x2 = right; | |
| 144564 | - iCellLeft = jj; | |
| 144565 | - } | |
| 144566 | - } | |
| 144567 | - | |
| 144568 | - if( x4!=x1 ){ | |
| 144569 | - RtreeDValue normalwidth = (x3 - x2) / (x4 - x1); | |
| 144570 | - if( normalwidth>maxNormalInnerWidth ){ | |
| 144571 | - iLeftSeed = iCellLeft; | |
| 144572 | - iRightSeed = iCellRight; | |
| 144573 | - } | |
| 144574 | - } | |
| 144575 | - } | |
| 144576 | - | |
| 144577 | - *piLeftSeed = iLeftSeed; | |
| 144578 | - *piRightSeed = iRightSeed; | |
| 144579 | -} | |
| 144580 | -#endif /* VARIANT_GUTTMAN_LINEAR_SPLIT */ | |
| 144581 | - | |
| 144582 | -#if VARIANT_GUTTMAN_QUADRATIC_SPLIT | |
| 144583 | -/* | |
| 144584 | -** Implementation of the quadratic variant of the PickNext() function from | |
| 144585 | -** Guttman[84]. | |
| 144586 | -*/ | |
| 144587 | -static RtreeCell *QuadraticPickNext( | |
| 144588 | - Rtree *pRtree, | |
| 144589 | - RtreeCell *aCell, | |
| 144590 | - int nCell, | |
| 144591 | - RtreeCell *pLeftBox, | |
| 144592 | - RtreeCell *pRightBox, | |
| 144593 | - int *aiUsed | |
| 144594 | -){ | |
| 144595 | - #define FABS(a) ((a)<0.0?-1.0*(a):(a)) | |
| 144596 | - | |
| 144597 | - int iSelect = -1; | |
| 144598 | - RtreeDValue fDiff; | |
| 144599 | - int ii; | |
| 144600 | - for(ii=0; ii<nCell; ii++){ | |
| 144601 | - if( aiUsed[ii]==0 ){ | |
| 144602 | - RtreeDValue left = cellGrowth(pRtree, pLeftBox, &aCell[ii]); | |
| 144603 | - RtreeDValue right = cellGrowth(pRtree, pLeftBox, &aCell[ii]); | |
| 144604 | - RtreeDValue diff = FABS(right-left); | |
| 144605 | - if( iSelect<0 || diff>fDiff ){ | |
| 144606 | - fDiff = diff; | |
| 144607 | - iSelect = ii; | |
| 144608 | - } | |
| 144609 | - } | |
| 144610 | - } | |
| 144611 | - aiUsed[iSelect] = 1; | |
| 144612 | - return &aCell[iSelect]; | |
| 144613 | -} | |
| 144614 | - | |
| 144615 | -/* | |
| 144616 | -** Implementation of the quadratic variant of the PickSeeds() function from | |
| 144617 | -** Guttman[84]. | |
| 144618 | -*/ | |
| 144619 | -static void QuadraticPickSeeds( | |
| 144620 | - Rtree *pRtree, | |
| 144621 | - RtreeCell *aCell, | |
| 144622 | - int nCell, | |
| 144623 | - int *piLeftSeed, | |
| 144624 | - int *piRightSeed | |
| 144625 | -){ | |
| 144626 | - int ii; | |
| 144627 | - int jj; | |
| 144628 | - | |
| 144629 | - int iLeftSeed = 0; | |
| 144630 | - int iRightSeed = 1; | |
| 144631 | - RtreeDValue fWaste = 0.0; | |
| 144632 | - | |
| 144633 | - for(ii=0; ii<nCell; ii++){ | |
| 144634 | - for(jj=ii+1; jj<nCell; jj++){ | |
| 144635 | - RtreeDValue right = cellArea(pRtree, &aCell[jj]); | |
| 144636 | - RtreeDValue growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]); | |
| 144637 | - RtreeDValue waste = growth - right; | |
| 144638 | - | |
| 144639 | - if( waste>fWaste ){ | |
| 144640 | - iLeftSeed = ii; | |
| 144641 | - iRightSeed = jj; | |
| 144642 | - fWaste = waste; | |
| 144643 | - } | |
| 144644 | - } | |
| 144645 | - } | |
| 144646 | - | |
| 144647 | - *piLeftSeed = iLeftSeed; | |
| 144648 | - *piRightSeed = iRightSeed; | |
| 144649 | -} | |
| 144650 | -#endif /* VARIANT_GUTTMAN_QUADRATIC_SPLIT */ | |
| 144651 | 145398 | |
| 144652 | 145399 | /* |
| 144653 | 145400 | ** Arguments aIdx, aDistance and aSpare all point to arrays of size |
| 144654 | 145401 | ** nIdx. The aIdx array contains the set of integers from 0 to |
| 144655 | 145402 | ** (nIdx-1) in no particular order. This function sorts the values |
| @@ -144786,11 +145533,10 @@ | ||
| 144786 | 145533 | } |
| 144787 | 145534 | #endif |
| 144788 | 145535 | } |
| 144789 | 145536 | } |
| 144790 | 145537 | |
| 144791 | -#if VARIANT_RSTARTREE_SPLIT | |
| 144792 | 145538 | /* |
| 144793 | 145539 | ** Implementation of the R*-tree variant of SplitNode from Beckman[1990]. |
| 144794 | 145540 | */ |
| 144795 | 145541 | static int splitNodeStartree( |
| 144796 | 145542 | Rtree *pRtree, |
| @@ -144805,11 +145551,11 @@ | ||
| 144805 | 145551 | int *aSpare; |
| 144806 | 145552 | int ii; |
| 144807 | 145553 | |
| 144808 | 145554 | int iBestDim = 0; |
| 144809 | 145555 | int iBestSplit = 0; |
| 144810 | - RtreeDValue fBestMargin = 0.0; | |
| 145556 | + RtreeDValue fBestMargin = RTREE_ZERO; | |
| 144811 | 145557 | |
| 144812 | 145558 | int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); |
| 144813 | 145559 | |
| 144814 | 145560 | aaSorted = (int **)sqlite3_malloc(nByte); |
| 144815 | 145561 | if( !aaSorted ){ |
| @@ -144826,13 +145572,13 @@ | ||
| 144826 | 145572 | } |
| 144827 | 145573 | SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare); |
| 144828 | 145574 | } |
| 144829 | 145575 | |
| 144830 | 145576 | for(ii=0; ii<pRtree->nDim; ii++){ |
| 144831 | - RtreeDValue margin = 0.0; | |
| 144832 | - RtreeDValue fBestOverlap = 0.0; | |
| 144833 | - RtreeDValue fBestArea = 0.0; | |
| 145577 | + RtreeDValue margin = RTREE_ZERO; | |
| 145578 | + RtreeDValue fBestOverlap = RTREE_ZERO; | |
| 145579 | + RtreeDValue fBestArea = RTREE_ZERO; | |
| 144834 | 145580 | int iBestLeft = 0; |
| 144835 | 145581 | int nLeft; |
| 144836 | 145582 | |
| 144837 | 145583 | for( |
| 144838 | 145584 | nLeft=RTREE_MINCELLS(pRtree); |
| @@ -144854,11 +145600,11 @@ | ||
| 144854 | 145600 | cellUnion(pRtree, &right, &aCell[aaSorted[ii][kk]]); |
| 144855 | 145601 | } |
| 144856 | 145602 | } |
| 144857 | 145603 | margin += cellMargin(pRtree, &left); |
| 144858 | 145604 | margin += cellMargin(pRtree, &right); |
| 144859 | - overlap = cellOverlap(pRtree, &left, &right, 1, -1); | |
| 145605 | + overlap = cellOverlap(pRtree, &left, &right, 1); | |
| 144860 | 145606 | area = cellArea(pRtree, &left) + cellArea(pRtree, &right); |
| 144861 | 145607 | if( (nLeft==RTREE_MINCELLS(pRtree)) |
| 144862 | 145608 | || (overlap<fBestOverlap) |
| 144863 | 145609 | || (overlap==fBestOverlap && area<fBestArea) |
| 144864 | 145610 | ){ |
| @@ -144886,67 +145632,11 @@ | ||
| 144886 | 145632 | } |
| 144887 | 145633 | |
| 144888 | 145634 | sqlite3_free(aaSorted); |
| 144889 | 145635 | return SQLITE_OK; |
| 144890 | 145636 | } |
| 144891 | -#endif | |
| 144892 | - | |
| 144893 | -#if VARIANT_GUTTMAN_SPLIT | |
| 144894 | -/* | |
| 144895 | -** Implementation of the regular R-tree SplitNode from Guttman[1984]. | |
| 144896 | -*/ | |
| 144897 | -static int splitNodeGuttman( | |
| 144898 | - Rtree *pRtree, | |
| 144899 | - RtreeCell *aCell, | |
| 144900 | - int nCell, | |
| 144901 | - RtreeNode *pLeft, | |
| 144902 | - RtreeNode *pRight, | |
| 144903 | - RtreeCell *pBboxLeft, | |
| 144904 | - RtreeCell *pBboxRight | |
| 144905 | -){ | |
| 144906 | - int iLeftSeed = 0; | |
| 144907 | - int iRightSeed = 1; | |
| 144908 | - int *aiUsed; | |
| 144909 | - int i; | |
| 144910 | - | |
| 144911 | - aiUsed = sqlite3_malloc(sizeof(int)*nCell); | |
| 144912 | - if( !aiUsed ){ | |
| 144913 | - return SQLITE_NOMEM; | |
| 144914 | - } | |
| 144915 | - memset(aiUsed, 0, sizeof(int)*nCell); | |
| 144916 | - | |
| 144917 | - PickSeeds(pRtree, aCell, nCell, &iLeftSeed, &iRightSeed); | |
| 144918 | - | |
| 144919 | - memcpy(pBboxLeft, &aCell[iLeftSeed], sizeof(RtreeCell)); | |
| 144920 | - memcpy(pBboxRight, &aCell[iRightSeed], sizeof(RtreeCell)); | |
| 144921 | - nodeInsertCell(pRtree, pLeft, &aCell[iLeftSeed]); | |
| 144922 | - nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]); | |
| 144923 | - aiUsed[iLeftSeed] = 1; | |
| 144924 | - aiUsed[iRightSeed] = 1; | |
| 144925 | - | |
| 144926 | - for(i=nCell-2; i>0; i--){ | |
| 144927 | - RtreeCell *pNext; | |
| 144928 | - pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed); | |
| 144929 | - RtreeDValue diff = | |
| 144930 | - cellGrowth(pRtree, pBboxLeft, pNext) - | |
| 144931 | - cellGrowth(pRtree, pBboxRight, pNext) | |
| 144932 | - ; | |
| 144933 | - if( (RTREE_MINCELLS(pRtree)-NCELL(pRight)==i) | |
| 144934 | - || (diff>0.0 && (RTREE_MINCELLS(pRtree)-NCELL(pLeft)!=i)) | |
| 144935 | - ){ | |
| 144936 | - nodeInsertCell(pRtree, pRight, pNext); | |
| 144937 | - cellUnion(pRtree, pBboxRight, pNext); | |
| 144938 | - }else{ | |
| 144939 | - nodeInsertCell(pRtree, pLeft, pNext); | |
| 144940 | - cellUnion(pRtree, pBboxLeft, pNext); | |
| 144941 | - } | |
| 144942 | - } | |
| 144943 | - | |
| 144944 | - sqlite3_free(aiUsed); | |
| 144945 | - return SQLITE_OK; | |
| 144946 | -} | |
| 144947 | -#endif | |
| 145637 | + | |
| 144948 | 145638 | |
| 144949 | 145639 | static int updateMapping( |
| 144950 | 145640 | Rtree *pRtree, |
| 144951 | 145641 | i64 iRowid, |
| 144952 | 145642 | RtreeNode *pNode, |
| @@ -145020,11 +145710,12 @@ | ||
| 145020 | 145710 | } |
| 145021 | 145711 | |
| 145022 | 145712 | memset(pLeft->zData, 0, pRtree->iNodeSize); |
| 145023 | 145713 | memset(pRight->zData, 0, pRtree->iNodeSize); |
| 145024 | 145714 | |
| 145025 | - rc = AssignCells(pRtree, aCell, nCell, pLeft, pRight, &leftbbox, &rightbbox); | |
| 145715 | + rc = splitNodeStartree(pRtree, aCell, nCell, pLeft, pRight, | |
| 145716 | + &leftbbox, &rightbbox); | |
| 145026 | 145717 | if( rc!=SQLITE_OK ){ |
| 145027 | 145718 | goto splitnode_out; |
| 145028 | 145719 | } |
| 145029 | 145720 | |
| 145030 | 145721 | /* Ensure both child nodes have node numbers assigned to them by calling |
| @@ -145303,11 +145994,11 @@ | ||
| 145303 | 145994 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 145304 | 145995 | aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2)); |
| 145305 | 145996 | } |
| 145306 | 145997 | |
| 145307 | 145998 | for(ii=0; ii<nCell; ii++){ |
| 145308 | - aDistance[ii] = 0.0; | |
| 145999 | + aDistance[ii] = RTREE_ZERO; | |
| 145309 | 146000 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 145310 | 146001 | RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) - |
| 145311 | 146002 | DCOORD(aCell[ii].aCoord[iDim*2])); |
| 145312 | 146003 | aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); |
| 145313 | 146004 | } |
| @@ -145369,20 +146060,16 @@ | ||
| 145369 | 146060 | nodeReference(pNode); |
| 145370 | 146061 | pChild->pParent = pNode; |
| 145371 | 146062 | } |
| 145372 | 146063 | } |
| 145373 | 146064 | if( nodeInsertCell(pRtree, pNode, pCell) ){ |
| 145374 | -#if VARIANT_RSTARTREE_REINSERT | |
| 145375 | 146065 | if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){ |
| 145376 | 146066 | rc = SplitNode(pRtree, pNode, pCell, iHeight); |
| 145377 | 146067 | }else{ |
| 145378 | 146068 | pRtree->iReinsertHeight = iHeight; |
| 145379 | 146069 | rc = Reinsert(pRtree, pNode, pCell, iHeight); |
| 145380 | 146070 | } |
| 145381 | -#else | |
| 145382 | - rc = SplitNode(pRtree, pNode, pCell, iHeight); | |
| 145383 | -#endif | |
| 145384 | 146071 | }else{ |
| 145385 | 146072 | rc = AdjustTree(pRtree, pNode, pCell); |
| 145386 | 146073 | if( rc==SQLITE_OK ){ |
| 145387 | 146074 | if( iHeight==0 ){ |
| 145388 | 146075 | rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); |
| @@ -145448,11 +146135,11 @@ | ||
| 145448 | 146135 | |
| 145449 | 146136 | /* Obtain a reference to the leaf node that contains the entry |
| 145450 | 146137 | ** about to be deleted. |
| 145451 | 146138 | */ |
| 145452 | 146139 | if( rc==SQLITE_OK ){ |
| 145453 | - rc = findLeafNode(pRtree, iDelete, &pLeaf); | |
| 146140 | + rc = findLeafNode(pRtree, iDelete, &pLeaf, 0); | |
| 145454 | 146141 | } |
| 145455 | 146142 | |
| 145456 | 146143 | /* Delete the cell in question from the leaf node. */ |
| 145457 | 146144 | if( rc==SQLITE_OK ){ |
| 145458 | 146145 | int rc2; |
| @@ -145785,11 +146472,12 @@ | ||
| 145785 | 146472 | |
| 145786 | 146473 | if( isCreate ){ |
| 145787 | 146474 | char *zCreate = sqlite3_mprintf( |
| 145788 | 146475 | "CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);" |
| 145789 | 146476 | "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);" |
| 145790 | -"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY, parentnode INTEGER);" | |
| 146477 | +"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY," | |
| 146478 | + " parentnode INTEGER);" | |
| 145791 | 146479 | "INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))", |
| 145792 | 146480 | zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize |
| 145793 | 146481 | ); |
| 145794 | 146482 | if( !zCreate ){ |
| 145795 | 146483 | return SQLITE_NOMEM; |
| @@ -145999,14 +146687,14 @@ | ||
| 145999 | 146687 | |
| 146000 | 146688 | /* |
| 146001 | 146689 | ** Implementation of a scalar function that decodes r-tree nodes to |
| 146002 | 146690 | ** human readable strings. This can be used for debugging and analysis. |
| 146003 | 146691 | ** |
| 146004 | -** The scalar function takes two arguments, a blob of data containing | |
| 146005 | -** an r-tree node, and the number of dimensions the r-tree indexes. | |
| 146006 | -** For a two-dimensional r-tree structure called "rt", to deserialize | |
| 146007 | -** all nodes, a statement like: | |
| 146692 | +** The scalar function takes two arguments: (1) the number of dimensions | |
| 146693 | +** to the rtree (between 1 and 5, inclusive) and (2) a blob of data containing | |
| 146694 | +** an r-tree node. For a two-dimensional r-tree structure called "rt", to | |
| 146695 | +** deserialize all nodes, a statement like: | |
| 146008 | 146696 | ** |
| 146009 | 146697 | ** SELECT rtreenode(2, data) FROM rt_node; |
| 146010 | 146698 | ** |
| 146011 | 146699 | ** The human readable string takes the form of a Tcl list with one |
| 146012 | 146700 | ** entry for each cell in the r-tree node. Each entry is itself a |
| @@ -146035,11 +146723,11 @@ | ||
| 146035 | 146723 | nodeGetCell(&tree, &node, ii, &cell); |
| 146036 | 146724 | sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid); |
| 146037 | 146725 | nCell = (int)strlen(zCell); |
| 146038 | 146726 | for(jj=0; jj<tree.nDim*2; jj++){ |
| 146039 | 146727 | #ifndef SQLITE_RTREE_INT_ONLY |
| 146040 | - sqlite3_snprintf(512-nCell,&zCell[nCell], " %f", | |
| 146728 | + sqlite3_snprintf(512-nCell,&zCell[nCell], " %g", | |
| 146041 | 146729 | (double)cell.aCoord[jj].f); |
| 146042 | 146730 | #else |
| 146043 | 146731 | sqlite3_snprintf(512-nCell,&zCell[nCell], " %d", |
| 146044 | 146732 | cell.aCoord[jj].i); |
| 146045 | 146733 | #endif |
| @@ -146056,10 +146744,19 @@ | ||
| 146056 | 146744 | } |
| 146057 | 146745 | |
| 146058 | 146746 | sqlite3_result_text(ctx, zText, -1, sqlite3_free); |
| 146059 | 146747 | } |
| 146060 | 146748 | |
| 146749 | +/* This routine implements an SQL function that returns the "depth" parameter | |
| 146750 | +** from the front of a blob that is an r-tree node. For example: | |
| 146751 | +** | |
| 146752 | +** SELECT rtreedepth(data) FROM rt_node WHERE nodeno=1; | |
| 146753 | +** | |
| 146754 | +** The depth value is 0 for all nodes other than the root node, and the root | |
| 146755 | +** node always has nodeno=1, so the example above is the primary use for this | |
| 146756 | +** routine. This routine is intended for testing and analysis only. | |
| 146757 | +*/ | |
| 146061 | 146758 | static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ |
| 146062 | 146759 | UNUSED_PARAMETER(nArg); |
| 146063 | 146760 | if( sqlite3_value_type(apArg[0])!=SQLITE_BLOB |
| 146064 | 146761 | || sqlite3_value_bytes(apArg[0])<2 |
| 146065 | 146762 | ){ |
| @@ -146098,26 +146795,35 @@ | ||
| 146098 | 146795 | |
| 146099 | 146796 | return rc; |
| 146100 | 146797 | } |
| 146101 | 146798 | |
| 146102 | 146799 | /* |
| 146103 | -** A version of sqlite3_free() that can be used as a callback. This is used | |
| 146104 | -** in two places - as the destructor for the blob value returned by the | |
| 146105 | -** invocation of a geometry function, and as the destructor for the geometry | |
| 146106 | -** functions themselves. | |
| 146800 | +** This routine deletes the RtreeGeomCallback object that was attached | |
| 146801 | +** one of the SQL functions create by sqlite3_rtree_geometry_callback() | |
| 146802 | +** or sqlite3_rtree_query_callback(). In other words, this routine is the | |
| 146803 | +** destructor for an RtreeGeomCallback objecct. This routine is called when | |
| 146804 | +** the corresponding SQL function is deleted. | |
| 146107 | 146805 | */ |
| 146108 | -static void doSqlite3Free(void *p){ | |
| 146806 | +static void rtreeFreeCallback(void *p){ | |
| 146807 | + RtreeGeomCallback *pInfo = (RtreeGeomCallback*)p; | |
| 146808 | + if( pInfo->xDestructor ) pInfo->xDestructor(pInfo->pContext); | |
| 146109 | 146809 | sqlite3_free(p); |
| 146110 | 146810 | } |
| 146111 | 146811 | |
| 146112 | 146812 | /* |
| 146113 | -** Each call to sqlite3_rtree_geometry_callback() creates an ordinary SQLite | |
| 146114 | -** scalar user function. This C function is the callback used for all such | |
| 146115 | -** registered SQL functions. | |
| 146813 | +** Each call to sqlite3_rtree_geometry_callback() or | |
| 146814 | +** sqlite3_rtree_query_callback() creates an ordinary SQLite | |
| 146815 | +** scalar function that is implemented by this routine. | |
| 146816 | +** | |
| 146817 | +** All this function does is construct an RtreeMatchArg object that | |
| 146818 | +** contains the geometry-checking callback routines and a list of | |
| 146819 | +** parameters to this function, then return that RtreeMatchArg object | |
| 146820 | +** as a BLOB. | |
| 146116 | 146821 | ** |
| 146117 | -** The scalar user functions return a blob that is interpreted by r-tree | |
| 146118 | -** table MATCH operators. | |
| 146822 | +** The R-Tree MATCH operator will read the returned BLOB, deserialize | |
| 146823 | +** the RtreeMatchArg object, and use the RtreeMatchArg object to figure | |
| 146824 | +** out which elements of the R-Tree should be returned by the query. | |
| 146119 | 146825 | */ |
| 146120 | 146826 | static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ |
| 146121 | 146827 | RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); |
| 146122 | 146828 | RtreeMatchArg *pBlob; |
| 146123 | 146829 | int nBlob; |
| @@ -146127,45 +146833,68 @@ | ||
| 146127 | 146833 | if( !pBlob ){ |
| 146128 | 146834 | sqlite3_result_error_nomem(ctx); |
| 146129 | 146835 | }else{ |
| 146130 | 146836 | int i; |
| 146131 | 146837 | pBlob->magic = RTREE_GEOMETRY_MAGIC; |
| 146132 | - pBlob->xGeom = pGeomCtx->xGeom; | |
| 146133 | - pBlob->pContext = pGeomCtx->pContext; | |
| 146838 | + pBlob->cb = pGeomCtx[0]; | |
| 146134 | 146839 | pBlob->nParam = nArg; |
| 146135 | 146840 | for(i=0; i<nArg; i++){ |
| 146136 | 146841 | #ifdef SQLITE_RTREE_INT_ONLY |
| 146137 | 146842 | pBlob->aParam[i] = sqlite3_value_int64(aArg[i]); |
| 146138 | 146843 | #else |
| 146139 | 146844 | pBlob->aParam[i] = sqlite3_value_double(aArg[i]); |
| 146140 | 146845 | #endif |
| 146141 | 146846 | } |
| 146142 | - sqlite3_result_blob(ctx, pBlob, nBlob, doSqlite3Free); | |
| 146847 | + sqlite3_result_blob(ctx, pBlob, nBlob, sqlite3_free); | |
| 146143 | 146848 | } |
| 146144 | 146849 | } |
| 146145 | 146850 | |
| 146146 | 146851 | /* |
| 146147 | 146852 | ** Register a new geometry function for use with the r-tree MATCH operator. |
| 146148 | 146853 | */ |
| 146149 | 146854 | SQLITE_API int sqlite3_rtree_geometry_callback( |
| 146150 | - sqlite3 *db, | |
| 146151 | - const char *zGeom, | |
| 146152 | - int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue *, int *), | |
| 146153 | - void *pContext | |
| 146855 | + sqlite3 *db, /* Register SQL function on this connection */ | |
| 146856 | + const char *zGeom, /* Name of the new SQL function */ | |
| 146857 | + int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */ | |
| 146858 | + void *pContext /* Extra data associated with the callback */ | |
| 146154 | 146859 | ){ |
| 146155 | 146860 | RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ |
| 146156 | 146861 | |
| 146157 | 146862 | /* Allocate and populate the context object. */ |
| 146158 | 146863 | pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); |
| 146159 | 146864 | if( !pGeomCtx ) return SQLITE_NOMEM; |
| 146160 | 146865 | pGeomCtx->xGeom = xGeom; |
| 146866 | + pGeomCtx->xQueryFunc = 0; | |
| 146867 | + pGeomCtx->xDestructor = 0; | |
| 146161 | 146868 | pGeomCtx->pContext = pContext; |
| 146162 | - | |
| 146163 | - /* Create the new user-function. Register a destructor function to delete | |
| 146164 | - ** the context object when it is no longer required. */ | |
| 146165 | 146869 | return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, |
| 146166 | - (void *)pGeomCtx, geomCallback, 0, 0, doSqlite3Free | |
| 146870 | + (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback | |
| 146871 | + ); | |
| 146872 | +} | |
| 146873 | + | |
| 146874 | +/* | |
| 146875 | +** Register a new 2nd-generation geometry function for use with the | |
| 146876 | +** r-tree MATCH operator. | |
| 146877 | +*/ | |
| 146878 | +SQLITE_API int sqlite3_rtree_query_callback( | |
| 146879 | + sqlite3 *db, /* Register SQL function on this connection */ | |
| 146880 | + const char *zQueryFunc, /* Name of new SQL function */ | |
| 146881 | + int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */ | |
| 146882 | + void *pContext, /* Extra data passed into the callback */ | |
| 146883 | + void (*xDestructor)(void*) /* Destructor for the extra data */ | |
| 146884 | +){ | |
| 146885 | + RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ | |
| 146886 | + | |
| 146887 | + /* Allocate and populate the context object. */ | |
| 146888 | + pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); | |
| 146889 | + if( !pGeomCtx ) return SQLITE_NOMEM; | |
| 146890 | + pGeomCtx->xGeom = 0; | |
| 146891 | + pGeomCtx->xQueryFunc = xQueryFunc; | |
| 146892 | + pGeomCtx->xDestructor = xDestructor; | |
| 146893 | + pGeomCtx->pContext = pContext; | |
| 146894 | + return sqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY, | |
| 146895 | + (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback | |
| 146167 | 146896 | ); |
| 146168 | 146897 | } |
| 146169 | 146898 | |
| 146170 | 146899 | #if !SQLITE_CORE |
| 146171 | 146900 | #ifdef _WIN32 |
| 146172 | 146901 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -222,11 +222,11 @@ | |
| 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | */ |
| 225 | #define SQLITE_VERSION "3.8.5" |
| 226 | #define SQLITE_VERSION_NUMBER 3008005 |
| 227 | #define SQLITE_SOURCE_ID "2014-04-18 22:20:31 9a5d38c79d2482a23bcfbc3ff35ca4fa269c768d" |
| 228 | |
| 229 | /* |
| 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | ** |
| @@ -673,11 +673,14 @@ | |
| 673 | ** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that |
| 674 | ** after reboot following a crash or power loss, the only bytes in a |
| 675 | ** file that were written at the application level might have changed |
| 676 | ** and that adjacent bytes, even bytes within the same sector are |
| 677 | ** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
| 678 | ** flag indicate that a file cannot be deleted when open. |
| 679 | */ |
| 680 | #define SQLITE_IOCAP_ATOMIC 0x00000001 |
| 681 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 |
| 682 | #define SQLITE_IOCAP_ATOMIC1K 0x00000004 |
| 683 | #define SQLITE_IOCAP_ATOMIC2K 0x00000008 |
| @@ -688,10 +691,11 @@ | |
| 688 | #define SQLITE_IOCAP_ATOMIC64K 0x00000100 |
| 689 | #define SQLITE_IOCAP_SAFE_APPEND 0x00000200 |
| 690 | #define SQLITE_IOCAP_SEQUENTIAL 0x00000400 |
| 691 | #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 |
| 692 | #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 |
| 693 | |
| 694 | /* |
| 695 | ** CAPI3REF: File Locking Levels |
| 696 | ** |
| 697 | ** SQLite uses one of these integer values as the second |
| @@ -2892,10 +2896,34 @@ | |
| 2892 | ** sqlite3_open_v2(). ^Setting the cache parameter to "private" is |
| 2893 | ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. |
| 2894 | ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in |
| 2895 | ** a URI filename, its value overrides any behavior requested by setting |
| 2896 | ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. |
| 2897 | ** </ul> |
| 2898 | ** |
| 2899 | ** ^Specifying an unknown parameter in the query component of a URI is not an |
| 2900 | ** error. Future versions of SQLite might understand additional query |
| 2901 | ** parameters. See "[query parameters with special meaning to SQLite]" for |
| @@ -2921,12 +2949,13 @@ | |
| 2921 | ** in URI filenames. |
| 2922 | ** <tr><td> file:data.db?mode=ro&cache=private <td> |
| 2923 | ** Open file "data.db" in the current directory for read-only access. |
| 2924 | ** Regardless of whether or not shared-cache mode is enabled by |
| 2925 | ** default, use a private cache. |
| 2926 | ** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td> |
| 2927 | ** Open file "/home/fred/data.db". Use the special VFS "unix-nolock". |
| 2928 | ** <tr><td> file:data.db?mode=readonly <td> |
| 2929 | ** An error. "readonly" is not a valid option for the "mode" parameter. |
| 2930 | ** </table> |
| 2931 | ** |
| 2932 | ** ^URI hexadecimal escape sequences (%HH) are supported within the path and |
| @@ -7460,10 +7489,20 @@ | |
| 7460 | #if 0 |
| 7461 | extern "C" { |
| 7462 | #endif |
| 7463 | |
| 7464 | typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; |
| 7465 | |
| 7466 | /* |
| 7467 | ** Register a geometry callback named zGeom that can be used as part of an |
| 7468 | ** R-Tree geometry query as follows: |
| 7469 | ** |
| @@ -7470,15 +7509,11 @@ | |
| 7470 | ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) |
| 7471 | */ |
| 7472 | SQLITE_API int sqlite3_rtree_geometry_callback( |
| 7473 | sqlite3 *db, |
| 7474 | const char *zGeom, |
| 7475 | #ifdef SQLITE_RTREE_INT_ONLY |
| 7476 | int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes), |
| 7477 | #else |
| 7478 | int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes), |
| 7479 | #endif |
| 7480 | void *pContext |
| 7481 | ); |
| 7482 | |
| 7483 | |
| 7484 | /* |
| @@ -7486,15 +7521,64 @@ | |
| 7486 | ** argument to callbacks registered using rtree_geometry_callback(). |
| 7487 | */ |
| 7488 | struct sqlite3_rtree_geometry { |
| 7489 | void *pContext; /* Copy of pContext passed to s_r_g_c() */ |
| 7490 | int nParam; /* Size of array aParam[] */ |
| 7491 | double *aParam; /* Parameters passed to SQL geom function */ |
| 7492 | void *pUser; /* Callback implementation user data */ |
| 7493 | void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ |
| 7494 | }; |
| 7495 | |
| 7496 | |
| 7497 | #if 0 |
| 7498 | } /* end of the 'extern "C"' block */ |
| 7499 | #endif |
| 7500 | |
| @@ -8417,14 +8501,14 @@ | |
| 8417 | ** Estimated quantities used for query planning are stored as 16-bit |
| 8418 | ** logarithms. For quantity X, the value stored is 10*log2(X). This |
| 8419 | ** gives a possible range of values of approximately 1.0e986 to 1e-986. |
| 8420 | ** But the allowed values are "grainy". Not every value is representable. |
| 8421 | ** For example, quantities 16 and 17 are both represented by a LogEst |
| 8422 | ** of 40. However, since LogEst quantatites are suppose to be estimates, |
| 8423 | ** not exact values, this imprecision is not a problem. |
| 8424 | ** |
| 8425 | ** "LogEst" is short for "Logarithimic Estimate". |
| 8426 | ** |
| 8427 | ** Examples: |
| 8428 | ** 1 -> 0 20 -> 43 10000 -> 132 |
| 8429 | ** 2 -> 10 25 -> 46 25000 -> 146 |
| 8430 | ** 3 -> 16 100 -> 66 1000000 -> 199 |
| @@ -8916,10 +9000,11 @@ | |
| 8916 | SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); |
| 8917 | SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *); |
| 8918 | SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); |
| 8919 | SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); |
| 8920 | SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask); |
| 8921 | |
| 8922 | #ifndef NDEBUG |
| 8923 | SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); |
| 8924 | #endif |
| 8925 | |
| @@ -9870,87 +9955,75 @@ | |
| 9870 | */ |
| 9871 | #ifndef _SQLITE_OS_H_ |
| 9872 | #define _SQLITE_OS_H_ |
| 9873 | |
| 9874 | /* |
| 9875 | ** Figure out if we are dealing with Unix, Windows, or some other |
| 9876 | ** operating system. After the following block of preprocess macros, |
| 9877 | ** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER |
| 9878 | ** will defined to either 1 or 0. One of the four will be 1. The other |
| 9879 | ** three will be 0. |
| 9880 | */ |
| 9881 | #if defined(SQLITE_OS_OTHER) |
| 9882 | # if SQLITE_OS_OTHER==1 |
| 9883 | # undef SQLITE_OS_UNIX |
| 9884 | # define SQLITE_OS_UNIX 0 |
| 9885 | # undef SQLITE_OS_WIN |
| 9886 | # define SQLITE_OS_WIN 0 |
| 9887 | # else |
| 9888 | # undef SQLITE_OS_OTHER |
| 9889 | # endif |
| 9890 | #endif |
| 9891 | #if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) |
| 9892 | # define SQLITE_OS_OTHER 0 |
| 9893 | # ifndef SQLITE_OS_WIN |
| 9894 | # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) |
| 9895 | # define SQLITE_OS_WIN 1 |
| 9896 | # define SQLITE_OS_UNIX 0 |
| 9897 | # else |
| 9898 | # define SQLITE_OS_WIN 0 |
| 9899 | # define SQLITE_OS_UNIX 1 |
| 9900 | # endif |
| 9901 | # else |
| 9902 | # define SQLITE_OS_UNIX 0 |
| 9903 | # endif |
| 9904 | #else |
| 9905 | # ifndef SQLITE_OS_WIN |
| 9906 | # define SQLITE_OS_WIN 0 |
| 9907 | # endif |
| 9908 | #endif |
| 9909 | |
| 9910 | #if SQLITE_OS_WIN |
| 9911 | # include <windows.h> |
| 9912 | #endif |
| 9913 | |
| 9914 | /* |
| 9915 | ** Determine if we are dealing with Windows NT. |
| 9916 | ** |
| 9917 | ** We ought to be able to determine if we are compiling for win98 or winNT |
| 9918 | ** using the _WIN32_WINNT macro as follows: |
| 9919 | ** |
| 9920 | ** #if defined(_WIN32_WINNT) |
| 9921 | ** # define SQLITE_OS_WINNT 1 |
| 9922 | ** #else |
| 9923 | ** # define SQLITE_OS_WINNT 0 |
| 9924 | ** #endif |
| 9925 | ** |
| 9926 | ** However, vs2005 does not set _WIN32_WINNT by default, as it ought to, |
| 9927 | ** so the above test does not work. We'll just assume that everything is |
| 9928 | ** winNT unless the programmer explicitly says otherwise by setting |
| 9929 | ** SQLITE_OS_WINNT to 0. |
| 9930 | */ |
| 9931 | #if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT) |
| 9932 | # define SQLITE_OS_WINNT 1 |
| 9933 | #endif |
| 9934 | |
| 9935 | /* |
| 9936 | ** Determine if we are dealing with WindowsCE - which has a much |
| 9937 | ** reduced API. |
| 9938 | */ |
| 9939 | #if defined(_WIN32_WCE) |
| 9940 | # define SQLITE_OS_WINCE 1 |
| 9941 | #else |
| 9942 | # define SQLITE_OS_WINCE 0 |
| 9943 | #endif |
| 9944 | |
| 9945 | /* |
| 9946 | ** Determine if we are dealing with WinRT, which provides only a subset of |
| 9947 | ** the full Win32 API. |
| 9948 | */ |
| 9949 | #if !defined(SQLITE_OS_WINRT) |
| 9950 | # define SQLITE_OS_WINRT 0 |
| 9951 | #endif |
| 9952 | |
| 9953 | /* If the SET_FULLSYNC macro is not defined above, then make it |
| 9954 | ** a no-op |
| 9955 | */ |
| 9956 | #ifndef SET_FULLSYNC |
| @@ -10845,11 +10918,11 @@ | |
| 10845 | FKey *pFKey; /* Linked list of all foreign keys in this table */ |
| 10846 | char *zColAff; /* String defining the affinity of each column */ |
| 10847 | #ifndef SQLITE_OMIT_CHECK |
| 10848 | ExprList *pCheck; /* All CHECK constraints */ |
| 10849 | #endif |
| 10850 | tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */ |
| 10851 | int tnum; /* Root BTree node for this table (see note above) */ |
| 10852 | i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */ |
| 10853 | i16 nCol; /* Number of columns in this table */ |
| 10854 | u16 nRef; /* Number of pointers to this Table */ |
| 10855 | LogEst szTabRow; /* Estimated size of each table row in bytes */ |
| @@ -11054,11 +11127,11 @@ | |
| 11054 | ** element. |
| 11055 | */ |
| 11056 | struct Index { |
| 11057 | char *zName; /* Name of this index */ |
| 11058 | i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */ |
| 11059 | tRowcnt *aiRowEst; /* From ANALYZE: Est. rows selected by each column */ |
| 11060 | Table *pTable; /* The SQL table being indexed */ |
| 11061 | char *zColAff; /* String defining the affinity of each column */ |
| 11062 | Index *pNext; /* The next index associated with the same table */ |
| 11063 | Schema *pSchema; /* Schema containing this index */ |
| 11064 | u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ |
| @@ -11499,10 +11572,11 @@ | |
| 11499 | #define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */ |
| 11500 | #define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */ |
| 11501 | #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ |
| 11502 | #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ |
| 11503 | #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ |
| 11504 | |
| 11505 | /* Allowed return values from sqlite3WhereIsDistinct() |
| 11506 | */ |
| 11507 | #define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ |
| 11508 | #define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ |
| @@ -12082,15 +12156,14 @@ | |
| 12082 | int isInit; /* True after initialization has finished */ |
| 12083 | int inProgress; /* True while initialization in progress */ |
| 12084 | int isMutexInit; /* True after mutexes are initialized */ |
| 12085 | int isMallocInit; /* True after malloc is initialized */ |
| 12086 | int isPCacheInit; /* True after malloc is initialized */ |
| 12087 | sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ |
| 12088 | int nRefInitMutex; /* Number of users of pInitMutex */ |
| 12089 | void (*xLog)(void*,int,const char*); /* Function for logging */ |
| 12090 | void *pLogArg; /* First argument to xLog() */ |
| 12091 | int bLocaltimeFault; /* True to fail localtime() calls */ |
| 12092 | #ifdef SQLITE_ENABLE_SQLLOG |
| 12093 | void(*xSqllog)(void*,sqlite3*,const char*, int); |
| 12094 | void *pSqllogArg; |
| 12095 | #endif |
| 12096 | #ifdef SQLITE_VDBE_COVERAGE |
| @@ -12098,10 +12171,14 @@ | |
| 12098 | ** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE. |
| 12099 | */ |
| 12100 | void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */ |
| 12101 | void *pVdbeBranchArg; /* 1st argument */ |
| 12102 | #endif |
| 12103 | }; |
| 12104 | |
| 12105 | /* |
| 12106 | ** This macro is used inside of assert() statements to indicate that |
| 12107 | ** the assert is only valid on a well-formed database. Instead of: |
| @@ -12398,10 +12475,16 @@ | |
| 12398 | SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); |
| 12399 | SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, |
| 12400 | sqlite3_vfs**,char**,char **); |
| 12401 | SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*); |
| 12402 | SQLITE_PRIVATE int sqlite3CodeOnce(Parse *); |
| 12403 | |
| 12404 | SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32); |
| 12405 | SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32); |
| 12406 | SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32); |
| 12407 | SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*); |
| @@ -12466,10 +12549,11 @@ | |
| 12466 | SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); |
| 12467 | SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); |
| 12468 | SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo*); |
| 12469 | SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*); |
| 12470 | SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*); |
| 12471 | SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*); |
| 12472 | SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*); |
| 12473 | SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*); |
| 12474 | SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); |
| 12475 | SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); |
| @@ -13203,19 +13287,26 @@ | |
| 13203 | 0, /* isInit */ |
| 13204 | 0, /* inProgress */ |
| 13205 | 0, /* isMutexInit */ |
| 13206 | 0, /* isMallocInit */ |
| 13207 | 0, /* isPCacheInit */ |
| 13208 | 0, /* pInitMutex */ |
| 13209 | 0, /* nRefInitMutex */ |
| 13210 | 0, /* xLog */ |
| 13211 | 0, /* pLogArg */ |
| 13212 | 0, /* bLocaltimeFault */ |
| 13213 | #ifdef SQLITE_ENABLE_SQLLOG |
| 13214 | 0, /* xSqllog */ |
| 13215 | 0 /* pSqllogArg */ |
| 13216 | #endif |
| 13217 | }; |
| 13218 | |
| 13219 | /* |
| 13220 | ** Hash table for global functions - functions common to all |
| 13221 | ** database connections. After initialization, this table is |
| @@ -18934,10 +19025,88 @@ | |
| 18934 | ** |
| 18935 | ************************************************************************* |
| 18936 | ** This file contains the C functions that implement mutexes for win32 |
| 18937 | */ |
| 18938 | |
| 18939 | /* |
| 18940 | ** The code in this file is only used if we are compiling multithreaded |
| 18941 | ** on a win32 system. |
| 18942 | */ |
| 18943 | #ifdef SQLITE_MUTEX_W32 |
| @@ -21789,10 +21958,28 @@ | |
| 21789 | static unsigned dummy = 0; |
| 21790 | dummy += (unsigned)x; |
| 21791 | } |
| 21792 | #endif |
| 21793 | |
| 21794 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 21795 | /* |
| 21796 | ** Return true if the floating point value is Not a Number (NaN). |
| 21797 | ** |
| 21798 | ** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. |
| @@ -23004,12 +23191,12 @@ | |
| 23004 | return b+x[b-a]; |
| 23005 | } |
| 23006 | } |
| 23007 | |
| 23008 | /* |
| 23009 | ** Convert an integer into a LogEst. In other words, compute a |
| 23010 | ** good approximatation for 10*log2(x). |
| 23011 | */ |
| 23012 | SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){ |
| 23013 | static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 }; |
| 23014 | LogEst y = 40; |
| 23015 | if( x<8 ){ |
| @@ -31226,15 +31413,10 @@ | |
| 31226 | ** |
| 31227 | ** This file contains code that is specific to Windows. |
| 31228 | */ |
| 31229 | #if SQLITE_OS_WIN /* This file is used for Windows only */ |
| 31230 | |
| 31231 | #ifdef __CYGWIN__ |
| 31232 | # include <sys/cygwin.h> |
| 31233 | # include <errno.h> /* amalgamator: keep */ |
| 31234 | #endif |
| 31235 | |
| 31236 | /* |
| 31237 | ** Include code that is common to all os_*.c files |
| 31238 | */ |
| 31239 | /************** Include os_common.h in the middle of os_win.c ****************/ |
| 31240 | /************** Begin file os_common.h ***************************************/ |
| @@ -31443,10 +31625,14 @@ | |
| 31443 | |
| 31444 | #endif /* !defined(_OS_COMMON_H_) */ |
| 31445 | |
| 31446 | /************** End of os_common.h *******************************************/ |
| 31447 | /************** Continuing where we left off in os_win.c *********************/ |
| 31448 | |
| 31449 | /* |
| 31450 | ** Compiling and using WAL mode requires several APIs that are only |
| 31451 | ** available in Windows platforms based on the NT kernel. |
| 31452 | */ |
| @@ -33255,10 +33441,36 @@ | |
| 33255 | # define SQLITE_WIN32_IOERR_RETRY_DELAY 25 |
| 33256 | #endif |
| 33257 | static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY; |
| 33258 | static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; |
| 33259 | |
| 33260 | /* |
| 33261 | ** If a ReadFile() or WriteFile() error occurs, invoke this routine |
| 33262 | ** to see if it should be retried. Return TRUE to retry. Return FALSE |
| 33263 | ** to give up with an error. |
| 33264 | */ |
| @@ -33268,17 +33480,22 @@ | |
| 33268 | if( pError ){ |
| 33269 | *pError = e; |
| 33270 | } |
| 33271 | return 0; |
| 33272 | } |
| 33273 | if( e==ERROR_ACCESS_DENIED || |
| 33274 | e==ERROR_LOCK_VIOLATION || |
| 33275 | e==ERROR_SHARING_VIOLATION ){ |
| 33276 | sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); |
| 33277 | ++*pnRetry; |
| 33278 | return 1; |
| 33279 | } |
| 33280 | if( pError ){ |
| 33281 | *pError = e; |
| 33282 | } |
| 33283 | return 0; |
| 33284 | } |
| @@ -40231,11 +40448,12 @@ | |
| 40231 | u8 noSync; /* Do not sync the journal if true */ |
| 40232 | u8 fullSync; /* Do extra syncs of the journal for robustness */ |
| 40233 | u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ |
| 40234 | u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ |
| 40235 | u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ |
| 40236 | u8 tempFile; /* zFilename is a temporary file */ |
| 40237 | u8 readOnly; /* True for a read-only database */ |
| 40238 | u8 memDb; /* True to inhibit all file I/O */ |
| 40239 | |
| 40240 | /************************************************************************** |
| 40241 | ** The following block contains those class members that change during |
| @@ -40696,11 +40914,11 @@ | |
| 40696 | assert( !pPager->exclusiveMode || pPager->eLock==eLock ); |
| 40697 | assert( eLock==NO_LOCK || eLock==SHARED_LOCK ); |
| 40698 | assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 ); |
| 40699 | if( isOpen(pPager->fd) ){ |
| 40700 | assert( pPager->eLock>=eLock ); |
| 40701 | rc = sqlite3OsUnlock(pPager->fd, eLock); |
| 40702 | if( pPager->eLock!=UNKNOWN_LOCK ){ |
| 40703 | pPager->eLock = (u8)eLock; |
| 40704 | } |
| 40705 | IOTRACE(("UNLOCK %p %d\n", pPager, eLock)) |
| 40706 | } |
| @@ -40720,11 +40938,11 @@ | |
| 40720 | static int pagerLockDb(Pager *pPager, int eLock){ |
| 40721 | int rc = SQLITE_OK; |
| 40722 | |
| 40723 | assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK ); |
| 40724 | if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){ |
| 40725 | rc = sqlite3OsLock(pPager->fd, eLock); |
| 40726 | if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){ |
| 40727 | pPager->eLock = (u8)eLock; |
| 40728 | IOTRACE(("LOCK %p %d\n", pPager, eLock)) |
| 40729 | } |
| 40730 | } |
| @@ -44279,47 +44497,59 @@ | |
| 44279 | ** |
| 44280 | ** + SQLITE_DEFAULT_PAGE_SIZE, |
| 44281 | ** + The value returned by sqlite3OsSectorSize() |
| 44282 | ** + The largest page size that can be written atomically. |
| 44283 | */ |
| 44284 | if( rc==SQLITE_OK && !readOnly ){ |
| 44285 | setSectorSize(pPager); |
| 44286 | assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE); |
| 44287 | if( szPageDflt<pPager->sectorSize ){ |
| 44288 | if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ |
| 44289 | szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; |
| 44290 | }else{ |
| 44291 | szPageDflt = (u32)pPager->sectorSize; |
| 44292 | } |
| 44293 | } |
| 44294 | #ifdef SQLITE_ENABLE_ATOMIC_WRITE |
| 44295 | { |
| 44296 | int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); |
| 44297 | int ii; |
| 44298 | assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); |
| 44299 | assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); |
| 44300 | assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); |
| 44301 | for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ |
| 44302 | if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){ |
| 44303 | szPageDflt = ii; |
| 44304 | } |
| 44305 | } |
| 44306 | } |
| 44307 | #endif |
| 44308 | } |
| 44309 | }else{ |
| 44310 | /* If a temporary file is requested, it is not opened immediately. |
| 44311 | ** In this case we accept the default page size and delay actually |
| 44312 | ** opening the file until the first call to OsWrite(). |
| 44313 | ** |
| 44314 | ** This branch is also run for an in-memory database. An in-memory |
| 44315 | ** database is the same as a temp-file that is never written out to |
| 44316 | ** disk and uses an in-memory rollback journal. |
| 44317 | */ |
| 44318 | tempFile = 1; |
| 44319 | pPager->eState = PAGER_READER; |
| 44320 | pPager->eLock = EXCLUSIVE_LOCK; |
| 44321 | readOnly = (vfsFlags&SQLITE_OPEN_READONLY); |
| 44322 | } |
| 44323 | |
| 44324 | /* The following call to PagerSetPagesize() serves to set the value of |
| 44325 | ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. |
| @@ -44356,13 +44586,10 @@ | |
| 44356 | /* pPager->stmtSize = 0; */ |
| 44357 | /* pPager->stmtJSize = 0; */ |
| 44358 | /* pPager->nPage = 0; */ |
| 44359 | pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; |
| 44360 | /* pPager->state = PAGER_UNLOCK; */ |
| 44361 | #if 0 |
| 44362 | assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) ); |
| 44363 | #endif |
| 44364 | /* pPager->errMask = 0; */ |
| 44365 | pPager->tempFile = (u8)tempFile; |
| 44366 | assert( tempFile==PAGER_LOCKINGMODE_NORMAL |
| 44367 | || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); |
| 44368 | assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); |
| @@ -59414,10 +59641,17 @@ | |
| 59414 | */ |
| 59415 | SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){ |
| 59416 | assert( mask==BTREE_BULKLOAD || mask==0 ); |
| 59417 | pCsr->hints = mask; |
| 59418 | } |
| 59419 | |
| 59420 | /************** End of btree.c ***********************************************/ |
| 59421 | /************** Begin file backup.c ******************************************/ |
| 59422 | /* |
| 59423 | ** 2009 January 28 |
| @@ -70686,11 +70920,11 @@ | |
| 70686 | ** |
| 70687 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 70688 | ** is greater than or equal to the key value. If there are no records |
| 70689 | ** greater than or equal to the key and P2 is not zero, then jump to P2. |
| 70690 | ** |
| 70691 | ** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe |
| 70692 | */ |
| 70693 | /* Opcode: SeekGt P1 P2 P3 P4 * |
| 70694 | ** Synopsis: key=r[P3@P4] |
| 70695 | ** |
| 70696 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| @@ -70700,11 +70934,11 @@ | |
| 70700 | ** |
| 70701 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 70702 | ** is greater than the key value. If there are no records greater than |
| 70703 | ** the key and P2 is not zero, then jump to P2. |
| 70704 | ** |
| 70705 | ** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe |
| 70706 | */ |
| 70707 | /* Opcode: SeekLt P1 P2 P3 P4 * |
| 70708 | ** Synopsis: key=r[P3@P4] |
| 70709 | ** |
| 70710 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| @@ -70714,11 +70948,11 @@ | |
| 70714 | ** |
| 70715 | ** Reposition cursor P1 so that it points to the largest entry that |
| 70716 | ** is less than the key value. If there are no records less than |
| 70717 | ** the key and P2 is not zero, then jump to P2. |
| 70718 | ** |
| 70719 | ** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe |
| 70720 | */ |
| 70721 | /* Opcode: SeekLe P1 P2 P3 P4 * |
| 70722 | ** Synopsis: key=r[P3@P4] |
| 70723 | ** |
| 70724 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| @@ -70728,11 +70962,11 @@ | |
| 70728 | ** |
| 70729 | ** Reposition cursor P1 so that it points to the largest entry that |
| 70730 | ** is less than or equal to the key value. If there are no records |
| 70731 | ** less than or equal to the key and P2 is not zero, then jump to P2. |
| 70732 | ** |
| 70733 | ** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt |
| 70734 | */ |
| 70735 | case OP_SeekLT: /* jump, in3 */ |
| 70736 | case OP_SeekLE: /* jump, in3 */ |
| 70737 | case OP_SeekGE: /* jump, in3 */ |
| 70738 | case OP_SeekGT: { /* jump, in3 */ |
| @@ -71454,10 +71688,11 @@ | |
| 71454 | |
| 71455 | pOut = &aMem[pOp->p2]; |
| 71456 | pC = p->apCsr[pOp->p1]; |
| 71457 | assert( isSorter(pC) ); |
| 71458 | rc = sqlite3VdbeSorterRowkey(pC, pOut); |
| 71459 | break; |
| 71460 | } |
| 71461 | |
| 71462 | /* Opcode: RowData P1 P2 * * * |
| 71463 | ** Synopsis: r[P2]=data |
| @@ -73545,12 +73780,12 @@ | |
| 73545 | *****************************************************************************/ |
| 73546 | } |
| 73547 | |
| 73548 | #ifdef VDBE_PROFILE |
| 73549 | { |
| 73550 | u64 elapsed = sqlite3Hwtime() - start; |
| 73551 | pOp->cycles += elapsed; |
| 73552 | pOp->cnt++; |
| 73553 | } |
| 73554 | #endif |
| 73555 | |
| 73556 | /* The following code adds nothing to the actual functionality |
| @@ -83789,10 +84024,11 @@ | |
| 83789 | */ |
| 83790 | static void decodeIntArray( |
| 83791 | char *zIntArray, /* String containing int array to decode */ |
| 83792 | int nOut, /* Number of slots in aOut[] */ |
| 83793 | tRowcnt *aOut, /* Store integers here */ |
| 83794 | Index *pIndex /* Handle extra flags for this index, if not NULL */ |
| 83795 | ){ |
| 83796 | char *z = zIntArray; |
| 83797 | int c; |
| 83798 | int i; |
| @@ -83807,11 +84043,21 @@ | |
| 83807 | v = 0; |
| 83808 | while( (c=z[0])>='0' && c<='9' ){ |
| 83809 | v = v*10 + c - '0'; |
| 83810 | z++; |
| 83811 | } |
| 83812 | aOut[i] = v; |
| 83813 | if( *z==' ' ) z++; |
| 83814 | } |
| 83815 | #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 83816 | assert( pIndex!=0 ); |
| 83817 | #else |
| @@ -83863,16 +84109,16 @@ | |
| 83863 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 83864 | } |
| 83865 | z = argv[2]; |
| 83866 | |
| 83867 | if( pIndex ){ |
| 83868 | decodeIntArray((char*)z, pIndex->nKeyCol+1, pIndex->aiRowEst, pIndex); |
| 83869 | if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0]; |
| 83870 | }else{ |
| 83871 | Index fakeIdx; |
| 83872 | fakeIdx.szIdxRow = pTable->szTabRow; |
| 83873 | decodeIntArray((char*)z, 1, &pTable->nRowEst, &fakeIdx); |
| 83874 | pTable->szTabRow = fakeIdx.szIdxRow; |
| 83875 | } |
| 83876 | |
| 83877 | return 0; |
| 83878 | } |
| @@ -84060,13 +84306,13 @@ | |
| 84060 | if( pIdx!=pPrevIdx ){ |
| 84061 | initAvgEq(pPrevIdx); |
| 84062 | pPrevIdx = pIdx; |
| 84063 | } |
| 84064 | pSample = &pIdx->aSample[pIdx->nSample]; |
| 84065 | decodeIntArray((char*)sqlite3_column_text(pStmt,1), nCol, pSample->anEq, 0); |
| 84066 | decodeIntArray((char*)sqlite3_column_text(pStmt,2), nCol, pSample->anLt, 0); |
| 84067 | decodeIntArray((char*)sqlite3_column_text(pStmt,3), nCol, pSample->anDLt,0); |
| 84068 | |
| 84069 | /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. |
| 84070 | ** This is in case the sample record is corrupted. In that case, the |
| 84071 | ** sqlite3VdbeRecordCompare() may read up to two varints past the |
| 84072 | ** end of the allocated buffer before it realizes it is dealing with |
| @@ -85924,11 +86170,11 @@ | |
| 85924 | } |
| 85925 | pTable->zName = zName; |
| 85926 | pTable->iPKey = -1; |
| 85927 | pTable->pSchema = db->aDb[iDb].pSchema; |
| 85928 | pTable->nRef = 1; |
| 85929 | pTable->nRowEst = 1048576; |
| 85930 | assert( pParse->pNewTable==0 ); |
| 85931 | pParse->pNewTable = pTable; |
| 85932 | |
| 85933 | /* If this is the magic sqlite_sequence table used by autoincrement, |
| 85934 | ** then record a pointer to this table in the main database structure |
| @@ -86325,11 +86571,14 @@ | |
| 86325 | Parse *pParse, /* Parsing context */ |
| 86326 | Expr *pCheckExpr /* The check expression */ |
| 86327 | ){ |
| 86328 | #ifndef SQLITE_OMIT_CHECK |
| 86329 | Table *pTab = pParse->pNewTable; |
| 86330 | if( pTab && !IN_DECLARE_VTAB ){ |
| 86331 | pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); |
| 86332 | if( pParse->constraintName.n ){ |
| 86333 | sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1); |
| 86334 | } |
| 86335 | }else |
| @@ -87749,19 +87998,19 @@ | |
| 87749 | Index *p; /* Allocated index object */ |
| 87750 | int nByte; /* Bytes of space for Index object + arrays */ |
| 87751 | |
| 87752 | nByte = ROUND8(sizeof(Index)) + /* Index structure */ |
| 87753 | ROUND8(sizeof(char*)*nCol) + /* Index.azColl */ |
| 87754 | ROUND8(sizeof(tRowcnt)*(nCol+1) + /* Index.aiRowEst */ |
| 87755 | sizeof(i16)*nCol + /* Index.aiColumn */ |
| 87756 | sizeof(u8)*nCol); /* Index.aSortOrder */ |
| 87757 | p = sqlite3DbMallocZero(db, nByte + nExtra); |
| 87758 | if( p ){ |
| 87759 | char *pExtra = ((char*)p)+ROUND8(sizeof(Index)); |
| 87760 | p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol); |
| 87761 | p->aiRowEst = (tRowcnt*)pExtra; pExtra += sizeof(tRowcnt)*(nCol+1); |
| 87762 | p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol; |
| 87763 | p->aSortOrder = (u8*)pExtra; |
| 87764 | p->nColumn = nCol; |
| 87765 | p->nKeyCol = nCol - 1; |
| 87766 | *ppExtra = ((char*)p) + nByte; |
| 87767 | } |
| @@ -87987,11 +88236,11 @@ | |
| 87987 | pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol, |
| 87988 | nName + nExtra + 1, &zExtra); |
| 87989 | if( db->mallocFailed ){ |
| 87990 | goto exit_create_index; |
| 87991 | } |
| 87992 | assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) ); |
| 87993 | assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) ); |
| 87994 | pIndex->zName = zExtra; |
| 87995 | zExtra += nName + 1; |
| 87996 | memcpy(pIndex->zName, zName, nName+1); |
| 87997 | pIndex->pTable = pTab; |
| @@ -88268,11 +88517,11 @@ | |
| 88268 | ** |
| 88269 | ** aiRowEst[0] is suppose to contain the number of elements in the index. |
| 88270 | ** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the |
| 88271 | ** number of rows in the table that match any particular value of the |
| 88272 | ** first column of the index. aiRowEst[2] is an estimate of the number |
| 88273 | ** of rows that match any particular combiniation of the first 2 columns |
| 88274 | ** of the index. And so forth. It must always be the case that |
| 88275 | * |
| 88276 | ** aiRowEst[N]<=aiRowEst[N-1] |
| 88277 | ** aiRowEst[N]>=1 |
| 88278 | ** |
| @@ -88279,24 +88528,31 @@ | |
| 88279 | ** Apart from that, we have little to go on besides intuition as to |
| 88280 | ** how aiRowEst[] should be initialized. The numbers generated here |
| 88281 | ** are based on typical values found in actual indices. |
| 88282 | */ |
| 88283 | SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){ |
| 88284 | tRowcnt *a = pIdx->aiRowEst; |
| 88285 | int i; |
| 88286 | tRowcnt n; |
| 88287 | assert( a!=0 ); |
| 88288 | a[0] = pIdx->pTable->nRowEst; |
| 88289 | if( a[0]<10 ) a[0] = 10; |
| 88290 | n = 10; |
| 88291 | for(i=1; i<=pIdx->nKeyCol; i++){ |
| 88292 | a[i] = n; |
| 88293 | if( n>5 ) n--; |
| 88294 | } |
| 88295 | if( pIdx->onError!=OE_None ){ |
| 88296 | a[pIdx->nKeyCol] = 1; |
| 88297 | } |
| 88298 | } |
| 88299 | |
| 88300 | /* |
| 88301 | ** This routine will drop an existing named index. This routine |
| 88302 | ** implements the DROP INDEX statement. |
| @@ -92116,11 +92372,11 @@ | |
| 92116 | } |
| 92117 | if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); |
| 92118 | } |
| 92119 | zVal = (char*)sqlite3_value_text(argv[0]); |
| 92120 | nVal = sqlite3_value_bytes(argv[0]); |
| 92121 | if( nVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal); |
| 92122 | } |
| 92123 | } |
| 92124 | static void groupConcatFinalize(sqlite3_context *context){ |
| 92125 | StrAccum *pAccum; |
| 92126 | pAccum = sqlite3_aggregate_context(context, 0); |
| @@ -94306,10 +94562,11 @@ | |
| 94306 | } |
| 94307 | } |
| 94308 | if( j>=pTab->nCol ){ |
| 94309 | if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){ |
| 94310 | ipkColumn = i; |
| 94311 | }else{ |
| 94312 | sqlite3ErrorMsg(pParse, "table %S has no column named %s", |
| 94313 | pTabList, 0, pColumn->a[i].zName); |
| 94314 | pParse->checkSchema = 1; |
| 94315 | goto insert_cleanup; |
| @@ -95557,18 +95814,27 @@ | |
| 95557 | } |
| 95558 | if( pDest->iPKey!=pSrc->iPKey ){ |
| 95559 | return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ |
| 95560 | } |
| 95561 | for(i=0; i<pDest->nCol; i++){ |
| 95562 | if( pDest->aCol[i].affinity!=pSrc->aCol[i].affinity ){ |
| 95563 | return 0; /* Affinity must be the same on all columns */ |
| 95564 | } |
| 95565 | if( !xferCompatibleCollation(pDest->aCol[i].zColl, pSrc->aCol[i].zColl) ){ |
| 95566 | return 0; /* Collating sequence must be the same on all columns */ |
| 95567 | } |
| 95568 | if( pDest->aCol[i].notNull && !pSrc->aCol[i].notNull ){ |
| 95569 | return 0; /* tab2 must be NOT NULL if tab1 is */ |
| 95570 | } |
| 95571 | } |
| 95572 | for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ |
| 95573 | if( pDestIdx->onError!=OE_None ){ |
| 95574 | destHasUniqueIdx = 1; |
| @@ -98583,17 +98849,19 @@ | |
| 98583 | Table *pTab = sqliteHashData(i); |
| 98584 | sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, pTab->zName, 0); |
| 98585 | sqlite3VdbeAddOp2(v, OP_Null, 0, 2); |
| 98586 | sqlite3VdbeAddOp2(v, OP_Integer, |
| 98587 | (int)sqlite3LogEstToInt(pTab->szTabRow), 3); |
| 98588 | sqlite3VdbeAddOp2(v, OP_Integer, (int)pTab->nRowEst, 4); |
| 98589 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); |
| 98590 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 98591 | sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); |
| 98592 | sqlite3VdbeAddOp2(v, OP_Integer, |
| 98593 | (int)sqlite3LogEstToInt(pIdx->szIdxRow), 3); |
| 98594 | sqlite3VdbeAddOp2(v, OP_Integer, (int)pIdx->aiRowEst[0], 4); |
| 98595 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); |
| 98596 | } |
| 98597 | } |
| 98598 | } |
| 98599 | break; |
| @@ -100760,19 +101028,21 @@ | |
| 100760 | Select *pSelect, /* The whole SELECT statement */ |
| 100761 | int regData /* Register holding data to be sorted */ |
| 100762 | ){ |
| 100763 | Vdbe *v = pParse->pVdbe; |
| 100764 | int nExpr = pSort->pOrderBy->nExpr; |
| 100765 | int regBase = sqlite3GetTempRange(pParse, nExpr+2); |
| 100766 | int regRecord = sqlite3GetTempReg(pParse); |
| 100767 | int nOBSat = pSort->nOBSat; |
| 100768 | int op; |
| 100769 | sqlite3ExprCacheClear(pParse); |
| 100770 | sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, 0); |
| 100771 | sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); |
| 100772 | sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); |
| 100773 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nExpr+2-nOBSat, regRecord); |
| 100774 | if( nOBSat>0 ){ |
| 100775 | int regPrevKey; /* The first nOBSat columns of the previous row */ |
| 100776 | int addrFirst; /* Address of the OP_IfNot opcode */ |
| 100777 | int addrJmp; /* Address of the OP_Jump opcode */ |
| 100778 | VdbeOp *pOp; /* Opcode that opens the sorter */ |
| @@ -100805,14 +101075,10 @@ | |
| 100805 | op = OP_SorterInsert; |
| 100806 | }else{ |
| 100807 | op = OP_IdxInsert; |
| 100808 | } |
| 100809 | sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord); |
| 100810 | if( nOBSat==0 ){ |
| 100811 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 100812 | sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); |
| 100813 | } |
| 100814 | if( pSelect->iLimit ){ |
| 100815 | int addr1, addr2; |
| 100816 | int iLimit; |
| 100817 | if( pSelect->iOffset ){ |
| 100818 | iLimit = pSelect->iOffset+1; |
| @@ -101984,11 +102250,11 @@ | |
| 101984 | /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside |
| 101985 | ** is disabled */ |
| 101986 | assert( db->lookaside.bEnabled==0 ); |
| 101987 | pTab->nRef = 1; |
| 101988 | pTab->zName = 0; |
| 101989 | pTab->nRowEst = 1048576; |
| 101990 | selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); |
| 101991 | selectAddColumnTypeAndCollation(pParse, pTab, pSelect); |
| 101992 | pTab->iPKey = -1; |
| 101993 | if( db->mallocFailed ){ |
| 101994 | sqlite3DeleteTable(db, pTab); |
| @@ -104123,11 +104389,11 @@ | |
| 104123 | pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); |
| 104124 | if( pTab==0 ) return WRC_Abort; |
| 104125 | pTab->nRef = 1; |
| 104126 | pTab->zName = sqlite3DbStrDup(db, pCte->zName); |
| 104127 | pTab->iPKey = -1; |
| 104128 | pTab->nRowEst = 1048576; |
| 104129 | pTab->tabFlags |= TF_Ephemeral; |
| 104130 | pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); |
| 104131 | if( db->mallocFailed ) return SQLITE_NOMEM; |
| 104132 | assert( pFrom->pSelect ); |
| 104133 | |
| @@ -104299,11 +104565,11 @@ | |
| 104299 | pTab->nRef = 1; |
| 104300 | pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); |
| 104301 | while( pSel->pPrior ){ pSel = pSel->pPrior; } |
| 104302 | selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); |
| 104303 | pTab->iPKey = -1; |
| 104304 | pTab->nRowEst = 1048576; |
| 104305 | pTab->tabFlags |= TF_Ephemeral; |
| 104306 | #endif |
| 104307 | }else{ |
| 104308 | /* An ordinary table or view name in the FROM clause */ |
| 104309 | assert( pFrom->pTab==0 ); |
| @@ -104794,14 +105060,15 @@ | |
| 104794 | Parse *pParse, /* Parse context */ |
| 104795 | Table *pTab, /* Table being queried */ |
| 104796 | Index *pIdx /* Index used to optimize scan, or NULL */ |
| 104797 | ){ |
| 104798 | if( pParse->explain==2 ){ |
| 104799 | char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s", |
| 104800 | pTab->zName, |
| 104801 | pIdx ? " USING COVERING INDEX " : "", |
| 104802 | pIdx ? pIdx->zName : "" |
| 104803 | ); |
| 104804 | sqlite3VdbeAddOp4( |
| 104805 | pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC |
| 104806 | ); |
| 104807 | } |
| @@ -104949,11 +105216,11 @@ | |
| 104949 | VdbeComment((v, "%s", pItem->pTab->zName)); |
| 104950 | pItem->addrFillSub = addrTop; |
| 104951 | sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); |
| 104952 | explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); |
| 104953 | sqlite3Select(pParse, pSub, &dest); |
| 104954 | pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; |
| 104955 | pItem->viaCoroutine = 1; |
| 104956 | pItem->regResult = dest.iSdst; |
| 104957 | sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn); |
| 104958 | sqlite3VdbeJumpHere(v, addrTop-1); |
| 104959 | sqlite3ClearTempRegCache(pParse); |
| @@ -104980,11 +105247,11 @@ | |
| 104980 | VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName)); |
| 104981 | } |
| 104982 | sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); |
| 104983 | explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); |
| 104984 | sqlite3Select(pParse, pSub, &dest); |
| 104985 | pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; |
| 104986 | if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); |
| 104987 | retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); |
| 104988 | VdbeComment((v, "end %s", pItem->pTab->zName)); |
| 104989 | sqlite3VdbeChangeP1(v, topAddr, retAddr); |
| 104990 | sqlite3ClearTempRegCache(pParse); |
| @@ -105013,22 +105280,10 @@ | |
| 105013 | explainSetInteger(pParse->iSelectId, iRestoreSelectId); |
| 105014 | return rc; |
| 105015 | } |
| 105016 | #endif |
| 105017 | |
| 105018 | /* If there is both a GROUP BY and an ORDER BY clause and they are |
| 105019 | ** identical, then disable the ORDER BY clause since the GROUP BY |
| 105020 | ** will cause elements to come out in the correct order. This is |
| 105021 | ** an optimization - the correct answer should result regardless. |
| 105022 | ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER |
| 105023 | ** to disable this optimization for testing purposes. |
| 105024 | */ |
| 105025 | if( sqlite3ExprListCompare(p->pGroupBy, sSort.pOrderBy, -1)==0 |
| 105026 | && OptimizationEnabled(db, SQLITE_GroupByOrder) ){ |
| 105027 | sSort.pOrderBy = 0; |
| 105028 | } |
| 105029 | |
| 105030 | /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and |
| 105031 | ** if the select-list is the same as the ORDER BY list, then this query |
| 105032 | ** can be rewritten as a GROUP BY. In other words, this: |
| 105033 | ** |
| 105034 | ** SELECT DISTINCT xyz FROM ... ORDER BY xyz |
| @@ -105153,10 +105408,11 @@ | |
| 105153 | int iAbortFlag; /* Mem address which causes query abort if positive */ |
| 105154 | int groupBySort; /* Rows come from source in GROUP BY order */ |
| 105155 | int addrEnd; /* End of processing for this SELECT */ |
| 105156 | int sortPTab = 0; /* Pseudotable used to decode sorting results */ |
| 105157 | int sortOut = 0; /* Output register from the sorter */ |
| 105158 | |
| 105159 | /* Remove any and all aliases between the result set and the |
| 105160 | ** GROUP BY clause. |
| 105161 | */ |
| 105162 | if( pGroupBy ){ |
| @@ -105172,10 +105428,22 @@ | |
| 105172 | if( p->nSelectRow>100 ) p->nSelectRow = 100; |
| 105173 | }else{ |
| 105174 | p->nSelectRow = 1; |
| 105175 | } |
| 105176 | |
| 105177 | |
| 105178 | /* Create a label to jump to when we want to abort the query */ |
| 105179 | addrEnd = sqlite3VdbeMakeLabel(v); |
| 105180 | |
| 105181 | /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in |
| @@ -105252,11 +105520,12 @@ | |
| 105252 | ** it might be a single loop that uses an index to extract information |
| 105253 | ** in the right order to begin with. |
| 105254 | */ |
| 105255 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); |
| 105256 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, |
| 105257 | WHERE_GROUPBY, 0); |
| 105258 | if( pWInfo==0 ) goto select_end; |
| 105259 | if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ |
| 105260 | /* The optimizer is able to deliver rows in group by order so |
| 105261 | ** we do not have to sort. The OP_OpenEphemeral table will be |
| 105262 | ** cancelled later because we still need to use the pKeyInfo |
| @@ -105317,10 +105586,25 @@ | |
| 105317 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); |
| 105318 | sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); |
| 105319 | VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); |
| 105320 | sAggInfo.useSortingIdx = 1; |
| 105321 | sqlite3ExprCacheClear(pParse); |
| 105322 | } |
| 105323 | |
| 105324 | /* Evaluate the current GROUP BY terms and store in b0, b1, b2... |
| 105325 | ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth) |
| 105326 | ** Then compare the current GROUP BY terms against the GROUP BY terms |
| @@ -109680,10 +109964,11 @@ | |
| 109680 | WhereLoop *pLoops; /* List of all WhereLoop objects */ |
| 109681 | Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ |
| 109682 | LogEst nRowOut; /* Estimated number of output rows */ |
| 109683 | u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ |
| 109684 | i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ |
| 109685 | u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */ |
| 109686 | u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ |
| 109687 | u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ |
| 109688 | u8 nLevel; /* Number of nested loop */ |
| 109689 | int iTop; /* The very beginning of the WHERE loop */ |
| @@ -109739,10 +110024,11 @@ | |
| 109739 | #define WHERE_ONEROW 0x00001000 /* Selects no more than one row */ |
| 109740 | #define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */ |
| 109741 | #define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */ |
| 109742 | #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ |
| 109743 | #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ |
| 109744 | |
| 109745 | /************** End of whereInt.h ********************************************/ |
| 109746 | /************** Continuing where we left off in where.c **********************/ |
| 109747 | |
| 109748 | /* |
| @@ -109951,11 +110237,11 @@ | |
| 109951 | } |
| 109952 | pTerm = &pWC->a[idx = pWC->nTerm++]; |
| 109953 | if( p && ExprHasProperty(p, EP_Unlikely) ){ |
| 109954 | pTerm->truthProb = sqlite3LogEst(p->iTable) - 99; |
| 109955 | }else{ |
| 109956 | pTerm->truthProb = -1; |
| 109957 | } |
| 109958 | pTerm->pExpr = sqlite3ExprSkipCollate(p); |
| 109959 | pTerm->wtFlags = wtFlags; |
| 109960 | pTerm->pWC = pWC; |
| 109961 | pTerm->iParent = -1; |
| @@ -111680,11 +111966,12 @@ | |
| 111680 | tRowcnt iLower, iUpper, iGap; |
| 111681 | if( i==0 ){ |
| 111682 | iLower = 0; |
| 111683 | iUpper = aSample[0].anLt[iCol]; |
| 111684 | }else{ |
| 111685 | iUpper = i>=pIdx->nSample ? pIdx->aiRowEst[0] : aSample[i].anLt[iCol]; |
| 111686 | iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol]; |
| 111687 | } |
| 111688 | aStat[1] = (pIdx->nKeyCol>iCol ? pIdx->aAvgEq[iCol] : 1); |
| 111689 | if( iLower>=iUpper ){ |
| 111690 | iGap = 0; |
| @@ -111698,10 +111985,33 @@ | |
| 111698 | } |
| 111699 | aStat[0] = iLower + iGap; |
| 111700 | } |
| 111701 | } |
| 111702 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 111703 | |
| 111704 | /* |
| 111705 | ** This function is used to estimate the number of rows that will be visited |
| 111706 | ** by scanning an index for a range of values. The range may have an upper |
| 111707 | ** bound, a lower bound, or both. The WHERE clause terms that set the upper |
| @@ -111791,11 +112101,11 @@ | |
| 111791 | aff = p->pTable->aCol[p->aiColumn[nEq]].affinity; |
| 111792 | } |
| 111793 | /* Determine iLower and iUpper using ($P) only. */ |
| 111794 | if( nEq==0 ){ |
| 111795 | iLower = 0; |
| 111796 | iUpper = p->aiRowEst[0]; |
| 111797 | }else{ |
| 111798 | /* Note: this call could be optimized away - since the same values must |
| 111799 | ** have been requested when testing key $P in whereEqualScanEst(). */ |
| 111800 | whereKeyStats(pParse, p, pRec, 0, a); |
| 111801 | iLower = a[0]; |
| @@ -111851,21 +112161,22 @@ | |
| 111851 | #else |
| 111852 | UNUSED_PARAMETER(pParse); |
| 111853 | UNUSED_PARAMETER(pBuilder); |
| 111854 | #endif |
| 111855 | assert( pLower || pUpper ); |
| 111856 | /* TUNING: Each inequality constraint reduces the search space 4-fold. |
| 111857 | ** A BETWEEN operator, therefore, reduces the search space 16-fold */ |
| 111858 | nNew = nOut; |
| 111859 | if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){ |
| 111860 | nNew -= 20; assert( 20==sqlite3LogEst(4) ); |
| 111861 | nOut--; |
| 111862 | } |
| 111863 | if( pUpper ){ |
| 111864 | nNew -= 20; assert( 20==sqlite3LogEst(4) ); |
| 111865 | nOut--; |
| 111866 | } |
| 111867 | if( nNew<10 ) nNew = 10; |
| 111868 | if( nNew<nOut ) nOut = nNew; |
| 111869 | pLoop->nOut = (LogEst)nOut; |
| 111870 | return rc; |
| 111871 | } |
| @@ -111958,26 +112269,27 @@ | |
| 111958 | WhereLoopBuilder *pBuilder, |
| 111959 | ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ |
| 111960 | tRowcnt *pnRow /* Write the revised row estimate here */ |
| 111961 | ){ |
| 111962 | Index *p = pBuilder->pNew->u.btree.pIndex; |
| 111963 | int nRecValid = pBuilder->nRecValid; |
| 111964 | int rc = SQLITE_OK; /* Subfunction return code */ |
| 111965 | tRowcnt nEst; /* Number of rows for a single term */ |
| 111966 | tRowcnt nRowEst = 0; /* New estimate of the number of rows */ |
| 111967 | int i; /* Loop counter */ |
| 111968 | |
| 111969 | assert( p->aSample!=0 ); |
| 111970 | for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){ |
| 111971 | nEst = p->aiRowEst[0]; |
| 111972 | rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst); |
| 111973 | nRowEst += nEst; |
| 111974 | pBuilder->nRecValid = nRecValid; |
| 111975 | } |
| 111976 | |
| 111977 | if( rc==SQLITE_OK ){ |
| 111978 | if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0]; |
| 111979 | *pnRow = nRowEst; |
| 111980 | WHERETRACE(0x10,("IN row estimate: est=%g\n", nRowEst)); |
| 111981 | } |
| 111982 | assert( pBuilder->nRecValid==nRecValid ); |
| 111983 | return rc; |
| @@ -112416,17 +112728,24 @@ | |
| 112416 | zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias); |
| 112417 | } |
| 112418 | if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 |
| 112419 | && ALWAYS(pLoop->u.btree.pIndex!=0) |
| 112420 | ){ |
| 112421 | char *zWhere = explainIndexRange(db, pLoop, pItem->pTab); |
| 112422 | zMsg = sqlite3MAppendf(db, zMsg, |
| 112423 | ((flags & WHERE_AUTO_INDEX) ? |
| 112424 | "%s USING AUTOMATIC %sINDEX%.0s%s" : |
| 112425 | "%s USING %sINDEX %s%s"), |
| 112426 | zMsg, ((flags & WHERE_IDX_ONLY) ? "COVERING " : ""), |
| 112427 | pLoop->u.btree.pIndex->zName, zWhere); |
| 112428 | sqlite3DbFree(db, zWhere); |
| 112429 | }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ |
| 112430 | zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg); |
| 112431 | |
| 112432 | if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ |
| @@ -113459,11 +113778,11 @@ | |
| 113459 | if( pX->nLTerm >= pY->nLTerm ) return 0; /* X is not a subset of Y */ |
| 113460 | if( pX->rRun >= pY->rRun ){ |
| 113461 | if( pX->rRun > pY->rRun ) return 0; /* X costs more than Y */ |
| 113462 | if( pX->nOut > pY->nOut ) return 0; /* X costs more than Y */ |
| 113463 | } |
| 113464 | for(j=0, i=pX->nLTerm-1; i>=0; i--){ |
| 113465 | for(j=pY->nLTerm-1; j>=0; j--){ |
| 113466 | if( pY->aLTerm[j]==pX->aLTerm[i] ) break; |
| 113467 | } |
| 113468 | if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */ |
| 113469 | } |
| @@ -113481,16 +113800,29 @@ | |
| 113481 | ** is a proper subset. |
| 113482 | ** |
| 113483 | ** To say "WhereLoop X is a proper subset of Y" means that X uses fewer |
| 113484 | ** WHERE clause terms than Y and that every WHERE clause term used by X is |
| 113485 | ** also used by Y. |
| 113486 | */ |
| 113487 | static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){ |
| 113488 | if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return; |
| 113489 | for(; p; p=p->pNextLoop){ |
| 113490 | if( p->iTab!=pTemplate->iTab ) continue; |
| 113491 | if( (p->wsFlags & WHERE_INDEXED)==0 ) continue; |
| 113492 | if( whereLoopCheaperProperSubset(p, pTemplate) ){ |
| 113493 | /* Adjust pTemplate cost downward so that it is cheaper than its |
| 113494 | ** subset p */ |
| 113495 | pTemplate->rRun = p->rRun; |
| 113496 | pTemplate->nOut = p->nOut - 1; |
| @@ -113711,17 +114043,24 @@ | |
| 113711 | pX = pLoop->aLTerm[j]; |
| 113712 | if( pX==0 ) continue; |
| 113713 | if( pX==pTerm ) break; |
| 113714 | if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; |
| 113715 | } |
| 113716 | if( j<0 ) pLoop->nOut += pTerm->truthProb; |
| 113717 | } |
| 113718 | } |
| 113719 | |
| 113720 | /* |
| 113721 | ** We have so far matched pBuilder->pNew->u.btree.nEq terms of the index pIndex. |
| 113722 | ** Try to match one more. |
| 113723 | ** |
| 113724 | ** If pProbe->tnum==0, that means pIndex is a fake index used for the |
| 113725 | ** INTEGER PRIMARY KEY. |
| 113726 | */ |
| 113727 | static int whereLoopAddBtreeIndex( |
| @@ -113743,11 +114082,10 @@ | |
| 113743 | u16 saved_nSkip; /* Original value of pNew->u.btree.nSkip */ |
| 113744 | u32 saved_wsFlags; /* Original value of pNew->wsFlags */ |
| 113745 | LogEst saved_nOut; /* Original value of pNew->nOut */ |
| 113746 | int iCol; /* Index of the column in the table */ |
| 113747 | int rc = SQLITE_OK; /* Return code */ |
| 113748 | LogEst nRowEst; /* Estimated index selectivity */ |
| 113749 | LogEst rLogSize; /* Logarithm of table size */ |
| 113750 | WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ |
| 113751 | |
| 113752 | pNew = pBuilder->pNew; |
| 113753 | if( db->mallocFailed ) return SQLITE_NOMEM; |
| @@ -113764,15 +114102,12 @@ | |
| 113764 | if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); |
| 113765 | |
| 113766 | assert( pNew->u.btree.nEq<=pProbe->nKeyCol ); |
| 113767 | if( pNew->u.btree.nEq < pProbe->nKeyCol ){ |
| 113768 | iCol = pProbe->aiColumn[pNew->u.btree.nEq]; |
| 113769 | nRowEst = sqlite3LogEst(pProbe->aiRowEst[pNew->u.btree.nEq+1]); |
| 113770 | if( nRowEst==0 && pProbe->onError==OE_None ) nRowEst = 1; |
| 113771 | }else{ |
| 113772 | iCol = -1; |
| 113773 | nRowEst = 0; |
| 113774 | } |
| 113775 | pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol, |
| 113776 | opMask, pProbe); |
| 113777 | saved_nEq = pNew->u.btree.nEq; |
| 113778 | saved_nSkip = pNew->u.btree.nSkip; |
| @@ -113779,57 +114114,68 @@ | |
| 113779 | saved_nLTerm = pNew->nLTerm; |
| 113780 | saved_wsFlags = pNew->wsFlags; |
| 113781 | saved_prereq = pNew->prereq; |
| 113782 | saved_nOut = pNew->nOut; |
| 113783 | pNew->rSetup = 0; |
| 113784 | rLogSize = estLog(sqlite3LogEst(pProbe->aiRowEst[0])); |
| 113785 | |
| 113786 | /* Consider using a skip-scan if there are no WHERE clause constraints |
| 113787 | ** available for the left-most terms of the index, and if the average |
| 113788 | ** number of repeats in the left-most terms is at least 18. The magic |
| 113789 | ** number 18 was found by experimentation to be the payoff point where |
| 113790 | ** skip-scan become faster than a full-scan. |
| 113791 | */ |
| 113792 | if( pTerm==0 |
| 113793 | && saved_nEq==saved_nSkip |
| 113794 | && saved_nEq+1<pProbe->nKeyCol |
| 113795 | && pProbe->aiRowEst[saved_nEq+1]>=18 /* TUNING: Minimum for skip-scan */ |
| 113796 | && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK |
| 113797 | ){ |
| 113798 | LogEst nIter; |
| 113799 | pNew->u.btree.nEq++; |
| 113800 | pNew->u.btree.nSkip++; |
| 113801 | pNew->aLTerm[pNew->nLTerm++] = 0; |
| 113802 | pNew->wsFlags |= WHERE_SKIPSCAN; |
| 113803 | nIter = sqlite3LogEst(pProbe->aiRowEst[0]/pProbe->aiRowEst[saved_nEq+1]); |
| 113804 | pNew->rRun = rLogSize + nIter; |
| 113805 | pNew->nOut += nIter; |
| 113806 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter); |
| 113807 | pNew->nOut = saved_nOut; |
| 113808 | } |
| 113809 | for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ |
| 113810 | int nIn = 0; |
| 113811 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 113812 | int nRecValid = pBuilder->nRecValid; |
| 113813 | #endif |
| 113814 | if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) |
| 113815 | && (iCol<0 || pSrc->pTab->aCol[iCol].notNull) |
| 113816 | ){ |
| 113817 | continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */ |
| 113818 | } |
| 113819 | if( pTerm->prereqRight & pNew->maskSelf ) continue; |
| 113820 | |
| 113821 | assert( pNew->nOut==saved_nOut ); |
| 113822 | |
| 113823 | pNew->wsFlags = saved_wsFlags; |
| 113824 | pNew->u.btree.nEq = saved_nEq; |
| 113825 | pNew->nLTerm = saved_nLTerm; |
| 113826 | if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ |
| 113827 | pNew->aLTerm[pNew->nLTerm++] = pTerm; |
| 113828 | pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf; |
| 113829 | pNew->rRun = rLogSize; /* Baseline cost is log2(N). Adjustments below */ |
| 113830 | if( pTerm->eOperator & WO_IN ){ |
| 113831 | Expr *pExpr = pTerm->pExpr; |
| 113832 | pNew->wsFlags |= WHERE_COLUMN_IN; |
| 113833 | if( ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 113834 | /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ |
| 113835 | nIn = 46; assert( 46==sqlite3LogEst(25) ); |
| @@ -113837,87 +114183,122 @@ | |
| 113837 | /* "x IN (value, value, ...)" */ |
| 113838 | nIn = sqlite3LogEst(pExpr->x.pList->nExpr); |
| 113839 | } |
| 113840 | assert( nIn>0 ); /* RHS always has 2 or more terms... The parser |
| 113841 | ** changes "x IN (?)" into "x=?". */ |
| 113842 | pNew->rRun += nIn; |
| 113843 | pNew->u.btree.nEq++; |
| 113844 | pNew->nOut = nRowEst + nInMul + nIn; |
| 113845 | }else if( pTerm->eOperator & (WO_EQ) ){ |
| 113846 | assert( |
| 113847 | (pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN|WHERE_SKIPSCAN))!=0 |
| 113848 | || nInMul==0 |
| 113849 | ); |
| 113850 | pNew->wsFlags |= WHERE_COLUMN_EQ; |
| 113851 | if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1)){ |
| 113852 | assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 ); |
| 113853 | if( iCol>=0 && pProbe->onError==OE_None ){ |
| 113854 | pNew->wsFlags |= WHERE_UNQ_WANTED; |
| 113855 | }else{ |
| 113856 | pNew->wsFlags |= WHERE_ONEROW; |
| 113857 | } |
| 113858 | } |
| 113859 | pNew->u.btree.nEq++; |
| 113860 | pNew->nOut = nRowEst + nInMul; |
| 113861 | }else if( pTerm->eOperator & (WO_ISNULL) ){ |
| 113862 | pNew->wsFlags |= WHERE_COLUMN_NULL; |
| 113863 | pNew->u.btree.nEq++; |
| 113864 | /* TUNING: IS NULL selects 2 rows */ |
| 113865 | nIn = 10; assert( 10==sqlite3LogEst(2) ); |
| 113866 | pNew->nOut = nRowEst + nInMul + nIn; |
| 113867 | }else if( pTerm->eOperator & (WO_GT|WO_GE) ){ |
| 113868 | testcase( pTerm->eOperator & WO_GT ); |
| 113869 | testcase( pTerm->eOperator & WO_GE ); |
| 113870 | pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; |
| 113871 | pBtm = pTerm; |
| 113872 | pTop = 0; |
| 113873 | }else{ |
| 113874 | assert( pTerm->eOperator & (WO_LT|WO_LE) ); |
| 113875 | testcase( pTerm->eOperator & WO_LT ); |
| 113876 | testcase( pTerm->eOperator & WO_LE ); |
| 113877 | pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; |
| 113878 | pTop = pTerm; |
| 113879 | pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? |
| 113880 | pNew->aLTerm[pNew->nLTerm-2] : 0; |
| 113881 | } |
| 113882 | if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ |
| 113883 | /* Adjust nOut and rRun for STAT3 range values */ |
| 113884 | assert( pNew->nOut==saved_nOut ); |
| 113885 | whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew); |
| 113886 | } |
| 113887 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 113888 | if( nInMul==0 |
| 113889 | && pProbe->nSample |
| 113890 | && pNew->u.btree.nEq<=pProbe->nSampleCol |
| 113891 | && OptimizationEnabled(db, SQLITE_Stat3) |
| 113892 | ){ |
| 113893 | Expr *pExpr = pTerm->pExpr; |
| 113894 | tRowcnt nOut = 0; |
| 113895 | if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){ |
| 113896 | testcase( pTerm->eOperator & WO_EQ ); |
| 113897 | testcase( pTerm->eOperator & WO_ISNULL ); |
| 113898 | rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); |
| 113899 | }else if( (pTerm->eOperator & WO_IN) |
| 113900 | && !ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 113901 | rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); |
| 113902 | } |
| 113903 | assert( nOut==0 || rc==SQLITE_OK ); |
| 113904 | if( nOut ){ |
| 113905 | pNew->nOut = sqlite3LogEst(nOut); |
| 113906 | if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; |
| 113907 | } |
| 113908 | } |
| 113909 | #endif |
| 113910 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 113911 | /* Each row involves a step of the index, then a binary search of |
| 113912 | ** the main table */ |
| 113913 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun,rLogSize>27 ? rLogSize-17 : 10); |
| 113914 | } |
| 113915 | /* Step cost for each output row */ |
| 113916 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut); |
| 113917 | whereLoopOutputAdjust(pBuilder->pWC, pNew); |
| 113918 | rc = whereLoopInsert(pBuilder, pNew); |
| 113919 | if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 |
| 113920 | && pNew->u.btree.nEq<(pProbe->nKeyCol + (pProbe->zName!=0)) |
| 113921 | ){ |
| 113922 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); |
| 113923 | } |
| @@ -113997,19 +114378,42 @@ | |
| 113997 | |
| 113998 | /* |
| 113999 | ** Add all WhereLoop objects for a single table of the join where the table |
| 114000 | ** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be |
| 114001 | ** a b-tree table, not a virtual table. |
| 114002 | */ |
| 114003 | static int whereLoopAddBtree( |
| 114004 | WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
| 114005 | Bitmask mExtra /* Extra prerequesites for using this table */ |
| 114006 | ){ |
| 114007 | WhereInfo *pWInfo; /* WHERE analysis context */ |
| 114008 | Index *pProbe; /* An index we are evaluating */ |
| 114009 | Index sPk; /* A fake index object for the primary key */ |
| 114010 | tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */ |
| 114011 | i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */ |
| 114012 | SrcList *pTabList; /* The FROM clause */ |
| 114013 | struct SrcList_item *pSrc; /* The FROM clause btree term to add */ |
| 114014 | WhereLoop *pNew; /* Template WhereLoop object */ |
| 114015 | int rc = SQLITE_OK; /* Return code */ |
| @@ -114040,24 +114444,25 @@ | |
| 114040 | ** indices to follow */ |
| 114041 | Index *pFirst; /* First of real indices on the table */ |
| 114042 | memset(&sPk, 0, sizeof(Index)); |
| 114043 | sPk.nKeyCol = 1; |
| 114044 | sPk.aiColumn = &aiColumnPk; |
| 114045 | sPk.aiRowEst = aiRowEstPk; |
| 114046 | sPk.onError = OE_Replace; |
| 114047 | sPk.pTable = pTab; |
| 114048 | aiRowEstPk[0] = pTab->nRowEst; |
| 114049 | aiRowEstPk[1] = 1; |
| 114050 | pFirst = pSrc->pTab->pIndex; |
| 114051 | if( pSrc->notIndexed==0 ){ |
| 114052 | /* The real indices of the table are only considered if the |
| 114053 | ** NOT INDEXED qualifier is omitted from the FROM clause */ |
| 114054 | sPk.pNext = pFirst; |
| 114055 | } |
| 114056 | pProbe = &sPk; |
| 114057 | } |
| 114058 | rSize = sqlite3LogEst(pTab->nRowEst); |
| 114059 | rLogSize = estLog(rSize); |
| 114060 | |
| 114061 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 114062 | /* Automatic indexes */ |
| 114063 | if( !pBuilder->pOrSet |
| @@ -114103,10 +114508,11 @@ | |
| 114103 | for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){ |
| 114104 | if( pProbe->pPartIdxWhere!=0 |
| 114105 | && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){ |
| 114106 | continue; /* Partial index inappropriate for this query */ |
| 114107 | } |
| 114108 | pNew->u.btree.nEq = 0; |
| 114109 | pNew->u.btree.nSkip = 0; |
| 114110 | pNew->nLTerm = 0; |
| 114111 | pNew->iSortIdx = 0; |
| 114112 | pNew->rSetup = 0; |
| @@ -114120,14 +114526,12 @@ | |
| 114120 | /* Integer primary key index */ |
| 114121 | pNew->wsFlags = WHERE_IPK; |
| 114122 | |
| 114123 | /* Full table scan */ |
| 114124 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 114125 | /* TUNING: Cost of full table scan is 3*(N + log2(N)). |
| 114126 | ** + The extra 3 factor is to encourage the use of indexed lookups |
| 114127 | ** over full scans. FIXME */ |
| 114128 | pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 16; |
| 114129 | whereLoopOutputAdjust(pWC, pNew); |
| 114130 | rc = whereLoopInsert(pBuilder, pNew); |
| 114131 | pNew->nOut = rSize; |
| 114132 | if( rc ) break; |
| 114133 | }else{ |
| @@ -114150,39 +114554,20 @@ | |
| 114150 | && sqlite3GlobalConfig.bUseCis |
| 114151 | && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan) |
| 114152 | ) |
| 114153 | ){ |
| 114154 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 114155 | /* TUNING: The base cost of an index scan is N + log2(N). |
| 114156 | ** The log2(N) is for the initial seek to the beginning and the N |
| 114157 | ** is for the scan itself. */ |
| 114158 | pNew->rRun = sqlite3LogEstAdd(rSize, rLogSize); |
| 114159 | if( m==0 ){ |
| 114160 | /* TUNING: Cost of a covering index scan is K*(N + log2(N)). |
| 114161 | ** + The extra factor K of between 1.1 and 3.0 that depends |
| 114162 | ** on the relative sizes of the table and the index. K |
| 114163 | ** is smaller for smaller indices, thus favoring them. |
| 114164 | ** The upper bound on K (3.0) matches the penalty factor |
| 114165 | ** on a full table scan that tries to encourage the use of |
| 114166 | ** indexed lookups over full scans. |
| 114167 | */ |
| 114168 | pNew->rRun += 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; |
| 114169 | }else{ |
| 114170 | /* TUNING: The cost of scanning a non-covering index is multiplied |
| 114171 | ** by log2(N) to account for the binary search of the main table |
| 114172 | ** that must happen for each row of the index. |
| 114173 | ** TODO: Should there be a multiplier here, analogous to the 3x |
| 114174 | ** multiplier for a fulltable scan or covering index scan, to |
| 114175 | ** further discourage the use of an index scan? Or is the log2(N) |
| 114176 | ** term sufficient discouragement? |
| 114177 | ** TODO: What if some or all of the WHERE clause terms can be |
| 114178 | ** computed without reference to the original table. Then the |
| 114179 | ** penality should reduce to logK where K is the number of output |
| 114180 | ** rows. |
| 114181 | */ |
| 114182 | pNew->rRun += rLogSize; |
| 114183 | } |
| 114184 | whereLoopOutputAdjust(pWC, pNew); |
| 114185 | rc = whereLoopInsert(pBuilder, pNew); |
| 114186 | pNew->nOut = rSize; |
| 114187 | if( rc ) break; |
| 114188 | } |
| @@ -114382,11 +114767,11 @@ | |
| 114382 | WhereTerm *pTerm, *pWCEnd; |
| 114383 | int rc = SQLITE_OK; |
| 114384 | int iCur; |
| 114385 | WhereClause tempWC; |
| 114386 | WhereLoopBuilder sSubBuild; |
| 114387 | WhereOrSet sSum, sCur, sPrev; |
| 114388 | struct SrcList_item *pItem; |
| 114389 | |
| 114390 | pWC = pBuilder->pWC; |
| 114391 | if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK; |
| 114392 | pWCEnd = pWC->a + pWC->nTerm; |
| @@ -114438,10 +114823,11 @@ | |
| 114438 | break; |
| 114439 | }else if( once ){ |
| 114440 | whereOrMove(&sSum, &sCur); |
| 114441 | once = 0; |
| 114442 | }else{ |
| 114443 | whereOrMove(&sPrev, &sSum); |
| 114444 | sSum.n = 0; |
| 114445 | for(i=0; i<sPrev.n; i++){ |
| 114446 | for(j=0; j<sCur.n; j++){ |
| 114447 | whereOrInsert(&sSum, sPrev.a[i].prereq | sCur.a[j].prereq, |
| @@ -114456,12 +114842,23 @@ | |
| 114456 | pNew->wsFlags = WHERE_MULTI_OR; |
| 114457 | pNew->rSetup = 0; |
| 114458 | pNew->iSortIdx = 0; |
| 114459 | memset(&pNew->u, 0, sizeof(pNew->u)); |
| 114460 | for(i=0; rc==SQLITE_OK && i<sSum.n; i++){ |
| 114461 | /* TUNING: Multiple by 3.5 for the secondary table lookup */ |
| 114462 | pNew->rRun = sSum.a[i].rRun + 18; |
| 114463 | pNew->nOut = sSum.a[i].nOut; |
| 114464 | pNew->prereq = sSum.a[i].prereq; |
| 114465 | rc = whereLoopInsert(pBuilder, pNew); |
| 114466 | } |
| 114467 | } |
| @@ -114520,11 +114917,11 @@ | |
| 114520 | ** N<0: Unknown yet how many terms of ORDER BY might be satisfied. |
| 114521 | ** |
| 114522 | ** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as |
| 114523 | ** strict. With GROUP BY and DISTINCT the only requirement is that |
| 114524 | ** equivalent rows appear immediately adjacent to one another. GROUP BY |
| 114525 | ** and DISTINT do not require rows to appear in any particular order as long |
| 114526 | ** as equivelent rows are grouped together. Thus for GROUP BY and DISTINCT |
| 114527 | ** the pOrderBy terms can be matched in any order. With ORDER BY, the |
| 114528 | ** pOrderBy terms must be matched in strict left-to-right order. |
| 114529 | */ |
| 114530 | static i8 wherePathSatisfiesOrderBy( |
| @@ -114581,18 +114978,10 @@ | |
| 114581 | ** rowid appears in the ORDER BY clause, the corresponding WhereLoop is |
| 114582 | ** automatically order-distinct. |
| 114583 | */ |
| 114584 | |
| 114585 | assert( pOrderBy!=0 ); |
| 114586 | |
| 114587 | /* Sortability of virtual tables is determined by the xBestIndex method |
| 114588 | ** of the virtual table itself */ |
| 114589 | if( pLast->wsFlags & WHERE_VIRTUALTABLE ){ |
| 114590 | testcase( nLoop>0 ); /* True when outer loops are one-row and match |
| 114591 | ** no ORDER BY terms */ |
| 114592 | return pLast->u.vtab.isOrdered; |
| 114593 | } |
| 114594 | if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0; |
| 114595 | |
| 114596 | nOrderBy = pOrderBy->nExpr; |
| 114597 | testcase( nOrderBy==BMS-1 ); |
| 114598 | if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */ |
| @@ -114601,11 +114990,14 @@ | |
| 114601 | orderDistinctMask = 0; |
| 114602 | ready = 0; |
| 114603 | for(iLoop=0; isOrderDistinct && obSat<obDone && iLoop<=nLoop; iLoop++){ |
| 114604 | if( iLoop>0 ) ready |= pLoop->maskSelf; |
| 114605 | pLoop = iLoop<nLoop ? pPath->aLoop[iLoop] : pLast; |
| 114606 | assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ); |
| 114607 | iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor; |
| 114608 | |
| 114609 | /* Mark off any ORDER BY term X that is a column in the table of |
| 114610 | ** the current loop for which there is term in the WHERE |
| 114611 | ** clause of the form X IS NULL or X=? that reference only outer |
| @@ -114689,11 +115081,11 @@ | |
| 114689 | ){ |
| 114690 | isOrderDistinct = 0; |
| 114691 | } |
| 114692 | |
| 114693 | /* Find the ORDER BY term that corresponds to the j-th column |
| 114694 | ** of the index and and mark that ORDER BY term off |
| 114695 | */ |
| 114696 | bOnce = 1; |
| 114697 | isMatch = 0; |
| 114698 | for(i=0; bOnce && i<nOrderBy; i++){ |
| 114699 | if( MASKBIT(i) & obSat ) continue; |
| @@ -114769,10 +115161,40 @@ | |
| 114769 | return 0; |
| 114770 | } |
| 114771 | return -1; |
| 114772 | } |
| 114773 | |
| 114774 | #ifdef WHERETRACE_ENABLED |
| 114775 | /* For debugging use only: */ |
| 114776 | static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){ |
| 114777 | static char zName[65]; |
| 114778 | int i; |
| @@ -114780,11 +115202,10 @@ | |
| 114780 | if( pLast ) zName[i++] = pLast->cId; |
| 114781 | zName[i] = 0; |
| 114782 | return zName; |
| 114783 | } |
| 114784 | #endif |
| 114785 | |
| 114786 | |
| 114787 | /* |
| 114788 | ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine |
| 114789 | ** attempts to find the lowest cost path that visits each WhereLoop |
| 114790 | ** once. This path is then loaded into the pWInfo->a[].pWLoop fields. |
| @@ -114879,26 +115300,31 @@ | |
| 114879 | if( isOrdered<0 ){ |
| 114880 | isOrdered = wherePathSatisfiesOrderBy(pWInfo, |
| 114881 | pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, |
| 114882 | iLoop, pWLoop, &revMask); |
| 114883 | if( isOrdered>=0 && isOrdered<nOrderBy ){ |
| 114884 | /* TUNING: Estimated cost of sorting is N*log(N). |
| 114885 | ** If the order-by clause has X terms but only the last Y terms |
| 114886 | ** are out of order, then block-sorting will reduce the sorting |
| 114887 | ** cost to N*log(N)*log(Y/X). The log(Y/X) term is computed |
| 114888 | ** by rScale. |
| 114889 | ** TODO: Should the sorting cost get a small multiplier to help |
| 114890 | ** discourage the use of sorting and encourage the use of index |
| 114891 | ** scans instead? |
| 114892 | */ |
| 114893 | LogEst rScale, rSortCost; |
| 114894 | assert( nOrderBy>0 ); |
| 114895 | rScale = sqlite3LogEst((nOrderBy-isOrdered)*100/nOrderBy) - 66; |
| 114896 | rSortCost = nRowEst + estLog(nRowEst) + rScale; |
| 114897 | /* TUNING: The cost of implementing DISTINCT using a B-TREE is |
| 114898 | ** also N*log(N) but it has a larger constant of proportionality. |
| 114899 | ** Multiply by 3.0. */ |
| 114900 | if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 114901 | rSortCost += 16; |
| 114902 | } |
| 114903 | WHERETRACE(0x002, |
| 114904 | ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", |
| @@ -115062,11 +115488,23 @@ | |
| 115062 | }else{ |
| 115063 | pWInfo->nOBSat = pFrom->isOrdered; |
| 115064 | if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0; |
| 115065 | pWInfo->revMask = pFrom->revLoop; |
| 115066 | } |
| 115067 | } |
| 115068 | pWInfo->nRowOut = pFrom->nRow; |
| 115069 | |
| 115070 | /* Free temporary memory and return success */ |
| 115071 | sqlite3DbFree(db, pSpace); |
| 115072 | return SQLITE_OK; |
| @@ -123654,10 +124092,32 @@ | |
| 123654 | int sz = va_arg(ap, int); |
| 123655 | int *aProg = va_arg(ap, int*); |
| 123656 | rc = sqlite3BitvecBuiltinTest(sz, aProg); |
| 123657 | break; |
| 123658 | } |
| 123659 | |
| 123660 | /* |
| 123661 | ** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) |
| 123662 | ** |
| 123663 | ** Register hooks to call to indicate which malloc() failures |
| @@ -123964,11 +124424,11 @@ | |
| 123964 | ** Return 1 if database is read-only or 0 if read/write. Return -1 if |
| 123965 | ** no such database exists. |
| 123966 | */ |
| 123967 | SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){ |
| 123968 | Btree *pBt = sqlite3DbNameToBtree(db, zDbName); |
| 123969 | return pBt ? sqlite3PagerIsreadonly(sqlite3BtreePager(pBt)) : -1; |
| 123970 | } |
| 123971 | |
| 123972 | /************** End of main.c ************************************************/ |
| 123973 | /************** Begin file notify.c ******************************************/ |
| 123974 | /* |
| @@ -125084,17 +125544,17 @@ | |
| 125084 | char **azColumn; /* column names. malloced */ |
| 125085 | u8 *abNotindexed; /* True for 'notindexed' columns */ |
| 125086 | sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ |
| 125087 | char *zContentTbl; /* content=xxx option, or NULL */ |
| 125088 | char *zLanguageid; /* languageid=xxx option, or NULL */ |
| 125089 | u8 bAutoincrmerge; /* True if automerge=1 */ |
| 125090 | u32 nLeafAdd; /* Number of leaf blocks added this trans */ |
| 125091 | |
| 125092 | /* Precompiled statements used by the implementation. Each of these |
| 125093 | ** statements is run and reset within a single virtual table API call. |
| 125094 | */ |
| 125095 | sqlite3_stmt *aStmt[37]; |
| 125096 | |
| 125097 | char *zReadExprlist; |
| 125098 | char *zWriteExprlist; |
| 125099 | |
| 125100 | int nNodeSize; /* Soft limit for node size */ |
| @@ -126512,11 +126972,11 @@ | |
| 126512 | p->nMaxPendingData = FTS3_MAX_PENDING_DATA; |
| 126513 | p->bHasDocsize = (isFts4 && bNoDocsize==0); |
| 126514 | p->bHasStat = isFts4; |
| 126515 | p->bFts4 = isFts4; |
| 126516 | p->bDescIdx = bDescIdx; |
| 126517 | p->bAutoincrmerge = 0xff; /* 0xff means setting unknown */ |
| 126518 | p->zContentTbl = zContent; |
| 126519 | p->zLanguageid = zLanguageid; |
| 126520 | zContent = 0; |
| 126521 | zLanguageid = 0; |
| 126522 | TESTONLY( p->inTransaction = -1 ); |
| @@ -128481,19 +128941,22 @@ | |
| 128481 | const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */ |
| 128482 | |
| 128483 | Fts3Table *p = (Fts3Table*)pVtab; |
| 128484 | int rc = sqlite3Fts3PendingTermsFlush(p); |
| 128485 | |
| 128486 | if( rc==SQLITE_OK && p->bAutoincrmerge==1 && p->nLeafAdd>(nMinMerge/16) ){ |
| 128487 | int mxLevel = 0; /* Maximum relative level value in db */ |
| 128488 | int A; /* Incr-merge parameter A */ |
| 128489 | |
| 128490 | rc = sqlite3Fts3MaxLevel(p, &mxLevel); |
| 128491 | assert( rc==SQLITE_OK || mxLevel==0 ); |
| 128492 | A = p->nLeafAdd * mxLevel; |
| 128493 | A += (A/2); |
| 128494 | if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, 8); |
| 128495 | } |
| 128496 | sqlite3Fts3SegmentsClose(p); |
| 128497 | return rc; |
| 128498 | } |
| 128499 | |
| @@ -131712,44 +132175,27 @@ | |
| 131712 | sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; |
| 131713 | sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; |
| 131714 | int rc; |
| 131715 | sqlite3_tokenizer_cursor *pCursor; |
| 131716 | Fts3Expr *pRet = 0; |
| 131717 | int nConsumed = 0; |
| 131718 | |
| 131719 | rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor); |
| 131720 | if( rc==SQLITE_OK ){ |
| 131721 | const char *zToken; |
| 131722 | int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; |
| 131723 | int nByte; /* total space to allocate */ |
| 131724 | |
| 131725 | rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); |
| 131726 | |
| 131727 | if( (rc==SQLITE_OK || rc==SQLITE_DONE) && sqlite3_fts3_enable_parentheses ){ |
| 131728 | int i; |
| 131729 | if( rc==SQLITE_DONE ) iStart = n; |
| 131730 | for(i=0; i<iStart; i++){ |
| 131731 | if( z[i]=='(' ){ |
| 131732 | pParse->nNest++; |
| 131733 | rc = fts3ExprParse(pParse, &z[i+1], n-i-1, &pRet, &nConsumed); |
| 131734 | if( rc==SQLITE_OK && !pRet ){ |
| 131735 | rc = SQLITE_DONE; |
| 131736 | } |
| 131737 | nConsumed = (int)(i + 1 + nConsumed); |
| 131738 | break; |
| 131739 | } |
| 131740 | |
| 131741 | if( z[i]==')' ){ |
| 131742 | rc = SQLITE_DONE; |
| 131743 | pParse->nNest--; |
| 131744 | nConsumed = i+1; |
| 131745 | break; |
| 131746 | } |
| 131747 | } |
| 131748 | } |
| 131749 | |
| 131750 | if( nConsumed==0 && rc==SQLITE_OK ){ |
| 131751 | nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; |
| 131752 | pRet = (Fts3Expr *)fts3MallocZero(nByte); |
| 131753 | if( !pRet ){ |
| 131754 | rc = SQLITE_NOMEM; |
| 131755 | }else{ |
| @@ -131779,17 +132225,18 @@ | |
| 131779 | break; |
| 131780 | } |
| 131781 | } |
| 131782 | |
| 131783 | } |
| 131784 | nConsumed = iEnd; |
| 131785 | } |
| 131786 | |
| 131787 | pModule->xClose(pCursor); |
| 131788 | } |
| 131789 | |
| 131790 | *pnConsumed = nConsumed; |
| 131791 | *ppExpr = pRet; |
| 131792 | return rc; |
| 131793 | } |
| 131794 | |
| 131795 | |
| @@ -132035,10 +132482,25 @@ | |
| 132035 | return SQLITE_ERROR; |
| 132036 | } |
| 132037 | return getNextString(pParse, &zInput[1], ii-1, ppExpr); |
| 132038 | } |
| 132039 | |
| 132040 | |
| 132041 | /* If control flows to this point, this must be a regular token, or |
| 132042 | ** the end of the input. Read a regular token using the sqlite3_tokenizer |
| 132043 | ** interface. Before doing so, figure out if there is an explicit |
| 132044 | ** column specifier for the token. |
| @@ -132153,100 +132615,104 @@ | |
| 132153 | int isRequirePhrase = 1; |
| 132154 | |
| 132155 | while( rc==SQLITE_OK ){ |
| 132156 | Fts3Expr *p = 0; |
| 132157 | int nByte = 0; |
| 132158 | rc = getNextNode(pParse, zIn, nIn, &p, &nByte); |
| 132159 | if( rc==SQLITE_OK ){ |
| 132160 | int isPhrase; |
| 132161 | |
| 132162 | if( !sqlite3_fts3_enable_parentheses |
| 132163 | && p->eType==FTSQUERY_PHRASE && pParse->isNot |
| 132164 | ){ |
| 132165 | /* Create an implicit NOT operator. */ |
| 132166 | Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr)); |
| 132167 | if( !pNot ){ |
| 132168 | sqlite3Fts3ExprFree(p); |
| 132169 | rc = SQLITE_NOMEM; |
| 132170 | goto exprparse_out; |
| 132171 | } |
| 132172 | pNot->eType = FTSQUERY_NOT; |
| 132173 | pNot->pRight = p; |
| 132174 | p->pParent = pNot; |
| 132175 | if( pNotBranch ){ |
| 132176 | pNot->pLeft = pNotBranch; |
| 132177 | pNotBranch->pParent = pNot; |
| 132178 | } |
| 132179 | pNotBranch = pNot; |
| 132180 | p = pPrev; |
| 132181 | }else{ |
| 132182 | int eType = p->eType; |
| 132183 | isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); |
| 132184 | |
| 132185 | /* The isRequirePhrase variable is set to true if a phrase or |
| 132186 | ** an expression contained in parenthesis is required. If a |
| 132187 | ** binary operator (AND, OR, NOT or NEAR) is encounted when |
| 132188 | ** isRequirePhrase is set, this is a syntax error. |
| 132189 | */ |
| 132190 | if( !isPhrase && isRequirePhrase ){ |
| 132191 | sqlite3Fts3ExprFree(p); |
| 132192 | rc = SQLITE_ERROR; |
| 132193 | goto exprparse_out; |
| 132194 | } |
| 132195 | |
| 132196 | if( isPhrase && !isRequirePhrase ){ |
| 132197 | /* Insert an implicit AND operator. */ |
| 132198 | Fts3Expr *pAnd; |
| 132199 | assert( pRet && pPrev ); |
| 132200 | pAnd = fts3MallocZero(sizeof(Fts3Expr)); |
| 132201 | if( !pAnd ){ |
| 132202 | sqlite3Fts3ExprFree(p); |
| 132203 | rc = SQLITE_NOMEM; |
| 132204 | goto exprparse_out; |
| 132205 | } |
| 132206 | pAnd->eType = FTSQUERY_AND; |
| 132207 | insertBinaryOperator(&pRet, pPrev, pAnd); |
| 132208 | pPrev = pAnd; |
| 132209 | } |
| 132210 | |
| 132211 | /* This test catches attempts to make either operand of a NEAR |
| 132212 | ** operator something other than a phrase. For example, either of |
| 132213 | ** the following: |
| 132214 | ** |
| 132215 | ** (bracketed expression) NEAR phrase |
| 132216 | ** phrase NEAR (bracketed expression) |
| 132217 | ** |
| 132218 | ** Return an error in either case. |
| 132219 | */ |
| 132220 | if( pPrev && ( |
| 132221 | (eType==FTSQUERY_NEAR && !isPhrase && pPrev->eType!=FTSQUERY_PHRASE) |
| 132222 | || (eType!=FTSQUERY_PHRASE && isPhrase && pPrev->eType==FTSQUERY_NEAR) |
| 132223 | )){ |
| 132224 | sqlite3Fts3ExprFree(p); |
| 132225 | rc = SQLITE_ERROR; |
| 132226 | goto exprparse_out; |
| 132227 | } |
| 132228 | |
| 132229 | if( isPhrase ){ |
| 132230 | if( pRet ){ |
| 132231 | assert( pPrev && pPrev->pLeft && pPrev->pRight==0 ); |
| 132232 | pPrev->pRight = p; |
| 132233 | p->pParent = pPrev; |
| 132234 | }else{ |
| 132235 | pRet = p; |
| 132236 | } |
| 132237 | }else{ |
| 132238 | insertBinaryOperator(&pRet, pPrev, p); |
| 132239 | } |
| 132240 | isRequirePhrase = !isPhrase; |
| 132241 | } |
| 132242 | assert( nByte>0 ); |
| 132243 | } |
| 132244 | assert( rc!=SQLITE_OK || (nByte>0 && nByte<=nIn) ); |
| 132245 | nIn -= nByte; |
| 132246 | zIn += nByte; |
| 132247 | pPrev = p; |
| 132248 | } |
| 132249 | |
| 132250 | if( rc==SQLITE_DONE && pRet && isRequirePhrase ){ |
| 132251 | rc = SQLITE_ERROR; |
| 132252 | } |
| @@ -135230,10 +135696,11 @@ | |
| 135230 | int nMalloc; /* Size of malloc'd buffer at zMalloc */ |
| 135231 | char *zMalloc; /* Malloc'd space (possibly) used for zTerm */ |
| 135232 | int nSize; /* Size of allocation at aData */ |
| 135233 | int nData; /* Bytes of data in aData */ |
| 135234 | char *aData; /* Pointer to block from malloc() */ |
| 135235 | }; |
| 135236 | |
| 135237 | /* |
| 135238 | ** Type SegmentNode is used by the following three functions to create |
| 135239 | ** the interior part of the segment b+-tree structures (everything except |
| @@ -135304,10 +135771,14 @@ | |
| 135304 | #define SQL_SELECT_SEGDIR 32 |
| 135305 | #define SQL_CHOMP_SEGDIR 33 |
| 135306 | #define SQL_SEGMENT_IS_APPENDABLE 34 |
| 135307 | #define SQL_SELECT_INDEXES 35 |
| 135308 | #define SQL_SELECT_MXLEVEL 36 |
| 135309 | |
| 135310 | /* |
| 135311 | ** This function is used to obtain an SQLite prepared statement handle |
| 135312 | ** for the statement identified by the second argument. If successful, |
| 135313 | ** *pp is set to the requested statement handle and SQLITE_OK returned. |
| @@ -135406,11 +135877,22 @@ | |
| 135406 | ** Return the list of valid segment indexes for absolute level ? */ |
| 135407 | /* 35 */ "SELECT idx FROM %Q.'%q_segdir' WHERE level=? ORDER BY 1 ASC", |
| 135408 | |
| 135409 | /* SQL_SELECT_MXLEVEL |
| 135410 | ** Return the largest relative level in the FTS index or indexes. */ |
| 135411 | /* 36 */ "SELECT max( level %% 1024 ) FROM %Q.'%q_segdir'" |
| 135412 | }; |
| 135413 | int rc = SQLITE_OK; |
| 135414 | sqlite3_stmt *pStmt; |
| 135415 | |
| 135416 | assert( SizeofArray(azSql)==SizeofArray(p->aStmt) ); |
| @@ -136947,10 +137429,11 @@ | |
| 136947 | sqlite3_int64 iLevel, /* Value for "level" field (absolute level) */ |
| 136948 | int iIdx, /* Value for "idx" field */ |
| 136949 | sqlite3_int64 iStartBlock, /* Value for "start_block" field */ |
| 136950 | sqlite3_int64 iLeafEndBlock, /* Value for "leaves_end_block" field */ |
| 136951 | sqlite3_int64 iEndBlock, /* Value for "end_block" field */ |
| 136952 | char *zRoot, /* Blob value for "root" field */ |
| 136953 | int nRoot /* Number of bytes in buffer zRoot */ |
| 136954 | ){ |
| 136955 | sqlite3_stmt *pStmt; |
| 136956 | int rc = fts3SqlStmt(p, SQL_INSERT_SEGDIR, &pStmt, 0); |
| @@ -136957,11 +137440,17 @@ | |
| 136957 | if( rc==SQLITE_OK ){ |
| 136958 | sqlite3_bind_int64(pStmt, 1, iLevel); |
| 136959 | sqlite3_bind_int(pStmt, 2, iIdx); |
| 136960 | sqlite3_bind_int64(pStmt, 3, iStartBlock); |
| 136961 | sqlite3_bind_int64(pStmt, 4, iLeafEndBlock); |
| 136962 | sqlite3_bind_int64(pStmt, 5, iEndBlock); |
| 136963 | sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC); |
| 136964 | sqlite3_step(pStmt); |
| 136965 | rc = sqlite3_reset(pStmt); |
| 136966 | } |
| 136967 | return rc; |
| @@ -137282,10 +137771,13 @@ | |
| 137282 | sqlite3Fts3VarintLen(nTerm) + /* varint containing suffix size */ |
| 137283 | nTerm + /* Term suffix */ |
| 137284 | sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ |
| 137285 | nDoclist; /* Doclist data */ |
| 137286 | } |
| 137287 | |
| 137288 | /* If the buffer currently allocated is too small for this entry, realloc |
| 137289 | ** the buffer to make it large enough. |
| 137290 | */ |
| 137291 | if( nReq>pWriter->nSize ){ |
| @@ -137354,17 +137846,17 @@ | |
| 137354 | if( rc==SQLITE_OK ){ |
| 137355 | rc = fts3NodeWrite(p, pWriter->pTree, 1, |
| 137356 | pWriter->iFirst, pWriter->iFree, &iLast, &zRoot, &nRoot); |
| 137357 | } |
| 137358 | if( rc==SQLITE_OK ){ |
| 137359 | rc = fts3WriteSegdir( |
| 137360 | p, iLevel, iIdx, pWriter->iFirst, iLastLeaf, iLast, zRoot, nRoot); |
| 137361 | } |
| 137362 | }else{ |
| 137363 | /* The entire tree fits on the root node. Write it to the segdir table. */ |
| 137364 | rc = fts3WriteSegdir( |
| 137365 | p, iLevel, iIdx, 0, 0, 0, pWriter->aData, pWriter->nData); |
| 137366 | } |
| 137367 | p->nLeafAdd++; |
| 137368 | return rc; |
| 137369 | } |
| 137370 | |
| @@ -137443,10 +137935,41 @@ | |
| 137443 | if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 137444 | *pnMax = sqlite3_column_int64(pStmt, 0); |
| 137445 | } |
| 137446 | return sqlite3_reset(pStmt); |
| 137447 | } |
| 137448 | |
| 137449 | /* |
| 137450 | ** Delete all entries in the %_segments table associated with the segment |
| 137451 | ** opened with seg-reader pSeg. This function does not affect the contents |
| 137452 | ** of the %_segdir table. |
| @@ -137978,10 +138501,144 @@ | |
| 137978 | pCsr->nSegment = 0; |
| 137979 | pCsr->apSegment = 0; |
| 137980 | pCsr->aBuffer = 0; |
| 137981 | } |
| 137982 | } |
| 137983 | |
| 137984 | /* |
| 137985 | ** Merge all level iLevel segments in the database into a single |
| 137986 | ** iLevel+1 segment. Or, if iLevel<0, merge all segments into a |
| 137987 | ** single segment with a level equal to the numerically largest level |
| @@ -138003,10 +138660,11 @@ | |
| 138003 | sqlite3_int64 iNewLevel = 0; /* Level/index to create new segment at */ |
| 138004 | SegmentWriter *pWriter = 0; /* Used to write the new, merged, segment */ |
| 138005 | Fts3SegFilter filter; /* Segment term filter condition */ |
| 138006 | Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */ |
| 138007 | int bIgnoreEmpty = 0; /* True to ignore empty segments */ |
| 138008 | |
| 138009 | assert( iLevel==FTS3_SEGCURSOR_ALL |
| 138010 | || iLevel==FTS3_SEGCURSOR_PENDING |
| 138011 | || iLevel>=0 |
| 138012 | ); |
| @@ -138013,10 +138671,15 @@ | |
| 138013 | assert( iLevel<FTS3_SEGDIR_MAXLEVEL ); |
| 138014 | assert( iIndex>=0 && iIndex<p->nIndex ); |
| 138015 | |
| 138016 | rc = sqlite3Fts3SegReaderCursor(p, iLangid, iIndex, iLevel, 0, 0, 1, 0, &csr); |
| 138017 | if( rc!=SQLITE_OK || csr.nSegment==0 ) goto finished; |
| 138018 | |
| 138019 | if( iLevel==FTS3_SEGCURSOR_ALL ){ |
| 138020 | /* This call is to merge all segments in the database to a single |
| 138021 | ** segment. The level of the new segment is equal to the numerically |
| 138022 | ** greatest segment level currently present in the database for this |
| @@ -138023,25 +138686,25 @@ | |
| 138023 | ** index. The idx of the new segment is always 0. */ |
| 138024 | if( csr.nSegment==1 ){ |
| 138025 | rc = SQLITE_DONE; |
| 138026 | goto finished; |
| 138027 | } |
| 138028 | rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iNewLevel); |
| 138029 | bIgnoreEmpty = 1; |
| 138030 | |
| 138031 | }else if( iLevel==FTS3_SEGCURSOR_PENDING ){ |
| 138032 | iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, 0); |
| 138033 | rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, 0, &iIdx); |
| 138034 | }else{ |
| 138035 | /* This call is to merge all segments at level iLevel. find the next |
| 138036 | ** available segment index at level iLevel+1. The call to |
| 138037 | ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to |
| 138038 | ** a single iLevel+2 segment if necessary. */ |
| 138039 | rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, iLevel+1, &iIdx); |
| 138040 | iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, iLevel+1); |
| 138041 | } |
| 138042 | if( rc!=SQLITE_OK ) goto finished; |
| 138043 | assert( csr.nSegment>0 ); |
| 138044 | assert( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) ); |
| 138045 | assert( iNewLevel<getAbsoluteLevel(p, iLangid, iIndex,FTS3_SEGDIR_MAXLEVEL) ); |
| 138046 | |
| 138047 | memset(&filter, 0, sizeof(Fts3SegFilter)); |
| @@ -138054,29 +138717,36 @@ | |
| 138054 | if( rc!=SQLITE_ROW ) break; |
| 138055 | rc = fts3SegWriterAdd(p, &pWriter, 1, |
| 138056 | csr.zTerm, csr.nTerm, csr.aDoclist, csr.nDoclist); |
| 138057 | } |
| 138058 | if( rc!=SQLITE_OK ) goto finished; |
| 138059 | assert( pWriter ); |
| 138060 | |
| 138061 | if( iLevel!=FTS3_SEGCURSOR_PENDING ){ |
| 138062 | rc = fts3DeleteSegdir( |
| 138063 | p, iLangid, iIndex, iLevel, csr.apSegment, csr.nSegment |
| 138064 | ); |
| 138065 | if( rc!=SQLITE_OK ) goto finished; |
| 138066 | } |
| 138067 | rc = fts3SegWriterFlush(p, pWriter, iNewLevel, iIdx); |
| 138068 | |
| 138069 | finished: |
| 138070 | fts3SegWriterFree(pWriter); |
| 138071 | sqlite3Fts3SegReaderFinish(&csr); |
| 138072 | return rc; |
| 138073 | } |
| 138074 | |
| 138075 | |
| 138076 | /* |
| 138077 | ** Flush the contents of pendingTerms to level 0 segments. |
| 138078 | */ |
| 138079 | SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ |
| 138080 | int rc = SQLITE_OK; |
| 138081 | int i; |
| 138082 | |
| @@ -138088,18 +138758,23 @@ | |
| 138088 | |
| 138089 | /* Determine the auto-incr-merge setting if unknown. If enabled, |
| 138090 | ** estimate the number of leaf blocks of content to be written |
| 138091 | */ |
| 138092 | if( rc==SQLITE_OK && p->bHasStat |
| 138093 | && p->bAutoincrmerge==0xff && p->nLeafAdd>0 |
| 138094 | ){ |
| 138095 | sqlite3_stmt *pStmt = 0; |
| 138096 | rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); |
| 138097 | if( rc==SQLITE_OK ){ |
| 138098 | sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); |
| 138099 | rc = sqlite3_step(pStmt); |
| 138100 | p->bAutoincrmerge = (rc==SQLITE_ROW && sqlite3_column_int(pStmt, 0)); |
| 138101 | rc = sqlite3_reset(pStmt); |
| 138102 | } |
| 138103 | } |
| 138104 | return rc; |
| 138105 | } |
| @@ -138463,10 +139138,12 @@ | |
| 138463 | int nWork; /* Number of leaf pages flushed */ |
| 138464 | sqlite3_int64 iAbsLevel; /* Absolute level of input segments */ |
| 138465 | int iIdx; /* Index of *output* segment in iAbsLevel+1 */ |
| 138466 | sqlite3_int64 iStart; /* Block number of first allocated block */ |
| 138467 | sqlite3_int64 iEnd; /* Block number of last allocated block */ |
| 138468 | NodeWriter aNodeWriter[FTS_MAX_APPENDABLE_HEIGHT]; |
| 138469 | }; |
| 138470 | |
| 138471 | /* |
| 138472 | ** An object of the following type is used to read data from a single |
| @@ -138801,12 +139478,12 @@ | |
| 138801 | nSpace = 1; |
| 138802 | nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; |
| 138803 | nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; |
| 138804 | } |
| 138805 | |
| 138806 | blobGrowBuffer(&pLeaf->block, pLeaf->block.n + nSpace, &rc); |
| 138807 | |
| 138808 | if( rc==SQLITE_OK ){ |
| 138809 | if( pLeaf->block.n==0 ){ |
| 138810 | pLeaf->block.n = 1; |
| 138811 | pLeaf->block.a[0] = '\0'; |
| 138812 | } |
| @@ -138901,10 +139578,11 @@ | |
| 138901 | pWriter->iAbsLevel+1, /* level */ |
| 138902 | pWriter->iIdx, /* idx */ |
| 138903 | pWriter->iStart, /* start_block */ |
| 138904 | pWriter->aNodeWriter[0].iBlock, /* leaves_end_block */ |
| 138905 | pWriter->iEnd, /* end_block */ |
| 138906 | pRoot->block.a, pRoot->block.n /* root */ |
| 138907 | ); |
| 138908 | } |
| 138909 | sqlite3_free(pRoot->block.a); |
| 138910 | sqlite3_free(pRoot->key.a); |
| @@ -139002,11 +139680,15 @@ | |
| 139002 | sqlite3_bind_int64(pSelect, 1, iAbsLevel+1); |
| 139003 | sqlite3_bind_int(pSelect, 2, iIdx); |
| 139004 | if( sqlite3_step(pSelect)==SQLITE_ROW ){ |
| 139005 | iStart = sqlite3_column_int64(pSelect, 1); |
| 139006 | iLeafEnd = sqlite3_column_int64(pSelect, 2); |
| 139007 | iEnd = sqlite3_column_int64(pSelect, 3); |
| 139008 | nRoot = sqlite3_column_bytes(pSelect, 4); |
| 139009 | aRoot = sqlite3_column_blob(pSelect, 4); |
| 139010 | }else{ |
| 139011 | return sqlite3_reset(pSelect); |
| 139012 | } |
| @@ -139603,15 +140285,15 @@ | |
| 139603 | |
| 139604 | |
| 139605 | /* |
| 139606 | ** Attempt an incremental merge that writes nMerge leaf blocks. |
| 139607 | ** |
| 139608 | ** Incremental merges happen nMin segments at a time. The two |
| 139609 | ** segments to be merged are the nMin oldest segments (the ones with |
| 139610 | ** the smallest indexes) in the highest level that contains at least |
| 139611 | ** nMin segments. Multiple merges might occur in an attempt to write the |
| 139612 | ** quota of nMerge leaf blocks. |
| 139613 | */ |
| 139614 | SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ |
| 139615 | int rc; /* Return code */ |
| 139616 | int nRem = nMerge; /* Number of leaf pages yet to be written */ |
| 139617 | Fts3MultiSegReader *pCsr; /* Cursor used to read input data */ |
| @@ -139632,10 +140314,11 @@ | |
| 139632 | rc = fts3IncrmergeHintLoad(p, &hint); |
| 139633 | while( rc==SQLITE_OK && nRem>0 ){ |
| 139634 | const i64 nMod = FTS3_SEGDIR_MAXLEVEL * p->nIndex; |
| 139635 | sqlite3_stmt *pFindLevel = 0; /* SQL used to determine iAbsLevel */ |
| 139636 | int bUseHint = 0; /* True if attempting to append */ |
| 139637 | |
| 139638 | /* Search the %_segdir table for the absolute level with the smallest |
| 139639 | ** relative level number that contains at least nMin segments, if any. |
| 139640 | ** If one is found, set iAbsLevel to the absolute level number and |
| 139641 | ** nSeg to nMin. If no level with at least nMin segments can be found, |
| @@ -139685,27 +140368,36 @@ | |
| 139685 | ** segments available in level iAbsLevel. In this case, no work is |
| 139686 | ** done on iAbsLevel - fall through to the next iteration of the loop |
| 139687 | ** to start work on some other level. */ |
| 139688 | memset(pWriter, 0, nAlloc); |
| 139689 | pFilter->flags = FTS3_SEGMENT_REQUIRE_POS; |
| 139690 | if( rc==SQLITE_OK ){ |
| 139691 | rc = fts3IncrmergeCsr(p, iAbsLevel, nSeg, pCsr); |
| 139692 | } |
| 139693 | if( SQLITE_OK==rc && pCsr->nSegment==nSeg |
| 139694 | && SQLITE_OK==(rc = sqlite3Fts3SegReaderStart(p, pCsr, pFilter)) |
| 139695 | && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pCsr)) |
| 139696 | ){ |
| 139697 | int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */ |
| 139698 | rc = fts3IncrmergeOutputIdx(p, iAbsLevel, &iIdx); |
| 139699 | if( rc==SQLITE_OK ){ |
| 139700 | if( bUseHint && iIdx>0 ){ |
| 139701 | const char *zKey = pCsr->zTerm; |
| 139702 | int nKey = pCsr->nTerm; |
| 139703 | rc = fts3IncrmergeLoad(p, iAbsLevel, iIdx-1, zKey, nKey, pWriter); |
| 139704 | }else{ |
| 139705 | rc = fts3IncrmergeWriter(p, iAbsLevel, iIdx, pCsr, pWriter); |
| 139706 | } |
| 139707 | } |
| 139708 | |
| 139709 | if( rc==SQLITE_OK && pWriter->nLeafEst ){ |
| 139710 | fts3LogMerge(nSeg, iAbsLevel); |
| 139711 | do { |
| @@ -139723,11 +140415,17 @@ | |
| 139723 | fts3IncrmergeHintPush(&hint, iAbsLevel, nSeg, &rc); |
| 139724 | } |
| 139725 | } |
| 139726 | } |
| 139727 | |
| 139728 | fts3IncrmergeRelease(p, pWriter, &rc); |
| 139729 | } |
| 139730 | |
| 139731 | sqlite3Fts3SegReaderFinish(pCsr); |
| 139732 | } |
| 139733 | |
| @@ -139810,20 +140508,23 @@ | |
| 139810 | Fts3Table *p, /* FTS3 table handle */ |
| 139811 | const char *zParam /* Nul-terminated string containing boolean */ |
| 139812 | ){ |
| 139813 | int rc = SQLITE_OK; |
| 139814 | sqlite3_stmt *pStmt = 0; |
| 139815 | p->bAutoincrmerge = fts3Getint(&zParam)!=0; |
| 139816 | if( !p->bHasStat ){ |
| 139817 | assert( p->bFts4==0 ); |
| 139818 | sqlite3Fts3CreateStatTable(&rc, p); |
| 139819 | if( rc ) return rc; |
| 139820 | } |
| 139821 | rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); |
| 139822 | if( rc ) return rc; |
| 139823 | sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); |
| 139824 | sqlite3_bind_int(pStmt, 2, p->bAutoincrmerge); |
| 139825 | sqlite3_step(pStmt); |
| 139826 | rc = sqlite3_reset(pStmt); |
| 139827 | return rc; |
| 139828 | } |
| 139829 | |
| @@ -142802,64 +143503,24 @@ | |
| 142802 | ** child page. |
| 142803 | */ |
| 142804 | |
| 142805 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) |
| 142806 | |
| 142807 | /* |
| 142808 | ** This file contains an implementation of a couple of different variants |
| 142809 | ** of the r-tree algorithm. See the README file for further details. The |
| 142810 | ** same data-structure is used for all, but the algorithms for insert and |
| 142811 | ** delete operations vary. The variants used are selected at compile time |
| 142812 | ** by defining the following symbols: |
| 142813 | */ |
| 142814 | |
| 142815 | /* Either, both or none of the following may be set to activate |
| 142816 | ** r*tree variant algorithms. |
| 142817 | */ |
| 142818 | #define VARIANT_RSTARTREE_CHOOSESUBTREE 0 |
| 142819 | #define VARIANT_RSTARTREE_REINSERT 1 |
| 142820 | |
| 142821 | /* |
| 142822 | ** Exactly one of the following must be set to 1. |
| 142823 | */ |
| 142824 | #define VARIANT_GUTTMAN_QUADRATIC_SPLIT 0 |
| 142825 | #define VARIANT_GUTTMAN_LINEAR_SPLIT 0 |
| 142826 | #define VARIANT_RSTARTREE_SPLIT 1 |
| 142827 | |
| 142828 | #define VARIANT_GUTTMAN_SPLIT \ |
| 142829 | (VARIANT_GUTTMAN_LINEAR_SPLIT||VARIANT_GUTTMAN_QUADRATIC_SPLIT) |
| 142830 | |
| 142831 | #if VARIANT_GUTTMAN_QUADRATIC_SPLIT |
| 142832 | #define PickNext QuadraticPickNext |
| 142833 | #define PickSeeds QuadraticPickSeeds |
| 142834 | #define AssignCells splitNodeGuttman |
| 142835 | #endif |
| 142836 | #if VARIANT_GUTTMAN_LINEAR_SPLIT |
| 142837 | #define PickNext LinearPickNext |
| 142838 | #define PickSeeds LinearPickSeeds |
| 142839 | #define AssignCells splitNodeGuttman |
| 142840 | #endif |
| 142841 | #if VARIANT_RSTARTREE_SPLIT |
| 142842 | #define AssignCells splitNodeStartree |
| 142843 | #endif |
| 142844 | |
| 142845 | #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) |
| 142846 | # define NDEBUG 1 |
| 142847 | #endif |
| 142848 | |
| 142849 | #ifndef SQLITE_CORE |
| 142850 | SQLITE_EXTENSION_INIT1 |
| 142851 | #else |
| 142852 | #endif |
| 142853 | |
| 142854 | /* #include <string.h> */ |
| 142855 | /* #include <assert.h> */ |
| 142856 | |
| 142857 | #ifndef SQLITE_AMALGAMATION |
| 142858 | #include "sqlite3rtree.h" |
| 142859 | typedef sqlite3_int64 i64; |
| 142860 | typedef unsigned char u8; |
| 142861 | typedef unsigned int u32; |
| 142862 | #endif |
| 142863 | |
| 142864 | /* The following macro is used to suppress compiler warnings. |
| 142865 | */ |
| @@ -142873,19 +143534,20 @@ | |
| 142873 | typedef struct RtreeCell RtreeCell; |
| 142874 | typedef struct RtreeConstraint RtreeConstraint; |
| 142875 | typedef struct RtreeMatchArg RtreeMatchArg; |
| 142876 | typedef struct RtreeGeomCallback RtreeGeomCallback; |
| 142877 | typedef union RtreeCoord RtreeCoord; |
| 142878 | |
| 142879 | /* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */ |
| 142880 | #define RTREE_MAX_DIMENSIONS 5 |
| 142881 | |
| 142882 | /* Size of hash table Rtree.aHash. This hash table is not expected to |
| 142883 | ** ever contain very many entries, so a fixed number of buckets is |
| 142884 | ** used. |
| 142885 | */ |
| 142886 | #define HASHSIZE 128 |
| 142887 | |
| 142888 | /* The xBestIndex method of this virtual table requires an estimate of |
| 142889 | ** the number of rows in the virtual table to calculate the costs of |
| 142890 | ** various strategies. If possible, this estimate is loaded from the |
| 142891 | ** sqlite_stat1 table (with RTREE_MIN_ROWEST as a hard-coded minimum). |
| @@ -142897,19 +143559,19 @@ | |
| 142897 | |
| 142898 | /* |
| 142899 | ** An rtree virtual-table object. |
| 142900 | */ |
| 142901 | struct Rtree { |
| 142902 | sqlite3_vtab base; |
| 142903 | sqlite3 *db; /* Host database connection */ |
| 142904 | int iNodeSize; /* Size in bytes of each node in the node table */ |
| 142905 | int nDim; /* Number of dimensions */ |
| 142906 | int nBytesPerCell; /* Bytes consumed per cell */ |
| 142907 | int iDepth; /* Current depth of the r-tree structure */ |
| 142908 | char *zDb; /* Name of database containing r-tree table */ |
| 142909 | char *zName; /* Name of r-tree table */ |
| 142910 | RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ |
| 142911 | int nBusy; /* Current number of users of this structure */ |
| 142912 | i64 nRowEst; /* Estimated number of rows in this table */ |
| 142913 | |
| 142914 | /* List of nodes removed during a CondenseTree operation. List is |
| 142915 | ** linked together via the pointer normally used for hash chains - |
| @@ -142932,14 +143594,14 @@ | |
| 142932 | /* Statements to read/write/delete a record from xxx_parent */ |
| 142933 | sqlite3_stmt *pReadParent; |
| 142934 | sqlite3_stmt *pWriteParent; |
| 142935 | sqlite3_stmt *pDeleteParent; |
| 142936 | |
| 142937 | int eCoordType; |
| 142938 | }; |
| 142939 | |
| 142940 | /* Possible values for eCoordType: */ |
| 142941 | #define RTREE_COORD_REAL32 0 |
| 142942 | #define RTREE_COORD_INT32 1 |
| 142943 | |
| 142944 | /* |
| 142945 | ** If SQLITE_RTREE_INT_ONLY is defined, then this virtual table will |
| @@ -142947,14 +143609,33 @@ | |
| 142947 | ** will be done. |
| 142948 | */ |
| 142949 | #ifdef SQLITE_RTREE_INT_ONLY |
| 142950 | typedef sqlite3_int64 RtreeDValue; /* High accuracy coordinate */ |
| 142951 | typedef int RtreeValue; /* Low accuracy coordinate */ |
| 142952 | #else |
| 142953 | typedef double RtreeDValue; /* High accuracy coordinate */ |
| 142954 | typedef float RtreeValue; /* Low accuracy coordinate */ |
| 142955 | #endif |
| 142956 | |
| 142957 | /* |
| 142958 | ** The minimum number of cells allowed for a node is a third of the |
| 142959 | ** maximum. In Gutman's notation: |
| 142960 | ** |
| @@ -142974,25 +143655,48 @@ | |
| 142974 | ** 2^40 is greater than 2^64, an r-tree structure always has a depth of |
| 142975 | ** 40 or less. |
| 142976 | */ |
| 142977 | #define RTREE_MAX_DEPTH 40 |
| 142978 | |
| 142979 | /* |
| 142980 | ** An rtree cursor object. |
| 142981 | */ |
| 142982 | struct RtreeCursor { |
| 142983 | sqlite3_vtab_cursor base; |
| 142984 | RtreeNode *pNode; /* Node cursor is currently pointing at */ |
| 142985 | int iCell; /* Index of current cell in pNode */ |
| 142986 | int iStrategy; /* Copy of idxNum search parameter */ |
| 142987 | int nConstraint; /* Number of entries in aConstraint */ |
| 142988 | RtreeConstraint *aConstraint; /* Search constraints. */ |
| 142989 | }; |
| 142990 | |
| 142991 | union RtreeCoord { |
| 142992 | RtreeValue f; |
| 142993 | int i; |
| 142994 | }; |
| 142995 | |
| 142996 | /* |
| 142997 | ** The argument is an RtreeCoord. Return the value stored within the RtreeCoord |
| 142998 | ** formatted as a RtreeDValue (double or int64). This macro assumes that local |
| @@ -143013,42 +143717,71 @@ | |
| 143013 | ** A search constraint. |
| 143014 | */ |
| 143015 | struct RtreeConstraint { |
| 143016 | int iCoord; /* Index of constrained coordinate */ |
| 143017 | int op; /* Constraining operation */ |
| 143018 | RtreeDValue rValue; /* Constraint value. */ |
| 143019 | int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); |
| 143020 | sqlite3_rtree_geometry *pGeom; /* Constraint callback argument for a MATCH */ |
| 143021 | }; |
| 143022 | |
| 143023 | /* Possible values for RtreeConstraint.op */ |
| 143024 | #define RTREE_EQ 0x41 |
| 143025 | #define RTREE_LE 0x42 |
| 143026 | #define RTREE_LT 0x43 |
| 143027 | #define RTREE_GE 0x44 |
| 143028 | #define RTREE_GT 0x45 |
| 143029 | #define RTREE_MATCH 0x46 |
| 143030 | |
| 143031 | /* |
| 143032 | ** An rtree structure node. |
| 143033 | */ |
| 143034 | struct RtreeNode { |
| 143035 | RtreeNode *pParent; /* Parent node */ |
| 143036 | i64 iNode; |
| 143037 | int nRef; |
| 143038 | int isDirty; |
| 143039 | u8 *zData; |
| 143040 | RtreeNode *pNext; /* Next node in this hash chain */ |
| 143041 | }; |
| 143042 | #define NCELL(pNode) readInt16(&(pNode)->zData[2]) |
| 143043 | |
| 143044 | /* |
| 143045 | ** Structure to store a deserialized rtree record. |
| 143046 | */ |
| 143047 | struct RtreeCell { |
| 143048 | i64 iRowid; |
| 143049 | RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; |
| 143050 | }; |
| 143051 | |
| 143052 | |
| 143053 | /* |
| 143054 | ** Value for the first field of every RtreeMatchArg object. The MATCH |
| @@ -143056,33 +143789,20 @@ | |
| 143056 | ** value to avoid operating on invalid blobs (which could cause a segfault). |
| 143057 | */ |
| 143058 | #define RTREE_GEOMETRY_MAGIC 0x891245AB |
| 143059 | |
| 143060 | /* |
| 143061 | ** An instance of this structure must be supplied as a blob argument to |
| 143062 | ** the right-hand-side of an SQL MATCH operator used to constrain an |
| 143063 | ** r-tree query. |
| 143064 | */ |
| 143065 | struct RtreeMatchArg { |
| 143066 | u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ |
| 143067 | int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue*, int *); |
| 143068 | void *pContext; |
| 143069 | int nParam; |
| 143070 | RtreeDValue aParam[1]; |
| 143071 | }; |
| 143072 | |
| 143073 | /* |
| 143074 | ** When a geometry callback is created (see sqlite3_rtree_geometry_callback), |
| 143075 | ** a single instance of the following structure is allocated. It is used |
| 143076 | ** as the context for the user-function created by by s_r_g_c(). The object |
| 143077 | ** is eventually deleted by the destructor mechanism provided by |
| 143078 | ** sqlite3_create_function_v2() (which is called by s_r_g_c() to create |
| 143079 | ** the geometry callback function). |
| 143080 | */ |
| 143081 | struct RtreeGeomCallback { |
| 143082 | int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); |
| 143083 | void *pContext; |
| 143084 | }; |
| 143085 | |
| 143086 | #ifndef MAX |
| 143087 | # define MAX(x,y) ((x) < (y) ? (y) : (x)) |
| 143088 | #endif |
| @@ -143172,14 +143892,11 @@ | |
| 143172 | /* |
| 143173 | ** Given a node number iNode, return the corresponding key to use |
| 143174 | ** in the Rtree.aHash table. |
| 143175 | */ |
| 143176 | static int nodeHash(i64 iNode){ |
| 143177 | return ( |
| 143178 | (iNode>>56) ^ (iNode>>48) ^ (iNode>>40) ^ (iNode>>32) ^ |
| 143179 | (iNode>>24) ^ (iNode>>16) ^ (iNode>> 8) ^ (iNode>> 0) |
| 143180 | ) % HASHSIZE; |
| 143181 | } |
| 143182 | |
| 143183 | /* |
| 143184 | ** Search the node hash table for node iNode. If found, return a pointer |
| 143185 | ** to it. Otherwise, return 0. |
| @@ -143235,12 +143952,11 @@ | |
| 143235 | } |
| 143236 | |
| 143237 | /* |
| 143238 | ** Obtain a reference to an r-tree node. |
| 143239 | */ |
| 143240 | static int |
| 143241 | nodeAcquire( |
| 143242 | Rtree *pRtree, /* R-tree structure */ |
| 143243 | i64 iNode, /* Node number to load */ |
| 143244 | RtreeNode *pParent, /* Either the parent node or NULL */ |
| 143245 | RtreeNode **ppNode /* OUT: Acquired node */ |
| 143246 | ){ |
| @@ -143325,14 +144041,14 @@ | |
| 143325 | |
| 143326 | /* |
| 143327 | ** Overwrite cell iCell of node pNode with the contents of pCell. |
| 143328 | */ |
| 143329 | static void nodeOverwriteCell( |
| 143330 | Rtree *pRtree, |
| 143331 | RtreeNode *pNode, |
| 143332 | RtreeCell *pCell, |
| 143333 | int iCell |
| 143334 | ){ |
| 143335 | int ii; |
| 143336 | u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; |
| 143337 | p += writeInt64(p, pCell->iRowid); |
| 143338 | for(ii=0; ii<(pRtree->nDim*2); ii++){ |
| @@ -143340,11 +144056,11 @@ | |
| 143340 | } |
| 143341 | pNode->isDirty = 1; |
| 143342 | } |
| 143343 | |
| 143344 | /* |
| 143345 | ** Remove cell the cell with index iCell from node pNode. |
| 143346 | */ |
| 143347 | static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){ |
| 143348 | u8 *pDst = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; |
| 143349 | u8 *pSrc = &pDst[pRtree->nBytesPerCell]; |
| 143350 | int nByte = (NCELL(pNode) - iCell - 1) * pRtree->nBytesPerCell; |
| @@ -143357,15 +144073,14 @@ | |
| 143357 | ** Insert the contents of cell pCell into node pNode. If the insert |
| 143358 | ** is successful, return SQLITE_OK. |
| 143359 | ** |
| 143360 | ** If there is not enough free space in pNode, return SQLITE_FULL. |
| 143361 | */ |
| 143362 | static int |
| 143363 | nodeInsertCell( |
| 143364 | Rtree *pRtree, |
| 143365 | RtreeNode *pNode, |
| 143366 | RtreeCell *pCell |
| 143367 | ){ |
| 143368 | int nCell; /* Current number of cells in pNode */ |
| 143369 | int nMaxCell; /* Maximum number of cells for pNode */ |
| 143370 | |
| 143371 | nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell; |
| @@ -143382,12 +144097,11 @@ | |
| 143382 | } |
| 143383 | |
| 143384 | /* |
| 143385 | ** If the node is dirty, write it out to the database. |
| 143386 | */ |
| 143387 | static int |
| 143388 | nodeWrite(Rtree *pRtree, RtreeNode *pNode){ |
| 143389 | int rc = SQLITE_OK; |
| 143390 | if( pNode->isDirty ){ |
| 143391 | sqlite3_stmt *p = pRtree->pWriteNode; |
| 143392 | if( pNode->iNode ){ |
| 143393 | sqlite3_bind_int64(p, 1, pNode->iNode); |
| @@ -143408,12 +144122,11 @@ | |
| 143408 | |
| 143409 | /* |
| 143410 | ** Release a reference to a node. If the node is dirty and the reference |
| 143411 | ** count drops to zero, the node data is written to the database. |
| 143412 | */ |
| 143413 | static int |
| 143414 | nodeRelease(Rtree *pRtree, RtreeNode *pNode){ |
| 143415 | int rc = SQLITE_OK; |
| 143416 | if( pNode ){ |
| 143417 | assert( pNode->nRef>0 ); |
| 143418 | pNode->nRef--; |
| 143419 | if( pNode->nRef==0 ){ |
| @@ -143437,45 +144150,50 @@ | |
| 143437 | ** Return the 64-bit integer value associated with cell iCell of |
| 143438 | ** node pNode. If pNode is a leaf node, this is a rowid. If it is |
| 143439 | ** an internal node, then the 64-bit integer is a child page number. |
| 143440 | */ |
| 143441 | static i64 nodeGetRowid( |
| 143442 | Rtree *pRtree, |
| 143443 | RtreeNode *pNode, |
| 143444 | int iCell |
| 143445 | ){ |
| 143446 | assert( iCell<NCELL(pNode) ); |
| 143447 | return readInt64(&pNode->zData[4 + pRtree->nBytesPerCell*iCell]); |
| 143448 | } |
| 143449 | |
| 143450 | /* |
| 143451 | ** Return coordinate iCoord from cell iCell in node pNode. |
| 143452 | */ |
| 143453 | static void nodeGetCoord( |
| 143454 | Rtree *pRtree, |
| 143455 | RtreeNode *pNode, |
| 143456 | int iCell, |
| 143457 | int iCoord, |
| 143458 | RtreeCoord *pCoord /* Space to write result to */ |
| 143459 | ){ |
| 143460 | readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord); |
| 143461 | } |
| 143462 | |
| 143463 | /* |
| 143464 | ** Deserialize cell iCell of node pNode. Populate the structure pointed |
| 143465 | ** to by pCell with the results. |
| 143466 | */ |
| 143467 | static void nodeGetCell( |
| 143468 | Rtree *pRtree, |
| 143469 | RtreeNode *pNode, |
| 143470 | int iCell, |
| 143471 | RtreeCell *pCell |
| 143472 | ){ |
| 143473 | int ii; |
| 143474 | pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); |
| 143475 | for(ii=0; ii<pRtree->nDim*2; ii++){ |
| 143476 | nodeGetCoord(pRtree, pNode, iCell, ii, &pCell->aCoord[ii]); |
| 143477 | } |
| 143478 | } |
| 143479 | |
| 143480 | |
| 143481 | /* Forward declaration for the function that does the work of |
| @@ -143597,14 +144315,14 @@ | |
| 143597 | */ |
| 143598 | static void freeCursorConstraints(RtreeCursor *pCsr){ |
| 143599 | if( pCsr->aConstraint ){ |
| 143600 | int i; /* Used to iterate through constraint array */ |
| 143601 | for(i=0; i<pCsr->nConstraint; i++){ |
| 143602 | sqlite3_rtree_geometry *pGeom = pCsr->aConstraint[i].pGeom; |
| 143603 | if( pGeom ){ |
| 143604 | if( pGeom->xDelUser ) pGeom->xDelUser(pGeom->pUser); |
| 143605 | sqlite3_free(pGeom); |
| 143606 | } |
| 143607 | } |
| 143608 | sqlite3_free(pCsr->aConstraint); |
| 143609 | pCsr->aConstraint = 0; |
| 143610 | } |
| @@ -143613,16 +144331,17 @@ | |
| 143613 | /* |
| 143614 | ** Rtree virtual table module xClose method. |
| 143615 | */ |
| 143616 | static int rtreeClose(sqlite3_vtab_cursor *cur){ |
| 143617 | Rtree *pRtree = (Rtree *)(cur->pVtab); |
| 143618 | int rc; |
| 143619 | RtreeCursor *pCsr = (RtreeCursor *)cur; |
| 143620 | freeCursorConstraints(pCsr); |
| 143621 | rc = nodeRelease(pRtree, pCsr->pNode); |
| 143622 | sqlite3_free(pCsr); |
| 143623 | return rc; |
| 143624 | } |
| 143625 | |
| 143626 | /* |
| 143627 | ** Rtree virtual table module xEof method. |
| 143628 | ** |
| @@ -143629,198 +144348,168 @@ | |
| 143629 | ** Return non-zero if the cursor does not currently point to a valid |
| 143630 | ** record (i.e if the scan has finished), or zero otherwise. |
| 143631 | */ |
| 143632 | static int rtreeEof(sqlite3_vtab_cursor *cur){ |
| 143633 | RtreeCursor *pCsr = (RtreeCursor *)cur; |
| 143634 | return (pCsr->pNode==0); |
| 143635 | } |
| 143636 | |
| 143637 | /* |
| 143638 | ** The r-tree constraint passed as the second argument to this function is |
| 143639 | ** guaranteed to be a MATCH constraint. |
| 143640 | */ |
| 143641 | static int testRtreeGeom( |
| 143642 | Rtree *pRtree, /* R-Tree object */ |
| 143643 | RtreeConstraint *pConstraint, /* MATCH constraint to test */ |
| 143644 | RtreeCell *pCell, /* Cell to test */ |
| 143645 | int *pbRes /* OUT: Test result */ |
| 143646 | ){ |
| 143647 | int i; |
| 143648 | RtreeDValue aCoord[RTREE_MAX_DIMENSIONS*2]; |
| 143649 | int nCoord = pRtree->nDim*2; |
| 143650 | |
| 143651 | assert( pConstraint->op==RTREE_MATCH ); |
| 143652 | assert( pConstraint->pGeom ); |
| 143653 | |
| 143654 | for(i=0; i<nCoord; i++){ |
| 143655 | aCoord[i] = DCOORD(pCell->aCoord[i]); |
| 143656 | } |
| 143657 | return pConstraint->xGeom(pConstraint->pGeom, nCoord, aCoord, pbRes); |
| 143658 | } |
| 143659 | |
| 143660 | /* |
| 143661 | ** Cursor pCursor currently points to a cell in a non-leaf page. |
| 143662 | ** Set *pbEof to true if the sub-tree headed by the cell is filtered |
| 143663 | ** (excluded) by the constraints in the pCursor->aConstraint[] |
| 143664 | ** array, or false otherwise. |
| 143665 | ** |
| 143666 | ** Return SQLITE_OK if successful or an SQLite error code if an error |
| 143667 | ** occurs within a geometry callback. |
| 143668 | */ |
| 143669 | static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){ |
| 143670 | RtreeCell cell; |
| 143671 | int ii; |
| 143672 | int bRes = 0; |
| 143673 | int rc = SQLITE_OK; |
| 143674 | |
| 143675 | nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); |
| 143676 | for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){ |
| 143677 | RtreeConstraint *p = &pCursor->aConstraint[ii]; |
| 143678 | RtreeDValue cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]); |
| 143679 | RtreeDValue cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]); |
| 143680 | |
| 143681 | assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE |
| 143682 | || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH |
| 143683 | ); |
| 143684 | |
| 143685 | switch( p->op ){ |
| 143686 | case RTREE_LE: case RTREE_LT: |
| 143687 | bRes = p->rValue<cell_min; |
| 143688 | break; |
| 143689 | |
| 143690 | case RTREE_GE: case RTREE_GT: |
| 143691 | bRes = p->rValue>cell_max; |
| 143692 | break; |
| 143693 | |
| 143694 | case RTREE_EQ: |
| 143695 | bRes = (p->rValue>cell_max || p->rValue<cell_min); |
| 143696 | break; |
| 143697 | |
| 143698 | default: { |
| 143699 | assert( p->op==RTREE_MATCH ); |
| 143700 | rc = testRtreeGeom(pRtree, p, &cell, &bRes); |
| 143701 | bRes = !bRes; |
| 143702 | break; |
| 143703 | } |
| 143704 | } |
| 143705 | } |
| 143706 | |
| 143707 | *pbEof = bRes; |
| 143708 | return rc; |
| 143709 | } |
| 143710 | |
| 143711 | /* |
| 143712 | ** Test if the cell that cursor pCursor currently points to |
| 143713 | ** would be filtered (excluded) by the constraints in the |
| 143714 | ** pCursor->aConstraint[] array. If so, set *pbEof to true before |
| 143715 | ** returning. If the cell is not filtered (excluded) by the constraints, |
| 143716 | ** set pbEof to zero. |
| 143717 | ** |
| 143718 | ** Return SQLITE_OK if successful or an SQLite error code if an error |
| 143719 | ** occurs within a geometry callback. |
| 143720 | ** |
| 143721 | ** This function assumes that the cell is part of a leaf node. |
| 143722 | */ |
| 143723 | static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){ |
| 143724 | RtreeCell cell; |
| 143725 | int ii; |
| 143726 | *pbEof = 0; |
| 143727 | |
| 143728 | nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); |
| 143729 | for(ii=0; ii<pCursor->nConstraint; ii++){ |
| 143730 | RtreeConstraint *p = &pCursor->aConstraint[ii]; |
| 143731 | RtreeDValue coord = DCOORD(cell.aCoord[p->iCoord]); |
| 143732 | int res; |
| 143733 | assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE |
| 143734 | || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH |
| 143735 | ); |
| 143736 | switch( p->op ){ |
| 143737 | case RTREE_LE: res = (coord<=p->rValue); break; |
| 143738 | case RTREE_LT: res = (coord<p->rValue); break; |
| 143739 | case RTREE_GE: res = (coord>=p->rValue); break; |
| 143740 | case RTREE_GT: res = (coord>p->rValue); break; |
| 143741 | case RTREE_EQ: res = (coord==p->rValue); break; |
| 143742 | default: { |
| 143743 | int rc; |
| 143744 | assert( p->op==RTREE_MATCH ); |
| 143745 | rc = testRtreeGeom(pRtree, p, &cell, &res); |
| 143746 | if( rc!=SQLITE_OK ){ |
| 143747 | return rc; |
| 143748 | } |
| 143749 | break; |
| 143750 | } |
| 143751 | } |
| 143752 | |
| 143753 | if( !res ){ |
| 143754 | *pbEof = 1; |
| 143755 | return SQLITE_OK; |
| 143756 | } |
| 143757 | } |
| 143758 | |
| 143759 | return SQLITE_OK; |
| 143760 | } |
| 143761 | |
| 143762 | /* |
| 143763 | ** Cursor pCursor currently points at a node that heads a sub-tree of |
| 143764 | ** height iHeight (if iHeight==0, then the node is a leaf). Descend |
| 143765 | ** to point to the left-most cell of the sub-tree that matches the |
| 143766 | ** configured constraints. |
| 143767 | */ |
| 143768 | static int descendToCell( |
| 143769 | Rtree *pRtree, |
| 143770 | RtreeCursor *pCursor, |
| 143771 | int iHeight, |
| 143772 | int *pEof /* OUT: Set to true if cannot descend */ |
| 143773 | ){ |
| 143774 | int isEof; |
| 143775 | int rc; |
| 143776 | int ii; |
| 143777 | RtreeNode *pChild; |
| 143778 | sqlite3_int64 iRowid; |
| 143779 | |
| 143780 | RtreeNode *pSavedNode = pCursor->pNode; |
| 143781 | int iSavedCell = pCursor->iCell; |
| 143782 | |
| 143783 | assert( iHeight>=0 ); |
| 143784 | |
| 143785 | if( iHeight==0 ){ |
| 143786 | rc = testRtreeEntry(pRtree, pCursor, &isEof); |
| 143787 | }else{ |
| 143788 | rc = testRtreeCell(pRtree, pCursor, &isEof); |
| 143789 | } |
| 143790 | if( rc!=SQLITE_OK || isEof || iHeight==0 ){ |
| 143791 | goto descend_to_cell_out; |
| 143792 | } |
| 143793 | |
| 143794 | iRowid = nodeGetRowid(pRtree, pCursor->pNode, pCursor->iCell); |
| 143795 | rc = nodeAcquire(pRtree, iRowid, pCursor->pNode, &pChild); |
| 143796 | if( rc!=SQLITE_OK ){ |
| 143797 | goto descend_to_cell_out; |
| 143798 | } |
| 143799 | |
| 143800 | nodeRelease(pRtree, pCursor->pNode); |
| 143801 | pCursor->pNode = pChild; |
| 143802 | isEof = 1; |
| 143803 | for(ii=0; isEof && ii<NCELL(pChild); ii++){ |
| 143804 | pCursor->iCell = ii; |
| 143805 | rc = descendToCell(pRtree, pCursor, iHeight-1, &isEof); |
| 143806 | if( rc!=SQLITE_OK ){ |
| 143807 | goto descend_to_cell_out; |
| 143808 | } |
| 143809 | } |
| 143810 | |
| 143811 | if( isEof ){ |
| 143812 | assert( pCursor->pNode==pChild ); |
| 143813 | nodeReference(pSavedNode); |
| 143814 | nodeRelease(pRtree, pChild); |
| 143815 | pCursor->pNode = pSavedNode; |
| 143816 | pCursor->iCell = iSavedCell; |
| 143817 | } |
| 143818 | |
| 143819 | descend_to_cell_out: |
| 143820 | *pEof = isEof; |
| 143821 | return rc; |
| 143822 | } |
| 143823 | |
| 143824 | /* |
| 143825 | ** One of the cells in node pNode is guaranteed to have a 64-bit |
| 143826 | ** integer value equal to iRowid. Return the index of this cell. |
| @@ -143831,10 +144520,11 @@ | |
| 143831 | i64 iRowid, |
| 143832 | int *piIndex |
| 143833 | ){ |
| 143834 | int ii; |
| 143835 | int nCell = NCELL(pNode); |
| 143836 | for(ii=0; ii<nCell; ii++){ |
| 143837 | if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){ |
| 143838 | *piIndex = ii; |
| 143839 | return SQLITE_OK; |
| 143840 | } |
| @@ -143852,82 +144542,342 @@ | |
| 143852 | return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex); |
| 143853 | } |
| 143854 | *piIndex = -1; |
| 143855 | return SQLITE_OK; |
| 143856 | } |
| 143857 | |
| 143858 | /* |
| 143859 | ** Rtree virtual table module xNext method. |
| 143860 | */ |
| 143861 | static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ |
| 143862 | Rtree *pRtree = (Rtree *)(pVtabCursor->pVtab); |
| 143863 | RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |
| 143864 | int rc = SQLITE_OK; |
| 143865 | |
| 143866 | /* RtreeCursor.pNode must not be NULL. If is is NULL, then this cursor is |
| 143867 | ** already at EOF. It is against the rules to call the xNext() method of |
| 143868 | ** a cursor that has already reached EOF. |
| 143869 | */ |
| 143870 | assert( pCsr->pNode ); |
| 143871 | |
| 143872 | if( pCsr->iStrategy==1 ){ |
| 143873 | /* This "scan" is a direct lookup by rowid. There is no next entry. */ |
| 143874 | nodeRelease(pRtree, pCsr->pNode); |
| 143875 | pCsr->pNode = 0; |
| 143876 | }else{ |
| 143877 | /* Move to the next entry that matches the configured constraints. */ |
| 143878 | int iHeight = 0; |
| 143879 | while( pCsr->pNode ){ |
| 143880 | RtreeNode *pNode = pCsr->pNode; |
| 143881 | int nCell = NCELL(pNode); |
| 143882 | for(pCsr->iCell++; pCsr->iCell<nCell; pCsr->iCell++){ |
| 143883 | int isEof; |
| 143884 | rc = descendToCell(pRtree, pCsr, iHeight, &isEof); |
| 143885 | if( rc!=SQLITE_OK || !isEof ){ |
| 143886 | return rc; |
| 143887 | } |
| 143888 | } |
| 143889 | pCsr->pNode = pNode->pParent; |
| 143890 | rc = nodeParentIndex(pRtree, pNode, &pCsr->iCell); |
| 143891 | if( rc!=SQLITE_OK ){ |
| 143892 | return rc; |
| 143893 | } |
| 143894 | nodeReference(pCsr->pNode); |
| 143895 | nodeRelease(pRtree, pNode); |
| 143896 | iHeight++; |
| 143897 | } |
| 143898 | } |
| 143899 | |
| 143900 | return rc; |
| 143901 | } |
| 143902 | |
| 143903 | /* |
| 143904 | ** Rtree virtual table module xRowid method. |
| 143905 | */ |
| 143906 | static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ |
| 143907 | Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; |
| 143908 | RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |
| 143909 | |
| 143910 | assert(pCsr->pNode); |
| 143911 | *pRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell); |
| 143912 | |
| 143913 | return SQLITE_OK; |
| 143914 | } |
| 143915 | |
| 143916 | /* |
| 143917 | ** Rtree virtual table module xColumn method. |
| 143918 | */ |
| 143919 | static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ |
| 143920 | Rtree *pRtree = (Rtree *)cur->pVtab; |
| 143921 | RtreeCursor *pCsr = (RtreeCursor *)cur; |
| 143922 | |
| 143923 | if( i==0 ){ |
| 143924 | i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell); |
| 143925 | sqlite3_result_int64(ctx, iRowid); |
| 143926 | }else{ |
| 143927 | RtreeCoord c; |
| 143928 | nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c); |
| 143929 | #ifndef SQLITE_RTREE_INT_ONLY |
| 143930 | if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ |
| 143931 | sqlite3_result_double(ctx, c.f); |
| 143932 | }else |
| 143933 | #endif |
| @@ -143934,11 +144884,10 @@ | |
| 143934 | { |
| 143935 | assert( pRtree->eCoordType==RTREE_COORD_INT32 ); |
| 143936 | sqlite3_result_int(ctx, c.i); |
| 143937 | } |
| 143938 | } |
| 143939 | |
| 143940 | return SQLITE_OK; |
| 143941 | } |
| 143942 | |
| 143943 | /* |
| 143944 | ** Use nodeAcquire() to obtain the leaf node containing the record with |
| @@ -143945,16 +144894,22 @@ | |
| 143945 | ** rowid iRowid. If successful, set *ppLeaf to point to the node and |
| 143946 | ** return SQLITE_OK. If there is no such record in the table, set |
| 143947 | ** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf |
| 143948 | ** to zero and return an SQLite error code. |
| 143949 | */ |
| 143950 | static int findLeafNode(Rtree *pRtree, i64 iRowid, RtreeNode **ppLeaf){ |
| 143951 | int rc; |
| 143952 | *ppLeaf = 0; |
| 143953 | sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid); |
| 143954 | if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){ |
| 143955 | i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0); |
| 143956 | rc = nodeAcquire(pRtree, iNode, 0, ppLeaf); |
| 143957 | sqlite3_reset(pRtree->pReadRowid); |
| 143958 | }else{ |
| 143959 | rc = sqlite3_reset(pRtree->pReadRowid); |
| 143960 | } |
| @@ -143966,13 +144921,14 @@ | |
| 143966 | ** as the second argument for a MATCH constraint. The value passed as the |
| 143967 | ** first argument to this function is the right-hand operand to the MATCH |
| 143968 | ** operator. |
| 143969 | */ |
| 143970 | static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ |
| 143971 | RtreeMatchArg *p; |
| 143972 | sqlite3_rtree_geometry *pGeom; |
| 143973 | int nBlob; |
| 143974 | |
| 143975 | /* Check that value is actually a blob. */ |
| 143976 | if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR; |
| 143977 | |
| 143978 | /* Check that the blob is roughly the right size. */ |
| @@ -143981,31 +144937,33 @@ | |
| 143981 | || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0 |
| 143982 | ){ |
| 143983 | return SQLITE_ERROR; |
| 143984 | } |
| 143985 | |
| 143986 | pGeom = (sqlite3_rtree_geometry *)sqlite3_malloc( |
| 143987 | sizeof(sqlite3_rtree_geometry) + nBlob |
| 143988 | ); |
| 143989 | if( !pGeom ) return SQLITE_NOMEM; |
| 143990 | memset(pGeom, 0, sizeof(sqlite3_rtree_geometry)); |
| 143991 | p = (RtreeMatchArg *)&pGeom[1]; |
| 143992 | |
| 143993 | memcpy(p, sqlite3_value_blob(pValue), nBlob); |
| 143994 | if( p->magic!=RTREE_GEOMETRY_MAGIC |
| 143995 | || nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(RtreeDValue)) |
| 143996 | ){ |
| 143997 | sqlite3_free(pGeom); |
| 143998 | return SQLITE_ERROR; |
| 143999 | } |
| 144000 | |
| 144001 | pGeom->pContext = p->pContext; |
| 144002 | pGeom->nParam = p->nParam; |
| 144003 | pGeom->aParam = p->aParam; |
| 144004 | |
| 144005 | pCons->xGeom = p->xGeom; |
| 144006 | pCons->pGeom = pGeom; |
| 144007 | return SQLITE_OK; |
| 144008 | } |
| 144009 | |
| 144010 | /* |
| 144011 | ** Rtree virtual table module xFilter method. |
| @@ -144015,91 +144973,96 @@ | |
| 144015 | int idxNum, const char *idxStr, |
| 144016 | int argc, sqlite3_value **argv |
| 144017 | ){ |
| 144018 | Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; |
| 144019 | RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |
| 144020 | |
| 144021 | RtreeNode *pRoot = 0; |
| 144022 | int ii; |
| 144023 | int rc = SQLITE_OK; |
| 144024 | |
| 144025 | rtreeReference(pRtree); |
| 144026 | |
| 144027 | freeCursorConstraints(pCsr); |
| 144028 | pCsr->iStrategy = idxNum; |
| 144029 | |
| 144030 | if( idxNum==1 ){ |
| 144031 | /* Special case - lookup by rowid. */ |
| 144032 | RtreeNode *pLeaf; /* Leaf on which the required cell resides */ |
| 144033 | i64 iRowid = sqlite3_value_int64(argv[0]); |
| 144034 | rc = findLeafNode(pRtree, iRowid, &pLeaf); |
| 144035 | pCsr->pNode = pLeaf; |
| 144036 | if( pLeaf ){ |
| 144037 | assert( rc==SQLITE_OK ); |
| 144038 | rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &pCsr->iCell); |
| 144039 | } |
| 144040 | }else{ |
| 144041 | /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array |
| 144042 | ** with the configured constraints. |
| 144043 | */ |
| 144044 | if( argc>0 ){ |
| 144045 | pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc); |
| 144046 | pCsr->nConstraint = argc; |
| 144047 | if( !pCsr->aConstraint ){ |
| 144048 | rc = SQLITE_NOMEM; |
| 144049 | }else{ |
| 144050 | memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc); |
| 144051 | assert( (idxStr==0 && argc==0) |
| 144052 | || (idxStr && (int)strlen(idxStr)==argc*2) ); |
| 144053 | for(ii=0; ii<argc; ii++){ |
| 144054 | RtreeConstraint *p = &pCsr->aConstraint[ii]; |
| 144055 | p->op = idxStr[ii*2]; |
| 144056 | p->iCoord = idxStr[ii*2+1]-'a'; |
| 144057 | if( p->op==RTREE_MATCH ){ |
| 144058 | /* A MATCH operator. The right-hand-side must be a blob that |
| 144059 | ** can be cast into an RtreeMatchArg object. One created using |
| 144060 | ** an sqlite3_rtree_geometry_callback() SQL user function. |
| 144061 | */ |
| 144062 | rc = deserializeGeometry(argv[ii], p); |
| 144063 | if( rc!=SQLITE_OK ){ |
| 144064 | break; |
| 144065 | } |
| 144066 | }else{ |
| 144067 | #ifdef SQLITE_RTREE_INT_ONLY |
| 144068 | p->rValue = sqlite3_value_int64(argv[ii]); |
| 144069 | #else |
| 144070 | p->rValue = sqlite3_value_double(argv[ii]); |
| 144071 | #endif |
| 144072 | } |
| 144073 | } |
| 144074 | } |
| 144075 | } |
| 144076 | |
| 144077 | if( rc==SQLITE_OK ){ |
| 144078 | pCsr->pNode = 0; |
| 144079 | rc = nodeAcquire(pRtree, 1, 0, &pRoot); |
| 144080 | } |
| 144081 | if( rc==SQLITE_OK ){ |
| 144082 | int isEof = 1; |
| 144083 | int nCell = NCELL(pRoot); |
| 144084 | pCsr->pNode = pRoot; |
| 144085 | for(pCsr->iCell=0; rc==SQLITE_OK && pCsr->iCell<nCell; pCsr->iCell++){ |
| 144086 | assert( pCsr->pNode==pRoot ); |
| 144087 | rc = descendToCell(pRtree, pCsr, pRtree->iDepth, &isEof); |
| 144088 | if( !isEof ){ |
| 144089 | break; |
| 144090 | } |
| 144091 | } |
| 144092 | if( rc==SQLITE_OK && isEof ){ |
| 144093 | assert( pCsr->pNode==pRoot ); |
| 144094 | nodeRelease(pRtree, pRoot); |
| 144095 | pCsr->pNode = 0; |
| 144096 | } |
| 144097 | assert( rc!=SQLITE_OK || !pCsr->pNode || pCsr->iCell<NCELL(pCsr->pNode) ); |
| 144098 | } |
| 144099 | } |
| 144100 | |
| 144101 | rtreeRelease(pRtree); |
| 144102 | return rc; |
| 144103 | } |
| 144104 | |
| 144105 | /* |
| @@ -144197,11 +145160,11 @@ | |
| 144197 | assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH ); |
| 144198 | op = RTREE_MATCH; |
| 144199 | break; |
| 144200 | } |
| 144201 | zIdxStr[iIdx++] = op; |
| 144202 | zIdxStr[iIdx++] = p->iColumn - 1 + 'a'; |
| 144203 | pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); |
| 144204 | pIdxInfo->aConstraintUsage[ii].omit = 1; |
| 144205 | } |
| 144206 | } |
| 144207 | |
| @@ -144290,66 +145253,36 @@ | |
| 144290 | area = cellArea(pRtree, &cell); |
| 144291 | cellUnion(pRtree, &cell, pCell); |
| 144292 | return (cellArea(pRtree, &cell)-area); |
| 144293 | } |
| 144294 | |
| 144295 | #if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT |
| 144296 | static RtreeDValue cellOverlap( |
| 144297 | Rtree *pRtree, |
| 144298 | RtreeCell *p, |
| 144299 | RtreeCell *aCell, |
| 144300 | int nCell, |
| 144301 | int iExclude |
| 144302 | ){ |
| 144303 | int ii; |
| 144304 | RtreeDValue overlap = 0.0; |
| 144305 | for(ii=0; ii<nCell; ii++){ |
| 144306 | #if VARIANT_RSTARTREE_CHOOSESUBTREE |
| 144307 | if( ii!=iExclude ) |
| 144308 | #else |
| 144309 | assert( iExclude==-1 ); |
| 144310 | UNUSED_PARAMETER(iExclude); |
| 144311 | #endif |
| 144312 | { |
| 144313 | int jj; |
| 144314 | RtreeDValue o = (RtreeDValue)1; |
| 144315 | for(jj=0; jj<(pRtree->nDim*2); jj+=2){ |
| 144316 | RtreeDValue x1, x2; |
| 144317 | |
| 144318 | x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); |
| 144319 | x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); |
| 144320 | |
| 144321 | if( x2<x1 ){ |
| 144322 | o = 0.0; |
| 144323 | break; |
| 144324 | }else{ |
| 144325 | o = o * (x2-x1); |
| 144326 | } |
| 144327 | } |
| 144328 | overlap += o; |
| 144329 | } |
| 144330 | } |
| 144331 | return overlap; |
| 144332 | } |
| 144333 | #endif |
| 144334 | |
| 144335 | #if VARIANT_RSTARTREE_CHOOSESUBTREE |
| 144336 | static RtreeDValue cellOverlapEnlargement( |
| 144337 | Rtree *pRtree, |
| 144338 | RtreeCell *p, |
| 144339 | RtreeCell *pInsert, |
| 144340 | RtreeCell *aCell, |
| 144341 | int nCell, |
| 144342 | int iExclude |
| 144343 | ){ |
| 144344 | RtreeDValue before, after; |
| 144345 | before = cellOverlap(pRtree, p, aCell, nCell, iExclude); |
| 144346 | cellUnion(pRtree, p, pInsert); |
| 144347 | after = cellOverlap(pRtree, p, aCell, nCell, iExclude); |
| 144348 | return (after-before); |
| 144349 | } |
| 144350 | #endif |
| 144351 | |
| 144352 | |
| 144353 | /* |
| 144354 | ** This function implements the ChooseLeaf algorithm from Gutman[84]. |
| 144355 | ** ChooseSubTree in r*tree terminology. |
| @@ -144367,39 +145300,19 @@ | |
| 144367 | |
| 144368 | for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ |
| 144369 | int iCell; |
| 144370 | sqlite3_int64 iBest = 0; |
| 144371 | |
| 144372 | RtreeDValue fMinGrowth = 0.0; |
| 144373 | RtreeDValue fMinArea = 0.0; |
| 144374 | #if VARIANT_RSTARTREE_CHOOSESUBTREE |
| 144375 | RtreeDValue fMinOverlap = 0.0; |
| 144376 | RtreeDValue overlap; |
| 144377 | #endif |
| 144378 | |
| 144379 | int nCell = NCELL(pNode); |
| 144380 | RtreeCell cell; |
| 144381 | RtreeNode *pChild; |
| 144382 | |
| 144383 | RtreeCell *aCell = 0; |
| 144384 | |
| 144385 | #if VARIANT_RSTARTREE_CHOOSESUBTREE |
| 144386 | if( ii==(pRtree->iDepth-1) ){ |
| 144387 | int jj; |
| 144388 | aCell = sqlite3_malloc(sizeof(RtreeCell)*nCell); |
| 144389 | if( !aCell ){ |
| 144390 | rc = SQLITE_NOMEM; |
| 144391 | nodeRelease(pRtree, pNode); |
| 144392 | pNode = 0; |
| 144393 | continue; |
| 144394 | } |
| 144395 | for(jj=0; jj<nCell; jj++){ |
| 144396 | nodeGetCell(pRtree, pNode, jj, &aCell[jj]); |
| 144397 | } |
| 144398 | } |
| 144399 | #endif |
| 144400 | |
| 144401 | /* Select the child node which will be enlarged the least if pCell |
| 144402 | ** is inserted into it. Resolve ties by choosing the entry with |
| 144403 | ** the smallest area. |
| 144404 | */ |
| 144405 | for(iCell=0; iCell<nCell; iCell++){ |
| @@ -144407,30 +145320,13 @@ | |
| 144407 | RtreeDValue growth; |
| 144408 | RtreeDValue area; |
| 144409 | nodeGetCell(pRtree, pNode, iCell, &cell); |
| 144410 | growth = cellGrowth(pRtree, &cell, pCell); |
| 144411 | area = cellArea(pRtree, &cell); |
| 144412 | |
| 144413 | #if VARIANT_RSTARTREE_CHOOSESUBTREE |
| 144414 | if( ii==(pRtree->iDepth-1) ){ |
| 144415 | overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell); |
| 144416 | }else{ |
| 144417 | overlap = 0.0; |
| 144418 | } |
| 144419 | if( (iCell==0) |
| 144420 | || (overlap<fMinOverlap) |
| 144421 | || (overlap==fMinOverlap && growth<fMinGrowth) |
| 144422 | || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea) |
| 144423 | ){ |
| 144424 | bBest = 1; |
| 144425 | fMinOverlap = overlap; |
| 144426 | } |
| 144427 | #else |
| 144428 | if( iCell==0||growth<fMinGrowth||(growth==fMinGrowth && area<fMinArea) ){ |
| 144429 | bBest = 1; |
| 144430 | } |
| 144431 | #endif |
| 144432 | if( bBest ){ |
| 144433 | fMinGrowth = growth; |
| 144434 | fMinArea = area; |
| 144435 | iBest = cell.iRowid; |
| 144436 | } |
| @@ -144497,159 +145393,10 @@ | |
| 144497 | return sqlite3_reset(pRtree->pWriteParent); |
| 144498 | } |
| 144499 | |
| 144500 | static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int); |
| 144501 | |
| 144502 | #if VARIANT_GUTTMAN_LINEAR_SPLIT |
| 144503 | /* |
| 144504 | ** Implementation of the linear variant of the PickNext() function from |
| 144505 | ** Guttman[84]. |
| 144506 | */ |
| 144507 | static RtreeCell *LinearPickNext( |
| 144508 | Rtree *pRtree, |
| 144509 | RtreeCell *aCell, |
| 144510 | int nCell, |
| 144511 | RtreeCell *pLeftBox, |
| 144512 | RtreeCell *pRightBox, |
| 144513 | int *aiUsed |
| 144514 | ){ |
| 144515 | int ii; |
| 144516 | for(ii=0; aiUsed[ii]; ii++); |
| 144517 | aiUsed[ii] = 1; |
| 144518 | return &aCell[ii]; |
| 144519 | } |
| 144520 | |
| 144521 | /* |
| 144522 | ** Implementation of the linear variant of the PickSeeds() function from |
| 144523 | ** Guttman[84]. |
| 144524 | */ |
| 144525 | static void LinearPickSeeds( |
| 144526 | Rtree *pRtree, |
| 144527 | RtreeCell *aCell, |
| 144528 | int nCell, |
| 144529 | int *piLeftSeed, |
| 144530 | int *piRightSeed |
| 144531 | ){ |
| 144532 | int i; |
| 144533 | int iLeftSeed = 0; |
| 144534 | int iRightSeed = 1; |
| 144535 | RtreeDValue maxNormalInnerWidth = (RtreeDValue)0; |
| 144536 | |
| 144537 | /* Pick two "seed" cells from the array of cells. The algorithm used |
| 144538 | ** here is the LinearPickSeeds algorithm from Gutman[1984]. The |
| 144539 | ** indices of the two seed cells in the array are stored in local |
| 144540 | ** variables iLeftSeek and iRightSeed. |
| 144541 | */ |
| 144542 | for(i=0; i<pRtree->nDim; i++){ |
| 144543 | RtreeDValue x1 = DCOORD(aCell[0].aCoord[i*2]); |
| 144544 | RtreeDValue x2 = DCOORD(aCell[0].aCoord[i*2+1]); |
| 144545 | RtreeDValue x3 = x1; |
| 144546 | RtreeDValue x4 = x2; |
| 144547 | int jj; |
| 144548 | |
| 144549 | int iCellLeft = 0; |
| 144550 | int iCellRight = 0; |
| 144551 | |
| 144552 | for(jj=1; jj<nCell; jj++){ |
| 144553 | RtreeDValue left = DCOORD(aCell[jj].aCoord[i*2]); |
| 144554 | RtreeDValue right = DCOORD(aCell[jj].aCoord[i*2+1]); |
| 144555 | |
| 144556 | if( left<x1 ) x1 = left; |
| 144557 | if( right>x4 ) x4 = right; |
| 144558 | if( left>x3 ){ |
| 144559 | x3 = left; |
| 144560 | iCellRight = jj; |
| 144561 | } |
| 144562 | if( right<x2 ){ |
| 144563 | x2 = right; |
| 144564 | iCellLeft = jj; |
| 144565 | } |
| 144566 | } |
| 144567 | |
| 144568 | if( x4!=x1 ){ |
| 144569 | RtreeDValue normalwidth = (x3 - x2) / (x4 - x1); |
| 144570 | if( normalwidth>maxNormalInnerWidth ){ |
| 144571 | iLeftSeed = iCellLeft; |
| 144572 | iRightSeed = iCellRight; |
| 144573 | } |
| 144574 | } |
| 144575 | } |
| 144576 | |
| 144577 | *piLeftSeed = iLeftSeed; |
| 144578 | *piRightSeed = iRightSeed; |
| 144579 | } |
| 144580 | #endif /* VARIANT_GUTTMAN_LINEAR_SPLIT */ |
| 144581 | |
| 144582 | #if VARIANT_GUTTMAN_QUADRATIC_SPLIT |
| 144583 | /* |
| 144584 | ** Implementation of the quadratic variant of the PickNext() function from |
| 144585 | ** Guttman[84]. |
| 144586 | */ |
| 144587 | static RtreeCell *QuadraticPickNext( |
| 144588 | Rtree *pRtree, |
| 144589 | RtreeCell *aCell, |
| 144590 | int nCell, |
| 144591 | RtreeCell *pLeftBox, |
| 144592 | RtreeCell *pRightBox, |
| 144593 | int *aiUsed |
| 144594 | ){ |
| 144595 | #define FABS(a) ((a)<0.0?-1.0*(a):(a)) |
| 144596 | |
| 144597 | int iSelect = -1; |
| 144598 | RtreeDValue fDiff; |
| 144599 | int ii; |
| 144600 | for(ii=0; ii<nCell; ii++){ |
| 144601 | if( aiUsed[ii]==0 ){ |
| 144602 | RtreeDValue left = cellGrowth(pRtree, pLeftBox, &aCell[ii]); |
| 144603 | RtreeDValue right = cellGrowth(pRtree, pLeftBox, &aCell[ii]); |
| 144604 | RtreeDValue diff = FABS(right-left); |
| 144605 | if( iSelect<0 || diff>fDiff ){ |
| 144606 | fDiff = diff; |
| 144607 | iSelect = ii; |
| 144608 | } |
| 144609 | } |
| 144610 | } |
| 144611 | aiUsed[iSelect] = 1; |
| 144612 | return &aCell[iSelect]; |
| 144613 | } |
| 144614 | |
| 144615 | /* |
| 144616 | ** Implementation of the quadratic variant of the PickSeeds() function from |
| 144617 | ** Guttman[84]. |
| 144618 | */ |
| 144619 | static void QuadraticPickSeeds( |
| 144620 | Rtree *pRtree, |
| 144621 | RtreeCell *aCell, |
| 144622 | int nCell, |
| 144623 | int *piLeftSeed, |
| 144624 | int *piRightSeed |
| 144625 | ){ |
| 144626 | int ii; |
| 144627 | int jj; |
| 144628 | |
| 144629 | int iLeftSeed = 0; |
| 144630 | int iRightSeed = 1; |
| 144631 | RtreeDValue fWaste = 0.0; |
| 144632 | |
| 144633 | for(ii=0; ii<nCell; ii++){ |
| 144634 | for(jj=ii+1; jj<nCell; jj++){ |
| 144635 | RtreeDValue right = cellArea(pRtree, &aCell[jj]); |
| 144636 | RtreeDValue growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]); |
| 144637 | RtreeDValue waste = growth - right; |
| 144638 | |
| 144639 | if( waste>fWaste ){ |
| 144640 | iLeftSeed = ii; |
| 144641 | iRightSeed = jj; |
| 144642 | fWaste = waste; |
| 144643 | } |
| 144644 | } |
| 144645 | } |
| 144646 | |
| 144647 | *piLeftSeed = iLeftSeed; |
| 144648 | *piRightSeed = iRightSeed; |
| 144649 | } |
| 144650 | #endif /* VARIANT_GUTTMAN_QUADRATIC_SPLIT */ |
| 144651 | |
| 144652 | /* |
| 144653 | ** Arguments aIdx, aDistance and aSpare all point to arrays of size |
| 144654 | ** nIdx. The aIdx array contains the set of integers from 0 to |
| 144655 | ** (nIdx-1) in no particular order. This function sorts the values |
| @@ -144786,11 +145533,10 @@ | |
| 144786 | } |
| 144787 | #endif |
| 144788 | } |
| 144789 | } |
| 144790 | |
| 144791 | #if VARIANT_RSTARTREE_SPLIT |
| 144792 | /* |
| 144793 | ** Implementation of the R*-tree variant of SplitNode from Beckman[1990]. |
| 144794 | */ |
| 144795 | static int splitNodeStartree( |
| 144796 | Rtree *pRtree, |
| @@ -144805,11 +145551,11 @@ | |
| 144805 | int *aSpare; |
| 144806 | int ii; |
| 144807 | |
| 144808 | int iBestDim = 0; |
| 144809 | int iBestSplit = 0; |
| 144810 | RtreeDValue fBestMargin = 0.0; |
| 144811 | |
| 144812 | int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); |
| 144813 | |
| 144814 | aaSorted = (int **)sqlite3_malloc(nByte); |
| 144815 | if( !aaSorted ){ |
| @@ -144826,13 +145572,13 @@ | |
| 144826 | } |
| 144827 | SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare); |
| 144828 | } |
| 144829 | |
| 144830 | for(ii=0; ii<pRtree->nDim; ii++){ |
| 144831 | RtreeDValue margin = 0.0; |
| 144832 | RtreeDValue fBestOverlap = 0.0; |
| 144833 | RtreeDValue fBestArea = 0.0; |
| 144834 | int iBestLeft = 0; |
| 144835 | int nLeft; |
| 144836 | |
| 144837 | for( |
| 144838 | nLeft=RTREE_MINCELLS(pRtree); |
| @@ -144854,11 +145600,11 @@ | |
| 144854 | cellUnion(pRtree, &right, &aCell[aaSorted[ii][kk]]); |
| 144855 | } |
| 144856 | } |
| 144857 | margin += cellMargin(pRtree, &left); |
| 144858 | margin += cellMargin(pRtree, &right); |
| 144859 | overlap = cellOverlap(pRtree, &left, &right, 1, -1); |
| 144860 | area = cellArea(pRtree, &left) + cellArea(pRtree, &right); |
| 144861 | if( (nLeft==RTREE_MINCELLS(pRtree)) |
| 144862 | || (overlap<fBestOverlap) |
| 144863 | || (overlap==fBestOverlap && area<fBestArea) |
| 144864 | ){ |
| @@ -144886,67 +145632,11 @@ | |
| 144886 | } |
| 144887 | |
| 144888 | sqlite3_free(aaSorted); |
| 144889 | return SQLITE_OK; |
| 144890 | } |
| 144891 | #endif |
| 144892 | |
| 144893 | #if VARIANT_GUTTMAN_SPLIT |
| 144894 | /* |
| 144895 | ** Implementation of the regular R-tree SplitNode from Guttman[1984]. |
| 144896 | */ |
| 144897 | static int splitNodeGuttman( |
| 144898 | Rtree *pRtree, |
| 144899 | RtreeCell *aCell, |
| 144900 | int nCell, |
| 144901 | RtreeNode *pLeft, |
| 144902 | RtreeNode *pRight, |
| 144903 | RtreeCell *pBboxLeft, |
| 144904 | RtreeCell *pBboxRight |
| 144905 | ){ |
| 144906 | int iLeftSeed = 0; |
| 144907 | int iRightSeed = 1; |
| 144908 | int *aiUsed; |
| 144909 | int i; |
| 144910 | |
| 144911 | aiUsed = sqlite3_malloc(sizeof(int)*nCell); |
| 144912 | if( !aiUsed ){ |
| 144913 | return SQLITE_NOMEM; |
| 144914 | } |
| 144915 | memset(aiUsed, 0, sizeof(int)*nCell); |
| 144916 | |
| 144917 | PickSeeds(pRtree, aCell, nCell, &iLeftSeed, &iRightSeed); |
| 144918 | |
| 144919 | memcpy(pBboxLeft, &aCell[iLeftSeed], sizeof(RtreeCell)); |
| 144920 | memcpy(pBboxRight, &aCell[iRightSeed], sizeof(RtreeCell)); |
| 144921 | nodeInsertCell(pRtree, pLeft, &aCell[iLeftSeed]); |
| 144922 | nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]); |
| 144923 | aiUsed[iLeftSeed] = 1; |
| 144924 | aiUsed[iRightSeed] = 1; |
| 144925 | |
| 144926 | for(i=nCell-2; i>0; i--){ |
| 144927 | RtreeCell *pNext; |
| 144928 | pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed); |
| 144929 | RtreeDValue diff = |
| 144930 | cellGrowth(pRtree, pBboxLeft, pNext) - |
| 144931 | cellGrowth(pRtree, pBboxRight, pNext) |
| 144932 | ; |
| 144933 | if( (RTREE_MINCELLS(pRtree)-NCELL(pRight)==i) |
| 144934 | || (diff>0.0 && (RTREE_MINCELLS(pRtree)-NCELL(pLeft)!=i)) |
| 144935 | ){ |
| 144936 | nodeInsertCell(pRtree, pRight, pNext); |
| 144937 | cellUnion(pRtree, pBboxRight, pNext); |
| 144938 | }else{ |
| 144939 | nodeInsertCell(pRtree, pLeft, pNext); |
| 144940 | cellUnion(pRtree, pBboxLeft, pNext); |
| 144941 | } |
| 144942 | } |
| 144943 | |
| 144944 | sqlite3_free(aiUsed); |
| 144945 | return SQLITE_OK; |
| 144946 | } |
| 144947 | #endif |
| 144948 | |
| 144949 | static int updateMapping( |
| 144950 | Rtree *pRtree, |
| 144951 | i64 iRowid, |
| 144952 | RtreeNode *pNode, |
| @@ -145020,11 +145710,12 @@ | |
| 145020 | } |
| 145021 | |
| 145022 | memset(pLeft->zData, 0, pRtree->iNodeSize); |
| 145023 | memset(pRight->zData, 0, pRtree->iNodeSize); |
| 145024 | |
| 145025 | rc = AssignCells(pRtree, aCell, nCell, pLeft, pRight, &leftbbox, &rightbbox); |
| 145026 | if( rc!=SQLITE_OK ){ |
| 145027 | goto splitnode_out; |
| 145028 | } |
| 145029 | |
| 145030 | /* Ensure both child nodes have node numbers assigned to them by calling |
| @@ -145303,11 +145994,11 @@ | |
| 145303 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 145304 | aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2)); |
| 145305 | } |
| 145306 | |
| 145307 | for(ii=0; ii<nCell; ii++){ |
| 145308 | aDistance[ii] = 0.0; |
| 145309 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 145310 | RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) - |
| 145311 | DCOORD(aCell[ii].aCoord[iDim*2])); |
| 145312 | aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); |
| 145313 | } |
| @@ -145369,20 +146060,16 @@ | |
| 145369 | nodeReference(pNode); |
| 145370 | pChild->pParent = pNode; |
| 145371 | } |
| 145372 | } |
| 145373 | if( nodeInsertCell(pRtree, pNode, pCell) ){ |
| 145374 | #if VARIANT_RSTARTREE_REINSERT |
| 145375 | if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){ |
| 145376 | rc = SplitNode(pRtree, pNode, pCell, iHeight); |
| 145377 | }else{ |
| 145378 | pRtree->iReinsertHeight = iHeight; |
| 145379 | rc = Reinsert(pRtree, pNode, pCell, iHeight); |
| 145380 | } |
| 145381 | #else |
| 145382 | rc = SplitNode(pRtree, pNode, pCell, iHeight); |
| 145383 | #endif |
| 145384 | }else{ |
| 145385 | rc = AdjustTree(pRtree, pNode, pCell); |
| 145386 | if( rc==SQLITE_OK ){ |
| 145387 | if( iHeight==0 ){ |
| 145388 | rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); |
| @@ -145448,11 +146135,11 @@ | |
| 145448 | |
| 145449 | /* Obtain a reference to the leaf node that contains the entry |
| 145450 | ** about to be deleted. |
| 145451 | */ |
| 145452 | if( rc==SQLITE_OK ){ |
| 145453 | rc = findLeafNode(pRtree, iDelete, &pLeaf); |
| 145454 | } |
| 145455 | |
| 145456 | /* Delete the cell in question from the leaf node. */ |
| 145457 | if( rc==SQLITE_OK ){ |
| 145458 | int rc2; |
| @@ -145785,11 +146472,12 @@ | |
| 145785 | |
| 145786 | if( isCreate ){ |
| 145787 | char *zCreate = sqlite3_mprintf( |
| 145788 | "CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);" |
| 145789 | "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);" |
| 145790 | "CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY, parentnode INTEGER);" |
| 145791 | "INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))", |
| 145792 | zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize |
| 145793 | ); |
| 145794 | if( !zCreate ){ |
| 145795 | return SQLITE_NOMEM; |
| @@ -145999,14 +146687,14 @@ | |
| 145999 | |
| 146000 | /* |
| 146001 | ** Implementation of a scalar function that decodes r-tree nodes to |
| 146002 | ** human readable strings. This can be used for debugging and analysis. |
| 146003 | ** |
| 146004 | ** The scalar function takes two arguments, a blob of data containing |
| 146005 | ** an r-tree node, and the number of dimensions the r-tree indexes. |
| 146006 | ** For a two-dimensional r-tree structure called "rt", to deserialize |
| 146007 | ** all nodes, a statement like: |
| 146008 | ** |
| 146009 | ** SELECT rtreenode(2, data) FROM rt_node; |
| 146010 | ** |
| 146011 | ** The human readable string takes the form of a Tcl list with one |
| 146012 | ** entry for each cell in the r-tree node. Each entry is itself a |
| @@ -146035,11 +146723,11 @@ | |
| 146035 | nodeGetCell(&tree, &node, ii, &cell); |
| 146036 | sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid); |
| 146037 | nCell = (int)strlen(zCell); |
| 146038 | for(jj=0; jj<tree.nDim*2; jj++){ |
| 146039 | #ifndef SQLITE_RTREE_INT_ONLY |
| 146040 | sqlite3_snprintf(512-nCell,&zCell[nCell], " %f", |
| 146041 | (double)cell.aCoord[jj].f); |
| 146042 | #else |
| 146043 | sqlite3_snprintf(512-nCell,&zCell[nCell], " %d", |
| 146044 | cell.aCoord[jj].i); |
| 146045 | #endif |
| @@ -146056,10 +146744,19 @@ | |
| 146056 | } |
| 146057 | |
| 146058 | sqlite3_result_text(ctx, zText, -1, sqlite3_free); |
| 146059 | } |
| 146060 | |
| 146061 | static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ |
| 146062 | UNUSED_PARAMETER(nArg); |
| 146063 | if( sqlite3_value_type(apArg[0])!=SQLITE_BLOB |
| 146064 | || sqlite3_value_bytes(apArg[0])<2 |
| 146065 | ){ |
| @@ -146098,26 +146795,35 @@ | |
| 146098 | |
| 146099 | return rc; |
| 146100 | } |
| 146101 | |
| 146102 | /* |
| 146103 | ** A version of sqlite3_free() that can be used as a callback. This is used |
| 146104 | ** in two places - as the destructor for the blob value returned by the |
| 146105 | ** invocation of a geometry function, and as the destructor for the geometry |
| 146106 | ** functions themselves. |
| 146107 | */ |
| 146108 | static void doSqlite3Free(void *p){ |
| 146109 | sqlite3_free(p); |
| 146110 | } |
| 146111 | |
| 146112 | /* |
| 146113 | ** Each call to sqlite3_rtree_geometry_callback() creates an ordinary SQLite |
| 146114 | ** scalar user function. This C function is the callback used for all such |
| 146115 | ** registered SQL functions. |
| 146116 | ** |
| 146117 | ** The scalar user functions return a blob that is interpreted by r-tree |
| 146118 | ** table MATCH operators. |
| 146119 | */ |
| 146120 | static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ |
| 146121 | RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); |
| 146122 | RtreeMatchArg *pBlob; |
| 146123 | int nBlob; |
| @@ -146127,45 +146833,68 @@ | |
| 146127 | if( !pBlob ){ |
| 146128 | sqlite3_result_error_nomem(ctx); |
| 146129 | }else{ |
| 146130 | int i; |
| 146131 | pBlob->magic = RTREE_GEOMETRY_MAGIC; |
| 146132 | pBlob->xGeom = pGeomCtx->xGeom; |
| 146133 | pBlob->pContext = pGeomCtx->pContext; |
| 146134 | pBlob->nParam = nArg; |
| 146135 | for(i=0; i<nArg; i++){ |
| 146136 | #ifdef SQLITE_RTREE_INT_ONLY |
| 146137 | pBlob->aParam[i] = sqlite3_value_int64(aArg[i]); |
| 146138 | #else |
| 146139 | pBlob->aParam[i] = sqlite3_value_double(aArg[i]); |
| 146140 | #endif |
| 146141 | } |
| 146142 | sqlite3_result_blob(ctx, pBlob, nBlob, doSqlite3Free); |
| 146143 | } |
| 146144 | } |
| 146145 | |
| 146146 | /* |
| 146147 | ** Register a new geometry function for use with the r-tree MATCH operator. |
| 146148 | */ |
| 146149 | SQLITE_API int sqlite3_rtree_geometry_callback( |
| 146150 | sqlite3 *db, |
| 146151 | const char *zGeom, |
| 146152 | int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue *, int *), |
| 146153 | void *pContext |
| 146154 | ){ |
| 146155 | RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ |
| 146156 | |
| 146157 | /* Allocate and populate the context object. */ |
| 146158 | pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); |
| 146159 | if( !pGeomCtx ) return SQLITE_NOMEM; |
| 146160 | pGeomCtx->xGeom = xGeom; |
| 146161 | pGeomCtx->pContext = pContext; |
| 146162 | |
| 146163 | /* Create the new user-function. Register a destructor function to delete |
| 146164 | ** the context object when it is no longer required. */ |
| 146165 | return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, |
| 146166 | (void *)pGeomCtx, geomCallback, 0, 0, doSqlite3Free |
| 146167 | ); |
| 146168 | } |
| 146169 | |
| 146170 | #if !SQLITE_CORE |
| 146171 | #ifdef _WIN32 |
| 146172 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -222,11 +222,11 @@ | |
| 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | */ |
| 225 | #define SQLITE_VERSION "3.8.5" |
| 226 | #define SQLITE_VERSION_NUMBER 3008005 |
| 227 | #define SQLITE_SOURCE_ID "2014-05-24 17:15:15 ebfb51fe40756713d269b4c0ade752666910bb6e" |
| 228 | |
| 229 | /* |
| 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | ** |
| @@ -673,11 +673,14 @@ | |
| 673 | ** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that |
| 674 | ** after reboot following a crash or power loss, the only bytes in a |
| 675 | ** file that were written at the application level might have changed |
| 676 | ** and that adjacent bytes, even bytes within the same sector are |
| 677 | ** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
| 678 | ** flag indicate that a file cannot be deleted when open. The |
| 679 | ** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on |
| 680 | ** read-only media and cannot be changed even by processes with |
| 681 | ** elevated privileges. |
| 682 | */ |
| 683 | #define SQLITE_IOCAP_ATOMIC 0x00000001 |
| 684 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 |
| 685 | #define SQLITE_IOCAP_ATOMIC1K 0x00000004 |
| 686 | #define SQLITE_IOCAP_ATOMIC2K 0x00000008 |
| @@ -688,10 +691,11 @@ | |
| 691 | #define SQLITE_IOCAP_ATOMIC64K 0x00000100 |
| 692 | #define SQLITE_IOCAP_SAFE_APPEND 0x00000200 |
| 693 | #define SQLITE_IOCAP_SEQUENTIAL 0x00000400 |
| 694 | #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 |
| 695 | #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 |
| 696 | #define SQLITE_IOCAP_IMMUTABLE 0x00002000 |
| 697 | |
| 698 | /* |
| 699 | ** CAPI3REF: File Locking Levels |
| 700 | ** |
| 701 | ** SQLite uses one of these integer values as the second |
| @@ -2892,10 +2896,34 @@ | |
| 2896 | ** sqlite3_open_v2(). ^Setting the cache parameter to "private" is |
| 2897 | ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. |
| 2898 | ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in |
| 2899 | ** a URI filename, its value overrides any behavior requested by setting |
| 2900 | ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. |
| 2901 | ** |
| 2902 | ** <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or |
| 2903 | ** "1") or "false" (or "off" or "no" or "0") to indicate that the |
| 2904 | ** [powersafe overwrite] property does or does not apply to the |
| 2905 | ** storage media on which the database file resides. ^The psow query |
| 2906 | ** parameter only works for the built-in unix and Windows VFSes. |
| 2907 | ** |
| 2908 | ** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter |
| 2909 | ** which if set disables file locking in rollback journal modes. This |
| 2910 | ** is useful for accessing a database on a filesystem that does not |
| 2911 | ** support locking. Caution: Database corruption might result if two |
| 2912 | ** or more processes write to the same database and any one of those |
| 2913 | ** processes uses nolock=1. |
| 2914 | ** |
| 2915 | ** <li> <b>immutable</b>: ^The immutable parameter is a boolean query |
| 2916 | ** parameter that indicates that the database file is stored on |
| 2917 | ** read-only media. ^When immutable is set, SQLite assumes that the |
| 2918 | ** database file cannot be changed, even by a process with higher |
| 2919 | ** privilege, and so the database is opened read-only and all locking |
| 2920 | ** and change detection is disabled. Caution: Setting the immutable |
| 2921 | ** property on a database file that does in fact change can result |
| 2922 | ** in incorrect query results and/or [SQLITE_CORRUPT] errors. |
| 2923 | ** See also: [SQLITE_IOCAP_IMMUTABLE]. |
| 2924 | ** |
| 2925 | ** </ul> |
| 2926 | ** |
| 2927 | ** ^Specifying an unknown parameter in the query component of a URI is not an |
| 2928 | ** error. Future versions of SQLite might understand additional query |
| 2929 | ** parameters. See "[query parameters with special meaning to SQLite]" for |
| @@ -2921,12 +2949,13 @@ | |
| 2949 | ** in URI filenames. |
| 2950 | ** <tr><td> file:data.db?mode=ro&cache=private <td> |
| 2951 | ** Open file "data.db" in the current directory for read-only access. |
| 2952 | ** Regardless of whether or not shared-cache mode is enabled by |
| 2953 | ** default, use a private cache. |
| 2954 | ** <tr><td> file:/home/fred/data.db?vfs=unix-dotfile <td> |
| 2955 | ** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile" |
| 2956 | ** that uses dot-files in place of posix advisory locking. |
| 2957 | ** <tr><td> file:data.db?mode=readonly <td> |
| 2958 | ** An error. "readonly" is not a valid option for the "mode" parameter. |
| 2959 | ** </table> |
| 2960 | ** |
| 2961 | ** ^URI hexadecimal escape sequences (%HH) are supported within the path and |
| @@ -7460,10 +7489,20 @@ | |
| 7489 | #if 0 |
| 7490 | extern "C" { |
| 7491 | #endif |
| 7492 | |
| 7493 | typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; |
| 7494 | typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; |
| 7495 | |
| 7496 | /* The double-precision datatype used by RTree depends on the |
| 7497 | ** SQLITE_RTREE_INT_ONLY compile-time option. |
| 7498 | */ |
| 7499 | #ifdef SQLITE_RTREE_INT_ONLY |
| 7500 | typedef sqlite3_int64 sqlite3_rtree_dbl; |
| 7501 | #else |
| 7502 | typedef double sqlite3_rtree_dbl; |
| 7503 | #endif |
| 7504 | |
| 7505 | /* |
| 7506 | ** Register a geometry callback named zGeom that can be used as part of an |
| 7507 | ** R-Tree geometry query as follows: |
| 7508 | ** |
| @@ -7470,15 +7509,11 @@ | |
| 7509 | ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) |
| 7510 | */ |
| 7511 | SQLITE_API int sqlite3_rtree_geometry_callback( |
| 7512 | sqlite3 *db, |
| 7513 | const char *zGeom, |
| 7514 | int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), |
| 7515 | void *pContext |
| 7516 | ); |
| 7517 | |
| 7518 | |
| 7519 | /* |
| @@ -7486,15 +7521,64 @@ | |
| 7521 | ** argument to callbacks registered using rtree_geometry_callback(). |
| 7522 | */ |
| 7523 | struct sqlite3_rtree_geometry { |
| 7524 | void *pContext; /* Copy of pContext passed to s_r_g_c() */ |
| 7525 | int nParam; /* Size of array aParam[] */ |
| 7526 | sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */ |
| 7527 | void *pUser; /* Callback implementation user data */ |
| 7528 | void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ |
| 7529 | }; |
| 7530 | |
| 7531 | /* |
| 7532 | ** Register a 2nd-generation geometry callback named zScore that can be |
| 7533 | ** used as part of an R-Tree geometry query as follows: |
| 7534 | ** |
| 7535 | ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...) |
| 7536 | */ |
| 7537 | SQLITE_API int sqlite3_rtree_query_callback( |
| 7538 | sqlite3 *db, |
| 7539 | const char *zQueryFunc, |
| 7540 | int (*xQueryFunc)(sqlite3_rtree_query_info*), |
| 7541 | void *pContext, |
| 7542 | void (*xDestructor)(void*) |
| 7543 | ); |
| 7544 | |
| 7545 | |
| 7546 | /* |
| 7547 | ** A pointer to a structure of the following type is passed as the |
| 7548 | ** argument to scored geometry callback registered using |
| 7549 | ** sqlite3_rtree_query_callback(). |
| 7550 | ** |
| 7551 | ** Note that the first 5 fields of this structure are identical to |
| 7552 | ** sqlite3_rtree_geometry. This structure is a subclass of |
| 7553 | ** sqlite3_rtree_geometry. |
| 7554 | */ |
| 7555 | struct sqlite3_rtree_query_info { |
| 7556 | void *pContext; /* pContext from when function registered */ |
| 7557 | int nParam; /* Number of function parameters */ |
| 7558 | sqlite3_rtree_dbl *aParam; /* value of function parameters */ |
| 7559 | void *pUser; /* callback can use this, if desired */ |
| 7560 | void (*xDelUser)(void*); /* function to free pUser */ |
| 7561 | sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */ |
| 7562 | unsigned int *anQueue; /* Number of pending entries in the queue */ |
| 7563 | int nCoord; /* Number of coordinates */ |
| 7564 | int iLevel; /* Level of current node or entry */ |
| 7565 | int mxLevel; /* The largest iLevel value in the tree */ |
| 7566 | sqlite3_int64 iRowid; /* Rowid for current entry */ |
| 7567 | sqlite3_rtree_dbl rParentScore; /* Score of parent node */ |
| 7568 | int eParentWithin; /* Visibility of parent node */ |
| 7569 | int eWithin; /* OUT: Visiblity */ |
| 7570 | sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ |
| 7571 | }; |
| 7572 | |
| 7573 | /* |
| 7574 | ** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin. |
| 7575 | */ |
| 7576 | #define NOT_WITHIN 0 /* Object completely outside of query region */ |
| 7577 | #define PARTLY_WITHIN 1 /* Object partially overlaps query region */ |
| 7578 | #define FULLY_WITHIN 2 /* Object fully contained within query region */ |
| 7579 | |
| 7580 | |
| 7581 | #if 0 |
| 7582 | } /* end of the 'extern "C"' block */ |
| 7583 | #endif |
| 7584 | |
| @@ -8417,14 +8501,14 @@ | |
| 8501 | ** Estimated quantities used for query planning are stored as 16-bit |
| 8502 | ** logarithms. For quantity X, the value stored is 10*log2(X). This |
| 8503 | ** gives a possible range of values of approximately 1.0e986 to 1e-986. |
| 8504 | ** But the allowed values are "grainy". Not every value is representable. |
| 8505 | ** For example, quantities 16 and 17 are both represented by a LogEst |
| 8506 | ** of 40. However, since LogEst quantaties are suppose to be estimates, |
| 8507 | ** not exact values, this imprecision is not a problem. |
| 8508 | ** |
| 8509 | ** "LogEst" is short for "Logarithmic Estimate". |
| 8510 | ** |
| 8511 | ** Examples: |
| 8512 | ** 1 -> 0 20 -> 43 10000 -> 132 |
| 8513 | ** 2 -> 10 25 -> 46 25000 -> 146 |
| 8514 | ** 3 -> 16 100 -> 66 1000000 -> 199 |
| @@ -8916,10 +9000,11 @@ | |
| 9000 | SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); |
| 9001 | SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *); |
| 9002 | SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); |
| 9003 | SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); |
| 9004 | SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask); |
| 9005 | SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt); |
| 9006 | |
| 9007 | #ifndef NDEBUG |
| 9008 | SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); |
| 9009 | #endif |
| 9010 | |
| @@ -9870,87 +9955,75 @@ | |
| 9955 | */ |
| 9956 | #ifndef _SQLITE_OS_H_ |
| 9957 | #define _SQLITE_OS_H_ |
| 9958 | |
| 9959 | /* |
| 9960 | ** Attempt to automatically detect the operating system and setup the |
| 9961 | ** necessary pre-processor macros for it. |
| 9962 | */ |
| 9963 | /************** Include os_setup.h in the middle of os.h *********************/ |
| 9964 | /************** Begin file os_setup.h ****************************************/ |
| 9965 | /* |
| 9966 | ** 2013 November 25 |
| 9967 | ** |
| 9968 | ** The author disclaims copyright to this source code. In place of |
| 9969 | ** a legal notice, here is a blessing: |
| 9970 | ** |
| 9971 | ** May you do good and not evil. |
| 9972 | ** May you find forgiveness for yourself and forgive others. |
| 9973 | ** May you share freely, never taking more than you give. |
| 9974 | ** |
| 9975 | ****************************************************************************** |
| 9976 | ** |
| 9977 | ** This file contains pre-processor directives related to operating system |
| 9978 | ** detection and/or setup. |
| 9979 | */ |
| 9980 | #ifndef _OS_SETUP_H_ |
| 9981 | #define _OS_SETUP_H_ |
| 9982 | |
| 9983 | /* |
| 9984 | ** Figure out if we are dealing with Unix, Windows, or some other operating |
| 9985 | ** system. |
| 9986 | ** |
| 9987 | ** After the following block of preprocess macros, all of SQLITE_OS_UNIX, |
| 9988 | ** SQLITE_OS_WIN, and SQLITE_OS_OTHER will defined to either 1 or 0. One of |
| 9989 | ** the three will be 1. The other two will be 0. |
| 9990 | */ |
| 9991 | #if defined(SQLITE_OS_OTHER) |
| 9992 | # if SQLITE_OS_OTHER==1 |
| 9993 | # undef SQLITE_OS_UNIX |
| 9994 | # define SQLITE_OS_UNIX 0 |
| 9995 | # undef SQLITE_OS_WIN |
| 9996 | # define SQLITE_OS_WIN 0 |
| 9997 | # else |
| 9998 | # undef SQLITE_OS_OTHER |
| 9999 | # endif |
| 10000 | #endif |
| 10001 | #if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) |
| 10002 | # define SQLITE_OS_OTHER 0 |
| 10003 | # ifndef SQLITE_OS_WIN |
| 10004 | # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ |
| 10005 | defined(__MINGW32__) || defined(__BORLANDC__) |
| 10006 | # define SQLITE_OS_WIN 1 |
| 10007 | # define SQLITE_OS_UNIX 0 |
| 10008 | # else |
| 10009 | # define SQLITE_OS_WIN 0 |
| 10010 | # define SQLITE_OS_UNIX 1 |
| 10011 | # endif |
| 10012 | # else |
| 10013 | # define SQLITE_OS_UNIX 0 |
| 10014 | # endif |
| 10015 | #else |
| 10016 | # ifndef SQLITE_OS_WIN |
| 10017 | # define SQLITE_OS_WIN 0 |
| 10018 | # endif |
| 10019 | #endif |
| 10020 | |
| 10021 | #endif /* _OS_SETUP_H_ */ |
| 10022 | |
| 10023 | /************** End of os_setup.h ********************************************/ |
| 10024 | /************** Continuing where we left off in os.h *************************/ |
| 10025 | |
| 10026 | /* If the SET_FULLSYNC macro is not defined above, then make it |
| 10027 | ** a no-op |
| 10028 | */ |
| 10029 | #ifndef SET_FULLSYNC |
| @@ -10845,11 +10918,11 @@ | |
| 10918 | FKey *pFKey; /* Linked list of all foreign keys in this table */ |
| 10919 | char *zColAff; /* String defining the affinity of each column */ |
| 10920 | #ifndef SQLITE_OMIT_CHECK |
| 10921 | ExprList *pCheck; /* All CHECK constraints */ |
| 10922 | #endif |
| 10923 | LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */ |
| 10924 | int tnum; /* Root BTree node for this table (see note above) */ |
| 10925 | i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */ |
| 10926 | i16 nCol; /* Number of columns in this table */ |
| 10927 | u16 nRef; /* Number of pointers to this Table */ |
| 10928 | LogEst szTabRow; /* Estimated size of each table row in bytes */ |
| @@ -11054,11 +11127,11 @@ | |
| 11127 | ** element. |
| 11128 | */ |
| 11129 | struct Index { |
| 11130 | char *zName; /* Name of this index */ |
| 11131 | i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */ |
| 11132 | LogEst *aiRowLogEst; /* From ANALYZE: Est. rows selected by each column */ |
| 11133 | Table *pTable; /* The SQL table being indexed */ |
| 11134 | char *zColAff; /* String defining the affinity of each column */ |
| 11135 | Index *pNext; /* The next index associated with the same table */ |
| 11136 | Schema *pSchema; /* Schema containing this index */ |
| 11137 | u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ |
| @@ -11499,10 +11572,11 @@ | |
| 11572 | #define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */ |
| 11573 | #define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */ |
| 11574 | #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ |
| 11575 | #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ |
| 11576 | #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ |
| 11577 | #define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */ |
| 11578 | |
| 11579 | /* Allowed return values from sqlite3WhereIsDistinct() |
| 11580 | */ |
| 11581 | #define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ |
| 11582 | #define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ |
| @@ -12082,15 +12156,14 @@ | |
| 12156 | int isInit; /* True after initialization has finished */ |
| 12157 | int inProgress; /* True while initialization in progress */ |
| 12158 | int isMutexInit; /* True after mutexes are initialized */ |
| 12159 | int isMallocInit; /* True after malloc is initialized */ |
| 12160 | int isPCacheInit; /* True after malloc is initialized */ |
| 12161 | int nRefInitMutex; /* Number of users of pInitMutex */ |
| 12162 | sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ |
| 12163 | void (*xLog)(void*,int,const char*); /* Function for logging */ |
| 12164 | void *pLogArg; /* First argument to xLog() */ |
| 12165 | #ifdef SQLITE_ENABLE_SQLLOG |
| 12166 | void(*xSqllog)(void*,sqlite3*,const char*, int); |
| 12167 | void *pSqllogArg; |
| 12168 | #endif |
| 12169 | #ifdef SQLITE_VDBE_COVERAGE |
| @@ -12098,10 +12171,14 @@ | |
| 12171 | ** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE. |
| 12172 | */ |
| 12173 | void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */ |
| 12174 | void *pVdbeBranchArg; /* 1st argument */ |
| 12175 | #endif |
| 12176 | #ifndef SQLITE_OMIT_BUILTIN_TEST |
| 12177 | int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ |
| 12178 | #endif |
| 12179 | int bLocaltimeFault; /* True to fail localtime() calls */ |
| 12180 | }; |
| 12181 | |
| 12182 | /* |
| 12183 | ** This macro is used inside of assert() statements to indicate that |
| 12184 | ** the assert is only valid on a well-formed database. Instead of: |
| @@ -12398,10 +12475,16 @@ | |
| 12475 | SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); |
| 12476 | SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, |
| 12477 | sqlite3_vfs**,char**,char **); |
| 12478 | SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*); |
| 12479 | SQLITE_PRIVATE int sqlite3CodeOnce(Parse *); |
| 12480 | |
| 12481 | #ifdef SQLITE_OMIT_BUILTIN_TEST |
| 12482 | # define sqlite3FaultSim(X) SQLITE_OK |
| 12483 | #else |
| 12484 | SQLITE_PRIVATE int sqlite3FaultSim(int); |
| 12485 | #endif |
| 12486 | |
| 12487 | SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32); |
| 12488 | SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32); |
| 12489 | SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32); |
| 12490 | SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*); |
| @@ -12466,10 +12549,11 @@ | |
| 12549 | SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); |
| 12550 | SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); |
| 12551 | SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo*); |
| 12552 | SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*); |
| 12553 | SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*); |
| 12554 | SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*); |
| 12555 | SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*); |
| 12556 | SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*); |
| 12557 | SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*); |
| 12558 | SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); |
| 12559 | SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); |
| @@ -13203,19 +13287,26 @@ | |
| 13287 | 0, /* isInit */ |
| 13288 | 0, /* inProgress */ |
| 13289 | 0, /* isMutexInit */ |
| 13290 | 0, /* isMallocInit */ |
| 13291 | 0, /* isPCacheInit */ |
| 13292 | 0, /* nRefInitMutex */ |
| 13293 | 0, /* pInitMutex */ |
| 13294 | 0, /* xLog */ |
| 13295 | 0, /* pLogArg */ |
| 13296 | #ifdef SQLITE_ENABLE_SQLLOG |
| 13297 | 0, /* xSqllog */ |
| 13298 | 0, /* pSqllogArg */ |
| 13299 | #endif |
| 13300 | #ifdef SQLITE_VDBE_COVERAGE |
| 13301 | 0, /* xVdbeBranch */ |
| 13302 | 0, /* pVbeBranchArg */ |
| 13303 | #endif |
| 13304 | #ifndef SQLITE_OMIT_BUILTIN_TEST |
| 13305 | 0, /* xTestCallback */ |
| 13306 | #endif |
| 13307 | 0 /* bLocaltimeFault */ |
| 13308 | }; |
| 13309 | |
| 13310 | /* |
| 13311 | ** Hash table for global functions - functions common to all |
| 13312 | ** database connections. After initialization, this table is |
| @@ -18934,10 +19025,88 @@ | |
| 19025 | ** |
| 19026 | ************************************************************************* |
| 19027 | ** This file contains the C functions that implement mutexes for win32 |
| 19028 | */ |
| 19029 | |
| 19030 | #if SQLITE_OS_WIN |
| 19031 | /* |
| 19032 | ** Include the header file for the Windows VFS. |
| 19033 | */ |
| 19034 | /************** Include os_win.h in the middle of mutex_w32.c ****************/ |
| 19035 | /************** Begin file os_win.h ******************************************/ |
| 19036 | /* |
| 19037 | ** 2013 November 25 |
| 19038 | ** |
| 19039 | ** The author disclaims copyright to this source code. In place of |
| 19040 | ** a legal notice, here is a blessing: |
| 19041 | ** |
| 19042 | ** May you do good and not evil. |
| 19043 | ** May you find forgiveness for yourself and forgive others. |
| 19044 | ** May you share freely, never taking more than you give. |
| 19045 | ** |
| 19046 | ****************************************************************************** |
| 19047 | ** |
| 19048 | ** This file contains code that is specific to Windows. |
| 19049 | */ |
| 19050 | #ifndef _OS_WIN_H_ |
| 19051 | #define _OS_WIN_H_ |
| 19052 | |
| 19053 | /* |
| 19054 | ** Include the primary Windows SDK header file. |
| 19055 | */ |
| 19056 | #include "windows.h" |
| 19057 | |
| 19058 | #ifdef __CYGWIN__ |
| 19059 | # include <sys/cygwin.h> |
| 19060 | # include <errno.h> /* amalgamator: dontcache */ |
| 19061 | #endif |
| 19062 | |
| 19063 | /* |
| 19064 | ** Determine if we are dealing with Windows NT. |
| 19065 | ** |
| 19066 | ** We ought to be able to determine if we are compiling for Windows 9x or |
| 19067 | ** Windows NT using the _WIN32_WINNT macro as follows: |
| 19068 | ** |
| 19069 | ** #if defined(_WIN32_WINNT) |
| 19070 | ** # define SQLITE_OS_WINNT 1 |
| 19071 | ** #else |
| 19072 | ** # define SQLITE_OS_WINNT 0 |
| 19073 | ** #endif |
| 19074 | ** |
| 19075 | ** However, Visual Studio 2005 does not set _WIN32_WINNT by default, as |
| 19076 | ** it ought to, so the above test does not work. We'll just assume that |
| 19077 | ** everything is Windows NT unless the programmer explicitly says otherwise |
| 19078 | ** by setting SQLITE_OS_WINNT to 0. |
| 19079 | */ |
| 19080 | #if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT) |
| 19081 | # define SQLITE_OS_WINNT 1 |
| 19082 | #endif |
| 19083 | |
| 19084 | /* |
| 19085 | ** Determine if we are dealing with Windows CE - which has a much reduced |
| 19086 | ** API. |
| 19087 | */ |
| 19088 | #if defined(_WIN32_WCE) |
| 19089 | # define SQLITE_OS_WINCE 1 |
| 19090 | #else |
| 19091 | # define SQLITE_OS_WINCE 0 |
| 19092 | #endif |
| 19093 | |
| 19094 | /* |
| 19095 | ** Determine if we are dealing with WinRT, which provides only a subset of |
| 19096 | ** the full Win32 API. |
| 19097 | */ |
| 19098 | #if !defined(SQLITE_OS_WINRT) |
| 19099 | # define SQLITE_OS_WINRT 0 |
| 19100 | #endif |
| 19101 | |
| 19102 | #endif /* _OS_WIN_H_ */ |
| 19103 | |
| 19104 | /************** End of os_win.h **********************************************/ |
| 19105 | /************** Continuing where we left off in mutex_w32.c ******************/ |
| 19106 | #endif |
| 19107 | |
| 19108 | /* |
| 19109 | ** The code in this file is only used if we are compiling multithreaded |
| 19110 | ** on a win32 system. |
| 19111 | */ |
| 19112 | #ifdef SQLITE_MUTEX_W32 |
| @@ -21789,10 +21958,28 @@ | |
| 21958 | static unsigned dummy = 0; |
| 21959 | dummy += (unsigned)x; |
| 21960 | } |
| 21961 | #endif |
| 21962 | |
| 21963 | /* |
| 21964 | ** Give a callback to the test harness that can be used to simulate faults |
| 21965 | ** in places where it is difficult or expensive to do so purely by means |
| 21966 | ** of inputs. |
| 21967 | ** |
| 21968 | ** The intent of the integer argument is to let the fault simulator know |
| 21969 | ** which of multiple sqlite3FaultSim() calls has been hit. |
| 21970 | ** |
| 21971 | ** Return whatever integer value the test callback returns, or return |
| 21972 | ** SQLITE_OK if no test callback is installed. |
| 21973 | */ |
| 21974 | #ifndef SQLITE_OMIT_BUILTIN_TEST |
| 21975 | SQLITE_PRIVATE int sqlite3FaultSim(int iTest){ |
| 21976 | int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback; |
| 21977 | return xCallback ? xCallback(iTest) : SQLITE_OK; |
| 21978 | } |
| 21979 | #endif |
| 21980 | |
| 21981 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 21982 | /* |
| 21983 | ** Return true if the floating point value is Not a Number (NaN). |
| 21984 | ** |
| 21985 | ** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. |
| @@ -23004,12 +23191,12 @@ | |
| 23191 | return b+x[b-a]; |
| 23192 | } |
| 23193 | } |
| 23194 | |
| 23195 | /* |
| 23196 | ** Convert an integer into a LogEst. In other words, compute an |
| 23197 | ** approximation for 10*log2(x). |
| 23198 | */ |
| 23199 | SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){ |
| 23200 | static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 }; |
| 23201 | LogEst y = 40; |
| 23202 | if( x<8 ){ |
| @@ -31226,15 +31413,10 @@ | |
| 31413 | ** |
| 31414 | ** This file contains code that is specific to Windows. |
| 31415 | */ |
| 31416 | #if SQLITE_OS_WIN /* This file is used for Windows only */ |
| 31417 | |
| 31418 | /* |
| 31419 | ** Include code that is common to all os_*.c files |
| 31420 | */ |
| 31421 | /************** Include os_common.h in the middle of os_win.c ****************/ |
| 31422 | /************** Begin file os_common.h ***************************************/ |
| @@ -31443,10 +31625,14 @@ | |
| 31625 | |
| 31626 | #endif /* !defined(_OS_COMMON_H_) */ |
| 31627 | |
| 31628 | /************** End of os_common.h *******************************************/ |
| 31629 | /************** Continuing where we left off in os_win.c *********************/ |
| 31630 | |
| 31631 | /* |
| 31632 | ** Include the header file for the Windows VFS. |
| 31633 | */ |
| 31634 | |
| 31635 | /* |
| 31636 | ** Compiling and using WAL mode requires several APIs that are only |
| 31637 | ** available in Windows platforms based on the NT kernel. |
| 31638 | */ |
| @@ -33255,10 +33441,36 @@ | |
| 33441 | # define SQLITE_WIN32_IOERR_RETRY_DELAY 25 |
| 33442 | #endif |
| 33443 | static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY; |
| 33444 | static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; |
| 33445 | |
| 33446 | /* |
| 33447 | ** The "winIoerrCanRetry1" macro is used to determine if a particular I/O |
| 33448 | ** error code obtained via GetLastError() is eligible to be retried. It |
| 33449 | ** must accept the error code DWORD as its only argument and should return |
| 33450 | ** non-zero if the error code is transient in nature and the operation |
| 33451 | ** responsible for generating the original error might succeed upon being |
| 33452 | ** retried. The argument to this macro should be a variable. |
| 33453 | ** |
| 33454 | ** Additionally, a macro named "winIoerrCanRetry2" may be defined. If it |
| 33455 | ** is defined, it will be consulted only when the macro "winIoerrCanRetry1" |
| 33456 | ** returns zero. The "winIoerrCanRetry2" macro is completely optional and |
| 33457 | ** may be used to include additional error codes in the set that should |
| 33458 | ** result in the failing I/O operation being retried by the caller. If |
| 33459 | ** defined, the "winIoerrCanRetry2" macro must exhibit external semantics |
| 33460 | ** identical to those of the "winIoerrCanRetry1" macro. |
| 33461 | */ |
| 33462 | #if !defined(winIoerrCanRetry1) |
| 33463 | #define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED) || \ |
| 33464 | ((a)==ERROR_SHARING_VIOLATION) || \ |
| 33465 | ((a)==ERROR_LOCK_VIOLATION) || \ |
| 33466 | ((a)==ERROR_DEV_NOT_EXIST) || \ |
| 33467 | ((a)==ERROR_NETNAME_DELETED) || \ |
| 33468 | ((a)==ERROR_SEM_TIMEOUT) || \ |
| 33469 | ((a)==ERROR_NETWORK_UNREACHABLE)) |
| 33470 | #endif |
| 33471 | |
| 33472 | /* |
| 33473 | ** If a ReadFile() or WriteFile() error occurs, invoke this routine |
| 33474 | ** to see if it should be retried. Return TRUE to retry. Return FALSE |
| 33475 | ** to give up with an error. |
| 33476 | */ |
| @@ -33268,17 +33480,22 @@ | |
| 33480 | if( pError ){ |
| 33481 | *pError = e; |
| 33482 | } |
| 33483 | return 0; |
| 33484 | } |
| 33485 | if( winIoerrCanRetry1(e) ){ |
| 33486 | sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); |
| 33487 | ++*pnRetry; |
| 33488 | return 1; |
| 33489 | } |
| 33490 | #if defined(winIoerrCanRetry2) |
| 33491 | else if( winIoerrCanRetry2(e) ){ |
| 33492 | sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); |
| 33493 | ++*pnRetry; |
| 33494 | return 1; |
| 33495 | } |
| 33496 | #endif |
| 33497 | if( pError ){ |
| 33498 | *pError = e; |
| 33499 | } |
| 33500 | return 0; |
| 33501 | } |
| @@ -40231,11 +40448,12 @@ | |
| 40448 | u8 noSync; /* Do not sync the journal if true */ |
| 40449 | u8 fullSync; /* Do extra syncs of the journal for robustness */ |
| 40450 | u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ |
| 40451 | u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ |
| 40452 | u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ |
| 40453 | u8 tempFile; /* zFilename is a temporary or immutable file */ |
| 40454 | u8 noLock; /* Do not lock (except in WAL mode) */ |
| 40455 | u8 readOnly; /* True for a read-only database */ |
| 40456 | u8 memDb; /* True to inhibit all file I/O */ |
| 40457 | |
| 40458 | /************************************************************************** |
| 40459 | ** The following block contains those class members that change during |
| @@ -40696,11 +40914,11 @@ | |
| 40914 | assert( !pPager->exclusiveMode || pPager->eLock==eLock ); |
| 40915 | assert( eLock==NO_LOCK || eLock==SHARED_LOCK ); |
| 40916 | assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 ); |
| 40917 | if( isOpen(pPager->fd) ){ |
| 40918 | assert( pPager->eLock>=eLock ); |
| 40919 | rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock); |
| 40920 | if( pPager->eLock!=UNKNOWN_LOCK ){ |
| 40921 | pPager->eLock = (u8)eLock; |
| 40922 | } |
| 40923 | IOTRACE(("UNLOCK %p %d\n", pPager, eLock)) |
| 40924 | } |
| @@ -40720,11 +40938,11 @@ | |
| 40938 | static int pagerLockDb(Pager *pPager, int eLock){ |
| 40939 | int rc = SQLITE_OK; |
| 40940 | |
| 40941 | assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK ); |
| 40942 | if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){ |
| 40943 | rc = pPager->noLock ? SQLITE_OK : sqlite3OsLock(pPager->fd, eLock); |
| 40944 | if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){ |
| 40945 | pPager->eLock = (u8)eLock; |
| 40946 | IOTRACE(("LOCK %p %d\n", pPager, eLock)) |
| 40947 | } |
| 40948 | } |
| @@ -44279,47 +44497,59 @@ | |
| 44497 | ** |
| 44498 | ** + SQLITE_DEFAULT_PAGE_SIZE, |
| 44499 | ** + The value returned by sqlite3OsSectorSize() |
| 44500 | ** + The largest page size that can be written atomically. |
| 44501 | */ |
| 44502 | if( rc==SQLITE_OK ){ |
| 44503 | int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); |
| 44504 | if( !readOnly ){ |
| 44505 | setSectorSize(pPager); |
| 44506 | assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE); |
| 44507 | if( szPageDflt<pPager->sectorSize ){ |
| 44508 | if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ |
| 44509 | szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; |
| 44510 | }else{ |
| 44511 | szPageDflt = (u32)pPager->sectorSize; |
| 44512 | } |
| 44513 | } |
| 44514 | #ifdef SQLITE_ENABLE_ATOMIC_WRITE |
| 44515 | { |
| 44516 | int ii; |
| 44517 | assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); |
| 44518 | assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); |
| 44519 | assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); |
| 44520 | for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ |
| 44521 | if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){ |
| 44522 | szPageDflt = ii; |
| 44523 | } |
| 44524 | } |
| 44525 | } |
| 44526 | #endif |
| 44527 | } |
| 44528 | pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0); |
| 44529 | if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 |
| 44530 | || sqlite3_uri_boolean(zFilename, "immutable", 0) ){ |
| 44531 | vfsFlags |= SQLITE_OPEN_READONLY; |
| 44532 | goto act_like_temp_file; |
| 44533 | } |
| 44534 | } |
| 44535 | }else{ |
| 44536 | /* If a temporary file is requested, it is not opened immediately. |
| 44537 | ** In this case we accept the default page size and delay actually |
| 44538 | ** opening the file until the first call to OsWrite(). |
| 44539 | ** |
| 44540 | ** This branch is also run for an in-memory database. An in-memory |
| 44541 | ** database is the same as a temp-file that is never written out to |
| 44542 | ** disk and uses an in-memory rollback journal. |
| 44543 | ** |
| 44544 | ** This branch also runs for files marked as immutable. |
| 44545 | */ |
| 44546 | act_like_temp_file: |
| 44547 | tempFile = 1; |
| 44548 | pPager->eState = PAGER_READER; /* Pretend we already have a lock */ |
| 44549 | pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE locking mode */ |
| 44550 | pPager->noLock = 1; /* Do no locking */ |
| 44551 | readOnly = (vfsFlags&SQLITE_OPEN_READONLY); |
| 44552 | } |
| 44553 | |
| 44554 | /* The following call to PagerSetPagesize() serves to set the value of |
| 44555 | ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. |
| @@ -44356,13 +44586,10 @@ | |
| 44586 | /* pPager->stmtSize = 0; */ |
| 44587 | /* pPager->stmtJSize = 0; */ |
| 44588 | /* pPager->nPage = 0; */ |
| 44589 | pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; |
| 44590 | /* pPager->state = PAGER_UNLOCK; */ |
| 44591 | /* pPager->errMask = 0; */ |
| 44592 | pPager->tempFile = (u8)tempFile; |
| 44593 | assert( tempFile==PAGER_LOCKINGMODE_NORMAL |
| 44594 | || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); |
| 44595 | assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); |
| @@ -59414,10 +59641,17 @@ | |
| 59641 | */ |
| 59642 | SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){ |
| 59643 | assert( mask==BTREE_BULKLOAD || mask==0 ); |
| 59644 | pCsr->hints = mask; |
| 59645 | } |
| 59646 | |
| 59647 | /* |
| 59648 | ** Return true if the given Btree is read-only. |
| 59649 | */ |
| 59650 | SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){ |
| 59651 | return (p->pBt->btsFlags & BTS_READ_ONLY)!=0; |
| 59652 | } |
| 59653 | |
| 59654 | /************** End of btree.c ***********************************************/ |
| 59655 | /************** Begin file backup.c ******************************************/ |
| 59656 | /* |
| 59657 | ** 2009 January 28 |
| @@ -70686,11 +70920,11 @@ | |
| 70920 | ** |
| 70921 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 70922 | ** is greater than or equal to the key value. If there are no records |
| 70923 | ** greater than or equal to the key and P2 is not zero, then jump to P2. |
| 70924 | ** |
| 70925 | ** See also: Found, NotFound, SeekLt, SeekGt, SeekLe |
| 70926 | */ |
| 70927 | /* Opcode: SeekGt P1 P2 P3 P4 * |
| 70928 | ** Synopsis: key=r[P3@P4] |
| 70929 | ** |
| 70930 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| @@ -70700,11 +70934,11 @@ | |
| 70934 | ** |
| 70935 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 70936 | ** is greater than the key value. If there are no records greater than |
| 70937 | ** the key and P2 is not zero, then jump to P2. |
| 70938 | ** |
| 70939 | ** See also: Found, NotFound, SeekLt, SeekGe, SeekLe |
| 70940 | */ |
| 70941 | /* Opcode: SeekLt P1 P2 P3 P4 * |
| 70942 | ** Synopsis: key=r[P3@P4] |
| 70943 | ** |
| 70944 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| @@ -70714,11 +70948,11 @@ | |
| 70948 | ** |
| 70949 | ** Reposition cursor P1 so that it points to the largest entry that |
| 70950 | ** is less than the key value. If there are no records less than |
| 70951 | ** the key and P2 is not zero, then jump to P2. |
| 70952 | ** |
| 70953 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLe |
| 70954 | */ |
| 70955 | /* Opcode: SeekLe P1 P2 P3 P4 * |
| 70956 | ** Synopsis: key=r[P3@P4] |
| 70957 | ** |
| 70958 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
| @@ -70728,11 +70962,11 @@ | |
| 70962 | ** |
| 70963 | ** Reposition cursor P1 so that it points to the largest entry that |
| 70964 | ** is less than or equal to the key value. If there are no records |
| 70965 | ** less than or equal to the key and P2 is not zero, then jump to P2. |
| 70966 | ** |
| 70967 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt |
| 70968 | */ |
| 70969 | case OP_SeekLT: /* jump, in3 */ |
| 70970 | case OP_SeekLE: /* jump, in3 */ |
| 70971 | case OP_SeekGE: /* jump, in3 */ |
| 70972 | case OP_SeekGT: { /* jump, in3 */ |
| @@ -71454,10 +71688,11 @@ | |
| 71688 | |
| 71689 | pOut = &aMem[pOp->p2]; |
| 71690 | pC = p->apCsr[pOp->p1]; |
| 71691 | assert( isSorter(pC) ); |
| 71692 | rc = sqlite3VdbeSorterRowkey(pC, pOut); |
| 71693 | assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) ); |
| 71694 | break; |
| 71695 | } |
| 71696 | |
| 71697 | /* Opcode: RowData P1 P2 * * * |
| 71698 | ** Synopsis: r[P2]=data |
| @@ -73545,12 +73780,12 @@ | |
| 73780 | *****************************************************************************/ |
| 73781 | } |
| 73782 | |
| 73783 | #ifdef VDBE_PROFILE |
| 73784 | { |
| 73785 | u64 endTime = sqlite3Hwtime(); |
| 73786 | if( endTime>start ) pOp->cycles += endTime - start; |
| 73787 | pOp->cnt++; |
| 73788 | } |
| 73789 | #endif |
| 73790 | |
| 73791 | /* The following code adds nothing to the actual functionality |
| @@ -83789,10 +84024,11 @@ | |
| 84024 | */ |
| 84025 | static void decodeIntArray( |
| 84026 | char *zIntArray, /* String containing int array to decode */ |
| 84027 | int nOut, /* Number of slots in aOut[] */ |
| 84028 | tRowcnt *aOut, /* Store integers here */ |
| 84029 | LogEst *aLog, /* Or, if aOut==0, here */ |
| 84030 | Index *pIndex /* Handle extra flags for this index, if not NULL */ |
| 84031 | ){ |
| 84032 | char *z = zIntArray; |
| 84033 | int c; |
| 84034 | int i; |
| @@ -83807,11 +84043,21 @@ | |
| 84043 | v = 0; |
| 84044 | while( (c=z[0])>='0' && c<='9' ){ |
| 84045 | v = v*10 + c - '0'; |
| 84046 | z++; |
| 84047 | } |
| 84048 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 84049 | if( aOut ){ |
| 84050 | aOut[i] = v; |
| 84051 | }else |
| 84052 | #else |
| 84053 | assert( aOut==0 ); |
| 84054 | UNUSED_PARAMETER(aOut); |
| 84055 | #endif |
| 84056 | { |
| 84057 | aLog[i] = sqlite3LogEst(v); |
| 84058 | } |
| 84059 | if( *z==' ' ) z++; |
| 84060 | } |
| 84061 | #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 84062 | assert( pIndex!=0 ); |
| 84063 | #else |
| @@ -83863,16 +84109,16 @@ | |
| 84109 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 84110 | } |
| 84111 | z = argv[2]; |
| 84112 | |
| 84113 | if( pIndex ){ |
| 84114 | decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex); |
| 84115 | if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; |
| 84116 | }else{ |
| 84117 | Index fakeIdx; |
| 84118 | fakeIdx.szIdxRow = pTable->szTabRow; |
| 84119 | decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); |
| 84120 | pTable->szTabRow = fakeIdx.szIdxRow; |
| 84121 | } |
| 84122 | |
| 84123 | return 0; |
| 84124 | } |
| @@ -84060,13 +84306,13 @@ | |
| 84306 | if( pIdx!=pPrevIdx ){ |
| 84307 | initAvgEq(pPrevIdx); |
| 84308 | pPrevIdx = pIdx; |
| 84309 | } |
| 84310 | pSample = &pIdx->aSample[pIdx->nSample]; |
| 84311 | decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0); |
| 84312 | decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); |
| 84313 | decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); |
| 84314 | |
| 84315 | /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. |
| 84316 | ** This is in case the sample record is corrupted. In that case, the |
| 84317 | ** sqlite3VdbeRecordCompare() may read up to two varints past the |
| 84318 | ** end of the allocated buffer before it realizes it is dealing with |
| @@ -85924,11 +86170,11 @@ | |
| 86170 | } |
| 86171 | pTable->zName = zName; |
| 86172 | pTable->iPKey = -1; |
| 86173 | pTable->pSchema = db->aDb[iDb].pSchema; |
| 86174 | pTable->nRef = 1; |
| 86175 | pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); |
| 86176 | assert( pParse->pNewTable==0 ); |
| 86177 | pParse->pNewTable = pTable; |
| 86178 | |
| 86179 | /* If this is the magic sqlite_sequence table used by autoincrement, |
| 86180 | ** then record a pointer to this table in the main database structure |
| @@ -86325,11 +86571,14 @@ | |
| 86571 | Parse *pParse, /* Parsing context */ |
| 86572 | Expr *pCheckExpr /* The check expression */ |
| 86573 | ){ |
| 86574 | #ifndef SQLITE_OMIT_CHECK |
| 86575 | Table *pTab = pParse->pNewTable; |
| 86576 | sqlite3 *db = pParse->db; |
| 86577 | if( pTab && !IN_DECLARE_VTAB |
| 86578 | && !sqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt) |
| 86579 | ){ |
| 86580 | pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); |
| 86581 | if( pParse->constraintName.n ){ |
| 86582 | sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1); |
| 86583 | } |
| 86584 | }else |
| @@ -87749,19 +87998,19 @@ | |
| 87998 | Index *p; /* Allocated index object */ |
| 87999 | int nByte; /* Bytes of space for Index object + arrays */ |
| 88000 | |
| 88001 | nByte = ROUND8(sizeof(Index)) + /* Index structure */ |
| 88002 | ROUND8(sizeof(char*)*nCol) + /* Index.azColl */ |
| 88003 | ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */ |
| 88004 | sizeof(i16)*nCol + /* Index.aiColumn */ |
| 88005 | sizeof(u8)*nCol); /* Index.aSortOrder */ |
| 88006 | p = sqlite3DbMallocZero(db, nByte + nExtra); |
| 88007 | if( p ){ |
| 88008 | char *pExtra = ((char*)p)+ROUND8(sizeof(Index)); |
| 88009 | p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol); |
| 88010 | p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1); |
| 88011 | p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol; |
| 88012 | p->aSortOrder = (u8*)pExtra; |
| 88013 | p->nColumn = nCol; |
| 88014 | p->nKeyCol = nCol - 1; |
| 88015 | *ppExtra = ((char*)p) + nByte; |
| 88016 | } |
| @@ -87987,11 +88236,11 @@ | |
| 88236 | pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol, |
| 88237 | nName + nExtra + 1, &zExtra); |
| 88238 | if( db->mallocFailed ){ |
| 88239 | goto exit_create_index; |
| 88240 | } |
| 88241 | assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowLogEst) ); |
| 88242 | assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) ); |
| 88243 | pIndex->zName = zExtra; |
| 88244 | zExtra += nName + 1; |
| 88245 | memcpy(pIndex->zName, zName, nName+1); |
| 88246 | pIndex->pTable = pTab; |
| @@ -88268,11 +88517,11 @@ | |
| 88517 | ** |
| 88518 | ** aiRowEst[0] is suppose to contain the number of elements in the index. |
| 88519 | ** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the |
| 88520 | ** number of rows in the table that match any particular value of the |
| 88521 | ** first column of the index. aiRowEst[2] is an estimate of the number |
| 88522 | ** of rows that match any particular combination of the first 2 columns |
| 88523 | ** of the index. And so forth. It must always be the case that |
| 88524 | * |
| 88525 | ** aiRowEst[N]<=aiRowEst[N-1] |
| 88526 | ** aiRowEst[N]>=1 |
| 88527 | ** |
| @@ -88279,24 +88528,31 @@ | |
| 88528 | ** Apart from that, we have little to go on besides intuition as to |
| 88529 | ** how aiRowEst[] should be initialized. The numbers generated here |
| 88530 | ** are based on typical values found in actual indices. |
| 88531 | */ |
| 88532 | SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){ |
| 88533 | /* 10, 9, 8, 7, 6 */ |
| 88534 | LogEst aVal[] = { 33, 32, 30, 28, 26 }; |
| 88535 | LogEst *a = pIdx->aiRowLogEst; |
| 88536 | int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol); |
| 88537 | int i; |
| 88538 | |
| 88539 | /* Set the first entry (number of rows in the index) to the estimated |
| 88540 | ** number of rows in the table. Or 10, if the estimated number of rows |
| 88541 | ** in the table is less than that. */ |
| 88542 | a[0] = pIdx->pTable->nRowLogEst; |
| 88543 | if( a[0]<33 ) a[0] = 33; assert( 33==sqlite3LogEst(10) ); |
| 88544 | |
| 88545 | /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is |
| 88546 | ** 6 and each subsequent value (if any) is 5. */ |
| 88547 | memcpy(&a[1], aVal, nCopy*sizeof(LogEst)); |
| 88548 | for(i=nCopy+1; i<=pIdx->nKeyCol; i++){ |
| 88549 | a[i] = 23; assert( 23==sqlite3LogEst(5) ); |
| 88550 | } |
| 88551 | |
| 88552 | assert( 0==sqlite3LogEst(1) ); |
| 88553 | if( pIdx->onError!=OE_None ) a[pIdx->nKeyCol] = 0; |
| 88554 | } |
| 88555 | |
| 88556 | /* |
| 88557 | ** This routine will drop an existing named index. This routine |
| 88558 | ** implements the DROP INDEX statement. |
| @@ -92116,11 +92372,11 @@ | |
| 92372 | } |
| 92373 | if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); |
| 92374 | } |
| 92375 | zVal = (char*)sqlite3_value_text(argv[0]); |
| 92376 | nVal = sqlite3_value_bytes(argv[0]); |
| 92377 | if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal); |
| 92378 | } |
| 92379 | } |
| 92380 | static void groupConcatFinalize(sqlite3_context *context){ |
| 92381 | StrAccum *pAccum; |
| 92382 | pAccum = sqlite3_aggregate_context(context, 0); |
| @@ -94306,10 +94562,11 @@ | |
| 94562 | } |
| 94563 | } |
| 94564 | if( j>=pTab->nCol ){ |
| 94565 | if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){ |
| 94566 | ipkColumn = i; |
| 94567 | bIdListInOrder = 0; |
| 94568 | }else{ |
| 94569 | sqlite3ErrorMsg(pParse, "table %S has no column named %s", |
| 94570 | pTabList, 0, pColumn->a[i].zName); |
| 94571 | pParse->checkSchema = 1; |
| 94572 | goto insert_cleanup; |
| @@ -95557,18 +95814,27 @@ | |
| 95814 | } |
| 95815 | if( pDest->iPKey!=pSrc->iPKey ){ |
| 95816 | return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ |
| 95817 | } |
| 95818 | for(i=0; i<pDest->nCol; i++){ |
| 95819 | Column *pDestCol = &pDest->aCol[i]; |
| 95820 | Column *pSrcCol = &pSrc->aCol[i]; |
| 95821 | if( pDestCol->affinity!=pSrcCol->affinity ){ |
| 95822 | return 0; /* Affinity must be the same on all columns */ |
| 95823 | } |
| 95824 | if( !xferCompatibleCollation(pDestCol->zColl, pSrcCol->zColl) ){ |
| 95825 | return 0; /* Collating sequence must be the same on all columns */ |
| 95826 | } |
| 95827 | if( pDestCol->notNull && !pSrcCol->notNull ){ |
| 95828 | return 0; /* tab2 must be NOT NULL if tab1 is */ |
| 95829 | } |
| 95830 | /* Default values for second and subsequent columns need to match. */ |
| 95831 | if( i>0 |
| 95832 | && ((pDestCol->zDflt==0)!=(pSrcCol->zDflt==0) |
| 95833 | || (pDestCol->zDflt && strcmp(pDestCol->zDflt, pSrcCol->zDflt)!=0)) |
| 95834 | ){ |
| 95835 | return 0; /* Default values must be the same for all columns */ |
| 95836 | } |
| 95837 | } |
| 95838 | for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ |
| 95839 | if( pDestIdx->onError!=OE_None ){ |
| 95840 | destHasUniqueIdx = 1; |
| @@ -98583,17 +98849,19 @@ | |
| 98849 | Table *pTab = sqliteHashData(i); |
| 98850 | sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, pTab->zName, 0); |
| 98851 | sqlite3VdbeAddOp2(v, OP_Null, 0, 2); |
| 98852 | sqlite3VdbeAddOp2(v, OP_Integer, |
| 98853 | (int)sqlite3LogEstToInt(pTab->szTabRow), 3); |
| 98854 | sqlite3VdbeAddOp2(v, OP_Integer, |
| 98855 | (int)sqlite3LogEstToInt(pTab->nRowLogEst), 4); |
| 98856 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); |
| 98857 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 98858 | sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); |
| 98859 | sqlite3VdbeAddOp2(v, OP_Integer, |
| 98860 | (int)sqlite3LogEstToInt(pIdx->szIdxRow), 3); |
| 98861 | sqlite3VdbeAddOp2(v, OP_Integer, |
| 98862 | (int)sqlite3LogEstToInt(pIdx->aiRowLogEst[0]), 4); |
| 98863 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); |
| 98864 | } |
| 98865 | } |
| 98866 | } |
| 98867 | break; |
| @@ -100760,19 +101028,21 @@ | |
| 101028 | Select *pSelect, /* The whole SELECT statement */ |
| 101029 | int regData /* Register holding data to be sorted */ |
| 101030 | ){ |
| 101031 | Vdbe *v = pParse->pVdbe; |
| 101032 | int nExpr = pSort->pOrderBy->nExpr; |
| 101033 | int regRecord = ++pParse->nMem; |
| 101034 | int regBase = pParse->nMem+1; |
| 101035 | int nOBSat = pSort->nOBSat; |
| 101036 | int op; |
| 101037 | |
| 101038 | pParse->nMem += nExpr+2; /* nExpr+2 registers allocated at regBase */ |
| 101039 | sqlite3ExprCacheClear(pParse); |
| 101040 | sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, 0); |
| 101041 | sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); |
| 101042 | sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); |
| 101043 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nExpr+2-nOBSat,regRecord); |
| 101044 | if( nOBSat>0 ){ |
| 101045 | int regPrevKey; /* The first nOBSat columns of the previous row */ |
| 101046 | int addrFirst; /* Address of the OP_IfNot opcode */ |
| 101047 | int addrJmp; /* Address of the OP_Jump opcode */ |
| 101048 | VdbeOp *pOp; /* Opcode that opens the sorter */ |
| @@ -100805,14 +101075,10 @@ | |
| 101075 | op = OP_SorterInsert; |
| 101076 | }else{ |
| 101077 | op = OP_IdxInsert; |
| 101078 | } |
| 101079 | sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord); |
| 101080 | if( pSelect->iLimit ){ |
| 101081 | int addr1, addr2; |
| 101082 | int iLimit; |
| 101083 | if( pSelect->iOffset ){ |
| 101084 | iLimit = pSelect->iOffset+1; |
| @@ -101984,11 +102250,11 @@ | |
| 102250 | /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside |
| 102251 | ** is disabled */ |
| 102252 | assert( db->lookaside.bEnabled==0 ); |
| 102253 | pTab->nRef = 1; |
| 102254 | pTab->zName = 0; |
| 102255 | pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); |
| 102256 | selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); |
| 102257 | selectAddColumnTypeAndCollation(pParse, pTab, pSelect); |
| 102258 | pTab->iPKey = -1; |
| 102259 | if( db->mallocFailed ){ |
| 102260 | sqlite3DeleteTable(db, pTab); |
| @@ -104123,11 +104389,11 @@ | |
| 104389 | pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); |
| 104390 | if( pTab==0 ) return WRC_Abort; |
| 104391 | pTab->nRef = 1; |
| 104392 | pTab->zName = sqlite3DbStrDup(db, pCte->zName); |
| 104393 | pTab->iPKey = -1; |
| 104394 | pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); |
| 104395 | pTab->tabFlags |= TF_Ephemeral; |
| 104396 | pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); |
| 104397 | if( db->mallocFailed ) return SQLITE_NOMEM; |
| 104398 | assert( pFrom->pSelect ); |
| 104399 | |
| @@ -104299,11 +104565,11 @@ | |
| 104565 | pTab->nRef = 1; |
| 104566 | pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); |
| 104567 | while( pSel->pPrior ){ pSel = pSel->pPrior; } |
| 104568 | selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); |
| 104569 | pTab->iPKey = -1; |
| 104570 | pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); |
| 104571 | pTab->tabFlags |= TF_Ephemeral; |
| 104572 | #endif |
| 104573 | }else{ |
| 104574 | /* An ordinary table or view name in the FROM clause */ |
| 104575 | assert( pFrom->pTab==0 ); |
| @@ -104794,14 +105060,15 @@ | |
| 105060 | Parse *pParse, /* Parse context */ |
| 105061 | Table *pTab, /* Table being queried */ |
| 105062 | Index *pIdx /* Index used to optimize scan, or NULL */ |
| 105063 | ){ |
| 105064 | if( pParse->explain==2 ){ |
| 105065 | int bCover = (pIdx!=0 && (HasRowid(pTab) || pIdx->autoIndex!=2)); |
| 105066 | char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s", |
| 105067 | pTab->zName, |
| 105068 | bCover ? " USING COVERING INDEX " : "", |
| 105069 | bCover ? pIdx->zName : "" |
| 105070 | ); |
| 105071 | sqlite3VdbeAddOp4( |
| 105072 | pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC |
| 105073 | ); |
| 105074 | } |
| @@ -104949,11 +105216,11 @@ | |
| 105216 | VdbeComment((v, "%s", pItem->pTab->zName)); |
| 105217 | pItem->addrFillSub = addrTop; |
| 105218 | sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); |
| 105219 | explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); |
| 105220 | sqlite3Select(pParse, pSub, &dest); |
| 105221 | pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow); |
| 105222 | pItem->viaCoroutine = 1; |
| 105223 | pItem->regResult = dest.iSdst; |
| 105224 | sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn); |
| 105225 | sqlite3VdbeJumpHere(v, addrTop-1); |
| 105226 | sqlite3ClearTempRegCache(pParse); |
| @@ -104980,11 +105247,11 @@ | |
| 105247 | VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName)); |
| 105248 | } |
| 105249 | sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); |
| 105250 | explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); |
| 105251 | sqlite3Select(pParse, pSub, &dest); |
| 105252 | pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow); |
| 105253 | if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); |
| 105254 | retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); |
| 105255 | VdbeComment((v, "end %s", pItem->pTab->zName)); |
| 105256 | sqlite3VdbeChangeP1(v, topAddr, retAddr); |
| 105257 | sqlite3ClearTempRegCache(pParse); |
| @@ -105013,22 +105280,10 @@ | |
| 105280 | explainSetInteger(pParse->iSelectId, iRestoreSelectId); |
| 105281 | return rc; |
| 105282 | } |
| 105283 | #endif |
| 105284 | |
| 105285 | /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and |
| 105286 | ** if the select-list is the same as the ORDER BY list, then this query |
| 105287 | ** can be rewritten as a GROUP BY. In other words, this: |
| 105288 | ** |
| 105289 | ** SELECT DISTINCT xyz FROM ... ORDER BY xyz |
| @@ -105153,10 +105408,11 @@ | |
| 105408 | int iAbortFlag; /* Mem address which causes query abort if positive */ |
| 105409 | int groupBySort; /* Rows come from source in GROUP BY order */ |
| 105410 | int addrEnd; /* End of processing for this SELECT */ |
| 105411 | int sortPTab = 0; /* Pseudotable used to decode sorting results */ |
| 105412 | int sortOut = 0; /* Output register from the sorter */ |
| 105413 | int orderByGrp = 0; /* True if the GROUP BY and ORDER BY are the same */ |
| 105414 | |
| 105415 | /* Remove any and all aliases between the result set and the |
| 105416 | ** GROUP BY clause. |
| 105417 | */ |
| 105418 | if( pGroupBy ){ |
| @@ -105172,10 +105428,22 @@ | |
| 105428 | if( p->nSelectRow>100 ) p->nSelectRow = 100; |
| 105429 | }else{ |
| 105430 | p->nSelectRow = 1; |
| 105431 | } |
| 105432 | |
| 105433 | |
| 105434 | /* If there is both a GROUP BY and an ORDER BY clause and they are |
| 105435 | ** identical, then it may be possible to disable the ORDER BY clause |
| 105436 | ** on the grounds that the GROUP BY will cause elements to come out |
| 105437 | ** in the correct order. It also may not - the GROUP BY may use a |
| 105438 | ** database index that causes rows to be grouped together as required |
| 105439 | ** but not actually sorted. Either way, record the fact that the |
| 105440 | ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp |
| 105441 | ** variable. */ |
| 105442 | if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){ |
| 105443 | orderByGrp = 1; |
| 105444 | } |
| 105445 | |
| 105446 | /* Create a label to jump to when we want to abort the query */ |
| 105447 | addrEnd = sqlite3VdbeMakeLabel(v); |
| 105448 | |
| 105449 | /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in |
| @@ -105252,11 +105520,12 @@ | |
| 105520 | ** it might be a single loop that uses an index to extract information |
| 105521 | ** in the right order to begin with. |
| 105522 | */ |
| 105523 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); |
| 105524 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, |
| 105525 | WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 |
| 105526 | ); |
| 105527 | if( pWInfo==0 ) goto select_end; |
| 105528 | if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ |
| 105529 | /* The optimizer is able to deliver rows in group by order so |
| 105530 | ** we do not have to sort. The OP_OpenEphemeral table will be |
| 105531 | ** cancelled later because we still need to use the pKeyInfo |
| @@ -105317,10 +105586,25 @@ | |
| 105586 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); |
| 105587 | sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); |
| 105588 | VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); |
| 105589 | sAggInfo.useSortingIdx = 1; |
| 105590 | sqlite3ExprCacheClear(pParse); |
| 105591 | |
| 105592 | } |
| 105593 | |
| 105594 | /* If the index or temporary table used by the GROUP BY sort |
| 105595 | ** will naturally deliver rows in the order required by the ORDER BY |
| 105596 | ** clause, cancel the ephemeral table open coded earlier. |
| 105597 | ** |
| 105598 | ** This is an optimization - the correct answer should result regardless. |
| 105599 | ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER to |
| 105600 | ** disable this optimization for testing purposes. */ |
| 105601 | if( orderByGrp && OptimizationEnabled(db, SQLITE_GroupByOrder) |
| 105602 | && (groupBySort || sqlite3WhereIsSorted(pWInfo)) |
| 105603 | ){ |
| 105604 | sSort.pOrderBy = 0; |
| 105605 | sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); |
| 105606 | } |
| 105607 | |
| 105608 | /* Evaluate the current GROUP BY terms and store in b0, b1, b2... |
| 105609 | ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth) |
| 105610 | ** Then compare the current GROUP BY terms against the GROUP BY terms |
| @@ -109680,10 +109964,11 @@ | |
| 109964 | WhereLoop *pLoops; /* List of all WhereLoop objects */ |
| 109965 | Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ |
| 109966 | LogEst nRowOut; /* Estimated number of output rows */ |
| 109967 | u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ |
| 109968 | i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ |
| 109969 | u8 sorted; /* True if really sorted (not just grouped) */ |
| 109970 | u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */ |
| 109971 | u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ |
| 109972 | u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ |
| 109973 | u8 nLevel; /* Number of nested loop */ |
| 109974 | int iTop; /* The very beginning of the WHERE loop */ |
| @@ -109739,10 +110024,11 @@ | |
| 110024 | #define WHERE_ONEROW 0x00001000 /* Selects no more than one row */ |
| 110025 | #define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */ |
| 110026 | #define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */ |
| 110027 | #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ |
| 110028 | #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ |
| 110029 | #define WHERE_LIKELIHOOD 0x00020000 /* A likelihood() is affecting nOut */ |
| 110030 | |
| 110031 | /************** End of whereInt.h ********************************************/ |
| 110032 | /************** Continuing where we left off in where.c **********************/ |
| 110033 | |
| 110034 | /* |
| @@ -109951,11 +110237,11 @@ | |
| 110237 | } |
| 110238 | pTerm = &pWC->a[idx = pWC->nTerm++]; |
| 110239 | if( p && ExprHasProperty(p, EP_Unlikely) ){ |
| 110240 | pTerm->truthProb = sqlite3LogEst(p->iTable) - 99; |
| 110241 | }else{ |
| 110242 | pTerm->truthProb = 1; |
| 110243 | } |
| 110244 | pTerm->pExpr = sqlite3ExprSkipCollate(p); |
| 110245 | pTerm->wtFlags = wtFlags; |
| 110246 | pTerm->pWC = pWC; |
| 110247 | pTerm->iParent = -1; |
| @@ -111680,11 +111966,12 @@ | |
| 111966 | tRowcnt iLower, iUpper, iGap; |
| 111967 | if( i==0 ){ |
| 111968 | iLower = 0; |
| 111969 | iUpper = aSample[0].anLt[iCol]; |
| 111970 | }else{ |
| 111971 | i64 nRow0 = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]); |
| 111972 | iUpper = i>=pIdx->nSample ? nRow0 : aSample[i].anLt[iCol]; |
| 111973 | iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol]; |
| 111974 | } |
| 111975 | aStat[1] = (pIdx->nKeyCol>iCol ? pIdx->aAvgEq[iCol] : 1); |
| 111976 | if( iLower>=iUpper ){ |
| 111977 | iGap = 0; |
| @@ -111698,10 +111985,33 @@ | |
| 111985 | } |
| 111986 | aStat[0] = iLower + iGap; |
| 111987 | } |
| 111988 | } |
| 111989 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 111990 | |
| 111991 | /* |
| 111992 | ** If it is not NULL, pTerm is a term that provides an upper or lower |
| 111993 | ** bound on a range scan. Without considering pTerm, it is estimated |
| 111994 | ** that the scan will visit nNew rows. This function returns the number |
| 111995 | ** estimated to be visited after taking pTerm into account. |
| 111996 | ** |
| 111997 | ** If the user explicitly specified a likelihood() value for this term, |
| 111998 | ** then the return value is the likelihood multiplied by the number of |
| 111999 | ** input rows. Otherwise, this function assumes that an "IS NOT NULL" term |
| 112000 | ** has a likelihood of 0.50, and any other term a likelihood of 0.25. |
| 112001 | */ |
| 112002 | static LogEst whereRangeAdjust(WhereTerm *pTerm, LogEst nNew){ |
| 112003 | LogEst nRet = nNew; |
| 112004 | if( pTerm ){ |
| 112005 | if( pTerm->truthProb<=0 ){ |
| 112006 | nRet += pTerm->truthProb; |
| 112007 | }else if( (pTerm->wtFlags & TERM_VNULL)==0 ){ |
| 112008 | nRet -= 20; assert( 20==sqlite3LogEst(4) ); |
| 112009 | } |
| 112010 | } |
| 112011 | return nRet; |
| 112012 | } |
| 112013 | |
| 112014 | /* |
| 112015 | ** This function is used to estimate the number of rows that will be visited |
| 112016 | ** by scanning an index for a range of values. The range may have an upper |
| 112017 | ** bound, a lower bound, or both. The WHERE clause terms that set the upper |
| @@ -111791,11 +112101,11 @@ | |
| 112101 | aff = p->pTable->aCol[p->aiColumn[nEq]].affinity; |
| 112102 | } |
| 112103 | /* Determine iLower and iUpper using ($P) only. */ |
| 112104 | if( nEq==0 ){ |
| 112105 | iLower = 0; |
| 112106 | iUpper = sqlite3LogEstToInt(p->aiRowLogEst[0]); |
| 112107 | }else{ |
| 112108 | /* Note: this call could be optimized away - since the same values must |
| 112109 | ** have been requested when testing key $P in whereEqualScanEst(). */ |
| 112110 | whereKeyStats(pParse, p, pRec, 0, a); |
| 112111 | iLower = a[0]; |
| @@ -111851,21 +112161,22 @@ | |
| 112161 | #else |
| 112162 | UNUSED_PARAMETER(pParse); |
| 112163 | UNUSED_PARAMETER(pBuilder); |
| 112164 | #endif |
| 112165 | assert( pLower || pUpper ); |
| 112166 | assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 ); |
| 112167 | nNew = whereRangeAdjust(pLower, nOut); |
| 112168 | nNew = whereRangeAdjust(pUpper, nNew); |
| 112169 | |
| 112170 | /* TUNING: If there is both an upper and lower limit, assume the range is |
| 112171 | ** reduced by an additional 75%. This means that, by default, an open-ended |
| 112172 | ** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the |
| 112173 | ** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to |
| 112174 | ** match 1/64 of the index. */ |
| 112175 | if( pLower && pUpper ) nNew -= 20; |
| 112176 | |
| 112177 | nOut -= (pLower!=0) + (pUpper!=0); |
| 112178 | if( nNew<10 ) nNew = 10; |
| 112179 | if( nNew<nOut ) nOut = nNew; |
| 112180 | pLoop->nOut = (LogEst)nOut; |
| 112181 | return rc; |
| 112182 | } |
| @@ -111958,26 +112269,27 @@ | |
| 112269 | WhereLoopBuilder *pBuilder, |
| 112270 | ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ |
| 112271 | tRowcnt *pnRow /* Write the revised row estimate here */ |
| 112272 | ){ |
| 112273 | Index *p = pBuilder->pNew->u.btree.pIndex; |
| 112274 | i64 nRow0 = sqlite3LogEstToInt(p->aiRowLogEst[0]); |
| 112275 | int nRecValid = pBuilder->nRecValid; |
| 112276 | int rc = SQLITE_OK; /* Subfunction return code */ |
| 112277 | tRowcnt nEst; /* Number of rows for a single term */ |
| 112278 | tRowcnt nRowEst = 0; /* New estimate of the number of rows */ |
| 112279 | int i; /* Loop counter */ |
| 112280 | |
| 112281 | assert( p->aSample!=0 ); |
| 112282 | for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){ |
| 112283 | nEst = nRow0; |
| 112284 | rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst); |
| 112285 | nRowEst += nEst; |
| 112286 | pBuilder->nRecValid = nRecValid; |
| 112287 | } |
| 112288 | |
| 112289 | if( rc==SQLITE_OK ){ |
| 112290 | if( nRowEst > nRow0 ) nRowEst = nRow0; |
| 112291 | *pnRow = nRowEst; |
| 112292 | WHERETRACE(0x10,("IN row estimate: est=%g\n", nRowEst)); |
| 112293 | } |
| 112294 | assert( pBuilder->nRecValid==nRecValid ); |
| 112295 | return rc; |
| @@ -112416,17 +112728,24 @@ | |
| 112728 | zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias); |
| 112729 | } |
| 112730 | if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 |
| 112731 | && ALWAYS(pLoop->u.btree.pIndex!=0) |
| 112732 | ){ |
| 112733 | const char *zFmt; |
| 112734 | Index *pIdx = pLoop->u.btree.pIndex; |
| 112735 | char *zWhere = explainIndexRange(db, pLoop, pItem->pTab); |
| 112736 | assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); |
| 112737 | if( !HasRowid(pItem->pTab) && pIdx->autoIndex==2 ){ |
| 112738 | zFmt = zWhere ? "%s USING PRIMARY KEY%.0s%s" : "%s%.0s%s"; |
| 112739 | }else if( flags & WHERE_AUTO_INDEX ){ |
| 112740 | zFmt = "%s USING AUTOMATIC COVERING INDEX%.0s%s"; |
| 112741 | }else if( flags & WHERE_IDX_ONLY ){ |
| 112742 | zFmt = "%s USING COVERING INDEX %s%s"; |
| 112743 | }else{ |
| 112744 | zFmt = "%s USING INDEX %s%s"; |
| 112745 | } |
| 112746 | zMsg = sqlite3MAppendf(db, zMsg, zFmt, zMsg, pIdx->zName, zWhere); |
| 112747 | sqlite3DbFree(db, zWhere); |
| 112748 | }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ |
| 112749 | zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg); |
| 112750 | |
| 112751 | if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ |
| @@ -113459,11 +113778,11 @@ | |
| 113778 | if( pX->nLTerm >= pY->nLTerm ) return 0; /* X is not a subset of Y */ |
| 113779 | if( pX->rRun >= pY->rRun ){ |
| 113780 | if( pX->rRun > pY->rRun ) return 0; /* X costs more than Y */ |
| 113781 | if( pX->nOut > pY->nOut ) return 0; /* X costs more than Y */ |
| 113782 | } |
| 113783 | for(i=pX->nLTerm-1; i>=0; i--){ |
| 113784 | for(j=pY->nLTerm-1; j>=0; j--){ |
| 113785 | if( pY->aLTerm[j]==pX->aLTerm[i] ) break; |
| 113786 | } |
| 113787 | if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */ |
| 113788 | } |
| @@ -113481,16 +113800,29 @@ | |
| 113800 | ** is a proper subset. |
| 113801 | ** |
| 113802 | ** To say "WhereLoop X is a proper subset of Y" means that X uses fewer |
| 113803 | ** WHERE clause terms than Y and that every WHERE clause term used by X is |
| 113804 | ** also used by Y. |
| 113805 | ** |
| 113806 | ** This adjustment is omitted for SKIPSCAN loops. In a SKIPSCAN loop, the |
| 113807 | ** WhereLoop.nLTerm field is not an accurate measure of the number of WHERE |
| 113808 | ** clause terms covered, since some of the first nLTerm entries in aLTerm[] |
| 113809 | ** will be NULL (because they are skipped). That makes it more difficult |
| 113810 | ** to compare the loops. We could add extra code to do the comparison, and |
| 113811 | ** perhaps we will someday. But SKIPSCAN is sufficiently uncommon, and this |
| 113812 | ** adjustment is sufficient minor, that it is very difficult to construct |
| 113813 | ** a test case where the extra code would improve the query plan. Better |
| 113814 | ** to avoid the added complexity and just omit cost adjustments to SKIPSCAN |
| 113815 | ** loops. |
| 113816 | */ |
| 113817 | static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){ |
| 113818 | if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return; |
| 113819 | if( (pTemplate->wsFlags & WHERE_SKIPSCAN)!=0 ) return; |
| 113820 | for(; p; p=p->pNextLoop){ |
| 113821 | if( p->iTab!=pTemplate->iTab ) continue; |
| 113822 | if( (p->wsFlags & WHERE_INDEXED)==0 ) continue; |
| 113823 | if( (p->wsFlags & WHERE_SKIPSCAN)!=0 ) continue; |
| 113824 | if( whereLoopCheaperProperSubset(p, pTemplate) ){ |
| 113825 | /* Adjust pTemplate cost downward so that it is cheaper than its |
| 113826 | ** subset p */ |
| 113827 | pTemplate->rRun = p->rRun; |
| 113828 | pTemplate->nOut = p->nOut - 1; |
| @@ -113711,17 +114043,24 @@ | |
| 114043 | pX = pLoop->aLTerm[j]; |
| 114044 | if( pX==0 ) continue; |
| 114045 | if( pX==pTerm ) break; |
| 114046 | if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; |
| 114047 | } |
| 114048 | if( j<0 ){ |
| 114049 | pLoop->nOut += (pTerm->truthProb<=0 ? pTerm->truthProb : -1); |
| 114050 | } |
| 114051 | } |
| 114052 | } |
| 114053 | |
| 114054 | /* |
| 114055 | ** We have so far matched pBuilder->pNew->u.btree.nEq terms of the |
| 114056 | ** index pIndex. Try to match one more. |
| 114057 | ** |
| 114058 | ** When this function is called, pBuilder->pNew->nOut contains the |
| 114059 | ** number of rows expected to be visited by filtering using the nEq |
| 114060 | ** terms only. If it is modified, this value is restored before this |
| 114061 | ** function returns. |
| 114062 | ** |
| 114063 | ** If pProbe->tnum==0, that means pIndex is a fake index used for the |
| 114064 | ** INTEGER PRIMARY KEY. |
| 114065 | */ |
| 114066 | static int whereLoopAddBtreeIndex( |
| @@ -113743,11 +114082,10 @@ | |
| 114082 | u16 saved_nSkip; /* Original value of pNew->u.btree.nSkip */ |
| 114083 | u32 saved_wsFlags; /* Original value of pNew->wsFlags */ |
| 114084 | LogEst saved_nOut; /* Original value of pNew->nOut */ |
| 114085 | int iCol; /* Index of the column in the table */ |
| 114086 | int rc = SQLITE_OK; /* Return code */ |
| 114087 | LogEst rLogSize; /* Logarithm of table size */ |
| 114088 | WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ |
| 114089 | |
| 114090 | pNew = pBuilder->pNew; |
| 114091 | if( db->mallocFailed ) return SQLITE_NOMEM; |
| @@ -113764,15 +114102,12 @@ | |
| 114102 | if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); |
| 114103 | |
| 114104 | assert( pNew->u.btree.nEq<=pProbe->nKeyCol ); |
| 114105 | if( pNew->u.btree.nEq < pProbe->nKeyCol ){ |
| 114106 | iCol = pProbe->aiColumn[pNew->u.btree.nEq]; |
| 114107 | }else{ |
| 114108 | iCol = -1; |
| 114109 | } |
| 114110 | pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol, |
| 114111 | opMask, pProbe); |
| 114112 | saved_nEq = pNew->u.btree.nEq; |
| 114113 | saved_nSkip = pNew->u.btree.nSkip; |
| @@ -113779,57 +114114,68 @@ | |
| 114114 | saved_nLTerm = pNew->nLTerm; |
| 114115 | saved_wsFlags = pNew->wsFlags; |
| 114116 | saved_prereq = pNew->prereq; |
| 114117 | saved_nOut = pNew->nOut; |
| 114118 | pNew->rSetup = 0; |
| 114119 | rLogSize = estLog(pProbe->aiRowLogEst[0]); |
| 114120 | |
| 114121 | /* Consider using a skip-scan if there are no WHERE clause constraints |
| 114122 | ** available for the left-most terms of the index, and if the average |
| 114123 | ** number of repeats in the left-most terms is at least 18. |
| 114124 | ** |
| 114125 | ** The magic number 18 is selected on the basis that scanning 17 rows |
| 114126 | ** is almost always quicker than an index seek (even though if the index |
| 114127 | ** contains fewer than 2^17 rows we assume otherwise in other parts of |
| 114128 | ** the code). And, even if it is not, it should not be too much slower. |
| 114129 | ** On the other hand, the extra seeks could end up being significantly |
| 114130 | ** more expensive. */ |
| 114131 | assert( 42==sqlite3LogEst(18) ); |
| 114132 | if( pTerm==0 |
| 114133 | && saved_nEq==saved_nSkip |
| 114134 | && saved_nEq+1<pProbe->nKeyCol |
| 114135 | && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ |
| 114136 | && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK |
| 114137 | ){ |
| 114138 | LogEst nIter; |
| 114139 | pNew->u.btree.nEq++; |
| 114140 | pNew->u.btree.nSkip++; |
| 114141 | pNew->aLTerm[pNew->nLTerm++] = 0; |
| 114142 | pNew->wsFlags |= WHERE_SKIPSCAN; |
| 114143 | nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1]; |
| 114144 | pNew->nOut -= nIter; |
| 114145 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul); |
| 114146 | pNew->nOut = saved_nOut; |
| 114147 | } |
| 114148 | for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ |
| 114149 | u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */ |
| 114150 | LogEst rCostIdx; |
| 114151 | LogEst nOutUnadjusted; /* nOut before IN() and WHERE adjustments */ |
| 114152 | int nIn = 0; |
| 114153 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 114154 | int nRecValid = pBuilder->nRecValid; |
| 114155 | #endif |
| 114156 | if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) |
| 114157 | && (iCol<0 || pSrc->pTab->aCol[iCol].notNull) |
| 114158 | ){ |
| 114159 | continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */ |
| 114160 | } |
| 114161 | if( pTerm->prereqRight & pNew->maskSelf ) continue; |
| 114162 | |
| 114163 | pNew->wsFlags = saved_wsFlags; |
| 114164 | pNew->u.btree.nEq = saved_nEq; |
| 114165 | pNew->nLTerm = saved_nLTerm; |
| 114166 | if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ |
| 114167 | pNew->aLTerm[pNew->nLTerm++] = pTerm; |
| 114168 | pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf; |
| 114169 | |
| 114170 | assert( nInMul==0 |
| 114171 | || (pNew->wsFlags & WHERE_COLUMN_NULL)!=0 |
| 114172 | || (pNew->wsFlags & WHERE_COLUMN_IN)!=0 |
| 114173 | || (pNew->wsFlags & WHERE_SKIPSCAN)!=0 |
| 114174 | ); |
| 114175 | |
| 114176 | if( eOp & WO_IN ){ |
| 114177 | Expr *pExpr = pTerm->pExpr; |
| 114178 | pNew->wsFlags |= WHERE_COLUMN_IN; |
| 114179 | if( ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 114180 | /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ |
| 114181 | nIn = 46; assert( 46==sqlite3LogEst(25) ); |
| @@ -113837,87 +114183,122 @@ | |
| 114183 | /* "x IN (value, value, ...)" */ |
| 114184 | nIn = sqlite3LogEst(pExpr->x.pList->nExpr); |
| 114185 | } |
| 114186 | assert( nIn>0 ); /* RHS always has 2 or more terms... The parser |
| 114187 | ** changes "x IN (?)" into "x=?". */ |
| 114188 | |
| 114189 | }else if( eOp & (WO_EQ) ){ |
| 114190 | pNew->wsFlags |= WHERE_COLUMN_EQ; |
| 114191 | if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){ |
| 114192 | if( iCol>=0 && pProbe->onError==OE_None ){ |
| 114193 | pNew->wsFlags |= WHERE_UNQ_WANTED; |
| 114194 | }else{ |
| 114195 | pNew->wsFlags |= WHERE_ONEROW; |
| 114196 | } |
| 114197 | } |
| 114198 | }else if( eOp & WO_ISNULL ){ |
| 114199 | pNew->wsFlags |= WHERE_COLUMN_NULL; |
| 114200 | }else if( eOp & (WO_GT|WO_GE) ){ |
| 114201 | testcase( eOp & WO_GT ); |
| 114202 | testcase( eOp & WO_GE ); |
| 114203 | pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; |
| 114204 | pBtm = pTerm; |
| 114205 | pTop = 0; |
| 114206 | }else{ |
| 114207 | assert( eOp & (WO_LT|WO_LE) ); |
| 114208 | testcase( eOp & WO_LT ); |
| 114209 | testcase( eOp & WO_LE ); |
| 114210 | pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; |
| 114211 | pTop = pTerm; |
| 114212 | pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? |
| 114213 | pNew->aLTerm[pNew->nLTerm-2] : 0; |
| 114214 | } |
| 114215 | |
| 114216 | /* At this point pNew->nOut is set to the number of rows expected to |
| 114217 | ** be visited by the index scan before considering term pTerm, or the |
| 114218 | ** values of nIn and nInMul. In other words, assuming that all |
| 114219 | ** "x IN(...)" terms are replaced with "x = ?". This block updates |
| 114220 | ** the value of pNew->nOut to account for pTerm (but not nIn/nInMul). */ |
| 114221 | assert( pNew->nOut==saved_nOut ); |
| 114222 | if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ |
| 114223 | /* Adjust nOut using stat3/stat4 data. Or, if there is no stat3/stat4 |
| 114224 | ** data, using some other estimate. */ |
| 114225 | whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew); |
| 114226 | }else{ |
| 114227 | int nEq = ++pNew->u.btree.nEq; |
| 114228 | assert( eOp & (WO_ISNULL|WO_EQ|WO_IN) ); |
| 114229 | |
| 114230 | assert( pNew->nOut==saved_nOut ); |
| 114231 | if( pTerm->truthProb<=0 && iCol>=0 ){ |
| 114232 | assert( (eOp & WO_IN) || nIn==0 ); |
| 114233 | testcase( eOp & WO_IN ); |
| 114234 | pNew->nOut += pTerm->truthProb; |
| 114235 | pNew->nOut -= nIn; |
| 114236 | pNew->wsFlags |= WHERE_LIKELIHOOD; |
| 114237 | }else{ |
| 114238 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 114239 | tRowcnt nOut = 0; |
| 114240 | if( nInMul==0 |
| 114241 | && pProbe->nSample |
| 114242 | && pNew->u.btree.nEq<=pProbe->nSampleCol |
| 114243 | && OptimizationEnabled(db, SQLITE_Stat3) |
| 114244 | && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect)) |
| 114245 | && (pNew->wsFlags & WHERE_LIKELIHOOD)==0 |
| 114246 | ){ |
| 114247 | Expr *pExpr = pTerm->pExpr; |
| 114248 | if( (eOp & (WO_EQ|WO_ISNULL))!=0 ){ |
| 114249 | testcase( eOp & WO_EQ ); |
| 114250 | testcase( eOp & WO_ISNULL ); |
| 114251 | rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); |
| 114252 | }else{ |
| 114253 | rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); |
| 114254 | } |
| 114255 | assert( rc!=SQLITE_OK || nOut>0 ); |
| 114256 | if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; |
| 114257 | if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ |
| 114258 | if( nOut ){ |
| 114259 | pNew->nOut = sqlite3LogEst(nOut); |
| 114260 | if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; |
| 114261 | pNew->nOut -= nIn; |
| 114262 | } |
| 114263 | } |
| 114264 | if( nOut==0 ) |
| 114265 | #endif |
| 114266 | { |
| 114267 | pNew->nOut += (pProbe->aiRowLogEst[nEq] - pProbe->aiRowLogEst[nEq-1]); |
| 114268 | if( eOp & WO_ISNULL ){ |
| 114269 | /* TUNING: If there is no likelihood() value, assume that a |
| 114270 | ** "col IS NULL" expression matches twice as many rows |
| 114271 | ** as (col=?). */ |
| 114272 | pNew->nOut += 10; |
| 114273 | } |
| 114274 | } |
| 114275 | } |
| 114276 | } |
| 114277 | |
| 114278 | /* Set rCostIdx to the cost of visiting selected rows in index. Add |
| 114279 | ** it to pNew->rRun, which is currently set to the cost of the index |
| 114280 | ** seek only. Then, if this is a non-covering index, add the cost of |
| 114281 | ** visiting the rows in the main table. */ |
| 114282 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; |
| 114283 | pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); |
| 114284 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 114285 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); |
| 114286 | } |
| 114287 | |
| 114288 | nOutUnadjusted = pNew->nOut; |
| 114289 | pNew->rRun += nInMul + nIn; |
| 114290 | pNew->nOut += nInMul + nIn; |
| 114291 | whereLoopOutputAdjust(pBuilder->pWC, pNew); |
| 114292 | rc = whereLoopInsert(pBuilder, pNew); |
| 114293 | |
| 114294 | if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ |
| 114295 | pNew->nOut = saved_nOut; |
| 114296 | }else{ |
| 114297 | pNew->nOut = nOutUnadjusted; |
| 114298 | } |
| 114299 | |
| 114300 | if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 |
| 114301 | && pNew->u.btree.nEq<(pProbe->nKeyCol + (pProbe->zName!=0)) |
| 114302 | ){ |
| 114303 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); |
| 114304 | } |
| @@ -113997,19 +114378,42 @@ | |
| 114378 | |
| 114379 | /* |
| 114380 | ** Add all WhereLoop objects for a single table of the join where the table |
| 114381 | ** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be |
| 114382 | ** a b-tree table, not a virtual table. |
| 114383 | ** |
| 114384 | ** The costs (WhereLoop.rRun) of the b-tree loops added by this function |
| 114385 | ** are calculated as follows: |
| 114386 | ** |
| 114387 | ** For a full scan, assuming the table (or index) contains nRow rows: |
| 114388 | ** |
| 114389 | ** cost = nRow * 3.0 // full-table scan |
| 114390 | ** cost = nRow * K // scan of covering index |
| 114391 | ** cost = nRow * (K+3.0) // scan of non-covering index |
| 114392 | ** |
| 114393 | ** where K is a value between 1.1 and 3.0 set based on the relative |
| 114394 | ** estimated average size of the index and table records. |
| 114395 | ** |
| 114396 | ** For an index scan, where nVisit is the number of index rows visited |
| 114397 | ** by the scan, and nSeek is the number of seek operations required on |
| 114398 | ** the index b-tree: |
| 114399 | ** |
| 114400 | ** cost = nSeek * (log(nRow) + K * nVisit) // covering index |
| 114401 | ** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index |
| 114402 | ** |
| 114403 | ** Normally, nSeek is 1. nSeek values greater than 1 come about if the |
| 114404 | ** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when |
| 114405 | ** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. |
| 114406 | */ |
| 114407 | static int whereLoopAddBtree( |
| 114408 | WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
| 114409 | Bitmask mExtra /* Extra prerequesites for using this table */ |
| 114410 | ){ |
| 114411 | WhereInfo *pWInfo; /* WHERE analysis context */ |
| 114412 | Index *pProbe; /* An index we are evaluating */ |
| 114413 | Index sPk; /* A fake index object for the primary key */ |
| 114414 | LogEst aiRowEstPk[2]; /* The aiRowLogEst[] value for the sPk index */ |
| 114415 | i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */ |
| 114416 | SrcList *pTabList; /* The FROM clause */ |
| 114417 | struct SrcList_item *pSrc; /* The FROM clause btree term to add */ |
| 114418 | WhereLoop *pNew; /* Template WhereLoop object */ |
| 114419 | int rc = SQLITE_OK; /* Return code */ |
| @@ -114040,24 +114444,25 @@ | |
| 114444 | ** indices to follow */ |
| 114445 | Index *pFirst; /* First of real indices on the table */ |
| 114446 | memset(&sPk, 0, sizeof(Index)); |
| 114447 | sPk.nKeyCol = 1; |
| 114448 | sPk.aiColumn = &aiColumnPk; |
| 114449 | sPk.aiRowLogEst = aiRowEstPk; |
| 114450 | sPk.onError = OE_Replace; |
| 114451 | sPk.pTable = pTab; |
| 114452 | sPk.szIdxRow = pTab->szTabRow; |
| 114453 | aiRowEstPk[0] = pTab->nRowLogEst; |
| 114454 | aiRowEstPk[1] = 0; |
| 114455 | pFirst = pSrc->pTab->pIndex; |
| 114456 | if( pSrc->notIndexed==0 ){ |
| 114457 | /* The real indices of the table are only considered if the |
| 114458 | ** NOT INDEXED qualifier is omitted from the FROM clause */ |
| 114459 | sPk.pNext = pFirst; |
| 114460 | } |
| 114461 | pProbe = &sPk; |
| 114462 | } |
| 114463 | rSize = pTab->nRowLogEst; |
| 114464 | rLogSize = estLog(rSize); |
| 114465 | |
| 114466 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 114467 | /* Automatic indexes */ |
| 114468 | if( !pBuilder->pOrSet |
| @@ -114103,10 +114508,11 @@ | |
| 114508 | for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){ |
| 114509 | if( pProbe->pPartIdxWhere!=0 |
| 114510 | && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){ |
| 114511 | continue; /* Partial index inappropriate for this query */ |
| 114512 | } |
| 114513 | rSize = pProbe->aiRowLogEst[0]; |
| 114514 | pNew->u.btree.nEq = 0; |
| 114515 | pNew->u.btree.nSkip = 0; |
| 114516 | pNew->nLTerm = 0; |
| 114517 | pNew->iSortIdx = 0; |
| 114518 | pNew->rSetup = 0; |
| @@ -114120,14 +114526,12 @@ | |
| 114526 | /* Integer primary key index */ |
| 114527 | pNew->wsFlags = WHERE_IPK; |
| 114528 | |
| 114529 | /* Full table scan */ |
| 114530 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 114531 | /* TUNING: Cost of full table scan is (N*3.0). */ |
| 114532 | pNew->rRun = rSize + 16; |
| 114533 | whereLoopOutputAdjust(pWC, pNew); |
| 114534 | rc = whereLoopInsert(pBuilder, pNew); |
| 114535 | pNew->nOut = rSize; |
| 114536 | if( rc ) break; |
| 114537 | }else{ |
| @@ -114150,39 +114554,20 @@ | |
| 114554 | && sqlite3GlobalConfig.bUseCis |
| 114555 | && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan) |
| 114556 | ) |
| 114557 | ){ |
| 114558 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 114559 | |
| 114560 | /* The cost of visiting the index rows is N*K, where K is |
| 114561 | ** between 1.1 and 3.0, depending on the relative sizes of the |
| 114562 | ** index and table rows. If this is a non-covering index scan, |
| 114563 | ** also add the cost of visiting table rows (N*3.0). */ |
| 114564 | pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; |
| 114565 | if( m!=0 ){ |
| 114566 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16); |
| 114567 | } |
| 114568 | |
| 114569 | whereLoopOutputAdjust(pWC, pNew); |
| 114570 | rc = whereLoopInsert(pBuilder, pNew); |
| 114571 | pNew->nOut = rSize; |
| 114572 | if( rc ) break; |
| 114573 | } |
| @@ -114382,11 +114767,11 @@ | |
| 114767 | WhereTerm *pTerm, *pWCEnd; |
| 114768 | int rc = SQLITE_OK; |
| 114769 | int iCur; |
| 114770 | WhereClause tempWC; |
| 114771 | WhereLoopBuilder sSubBuild; |
| 114772 | WhereOrSet sSum, sCur; |
| 114773 | struct SrcList_item *pItem; |
| 114774 | |
| 114775 | pWC = pBuilder->pWC; |
| 114776 | if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK; |
| 114777 | pWCEnd = pWC->a + pWC->nTerm; |
| @@ -114438,10 +114823,11 @@ | |
| 114823 | break; |
| 114824 | }else if( once ){ |
| 114825 | whereOrMove(&sSum, &sCur); |
| 114826 | once = 0; |
| 114827 | }else{ |
| 114828 | WhereOrSet sPrev; |
| 114829 | whereOrMove(&sPrev, &sSum); |
| 114830 | sSum.n = 0; |
| 114831 | for(i=0; i<sPrev.n; i++){ |
| 114832 | for(j=0; j<sCur.n; j++){ |
| 114833 | whereOrInsert(&sSum, sPrev.a[i].prereq | sCur.a[j].prereq, |
| @@ -114456,12 +114842,23 @@ | |
| 114842 | pNew->wsFlags = WHERE_MULTI_OR; |
| 114843 | pNew->rSetup = 0; |
| 114844 | pNew->iSortIdx = 0; |
| 114845 | memset(&pNew->u, 0, sizeof(pNew->u)); |
| 114846 | for(i=0; rc==SQLITE_OK && i<sSum.n; i++){ |
| 114847 | /* TUNING: Currently sSum.a[i].rRun is set to the sum of the costs |
| 114848 | ** of all sub-scans required by the OR-scan. However, due to rounding |
| 114849 | ** errors, it may be that the cost of the OR-scan is equal to its |
| 114850 | ** most expensive sub-scan. Add the smallest possible penalty |
| 114851 | ** (equivalent to multiplying the cost by 1.07) to ensure that |
| 114852 | ** this does not happen. Otherwise, for WHERE clauses such as the |
| 114853 | ** following where there is an index on "y": |
| 114854 | ** |
| 114855 | ** WHERE likelihood(x=?, 0.99) OR y=? |
| 114856 | ** |
| 114857 | ** the planner may elect to "OR" together a full-table scan and an |
| 114858 | ** index lookup. And other similarly odd results. */ |
| 114859 | pNew->rRun = sSum.a[i].rRun + 1; |
| 114860 | pNew->nOut = sSum.a[i].nOut; |
| 114861 | pNew->prereq = sSum.a[i].prereq; |
| 114862 | rc = whereLoopInsert(pBuilder, pNew); |
| 114863 | } |
| 114864 | } |
| @@ -114520,11 +114917,11 @@ | |
| 114917 | ** N<0: Unknown yet how many terms of ORDER BY might be satisfied. |
| 114918 | ** |
| 114919 | ** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as |
| 114920 | ** strict. With GROUP BY and DISTINCT the only requirement is that |
| 114921 | ** equivalent rows appear immediately adjacent to one another. GROUP BY |
| 114922 | ** and DISTINCT do not require rows to appear in any particular order as long |
| 114923 | ** as equivelent rows are grouped together. Thus for GROUP BY and DISTINCT |
| 114924 | ** the pOrderBy terms can be matched in any order. With ORDER BY, the |
| 114925 | ** pOrderBy terms must be matched in strict left-to-right order. |
| 114926 | */ |
| 114927 | static i8 wherePathSatisfiesOrderBy( |
| @@ -114581,18 +114978,10 @@ | |
| 114978 | ** rowid appears in the ORDER BY clause, the corresponding WhereLoop is |
| 114979 | ** automatically order-distinct. |
| 114980 | */ |
| 114981 | |
| 114982 | assert( pOrderBy!=0 ); |
| 114983 | if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0; |
| 114984 | |
| 114985 | nOrderBy = pOrderBy->nExpr; |
| 114986 | testcase( nOrderBy==BMS-1 ); |
| 114987 | if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */ |
| @@ -114601,11 +114990,14 @@ | |
| 114990 | orderDistinctMask = 0; |
| 114991 | ready = 0; |
| 114992 | for(iLoop=0; isOrderDistinct && obSat<obDone && iLoop<=nLoop; iLoop++){ |
| 114993 | if( iLoop>0 ) ready |= pLoop->maskSelf; |
| 114994 | pLoop = iLoop<nLoop ? pPath->aLoop[iLoop] : pLast; |
| 114995 | if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ |
| 114996 | if( pLoop->u.vtab.isOrdered ) obSat = obDone; |
| 114997 | break; |
| 114998 | } |
| 114999 | iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor; |
| 115000 | |
| 115001 | /* Mark off any ORDER BY term X that is a column in the table of |
| 115002 | ** the current loop for which there is term in the WHERE |
| 115003 | ** clause of the form X IS NULL or X=? that reference only outer |
| @@ -114689,11 +115081,11 @@ | |
| 115081 | ){ |
| 115082 | isOrderDistinct = 0; |
| 115083 | } |
| 115084 | |
| 115085 | /* Find the ORDER BY term that corresponds to the j-th column |
| 115086 | ** of the index and mark that ORDER BY term off |
| 115087 | */ |
| 115088 | bOnce = 1; |
| 115089 | isMatch = 0; |
| 115090 | for(i=0; bOnce && i<nOrderBy; i++){ |
| 115091 | if( MASKBIT(i) & obSat ) continue; |
| @@ -114769,10 +115161,40 @@ | |
| 115161 | return 0; |
| 115162 | } |
| 115163 | return -1; |
| 115164 | } |
| 115165 | |
| 115166 | |
| 115167 | /* |
| 115168 | ** If the WHERE_GROUPBY flag is set in the mask passed to sqlite3WhereBegin(), |
| 115169 | ** the planner assumes that the specified pOrderBy list is actually a GROUP |
| 115170 | ** BY clause - and so any order that groups rows as required satisfies the |
| 115171 | ** request. |
| 115172 | ** |
| 115173 | ** Normally, in this case it is not possible for the caller to determine |
| 115174 | ** whether or not the rows are really being delivered in sorted order, or |
| 115175 | ** just in some other order that provides the required grouping. However, |
| 115176 | ** if the WHERE_SORTBYGROUP flag is also passed to sqlite3WhereBegin(), then |
| 115177 | ** this function may be called on the returned WhereInfo object. It returns |
| 115178 | ** true if the rows really will be sorted in the specified order, or false |
| 115179 | ** otherwise. |
| 115180 | ** |
| 115181 | ** For example, assuming: |
| 115182 | ** |
| 115183 | ** CREATE INDEX i1 ON t1(x, Y); |
| 115184 | ** |
| 115185 | ** then |
| 115186 | ** |
| 115187 | ** SELECT * FROM t1 GROUP BY x,y ORDER BY x,y; -- IsSorted()==1 |
| 115188 | ** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0 |
| 115189 | */ |
| 115190 | SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){ |
| 115191 | assert( pWInfo->wctrlFlags & WHERE_GROUPBY ); |
| 115192 | assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP ); |
| 115193 | return pWInfo->sorted; |
| 115194 | } |
| 115195 | |
| 115196 | #ifdef WHERETRACE_ENABLED |
| 115197 | /* For debugging use only: */ |
| 115198 | static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){ |
| 115199 | static char zName[65]; |
| 115200 | int i; |
| @@ -114780,11 +115202,10 @@ | |
| 115202 | if( pLast ) zName[i++] = pLast->cId; |
| 115203 | zName[i] = 0; |
| 115204 | return zName; |
| 115205 | } |
| 115206 | #endif |
| 115207 | |
| 115208 | /* |
| 115209 | ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine |
| 115210 | ** attempts to find the lowest cost path that visits each WhereLoop |
| 115211 | ** once. This path is then loaded into the pWInfo->a[].pWLoop fields. |
| @@ -114879,26 +115300,31 @@ | |
| 115300 | if( isOrdered<0 ){ |
| 115301 | isOrdered = wherePathSatisfiesOrderBy(pWInfo, |
| 115302 | pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, |
| 115303 | iLoop, pWLoop, &revMask); |
| 115304 | if( isOrdered>=0 && isOrdered<nOrderBy ){ |
| 115305 | /* TUNING: Estimated cost of a full external sort, where N is |
| 115306 | ** the number of rows to sort is: |
| 115307 | ** |
| 115308 | ** cost = (3.0 * N * log(N)). |
| 115309 | ** |
| 115310 | ** Or, if the order-by clause has X terms but only the last Y |
| 115311 | ** terms are out of order, then block-sorting will reduce the |
| 115312 | ** sorting cost to: |
| 115313 | ** |
| 115314 | ** cost = (3.0 * N * log(N)) * (Y/X) |
| 115315 | ** |
| 115316 | ** The (Y/X) term is implemented using stack variable rScale |
| 115317 | ** below. */ |
| 115318 | LogEst rScale, rSortCost; |
| 115319 | assert( nOrderBy>0 && 66==sqlite3LogEst(100) ); |
| 115320 | rScale = sqlite3LogEst((nOrderBy-isOrdered)*100/nOrderBy) - 66; |
| 115321 | rSortCost = nRowEst + estLog(nRowEst) + rScale + 16; |
| 115322 | |
| 115323 | /* TUNING: The cost of implementing DISTINCT using a B-TREE is |
| 115324 | ** similar but with a larger constant of proportionality. |
| 115325 | ** Multiply by an additional factor of 3.0. */ |
| 115326 | if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 115327 | rSortCost += 16; |
| 115328 | } |
| 115329 | WHERETRACE(0x002, |
| 115330 | ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", |
| @@ -115062,11 +115488,23 @@ | |
| 115488 | }else{ |
| 115489 | pWInfo->nOBSat = pFrom->isOrdered; |
| 115490 | if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0; |
| 115491 | pWInfo->revMask = pFrom->revLoop; |
| 115492 | } |
| 115493 | if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP) |
| 115494 | && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr |
| 115495 | ){ |
| 115496 | Bitmask notUsed = 0; |
| 115497 | int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, |
| 115498 | pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used |
| 115499 | ); |
| 115500 | assert( pWInfo->sorted==0 ); |
| 115501 | pWInfo->sorted = (nOrder==pWInfo->pOrderBy->nExpr); |
| 115502 | } |
| 115503 | } |
| 115504 | |
| 115505 | |
| 115506 | pWInfo->nRowOut = pFrom->nRow; |
| 115507 | |
| 115508 | /* Free temporary memory and return success */ |
| 115509 | sqlite3DbFree(db, pSpace); |
| 115510 | return SQLITE_OK; |
| @@ -123654,10 +124092,32 @@ | |
| 124092 | int sz = va_arg(ap, int); |
| 124093 | int *aProg = va_arg(ap, int*); |
| 124094 | rc = sqlite3BitvecBuiltinTest(sz, aProg); |
| 124095 | break; |
| 124096 | } |
| 124097 | |
| 124098 | /* |
| 124099 | ** sqlite3_test_control(FAULT_INSTALL, xCallback) |
| 124100 | ** |
| 124101 | ** Arrange to invoke xCallback() whenever sqlite3FaultSim() is called, |
| 124102 | ** if xCallback is not NULL. |
| 124103 | ** |
| 124104 | ** As a test of the fault simulator mechanism itself, sqlite3FaultSim(0) |
| 124105 | ** is called immediately after installing the new callback and the return |
| 124106 | ** value from sqlite3FaultSim(0) becomes the return from |
| 124107 | ** sqlite3_test_control(). |
| 124108 | */ |
| 124109 | case SQLITE_TESTCTRL_FAULT_INSTALL: { |
| 124110 | /* MSVC is picky about pulling func ptrs from va lists. |
| 124111 | ** http://support.microsoft.com/kb/47961 |
| 124112 | ** sqlite3Config.xTestCallback = va_arg(ap, int(*)(int)); |
| 124113 | */ |
| 124114 | typedef int(*TESTCALLBACKFUNC_t)(int); |
| 124115 | sqlite3Config.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t); |
| 124116 | rc = sqlite3FaultSim(0); |
| 124117 | break; |
| 124118 | } |
| 124119 | |
| 124120 | /* |
| 124121 | ** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) |
| 124122 | ** |
| 124123 | ** Register hooks to call to indicate which malloc() failures |
| @@ -123964,11 +124424,11 @@ | |
| 124424 | ** Return 1 if database is read-only or 0 if read/write. Return -1 if |
| 124425 | ** no such database exists. |
| 124426 | */ |
| 124427 | SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){ |
| 124428 | Btree *pBt = sqlite3DbNameToBtree(db, zDbName); |
| 124429 | return pBt ? sqlite3BtreeIsReadonly(pBt) : -1; |
| 124430 | } |
| 124431 | |
| 124432 | /************** End of main.c ************************************************/ |
| 124433 | /************** Begin file notify.c ******************************************/ |
| 124434 | /* |
| @@ -125084,17 +125544,17 @@ | |
| 125544 | char **azColumn; /* column names. malloced */ |
| 125545 | u8 *abNotindexed; /* True for 'notindexed' columns */ |
| 125546 | sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ |
| 125547 | char *zContentTbl; /* content=xxx option, or NULL */ |
| 125548 | char *zLanguageid; /* languageid=xxx option, or NULL */ |
| 125549 | int nAutoincrmerge; /* Value configured by 'automerge' */ |
| 125550 | u32 nLeafAdd; /* Number of leaf blocks added this trans */ |
| 125551 | |
| 125552 | /* Precompiled statements used by the implementation. Each of these |
| 125553 | ** statements is run and reset within a single virtual table API call. |
| 125554 | */ |
| 125555 | sqlite3_stmt *aStmt[40]; |
| 125556 | |
| 125557 | char *zReadExprlist; |
| 125558 | char *zWriteExprlist; |
| 125559 | |
| 125560 | int nNodeSize; /* Soft limit for node size */ |
| @@ -126512,11 +126972,11 @@ | |
| 126972 | p->nMaxPendingData = FTS3_MAX_PENDING_DATA; |
| 126973 | p->bHasDocsize = (isFts4 && bNoDocsize==0); |
| 126974 | p->bHasStat = isFts4; |
| 126975 | p->bFts4 = isFts4; |
| 126976 | p->bDescIdx = bDescIdx; |
| 126977 | p->nAutoincrmerge = 0xff; /* 0xff means setting unknown */ |
| 126978 | p->zContentTbl = zContent; |
| 126979 | p->zLanguageid = zLanguageid; |
| 126980 | zContent = 0; |
| 126981 | zLanguageid = 0; |
| 126982 | TESTONLY( p->inTransaction = -1 ); |
| @@ -128481,19 +128941,22 @@ | |
| 128941 | const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */ |
| 128942 | |
| 128943 | Fts3Table *p = (Fts3Table*)pVtab; |
| 128944 | int rc = sqlite3Fts3PendingTermsFlush(p); |
| 128945 | |
| 128946 | if( rc==SQLITE_OK |
| 128947 | && p->nLeafAdd>(nMinMerge/16) |
| 128948 | && p->nAutoincrmerge && p->nAutoincrmerge!=0xff |
| 128949 | ){ |
| 128950 | int mxLevel = 0; /* Maximum relative level value in db */ |
| 128951 | int A; /* Incr-merge parameter A */ |
| 128952 | |
| 128953 | rc = sqlite3Fts3MaxLevel(p, &mxLevel); |
| 128954 | assert( rc==SQLITE_OK || mxLevel==0 ); |
| 128955 | A = p->nLeafAdd * mxLevel; |
| 128956 | A += (A/2); |
| 128957 | if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge); |
| 128958 | } |
| 128959 | sqlite3Fts3SegmentsClose(p); |
| 128960 | return rc; |
| 128961 | } |
| 128962 | |
| @@ -131712,44 +132175,27 @@ | |
| 132175 | sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; |
| 132176 | sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; |
| 132177 | int rc; |
| 132178 | sqlite3_tokenizer_cursor *pCursor; |
| 132179 | Fts3Expr *pRet = 0; |
| 132180 | int i = 0; |
| 132181 | |
| 132182 | /* Set variable i to the maximum number of bytes of input to tokenize. */ |
| 132183 | for(i=0; i<n; i++){ |
| 132184 | if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break; |
| 132185 | if( z[i]=='*' || z[i]=='"' ) break; |
| 132186 | } |
| 132187 | |
| 132188 | *pnConsumed = i; |
| 132189 | rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor); |
| 132190 | if( rc==SQLITE_OK ){ |
| 132191 | const char *zToken; |
| 132192 | int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; |
| 132193 | int nByte; /* total space to allocate */ |
| 132194 | |
| 132195 | rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); |
| 132196 | if( rc==SQLITE_OK ){ |
| 132197 | nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; |
| 132198 | pRet = (Fts3Expr *)fts3MallocZero(nByte); |
| 132199 | if( !pRet ){ |
| 132200 | rc = SQLITE_NOMEM; |
| 132201 | }else{ |
| @@ -131779,17 +132225,18 @@ | |
| 132225 | break; |
| 132226 | } |
| 132227 | } |
| 132228 | |
| 132229 | } |
| 132230 | *pnConsumed = iEnd; |
| 132231 | }else if( i && rc==SQLITE_DONE ){ |
| 132232 | rc = SQLITE_OK; |
| 132233 | } |
| 132234 | |
| 132235 | pModule->xClose(pCursor); |
| 132236 | } |
| 132237 | |
| 132238 | *ppExpr = pRet; |
| 132239 | return rc; |
| 132240 | } |
| 132241 | |
| 132242 | |
| @@ -132035,10 +132482,25 @@ | |
| 132482 | return SQLITE_ERROR; |
| 132483 | } |
| 132484 | return getNextString(pParse, &zInput[1], ii-1, ppExpr); |
| 132485 | } |
| 132486 | |
| 132487 | if( sqlite3_fts3_enable_parentheses ){ |
| 132488 | if( *zInput=='(' ){ |
| 132489 | int nConsumed = 0; |
| 132490 | pParse->nNest++; |
| 132491 | rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed); |
| 132492 | if( rc==SQLITE_OK && !*ppExpr ){ rc = SQLITE_DONE; } |
| 132493 | *pnConsumed = (int)(zInput - z) + 1 + nConsumed; |
| 132494 | return rc; |
| 132495 | }else if( *zInput==')' ){ |
| 132496 | pParse->nNest--; |
| 132497 | *pnConsumed = (zInput - z) + 1; |
| 132498 | *ppExpr = 0; |
| 132499 | return SQLITE_DONE; |
| 132500 | } |
| 132501 | } |
| 132502 | |
| 132503 | /* If control flows to this point, this must be a regular token, or |
| 132504 | ** the end of the input. Read a regular token using the sqlite3_tokenizer |
| 132505 | ** interface. Before doing so, figure out if there is an explicit |
| 132506 | ** column specifier for the token. |
| @@ -132153,100 +132615,104 @@ | |
| 132615 | int isRequirePhrase = 1; |
| 132616 | |
| 132617 | while( rc==SQLITE_OK ){ |
| 132618 | Fts3Expr *p = 0; |
| 132619 | int nByte = 0; |
| 132620 | |
| 132621 | rc = getNextNode(pParse, zIn, nIn, &p, &nByte); |
| 132622 | assert( nByte>0 || (rc!=SQLITE_OK && p==0) ); |
| 132623 | if( rc==SQLITE_OK ){ |
| 132624 | if( p ){ |
| 132625 | int isPhrase; |
| 132626 | |
| 132627 | if( !sqlite3_fts3_enable_parentheses |
| 132628 | && p->eType==FTSQUERY_PHRASE && pParse->isNot |
| 132629 | ){ |
| 132630 | /* Create an implicit NOT operator. */ |
| 132631 | Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr)); |
| 132632 | if( !pNot ){ |
| 132633 | sqlite3Fts3ExprFree(p); |
| 132634 | rc = SQLITE_NOMEM; |
| 132635 | goto exprparse_out; |
| 132636 | } |
| 132637 | pNot->eType = FTSQUERY_NOT; |
| 132638 | pNot->pRight = p; |
| 132639 | p->pParent = pNot; |
| 132640 | if( pNotBranch ){ |
| 132641 | pNot->pLeft = pNotBranch; |
| 132642 | pNotBranch->pParent = pNot; |
| 132643 | } |
| 132644 | pNotBranch = pNot; |
| 132645 | p = pPrev; |
| 132646 | }else{ |
| 132647 | int eType = p->eType; |
| 132648 | isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); |
| 132649 | |
| 132650 | /* The isRequirePhrase variable is set to true if a phrase or |
| 132651 | ** an expression contained in parenthesis is required. If a |
| 132652 | ** binary operator (AND, OR, NOT or NEAR) is encounted when |
| 132653 | ** isRequirePhrase is set, this is a syntax error. |
| 132654 | */ |
| 132655 | if( !isPhrase && isRequirePhrase ){ |
| 132656 | sqlite3Fts3ExprFree(p); |
| 132657 | rc = SQLITE_ERROR; |
| 132658 | goto exprparse_out; |
| 132659 | } |
| 132660 | |
| 132661 | if( isPhrase && !isRequirePhrase ){ |
| 132662 | /* Insert an implicit AND operator. */ |
| 132663 | Fts3Expr *pAnd; |
| 132664 | assert( pRet && pPrev ); |
| 132665 | pAnd = fts3MallocZero(sizeof(Fts3Expr)); |
| 132666 | if( !pAnd ){ |
| 132667 | sqlite3Fts3ExprFree(p); |
| 132668 | rc = SQLITE_NOMEM; |
| 132669 | goto exprparse_out; |
| 132670 | } |
| 132671 | pAnd->eType = FTSQUERY_AND; |
| 132672 | insertBinaryOperator(&pRet, pPrev, pAnd); |
| 132673 | pPrev = pAnd; |
| 132674 | } |
| 132675 | |
| 132676 | /* This test catches attempts to make either operand of a NEAR |
| 132677 | ** operator something other than a phrase. For example, either of |
| 132678 | ** the following: |
| 132679 | ** |
| 132680 | ** (bracketed expression) NEAR phrase |
| 132681 | ** phrase NEAR (bracketed expression) |
| 132682 | ** |
| 132683 | ** Return an error in either case. |
| 132684 | */ |
| 132685 | if( pPrev && ( |
| 132686 | (eType==FTSQUERY_NEAR && !isPhrase && pPrev->eType!=FTSQUERY_PHRASE) |
| 132687 | || (eType!=FTSQUERY_PHRASE && isPhrase && pPrev->eType==FTSQUERY_NEAR) |
| 132688 | )){ |
| 132689 | sqlite3Fts3ExprFree(p); |
| 132690 | rc = SQLITE_ERROR; |
| 132691 | goto exprparse_out; |
| 132692 | } |
| 132693 | |
| 132694 | if( isPhrase ){ |
| 132695 | if( pRet ){ |
| 132696 | assert( pPrev && pPrev->pLeft && pPrev->pRight==0 ); |
| 132697 | pPrev->pRight = p; |
| 132698 | p->pParent = pPrev; |
| 132699 | }else{ |
| 132700 | pRet = p; |
| 132701 | } |
| 132702 | }else{ |
| 132703 | insertBinaryOperator(&pRet, pPrev, p); |
| 132704 | } |
| 132705 | isRequirePhrase = !isPhrase; |
| 132706 | } |
| 132707 | pPrev = p; |
| 132708 | } |
| 132709 | assert( nByte>0 ); |
| 132710 | } |
| 132711 | assert( rc!=SQLITE_OK || (nByte>0 && nByte<=nIn) ); |
| 132712 | nIn -= nByte; |
| 132713 | zIn += nByte; |
| 132714 | } |
| 132715 | |
| 132716 | if( rc==SQLITE_DONE && pRet && isRequirePhrase ){ |
| 132717 | rc = SQLITE_ERROR; |
| 132718 | } |
| @@ -135230,10 +135696,11 @@ | |
| 135696 | int nMalloc; /* Size of malloc'd buffer at zMalloc */ |
| 135697 | char *zMalloc; /* Malloc'd space (possibly) used for zTerm */ |
| 135698 | int nSize; /* Size of allocation at aData */ |
| 135699 | int nData; /* Bytes of data in aData */ |
| 135700 | char *aData; /* Pointer to block from malloc() */ |
| 135701 | i64 nLeafData; /* Number of bytes of leaf data written */ |
| 135702 | }; |
| 135703 | |
| 135704 | /* |
| 135705 | ** Type SegmentNode is used by the following three functions to create |
| 135706 | ** the interior part of the segment b+-tree structures (everything except |
| @@ -135304,10 +135771,14 @@ | |
| 135771 | #define SQL_SELECT_SEGDIR 32 |
| 135772 | #define SQL_CHOMP_SEGDIR 33 |
| 135773 | #define SQL_SEGMENT_IS_APPENDABLE 34 |
| 135774 | #define SQL_SELECT_INDEXES 35 |
| 135775 | #define SQL_SELECT_MXLEVEL 36 |
| 135776 | |
| 135777 | #define SQL_SELECT_LEVEL_RANGE2 37 |
| 135778 | #define SQL_UPDATE_LEVEL_IDX 38 |
| 135779 | #define SQL_UPDATE_LEVEL 39 |
| 135780 | |
| 135781 | /* |
| 135782 | ** This function is used to obtain an SQLite prepared statement handle |
| 135783 | ** for the statement identified by the second argument. If successful, |
| 135784 | ** *pp is set to the requested statement handle and SQLITE_OK returned. |
| @@ -135406,11 +135877,22 @@ | |
| 135877 | ** Return the list of valid segment indexes for absolute level ? */ |
| 135878 | /* 35 */ "SELECT idx FROM %Q.'%q_segdir' WHERE level=? ORDER BY 1 ASC", |
| 135879 | |
| 135880 | /* SQL_SELECT_MXLEVEL |
| 135881 | ** Return the largest relative level in the FTS index or indexes. */ |
| 135882 | /* 36 */ "SELECT max( level %% 1024 ) FROM %Q.'%q_segdir'", |
| 135883 | |
| 135884 | /* Return segments in order from oldest to newest.*/ |
| 135885 | /* 37 */ "SELECT level, idx, end_block " |
| 135886 | "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? " |
| 135887 | "ORDER BY level DESC, idx ASC", |
| 135888 | |
| 135889 | /* Update statements used while promoting segments */ |
| 135890 | /* 38 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=-1,idx=? " |
| 135891 | "WHERE level=? AND idx=?", |
| 135892 | /* 39 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=? WHERE level=-1" |
| 135893 | |
| 135894 | }; |
| 135895 | int rc = SQLITE_OK; |
| 135896 | sqlite3_stmt *pStmt; |
| 135897 | |
| 135898 | assert( SizeofArray(azSql)==SizeofArray(p->aStmt) ); |
| @@ -136947,10 +137429,11 @@ | |
| 137429 | sqlite3_int64 iLevel, /* Value for "level" field (absolute level) */ |
| 137430 | int iIdx, /* Value for "idx" field */ |
| 137431 | sqlite3_int64 iStartBlock, /* Value for "start_block" field */ |
| 137432 | sqlite3_int64 iLeafEndBlock, /* Value for "leaves_end_block" field */ |
| 137433 | sqlite3_int64 iEndBlock, /* Value for "end_block" field */ |
| 137434 | sqlite3_int64 nLeafData, /* Bytes of leaf data in segment */ |
| 137435 | char *zRoot, /* Blob value for "root" field */ |
| 137436 | int nRoot /* Number of bytes in buffer zRoot */ |
| 137437 | ){ |
| 137438 | sqlite3_stmt *pStmt; |
| 137439 | int rc = fts3SqlStmt(p, SQL_INSERT_SEGDIR, &pStmt, 0); |
| @@ -136957,11 +137440,17 @@ | |
| 137440 | if( rc==SQLITE_OK ){ |
| 137441 | sqlite3_bind_int64(pStmt, 1, iLevel); |
| 137442 | sqlite3_bind_int(pStmt, 2, iIdx); |
| 137443 | sqlite3_bind_int64(pStmt, 3, iStartBlock); |
| 137444 | sqlite3_bind_int64(pStmt, 4, iLeafEndBlock); |
| 137445 | if( nLeafData==0 ){ |
| 137446 | sqlite3_bind_int64(pStmt, 5, iEndBlock); |
| 137447 | }else{ |
| 137448 | char *zEnd = sqlite3_mprintf("%lld %lld", iEndBlock, nLeafData); |
| 137449 | if( !zEnd ) return SQLITE_NOMEM; |
| 137450 | sqlite3_bind_text(pStmt, 5, zEnd, -1, sqlite3_free); |
| 137451 | } |
| 137452 | sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC); |
| 137453 | sqlite3_step(pStmt); |
| 137454 | rc = sqlite3_reset(pStmt); |
| 137455 | } |
| 137456 | return rc; |
| @@ -137282,10 +137771,13 @@ | |
| 137771 | sqlite3Fts3VarintLen(nTerm) + /* varint containing suffix size */ |
| 137772 | nTerm + /* Term suffix */ |
| 137773 | sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ |
| 137774 | nDoclist; /* Doclist data */ |
| 137775 | } |
| 137776 | |
| 137777 | /* Increase the total number of bytes written to account for the new entry. */ |
| 137778 | pWriter->nLeafData += nReq; |
| 137779 | |
| 137780 | /* If the buffer currently allocated is too small for this entry, realloc |
| 137781 | ** the buffer to make it large enough. |
| 137782 | */ |
| 137783 | if( nReq>pWriter->nSize ){ |
| @@ -137354,17 +137846,17 @@ | |
| 137846 | if( rc==SQLITE_OK ){ |
| 137847 | rc = fts3NodeWrite(p, pWriter->pTree, 1, |
| 137848 | pWriter->iFirst, pWriter->iFree, &iLast, &zRoot, &nRoot); |
| 137849 | } |
| 137850 | if( rc==SQLITE_OK ){ |
| 137851 | rc = fts3WriteSegdir(p, iLevel, iIdx, |
| 137852 | pWriter->iFirst, iLastLeaf, iLast, pWriter->nLeafData, zRoot, nRoot); |
| 137853 | } |
| 137854 | }else{ |
| 137855 | /* The entire tree fits on the root node. Write it to the segdir table. */ |
| 137856 | rc = fts3WriteSegdir(p, iLevel, iIdx, |
| 137857 | 0, 0, 0, pWriter->nLeafData, pWriter->aData, pWriter->nData); |
| 137858 | } |
| 137859 | p->nLeafAdd++; |
| 137860 | return rc; |
| 137861 | } |
| 137862 | |
| @@ -137443,10 +137935,41 @@ | |
| 137935 | if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 137936 | *pnMax = sqlite3_column_int64(pStmt, 0); |
| 137937 | } |
| 137938 | return sqlite3_reset(pStmt); |
| 137939 | } |
| 137940 | |
| 137941 | /* |
| 137942 | ** iAbsLevel is an absolute level that may be assumed to exist within |
| 137943 | ** the database. This function checks if it is the largest level number |
| 137944 | ** within its index. Assuming no error occurs, *pbMax is set to 1 if |
| 137945 | ** iAbsLevel is indeed the largest level, or 0 otherwise, and SQLITE_OK |
| 137946 | ** is returned. If an error occurs, an error code is returned and the |
| 137947 | ** final value of *pbMax is undefined. |
| 137948 | */ |
| 137949 | static int fts3SegmentIsMaxLevel(Fts3Table *p, i64 iAbsLevel, int *pbMax){ |
| 137950 | |
| 137951 | /* Set pStmt to the compiled version of: |
| 137952 | ** |
| 137953 | ** SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? |
| 137954 | ** |
| 137955 | ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR). |
| 137956 | */ |
| 137957 | sqlite3_stmt *pStmt; |
| 137958 | int rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); |
| 137959 | if( rc!=SQLITE_OK ) return rc; |
| 137960 | sqlite3_bind_int64(pStmt, 1, iAbsLevel+1); |
| 137961 | sqlite3_bind_int64(pStmt, 2, |
| 137962 | ((iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL |
| 137963 | ); |
| 137964 | |
| 137965 | *pbMax = 0; |
| 137966 | if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 137967 | *pbMax = sqlite3_column_type(pStmt, 0)==SQLITE_NULL; |
| 137968 | } |
| 137969 | return sqlite3_reset(pStmt); |
| 137970 | } |
| 137971 | |
| 137972 | /* |
| 137973 | ** Delete all entries in the %_segments table associated with the segment |
| 137974 | ** opened with seg-reader pSeg. This function does not affect the contents |
| 137975 | ** of the %_segdir table. |
| @@ -137978,10 +138501,144 @@ | |
| 138501 | pCsr->nSegment = 0; |
| 138502 | pCsr->apSegment = 0; |
| 138503 | pCsr->aBuffer = 0; |
| 138504 | } |
| 138505 | } |
| 138506 | |
| 138507 | /* |
| 138508 | ** Decode the "end_block" field, selected by column iCol of the SELECT |
| 138509 | ** statement passed as the first argument. |
| 138510 | ** |
| 138511 | ** The "end_block" field may contain either an integer, or a text field |
| 138512 | ** containing the text representation of two non-negative integers separated |
| 138513 | ** by one or more space (0x20) characters. In the first case, set *piEndBlock |
| 138514 | ** to the integer value and *pnByte to zero before returning. In the second, |
| 138515 | ** set *piEndBlock to the first value and *pnByte to the second. |
| 138516 | */ |
| 138517 | static void fts3ReadEndBlockField( |
| 138518 | sqlite3_stmt *pStmt, |
| 138519 | int iCol, |
| 138520 | i64 *piEndBlock, |
| 138521 | i64 *pnByte |
| 138522 | ){ |
| 138523 | const unsigned char *zText = sqlite3_column_text(pStmt, iCol); |
| 138524 | if( zText ){ |
| 138525 | int i; |
| 138526 | int iMul = 1; |
| 138527 | i64 iVal = 0; |
| 138528 | for(i=0; zText[i]>='0' && zText[i]<='9'; i++){ |
| 138529 | iVal = iVal*10 + (zText[i] - '0'); |
| 138530 | } |
| 138531 | *piEndBlock = iVal; |
| 138532 | while( zText[i]==' ' ) i++; |
| 138533 | iVal = 0; |
| 138534 | if( zText[i]=='-' ){ |
| 138535 | i++; |
| 138536 | iMul = -1; |
| 138537 | } |
| 138538 | for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){ |
| 138539 | iVal = iVal*10 + (zText[i] - '0'); |
| 138540 | } |
| 138541 | *pnByte = (iVal * (i64)iMul); |
| 138542 | } |
| 138543 | } |
| 138544 | |
| 138545 | |
| 138546 | /* |
| 138547 | ** A segment of size nByte bytes has just been written to absolute level |
| 138548 | ** iAbsLevel. Promote any segments that should be promoted as a result. |
| 138549 | */ |
| 138550 | static int fts3PromoteSegments( |
| 138551 | Fts3Table *p, /* FTS table handle */ |
| 138552 | sqlite3_int64 iAbsLevel, /* Absolute level just updated */ |
| 138553 | sqlite3_int64 nByte /* Size of new segment at iAbsLevel */ |
| 138554 | ){ |
| 138555 | int rc = SQLITE_OK; |
| 138556 | sqlite3_stmt *pRange; |
| 138557 | |
| 138558 | rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE2, &pRange, 0); |
| 138559 | |
| 138560 | if( rc==SQLITE_OK ){ |
| 138561 | int bOk = 0; |
| 138562 | i64 iLast = (iAbsLevel/FTS3_SEGDIR_MAXLEVEL + 1) * FTS3_SEGDIR_MAXLEVEL - 1; |
| 138563 | i64 nLimit = (nByte*3)/2; |
| 138564 | |
| 138565 | /* Loop through all entries in the %_segdir table corresponding to |
| 138566 | ** segments in this index on levels greater than iAbsLevel. If there is |
| 138567 | ** at least one such segment, and it is possible to determine that all |
| 138568 | ** such segments are smaller than nLimit bytes in size, they will be |
| 138569 | ** promoted to level iAbsLevel. */ |
| 138570 | sqlite3_bind_int64(pRange, 1, iAbsLevel+1); |
| 138571 | sqlite3_bind_int64(pRange, 2, iLast); |
| 138572 | while( SQLITE_ROW==sqlite3_step(pRange) ){ |
| 138573 | i64 nSize, dummy; |
| 138574 | fts3ReadEndBlockField(pRange, 2, &dummy, &nSize); |
| 138575 | if( nSize<=0 || nSize>nLimit ){ |
| 138576 | /* If nSize==0, then the %_segdir.end_block field does not not |
| 138577 | ** contain a size value. This happens if it was written by an |
| 138578 | ** old version of FTS. In this case it is not possible to determine |
| 138579 | ** the size of the segment, and so segment promotion does not |
| 138580 | ** take place. */ |
| 138581 | bOk = 0; |
| 138582 | break; |
| 138583 | } |
| 138584 | bOk = 1; |
| 138585 | } |
| 138586 | rc = sqlite3_reset(pRange); |
| 138587 | |
| 138588 | if( bOk ){ |
| 138589 | int iIdx = 0; |
| 138590 | sqlite3_stmt *pUpdate1; |
| 138591 | sqlite3_stmt *pUpdate2; |
| 138592 | |
| 138593 | if( rc==SQLITE_OK ){ |
| 138594 | rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0); |
| 138595 | } |
| 138596 | if( rc==SQLITE_OK ){ |
| 138597 | rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL, &pUpdate2, 0); |
| 138598 | } |
| 138599 | |
| 138600 | if( rc==SQLITE_OK ){ |
| 138601 | |
| 138602 | /* Loop through all %_segdir entries for segments in this index with |
| 138603 | ** levels equal to or greater than iAbsLevel. As each entry is visited, |
| 138604 | ** updated it to set (level = -1) and (idx = N), where N is 0 for the |
| 138605 | ** oldest segment in the range, 1 for the next oldest, and so on. |
| 138606 | ** |
| 138607 | ** In other words, move all segments being promoted to level -1, |
| 138608 | ** setting the "idx" fields as appropriate to keep them in the same |
| 138609 | ** order. The contents of level -1 (which is never used, except |
| 138610 | ** transiently here), will be moved back to level iAbsLevel below. */ |
| 138611 | sqlite3_bind_int64(pRange, 1, iAbsLevel); |
| 138612 | while( SQLITE_ROW==sqlite3_step(pRange) ){ |
| 138613 | sqlite3_bind_int(pUpdate1, 1, iIdx++); |
| 138614 | sqlite3_bind_int(pUpdate1, 2, sqlite3_column_int(pRange, 0)); |
| 138615 | sqlite3_bind_int(pUpdate1, 3, sqlite3_column_int(pRange, 1)); |
| 138616 | sqlite3_step(pUpdate1); |
| 138617 | rc = sqlite3_reset(pUpdate1); |
| 138618 | if( rc!=SQLITE_OK ){ |
| 138619 | sqlite3_reset(pRange); |
| 138620 | break; |
| 138621 | } |
| 138622 | } |
| 138623 | } |
| 138624 | if( rc==SQLITE_OK ){ |
| 138625 | rc = sqlite3_reset(pRange); |
| 138626 | } |
| 138627 | |
| 138628 | /* Move level -1 to level iAbsLevel */ |
| 138629 | if( rc==SQLITE_OK ){ |
| 138630 | sqlite3_bind_int64(pUpdate2, 1, iAbsLevel); |
| 138631 | sqlite3_step(pUpdate2); |
| 138632 | rc = sqlite3_reset(pUpdate2); |
| 138633 | } |
| 138634 | } |
| 138635 | } |
| 138636 | |
| 138637 | |
| 138638 | return rc; |
| 138639 | } |
| 138640 | |
| 138641 | /* |
| 138642 | ** Merge all level iLevel segments in the database into a single |
| 138643 | ** iLevel+1 segment. Or, if iLevel<0, merge all segments into a |
| 138644 | ** single segment with a level equal to the numerically largest level |
| @@ -138003,10 +138660,11 @@ | |
| 138660 | sqlite3_int64 iNewLevel = 0; /* Level/index to create new segment at */ |
| 138661 | SegmentWriter *pWriter = 0; /* Used to write the new, merged, segment */ |
| 138662 | Fts3SegFilter filter; /* Segment term filter condition */ |
| 138663 | Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */ |
| 138664 | int bIgnoreEmpty = 0; /* True to ignore empty segments */ |
| 138665 | i64 iMaxLevel = 0; /* Max level number for this index/langid */ |
| 138666 | |
| 138667 | assert( iLevel==FTS3_SEGCURSOR_ALL |
| 138668 | || iLevel==FTS3_SEGCURSOR_PENDING |
| 138669 | || iLevel>=0 |
| 138670 | ); |
| @@ -138013,10 +138671,15 @@ | |
| 138671 | assert( iLevel<FTS3_SEGDIR_MAXLEVEL ); |
| 138672 | assert( iIndex>=0 && iIndex<p->nIndex ); |
| 138673 | |
| 138674 | rc = sqlite3Fts3SegReaderCursor(p, iLangid, iIndex, iLevel, 0, 0, 1, 0, &csr); |
| 138675 | if( rc!=SQLITE_OK || csr.nSegment==0 ) goto finished; |
| 138676 | |
| 138677 | if( iLevel!=FTS3_SEGCURSOR_PENDING ){ |
| 138678 | rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iMaxLevel); |
| 138679 | if( rc!=SQLITE_OK ) goto finished; |
| 138680 | } |
| 138681 | |
| 138682 | if( iLevel==FTS3_SEGCURSOR_ALL ){ |
| 138683 | /* This call is to merge all segments in the database to a single |
| 138684 | ** segment. The level of the new segment is equal to the numerically |
| 138685 | ** greatest segment level currently present in the database for this |
| @@ -138023,25 +138686,25 @@ | |
| 138686 | ** index. The idx of the new segment is always 0. */ |
| 138687 | if( csr.nSegment==1 ){ |
| 138688 | rc = SQLITE_DONE; |
| 138689 | goto finished; |
| 138690 | } |
| 138691 | iNewLevel = iMaxLevel; |
| 138692 | bIgnoreEmpty = 1; |
| 138693 | |
| 138694 | }else{ |
| 138695 | /* This call is to merge all segments at level iLevel. find the next |
| 138696 | ** available segment index at level iLevel+1. The call to |
| 138697 | ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to |
| 138698 | ** a single iLevel+2 segment if necessary. */ |
| 138699 | assert( FTS3_SEGCURSOR_PENDING==-1 ); |
| 138700 | iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, iLevel+1); |
| 138701 | rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, iLevel+1, &iIdx); |
| 138702 | bIgnoreEmpty = (iLevel!=FTS3_SEGCURSOR_PENDING) && (iNewLevel>iMaxLevel); |
| 138703 | } |
| 138704 | if( rc!=SQLITE_OK ) goto finished; |
| 138705 | |
| 138706 | assert( csr.nSegment>0 ); |
| 138707 | assert( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) ); |
| 138708 | assert( iNewLevel<getAbsoluteLevel(p, iLangid, iIndex,FTS3_SEGDIR_MAXLEVEL) ); |
| 138709 | |
| 138710 | memset(&filter, 0, sizeof(Fts3SegFilter)); |
| @@ -138054,29 +138717,36 @@ | |
| 138717 | if( rc!=SQLITE_ROW ) break; |
| 138718 | rc = fts3SegWriterAdd(p, &pWriter, 1, |
| 138719 | csr.zTerm, csr.nTerm, csr.aDoclist, csr.nDoclist); |
| 138720 | } |
| 138721 | if( rc!=SQLITE_OK ) goto finished; |
| 138722 | assert( pWriter || bIgnoreEmpty ); |
| 138723 | |
| 138724 | if( iLevel!=FTS3_SEGCURSOR_PENDING ){ |
| 138725 | rc = fts3DeleteSegdir( |
| 138726 | p, iLangid, iIndex, iLevel, csr.apSegment, csr.nSegment |
| 138727 | ); |
| 138728 | if( rc!=SQLITE_OK ) goto finished; |
| 138729 | } |
| 138730 | if( pWriter ){ |
| 138731 | rc = fts3SegWriterFlush(p, pWriter, iNewLevel, iIdx); |
| 138732 | if( rc==SQLITE_OK ){ |
| 138733 | if( iLevel==FTS3_SEGCURSOR_PENDING || iNewLevel<iMaxLevel ){ |
| 138734 | rc = fts3PromoteSegments(p, iNewLevel, pWriter->nLeafData); |
| 138735 | } |
| 138736 | } |
| 138737 | } |
| 138738 | |
| 138739 | finished: |
| 138740 | fts3SegWriterFree(pWriter); |
| 138741 | sqlite3Fts3SegReaderFinish(&csr); |
| 138742 | return rc; |
| 138743 | } |
| 138744 | |
| 138745 | |
| 138746 | /* |
| 138747 | ** Flush the contents of pendingTerms to level 0 segments. |
| 138748 | */ |
| 138749 | SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ |
| 138750 | int rc = SQLITE_OK; |
| 138751 | int i; |
| 138752 | |
| @@ -138088,18 +138758,23 @@ | |
| 138758 | |
| 138759 | /* Determine the auto-incr-merge setting if unknown. If enabled, |
| 138760 | ** estimate the number of leaf blocks of content to be written |
| 138761 | */ |
| 138762 | if( rc==SQLITE_OK && p->bHasStat |
| 138763 | && p->nAutoincrmerge==0xff && p->nLeafAdd>0 |
| 138764 | ){ |
| 138765 | sqlite3_stmt *pStmt = 0; |
| 138766 | rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); |
| 138767 | if( rc==SQLITE_OK ){ |
| 138768 | sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); |
| 138769 | rc = sqlite3_step(pStmt); |
| 138770 | if( rc==SQLITE_ROW ){ |
| 138771 | p->nAutoincrmerge = sqlite3_column_int(pStmt, 0); |
| 138772 | if( p->nAutoincrmerge==1 ) p->nAutoincrmerge = 8; |
| 138773 | }else if( rc==SQLITE_DONE ){ |
| 138774 | p->nAutoincrmerge = 0; |
| 138775 | } |
| 138776 | rc = sqlite3_reset(pStmt); |
| 138777 | } |
| 138778 | } |
| 138779 | return rc; |
| 138780 | } |
| @@ -138463,10 +139138,12 @@ | |
| 139138 | int nWork; /* Number of leaf pages flushed */ |
| 139139 | sqlite3_int64 iAbsLevel; /* Absolute level of input segments */ |
| 139140 | int iIdx; /* Index of *output* segment in iAbsLevel+1 */ |
| 139141 | sqlite3_int64 iStart; /* Block number of first allocated block */ |
| 139142 | sqlite3_int64 iEnd; /* Block number of last allocated block */ |
| 139143 | sqlite3_int64 nLeafData; /* Bytes of leaf page data so far */ |
| 139144 | u8 bNoLeafData; /* If true, store 0 for segment size */ |
| 139145 | NodeWriter aNodeWriter[FTS_MAX_APPENDABLE_HEIGHT]; |
| 139146 | }; |
| 139147 | |
| 139148 | /* |
| 139149 | ** An object of the following type is used to read data from a single |
| @@ -138801,12 +139478,12 @@ | |
| 139478 | nSpace = 1; |
| 139479 | nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; |
| 139480 | nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; |
| 139481 | } |
| 139482 | |
| 139483 | pWriter->nLeafData += nSpace; |
| 139484 | blobGrowBuffer(&pLeaf->block, pLeaf->block.n + nSpace, &rc); |
| 139485 | if( rc==SQLITE_OK ){ |
| 139486 | if( pLeaf->block.n==0 ){ |
| 139487 | pLeaf->block.n = 1; |
| 139488 | pLeaf->block.a[0] = '\0'; |
| 139489 | } |
| @@ -138901,10 +139578,11 @@ | |
| 139578 | pWriter->iAbsLevel+1, /* level */ |
| 139579 | pWriter->iIdx, /* idx */ |
| 139580 | pWriter->iStart, /* start_block */ |
| 139581 | pWriter->aNodeWriter[0].iBlock, /* leaves_end_block */ |
| 139582 | pWriter->iEnd, /* end_block */ |
| 139583 | (pWriter->bNoLeafData==0 ? pWriter->nLeafData : 0), /* end_block */ |
| 139584 | pRoot->block.a, pRoot->block.n /* root */ |
| 139585 | ); |
| 139586 | } |
| 139587 | sqlite3_free(pRoot->block.a); |
| 139588 | sqlite3_free(pRoot->key.a); |
| @@ -139002,11 +139680,15 @@ | |
| 139680 | sqlite3_bind_int64(pSelect, 1, iAbsLevel+1); |
| 139681 | sqlite3_bind_int(pSelect, 2, iIdx); |
| 139682 | if( sqlite3_step(pSelect)==SQLITE_ROW ){ |
| 139683 | iStart = sqlite3_column_int64(pSelect, 1); |
| 139684 | iLeafEnd = sqlite3_column_int64(pSelect, 2); |
| 139685 | fts3ReadEndBlockField(pSelect, 3, &iEnd, &pWriter->nLeafData); |
| 139686 | if( pWriter->nLeafData<0 ){ |
| 139687 | pWriter->nLeafData = pWriter->nLeafData * -1; |
| 139688 | } |
| 139689 | pWriter->bNoLeafData = (pWriter->nLeafData==0); |
| 139690 | nRoot = sqlite3_column_bytes(pSelect, 4); |
| 139691 | aRoot = sqlite3_column_blob(pSelect, 4); |
| 139692 | }else{ |
| 139693 | return sqlite3_reset(pSelect); |
| 139694 | } |
| @@ -139603,15 +140285,15 @@ | |
| 140285 | |
| 140286 | |
| 140287 | /* |
| 140288 | ** Attempt an incremental merge that writes nMerge leaf blocks. |
| 140289 | ** |
| 140290 | ** Incremental merges happen nMin segments at a time. The segments |
| 140291 | ** to be merged are the nMin oldest segments (the ones with the smallest |
| 140292 | ** values for the _segdir.idx field) in the highest level that contains |
| 140293 | ** at least nMin segments. Multiple merges might occur in an attempt to |
| 140294 | ** write the quota of nMerge leaf blocks. |
| 140295 | */ |
| 140296 | SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ |
| 140297 | int rc; /* Return code */ |
| 140298 | int nRem = nMerge; /* Number of leaf pages yet to be written */ |
| 140299 | Fts3MultiSegReader *pCsr; /* Cursor used to read input data */ |
| @@ -139632,10 +140314,11 @@ | |
| 140314 | rc = fts3IncrmergeHintLoad(p, &hint); |
| 140315 | while( rc==SQLITE_OK && nRem>0 ){ |
| 140316 | const i64 nMod = FTS3_SEGDIR_MAXLEVEL * p->nIndex; |
| 140317 | sqlite3_stmt *pFindLevel = 0; /* SQL used to determine iAbsLevel */ |
| 140318 | int bUseHint = 0; /* True if attempting to append */ |
| 140319 | int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */ |
| 140320 | |
| 140321 | /* Search the %_segdir table for the absolute level with the smallest |
| 140322 | ** relative level number that contains at least nMin segments, if any. |
| 140323 | ** If one is found, set iAbsLevel to the absolute level number and |
| 140324 | ** nSeg to nMin. If no level with at least nMin segments can be found, |
| @@ -139685,27 +140368,36 @@ | |
| 140368 | ** segments available in level iAbsLevel. In this case, no work is |
| 140369 | ** done on iAbsLevel - fall through to the next iteration of the loop |
| 140370 | ** to start work on some other level. */ |
| 140371 | memset(pWriter, 0, nAlloc); |
| 140372 | pFilter->flags = FTS3_SEGMENT_REQUIRE_POS; |
| 140373 | |
| 140374 | if( rc==SQLITE_OK ){ |
| 140375 | rc = fts3IncrmergeOutputIdx(p, iAbsLevel, &iIdx); |
| 140376 | assert( bUseHint==1 || bUseHint==0 ); |
| 140377 | if( iIdx==0 || (bUseHint && iIdx==1) ){ |
| 140378 | int bIgnore; |
| 140379 | rc = fts3SegmentIsMaxLevel(p, iAbsLevel+1, &bIgnore); |
| 140380 | if( bIgnore ){ |
| 140381 | pFilter->flags |= FTS3_SEGMENT_IGNORE_EMPTY; |
| 140382 | } |
| 140383 | } |
| 140384 | } |
| 140385 | |
| 140386 | if( rc==SQLITE_OK ){ |
| 140387 | rc = fts3IncrmergeCsr(p, iAbsLevel, nSeg, pCsr); |
| 140388 | } |
| 140389 | if( SQLITE_OK==rc && pCsr->nSegment==nSeg |
| 140390 | && SQLITE_OK==(rc = sqlite3Fts3SegReaderStart(p, pCsr, pFilter)) |
| 140391 | && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pCsr)) |
| 140392 | ){ |
| 140393 | if( bUseHint && iIdx>0 ){ |
| 140394 | const char *zKey = pCsr->zTerm; |
| 140395 | int nKey = pCsr->nTerm; |
| 140396 | rc = fts3IncrmergeLoad(p, iAbsLevel, iIdx-1, zKey, nKey, pWriter); |
| 140397 | }else{ |
| 140398 | rc = fts3IncrmergeWriter(p, iAbsLevel, iIdx, pCsr, pWriter); |
| 140399 | } |
| 140400 | |
| 140401 | if( rc==SQLITE_OK && pWriter->nLeafEst ){ |
| 140402 | fts3LogMerge(nSeg, iAbsLevel); |
| 140403 | do { |
| @@ -139723,11 +140415,17 @@ | |
| 140415 | fts3IncrmergeHintPush(&hint, iAbsLevel, nSeg, &rc); |
| 140416 | } |
| 140417 | } |
| 140418 | } |
| 140419 | |
| 140420 | if( nSeg!=0 ){ |
| 140421 | pWriter->nLeafData = pWriter->nLeafData * -1; |
| 140422 | } |
| 140423 | fts3IncrmergeRelease(p, pWriter, &rc); |
| 140424 | if( nSeg==0 && pWriter->bNoLeafData==0 ){ |
| 140425 | fts3PromoteSegments(p, iAbsLevel+1, pWriter->nLeafData); |
| 140426 | } |
| 140427 | } |
| 140428 | |
| 140429 | sqlite3Fts3SegReaderFinish(pCsr); |
| 140430 | } |
| 140431 | |
| @@ -139810,20 +140508,23 @@ | |
| 140508 | Fts3Table *p, /* FTS3 table handle */ |
| 140509 | const char *zParam /* Nul-terminated string containing boolean */ |
| 140510 | ){ |
| 140511 | int rc = SQLITE_OK; |
| 140512 | sqlite3_stmt *pStmt = 0; |
| 140513 | p->nAutoincrmerge = fts3Getint(&zParam); |
| 140514 | if( p->nAutoincrmerge==1 || p->nAutoincrmerge>FTS3_MERGE_COUNT ){ |
| 140515 | p->nAutoincrmerge = 8; |
| 140516 | } |
| 140517 | if( !p->bHasStat ){ |
| 140518 | assert( p->bFts4==0 ); |
| 140519 | sqlite3Fts3CreateStatTable(&rc, p); |
| 140520 | if( rc ) return rc; |
| 140521 | } |
| 140522 | rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); |
| 140523 | if( rc ) return rc; |
| 140524 | sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); |
| 140525 | sqlite3_bind_int(pStmt, 2, p->nAutoincrmerge); |
| 140526 | sqlite3_step(pStmt); |
| 140527 | rc = sqlite3_reset(pStmt); |
| 140528 | return rc; |
| 140529 | } |
| 140530 | |
| @@ -142802,64 +143503,24 @@ | |
| 143503 | ** child page. |
| 143504 | */ |
| 143505 | |
| 143506 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) |
| 143507 | |
| 143508 | #ifndef SQLITE_CORE |
| 143509 | SQLITE_EXTENSION_INIT1 |
| 143510 | #else |
| 143511 | #endif |
| 143512 | |
| 143513 | /* #include <string.h> */ |
| 143514 | /* #include <assert.h> */ |
| 143515 | /* #include <stdio.h> */ |
| 143516 | |
| 143517 | #ifndef SQLITE_AMALGAMATION |
| 143518 | #include "sqlite3rtree.h" |
| 143519 | typedef sqlite3_int64 i64; |
| 143520 | typedef unsigned char u8; |
| 143521 | typedef unsigned short u16; |
| 143522 | typedef unsigned int u32; |
| 143523 | #endif |
| 143524 | |
| 143525 | /* The following macro is used to suppress compiler warnings. |
| 143526 | */ |
| @@ -142873,19 +143534,20 @@ | |
| 143534 | typedef struct RtreeCell RtreeCell; |
| 143535 | typedef struct RtreeConstraint RtreeConstraint; |
| 143536 | typedef struct RtreeMatchArg RtreeMatchArg; |
| 143537 | typedef struct RtreeGeomCallback RtreeGeomCallback; |
| 143538 | typedef union RtreeCoord RtreeCoord; |
| 143539 | typedef struct RtreeSearchPoint RtreeSearchPoint; |
| 143540 | |
| 143541 | /* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */ |
| 143542 | #define RTREE_MAX_DIMENSIONS 5 |
| 143543 | |
| 143544 | /* Size of hash table Rtree.aHash. This hash table is not expected to |
| 143545 | ** ever contain very many entries, so a fixed number of buckets is |
| 143546 | ** used. |
| 143547 | */ |
| 143548 | #define HASHSIZE 97 |
| 143549 | |
| 143550 | /* The xBestIndex method of this virtual table requires an estimate of |
| 143551 | ** the number of rows in the virtual table to calculate the costs of |
| 143552 | ** various strategies. If possible, this estimate is loaded from the |
| 143553 | ** sqlite_stat1 table (with RTREE_MIN_ROWEST as a hard-coded minimum). |
| @@ -142897,19 +143559,19 @@ | |
| 143559 | |
| 143560 | /* |
| 143561 | ** An rtree virtual-table object. |
| 143562 | */ |
| 143563 | struct Rtree { |
| 143564 | sqlite3_vtab base; /* Base class. Must be first */ |
| 143565 | sqlite3 *db; /* Host database connection */ |
| 143566 | int iNodeSize; /* Size in bytes of each node in the node table */ |
| 143567 | u8 nDim; /* Number of dimensions */ |
| 143568 | u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ |
| 143569 | u8 nBytesPerCell; /* Bytes consumed per cell */ |
| 143570 | int iDepth; /* Current depth of the r-tree structure */ |
| 143571 | char *zDb; /* Name of database containing r-tree table */ |
| 143572 | char *zName; /* Name of r-tree table */ |
| 143573 | int nBusy; /* Current number of users of this structure */ |
| 143574 | i64 nRowEst; /* Estimated number of rows in this table */ |
| 143575 | |
| 143576 | /* List of nodes removed during a CondenseTree operation. List is |
| 143577 | ** linked together via the pointer normally used for hash chains - |
| @@ -142932,14 +143594,14 @@ | |
| 143594 | /* Statements to read/write/delete a record from xxx_parent */ |
| 143595 | sqlite3_stmt *pReadParent; |
| 143596 | sqlite3_stmt *pWriteParent; |
| 143597 | sqlite3_stmt *pDeleteParent; |
| 143598 | |
| 143599 | RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ |
| 143600 | }; |
| 143601 | |
| 143602 | /* Possible values for Rtree.eCoordType: */ |
| 143603 | #define RTREE_COORD_REAL32 0 |
| 143604 | #define RTREE_COORD_INT32 1 |
| 143605 | |
| 143606 | /* |
| 143607 | ** If SQLITE_RTREE_INT_ONLY is defined, then this virtual table will |
| @@ -142947,14 +143609,33 @@ | |
| 143609 | ** will be done. |
| 143610 | */ |
| 143611 | #ifdef SQLITE_RTREE_INT_ONLY |
| 143612 | typedef sqlite3_int64 RtreeDValue; /* High accuracy coordinate */ |
| 143613 | typedef int RtreeValue; /* Low accuracy coordinate */ |
| 143614 | # define RTREE_ZERO 0 |
| 143615 | #else |
| 143616 | typedef double RtreeDValue; /* High accuracy coordinate */ |
| 143617 | typedef float RtreeValue; /* Low accuracy coordinate */ |
| 143618 | # define RTREE_ZERO 0.0 |
| 143619 | #endif |
| 143620 | |
| 143621 | /* |
| 143622 | ** When doing a search of an r-tree, instances of the following structure |
| 143623 | ** record intermediate results from the tree walk. |
| 143624 | ** |
| 143625 | ** The id is always a node-id. For iLevel>=1 the id is the node-id of |
| 143626 | ** the node that the RtreeSearchPoint represents. When iLevel==0, however, |
| 143627 | ** the id is of the parent node and the cell that RtreeSearchPoint |
| 143628 | ** represents is the iCell-th entry in the parent node. |
| 143629 | */ |
| 143630 | struct RtreeSearchPoint { |
| 143631 | RtreeDValue rScore; /* The score for this node. Smallest goes first. */ |
| 143632 | sqlite3_int64 id; /* Node ID */ |
| 143633 | u8 iLevel; /* 0=entries. 1=leaf node. 2+ for higher */ |
| 143634 | u8 eWithin; /* PARTLY_WITHIN or FULLY_WITHIN */ |
| 143635 | u8 iCell; /* Cell index within the node */ |
| 143636 | }; |
| 143637 | |
| 143638 | /* |
| 143639 | ** The minimum number of cells allowed for a node is a third of the |
| 143640 | ** maximum. In Gutman's notation: |
| 143641 | ** |
| @@ -142974,25 +143655,48 @@ | |
| 143655 | ** 2^40 is greater than 2^64, an r-tree structure always has a depth of |
| 143656 | ** 40 or less. |
| 143657 | */ |
| 143658 | #define RTREE_MAX_DEPTH 40 |
| 143659 | |
| 143660 | |
| 143661 | /* |
| 143662 | ** Number of entries in the cursor RtreeNode cache. The first entry is |
| 143663 | ** used to cache the RtreeNode for RtreeCursor.sPoint. The remaining |
| 143664 | ** entries cache the RtreeNode for the first elements of the priority queue. |
| 143665 | */ |
| 143666 | #define RTREE_CACHE_SZ 5 |
| 143667 | |
| 143668 | /* |
| 143669 | ** An rtree cursor object. |
| 143670 | */ |
| 143671 | struct RtreeCursor { |
| 143672 | sqlite3_vtab_cursor base; /* Base class. Must be first */ |
| 143673 | u8 atEOF; /* True if at end of search */ |
| 143674 | u8 bPoint; /* True if sPoint is valid */ |
| 143675 | int iStrategy; /* Copy of idxNum search parameter */ |
| 143676 | int nConstraint; /* Number of entries in aConstraint */ |
| 143677 | RtreeConstraint *aConstraint; /* Search constraints. */ |
| 143678 | int nPointAlloc; /* Number of slots allocated for aPoint[] */ |
| 143679 | int nPoint; /* Number of slots used in aPoint[] */ |
| 143680 | int mxLevel; /* iLevel value for root of the tree */ |
| 143681 | RtreeSearchPoint *aPoint; /* Priority queue for search points */ |
| 143682 | RtreeSearchPoint sPoint; /* Cached next search point */ |
| 143683 | RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */ |
| 143684 | u32 anQueue[RTREE_MAX_DEPTH+1]; /* Number of queued entries by iLevel */ |
| 143685 | }; |
| 143686 | |
| 143687 | /* Return the Rtree of a RtreeCursor */ |
| 143688 | #define RTREE_OF_CURSOR(X) ((Rtree*)((X)->base.pVtab)) |
| 143689 | |
| 143690 | /* |
| 143691 | ** A coordinate can be either a floating point number or a integer. All |
| 143692 | ** coordinates within a single R-Tree are always of the same time. |
| 143693 | */ |
| 143694 | union RtreeCoord { |
| 143695 | RtreeValue f; /* Floating point value */ |
| 143696 | int i; /* Integer value */ |
| 143697 | u32 u; /* Unsigned for byte-order conversions */ |
| 143698 | }; |
| 143699 | |
| 143700 | /* |
| 143701 | ** The argument is an RtreeCoord. Return the value stored within the RtreeCoord |
| 143702 | ** formatted as a RtreeDValue (double or int64). This macro assumes that local |
| @@ -143013,42 +143717,71 @@ | |
| 143717 | ** A search constraint. |
| 143718 | */ |
| 143719 | struct RtreeConstraint { |
| 143720 | int iCoord; /* Index of constrained coordinate */ |
| 143721 | int op; /* Constraining operation */ |
| 143722 | union { |
| 143723 | RtreeDValue rValue; /* Constraint value. */ |
| 143724 | int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*); |
| 143725 | int (*xQueryFunc)(sqlite3_rtree_query_info*); |
| 143726 | } u; |
| 143727 | sqlite3_rtree_query_info *pInfo; /* xGeom and xQueryFunc argument */ |
| 143728 | }; |
| 143729 | |
| 143730 | /* Possible values for RtreeConstraint.op */ |
| 143731 | #define RTREE_EQ 0x41 /* A */ |
| 143732 | #define RTREE_LE 0x42 /* B */ |
| 143733 | #define RTREE_LT 0x43 /* C */ |
| 143734 | #define RTREE_GE 0x44 /* D */ |
| 143735 | #define RTREE_GT 0x45 /* E */ |
| 143736 | #define RTREE_MATCH 0x46 /* F: Old-style sqlite3_rtree_geometry_callback() */ |
| 143737 | #define RTREE_QUERY 0x47 /* G: New-style sqlite3_rtree_query_callback() */ |
| 143738 | |
| 143739 | |
| 143740 | /* |
| 143741 | ** An rtree structure node. |
| 143742 | */ |
| 143743 | struct RtreeNode { |
| 143744 | RtreeNode *pParent; /* Parent node */ |
| 143745 | i64 iNode; /* The node number */ |
| 143746 | int nRef; /* Number of references to this node */ |
| 143747 | int isDirty; /* True if the node needs to be written to disk */ |
| 143748 | u8 *zData; /* Content of the node, as should be on disk */ |
| 143749 | RtreeNode *pNext; /* Next node in this hash collision chain */ |
| 143750 | }; |
| 143751 | |
| 143752 | /* Return the number of cells in a node */ |
| 143753 | #define NCELL(pNode) readInt16(&(pNode)->zData[2]) |
| 143754 | |
| 143755 | /* |
| 143756 | ** A single cell from a node, deserialized |
| 143757 | */ |
| 143758 | struct RtreeCell { |
| 143759 | i64 iRowid; /* Node or entry ID */ |
| 143760 | RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; /* Bounding box coordinates */ |
| 143761 | }; |
| 143762 | |
| 143763 | |
| 143764 | /* |
| 143765 | ** This object becomes the sqlite3_user_data() for the SQL functions |
| 143766 | ** that are created by sqlite3_rtree_geometry_callback() and |
| 143767 | ** sqlite3_rtree_query_callback() and which appear on the right of MATCH |
| 143768 | ** operators in order to constrain a search. |
| 143769 | ** |
| 143770 | ** xGeom and xQueryFunc are the callback functions. Exactly one of |
| 143771 | ** xGeom and xQueryFunc fields is non-NULL, depending on whether the |
| 143772 | ** SQL function was created using sqlite3_rtree_geometry_callback() or |
| 143773 | ** sqlite3_rtree_query_callback(). |
| 143774 | ** |
| 143775 | ** This object is deleted automatically by the destructor mechanism in |
| 143776 | ** sqlite3_create_function_v2(). |
| 143777 | */ |
| 143778 | struct RtreeGeomCallback { |
| 143779 | int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); |
| 143780 | int (*xQueryFunc)(sqlite3_rtree_query_info*); |
| 143781 | void (*xDestructor)(void*); |
| 143782 | void *pContext; |
| 143783 | }; |
| 143784 | |
| 143785 | |
| 143786 | /* |
| 143787 | ** Value for the first field of every RtreeMatchArg object. The MATCH |
| @@ -143056,33 +143789,20 @@ | |
| 143789 | ** value to avoid operating on invalid blobs (which could cause a segfault). |
| 143790 | */ |
| 143791 | #define RTREE_GEOMETRY_MAGIC 0x891245AB |
| 143792 | |
| 143793 | /* |
| 143794 | ** An instance of this structure (in the form of a BLOB) is returned by |
| 143795 | ** the SQL functions that sqlite3_rtree_geometry_callback() and |
| 143796 | ** sqlite3_rtree_query_callback() create, and is read as the right-hand |
| 143797 | ** operand to the MATCH operator of an R-Tree. |
| 143798 | */ |
| 143799 | struct RtreeMatchArg { |
| 143800 | u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ |
| 143801 | RtreeGeomCallback cb; /* Info about the callback functions */ |
| 143802 | int nParam; /* Number of parameters to the SQL function */ |
| 143803 | RtreeDValue aParam[1]; /* Values for parameters to the SQL function */ |
| 143804 | }; |
| 143805 | |
| 143806 | #ifndef MAX |
| 143807 | # define MAX(x,y) ((x) < (y) ? (y) : (x)) |
| 143808 | #endif |
| @@ -143172,14 +143892,11 @@ | |
| 143892 | /* |
| 143893 | ** Given a node number iNode, return the corresponding key to use |
| 143894 | ** in the Rtree.aHash table. |
| 143895 | */ |
| 143896 | static int nodeHash(i64 iNode){ |
| 143897 | return iNode % HASHSIZE; |
| 143898 | } |
| 143899 | |
| 143900 | /* |
| 143901 | ** Search the node hash table for node iNode. If found, return a pointer |
| 143902 | ** to it. Otherwise, return 0. |
| @@ -143235,12 +143952,11 @@ | |
| 143952 | } |
| 143953 | |
| 143954 | /* |
| 143955 | ** Obtain a reference to an r-tree node. |
| 143956 | */ |
| 143957 | static int nodeAcquire( |
| 143958 | Rtree *pRtree, /* R-tree structure */ |
| 143959 | i64 iNode, /* Node number to load */ |
| 143960 | RtreeNode *pParent, /* Either the parent node or NULL */ |
| 143961 | RtreeNode **ppNode /* OUT: Acquired node */ |
| 143962 | ){ |
| @@ -143325,14 +144041,14 @@ | |
| 144041 | |
| 144042 | /* |
| 144043 | ** Overwrite cell iCell of node pNode with the contents of pCell. |
| 144044 | */ |
| 144045 | static void nodeOverwriteCell( |
| 144046 | Rtree *pRtree, /* The overall R-Tree */ |
| 144047 | RtreeNode *pNode, /* The node into which the cell is to be written */ |
| 144048 | RtreeCell *pCell, /* The cell to write */ |
| 144049 | int iCell /* Index into pNode into which pCell is written */ |
| 144050 | ){ |
| 144051 | int ii; |
| 144052 | u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; |
| 144053 | p += writeInt64(p, pCell->iRowid); |
| 144054 | for(ii=0; ii<(pRtree->nDim*2); ii++){ |
| @@ -143340,11 +144056,11 @@ | |
| 144056 | } |
| 144057 | pNode->isDirty = 1; |
| 144058 | } |
| 144059 | |
| 144060 | /* |
| 144061 | ** Remove the cell with index iCell from node pNode. |
| 144062 | */ |
| 144063 | static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){ |
| 144064 | u8 *pDst = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; |
| 144065 | u8 *pSrc = &pDst[pRtree->nBytesPerCell]; |
| 144066 | int nByte = (NCELL(pNode) - iCell - 1) * pRtree->nBytesPerCell; |
| @@ -143357,15 +144073,14 @@ | |
| 144073 | ** Insert the contents of cell pCell into node pNode. If the insert |
| 144074 | ** is successful, return SQLITE_OK. |
| 144075 | ** |
| 144076 | ** If there is not enough free space in pNode, return SQLITE_FULL. |
| 144077 | */ |
| 144078 | static int nodeInsertCell( |
| 144079 | Rtree *pRtree, /* The overall R-Tree */ |
| 144080 | RtreeNode *pNode, /* Write new cell into this node */ |
| 144081 | RtreeCell *pCell /* The cell to be inserted */ |
| 144082 | ){ |
| 144083 | int nCell; /* Current number of cells in pNode */ |
| 144084 | int nMaxCell; /* Maximum number of cells for pNode */ |
| 144085 | |
| 144086 | nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell; |
| @@ -143382,12 +144097,11 @@ | |
| 144097 | } |
| 144098 | |
| 144099 | /* |
| 144100 | ** If the node is dirty, write it out to the database. |
| 144101 | */ |
| 144102 | static int nodeWrite(Rtree *pRtree, RtreeNode *pNode){ |
| 144103 | int rc = SQLITE_OK; |
| 144104 | if( pNode->isDirty ){ |
| 144105 | sqlite3_stmt *p = pRtree->pWriteNode; |
| 144106 | if( pNode->iNode ){ |
| 144107 | sqlite3_bind_int64(p, 1, pNode->iNode); |
| @@ -143408,12 +144122,11 @@ | |
| 144122 | |
| 144123 | /* |
| 144124 | ** Release a reference to a node. If the node is dirty and the reference |
| 144125 | ** count drops to zero, the node data is written to the database. |
| 144126 | */ |
| 144127 | static int nodeRelease(Rtree *pRtree, RtreeNode *pNode){ |
| 144128 | int rc = SQLITE_OK; |
| 144129 | if( pNode ){ |
| 144130 | assert( pNode->nRef>0 ); |
| 144131 | pNode->nRef--; |
| 144132 | if( pNode->nRef==0 ){ |
| @@ -143437,45 +144150,50 @@ | |
| 144150 | ** Return the 64-bit integer value associated with cell iCell of |
| 144151 | ** node pNode. If pNode is a leaf node, this is a rowid. If it is |
| 144152 | ** an internal node, then the 64-bit integer is a child page number. |
| 144153 | */ |
| 144154 | static i64 nodeGetRowid( |
| 144155 | Rtree *pRtree, /* The overall R-Tree */ |
| 144156 | RtreeNode *pNode, /* The node from which to extract the ID */ |
| 144157 | int iCell /* The cell index from which to extract the ID */ |
| 144158 | ){ |
| 144159 | assert( iCell<NCELL(pNode) ); |
| 144160 | return readInt64(&pNode->zData[4 + pRtree->nBytesPerCell*iCell]); |
| 144161 | } |
| 144162 | |
| 144163 | /* |
| 144164 | ** Return coordinate iCoord from cell iCell in node pNode. |
| 144165 | */ |
| 144166 | static void nodeGetCoord( |
| 144167 | Rtree *pRtree, /* The overall R-Tree */ |
| 144168 | RtreeNode *pNode, /* The node from which to extract a coordinate */ |
| 144169 | int iCell, /* The index of the cell within the node */ |
| 144170 | int iCoord, /* Which coordinate to extract */ |
| 144171 | RtreeCoord *pCoord /* OUT: Space to write result to */ |
| 144172 | ){ |
| 144173 | readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord); |
| 144174 | } |
| 144175 | |
| 144176 | /* |
| 144177 | ** Deserialize cell iCell of node pNode. Populate the structure pointed |
| 144178 | ** to by pCell with the results. |
| 144179 | */ |
| 144180 | static void nodeGetCell( |
| 144181 | Rtree *pRtree, /* The overall R-Tree */ |
| 144182 | RtreeNode *pNode, /* The node containing the cell to be read */ |
| 144183 | int iCell, /* Index of the cell within the node */ |
| 144184 | RtreeCell *pCell /* OUT: Write the cell contents here */ |
| 144185 | ){ |
| 144186 | u8 *pData; |
| 144187 | u8 *pEnd; |
| 144188 | RtreeCoord *pCoord; |
| 144189 | pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); |
| 144190 | pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell); |
| 144191 | pEnd = pData + pRtree->nDim*8; |
| 144192 | pCoord = pCell->aCoord; |
| 144193 | for(; pData<pEnd; pData+=4, pCoord++){ |
| 144194 | readCoord(pData, pCoord); |
| 144195 | } |
| 144196 | } |
| 144197 | |
| 144198 | |
| 144199 | /* Forward declaration for the function that does the work of |
| @@ -143597,14 +144315,14 @@ | |
| 144315 | */ |
| 144316 | static void freeCursorConstraints(RtreeCursor *pCsr){ |
| 144317 | if( pCsr->aConstraint ){ |
| 144318 | int i; /* Used to iterate through constraint array */ |
| 144319 | for(i=0; i<pCsr->nConstraint; i++){ |
| 144320 | sqlite3_rtree_query_info *pInfo = pCsr->aConstraint[i].pInfo; |
| 144321 | if( pInfo ){ |
| 144322 | if( pInfo->xDelUser ) pInfo->xDelUser(pInfo->pUser); |
| 144323 | sqlite3_free(pInfo); |
| 144324 | } |
| 144325 | } |
| 144326 | sqlite3_free(pCsr->aConstraint); |
| 144327 | pCsr->aConstraint = 0; |
| 144328 | } |
| @@ -143613,16 +144331,17 @@ | |
| 144331 | /* |
| 144332 | ** Rtree virtual table module xClose method. |
| 144333 | */ |
| 144334 | static int rtreeClose(sqlite3_vtab_cursor *cur){ |
| 144335 | Rtree *pRtree = (Rtree *)(cur->pVtab); |
| 144336 | int ii; |
| 144337 | RtreeCursor *pCsr = (RtreeCursor *)cur; |
| 144338 | freeCursorConstraints(pCsr); |
| 144339 | sqlite3_free(pCsr->aPoint); |
| 144340 | for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]); |
| 144341 | sqlite3_free(pCsr); |
| 144342 | return SQLITE_OK; |
| 144343 | } |
| 144344 | |
| 144345 | /* |
| 144346 | ** Rtree virtual table module xEof method. |
| 144347 | ** |
| @@ -143629,198 +144348,168 @@ | |
| 144348 | ** Return non-zero if the cursor does not currently point to a valid |
| 144349 | ** record (i.e if the scan has finished), or zero otherwise. |
| 144350 | */ |
| 144351 | static int rtreeEof(sqlite3_vtab_cursor *cur){ |
| 144352 | RtreeCursor *pCsr = (RtreeCursor *)cur; |
| 144353 | return pCsr->atEOF; |
| 144354 | } |
| 144355 | |
| 144356 | /* |
| 144357 | ** Convert raw bits from the on-disk RTree record into a coordinate value. |
| 144358 | ** The on-disk format is big-endian and needs to be converted for little- |
| 144359 | ** endian platforms. The on-disk record stores integer coordinates if |
| 144360 | ** eInt is true and it stores 32-bit floating point records if eInt is |
| 144361 | ** false. a[] is the four bytes of the on-disk record to be decoded. |
| 144362 | ** Store the results in "r". |
| 144363 | ** |
| 144364 | ** There are three versions of this macro, one each for little-endian and |
| 144365 | ** big-endian processors and a third generic implementation. The endian- |
| 144366 | ** specific implementations are much faster and are preferred if the |
| 144367 | ** processor endianness is known at compile-time. The SQLITE_BYTEORDER |
| 144368 | ** macro is part of sqliteInt.h and hence the endian-specific |
| 144369 | ** implementation will only be used if this module is compiled as part |
| 144370 | ** of the amalgamation. |
| 144371 | */ |
| 144372 | #if defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==1234 |
| 144373 | #define RTREE_DECODE_COORD(eInt, a, r) { \ |
| 144374 | RtreeCoord c; /* Coordinate decoded */ \ |
| 144375 | memcpy(&c.u,a,4); \ |
| 144376 | c.u = ((c.u>>24)&0xff)|((c.u>>8)&0xff00)| \ |
| 144377 | ((c.u&0xff)<<24)|((c.u&0xff00)<<8); \ |
| 144378 | r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ |
| 144379 | } |
| 144380 | #elif defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==4321 |
| 144381 | #define RTREE_DECODE_COORD(eInt, a, r) { \ |
| 144382 | RtreeCoord c; /* Coordinate decoded */ \ |
| 144383 | memcpy(&c.u,a,4); \ |
| 144384 | r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ |
| 144385 | } |
| 144386 | #else |
| 144387 | #define RTREE_DECODE_COORD(eInt, a, r) { \ |
| 144388 | RtreeCoord c; /* Coordinate decoded */ \ |
| 144389 | c.u = ((u32)a[0]<<24) + ((u32)a[1]<<16) \ |
| 144390 | +((u32)a[2]<<8) + a[3]; \ |
| 144391 | r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ |
| 144392 | } |
| 144393 | #endif |
| 144394 | |
| 144395 | /* |
| 144396 | ** Check the RTree node or entry given by pCellData and p against the MATCH |
| 144397 | ** constraint pConstraint. |
| 144398 | */ |
| 144399 | static int rtreeCallbackConstraint( |
| 144400 | RtreeConstraint *pConstraint, /* The constraint to test */ |
| 144401 | int eInt, /* True if RTree holding integer coordinates */ |
| 144402 | u8 *pCellData, /* Raw cell content */ |
| 144403 | RtreeSearchPoint *pSearch, /* Container of this cell */ |
| 144404 | sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */ |
| 144405 | int *peWithin /* OUT: visibility of the cell */ |
| 144406 | ){ |
| 144407 | int i; /* Loop counter */ |
| 144408 | sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */ |
| 144409 | int nCoord = pInfo->nCoord; /* No. of coordinates */ |
| 144410 | int rc; /* Callback return code */ |
| 144411 | sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */ |
| 144412 | |
| 144413 | assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY ); |
| 144414 | assert( nCoord==2 || nCoord==4 || nCoord==6 || nCoord==8 || nCoord==10 ); |
| 144415 | |
| 144416 | if( pConstraint->op==RTREE_QUERY && pSearch->iLevel==1 ){ |
| 144417 | pInfo->iRowid = readInt64(pCellData); |
| 144418 | } |
| 144419 | pCellData += 8; |
| 144420 | for(i=0; i<nCoord; i++, pCellData += 4){ |
| 144421 | RTREE_DECODE_COORD(eInt, pCellData, aCoord[i]); |
| 144422 | } |
| 144423 | if( pConstraint->op==RTREE_MATCH ){ |
| 144424 | rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo, |
| 144425 | nCoord, aCoord, &i); |
| 144426 | if( i==0 ) *peWithin = NOT_WITHIN; |
| 144427 | *prScore = RTREE_ZERO; |
| 144428 | }else{ |
| 144429 | pInfo->aCoord = aCoord; |
| 144430 | pInfo->iLevel = pSearch->iLevel - 1; |
| 144431 | pInfo->rScore = pInfo->rParentScore = pSearch->rScore; |
| 144432 | pInfo->eWithin = pInfo->eParentWithin = pSearch->eWithin; |
| 144433 | rc = pConstraint->u.xQueryFunc(pInfo); |
| 144434 | if( pInfo->eWithin<*peWithin ) *peWithin = pInfo->eWithin; |
| 144435 | if( pInfo->rScore<*prScore || *prScore<RTREE_ZERO ){ |
| 144436 | *prScore = pInfo->rScore; |
| 144437 | } |
| 144438 | } |
| 144439 | return rc; |
| 144440 | } |
| 144441 | |
| 144442 | /* |
| 144443 | ** Check the internal RTree node given by pCellData against constraint p. |
| 144444 | ** If this constraint cannot be satisfied by any child within the node, |
| 144445 | ** set *peWithin to NOT_WITHIN. |
| 144446 | */ |
| 144447 | static void rtreeNonleafConstraint( |
| 144448 | RtreeConstraint *p, /* The constraint to test */ |
| 144449 | int eInt, /* True if RTree holds integer coordinates */ |
| 144450 | u8 *pCellData, /* Raw cell content as appears on disk */ |
| 144451 | int *peWithin /* Adjust downward, as appropriate */ |
| 144452 | ){ |
| 144453 | sqlite3_rtree_dbl val; /* Coordinate value convert to a double */ |
| 144454 | |
| 144455 | /* p->iCoord might point to either a lower or upper bound coordinate |
| 144456 | ** in a coordinate pair. But make pCellData point to the lower bound. |
| 144457 | */ |
| 144458 | pCellData += 8 + 4*(p->iCoord&0xfe); |
| 144459 | |
| 144460 | assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE |
| 144461 | || p->op==RTREE_GT || p->op==RTREE_EQ ); |
| 144462 | switch( p->op ){ |
| 144463 | case RTREE_LE: |
| 144464 | case RTREE_LT: |
| 144465 | case RTREE_EQ: |
| 144466 | RTREE_DECODE_COORD(eInt, pCellData, val); |
| 144467 | /* val now holds the lower bound of the coordinate pair */ |
| 144468 | if( p->u.rValue>=val ) return; |
| 144469 | if( p->op!=RTREE_EQ ) break; /* RTREE_LE and RTREE_LT end here */ |
| 144470 | /* Fall through for the RTREE_EQ case */ |
| 144471 | |
| 144472 | default: /* RTREE_GT or RTREE_GE, or fallthrough of RTREE_EQ */ |
| 144473 | pCellData += 4; |
| 144474 | RTREE_DECODE_COORD(eInt, pCellData, val); |
| 144475 | /* val now holds the upper bound of the coordinate pair */ |
| 144476 | if( p->u.rValue<=val ) return; |
| 144477 | } |
| 144478 | *peWithin = NOT_WITHIN; |
| 144479 | } |
| 144480 | |
| 144481 | /* |
| 144482 | ** Check the leaf RTree cell given by pCellData against constraint p. |
| 144483 | ** If this constraint is not satisfied, set *peWithin to NOT_WITHIN. |
| 144484 | ** If the constraint is satisfied, leave *peWithin unchanged. |
| 144485 | ** |
| 144486 | ** The constraint is of the form: xN op $val |
| 144487 | ** |
| 144488 | ** The op is given by p->op. The xN is p->iCoord-th coordinate in |
| 144489 | ** pCellData. $val is given by p->u.rValue. |
| 144490 | */ |
| 144491 | static void rtreeLeafConstraint( |
| 144492 | RtreeConstraint *p, /* The constraint to test */ |
| 144493 | int eInt, /* True if RTree holds integer coordinates */ |
| 144494 | u8 *pCellData, /* Raw cell content as appears on disk */ |
| 144495 | int *peWithin /* Adjust downward, as appropriate */ |
| 144496 | ){ |
| 144497 | RtreeDValue xN; /* Coordinate value converted to a double */ |
| 144498 | |
| 144499 | assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE |
| 144500 | || p->op==RTREE_GT || p->op==RTREE_EQ ); |
| 144501 | pCellData += 8 + p->iCoord*4; |
| 144502 | RTREE_DECODE_COORD(eInt, pCellData, xN); |
| 144503 | switch( p->op ){ |
| 144504 | case RTREE_LE: if( xN <= p->u.rValue ) return; break; |
| 144505 | case RTREE_LT: if( xN < p->u.rValue ) return; break; |
| 144506 | case RTREE_GE: if( xN >= p->u.rValue ) return; break; |
| 144507 | case RTREE_GT: if( xN > p->u.rValue ) return; break; |
| 144508 | default: if( xN == p->u.rValue ) return; break; |
| 144509 | } |
| 144510 | *peWithin = NOT_WITHIN; |
| 144511 | } |
| 144512 | |
| 144513 | /* |
| 144514 | ** One of the cells in node pNode is guaranteed to have a 64-bit |
| 144515 | ** integer value equal to iRowid. Return the index of this cell. |
| @@ -143831,10 +144520,11 @@ | |
| 144520 | i64 iRowid, |
| 144521 | int *piIndex |
| 144522 | ){ |
| 144523 | int ii; |
| 144524 | int nCell = NCELL(pNode); |
| 144525 | assert( nCell<200 ); |
| 144526 | for(ii=0; ii<nCell; ii++){ |
| 144527 | if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){ |
| 144528 | *piIndex = ii; |
| 144529 | return SQLITE_OK; |
| 144530 | } |
| @@ -143852,82 +144542,342 @@ | |
| 144542 | return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex); |
| 144543 | } |
| 144544 | *piIndex = -1; |
| 144545 | return SQLITE_OK; |
| 144546 | } |
| 144547 | |
| 144548 | /* |
| 144549 | ** Compare two search points. Return negative, zero, or positive if the first |
| 144550 | ** is less than, equal to, or greater than the second. |
| 144551 | ** |
| 144552 | ** The rScore is the primary key. Smaller rScore values come first. |
| 144553 | ** If the rScore is a tie, then use iLevel as the tie breaker with smaller |
| 144554 | ** iLevel values coming first. In this way, if rScore is the same for all |
| 144555 | ** SearchPoints, then iLevel becomes the deciding factor and the result |
| 144556 | ** is a depth-first search, which is the desired default behavior. |
| 144557 | */ |
| 144558 | static int rtreeSearchPointCompare( |
| 144559 | const RtreeSearchPoint *pA, |
| 144560 | const RtreeSearchPoint *pB |
| 144561 | ){ |
| 144562 | if( pA->rScore<pB->rScore ) return -1; |
| 144563 | if( pA->rScore>pB->rScore ) return +1; |
| 144564 | if( pA->iLevel<pB->iLevel ) return -1; |
| 144565 | if( pA->iLevel>pB->iLevel ) return +1; |
| 144566 | return 0; |
| 144567 | } |
| 144568 | |
| 144569 | /* |
| 144570 | ** Interchange to search points in a cursor. |
| 144571 | */ |
| 144572 | static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){ |
| 144573 | RtreeSearchPoint t = p->aPoint[i]; |
| 144574 | assert( i<j ); |
| 144575 | p->aPoint[i] = p->aPoint[j]; |
| 144576 | p->aPoint[j] = t; |
| 144577 | i++; j++; |
| 144578 | if( i<RTREE_CACHE_SZ ){ |
| 144579 | if( j>=RTREE_CACHE_SZ ){ |
| 144580 | nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); |
| 144581 | p->aNode[i] = 0; |
| 144582 | }else{ |
| 144583 | RtreeNode *pTemp = p->aNode[i]; |
| 144584 | p->aNode[i] = p->aNode[j]; |
| 144585 | p->aNode[j] = pTemp; |
| 144586 | } |
| 144587 | } |
| 144588 | } |
| 144589 | |
| 144590 | /* |
| 144591 | ** Return the search point with the lowest current score. |
| 144592 | */ |
| 144593 | static RtreeSearchPoint *rtreeSearchPointFirst(RtreeCursor *pCur){ |
| 144594 | return pCur->bPoint ? &pCur->sPoint : pCur->nPoint ? pCur->aPoint : 0; |
| 144595 | } |
| 144596 | |
| 144597 | /* |
| 144598 | ** Get the RtreeNode for the search point with the lowest score. |
| 144599 | */ |
| 144600 | static RtreeNode *rtreeNodeOfFirstSearchPoint(RtreeCursor *pCur, int *pRC){ |
| 144601 | sqlite3_int64 id; |
| 144602 | int ii = 1 - pCur->bPoint; |
| 144603 | assert( ii==0 || ii==1 ); |
| 144604 | assert( pCur->bPoint || pCur->nPoint ); |
| 144605 | if( pCur->aNode[ii]==0 ){ |
| 144606 | assert( pRC!=0 ); |
| 144607 | id = ii ? pCur->aPoint[0].id : pCur->sPoint.id; |
| 144608 | *pRC = nodeAcquire(RTREE_OF_CURSOR(pCur), id, 0, &pCur->aNode[ii]); |
| 144609 | } |
| 144610 | return pCur->aNode[ii]; |
| 144611 | } |
| 144612 | |
| 144613 | /* |
| 144614 | ** Push a new element onto the priority queue |
| 144615 | */ |
| 144616 | static RtreeSearchPoint *rtreeEnqueue( |
| 144617 | RtreeCursor *pCur, /* The cursor */ |
| 144618 | RtreeDValue rScore, /* Score for the new search point */ |
| 144619 | u8 iLevel /* Level for the new search point */ |
| 144620 | ){ |
| 144621 | int i, j; |
| 144622 | RtreeSearchPoint *pNew; |
| 144623 | if( pCur->nPoint>=pCur->nPointAlloc ){ |
| 144624 | int nNew = pCur->nPointAlloc*2 + 8; |
| 144625 | pNew = sqlite3_realloc(pCur->aPoint, nNew*sizeof(pCur->aPoint[0])); |
| 144626 | if( pNew==0 ) return 0; |
| 144627 | pCur->aPoint = pNew; |
| 144628 | pCur->nPointAlloc = nNew; |
| 144629 | } |
| 144630 | i = pCur->nPoint++; |
| 144631 | pNew = pCur->aPoint + i; |
| 144632 | pNew->rScore = rScore; |
| 144633 | pNew->iLevel = iLevel; |
| 144634 | assert( iLevel>=0 && iLevel<=RTREE_MAX_DEPTH ); |
| 144635 | while( i>0 ){ |
| 144636 | RtreeSearchPoint *pParent; |
| 144637 | j = (i-1)/2; |
| 144638 | pParent = pCur->aPoint + j; |
| 144639 | if( rtreeSearchPointCompare(pNew, pParent)>=0 ) break; |
| 144640 | rtreeSearchPointSwap(pCur, j, i); |
| 144641 | i = j; |
| 144642 | pNew = pParent; |
| 144643 | } |
| 144644 | return pNew; |
| 144645 | } |
| 144646 | |
| 144647 | /* |
| 144648 | ** Allocate a new RtreeSearchPoint and return a pointer to it. Return |
| 144649 | ** NULL if malloc fails. |
| 144650 | */ |
| 144651 | static RtreeSearchPoint *rtreeSearchPointNew( |
| 144652 | RtreeCursor *pCur, /* The cursor */ |
| 144653 | RtreeDValue rScore, /* Score for the new search point */ |
| 144654 | u8 iLevel /* Level for the new search point */ |
| 144655 | ){ |
| 144656 | RtreeSearchPoint *pNew, *pFirst; |
| 144657 | pFirst = rtreeSearchPointFirst(pCur); |
| 144658 | pCur->anQueue[iLevel]++; |
| 144659 | if( pFirst==0 |
| 144660 | || pFirst->rScore>rScore |
| 144661 | || (pFirst->rScore==rScore && pFirst->iLevel>iLevel) |
| 144662 | ){ |
| 144663 | if( pCur->bPoint ){ |
| 144664 | int ii; |
| 144665 | pNew = rtreeEnqueue(pCur, rScore, iLevel); |
| 144666 | if( pNew==0 ) return 0; |
| 144667 | ii = (int)(pNew - pCur->aPoint) + 1; |
| 144668 | if( ii<RTREE_CACHE_SZ ){ |
| 144669 | assert( pCur->aNode[ii]==0 ); |
| 144670 | pCur->aNode[ii] = pCur->aNode[0]; |
| 144671 | }else{ |
| 144672 | nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]); |
| 144673 | } |
| 144674 | pCur->aNode[0] = 0; |
| 144675 | *pNew = pCur->sPoint; |
| 144676 | } |
| 144677 | pCur->sPoint.rScore = rScore; |
| 144678 | pCur->sPoint.iLevel = iLevel; |
| 144679 | pCur->bPoint = 1; |
| 144680 | return &pCur->sPoint; |
| 144681 | }else{ |
| 144682 | return rtreeEnqueue(pCur, rScore, iLevel); |
| 144683 | } |
| 144684 | } |
| 144685 | |
| 144686 | #if 0 |
| 144687 | /* Tracing routines for the RtreeSearchPoint queue */ |
| 144688 | static void tracePoint(RtreeSearchPoint *p, int idx, RtreeCursor *pCur){ |
| 144689 | if( idx<0 ){ printf(" s"); }else{ printf("%2d", idx); } |
| 144690 | printf(" %d.%05lld.%02d %g %d", |
| 144691 | p->iLevel, p->id, p->iCell, p->rScore, p->eWithin |
| 144692 | ); |
| 144693 | idx++; |
| 144694 | if( idx<RTREE_CACHE_SZ ){ |
| 144695 | printf(" %p\n", pCur->aNode[idx]); |
| 144696 | }else{ |
| 144697 | printf("\n"); |
| 144698 | } |
| 144699 | } |
| 144700 | static void traceQueue(RtreeCursor *pCur, const char *zPrefix){ |
| 144701 | int ii; |
| 144702 | printf("=== %9s ", zPrefix); |
| 144703 | if( pCur->bPoint ){ |
| 144704 | tracePoint(&pCur->sPoint, -1, pCur); |
| 144705 | } |
| 144706 | for(ii=0; ii<pCur->nPoint; ii++){ |
| 144707 | if( ii>0 || pCur->bPoint ) printf(" "); |
| 144708 | tracePoint(&pCur->aPoint[ii], ii, pCur); |
| 144709 | } |
| 144710 | } |
| 144711 | # define RTREE_QUEUE_TRACE(A,B) traceQueue(A,B) |
| 144712 | #else |
| 144713 | # define RTREE_QUEUE_TRACE(A,B) /* no-op */ |
| 144714 | #endif |
| 144715 | |
| 144716 | /* Remove the search point with the lowest current score. |
| 144717 | */ |
| 144718 | static void rtreeSearchPointPop(RtreeCursor *p){ |
| 144719 | int i, j, k, n; |
| 144720 | i = 1 - p->bPoint; |
| 144721 | assert( i==0 || i==1 ); |
| 144722 | if( p->aNode[i] ){ |
| 144723 | nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); |
| 144724 | p->aNode[i] = 0; |
| 144725 | } |
| 144726 | if( p->bPoint ){ |
| 144727 | p->anQueue[p->sPoint.iLevel]--; |
| 144728 | p->bPoint = 0; |
| 144729 | }else if( p->nPoint ){ |
| 144730 | p->anQueue[p->aPoint[0].iLevel]--; |
| 144731 | n = --p->nPoint; |
| 144732 | p->aPoint[0] = p->aPoint[n]; |
| 144733 | if( n<RTREE_CACHE_SZ-1 ){ |
| 144734 | p->aNode[1] = p->aNode[n+1]; |
| 144735 | p->aNode[n+1] = 0; |
| 144736 | } |
| 144737 | i = 0; |
| 144738 | while( (j = i*2+1)<n ){ |
| 144739 | k = j+1; |
| 144740 | if( k<n && rtreeSearchPointCompare(&p->aPoint[k], &p->aPoint[j])<0 ){ |
| 144741 | if( rtreeSearchPointCompare(&p->aPoint[k], &p->aPoint[i])<0 ){ |
| 144742 | rtreeSearchPointSwap(p, i, k); |
| 144743 | i = k; |
| 144744 | }else{ |
| 144745 | break; |
| 144746 | } |
| 144747 | }else{ |
| 144748 | if( rtreeSearchPointCompare(&p->aPoint[j], &p->aPoint[i])<0 ){ |
| 144749 | rtreeSearchPointSwap(p, i, j); |
| 144750 | i = j; |
| 144751 | }else{ |
| 144752 | break; |
| 144753 | } |
| 144754 | } |
| 144755 | } |
| 144756 | } |
| 144757 | } |
| 144758 | |
| 144759 | |
| 144760 | /* |
| 144761 | ** Continue the search on cursor pCur until the front of the queue |
| 144762 | ** contains an entry suitable for returning as a result-set row, |
| 144763 | ** or until the RtreeSearchPoint queue is empty, indicating that the |
| 144764 | ** query has completed. |
| 144765 | */ |
| 144766 | static int rtreeStepToLeaf(RtreeCursor *pCur){ |
| 144767 | RtreeSearchPoint *p; |
| 144768 | Rtree *pRtree = RTREE_OF_CURSOR(pCur); |
| 144769 | RtreeNode *pNode; |
| 144770 | int eWithin; |
| 144771 | int rc = SQLITE_OK; |
| 144772 | int nCell; |
| 144773 | int nConstraint = pCur->nConstraint; |
| 144774 | int ii; |
| 144775 | int eInt; |
| 144776 | RtreeSearchPoint x; |
| 144777 | |
| 144778 | eInt = pRtree->eCoordType==RTREE_COORD_INT32; |
| 144779 | while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){ |
| 144780 | pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc); |
| 144781 | if( rc ) return rc; |
| 144782 | nCell = NCELL(pNode); |
| 144783 | assert( nCell<200 ); |
| 144784 | while( p->iCell<nCell ){ |
| 144785 | sqlite3_rtree_dbl rScore = (sqlite3_rtree_dbl)-1; |
| 144786 | u8 *pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell); |
| 144787 | eWithin = FULLY_WITHIN; |
| 144788 | for(ii=0; ii<nConstraint; ii++){ |
| 144789 | RtreeConstraint *pConstraint = pCur->aConstraint + ii; |
| 144790 | if( pConstraint->op>=RTREE_MATCH ){ |
| 144791 | rc = rtreeCallbackConstraint(pConstraint, eInt, pCellData, p, |
| 144792 | &rScore, &eWithin); |
| 144793 | if( rc ) return rc; |
| 144794 | }else if( p->iLevel==1 ){ |
| 144795 | rtreeLeafConstraint(pConstraint, eInt, pCellData, &eWithin); |
| 144796 | }else{ |
| 144797 | rtreeNonleafConstraint(pConstraint, eInt, pCellData, &eWithin); |
| 144798 | } |
| 144799 | if( eWithin==NOT_WITHIN ) break; |
| 144800 | } |
| 144801 | p->iCell++; |
| 144802 | if( eWithin==NOT_WITHIN ) continue; |
| 144803 | x.iLevel = p->iLevel - 1; |
| 144804 | if( x.iLevel ){ |
| 144805 | x.id = readInt64(pCellData); |
| 144806 | x.iCell = 0; |
| 144807 | }else{ |
| 144808 | x.id = p->id; |
| 144809 | x.iCell = p->iCell - 1; |
| 144810 | } |
| 144811 | if( p->iCell>=nCell ){ |
| 144812 | RTREE_QUEUE_TRACE(pCur, "POP-S:"); |
| 144813 | rtreeSearchPointPop(pCur); |
| 144814 | } |
| 144815 | if( rScore<RTREE_ZERO ) rScore = RTREE_ZERO; |
| 144816 | p = rtreeSearchPointNew(pCur, rScore, x.iLevel); |
| 144817 | if( p==0 ) return SQLITE_NOMEM; |
| 144818 | p->eWithin = eWithin; |
| 144819 | p->id = x.id; |
| 144820 | p->iCell = x.iCell; |
| 144821 | RTREE_QUEUE_TRACE(pCur, "PUSH-S:"); |
| 144822 | break; |
| 144823 | } |
| 144824 | if( p->iCell>=nCell ){ |
| 144825 | RTREE_QUEUE_TRACE(pCur, "POP-Se:"); |
| 144826 | rtreeSearchPointPop(pCur); |
| 144827 | } |
| 144828 | } |
| 144829 | pCur->atEOF = p==0; |
| 144830 | return SQLITE_OK; |
| 144831 | } |
| 144832 | |
| 144833 | /* |
| 144834 | ** Rtree virtual table module xNext method. |
| 144835 | */ |
| 144836 | static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ |
| 144837 | RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |
| 144838 | int rc = SQLITE_OK; |
| 144839 | |
| 144840 | /* Move to the next entry that matches the configured constraints. */ |
| 144841 | RTREE_QUEUE_TRACE(pCsr, "POP-Nx:"); |
| 144842 | rtreeSearchPointPop(pCsr); |
| 144843 | rc = rtreeStepToLeaf(pCsr); |
| 144844 | return rc; |
| 144845 | } |
| 144846 | |
| 144847 | /* |
| 144848 | ** Rtree virtual table module xRowid method. |
| 144849 | */ |
| 144850 | static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ |
| 144851 | RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |
| 144852 | RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); |
| 144853 | int rc = SQLITE_OK; |
| 144854 | RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); |
| 144855 | if( rc==SQLITE_OK && p ){ |
| 144856 | *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); |
| 144857 | } |
| 144858 | return rc; |
| 144859 | } |
| 144860 | |
| 144861 | /* |
| 144862 | ** Rtree virtual table module xColumn method. |
| 144863 | */ |
| 144864 | static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ |
| 144865 | Rtree *pRtree = (Rtree *)cur->pVtab; |
| 144866 | RtreeCursor *pCsr = (RtreeCursor *)cur; |
| 144867 | RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); |
| 144868 | RtreeCoord c; |
| 144869 | int rc = SQLITE_OK; |
| 144870 | RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); |
| 144871 | |
| 144872 | if( rc ) return rc; |
| 144873 | if( p==0 ) return SQLITE_OK; |
| 144874 | if( i==0 ){ |
| 144875 | sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); |
| 144876 | }else{ |
| 144877 | if( rc ) return rc; |
| 144878 | nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c); |
| 144879 | #ifndef SQLITE_RTREE_INT_ONLY |
| 144880 | if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ |
| 144881 | sqlite3_result_double(ctx, c.f); |
| 144882 | }else |
| 144883 | #endif |
| @@ -143934,11 +144884,10 @@ | |
| 144884 | { |
| 144885 | assert( pRtree->eCoordType==RTREE_COORD_INT32 ); |
| 144886 | sqlite3_result_int(ctx, c.i); |
| 144887 | } |
| 144888 | } |
| 144889 | return SQLITE_OK; |
| 144890 | } |
| 144891 | |
| 144892 | /* |
| 144893 | ** Use nodeAcquire() to obtain the leaf node containing the record with |
| @@ -143945,16 +144894,22 @@ | |
| 144894 | ** rowid iRowid. If successful, set *ppLeaf to point to the node and |
| 144895 | ** return SQLITE_OK. If there is no such record in the table, set |
| 144896 | ** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf |
| 144897 | ** to zero and return an SQLite error code. |
| 144898 | */ |
| 144899 | static int findLeafNode( |
| 144900 | Rtree *pRtree, /* RTree to search */ |
| 144901 | i64 iRowid, /* The rowid searching for */ |
| 144902 | RtreeNode **ppLeaf, /* Write the node here */ |
| 144903 | sqlite3_int64 *piNode /* Write the node-id here */ |
| 144904 | ){ |
| 144905 | int rc; |
| 144906 | *ppLeaf = 0; |
| 144907 | sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid); |
| 144908 | if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){ |
| 144909 | i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0); |
| 144910 | if( piNode ) *piNode = iNode; |
| 144911 | rc = nodeAcquire(pRtree, iNode, 0, ppLeaf); |
| 144912 | sqlite3_reset(pRtree->pReadRowid); |
| 144913 | }else{ |
| 144914 | rc = sqlite3_reset(pRtree->pReadRowid); |
| 144915 | } |
| @@ -143966,13 +144921,14 @@ | |
| 144921 | ** as the second argument for a MATCH constraint. The value passed as the |
| 144922 | ** first argument to this function is the right-hand operand to the MATCH |
| 144923 | ** operator. |
| 144924 | */ |
| 144925 | static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ |
| 144926 | RtreeMatchArg *pBlob; /* BLOB returned by geometry function */ |
| 144927 | sqlite3_rtree_query_info *pInfo; /* Callback information */ |
| 144928 | int nBlob; /* Size of the geometry function blob */ |
| 144929 | int nExpected; /* Expected size of the BLOB */ |
| 144930 | |
| 144931 | /* Check that value is actually a blob. */ |
| 144932 | if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR; |
| 144933 | |
| 144934 | /* Check that the blob is roughly the right size. */ |
| @@ -143981,31 +144937,33 @@ | |
| 144937 | || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0 |
| 144938 | ){ |
| 144939 | return SQLITE_ERROR; |
| 144940 | } |
| 144941 | |
| 144942 | pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob ); |
| 144943 | if( !pInfo ) return SQLITE_NOMEM; |
| 144944 | memset(pInfo, 0, sizeof(*pInfo)); |
| 144945 | pBlob = (RtreeMatchArg*)&pInfo[1]; |
| 144946 | |
| 144947 | memcpy(pBlob, sqlite3_value_blob(pValue), nBlob); |
| 144948 | nExpected = (int)(sizeof(RtreeMatchArg) + |
| 144949 | (pBlob->nParam-1)*sizeof(RtreeDValue)); |
| 144950 | if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){ |
| 144951 | sqlite3_free(pInfo); |
| 144952 | return SQLITE_ERROR; |
| 144953 | } |
| 144954 | pInfo->pContext = pBlob->cb.pContext; |
| 144955 | pInfo->nParam = pBlob->nParam; |
| 144956 | pInfo->aParam = pBlob->aParam; |
| 144957 | |
| 144958 | if( pBlob->cb.xGeom ){ |
| 144959 | pCons->u.xGeom = pBlob->cb.xGeom; |
| 144960 | }else{ |
| 144961 | pCons->op = RTREE_QUERY; |
| 144962 | pCons->u.xQueryFunc = pBlob->cb.xQueryFunc; |
| 144963 | } |
| 144964 | pCons->pInfo = pInfo; |
| 144965 | return SQLITE_OK; |
| 144966 | } |
| 144967 | |
| 144968 | /* |
| 144969 | ** Rtree virtual table module xFilter method. |
| @@ -144015,91 +144973,96 @@ | |
| 144973 | int idxNum, const char *idxStr, |
| 144974 | int argc, sqlite3_value **argv |
| 144975 | ){ |
| 144976 | Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; |
| 144977 | RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |
| 144978 | RtreeNode *pRoot = 0; |
| 144979 | int ii; |
| 144980 | int rc = SQLITE_OK; |
| 144981 | int iCell = 0; |
| 144982 | |
| 144983 | rtreeReference(pRtree); |
| 144984 | |
| 144985 | freeCursorConstraints(pCsr); |
| 144986 | pCsr->iStrategy = idxNum; |
| 144987 | |
| 144988 | if( idxNum==1 ){ |
| 144989 | /* Special case - lookup by rowid. */ |
| 144990 | RtreeNode *pLeaf; /* Leaf on which the required cell resides */ |
| 144991 | RtreeSearchPoint *p; /* Search point for the the leaf */ |
| 144992 | i64 iRowid = sqlite3_value_int64(argv[0]); |
| 144993 | i64 iNode = 0; |
| 144994 | rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); |
| 144995 | if( rc==SQLITE_OK && pLeaf!=0 ){ |
| 144996 | p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); |
| 144997 | assert( p!=0 ); /* Always returns pCsr->sPoint */ |
| 144998 | pCsr->aNode[0] = pLeaf; |
| 144999 | p->id = iNode; |
| 145000 | p->eWithin = PARTLY_WITHIN; |
| 145001 | rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); |
| 145002 | p->iCell = iCell; |
| 145003 | RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); |
| 145004 | }else{ |
| 145005 | pCsr->atEOF = 1; |
| 145006 | } |
| 145007 | }else{ |
| 145008 | /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array |
| 145009 | ** with the configured constraints. |
| 145010 | */ |
| 145011 | rc = nodeAcquire(pRtree, 1, 0, &pRoot); |
| 145012 | if( rc==SQLITE_OK && argc>0 ){ |
| 145013 | pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc); |
| 145014 | pCsr->nConstraint = argc; |
| 145015 | if( !pCsr->aConstraint ){ |
| 145016 | rc = SQLITE_NOMEM; |
| 145017 | }else{ |
| 145018 | memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc); |
| 145019 | memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1)); |
| 145020 | assert( (idxStr==0 && argc==0) |
| 145021 | || (idxStr && (int)strlen(idxStr)==argc*2) ); |
| 145022 | for(ii=0; ii<argc; ii++){ |
| 145023 | RtreeConstraint *p = &pCsr->aConstraint[ii]; |
| 145024 | p->op = idxStr[ii*2]; |
| 145025 | p->iCoord = idxStr[ii*2+1]-'0'; |
| 145026 | if( p->op>=RTREE_MATCH ){ |
| 145027 | /* A MATCH operator. The right-hand-side must be a blob that |
| 145028 | ** can be cast into an RtreeMatchArg object. One created using |
| 145029 | ** an sqlite3_rtree_geometry_callback() SQL user function. |
| 145030 | */ |
| 145031 | rc = deserializeGeometry(argv[ii], p); |
| 145032 | if( rc!=SQLITE_OK ){ |
| 145033 | break; |
| 145034 | } |
| 145035 | p->pInfo->nCoord = pRtree->nDim*2; |
| 145036 | p->pInfo->anQueue = pCsr->anQueue; |
| 145037 | p->pInfo->mxLevel = pRtree->iDepth + 1; |
| 145038 | }else{ |
| 145039 | #ifdef SQLITE_RTREE_INT_ONLY |
| 145040 | p->u.rValue = sqlite3_value_int64(argv[ii]); |
| 145041 | #else |
| 145042 | p->u.rValue = sqlite3_value_double(argv[ii]); |
| 145043 | #endif |
| 145044 | } |
| 145045 | } |
| 145046 | } |
| 145047 | } |
| 145048 | if( rc==SQLITE_OK ){ |
| 145049 | RtreeSearchPoint *pNew; |
| 145050 | pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, pRtree->iDepth+1); |
| 145051 | if( pNew==0 ) return SQLITE_NOMEM; |
| 145052 | pNew->id = 1; |
| 145053 | pNew->iCell = 0; |
| 145054 | pNew->eWithin = PARTLY_WITHIN; |
| 145055 | assert( pCsr->bPoint==1 ); |
| 145056 | pCsr->aNode[0] = pRoot; |
| 145057 | pRoot = 0; |
| 145058 | RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); |
| 145059 | rc = rtreeStepToLeaf(pCsr); |
| 145060 | } |
| 145061 | } |
| 145062 | |
| 145063 | nodeRelease(pRtree, pRoot); |
| 145064 | rtreeRelease(pRtree); |
| 145065 | return rc; |
| 145066 | } |
| 145067 | |
| 145068 | /* |
| @@ -144197,11 +145160,11 @@ | |
| 145160 | assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH ); |
| 145161 | op = RTREE_MATCH; |
| 145162 | break; |
| 145163 | } |
| 145164 | zIdxStr[iIdx++] = op; |
| 145165 | zIdxStr[iIdx++] = p->iColumn - 1 + '0'; |
| 145166 | pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); |
| 145167 | pIdxInfo->aConstraintUsage[ii].omit = 1; |
| 145168 | } |
| 145169 | } |
| 145170 | |
| @@ -144290,66 +145253,36 @@ | |
| 145253 | area = cellArea(pRtree, &cell); |
| 145254 | cellUnion(pRtree, &cell, pCell); |
| 145255 | return (cellArea(pRtree, &cell)-area); |
| 145256 | } |
| 145257 | |
| 145258 | static RtreeDValue cellOverlap( |
| 145259 | Rtree *pRtree, |
| 145260 | RtreeCell *p, |
| 145261 | RtreeCell *aCell, |
| 145262 | int nCell |
| 145263 | ){ |
| 145264 | int ii; |
| 145265 | RtreeDValue overlap = RTREE_ZERO; |
| 145266 | for(ii=0; ii<nCell; ii++){ |
| 145267 | int jj; |
| 145268 | RtreeDValue o = (RtreeDValue)1; |
| 145269 | for(jj=0; jj<(pRtree->nDim*2); jj+=2){ |
| 145270 | RtreeDValue x1, x2; |
| 145271 | x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); |
| 145272 | x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); |
| 145273 | if( x2<x1 ){ |
| 145274 | o = (RtreeDValue)0; |
| 145275 | break; |
| 145276 | }else{ |
| 145277 | o = o * (x2-x1); |
| 145278 | } |
| 145279 | } |
| 145280 | overlap += o; |
| 145281 | } |
| 145282 | return overlap; |
| 145283 | } |
| 145284 | |
| 145285 | |
| 145286 | /* |
| 145287 | ** This function implements the ChooseLeaf algorithm from Gutman[84]. |
| 145288 | ** ChooseSubTree in r*tree terminology. |
| @@ -144367,39 +145300,19 @@ | |
| 145300 | |
| 145301 | for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ |
| 145302 | int iCell; |
| 145303 | sqlite3_int64 iBest = 0; |
| 145304 | |
| 145305 | RtreeDValue fMinGrowth = RTREE_ZERO; |
| 145306 | RtreeDValue fMinArea = RTREE_ZERO; |
| 145307 | |
| 145308 | int nCell = NCELL(pNode); |
| 145309 | RtreeCell cell; |
| 145310 | RtreeNode *pChild; |
| 145311 | |
| 145312 | RtreeCell *aCell = 0; |
| 145313 | |
| 145314 | /* Select the child node which will be enlarged the least if pCell |
| 145315 | ** is inserted into it. Resolve ties by choosing the entry with |
| 145316 | ** the smallest area. |
| 145317 | */ |
| 145318 | for(iCell=0; iCell<nCell; iCell++){ |
| @@ -144407,30 +145320,13 @@ | |
| 145320 | RtreeDValue growth; |
| 145321 | RtreeDValue area; |
| 145322 | nodeGetCell(pRtree, pNode, iCell, &cell); |
| 145323 | growth = cellGrowth(pRtree, &cell, pCell); |
| 145324 | area = cellArea(pRtree, &cell); |
| 145325 | if( iCell==0||growth<fMinGrowth||(growth==fMinGrowth && area<fMinArea) ){ |
| 145326 | bBest = 1; |
| 145327 | } |
| 145328 | if( bBest ){ |
| 145329 | fMinGrowth = growth; |
| 145330 | fMinArea = area; |
| 145331 | iBest = cell.iRowid; |
| 145332 | } |
| @@ -144497,159 +145393,10 @@ | |
| 145393 | return sqlite3_reset(pRtree->pWriteParent); |
| 145394 | } |
| 145395 | |
| 145396 | static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int); |
| 145397 | |
| 145398 | |
| 145399 | /* |
| 145400 | ** Arguments aIdx, aDistance and aSpare all point to arrays of size |
| 145401 | ** nIdx. The aIdx array contains the set of integers from 0 to |
| 145402 | ** (nIdx-1) in no particular order. This function sorts the values |
| @@ -144786,11 +145533,10 @@ | |
| 145533 | } |
| 145534 | #endif |
| 145535 | } |
| 145536 | } |
| 145537 | |
| 145538 | /* |
| 145539 | ** Implementation of the R*-tree variant of SplitNode from Beckman[1990]. |
| 145540 | */ |
| 145541 | static int splitNodeStartree( |
| 145542 | Rtree *pRtree, |
| @@ -144805,11 +145551,11 @@ | |
| 145551 | int *aSpare; |
| 145552 | int ii; |
| 145553 | |
| 145554 | int iBestDim = 0; |
| 145555 | int iBestSplit = 0; |
| 145556 | RtreeDValue fBestMargin = RTREE_ZERO; |
| 145557 | |
| 145558 | int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); |
| 145559 | |
| 145560 | aaSorted = (int **)sqlite3_malloc(nByte); |
| 145561 | if( !aaSorted ){ |
| @@ -144826,13 +145572,13 @@ | |
| 145572 | } |
| 145573 | SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare); |
| 145574 | } |
| 145575 | |
| 145576 | for(ii=0; ii<pRtree->nDim; ii++){ |
| 145577 | RtreeDValue margin = RTREE_ZERO; |
| 145578 | RtreeDValue fBestOverlap = RTREE_ZERO; |
| 145579 | RtreeDValue fBestArea = RTREE_ZERO; |
| 145580 | int iBestLeft = 0; |
| 145581 | int nLeft; |
| 145582 | |
| 145583 | for( |
| 145584 | nLeft=RTREE_MINCELLS(pRtree); |
| @@ -144854,11 +145600,11 @@ | |
| 145600 | cellUnion(pRtree, &right, &aCell[aaSorted[ii][kk]]); |
| 145601 | } |
| 145602 | } |
| 145603 | margin += cellMargin(pRtree, &left); |
| 145604 | margin += cellMargin(pRtree, &right); |
| 145605 | overlap = cellOverlap(pRtree, &left, &right, 1); |
| 145606 | area = cellArea(pRtree, &left) + cellArea(pRtree, &right); |
| 145607 | if( (nLeft==RTREE_MINCELLS(pRtree)) |
| 145608 | || (overlap<fBestOverlap) |
| 145609 | || (overlap==fBestOverlap && area<fBestArea) |
| 145610 | ){ |
| @@ -144886,67 +145632,11 @@ | |
| 145632 | } |
| 145633 | |
| 145634 | sqlite3_free(aaSorted); |
| 145635 | return SQLITE_OK; |
| 145636 | } |
| 145637 | |
| 145638 | |
| 145639 | static int updateMapping( |
| 145640 | Rtree *pRtree, |
| 145641 | i64 iRowid, |
| 145642 | RtreeNode *pNode, |
| @@ -145020,11 +145710,12 @@ | |
| 145710 | } |
| 145711 | |
| 145712 | memset(pLeft->zData, 0, pRtree->iNodeSize); |
| 145713 | memset(pRight->zData, 0, pRtree->iNodeSize); |
| 145714 | |
| 145715 | rc = splitNodeStartree(pRtree, aCell, nCell, pLeft, pRight, |
| 145716 | &leftbbox, &rightbbox); |
| 145717 | if( rc!=SQLITE_OK ){ |
| 145718 | goto splitnode_out; |
| 145719 | } |
| 145720 | |
| 145721 | /* Ensure both child nodes have node numbers assigned to them by calling |
| @@ -145303,11 +145994,11 @@ | |
| 145994 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 145995 | aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2)); |
| 145996 | } |
| 145997 | |
| 145998 | for(ii=0; ii<nCell; ii++){ |
| 145999 | aDistance[ii] = RTREE_ZERO; |
| 146000 | for(iDim=0; iDim<pRtree->nDim; iDim++){ |
| 146001 | RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) - |
| 146002 | DCOORD(aCell[ii].aCoord[iDim*2])); |
| 146003 | aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); |
| 146004 | } |
| @@ -145369,20 +146060,16 @@ | |
| 146060 | nodeReference(pNode); |
| 146061 | pChild->pParent = pNode; |
| 146062 | } |
| 146063 | } |
| 146064 | if( nodeInsertCell(pRtree, pNode, pCell) ){ |
| 146065 | if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){ |
| 146066 | rc = SplitNode(pRtree, pNode, pCell, iHeight); |
| 146067 | }else{ |
| 146068 | pRtree->iReinsertHeight = iHeight; |
| 146069 | rc = Reinsert(pRtree, pNode, pCell, iHeight); |
| 146070 | } |
| 146071 | }else{ |
| 146072 | rc = AdjustTree(pRtree, pNode, pCell); |
| 146073 | if( rc==SQLITE_OK ){ |
| 146074 | if( iHeight==0 ){ |
| 146075 | rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); |
| @@ -145448,11 +146135,11 @@ | |
| 146135 | |
| 146136 | /* Obtain a reference to the leaf node that contains the entry |
| 146137 | ** about to be deleted. |
| 146138 | */ |
| 146139 | if( rc==SQLITE_OK ){ |
| 146140 | rc = findLeafNode(pRtree, iDelete, &pLeaf, 0); |
| 146141 | } |
| 146142 | |
| 146143 | /* Delete the cell in question from the leaf node. */ |
| 146144 | if( rc==SQLITE_OK ){ |
| 146145 | int rc2; |
| @@ -145785,11 +146472,12 @@ | |
| 146472 | |
| 146473 | if( isCreate ){ |
| 146474 | char *zCreate = sqlite3_mprintf( |
| 146475 | "CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);" |
| 146476 | "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);" |
| 146477 | "CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY," |
| 146478 | " parentnode INTEGER);" |
| 146479 | "INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))", |
| 146480 | zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize |
| 146481 | ); |
| 146482 | if( !zCreate ){ |
| 146483 | return SQLITE_NOMEM; |
| @@ -145999,14 +146687,14 @@ | |
| 146687 | |
| 146688 | /* |
| 146689 | ** Implementation of a scalar function that decodes r-tree nodes to |
| 146690 | ** human readable strings. This can be used for debugging and analysis. |
| 146691 | ** |
| 146692 | ** The scalar function takes two arguments: (1) the number of dimensions |
| 146693 | ** to the rtree (between 1 and 5, inclusive) and (2) a blob of data containing |
| 146694 | ** an r-tree node. For a two-dimensional r-tree structure called "rt", to |
| 146695 | ** deserialize all nodes, a statement like: |
| 146696 | ** |
| 146697 | ** SELECT rtreenode(2, data) FROM rt_node; |
| 146698 | ** |
| 146699 | ** The human readable string takes the form of a Tcl list with one |
| 146700 | ** entry for each cell in the r-tree node. Each entry is itself a |
| @@ -146035,11 +146723,11 @@ | |
| 146723 | nodeGetCell(&tree, &node, ii, &cell); |
| 146724 | sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid); |
| 146725 | nCell = (int)strlen(zCell); |
| 146726 | for(jj=0; jj<tree.nDim*2; jj++){ |
| 146727 | #ifndef SQLITE_RTREE_INT_ONLY |
| 146728 | sqlite3_snprintf(512-nCell,&zCell[nCell], " %g", |
| 146729 | (double)cell.aCoord[jj].f); |
| 146730 | #else |
| 146731 | sqlite3_snprintf(512-nCell,&zCell[nCell], " %d", |
| 146732 | cell.aCoord[jj].i); |
| 146733 | #endif |
| @@ -146056,10 +146744,19 @@ | |
| 146744 | } |
| 146745 | |
| 146746 | sqlite3_result_text(ctx, zText, -1, sqlite3_free); |
| 146747 | } |
| 146748 | |
| 146749 | /* This routine implements an SQL function that returns the "depth" parameter |
| 146750 | ** from the front of a blob that is an r-tree node. For example: |
| 146751 | ** |
| 146752 | ** SELECT rtreedepth(data) FROM rt_node WHERE nodeno=1; |
| 146753 | ** |
| 146754 | ** The depth value is 0 for all nodes other than the root node, and the root |
| 146755 | ** node always has nodeno=1, so the example above is the primary use for this |
| 146756 | ** routine. This routine is intended for testing and analysis only. |
| 146757 | */ |
| 146758 | static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ |
| 146759 | UNUSED_PARAMETER(nArg); |
| 146760 | if( sqlite3_value_type(apArg[0])!=SQLITE_BLOB |
| 146761 | || sqlite3_value_bytes(apArg[0])<2 |
| 146762 | ){ |
| @@ -146098,26 +146795,35 @@ | |
| 146795 | |
| 146796 | return rc; |
| 146797 | } |
| 146798 | |
| 146799 | /* |
| 146800 | ** This routine deletes the RtreeGeomCallback object that was attached |
| 146801 | ** one of the SQL functions create by sqlite3_rtree_geometry_callback() |
| 146802 | ** or sqlite3_rtree_query_callback(). In other words, this routine is the |
| 146803 | ** destructor for an RtreeGeomCallback objecct. This routine is called when |
| 146804 | ** the corresponding SQL function is deleted. |
| 146805 | */ |
| 146806 | static void rtreeFreeCallback(void *p){ |
| 146807 | RtreeGeomCallback *pInfo = (RtreeGeomCallback*)p; |
| 146808 | if( pInfo->xDestructor ) pInfo->xDestructor(pInfo->pContext); |
| 146809 | sqlite3_free(p); |
| 146810 | } |
| 146811 | |
| 146812 | /* |
| 146813 | ** Each call to sqlite3_rtree_geometry_callback() or |
| 146814 | ** sqlite3_rtree_query_callback() creates an ordinary SQLite |
| 146815 | ** scalar function that is implemented by this routine. |
| 146816 | ** |
| 146817 | ** All this function does is construct an RtreeMatchArg object that |
| 146818 | ** contains the geometry-checking callback routines and a list of |
| 146819 | ** parameters to this function, then return that RtreeMatchArg object |
| 146820 | ** as a BLOB. |
| 146821 | ** |
| 146822 | ** The R-Tree MATCH operator will read the returned BLOB, deserialize |
| 146823 | ** the RtreeMatchArg object, and use the RtreeMatchArg object to figure |
| 146824 | ** out which elements of the R-Tree should be returned by the query. |
| 146825 | */ |
| 146826 | static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ |
| 146827 | RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); |
| 146828 | RtreeMatchArg *pBlob; |
| 146829 | int nBlob; |
| @@ -146127,45 +146833,68 @@ | |
| 146833 | if( !pBlob ){ |
| 146834 | sqlite3_result_error_nomem(ctx); |
| 146835 | }else{ |
| 146836 | int i; |
| 146837 | pBlob->magic = RTREE_GEOMETRY_MAGIC; |
| 146838 | pBlob->cb = pGeomCtx[0]; |
| 146839 | pBlob->nParam = nArg; |
| 146840 | for(i=0; i<nArg; i++){ |
| 146841 | #ifdef SQLITE_RTREE_INT_ONLY |
| 146842 | pBlob->aParam[i] = sqlite3_value_int64(aArg[i]); |
| 146843 | #else |
| 146844 | pBlob->aParam[i] = sqlite3_value_double(aArg[i]); |
| 146845 | #endif |
| 146846 | } |
| 146847 | sqlite3_result_blob(ctx, pBlob, nBlob, sqlite3_free); |
| 146848 | } |
| 146849 | } |
| 146850 | |
| 146851 | /* |
| 146852 | ** Register a new geometry function for use with the r-tree MATCH operator. |
| 146853 | */ |
| 146854 | SQLITE_API int sqlite3_rtree_geometry_callback( |
| 146855 | sqlite3 *db, /* Register SQL function on this connection */ |
| 146856 | const char *zGeom, /* Name of the new SQL function */ |
| 146857 | int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */ |
| 146858 | void *pContext /* Extra data associated with the callback */ |
| 146859 | ){ |
| 146860 | RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ |
| 146861 | |
| 146862 | /* Allocate and populate the context object. */ |
| 146863 | pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); |
| 146864 | if( !pGeomCtx ) return SQLITE_NOMEM; |
| 146865 | pGeomCtx->xGeom = xGeom; |
| 146866 | pGeomCtx->xQueryFunc = 0; |
| 146867 | pGeomCtx->xDestructor = 0; |
| 146868 | pGeomCtx->pContext = pContext; |
| 146869 | return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, |
| 146870 | (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback |
| 146871 | ); |
| 146872 | } |
| 146873 | |
| 146874 | /* |
| 146875 | ** Register a new 2nd-generation geometry function for use with the |
| 146876 | ** r-tree MATCH operator. |
| 146877 | */ |
| 146878 | SQLITE_API int sqlite3_rtree_query_callback( |
| 146879 | sqlite3 *db, /* Register SQL function on this connection */ |
| 146880 | const char *zQueryFunc, /* Name of new SQL function */ |
| 146881 | int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */ |
| 146882 | void *pContext, /* Extra data passed into the callback */ |
| 146883 | void (*xDestructor)(void*) /* Destructor for the extra data */ |
| 146884 | ){ |
| 146885 | RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ |
| 146886 | |
| 146887 | /* Allocate and populate the context object. */ |
| 146888 | pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); |
| 146889 | if( !pGeomCtx ) return SQLITE_NOMEM; |
| 146890 | pGeomCtx->xGeom = 0; |
| 146891 | pGeomCtx->xQueryFunc = xQueryFunc; |
| 146892 | pGeomCtx->xDestructor = xDestructor; |
| 146893 | pGeomCtx->pContext = pContext; |
| 146894 | return sqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY, |
| 146895 | (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback |
| 146896 | ); |
| 146897 | } |
| 146898 | |
| 146899 | #if !SQLITE_CORE |
| 146900 | #ifdef _WIN32 |
| 146901 |
+94
-10
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -107,11 +107,11 @@ | ||
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | 110 | #define SQLITE_VERSION "3.8.5" |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3008005 |
| 112 | -#define SQLITE_SOURCE_ID "2014-04-18 22:20:31 9a5d38c79d2482a23bcfbc3ff35ca4fa269c768d" | |
| 112 | +#define SQLITE_SOURCE_ID "2014-05-24 17:15:15 ebfb51fe40756713d269b4c0ade752666910bb6e" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| @@ -558,11 +558,14 @@ | ||
| 558 | 558 | ** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that |
| 559 | 559 | ** after reboot following a crash or power loss, the only bytes in a |
| 560 | 560 | ** file that were written at the application level might have changed |
| 561 | 561 | ** and that adjacent bytes, even bytes within the same sector are |
| 562 | 562 | ** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
| 563 | -** flag indicate that a file cannot be deleted when open. | |
| 563 | +** flag indicate that a file cannot be deleted when open. The | |
| 564 | +** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on | |
| 565 | +** read-only media and cannot be changed even by processes with | |
| 566 | +** elevated privileges. | |
| 564 | 567 | */ |
| 565 | 568 | #define SQLITE_IOCAP_ATOMIC 0x00000001 |
| 566 | 569 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 |
| 567 | 570 | #define SQLITE_IOCAP_ATOMIC1K 0x00000004 |
| 568 | 571 | #define SQLITE_IOCAP_ATOMIC2K 0x00000008 |
| @@ -573,10 +576,11 @@ | ||
| 573 | 576 | #define SQLITE_IOCAP_ATOMIC64K 0x00000100 |
| 574 | 577 | #define SQLITE_IOCAP_SAFE_APPEND 0x00000200 |
| 575 | 578 | #define SQLITE_IOCAP_SEQUENTIAL 0x00000400 |
| 576 | 579 | #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 |
| 577 | 580 | #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 |
| 581 | +#define SQLITE_IOCAP_IMMUTABLE 0x00002000 | |
| 578 | 582 | |
| 579 | 583 | /* |
| 580 | 584 | ** CAPI3REF: File Locking Levels |
| 581 | 585 | ** |
| 582 | 586 | ** SQLite uses one of these integer values as the second |
| @@ -2777,10 +2781,34 @@ | ||
| 2777 | 2781 | ** sqlite3_open_v2(). ^Setting the cache parameter to "private" is |
| 2778 | 2782 | ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. |
| 2779 | 2783 | ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in |
| 2780 | 2784 | ** a URI filename, its value overrides any behavior requested by setting |
| 2781 | 2785 | ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. |
| 2786 | +** | |
| 2787 | +** <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or | |
| 2788 | +** "1") or "false" (or "off" or "no" or "0") to indicate that the | |
| 2789 | +** [powersafe overwrite] property does or does not apply to the | |
| 2790 | +** storage media on which the database file resides. ^The psow query | |
| 2791 | +** parameter only works for the built-in unix and Windows VFSes. | |
| 2792 | +** | |
| 2793 | +** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter | |
| 2794 | +** which if set disables file locking in rollback journal modes. This | |
| 2795 | +** is useful for accessing a database on a filesystem that does not | |
| 2796 | +** support locking. Caution: Database corruption might result if two | |
| 2797 | +** or more processes write to the same database and any one of those | |
| 2798 | +** processes uses nolock=1. | |
| 2799 | +** | |
| 2800 | +** <li> <b>immutable</b>: ^The immutable parameter is a boolean query | |
| 2801 | +** parameter that indicates that the database file is stored on | |
| 2802 | +** read-only media. ^When immutable is set, SQLite assumes that the | |
| 2803 | +** database file cannot be changed, even by a process with higher | |
| 2804 | +** privilege, and so the database is opened read-only and all locking | |
| 2805 | +** and change detection is disabled. Caution: Setting the immutable | |
| 2806 | +** property on a database file that does in fact change can result | |
| 2807 | +** in incorrect query results and/or [SQLITE_CORRUPT] errors. | |
| 2808 | +** See also: [SQLITE_IOCAP_IMMUTABLE]. | |
| 2809 | +** | |
| 2782 | 2810 | ** </ul> |
| 2783 | 2811 | ** |
| 2784 | 2812 | ** ^Specifying an unknown parameter in the query component of a URI is not an |
| 2785 | 2813 | ** error. Future versions of SQLite might understand additional query |
| 2786 | 2814 | ** parameters. See "[query parameters with special meaning to SQLite]" for |
| @@ -2806,12 +2834,13 @@ | ||
| 2806 | 2834 | ** in URI filenames. |
| 2807 | 2835 | ** <tr><td> file:data.db?mode=ro&cache=private <td> |
| 2808 | 2836 | ** Open file "data.db" in the current directory for read-only access. |
| 2809 | 2837 | ** Regardless of whether or not shared-cache mode is enabled by |
| 2810 | 2838 | ** default, use a private cache. |
| 2811 | -** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td> | |
| 2812 | -** Open file "/home/fred/data.db". Use the special VFS "unix-nolock". | |
| 2839 | +** <tr><td> file:/home/fred/data.db?vfs=unix-dotfile <td> | |
| 2840 | +** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile" | |
| 2841 | +** that uses dot-files in place of posix advisory locking. | |
| 2813 | 2842 | ** <tr><td> file:data.db?mode=readonly <td> |
| 2814 | 2843 | ** An error. "readonly" is not a valid option for the "mode" parameter. |
| 2815 | 2844 | ** </table> |
| 2816 | 2845 | ** |
| 2817 | 2846 | ** ^URI hexadecimal escape sequences (%HH) are supported within the path and |
| @@ -7345,10 +7374,20 @@ | ||
| 7345 | 7374 | #ifdef __cplusplus |
| 7346 | 7375 | extern "C" { |
| 7347 | 7376 | #endif |
| 7348 | 7377 | |
| 7349 | 7378 | typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; |
| 7379 | +typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; | |
| 7380 | + | |
| 7381 | +/* The double-precision datatype used by RTree depends on the | |
| 7382 | +** SQLITE_RTREE_INT_ONLY compile-time option. | |
| 7383 | +*/ | |
| 7384 | +#ifdef SQLITE_RTREE_INT_ONLY | |
| 7385 | + typedef sqlite3_int64 sqlite3_rtree_dbl; | |
| 7386 | +#else | |
| 7387 | + typedef double sqlite3_rtree_dbl; | |
| 7388 | +#endif | |
| 7350 | 7389 | |
| 7351 | 7390 | /* |
| 7352 | 7391 | ** Register a geometry callback named zGeom that can be used as part of an |
| 7353 | 7392 | ** R-Tree geometry query as follows: |
| 7354 | 7393 | ** |
| @@ -7355,15 +7394,11 @@ | ||
| 7355 | 7394 | ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) |
| 7356 | 7395 | */ |
| 7357 | 7396 | SQLITE_API int sqlite3_rtree_geometry_callback( |
| 7358 | 7397 | sqlite3 *db, |
| 7359 | 7398 | const char *zGeom, |
| 7360 | -#ifdef SQLITE_RTREE_INT_ONLY | |
| 7361 | - int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes), | |
| 7362 | -#else | |
| 7363 | - int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes), | |
| 7364 | -#endif | |
| 7399 | + int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), | |
| 7365 | 7400 | void *pContext |
| 7366 | 7401 | ); |
| 7367 | 7402 | |
| 7368 | 7403 | |
| 7369 | 7404 | /* |
| @@ -7371,17 +7406,66 @@ | ||
| 7371 | 7406 | ** argument to callbacks registered using rtree_geometry_callback(). |
| 7372 | 7407 | */ |
| 7373 | 7408 | struct sqlite3_rtree_geometry { |
| 7374 | 7409 | void *pContext; /* Copy of pContext passed to s_r_g_c() */ |
| 7375 | 7410 | int nParam; /* Size of array aParam[] */ |
| 7376 | - double *aParam; /* Parameters passed to SQL geom function */ | |
| 7411 | + sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */ | |
| 7377 | 7412 | void *pUser; /* Callback implementation user data */ |
| 7378 | 7413 | void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ |
| 7379 | 7414 | }; |
| 7380 | 7415 | |
| 7416 | +/* | |
| 7417 | +** Register a 2nd-generation geometry callback named zScore that can be | |
| 7418 | +** used as part of an R-Tree geometry query as follows: | |
| 7419 | +** | |
| 7420 | +** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...) | |
| 7421 | +*/ | |
| 7422 | +SQLITE_API int sqlite3_rtree_query_callback( | |
| 7423 | + sqlite3 *db, | |
| 7424 | + const char *zQueryFunc, | |
| 7425 | + int (*xQueryFunc)(sqlite3_rtree_query_info*), | |
| 7426 | + void *pContext, | |
| 7427 | + void (*xDestructor)(void*) | |
| 7428 | +); | |
| 7429 | + | |
| 7430 | + | |
| 7431 | +/* | |
| 7432 | +** A pointer to a structure of the following type is passed as the | |
| 7433 | +** argument to scored geometry callback registered using | |
| 7434 | +** sqlite3_rtree_query_callback(). | |
| 7435 | +** | |
| 7436 | +** Note that the first 5 fields of this structure are identical to | |
| 7437 | +** sqlite3_rtree_geometry. This structure is a subclass of | |
| 7438 | +** sqlite3_rtree_geometry. | |
| 7439 | +*/ | |
| 7440 | +struct sqlite3_rtree_query_info { | |
| 7441 | + void *pContext; /* pContext from when function registered */ | |
| 7442 | + int nParam; /* Number of function parameters */ | |
| 7443 | + sqlite3_rtree_dbl *aParam; /* value of function parameters */ | |
| 7444 | + void *pUser; /* callback can use this, if desired */ | |
| 7445 | + void (*xDelUser)(void*); /* function to free pUser */ | |
| 7446 | + sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */ | |
| 7447 | + unsigned int *anQueue; /* Number of pending entries in the queue */ | |
| 7448 | + int nCoord; /* Number of coordinates */ | |
| 7449 | + int iLevel; /* Level of current node or entry */ | |
| 7450 | + int mxLevel; /* The largest iLevel value in the tree */ | |
| 7451 | + sqlite3_int64 iRowid; /* Rowid for current entry */ | |
| 7452 | + sqlite3_rtree_dbl rParentScore; /* Score of parent node */ | |
| 7453 | + int eParentWithin; /* Visibility of parent node */ | |
| 7454 | + int eWithin; /* OUT: Visiblity */ | |
| 7455 | + sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ | |
| 7456 | +}; | |
| 7457 | + | |
| 7458 | +/* | |
| 7459 | +** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin. | |
| 7460 | +*/ | |
| 7461 | +#define NOT_WITHIN 0 /* Object completely outside of query region */ | |
| 7462 | +#define PARTLY_WITHIN 1 /* Object partially overlaps query region */ | |
| 7463 | +#define FULLY_WITHIN 2 /* Object fully contained within query region */ | |
| 7464 | + | |
| 7381 | 7465 | |
| 7382 | 7466 | #ifdef __cplusplus |
| 7383 | 7467 | } /* end of the 'extern "C"' block */ |
| 7384 | 7468 | #endif |
| 7385 | 7469 | |
| 7386 | 7470 | #endif /* ifndef _SQLITE3RTREE_H_ */ |
| 7387 | 7471 | |
| 7388 | 7472 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.5" |
| 111 | #define SQLITE_VERSION_NUMBER 3008005 |
| 112 | #define SQLITE_SOURCE_ID "2014-04-18 22:20:31 9a5d38c79d2482a23bcfbc3ff35ca4fa269c768d" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -558,11 +558,14 @@ | |
| 558 | ** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that |
| 559 | ** after reboot following a crash or power loss, the only bytes in a |
| 560 | ** file that were written at the application level might have changed |
| 561 | ** and that adjacent bytes, even bytes within the same sector are |
| 562 | ** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
| 563 | ** flag indicate that a file cannot be deleted when open. |
| 564 | */ |
| 565 | #define SQLITE_IOCAP_ATOMIC 0x00000001 |
| 566 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 |
| 567 | #define SQLITE_IOCAP_ATOMIC1K 0x00000004 |
| 568 | #define SQLITE_IOCAP_ATOMIC2K 0x00000008 |
| @@ -573,10 +576,11 @@ | |
| 573 | #define SQLITE_IOCAP_ATOMIC64K 0x00000100 |
| 574 | #define SQLITE_IOCAP_SAFE_APPEND 0x00000200 |
| 575 | #define SQLITE_IOCAP_SEQUENTIAL 0x00000400 |
| 576 | #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 |
| 577 | #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 |
| 578 | |
| 579 | /* |
| 580 | ** CAPI3REF: File Locking Levels |
| 581 | ** |
| 582 | ** SQLite uses one of these integer values as the second |
| @@ -2777,10 +2781,34 @@ | |
| 2777 | ** sqlite3_open_v2(). ^Setting the cache parameter to "private" is |
| 2778 | ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. |
| 2779 | ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in |
| 2780 | ** a URI filename, its value overrides any behavior requested by setting |
| 2781 | ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. |
| 2782 | ** </ul> |
| 2783 | ** |
| 2784 | ** ^Specifying an unknown parameter in the query component of a URI is not an |
| 2785 | ** error. Future versions of SQLite might understand additional query |
| 2786 | ** parameters. See "[query parameters with special meaning to SQLite]" for |
| @@ -2806,12 +2834,13 @@ | |
| 2806 | ** in URI filenames. |
| 2807 | ** <tr><td> file:data.db?mode=ro&cache=private <td> |
| 2808 | ** Open file "data.db" in the current directory for read-only access. |
| 2809 | ** Regardless of whether or not shared-cache mode is enabled by |
| 2810 | ** default, use a private cache. |
| 2811 | ** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td> |
| 2812 | ** Open file "/home/fred/data.db". Use the special VFS "unix-nolock". |
| 2813 | ** <tr><td> file:data.db?mode=readonly <td> |
| 2814 | ** An error. "readonly" is not a valid option for the "mode" parameter. |
| 2815 | ** </table> |
| 2816 | ** |
| 2817 | ** ^URI hexadecimal escape sequences (%HH) are supported within the path and |
| @@ -7345,10 +7374,20 @@ | |
| 7345 | #ifdef __cplusplus |
| 7346 | extern "C" { |
| 7347 | #endif |
| 7348 | |
| 7349 | typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; |
| 7350 | |
| 7351 | /* |
| 7352 | ** Register a geometry callback named zGeom that can be used as part of an |
| 7353 | ** R-Tree geometry query as follows: |
| 7354 | ** |
| @@ -7355,15 +7394,11 @@ | |
| 7355 | ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) |
| 7356 | */ |
| 7357 | SQLITE_API int sqlite3_rtree_geometry_callback( |
| 7358 | sqlite3 *db, |
| 7359 | const char *zGeom, |
| 7360 | #ifdef SQLITE_RTREE_INT_ONLY |
| 7361 | int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes), |
| 7362 | #else |
| 7363 | int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes), |
| 7364 | #endif |
| 7365 | void *pContext |
| 7366 | ); |
| 7367 | |
| 7368 | |
| 7369 | /* |
| @@ -7371,17 +7406,66 @@ | |
| 7371 | ** argument to callbacks registered using rtree_geometry_callback(). |
| 7372 | */ |
| 7373 | struct sqlite3_rtree_geometry { |
| 7374 | void *pContext; /* Copy of pContext passed to s_r_g_c() */ |
| 7375 | int nParam; /* Size of array aParam[] */ |
| 7376 | double *aParam; /* Parameters passed to SQL geom function */ |
| 7377 | void *pUser; /* Callback implementation user data */ |
| 7378 | void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ |
| 7379 | }; |
| 7380 | |
| 7381 | |
| 7382 | #ifdef __cplusplus |
| 7383 | } /* end of the 'extern "C"' block */ |
| 7384 | #endif |
| 7385 | |
| 7386 | #endif /* ifndef _SQLITE3RTREE_H_ */ |
| 7387 | |
| 7388 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.5" |
| 111 | #define SQLITE_VERSION_NUMBER 3008005 |
| 112 | #define SQLITE_SOURCE_ID "2014-05-24 17:15:15 ebfb51fe40756713d269b4c0ade752666910bb6e" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -558,11 +558,14 @@ | |
| 558 | ** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that |
| 559 | ** after reboot following a crash or power loss, the only bytes in a |
| 560 | ** file that were written at the application level might have changed |
| 561 | ** and that adjacent bytes, even bytes within the same sector are |
| 562 | ** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
| 563 | ** flag indicate that a file cannot be deleted when open. The |
| 564 | ** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on |
| 565 | ** read-only media and cannot be changed even by processes with |
| 566 | ** elevated privileges. |
| 567 | */ |
| 568 | #define SQLITE_IOCAP_ATOMIC 0x00000001 |
| 569 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 |
| 570 | #define SQLITE_IOCAP_ATOMIC1K 0x00000004 |
| 571 | #define SQLITE_IOCAP_ATOMIC2K 0x00000008 |
| @@ -573,10 +576,11 @@ | |
| 576 | #define SQLITE_IOCAP_ATOMIC64K 0x00000100 |
| 577 | #define SQLITE_IOCAP_SAFE_APPEND 0x00000200 |
| 578 | #define SQLITE_IOCAP_SEQUENTIAL 0x00000400 |
| 579 | #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 |
| 580 | #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 |
| 581 | #define SQLITE_IOCAP_IMMUTABLE 0x00002000 |
| 582 | |
| 583 | /* |
| 584 | ** CAPI3REF: File Locking Levels |
| 585 | ** |
| 586 | ** SQLite uses one of these integer values as the second |
| @@ -2777,10 +2781,34 @@ | |
| 2781 | ** sqlite3_open_v2(). ^Setting the cache parameter to "private" is |
| 2782 | ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. |
| 2783 | ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in |
| 2784 | ** a URI filename, its value overrides any behavior requested by setting |
| 2785 | ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. |
| 2786 | ** |
| 2787 | ** <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or |
| 2788 | ** "1") or "false" (or "off" or "no" or "0") to indicate that the |
| 2789 | ** [powersafe overwrite] property does or does not apply to the |
| 2790 | ** storage media on which the database file resides. ^The psow query |
| 2791 | ** parameter only works for the built-in unix and Windows VFSes. |
| 2792 | ** |
| 2793 | ** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter |
| 2794 | ** which if set disables file locking in rollback journal modes. This |
| 2795 | ** is useful for accessing a database on a filesystem that does not |
| 2796 | ** support locking. Caution: Database corruption might result if two |
| 2797 | ** or more processes write to the same database and any one of those |
| 2798 | ** processes uses nolock=1. |
| 2799 | ** |
| 2800 | ** <li> <b>immutable</b>: ^The immutable parameter is a boolean query |
| 2801 | ** parameter that indicates that the database file is stored on |
| 2802 | ** read-only media. ^When immutable is set, SQLite assumes that the |
| 2803 | ** database file cannot be changed, even by a process with higher |
| 2804 | ** privilege, and so the database is opened read-only and all locking |
| 2805 | ** and change detection is disabled. Caution: Setting the immutable |
| 2806 | ** property on a database file that does in fact change can result |
| 2807 | ** in incorrect query results and/or [SQLITE_CORRUPT] errors. |
| 2808 | ** See also: [SQLITE_IOCAP_IMMUTABLE]. |
| 2809 | ** |
| 2810 | ** </ul> |
| 2811 | ** |
| 2812 | ** ^Specifying an unknown parameter in the query component of a URI is not an |
| 2813 | ** error. Future versions of SQLite might understand additional query |
| 2814 | ** parameters. See "[query parameters with special meaning to SQLite]" for |
| @@ -2806,12 +2834,13 @@ | |
| 2834 | ** in URI filenames. |
| 2835 | ** <tr><td> file:data.db?mode=ro&cache=private <td> |
| 2836 | ** Open file "data.db" in the current directory for read-only access. |
| 2837 | ** Regardless of whether or not shared-cache mode is enabled by |
| 2838 | ** default, use a private cache. |
| 2839 | ** <tr><td> file:/home/fred/data.db?vfs=unix-dotfile <td> |
| 2840 | ** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile" |
| 2841 | ** that uses dot-files in place of posix advisory locking. |
| 2842 | ** <tr><td> file:data.db?mode=readonly <td> |
| 2843 | ** An error. "readonly" is not a valid option for the "mode" parameter. |
| 2844 | ** </table> |
| 2845 | ** |
| 2846 | ** ^URI hexadecimal escape sequences (%HH) are supported within the path and |
| @@ -7345,10 +7374,20 @@ | |
| 7374 | #ifdef __cplusplus |
| 7375 | extern "C" { |
| 7376 | #endif |
| 7377 | |
| 7378 | typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; |
| 7379 | typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; |
| 7380 | |
| 7381 | /* The double-precision datatype used by RTree depends on the |
| 7382 | ** SQLITE_RTREE_INT_ONLY compile-time option. |
| 7383 | */ |
| 7384 | #ifdef SQLITE_RTREE_INT_ONLY |
| 7385 | typedef sqlite3_int64 sqlite3_rtree_dbl; |
| 7386 | #else |
| 7387 | typedef double sqlite3_rtree_dbl; |
| 7388 | #endif |
| 7389 | |
| 7390 | /* |
| 7391 | ** Register a geometry callback named zGeom that can be used as part of an |
| 7392 | ** R-Tree geometry query as follows: |
| 7393 | ** |
| @@ -7355,15 +7394,11 @@ | |
| 7394 | ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) |
| 7395 | */ |
| 7396 | SQLITE_API int sqlite3_rtree_geometry_callback( |
| 7397 | sqlite3 *db, |
| 7398 | const char *zGeom, |
| 7399 | int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), |
| 7400 | void *pContext |
| 7401 | ); |
| 7402 | |
| 7403 | |
| 7404 | /* |
| @@ -7371,17 +7406,66 @@ | |
| 7406 | ** argument to callbacks registered using rtree_geometry_callback(). |
| 7407 | */ |
| 7408 | struct sqlite3_rtree_geometry { |
| 7409 | void *pContext; /* Copy of pContext passed to s_r_g_c() */ |
| 7410 | int nParam; /* Size of array aParam[] */ |
| 7411 | sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */ |
| 7412 | void *pUser; /* Callback implementation user data */ |
| 7413 | void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ |
| 7414 | }; |
| 7415 | |
| 7416 | /* |
| 7417 | ** Register a 2nd-generation geometry callback named zScore that can be |
| 7418 | ** used as part of an R-Tree geometry query as follows: |
| 7419 | ** |
| 7420 | ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...) |
| 7421 | */ |
| 7422 | SQLITE_API int sqlite3_rtree_query_callback( |
| 7423 | sqlite3 *db, |
| 7424 | const char *zQueryFunc, |
| 7425 | int (*xQueryFunc)(sqlite3_rtree_query_info*), |
| 7426 | void *pContext, |
| 7427 | void (*xDestructor)(void*) |
| 7428 | ); |
| 7429 | |
| 7430 | |
| 7431 | /* |
| 7432 | ** A pointer to a structure of the following type is passed as the |
| 7433 | ** argument to scored geometry callback registered using |
| 7434 | ** sqlite3_rtree_query_callback(). |
| 7435 | ** |
| 7436 | ** Note that the first 5 fields of this structure are identical to |
| 7437 | ** sqlite3_rtree_geometry. This structure is a subclass of |
| 7438 | ** sqlite3_rtree_geometry. |
| 7439 | */ |
| 7440 | struct sqlite3_rtree_query_info { |
| 7441 | void *pContext; /* pContext from when function registered */ |
| 7442 | int nParam; /* Number of function parameters */ |
| 7443 | sqlite3_rtree_dbl *aParam; /* value of function parameters */ |
| 7444 | void *pUser; /* callback can use this, if desired */ |
| 7445 | void (*xDelUser)(void*); /* function to free pUser */ |
| 7446 | sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */ |
| 7447 | unsigned int *anQueue; /* Number of pending entries in the queue */ |
| 7448 | int nCoord; /* Number of coordinates */ |
| 7449 | int iLevel; /* Level of current node or entry */ |
| 7450 | int mxLevel; /* The largest iLevel value in the tree */ |
| 7451 | sqlite3_int64 iRowid; /* Rowid for current entry */ |
| 7452 | sqlite3_rtree_dbl rParentScore; /* Score of parent node */ |
| 7453 | int eParentWithin; /* Visibility of parent node */ |
| 7454 | int eWithin; /* OUT: Visiblity */ |
| 7455 | sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ |
| 7456 | }; |
| 7457 | |
| 7458 | /* |
| 7459 | ** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin. |
| 7460 | */ |
| 7461 | #define NOT_WITHIN 0 /* Object completely outside of query region */ |
| 7462 | #define PARTLY_WITHIN 1 /* Object partially overlaps query region */ |
| 7463 | #define FULLY_WITHIN 2 /* Object fully contained within query region */ |
| 7464 | |
| 7465 | |
| 7466 | #ifdef __cplusplus |
| 7467 | } /* end of the 'extern "C"' block */ |
| 7468 | #endif |
| 7469 | |
| 7470 | #endif /* ifndef _SQLITE3RTREE_H_ */ |
| 7471 | |
| 7472 |