| | @@ -673,11 +673,11 @@ |
| 673 | 673 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 674 | 674 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 675 | 675 | */ |
| 676 | 676 | #define SQLITE_VERSION "3.7.15" |
| 677 | 677 | #define SQLITE_VERSION_NUMBER 3007015 |
| 678 | | -#define SQLITE_SOURCE_ID "2012-10-05 07:36:34 43155b1543bddbb84a8bc13a5b7344b228ddacb9" |
| 678 | +#define SQLITE_SOURCE_ID "2012-10-09 01:39:25 01dc032b5bbd9c9ebb1965f176ca5d732cda85ea" |
| 679 | 679 | |
| 680 | 680 | /* |
| 681 | 681 | ** CAPI3REF: Run-Time Library Version Numbers |
| 682 | 682 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 683 | 683 | ** |
| | @@ -10905,10 +10905,11 @@ |
| 10905 | 10905 | */ |
| 10906 | 10906 | struct SrcList { |
| 10907 | 10907 | i16 nSrc; /* Number of tables or subqueries in the FROM clause */ |
| 10908 | 10908 | i16 nAlloc; /* Number of entries allocated in a[] below */ |
| 10909 | 10909 | struct SrcList_item { |
| 10910 | + Schema *pSchema; /* Schema to which this item is fixed */ |
| 10910 | 10911 | char *zDatabase; /* Name of database holding this table */ |
| 10911 | 10912 | char *zName; /* Name of the table */ |
| 10912 | 10913 | char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ |
| 10913 | 10914 | Table *pTab; /* An SQL table corresponding to zName */ |
| 10914 | 10915 | Select *pSelect; /* A SELECT statement used in place of a table name */ |
| | @@ -11473,10 +11474,11 @@ |
| 11473 | 11474 | ** explicit. |
| 11474 | 11475 | */ |
| 11475 | 11476 | typedef struct DbFixer DbFixer; |
| 11476 | 11477 | struct DbFixer { |
| 11477 | 11478 | Parse *pParse; /* The parsing context. Error messages written here */ |
| 11479 | + Schema *pSchema; /* Fix items to this schema */ |
| 11478 | 11480 | const char *zDb; /* Make sure all objects are contained in this database */ |
| 11479 | 11481 | const char *zType; /* Type of the container - used for error messages */ |
| 11480 | 11482 | const Token *pName; /* Name of the container - used for error messages */ |
| 11481 | 11483 | }; |
| 11482 | 11484 | |
| | @@ -11883,10 +11885,11 @@ |
| 11883 | 11885 | SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int); |
| 11884 | 11886 | SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int); |
| 11885 | 11887 | SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int); |
| 11886 | 11888 | SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*); |
| 11887 | 11889 | SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*); |
| 11890 | +SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *); |
| 11888 | 11891 | SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*); |
| 11889 | 11892 | SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); |
| 11890 | 11893 | SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); |
| 11891 | 11894 | SQLITE_PRIVATE void sqlite3Vacuum(Parse*); |
| 11892 | 11895 | SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*); |
| | @@ -12113,11 +12116,11 @@ |
| 12113 | 12116 | SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); |
| 12114 | 12117 | SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); |
| 12115 | 12118 | SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); |
| 12116 | 12119 | SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); |
| 12117 | 12120 | SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); |
| 12118 | | -SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(sqlite3*, u8, CollSeq *, const char*); |
| 12121 | +SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); |
| 12119 | 12122 | SQLITE_PRIVATE char sqlite3AffinityType(const char*); |
| 12120 | 12123 | SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*); |
| 12121 | 12124 | SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*); |
| 12122 | 12125 | SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*); |
| 12123 | 12126 | SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *); |
| | @@ -29968,10 +29971,61 @@ |
| 29968 | 29971 | #if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) |
| 29969 | 29972 | # error "WAL mode requires support from the Windows NT kernel, compile\ |
| 29970 | 29973 | with SQLITE_OMIT_WAL." |
| 29971 | 29974 | #endif |
| 29972 | 29975 | |
| 29976 | +/* |
| 29977 | +** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions |
| 29978 | +** based on the sub-platform)? |
| 29979 | +*/ |
| 29980 | +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT |
| 29981 | +# define SQLITE_WIN32_HAS_ANSI |
| 29982 | +#endif |
| 29983 | + |
| 29984 | +/* |
| 29985 | +** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions |
| 29986 | +** based on the sub-platform)? |
| 29987 | +*/ |
| 29988 | +#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT |
| 29989 | +# define SQLITE_WIN32_HAS_WIDE |
| 29990 | +#endif |
| 29991 | + |
| 29992 | +/* |
| 29993 | +** Do we need to manually define the Win32 file mapping APIs for use with WAL |
| 29994 | +** mode (e.g. these APIs are available in the Windows CE SDK; however, they |
| 29995 | +** are not present in the header file)? |
| 29996 | +*/ |
| 29997 | +#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) |
| 29998 | +/* |
| 29999 | +** Two of the file mapping APIs are different under WinRT. Figure out which |
| 30000 | +** set we need. |
| 30001 | +*/ |
| 30002 | +#if SQLITE_OS_WINRT |
| 30003 | +WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \ |
| 30004 | + LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR); |
| 30005 | + |
| 30006 | +WINBASEAPI LPVOID WINAPI MapViewOfFileFromApp(HANDLE, ULONG, ULONG64, SIZE_T); |
| 30007 | +#else |
| 30008 | +#if defined(SQLITE_WIN32_HAS_ANSI) |
| 30009 | +WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, \ |
| 30010 | + DWORD, DWORD, DWORD, LPCSTR); |
| 30011 | +#endif /* defined(SQLITE_WIN32_HAS_ANSI) */ |
| 30012 | + |
| 30013 | +#if defined(SQLITE_WIN32_HAS_WIDE) |
| 30014 | +WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \ |
| 30015 | + DWORD, DWORD, DWORD, LPCWSTR); |
| 30016 | +#endif /* defined(SQLITE_WIN32_HAS_WIDE) */ |
| 30017 | + |
| 30018 | +WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T); |
| 30019 | +#endif /* SQLITE_OS_WINRT */ |
| 30020 | + |
| 30021 | +/* |
| 30022 | +** This file mapping API is common to both Win32 and WinRT. |
| 30023 | +*/ |
| 30024 | +WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID); |
| 30025 | +#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */ |
| 30026 | + |
| 29973 | 30027 | /* |
| 29974 | 30028 | ** Macro to find the minimum of two numeric values. |
| 29975 | 30029 | */ |
| 29976 | 30030 | #ifndef MIN |
| 29977 | 30031 | # define MIN(x,y) ((x)<(y)?(x):(y)) |
| | @@ -30173,18 +30227,10 @@ |
| 30173 | 30227 | SQLITE_API int sqlite3_os_type = 0; |
| 30174 | 30228 | #else |
| 30175 | 30229 | static int sqlite3_os_type = 0; |
| 30176 | 30230 | #endif |
| 30177 | 30231 | |
| 30178 | | -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT |
| 30179 | | -# define SQLITE_WIN32_HAS_ANSI |
| 30180 | | -#endif |
| 30181 | | - |
| 30182 | | -#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT |
| 30183 | | -# define SQLITE_WIN32_HAS_WIDE |
| 30184 | | -#endif |
| 30185 | | - |
| 30186 | 30232 | #ifndef SYSCALL |
| 30187 | 30233 | # define SYSCALL sqlite3_syscall_ptr |
| 30188 | 30234 | #endif |
| 30189 | 30235 | |
| 30190 | 30236 | /* |
| | @@ -30337,11 +30383,15 @@ |
| 30337 | 30383 | #endif |
| 30338 | 30384 | |
| 30339 | 30385 | #define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \ |
| 30340 | 30386 | DWORD,va_list*))aSyscall[15].pCurrent) |
| 30341 | 30387 | |
| 30388 | +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 30342 | 30389 | { "FreeLibrary", (SYSCALL)FreeLibrary, 0 }, |
| 30390 | +#else |
| 30391 | + { "FreeLibrary", (SYSCALL)0, 0 }, |
| 30392 | +#endif |
| 30343 | 30393 | |
| 30344 | 30394 | #define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent) |
| 30345 | 30395 | |
| 30346 | 30396 | { "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 }, |
| 30347 | 30397 | |
| | @@ -30418,18 +30468,22 @@ |
| 30418 | 30468 | |
| 30419 | 30469 | { "GetLastError", (SYSCALL)GetLastError, 0 }, |
| 30420 | 30470 | |
| 30421 | 30471 | #define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) |
| 30422 | 30472 | |
| 30473 | +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 30423 | 30474 | #if SQLITE_OS_WINCE |
| 30424 | 30475 | /* The GetProcAddressA() routine is only available on Windows CE. */ |
| 30425 | 30476 | { "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 }, |
| 30426 | 30477 | #else |
| 30427 | 30478 | /* All other Windows platforms expect GetProcAddress() to take |
| 30428 | 30479 | ** an ANSI string regardless of the _UNICODE setting */ |
| 30429 | 30480 | { "GetProcAddressA", (SYSCALL)GetProcAddress, 0 }, |
| 30430 | 30481 | #endif |
| 30482 | +#else |
| 30483 | + { "GetProcAddressA", (SYSCALL)0, 0 }, |
| 30484 | +#endif |
| 30431 | 30485 | |
| 30432 | 30486 | #define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \ |
| 30433 | 30487 | LPCSTR))aSyscall[27].pCurrent) |
| 30434 | 30488 | |
| 30435 | 30489 | #if !SQLITE_OS_WINRT |
| | @@ -30529,19 +30583,20 @@ |
| 30529 | 30583 | #endif |
| 30530 | 30584 | |
| 30531 | 30585 | #define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ |
| 30532 | 30586 | LPCVOID))aSyscall[41].pCurrent) |
| 30533 | 30587 | |
| 30534 | | -#if defined(SQLITE_WIN32_HAS_ANSI) |
| 30588 | +#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 30535 | 30589 | { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 }, |
| 30536 | 30590 | #else |
| 30537 | 30591 | { "LoadLibraryA", (SYSCALL)0, 0 }, |
| 30538 | 30592 | #endif |
| 30539 | 30593 | |
| 30540 | 30594 | #define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent) |
| 30541 | 30595 | |
| 30542 | | -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) |
| 30596 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ |
| 30597 | + !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 30543 | 30598 | { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, |
| 30544 | 30599 | #else |
| 30545 | 30600 | { "LoadLibraryW", (SYSCALL)0, 0 }, |
| 30546 | 30601 | #endif |
| 30547 | 30602 | |
| | @@ -30726,11 +30781,11 @@ |
| 30726 | 30781 | #endif |
| 30727 | 30782 | |
| 30728 | 30783 | #define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \ |
| 30729 | 30784 | LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent) |
| 30730 | 30785 | |
| 30731 | | -#if SQLITE_OS_WINRT |
| 30786 | +#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 30732 | 30787 | { "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 }, |
| 30733 | 30788 | #else |
| 30734 | 30789 | { "LoadPackagedLibrary", (SYSCALL)0, 0 }, |
| 30735 | 30790 | #endif |
| 30736 | 30791 | |
| | @@ -60050,11 +60105,13 @@ |
| 60050 | 60105 | for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ |
| 60051 | 60106 | Btree *pBt = db->aDb[i].pBt; |
| 60052 | 60107 | if( sqlite3BtreeIsInTrans(pBt) ){ |
| 60053 | 60108 | needXcommit = 1; |
| 60054 | 60109 | if( i!=1 ) nTrans++; |
| 60110 | + sqlite3BtreeEnter(pBt); |
| 60055 | 60111 | rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt)); |
| 60112 | + sqlite3BtreeLeave(pBt); |
| 60056 | 60113 | } |
| 60057 | 60114 | } |
| 60058 | 60115 | if( rc!=SQLITE_OK ){ |
| 60059 | 60116 | return rc; |
| 60060 | 60117 | } |
| | @@ -74362,10 +74419,11 @@ |
| 74362 | 74419 | pNew->nSrc = pNew->nAlloc = p->nSrc; |
| 74363 | 74420 | for(i=0; i<p->nSrc; i++){ |
| 74364 | 74421 | struct SrcList_item *pNewItem = &pNew->a[i]; |
| 74365 | 74422 | struct SrcList_item *pOldItem = &p->a[i]; |
| 74366 | 74423 | Table *pTab; |
| 74424 | + pNewItem->pSchema = pOldItem->pSchema; |
| 74367 | 74425 | pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); |
| 74368 | 74426 | pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); |
| 74369 | 74427 | pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); |
| 74370 | 74428 | pNewItem->jointype = pOldItem->jointype; |
| 74371 | 74429 | pNewItem->iCursor = pOldItem->iCursor; |
| | @@ -77988,11 +78046,11 @@ |
| 77988 | 78046 | savedDbFlags = db->flags; |
| 77989 | 78047 | if( NEVER(db->mallocFailed) ) goto exit_rename_table; |
| 77990 | 78048 | assert( pSrc->nSrc==1 ); |
| 77991 | 78049 | assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); |
| 77992 | 78050 | |
| 77993 | | - pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase); |
| 78051 | + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); |
| 77994 | 78052 | if( !pTab ) goto exit_rename_table; |
| 77995 | 78053 | iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); |
| 77996 | 78054 | zDb = db->aDb[iDb].zName; |
| 77997 | 78055 | db->flags |= SQLITE_PreferBuiltin; |
| 77998 | 78056 | |
| | @@ -78331,11 +78389,11 @@ |
| 78331 | 78389 | |
| 78332 | 78390 | /* Look up the table being altered. */ |
| 78333 | 78391 | assert( pParse->pNewTable==0 ); |
| 78334 | 78392 | assert( sqlite3BtreeHoldsAllMutexes(db) ); |
| 78335 | 78393 | if( db->mallocFailed ) goto exit_begin_add_column; |
| 78336 | | - pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase); |
| 78394 | + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); |
| 78337 | 78395 | if( !pTab ) goto exit_begin_add_column; |
| 78338 | 78396 | |
| 78339 | 78397 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 78340 | 78398 | if( IsVirtual(pTab) ){ |
| 78341 | 78399 | sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); |
| | @@ -79962,10 +80020,11 @@ |
| 79962 | 80020 | if( NEVER(iDb<0) || iDb==1 ) return 0; |
| 79963 | 80021 | db = pParse->db; |
| 79964 | 80022 | assert( db->nDb>iDb ); |
| 79965 | 80023 | pFix->pParse = pParse; |
| 79966 | 80024 | pFix->zDb = db->aDb[iDb].zName; |
| 80025 | + pFix->pSchema = db->aDb[iDb].pSchema; |
| 79967 | 80026 | pFix->zType = zType; |
| 79968 | 80027 | pFix->pName = pName; |
| 79969 | 80028 | return 1; |
| 79970 | 80029 | } |
| 79971 | 80030 | |
| | @@ -79992,18 +80051,19 @@ |
| 79992 | 80051 | struct SrcList_item *pItem; |
| 79993 | 80052 | |
| 79994 | 80053 | if( NEVER(pList==0) ) return 0; |
| 79995 | 80054 | zDb = pFix->zDb; |
| 79996 | 80055 | for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ |
| 79997 | | - if( pItem->zDatabase==0 ){ |
| 79998 | | - pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb); |
| 79999 | | - }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){ |
| 80056 | + if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ |
| 80000 | 80057 | sqlite3ErrorMsg(pFix->pParse, |
| 80001 | 80058 | "%s %T cannot reference objects in database %s", |
| 80002 | 80059 | pFix->zType, pFix->pName, pItem->zDatabase); |
| 80003 | 80060 | return 1; |
| 80004 | 80061 | } |
| 80062 | + sqlite3_free(pItem->zDatabase); |
| 80063 | + pItem->zDatabase = 0; |
| 80064 | + pItem->pSchema = pFix->pSchema; |
| 80005 | 80065 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) |
| 80006 | 80066 | if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; |
| 80007 | 80067 | if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; |
| 80008 | 80068 | #endif |
| 80009 | 80069 | } |
| | @@ -80656,10 +80716,35 @@ |
| 80656 | 80716 | } |
| 80657 | 80717 | pParse->checkSchema = 1; |
| 80658 | 80718 | } |
| 80659 | 80719 | return p; |
| 80660 | 80720 | } |
| 80721 | + |
| 80722 | +/* |
| 80723 | +** Locate the table identified by *p. |
| 80724 | +** |
| 80725 | +** This is a wrapper around sqlite3LocateTable(). The difference between |
| 80726 | +** sqlite3LocateTable() and this function is that this function restricts |
| 80727 | +** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be |
| 80728 | +** non-NULL if it is part of a view or trigger program definition. See |
| 80729 | +** sqlite3FixSrcList() for details. |
| 80730 | +*/ |
| 80731 | +SQLITE_PRIVATE Table *sqlite3LocateTableItem( |
| 80732 | + Parse *pParse, |
| 80733 | + int isView, |
| 80734 | + struct SrcList_item *p |
| 80735 | +){ |
| 80736 | + const char *zDb; |
| 80737 | + assert( p->pSchema==0 || p->zDatabase==0 ); |
| 80738 | + if( p->pSchema ){ |
| 80739 | + int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); |
| 80740 | + zDb = pParse->db->aDb[iDb].zName; |
| 80741 | + }else{ |
| 80742 | + zDb = p->zDatabase; |
| 80743 | + } |
| 80744 | + return sqlite3LocateTable(pParse, isView, p->zName, zDb); |
| 80745 | +} |
| 80661 | 80746 | |
| 80662 | 80747 | /* |
| 80663 | 80748 | ** Locate the in-memory structure that describes |
| 80664 | 80749 | ** a particular index given the name of that index |
| 80665 | 80750 | ** and the name of the database that contains the index. |
| | @@ -81633,14 +81718,11 @@ |
| 81633 | 81718 | u8 initbusy = db->init.busy; |
| 81634 | 81719 | CollSeq *pColl; |
| 81635 | 81720 | |
| 81636 | 81721 | pColl = sqlite3FindCollSeq(db, enc, zName, initbusy); |
| 81637 | 81722 | if( !initbusy && (!pColl || !pColl->xCmp) ){ |
| 81638 | | - pColl = sqlite3GetCollSeq(db, enc, pColl, zName); |
| 81639 | | - if( !pColl ){ |
| 81640 | | - sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); |
| 81641 | | - } |
| 81723 | + pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName); |
| 81642 | 81724 | } |
| 81643 | 81725 | |
| 81644 | 81726 | return pColl; |
| 81645 | 81727 | } |
| 81646 | 81728 | |
| | @@ -82452,12 +82534,11 @@ |
| 82452 | 82534 | goto exit_drop_table; |
| 82453 | 82535 | } |
| 82454 | 82536 | assert( pParse->nErr==0 ); |
| 82455 | 82537 | assert( pName->nSrc==1 ); |
| 82456 | 82538 | if( noErr ) db->suppressErr++; |
| 82457 | | - pTab = sqlite3LocateTable(pParse, isView, |
| 82458 | | - pName->a[0].zName, pName->a[0].zDatabase); |
| 82539 | + pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); |
| 82459 | 82540 | if( noErr ) db->suppressErr--; |
| 82460 | 82541 | |
| 82461 | 82542 | if( pTab==0 ){ |
| 82462 | 82543 | if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); |
| 82463 | 82544 | goto exit_drop_table; |
| | @@ -82893,13 +82974,13 @@ |
| 82893 | 82974 | ){ |
| 82894 | 82975 | /* Because the parser constructs pTblName from a single identifier, |
| 82895 | 82976 | ** sqlite3FixSrcList can never fail. */ |
| 82896 | 82977 | assert(0); |
| 82897 | 82978 | } |
| 82898 | | - pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName, |
| 82899 | | - pTblName->a[0].zDatabase); |
| 82900 | | - if( !pTab || db->mallocFailed ) goto exit_create_index; |
| 82979 | + pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]); |
| 82980 | + assert( db->mallocFailed==0 || pTab==0 ); |
| 82981 | + if( pTab==0 ) goto exit_create_index; |
| 82901 | 82982 | assert( db->aDb[iDb].pSchema==pTab->pSchema ); |
| 82902 | 82983 | }else{ |
| 82903 | 82984 | assert( pName==0 ); |
| 82904 | 82985 | assert( pStart==0 ); |
| 82905 | 82986 | pTab = pParse->pNewTable; |
| | @@ -84254,21 +84335,22 @@ |
| 84254 | 84335 | ** If it is not NULL, then pColl must point to the database native encoding |
| 84255 | 84336 | ** collation sequence with name zName, length nName. |
| 84256 | 84337 | ** |
| 84257 | 84338 | ** The return value is either the collation sequence to be used in database |
| 84258 | 84339 | ** db for collation type name zName, length nName, or NULL, if no collation |
| 84259 | | -** sequence can be found. |
| 84340 | +** sequence can be found. If no collation is found, leave an error message. |
| 84260 | 84341 | ** |
| 84261 | 84342 | ** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq() |
| 84262 | 84343 | */ |
| 84263 | 84344 | SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq( |
| 84264 | | - sqlite3* db, /* The database connection */ |
| 84345 | + Parse *pParse, /* Parsing context */ |
| 84265 | 84346 | u8 enc, /* The desired encoding for the collating sequence */ |
| 84266 | 84347 | CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ |
| 84267 | 84348 | const char *zName /* Collating sequence name */ |
| 84268 | 84349 | ){ |
| 84269 | 84350 | CollSeq *p; |
| 84351 | + sqlite3 *db = pParse->db; |
| 84270 | 84352 | |
| 84271 | 84353 | p = pColl; |
| 84272 | 84354 | if( !p ){ |
| 84273 | 84355 | p = sqlite3FindCollSeq(db, enc, zName, 0); |
| 84274 | 84356 | } |
| | @@ -84281,10 +84363,13 @@ |
| 84281 | 84363 | } |
| 84282 | 84364 | if( p && !p->xCmp && synthCollSeq(db, p) ){ |
| 84283 | 84365 | p = 0; |
| 84284 | 84366 | } |
| 84285 | 84367 | assert( !p || p->xCmp ); |
| 84368 | + if( p==0 ){ |
| 84369 | + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); |
| 84370 | + } |
| 84286 | 84371 | return p; |
| 84287 | 84372 | } |
| 84288 | 84373 | |
| 84289 | 84374 | /* |
| 84290 | 84375 | ** This routine is called on a collation sequence before it is used to |
| | @@ -84299,14 +84384,12 @@ |
| 84299 | 84384 | */ |
| 84300 | 84385 | SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ |
| 84301 | 84386 | if( pColl ){ |
| 84302 | 84387 | const char *zName = pColl->zName; |
| 84303 | 84388 | sqlite3 *db = pParse->db; |
| 84304 | | - CollSeq *p = sqlite3GetCollSeq(db, ENC(db), pColl, zName); |
| 84389 | + CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName); |
| 84305 | 84390 | if( !p ){ |
| 84306 | | - sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); |
| 84307 | | - pParse->nErr++; |
| 84308 | 84391 | return SQLITE_ERROR; |
| 84309 | 84392 | } |
| 84310 | 84393 | assert( p==pColl ); |
| 84311 | 84394 | } |
| 84312 | 84395 | return SQLITE_OK; |
| | @@ -84689,11 +84772,11 @@ |
| 84689 | 84772 | */ |
| 84690 | 84773 | SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ |
| 84691 | 84774 | struct SrcList_item *pItem = pSrc->a; |
| 84692 | 84775 | Table *pTab; |
| 84693 | 84776 | assert( pItem && pSrc->nSrc==1 ); |
| 84694 | | - pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase); |
| 84777 | + pTab = sqlite3LocateTableItem(pParse, 0, pItem); |
| 84695 | 84778 | sqlite3DeleteTable(pParse->db, pItem->pTab); |
| 84696 | 84779 | pItem->pTab = pTab; |
| 84697 | 84780 | if( pTab ){ |
| 84698 | 84781 | pTab->nRef++; |
| 84699 | 84782 | } |
| | @@ -89415,24 +89498,29 @@ |
| 89415 | 89498 | ExprList *pCheck = pTab->pCheck; |
| 89416 | 89499 | pParse->ckBase = regData; |
| 89417 | 89500 | onError = overrideError!=OE_Default ? overrideError : OE_Abort; |
| 89418 | 89501 | for(i=0; i<pCheck->nExpr; i++){ |
| 89419 | 89502 | int allOk = sqlite3VdbeMakeLabel(v); |
| 89420 | | - sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL); |
| 89421 | | - if( onError==OE_Ignore ){ |
| 89422 | | - sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); |
| 89423 | | - }else{ |
| 89424 | | - char *zConsName = pCheck->a[i].zName; |
| 89425 | | - if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */ |
| 89426 | | - if( zConsName ){ |
| 89427 | | - zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName); |
| 89428 | | - }else{ |
| 89429 | | - zConsName = 0; |
| 89430 | | - } |
| 89431 | | - sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC); |
| 89432 | | - } |
| 89433 | | - sqlite3VdbeResolveLabel(v, allOk); |
| 89503 | + Expr *pDup = sqlite3ExprDup(db, pCheck->a[i].pExpr, 0); |
| 89504 | + if( !db->mallocFailed ){ |
| 89505 | + assert( pDup!=0 ); |
| 89506 | + sqlite3ExprIfTrue(pParse, pDup, allOk, SQLITE_JUMPIFNULL); |
| 89507 | + if( onError==OE_Ignore ){ |
| 89508 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); |
| 89509 | + }else{ |
| 89510 | + char *zConsName = pCheck->a[i].zName; |
| 89511 | + if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */ |
| 89512 | + if( zConsName ){ |
| 89513 | + zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName); |
| 89514 | + }else{ |
| 89515 | + zConsName = 0; |
| 89516 | + } |
| 89517 | + sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC); |
| 89518 | + } |
| 89519 | + sqlite3VdbeResolveLabel(v, allOk); |
| 89520 | + } |
| 89521 | + sqlite3ExprDelete(db, pDup); |
| 89434 | 89522 | } |
| 89435 | 89523 | } |
| 89436 | 89524 | #endif /* !defined(SQLITE_OMIT_CHECK) */ |
| 89437 | 89525 | |
| 89438 | 89526 | /* If we have an INTEGER PRIMARY KEY, make sure the primary key |
| | @@ -89884,11 +89972,11 @@ |
| 89884 | 89972 | /* At this point we have established that the statement is of the |
| 89885 | 89973 | ** correct syntactic form to participate in this optimization. Now |
| 89886 | 89974 | ** we have to check the semantics. |
| 89887 | 89975 | */ |
| 89888 | 89976 | pItem = pSelect->pSrc->a; |
| 89889 | | - pSrc = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase); |
| 89977 | + pSrc = sqlite3LocateTableItem(pParse, 0, pItem); |
| 89890 | 89978 | if( pSrc==0 ){ |
| 89891 | 89979 | return 0; /* FROM clause does not contain a real table */ |
| 89892 | 89980 | } |
| 89893 | 89981 | if( pSrc==pDest ){ |
| 89894 | 89982 | return 0; /* tab1 and tab2 may not be the same table */ |
| | @@ -97153,12 +97241,11 @@ |
| 97153 | 97241 | pTab->tabFlags |= TF_Ephemeral; |
| 97154 | 97242 | #endif |
| 97155 | 97243 | }else{ |
| 97156 | 97244 | /* An ordinary table or view name in the FROM clause */ |
| 97157 | 97245 | assert( pFrom->pTab==0 ); |
| 97158 | | - pFrom->pTab = pTab = |
| 97159 | | - sqlite3LocateTable(pParse,0,pFrom->zName,pFrom->zDatabase); |
| 97246 | + pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); |
| 97160 | 97247 | if( pTab==0 ) return WRC_Abort; |
| 97161 | 97248 | pTab->nRef++; |
| 97162 | 97249 | #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) |
| 97163 | 97250 | if( pTab->pSelect || IsVirtual(pTab) ){ |
| 97164 | 97251 | /* We reach here if the named table is a really a view */ |
| | @@ -101095,10 +101182,11 @@ |
| 101095 | 101182 | */ |
| 101096 | 101183 | SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){ |
| 101097 | 101184 | if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); |
| 101098 | 101185 | if( p->azModuleArg ){ |
| 101099 | 101186 | int i; |
| 101187 | + assert( p->nModuleArg<2 || p->azModuleArg[1]==0 ); |
| 101100 | 101188 | for(i=0; i<p->nModuleArg; i++){ |
| 101101 | 101189 | sqlite3DbFree(db, p->azModuleArg[i]); |
| 101102 | 101190 | } |
| 101103 | 101191 | sqlite3DbFree(db, p->azModuleArg); |
| 101104 | 101192 | } |
| | @@ -101156,11 +101244,11 @@ |
| 101156 | 101244 | assert( iDb>=0 ); |
| 101157 | 101245 | |
| 101158 | 101246 | pTable->tabFlags |= TF_Virtual; |
| 101159 | 101247 | pTable->nModuleArg = 0; |
| 101160 | 101248 | addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); |
| 101161 | | - addModuleArgument(db, pTable, sqlite3DbStrDup(db, db->aDb[iDb].zName)); |
| 101249 | + addModuleArgument(db, pTable, 0); |
| 101162 | 101250 | addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName)); |
| 101163 | 101251 | pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z); |
| 101164 | 101252 | |
| 101165 | 101253 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| 101166 | 101254 | /* Creating a virtual table invokes the authorization callback twice. |
| | @@ -101313,10 +101401,11 @@ |
| 101313 | 101401 | int rc; |
| 101314 | 101402 | const char *const*azArg = (const char *const*)pTab->azModuleArg; |
| 101315 | 101403 | int nArg = pTab->nModuleArg; |
| 101316 | 101404 | char *zErr = 0; |
| 101317 | 101405 | char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); |
| 101406 | + int iDb; |
| 101318 | 101407 | |
| 101319 | 101408 | if( !zModuleName ){ |
| 101320 | 101409 | return SQLITE_NOMEM; |
| 101321 | 101410 | } |
| 101322 | 101411 | |
| | @@ -101326,10 +101415,14 @@ |
| 101326 | 101415 | return SQLITE_NOMEM; |
| 101327 | 101416 | } |
| 101328 | 101417 | pVTable->db = db; |
| 101329 | 101418 | pVTable->pMod = pMod; |
| 101330 | 101419 | |
| 101420 | + assert( pTab->azModuleArg[1]==0 ); |
| 101421 | + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
| 101422 | + pTab->azModuleArg[1] = db->aDb[iDb].zName; |
| 101423 | + |
| 101331 | 101424 | /* Invoke the virtual table constructor */ |
| 101332 | 101425 | assert( &db->pVtabCtx ); |
| 101333 | 101426 | assert( xConstruct ); |
| 101334 | 101427 | sCtx.pTab = pTab; |
| 101335 | 101428 | sCtx.pVTable = pVTable; |
| | @@ -101336,10 +101429,11 @@ |
| 101336 | 101429 | pPriorCtx = db->pVtabCtx; |
| 101337 | 101430 | db->pVtabCtx = &sCtx; |
| 101338 | 101431 | rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); |
| 101339 | 101432 | db->pVtabCtx = pPriorCtx; |
| 101340 | 101433 | if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; |
| 101434 | + pTab->azModuleArg[1] = 0; |
| 101341 | 101435 | |
| 101342 | 101436 | if( SQLITE_OK!=rc ){ |
| 101343 | 101437 | if( zErr==0 ){ |
| 101344 | 101438 | *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); |
| 101345 | 101439 | }else { |
| | @@ -103371,26 +103465,10 @@ |
| 103371 | 103465 | ** an index for tables to the left of the join. |
| 103372 | 103466 | */ |
| 103373 | 103467 | pTerm->prereqRight |= extraRight; |
| 103374 | 103468 | } |
| 103375 | 103469 | |
| 103376 | | -/* |
| 103377 | | -** Return TRUE if the given index is UNIQUE and all columns past the |
| 103378 | | -** first nSkip columns are NOT NULL. |
| 103379 | | -*/ |
| 103380 | | -static int indexIsUniqueNotNull(Index *pIdx, int nSkip){ |
| 103381 | | - Table *pTab = pIdx->pTable; |
| 103382 | | - int i; |
| 103383 | | - if( pIdx->onError==OE_None ) return 0; |
| 103384 | | - for(i=nSkip; i<pIdx->nColumn; i++){ |
| 103385 | | - int j = pIdx->aiColumn[i]; |
| 103386 | | - assert( j>=0 && j<pTab->nCol ); |
| 103387 | | - if( pTab->aCol[j].notNull==0 ) return 0; |
| 103388 | | - } |
| 103389 | | - return 1; |
| 103390 | | -} |
| 103391 | | - |
| 103392 | 103470 | /* |
| 103393 | 103471 | ** This function searches the expression list passed as the second argument |
| 103394 | 103472 | ** for an expression of type TK_COLUMN that refers to the same column and |
| 103395 | 103473 | ** uses the same collation sequence as the iCol'th column of index pIdx. |
| 103396 | 103474 | ** Argument iBase is the cursor number used for the table that pIdx refers |
| | @@ -104344,14 +104422,12 @@ |
| 104344 | 104422 | if( eType==SQLITE_BLOB ){ |
| 104345 | 104423 | z = (const u8 *)sqlite3_value_blob(pVal); |
| 104346 | 104424 | pColl = db->pDfltColl; |
| 104347 | 104425 | assert( pColl->enc==SQLITE_UTF8 ); |
| 104348 | 104426 | }else{ |
| 104349 | | - pColl = sqlite3GetCollSeq(db, SQLITE_UTF8, 0, *pIdx->azColl); |
| 104427 | + pColl = sqlite3GetCollSeq(pParse, SQLITE_UTF8, 0, *pIdx->azColl); |
| 104350 | 104428 | if( pColl==0 ){ |
| 104351 | | - sqlite3ErrorMsg(pParse, "no such collation sequence: %s", |
| 104352 | | - *pIdx->azColl); |
| 104353 | 104429 | return SQLITE_ERROR; |
| 104354 | 104430 | } |
| 104355 | 104431 | z = (const u8 *)sqlite3ValueText(pVal, pColl->enc); |
| 104356 | 104432 | if( !z ){ |
| 104357 | 104433 | return SQLITE_NOMEM; |
| | @@ -104657,30 +104733,34 @@ |
| 104657 | 104733 | } |
| 104658 | 104734 | #endif /* defined(SQLITE_ENABLE_STAT3) */ |
| 104659 | 104735 | |
| 104660 | 104736 | /* |
| 104661 | 104737 | ** Check to see if column iCol of the table with cursor iTab will appear |
| 104662 | | -** in sorted order according to the current query plan. Return true if |
| 104663 | | -** it will and false if not. |
| 104738 | +** in sorted order according to the current query plan. |
| 104664 | 104739 | ** |
| 104665 | | -** If *pbRev is initially 2 (meaning "unknown") then set *pbRev to the |
| 104666 | | -** sort order of iTab.iCol. If *pbRev is 0 or 1 but does not match |
| 104667 | | -** the sort order of iTab.iCol, then consider the column to be unordered. |
| 104740 | +** Return values: |
| 104741 | +** |
| 104742 | +** 0 iCol is not ordered |
| 104743 | +** 1 iCol has only a single value |
| 104744 | +** 2 iCol is in ASC order |
| 104745 | +** 3 iCol is in DESC order |
| 104668 | 104746 | */ |
| 104669 | | -static int isOrderedColumn(WhereBestIdx *p, int iTab, int iCol, int *pbRev){ |
| 104747 | +static int isOrderedColumn( |
| 104748 | + WhereBestIdx *p, |
| 104749 | + int iTab, |
| 104750 | + int iCol |
| 104751 | +){ |
| 104670 | 104752 | int i, j; |
| 104671 | 104753 | WhereLevel *pLevel = &p->aLevel[p->i-1]; |
| 104672 | 104754 | Index *pIdx; |
| 104673 | 104755 | u8 sortOrder; |
| 104674 | 104756 | for(i=p->i-1; i>=0; i--, pLevel--){ |
| 104675 | 104757 | if( pLevel->iTabCur!=iTab ) continue; |
| 104676 | 104758 | if( (pLevel->plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){ |
| 104677 | 104759 | return 1; |
| 104678 | 104760 | } |
| 104679 | | - if( (pLevel->plan.wsFlags & WHERE_ORDERED)==0 ){ |
| 104680 | | - return 0; |
| 104681 | | - } |
| 104761 | + assert( (pLevel->plan.wsFlags & WHERE_ORDERED)!=0 ); |
| 104682 | 104762 | if( (pIdx = pLevel->plan.u.pIdx)!=0 ){ |
| 104683 | 104763 | if( iCol<0 ){ |
| 104684 | 104764 | sortOrder = 0; |
| 104685 | 104765 | testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ); |
| 104686 | 104766 | }else{ |
| | @@ -104700,39 +104780,12 @@ |
| 104700 | 104780 | if( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ){ |
| 104701 | 104781 | assert( sortOrder==0 || sortOrder==1 ); |
| 104702 | 104782 | testcase( sortOrder==1 ); |
| 104703 | 104783 | sortOrder = 1 - sortOrder; |
| 104704 | 104784 | } |
| 104705 | | - if( *pbRev==2 ){ |
| 104706 | | - *pbRev = sortOrder; |
| 104707 | | - return 1; |
| 104708 | | - } |
| 104709 | | - return (*pbRev==sortOrder); |
| 104710 | | - } |
| 104711 | | - return 0; |
| 104712 | | -} |
| 104713 | | - |
| 104714 | | -/* |
| 104715 | | -** pTerm is an == constraint. Check to see if the other side of |
| 104716 | | -** the == is a constant or a value that is guaranteed to be ordered |
| 104717 | | -** by outer loops. Return 1 if pTerm is ordered, and 0 if not. |
| 104718 | | -*/ |
| 104719 | | -static int isOrderedTerm(WhereBestIdx *p, WhereTerm *pTerm, int *pbRev){ |
| 104720 | | - Expr *pExpr = pTerm->pExpr; |
| 104721 | | - assert( pExpr->op==TK_EQ ); |
| 104722 | | - assert( pExpr->pLeft!=0 && pExpr->pLeft->op==TK_COLUMN ); |
| 104723 | | - assert( pExpr->pRight!=0 ); |
| 104724 | | - if( pTerm->prereqRight==0 ){ |
| 104725 | | - return 1; /* RHS of the == is a constant */ |
| 104726 | | - } |
| 104727 | | - if( pExpr->pRight->op==TK_COLUMN |
| 104728 | | - && isOrderedColumn(p, pExpr->pRight->iTable, pExpr->pRight->iColumn, pbRev) |
| 104729 | | - ){ |
| 104730 | | - return 1; |
| 104731 | | - } |
| 104732 | | - |
| 104733 | | - /* If we cannot prove that the constraint is ordered, assume it is not */ |
| 104785 | + return sortOrder+2; |
| 104786 | + } |
| 104734 | 104787 | return 0; |
| 104735 | 104788 | } |
| 104736 | 104789 | |
| 104737 | 104790 | /* |
| 104738 | 104791 | ** This routine decides if pIdx can be used to satisfy the ORDER BY |
| | @@ -104756,49 +104809,49 @@ |
| 104756 | 104809 | */ |
| 104757 | 104810 | static int isSortingIndex( |
| 104758 | 104811 | WhereBestIdx *p, /* Best index search context */ |
| 104759 | 104812 | Index *pIdx, /* The index we are testing */ |
| 104760 | 104813 | int base, /* Cursor number for the table to be sorted */ |
| 104761 | | - int nEqCol, /* Number of index columns with ordered == constraints */ |
| 104762 | | - int wsFlags, /* Index usages flags */ |
| 104763 | | - int bOuterRev, /* True if outer loops scan in reverse order */ |
| 104764 | 104814 | int *pbRev /* Set to 1 for reverse-order scan of pIdx */ |
| 104765 | 104815 | ){ |
| 104766 | 104816 | int i; /* Number of pIdx terms used */ |
| 104767 | 104817 | int j; /* Number of ORDER BY terms satisfied */ |
| 104768 | | - int sortOrder = 0; /* XOR of index and ORDER BY sort direction */ |
| 104818 | + int sortOrder = 2; /* 0: forward. 1: backward. 2: unknown */ |
| 104769 | 104819 | int nTerm; /* Number of ORDER BY terms */ |
| 104770 | | - struct ExprList_item *pTerm; /* A term of the ORDER BY clause */ |
| 104820 | + struct ExprList_item *pOBItem;/* A term of the ORDER BY clause */ |
| 104821 | + Table *pTab = pIdx->pTable; /* Table that owns index pIdx */ |
| 104771 | 104822 | ExprList *pOrderBy; /* The ORDER BY clause */ |
| 104772 | 104823 | Parse *pParse = p->pParse; /* Parser context */ |
| 104773 | 104824 | sqlite3 *db = pParse->db; /* Database connection */ |
| 104774 | 104825 | int nPriorSat; /* ORDER BY terms satisfied by outer loops */ |
| 104775 | 104826 | int seenRowid = 0; /* True if an ORDER BY rowid term is seen */ |
| 104776 | | - int nEqOneRow; /* Idx columns that ref unique values */ |
| 104827 | + int uniqueNotNull; /* pIdx is UNIQUE with all terms are NOT NULL */ |
| 104777 | 104828 | |
| 104778 | 104829 | if( p->i==0 ){ |
| 104779 | 104830 | nPriorSat = 0; |
| 104780 | 104831 | }else{ |
| 104781 | 104832 | nPriorSat = p->aLevel[p->i-1].plan.nOBSat; |
| 104782 | | - if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return nPriorSat; |
| 104783 | | - } |
| 104784 | | - if( nEqCol==0 ){ |
| 104785 | | - if( p->i && (p->aLevel[p->i-1].plan.wsFlags & WHERE_ORDERED)==0 ){ |
| 104833 | + if( (p->aLevel[p->i-1].plan.wsFlags & WHERE_ORDERED)==0 ){ |
| 104834 | + /* This loop cannot be ordered unless the next outer loop is |
| 104835 | + ** also ordered */ |
| 104836 | + return nPriorSat; |
| 104837 | + } |
| 104838 | + if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ){ |
| 104839 | + /* Only look at the outer-most loop if the OrderByIdxJoin |
| 104840 | + ** optimization is disabled */ |
| 104786 | 104841 | return nPriorSat; |
| 104787 | 104842 | } |
| 104788 | | - nEqOneRow = 0; |
| 104789 | | - }else if( p->i==0 || (p->aLevel[p->i-1].plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){ |
| 104790 | | - nEqOneRow = nEqCol; |
| 104791 | | - }else{ |
| 104792 | | - sortOrder = bOuterRev; |
| 104793 | | - nEqOneRow = -1; |
| 104794 | 104843 | } |
| 104795 | 104844 | pOrderBy = p->pOrderBy; |
| 104796 | 104845 | assert( pOrderBy!=0 ); |
| 104797 | | - if( wsFlags & WHERE_COLUMN_IN ) return nPriorSat; |
| 104798 | | - if( pIdx->bUnordered ) return nPriorSat; |
| 104846 | + if( pIdx->bUnordered ){ |
| 104847 | + /* Hash indices (indicated by the "unordered" tag on sqlite_stat1) cannot |
| 104848 | + ** be used for sorting */ |
| 104849 | + return nPriorSat; |
| 104850 | + } |
| 104799 | 104851 | nTerm = pOrderBy->nExpr; |
| 104852 | + uniqueNotNull = pIdx->onError!=OE_None; |
| 104800 | 104853 | assert( nTerm>0 ); |
| 104801 | 104854 | |
| 104802 | 104855 | /* Argument pIdx must either point to a 'real' named index structure, |
| 104803 | 104856 | ** or an index structure allocated on the stack by bestBtreeIndex() to |
| 104804 | 104857 | ** represent the rowid index that is part of every table. */ |
| | @@ -104810,90 +104863,130 @@ |
| 104810 | 104863 | ** Note that indices have pIdx->nColumn regular columns plus |
| 104811 | 104864 | ** one additional column containing the rowid. The rowid column |
| 104812 | 104865 | ** of the index is also allowed to match against the ORDER BY |
| 104813 | 104866 | ** clause. |
| 104814 | 104867 | */ |
| 104815 | | - for(i=0,j=nPriorSat,pTerm=&pOrderBy->a[j]; j<nTerm; i++){ |
| 104816 | | - Expr *pExpr; /* The expression of the ORDER BY pTerm */ |
| 104817 | | - CollSeq *pColl; /* The collating sequence of pExpr */ |
| 104818 | | - int termSortOrder; /* Sort order for this term */ |
| 104819 | | - int iColumn; /* The i-th column of the index. -1 for rowid */ |
| 104820 | | - int iSortOrder; /* 1 for DESC, 0 for ASC on the i-th index term */ |
| 104821 | | - const char *zColl; /* Name of the collating sequence for i-th index term */ |
| 104822 | | - |
| 104823 | | - assert( i<=pIdx->nColumn ); |
| 104824 | | - pExpr = pTerm->pExpr; |
| 104825 | | - if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){ |
| 104826 | | - /* Can not use an index sort on anything that is not a column in the |
| 104827 | | - ** left-most table of the FROM clause */ |
| 104868 | + j = nPriorSat; |
| 104869 | + for(i=0,pOBItem=&pOrderBy->a[j]; j<nTerm && i<=pIdx->nColumn; i++){ |
| 104870 | + Expr *pOBExpr; /* The expression of the ORDER BY pOBItem */ |
| 104871 | + CollSeq *pColl; /* The collating sequence of pOBExpr */ |
| 104872 | + int termSortOrder; /* Sort order for this term */ |
| 104873 | + int iColumn; /* The i-th column of the index. -1 for rowid */ |
| 104874 | + int iSortOrder; /* 1 for DESC, 0 for ASC on the i-th index term */ |
| 104875 | + int isEq; /* Subject to an == or IS NULL constraint */ |
| 104876 | + int isMatch; /* ORDER BY term matches the index term */ |
| 104877 | + const char *zColl; /* Name of collating sequence for i-th index term */ |
| 104878 | + WhereTerm *pConstraint; /* A constraint in the WHERE clause */ |
| 104879 | + |
| 104880 | + /* If the next term of the ORDER BY clause refers to anything other than |
| 104881 | + ** a column in the "base" table, then this index will not be of any |
| 104882 | + ** further use in handling the ORDER BY. */ |
| 104883 | + pOBExpr = pOBItem->pExpr; |
| 104884 | + if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){ |
| 104828 | 104885 | break; |
| 104829 | 104886 | } |
| 104830 | | - pColl = sqlite3ExprCollSeq(pParse, pExpr); |
| 104831 | | - if( !pColl ){ |
| 104832 | | - pColl = db->pDfltColl; |
| 104833 | | - } |
| 104887 | + |
| 104888 | + /* Find column number and collating sequence for the next entry |
| 104889 | + ** in the index */ |
| 104834 | 104890 | if( pIdx->zName && i<pIdx->nColumn ){ |
| 104835 | 104891 | iColumn = pIdx->aiColumn[i]; |
| 104836 | 104892 | if( iColumn==pIdx->pTable->iPKey ){ |
| 104837 | 104893 | iColumn = -1; |
| 104838 | 104894 | } |
| 104839 | 104895 | iSortOrder = pIdx->aSortOrder[i]; |
| 104840 | 104896 | zColl = pIdx->azColl[i]; |
| 104897 | + assert( zColl!=0 ); |
| 104841 | 104898 | }else{ |
| 104842 | 104899 | iColumn = -1; |
| 104843 | 104900 | iSortOrder = 0; |
| 104844 | | - zColl = pColl->zName; |
| 104845 | | - } |
| 104846 | | - if( pExpr->iColumn!=iColumn || sqlite3StrICmp(pColl->zName, zColl) ){ |
| 104847 | | - /* Term j of the ORDER BY clause does not match column i of the index */ |
| 104848 | | - if( i<nEqCol ){ |
| 104849 | | - /* If an index column that is constrained by == fails to match an |
| 104850 | | - ** ORDER BY term, that is OK. Just ignore that column of the index |
| 104851 | | - */ |
| 104852 | | - continue; |
| 104853 | | - }else if( i==pIdx->nColumn ){ |
| 104854 | | - /* Index column i is the rowid. All other terms match. */ |
| 104855 | | - break; |
| 104901 | + zColl = 0; |
| 104902 | + } |
| 104903 | + |
| 104904 | + /* Check to see if the column number and collating sequence of the |
| 104905 | + ** index match the column number and collating sequence of the ORDER BY |
| 104906 | + ** clause entry. Set isMatch to 1 if they both match. */ |
| 104907 | + if( pOBExpr->iColumn==iColumn ){ |
| 104908 | + if( zColl ){ |
| 104909 | + pColl = sqlite3ExprCollSeq(pParse, pOBExpr); |
| 104910 | + if( !pColl ) pColl = db->pDfltColl; |
| 104911 | + isMatch = sqlite3StrICmp(pColl->zName, zColl)==0; |
| 104912 | + }else{ |
| 104913 | + isMatch = 1; |
| 104914 | + } |
| 104915 | + }else{ |
| 104916 | + isMatch = 0; |
| 104917 | + } |
| 104918 | + |
| 104919 | + /* termSortOrder is 0 or 1 for whether or not the access loop should |
| 104920 | + ** run forward or backwards (respectively) in order to satisfy this |
| 104921 | + ** term of the ORDER BY clause. */ |
| 104922 | + termSortOrder = iSortOrder ^ pOBItem->sortOrder; |
| 104923 | + |
| 104924 | + /* If X is the column in the index and ORDER BY clause, check to see |
| 104925 | + ** if there are any X= or X IS NULL constraints in the WHERE clause. */ |
| 104926 | + pConstraint = findTerm(p->pWC, base, iColumn, p->notReady, |
| 104927 | + WO_EQ|WO_ISNULL|WO_IN, pIdx); |
| 104928 | + if( pConstraint==0 ){ |
| 104929 | + isEq = 0; |
| 104930 | + }else if( pConstraint->eOperator==WO_IN ){ |
| 104931 | + break; |
| 104932 | + }else if( pConstraint->eOperator==WO_ISNULL ){ |
| 104933 | + uniqueNotNull = 0; |
| 104934 | + isEq = 1; |
| 104935 | + }else if( pConstraint->prereqRight==0 ){ |
| 104936 | + isEq = 1; |
| 104937 | + }else{ |
| 104938 | + Expr *pRight = pConstraint->pExpr->pRight; |
| 104939 | + if( pRight->op==TK_COLUMN ){ |
| 104940 | + WHERETRACE((" .. isOrderedColumn(tab=%d,col=%d)", |
| 104941 | + pRight->iTable, pRight->iColumn)); |
| 104942 | + isEq = isOrderedColumn(p, pRight->iTable, pRight->iColumn); |
| 104943 | + WHERETRACE((" -> isEq=%d\n", isEq)); |
| 104944 | + if( isMatch && isEq>=2 && isEq!=pOBItem->sortOrder+2 ){ |
| 104945 | + break; |
| 104946 | + } |
| 104856 | 104947 | }else{ |
| 104857 | | - /* If an index column fails to match and is not constrained by == |
| 104858 | | - ** then the index cannot satisfy the ORDER BY constraint. |
| 104859 | | - */ |
| 104860 | | - return nPriorSat; |
| 104948 | + isEq = 0; |
| 104861 | 104949 | } |
| 104862 | 104950 | } |
| 104863 | | - assert( pIdx->aSortOrder!=0 || iColumn==-1 ); |
| 104864 | | - assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 ); |
| 104951 | + assert( pOBItem->sortOrder==0 || pOBItem->sortOrder==1 ); |
| 104865 | 104952 | assert( iSortOrder==0 || iSortOrder==1 ); |
| 104866 | | - termSortOrder = iSortOrder ^ pTerm->sortOrder; |
| 104867 | | - if( i>nEqOneRow ){ |
| 104868 | | - if( termSortOrder!=sortOrder ){ |
| 104869 | | - /* Indices can only be used if all ORDER BY terms past the |
| 104870 | | - ** equality constraints have the correct DESC or ASC. */ |
| 104953 | + if( !isMatch ){ |
| 104954 | + if( isEq==0 ){ |
| 104955 | + break; |
| 104956 | + }else{ |
| 104957 | + continue; |
| 104958 | + } |
| 104959 | + }else if( isEq!=1 ){ |
| 104960 | + if( sortOrder==2 ){ |
| 104961 | + sortOrder = termSortOrder; |
| 104962 | + }else if( termSortOrder!=sortOrder ){ |
| 104871 | 104963 | break; |
| 104872 | 104964 | } |
| 104873 | | - }else{ |
| 104874 | | - sortOrder = termSortOrder; |
| 104875 | 104965 | } |
| 104876 | 104966 | j++; |
| 104877 | | - pTerm++; |
| 104967 | + pOBItem++; |
| 104878 | 104968 | if( iColumn<0 ){ |
| 104879 | 104969 | seenRowid = 1; |
| 104880 | 104970 | break; |
| 104971 | + }else if( pTab->aCol[iColumn].notNull==0 && isEq==0 ){ |
| 104972 | + uniqueNotNull = 0; |
| 104881 | 104973 | } |
| 104882 | 104974 | } |
| 104883 | | - *pbRev = sortOrder; |
| 104975 | + |
| 104976 | + /* If we have not found at least one ORDER BY term that matches the |
| 104977 | + ** index, then show no progress. */ |
| 104978 | + if( pOBItem==&pOrderBy->a[nPriorSat] ) return nPriorSat; |
| 104979 | + |
| 104980 | + /* Return the necessary scan order back to the caller */ |
| 104981 | + *pbRev = sortOrder & 1; |
| 104884 | 104982 | |
| 104885 | 104983 | /* If there was an "ORDER BY rowid" term that matched, or it is only |
| 104886 | 104984 | ** possible for a single row from this table to match, then skip over |
| 104887 | 104985 | ** any additional ORDER BY terms dealing with this table. |
| 104888 | 104986 | */ |
| 104889 | | - if( seenRowid || |
| 104890 | | - ( (wsFlags & WHERE_COLUMN_NULL)==0 |
| 104891 | | - && i>=pIdx->nColumn |
| 104892 | | - && indexIsUniqueNotNull(pIdx, nEqCol) |
| 104893 | | - ) |
| 104894 | | - ){ |
| 104987 | + if( seenRowid || (uniqueNotNull && i>=pIdx->nColumn) ){ |
| 104895 | 104988 | /* Advance j over additional ORDER BY terms associated with base */ |
| 104896 | 104989 | WhereMaskSet *pMS = p->pWC->pMaskSet; |
| 104897 | 104990 | Bitmask m = ~getMask(pMS, base); |
| 104898 | 104991 | while( j<nTerm && (exprTableUsage(pMS, pOrderBy->a[j].pExpr)&m)==0 ){ |
| 104899 | 104992 | j++; |
| | @@ -104995,11 +105088,10 @@ |
| 104995 | 105088 | */ |
| 104996 | 105089 | for(; pProbe; pIdx=pProbe=pProbe->pNext){ |
| 104997 | 105090 | const tRowcnt * const aiRowEst = pProbe->aiRowEst; |
| 104998 | 105091 | WhereCost pc; /* Cost of using pProbe */ |
| 104999 | 105092 | double log10N = (double)1; /* base-10 logarithm of nRow (inexact) */ |
| 105000 | | - int bRev = 2; /* 0=forward scan. 1=reverse. 2=undecided */ |
| 105001 | 105093 | |
| 105002 | 105094 | /* The following variables are populated based on the properties of |
| 105003 | 105095 | ** index being evaluated. They are then used to determine the expected |
| 105004 | 105096 | ** cost and number of rows returned. |
| 105005 | 105097 | ** |
| | @@ -105026,14 +105118,10 @@ |
| 105026 | 105118 | ** |
| 105027 | 105119 | ** If there exists a WHERE term of the form "x IN (SELECT ...)", then |
| 105028 | 105120 | ** the sub-select is assumed to return 25 rows for the purposes of |
| 105029 | 105121 | ** determining nInMul. |
| 105030 | 105122 | ** |
| 105031 | | - ** nOrdered: |
| 105032 | | - ** The number of equality terms that are constrainted by outer loop |
| 105033 | | - ** variables that are well-ordered. |
| 105034 | | - ** |
| 105035 | 105123 | ** bInEst: |
| 105036 | 105124 | ** Set to true if there was at least one "x IN (SELECT ...)" term used |
| 105037 | 105125 | ** in determining the value of nInMul. Note that the RHS of the |
| 105038 | 105126 | ** IN operator must be a SELECT, not a value list, for this variable |
| 105039 | 105127 | ** to be true. |
| | @@ -105067,11 +105155,10 @@ |
| 105067 | 105155 | ** both available in the index. |
| 105068 | 105156 | ** |
| 105069 | 105157 | ** SELECT a, b FROM tbl WHERE a = 1; |
| 105070 | 105158 | ** SELECT a, b, c FROM tbl WHERE a = 1; |
| 105071 | 105159 | */ |
| 105072 | | - int nOrdered; /* Number of ordered terms matching index */ |
| 105073 | 105160 | int bInEst = 0; /* True if "x IN (SELECT...)" seen */ |
| 105074 | 105161 | int nInMul = 1; /* Number of distinct equalities to lookup */ |
| 105075 | 105162 | double rangeDiv = (double)1; /* Estimated reduction in search space */ |
| 105076 | 105163 | int nBound = 0; /* Number of range constraints seen */ |
| 105077 | 105164 | int bSort; /* True if external sort required */ |
| | @@ -105082,10 +105169,14 @@ |
| 105082 | 105169 | WhereTerm *pTerm; /* A single term of the WHERE clause */ |
| 105083 | 105170 | #ifdef SQLITE_ENABLE_STAT3 |
| 105084 | 105171 | WhereTerm *pFirstTerm = 0; /* First term matching the index */ |
| 105085 | 105172 | #endif |
| 105086 | 105173 | |
| 105174 | + WHERETRACE(( |
| 105175 | + " %s(%s):\n", |
| 105176 | + pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk") |
| 105177 | + )); |
| 105087 | 105178 | memset(&pc, 0, sizeof(pc)); |
| 105088 | 105179 | nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0; |
| 105089 | 105180 | if( p->i ){ |
| 105090 | 105181 | nPriorSat = pc.plan.nOBSat = p->aLevel[p->i-1].plan.nOBSat; |
| 105091 | 105182 | bSort = nPriorSat<nOrderBy; |
| | @@ -105095,11 +105186,11 @@ |
| 105095 | 105186 | bSort = nOrderBy>0; |
| 105096 | 105187 | bDist = p->pDistinct!=0; |
| 105097 | 105188 | } |
| 105098 | 105189 | |
| 105099 | 105190 | /* Determine the values of pc.plan.nEq and nInMul */ |
| 105100 | | - for(pc.plan.nEq=nOrdered=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){ |
| 105191 | + for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){ |
| 105101 | 105192 | int j = pProbe->aiColumn[pc.plan.nEq]; |
| 105102 | 105193 | pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx); |
| 105103 | 105194 | if( pTerm==0 ) break; |
| 105104 | 105195 | pc.plan.wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ); |
| 105105 | 105196 | testcase( pTerm->pWC!=pWC ); |
| | @@ -105114,14 +105205,10 @@ |
| 105114 | 105205 | /* "x IN (value, value, ...)" */ |
| 105115 | 105206 | nInMul *= pExpr->x.pList->nExpr; |
| 105116 | 105207 | } |
| 105117 | 105208 | }else if( pTerm->eOperator & WO_ISNULL ){ |
| 105118 | 105209 | pc.plan.wsFlags |= WHERE_COLUMN_NULL; |
| 105119 | | - if( pc.plan.nEq==nOrdered ) nOrdered++; |
| 105120 | | - }else if( bSort && pc.plan.nEq==nOrdered |
| 105121 | | - && isOrderedTerm(p,pTerm,&bRev) ){ |
| 105122 | | - nOrdered++; |
| 105123 | 105210 | } |
| 105124 | 105211 | #ifdef SQLITE_ENABLE_STAT3 |
| 105125 | 105212 | if( pc.plan.nEq==0 && pProbe->aSample ) pFirstTerm = pTerm; |
| 105126 | 105213 | #endif |
| 105127 | 105214 | pc.used |= pTerm->prereqRight; |
| | @@ -105172,17 +105259,16 @@ |
| 105172 | 105259 | /* If there is an ORDER BY clause and the index being considered will |
| 105173 | 105260 | ** naturally scan rows in the required order, set the appropriate flags |
| 105174 | 105261 | ** in pc.plan.wsFlags. Otherwise, if there is an ORDER BY clause but |
| 105175 | 105262 | ** the index will scan rows in a different order, set the bSort |
| 105176 | 105263 | ** variable. */ |
| 105177 | | - assert( bRev>=0 && bRev<=2 ); |
| 105178 | | - if( bSort ){ |
| 105179 | | - testcase( bRev==0 ); |
| 105180 | | - testcase( bRev==1 ); |
| 105181 | | - testcase( bRev==2 ); |
| 105182 | | - pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, nOrdered, |
| 105183 | | - pc.plan.wsFlags, bRev&1, &bRev); |
| 105264 | + if( bSort && (pSrc->jointype & JT_LEFT)==0 ){ |
| 105265 | + int bRev = 2; |
| 105266 | + WHERETRACE((" --> before isSortingIndex: nPriorSat=%d\n",nPriorSat)); |
| 105267 | + pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, &bRev); |
| 105268 | + WHERETRACE((" --> after isSortingIndex: bRev=%d nOBSat=%d\n", |
| 105269 | + bRev, pc.plan.nOBSat)); |
| 105184 | 105270 | if( nPriorSat<pc.plan.nOBSat || (pc.plan.wsFlags & WHERE_UNIQUE)!=0 ){ |
| 105185 | 105271 | pc.plan.wsFlags |= WHERE_ORDERED; |
| 105186 | 105272 | } |
| 105187 | 105273 | if( nOrderBy==pc.plan.nOBSat ){ |
| 105188 | 105274 | bSort = 0; |
| | @@ -105296,11 +105382,14 @@ |
| 105296 | 105382 | ** decision and one which we expect to revisit in the future. But |
| 105297 | 105383 | ** it seems to be working well enough at the moment. |
| 105298 | 105384 | */ |
| 105299 | 105385 | pc.rCost = aiRowEst[0]*4; |
| 105300 | 105386 | pc.plan.wsFlags &= ~WHERE_IDX_ONLY; |
| 105301 | | - if( pIdx ) pc.plan.wsFlags &= ~WHERE_ORDERED; |
| 105387 | + if( pIdx ){ |
| 105388 | + pc.plan.wsFlags &= ~WHERE_ORDERED; |
| 105389 | + pc.plan.nOBSat = nPriorSat; |
| 105390 | + } |
| 105302 | 105391 | }else{ |
| 105303 | 105392 | log10N = estLog(aiRowEst[0]); |
| 105304 | 105393 | pc.rCost = pc.plan.nRow; |
| 105305 | 105394 | if( pIdx ){ |
| 105306 | 105395 | if( bLookup ){ |
| | @@ -105401,17 +105490,15 @@ |
| 105401 | 105490 | if( pc.plan.nRow<2 ) pc.plan.nRow = 2; |
| 105402 | 105491 | } |
| 105403 | 105492 | |
| 105404 | 105493 | |
| 105405 | 105494 | WHERETRACE(( |
| 105406 | | - "%s(%s):\n" |
| 105407 | | - " nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%08x\n" |
| 105408 | | - " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n" |
| 105409 | | - " used=0x%llx nOrdered=%d nOBSat=%d\n", |
| 105410 | | - pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), |
| 105495 | + " nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%08x\n" |
| 105496 | + " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n" |
| 105497 | + " used=0x%llx nOBSat=%d\n", |
| 105411 | 105498 | pc.plan.nEq, nInMul, (int)rangeDiv, bSort, bLookup, pc.plan.wsFlags, |
| 105412 | | - p->notReady, log10N, pc.plan.nRow, pc.rCost, pc.used, nOrdered, |
| 105499 | + p->notReady, log10N, pc.plan.nRow, pc.rCost, pc.used, |
| 105413 | 105500 | pc.plan.nOBSat |
| 105414 | 105501 | )); |
| 105415 | 105502 | |
| 105416 | 105503 | /* If this index is the best we have seen so far, then record this |
| 105417 | 105504 | ** index and its cost in the p->cost structure. |
| | @@ -105445,11 +105532,11 @@ |
| 105445 | 105532 | assert( pSrc->pIndex==0 |
| 105446 | 105533 | || p->cost.plan.u.pIdx==0 |
| 105447 | 105534 | || p->cost.plan.u.pIdx==pSrc->pIndex |
| 105448 | 105535 | ); |
| 105449 | 105536 | |
| 105450 | | - WHERETRACE(("best index is: %s\n", |
| 105537 | + WHERETRACE((" best index is: %s\n", |
| 105451 | 105538 | p->cost.plan.u.pIdx ? p->cost.plan.u.pIdx->zName : "ipk")); |
| 105452 | 105539 | |
| 105453 | 105540 | bestOrClauseIndex(p); |
| 105454 | 105541 | bestAutomaticIndex(p); |
| 105455 | 105542 | p->cost.plan.wsFlags |= eqTermMask; |
| | @@ -106995,11 +107082,11 @@ |
| 106995 | 107082 | continue; |
| 106996 | 107083 | } |
| 106997 | 107084 | sWBI.notReady = (isOptimal ? m : sWBI.notValid); |
| 106998 | 107085 | if( sWBI.pSrc->pIndex==0 ) nUnconstrained++; |
| 106999 | 107086 | |
| 107000 | | - WHERETRACE(("=== trying table %d (%s) with isOptimal=%d ===\n", |
| 107087 | + WHERETRACE((" === trying table %d (%s) with isOptimal=%d ===\n", |
| 107001 | 107088 | j, sWBI.pSrc->pTab->zName, isOptimal)); |
| 107002 | 107089 | assert( sWBI.pSrc->pTab ); |
| 107003 | 107090 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 107004 | 107091 | if( IsVirtual(sWBI.pSrc->pTab) ){ |
| 107005 | 107092 | sWBI.ppIdxInfo = &pWInfo->a[j].pIdxInfo; |
| | @@ -107048,12 +107135,12 @@ |
| 107048 | 107135 | || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0) |
| 107049 | 107136 | && (nUnconstrained==0 || sWBI.pSrc->pIndex==0 /* (3) */ |
| 107050 | 107137 | || NEVER((sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)) |
| 107051 | 107138 | && (bestJ<0 || compareCost(&sWBI.cost, &bestPlan)) /* (4) */ |
| 107052 | 107139 | ){ |
| 107053 | | - WHERETRACE(("=== table %d (%s) is best so far\n" |
| 107054 | | - " cost=%.1f, nRow=%.1f, nOBSat=%d, wsFlags=%08x\n", |
| 107140 | + WHERETRACE((" === table %d (%s) is best so far\n" |
| 107141 | + " cost=%.1f, nRow=%.1f, nOBSat=%d, wsFlags=%08x\n", |
| 107055 | 107142 | j, sWBI.pSrc->pTab->zName, |
| 107056 | 107143 | sWBI.cost.rCost, sWBI.cost.plan.nRow, |
| 107057 | 107144 | sWBI.cost.plan.nOBSat, sWBI.cost.plan.wsFlags)); |
| 107058 | 107145 | bestPlan = sWBI.cost; |
| 107059 | 107146 | bestJ = j; |
| 107060 | 107147 | |