Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch vtab-left-join Excluding Merge-Ins
This is equivalent to a diff from e49c2917 to a34cd71c
2015-06-10
| ||
14:27 | Avoid passing constraints that are unusable due to LEFT or CROSS joins to virtual table xBestIndex() methods. (check-in: 7b446771 user: dan tags: trunk) | |
2015-06-09
| ||
10:58 | Remove some repeated lines of source code. Probably introduced by careless cut'n'pasting. (Closed-Leaf check-in: a34cd71c user: dan tags: vtab-left-join) | |
2015-06-08
| ||
19:15 | Add the valgrindfuzz target to unix makefile. (check-in: e62aed01 user: drh tags: trunk) | |
18:48 | If a query contains "FROM t1 LEFT JOIN t2, t3, t4", ensure that tables t3 and t4 are not scanned before t2. The trunk already does this. (check-in: 0d9edfab user: dan tags: vtab-left-join) | |
18:05 | Avoid passing constraints that are unusable due to LEFT or CROSS joins to virtual table xBestIndex() methods. (check-in: 80ee56dd user: dan tags: vtab-left-join) | |
17:42 | Fix typo in comment. No changes to code. (check-in: e49c2917 user: mistachkin tags: trunk) | |
17:40 | Split out some source code into new files: wherecode.c, whereexpr.c, and treeview.c. Other minor refactoring changes. (check-in: 50f33681 user: drh tags: trunk) | |
Changes to ext/rtree/rtreeC.test.
︙ | |||
264 265 266 267 268 269 270 271 272 273 | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | sqlite3 db2 test.db db2 eval { DROP TABLE sqlite_stat1 } db2 close execsql { SELECT * FROM rt } } {1 2.0 3.0} db close } #-------------------------------------------------------------------- # Test that queries featuring LEFT or CROSS JOINS are handled correctly. # Handled correctly in this case means: # # * Terms with prereqs that appear to the left of a LEFT JOIN against # the virtual table are always available to xBestIndex. # # * Terms with prereqs that appear to the right of a LEFT JOIN against # the virtual table are never available to xBestIndex. # # And the same behaviour for CROSS joins. # reset_db do_execsql_test 7.0 { CREATE TABLE xdir(x1); CREATE TABLE ydir(y1); CREATE VIRTUAL TABLE rt USING rtree_i32(id, xmin, xmax, ymin, ymax); INSERT INTO xdir VALUES(5); INSERT INTO ydir VALUES(10); INSERT INTO rt VALUES(1, 2, 7, 12, 14); -- Not a hit INSERT INTO rt VALUES(2, 2, 7, 8, 12); -- A hit! INSERT INTO rt VALUES(3, 7, 11, 8, 12); -- Not a hit! INSERT INTO rt VALUES(4, 5, 5, 10, 10); -- A hit! } proc do_eqp_execsql_test {tn sql res} { set query "EXPLAIN QUERY PLAN $sql ; $sql " uplevel [list do_execsql_test $tn $query $res] } do_eqp_execsql_test 7.1 { SELECT id FROM xdir, rt, ydir ON (y1 BETWEEN ymin AND ymax) WHERE (x1 BETWEEN xmin AND xmax); } { 0 0 0 {SCAN TABLE xdir} 0 1 2 {SCAN TABLE ydir} 0 2 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B2D3B0D1} 2 4 } do_eqp_execsql_test 7.2 { SELECT * FROM xdir, rt LEFT JOIN ydir ON (y1 BETWEEN ymin AND ymax) WHERE (x1 BETWEEN xmin AND xmax); } { 0 0 0 {SCAN TABLE xdir} 0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1} 0 2 2 {SCAN TABLE ydir} 5 1 2 7 12 14 {} 5 2 2 7 8 12 10 5 4 5 5 10 10 10 } do_eqp_execsql_test 7.3 { SELECT id FROM xdir, rt CROSS JOIN ydir ON (y1 BETWEEN ymin AND ymax) WHERE (x1 BETWEEN xmin AND xmax); } { 0 0 0 {SCAN TABLE xdir} 0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1} 0 2 2 {SCAN TABLE ydir} 2 4 } do_eqp_execsql_test 7.4 { SELECT id FROM rt, xdir CROSS JOIN ydir ON (y1 BETWEEN ymin AND ymax) WHERE (x1 BETWEEN xmin AND xmax); } { 0 0 1 {SCAN TABLE xdir} 0 1 0 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1} 0 2 2 {SCAN TABLE ydir} 2 4 } finish_test finish_test |
Changes to src/where.c.
︙ | |||
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 | 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 | + + | ** Allocate and populate an sqlite3_index_info structure. It is the ** responsibility of the caller to eventually release the structure ** by passing the pointer returned by this function to sqlite3_free(). */ static sqlite3_index_info *allocateIndexInfo( Parse *pParse, WhereClause *pWC, Bitmask mUnusable, /* Ignore terms with these prereqs */ struct SrcList_item *pSrc, ExprList *pOrderBy ){ int i, j; int nTerm; struct sqlite3_index_constraint *pIdxCons; struct sqlite3_index_orderby *pIdxOrderBy; struct sqlite3_index_constraint_usage *pUsage; WhereTerm *pTerm; int nOrderBy; sqlite3_index_info *pIdxInfo; /* Count the number of possible WHERE clause constraints referring ** to this virtual table */ for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ if( pTerm->leftCursor != pSrc->iCursor ) continue; if( pTerm->prereqRight & mUnusable ) continue; assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); testcase( pTerm->eOperator & WO_IN ); testcase( pTerm->eOperator & WO_ISNULL ); testcase( pTerm->eOperator & WO_IS ); testcase( pTerm->eOperator & WO_ALL ); if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue; if( pTerm->wtFlags & TERM_VNULL ) continue; |
︙ | |||
823 824 825 826 827 828 829 830 831 832 833 834 835 836 | 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 | + | *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy; *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage = pUsage; for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ u8 op; if( pTerm->leftCursor != pSrc->iCursor ) continue; if( pTerm->prereqRight & mUnusable ) continue; assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); testcase( pTerm->eOperator & WO_IN ); testcase( pTerm->eOperator & WO_IS ); testcase( pTerm->eOperator & WO_ISNULL ); testcase( pTerm->eOperator & WO_ALL ); if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue; if( pTerm->wtFlags & TERM_VNULL ) continue; |
︙ | |||
2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 | 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 | + + + + + + + + + + + + + + + + + + + + + - + + + - + | return rc; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Add all WhereLoop objects for a table of the join identified by ** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table. ** ** If there are no LEFT or CROSS JOIN joins in the query, both mExtra and ** mUnusable are set to 0. Otherwise, mExtra is a mask of all FROM clause ** entries that occur before the virtual table in the FROM clause and are ** separated from it by at least one LEFT or CROSS JOIN. Similarly, the ** mUnusable mask contains all FROM clause entries that occur after the ** virtual table and are separated from it by at least one LEFT or ** CROSS JOIN. ** ** For example, if the query were: ** ** ... FROM t1, t2 LEFT JOIN t3, t4, vt CROSS JOIN t5, t6; ** ** then mExtra corresponds to (t1, t2) and mUnusable to (t5, t6). ** ** All the tables in mExtra must be scanned before the current virtual ** table. So any terms for which all prerequisites are satisfied by ** mExtra may be specified as "usable" in all calls to xBestIndex. ** Conversely, all tables in mUnusable must be scanned after the current ** virtual table, so any terms for which the prerequisites overlap with ** mUnusable should always be configured as "not-usable" for xBestIndex. */ static int whereLoopAddVirtual( WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
︙ | |||
2724 2725 2726 2727 2728 2729 2730 | 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 | - + - + | pTerm = &pWC->a[j]; switch( iPhase ){ case 0: /* Constants without IN operator */ pIdxCons->usable = 0; if( (pTerm->eOperator & WO_IN)!=0 ){ seenIn = 1; } |
︙ | |||
2831 2832 2833 2834 2835 2836 2837 | 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 | - + + + + + | } #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* ** Add WhereLoop entries to handle OR terms. This works for either ** btrees or virtual tables. */ |
︙ | |||
2890 2891 2892 2893 2894 2895 2896 | 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 | - + - + | for(i=0; i<sSubBuild.pWC->nTerm; i++){ whereTermPrint(&sSubBuild.pWC->a[i], i); } } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ |
︙ | |||
2959 2960 2961 2962 2963 2964 2965 2966 | 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 | + - - + - + + - + + + - + + + + + + + - + - + + | static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ WhereInfo *pWInfo = pBuilder->pWInfo; Bitmask mExtra = 0; Bitmask mPrior = 0; int iTab; SrcList *pTabList = pWInfo->pTabList; struct SrcList_item *pItem; struct SrcList_item *pEnd = &pTabList->a[pWInfo->nLevel]; sqlite3 *db = pWInfo->pParse->db; |
︙ |
Changes to test/join.test.
︙ | |||
682 683 684 685 686 687 688 689 690 | 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 | + + + + + + + + + + + + + + + + + + + + + + + + + + | if {[lsearch [db eval {PRAGMA compile_options}] MEMDEBUG]<0} { jointest join-12.10 65534 {1 {at most 64 tables in a join}} jointest join-12.11 65535 {1 {too many references to "t14": max 65535}} jointest join-12.12 65536 {1 {too many references to "t14": max 65535}} jointest join-12.13 65537 {1 {too many references to "t14": max 65535}} } } #------------------------------------------------------------------------- # Test a problem with reordering tables following a LEFT JOIN. # do_execsql_test join-13.0 { CREATE TABLE aa(a); CREATE TABLE bb(b); CREATE TABLE cc(c); INSERT INTO aa VALUES(45); INSERT INTO cc VALUES(45); INSERT INTO cc VALUES(45); } do_execsql_test join-13.1 { SELECT * FROM aa LEFT JOIN bb, cc WHERE cc.c=aa.a; } {45 {} 45 45 {} 45} # In the following, the order of [cc] and [bb] must not be exchanged, even # though this would be helpful if the query used an inner join. do_execsql_test join-13.2 { CREATE INDEX ccc ON cc(c); SELECT * FROM aa LEFT JOIN bb, cc WHERE cc.c=aa.a; } {45 {} 45 45 {} 45} finish_test |