GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — sqlcipher/src/select.c at master · securitykernel/sqlcipher Expand file tree/ Copy pathselect.cMore file actions 6785 lines (6408 loc) · 243 KB / Copy pathselect.cFile metadata and controls6785 lines (6408 loc) · 243 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 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 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 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 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 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 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. */ #include "sqliteInt.h" /* ** Trace output macros */ #if SELECTTRACE_ENABLED /***/ int sqlite3SelectTrace = 0; # define SELECTTRACE(K,P,S,X) \ if(sqlite3SelectTrace&(K)) \ sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ sqlite3DebugPrintf X #else # define SELECTTRACE(K,P,S,X) #endif /* ** An instance of the following object is used to record information about ** how to process the DISTINCT keyword, to simplify passing that information ** into the selectInnerLoop() routine. */ typedef struct DistinctCtx DistinctCtx; struct DistinctCtx { u8 isTnct; /* True if the DISTINCT keyword is present */ u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */ int tabTnct; /* Ephemeral table used for DISTINCT processing */ int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */ }; /* ** An instance of the following object is used to record information about ** the ORDER BY (or GROUP BY) clause of query is being coded. ** ** The aDefer[] array is used by the sorter-references optimization. For ** example, assuming there is no index that can be used for the ORDER BY, ** for the query: ** ** SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10; ** ** it may be more efficient to add just the "a" values to the sorter, and ** retrieve the associated "bigblob" values directly from table t1 as the ** 10 smallest "a" values are extracted from the sorter. ** ** When the sorter-reference optimization is used, there is one entry in the ** aDefer[] array for each database table that may be read as values are ** extracted from the sorter. */ typedef struct SortCtx SortCtx; struct SortCtx { ExprList *pOrderBy; /* The ORDER BY (or GROUP BY clause) */ int nOBSat; /* Number of ORDER BY terms satisfied by indices */ int iECursor; /* Cursor number for the sorter */ int regReturn; /* Register holding block-output return address */ int labelBkOut; /* Start label for the block-output subroutine */ int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */ int labelDone; /* Jump here when done, ex: LIMIT reached */ int labelOBLopt; /* Jump here when sorter is full */ u8 sortFlags; /* Zero or more SORTFLAG_* bits */ #ifdef SQLITE_ENABLE_SORTER_REFERENCES u8 nDefer; /* Number of valid entries in aDefer[] */ struct DeferredCsr { Table *pTab; /* Table definition */ int iCsr; /* Cursor number for table */ int nKey; /* Number of PK columns for table pTab (>=1) */ } aDefer[4]; #endif struct RowLoadInfo *pDeferredRowLoad; /* Deferred row loading info or NULL */ }; #define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ /* ** Delete all the content of a Select structure. Deallocate the structure ** itself depending on the value of bFree ** ** If bFree==1, call sqlite3DbFree() on the p object. ** If bFree==0, Leave the first Select object unfreed */ static void clearSelect(sqlite3 *db, Select *p, int bFree){ while( p ){ Select *pPrior = p->pPrior; sqlite3ExprListDelete(db, p->pEList); sqlite3SrcListDelete(db, p->pSrc); sqlite3ExprDelete(db, p->pWhere); sqlite3ExprListDelete(db, p->pGroupBy); sqlite3ExprDelete(db, p->pHaving); sqlite3ExprListDelete(db, p->pOrderBy); sqlite3ExprDelete(db, p->pLimit); #ifndef SQLITE_OMIT_WINDOWFUNC if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){ sqlite3WindowListDelete(db, p->pWinDefn); } assert( p->pWin==0 ); #endif if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; bFree = 1; } } /* ** Initialize a SelectDest structure. */ void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ pDest->eDest = (u8)eDest; pDest->iSDParm = iParm; pDest->zAffSdst = 0; pDest->iSdst = 0; pDest->nSdst = 0; } /* ** Allocate a new Select structure and return a pointer to that ** structure. */ Select *sqlite3SelectNew( Parse *pParse, /* Parsing context */ ExprList *pEList, /* which columns to include in the result */ SrcList *pSrc, /* the FROM clause -- which tables to scan */ Expr *pWhere, /* the WHERE clause */ ExprList *pGroupBy, /* the GROUP BY clause */ Expr *pHaving, /* the HAVING clause */ ExprList *pOrderBy, /* the ORDER BY clause */ u32 selFlags, /* Flag parameters, such as SF_Distinct */ Expr *pLimit /* LIMIT value. NULL means not used */ ){ Select *pNew; Select standin; pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) ); if( pNew==0 ){ assert( pParse->db->mallocFailed ); pNew = &standin; } if( pEList==0 ){ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(pParse->db,TK_ASTERISK,0)); } pNew->pEList = pEList; pNew->op = TK_SELECT; pNew->selFlags = selFlags; pNew->iLimit = 0; pNew->iOffset = 0; pNew->selId = ++pParse->nSelect; pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = 0; if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc)); pNew->pSrc = pSrc; pNew->pWhere = pWhere; pNew->pGroupBy = pGroupBy; pNew->pHaving = pHaving; pNew->pOrderBy = pOrderBy; pNew->pPrior = 0; pNew->pNext = 0; pNew->pLimit = pLimit; pNew->pWith = 0; #ifndef SQLITE_OMIT_WINDOWFUNC pNew->pWin = 0; pNew->pWinDefn = 0; #endif if( pParse->db->mallocFailed ) { clearSelect(pParse->db, pNew, pNew!=&standin); pNew = 0; }else{ assert( pNew->pSrc!=0 || pParse->nErr>0 ); } assert( pNew!=&standin ); return pNew; } /* ** Delete the given Select structure and all of its substructures. */ void sqlite3SelectDelete(sqlite3 *db, Select *p){ if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1); } /* ** Delete all the substructure for p, but keep p allocated. Redefine ** p to be a single SELECT where every column of the result set has a ** value of NULL. */ void sqlite3SelectReset(Parse *pParse, Select *p){ if( ALWAYS(p) ){ clearSelect(pParse->db, p, 0); memset(&p->iLimit, 0, sizeof(Select) - offsetof(Select,iLimit)); p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(pParse->db,TK_NULL,0,0)); p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(SrcList)); } } /* ** Return a pointer to the right-most SELECT statement in a compound. */ static Select *findRightmost(Select *p){ while( p->pNext ) p = p->pNext; return p; } /* ** Given 1 to 3 identifiers preceding the JOIN keyword, determine the ** type of join. Return an integer constant that expresses that type ** in terms of the following bit values: ** ** JT_INNER ** JT_CROSS ** JT_OUTER ** JT_NATURAL ** JT_LEFT ** JT_RIGHT ** ** A full outer join is the combination of JT_LEFT and JT_RIGHT. ** ** If an illegal or unsupported join type is seen, then still return ** a join type, but put an error in the pParse structure. */ int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ int jointype = 0; Token *apAll[3]; Token *p; /* 0123456789 123456789 123456789 123 */ static const char zKeyText[] = "naturaleftouterightfullinnercross"; static const struct { u8 i; /* Beginning of keyword text in zKeyText[] */ u8 nChar; /* Length of the keyword in characters */ u8 code; /* Join type mask */ } aKeyword[] = { /* natural */ { 0, 7, JT_NATURAL }, /* left */ { 6, 4, JT_LEFT|JT_OUTER }, /* outer */ { 10, 5, JT_OUTER }, /* right */ { 14, 5, JT_RIGHT|JT_OUTER }, /* full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER }, /* inner */ { 23, 5, JT_INNER }, /* cross */ { 28, 5, JT_INNER|JT_CROSS }, }; int i, j; apAll[0] = pA; apAll[1] = pB; apAll[2] = pC; for(i=0; i<3 && apAll[i]; i++){ p = apAll[i]; for(j=0; j<ArraySize(aKeyword); j++){ if( p->n==aKeyword[j].nChar && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){ jointype |= aKeyword[j].code; break; } } testcase( j==0 || j==1 || j==2 || j==3 || j==4 || j==5 || j==6 ); if( j>=ArraySize(aKeyword) ){ jointype |= JT_ERROR; break; } } if( (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) || (jointype & JT_ERROR)!=0 ){ const char *zSp = " "; assert( pB!=0 ); if( pC==0 ){ zSp++; } sqlite3ErrorMsg(pParse, "unknown or unsupported join type: " "%T %T%s%T", pA, pB, zSp, pC); jointype = JT_INNER; }else if( (jointype & JT_OUTER)!=0 && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){ sqlite3ErrorMsg(pParse, "RIGHT and FULL OUTER JOINs are not currently supported"); jointype = JT_INNER; } return jointype; } /* ** Return the index of a column in a table. Return -1 if the column ** is not contained in the table. */ static int columnIndex(Table *pTab, const char *zCol){ int i; for(i=0; i<pTab->nCol; i++){ if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i; } return -1; } /* ** Search the first N tables in pSrc, from left to right, looking for a ** table that has a column named zCol. ** ** When found, set *piTab and *piCol to the table index and column index ** of the matching column and return TRUE. ** ** If not found, return FALSE. */ static int tableAndColumnIndex( SrcList *pSrc, /* Array of tables to search */ int N, /* Number of tables in pSrc->a[] to search */ const char *zCol, /* Name of the column we are looking for */ int *piTab, /* Write index of pSrc->a[] here */ int *piCol, /* Write index of pSrc->a[*piTab].pTab->aCol[] here */ int bIgnoreHidden /* True to ignore hidden columns */ ){ int i; /* For looping over tables in pSrc */ int iCol; /* Index of column matching zCol */ assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=0; i<N; i++){ iCol = columnIndex(pSrc->a[i].pTab, zCol); if( iCol>=0 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) ){ if( piTab ){ *piTab = i; *piCol = iCol; } return 1; } } return 0; } /* ** This function is used to add terms implied by JOIN syntax to the ** WHERE clause expression of a SELECT statement. The new term, which ** is ANDed with the existing WHERE clause, is of the form: ** ** (tab1.col1 = tab2.col2) ** ** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the ** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is ** column iColRight of tab2. */ static void addWhereTerm( Parse *pParse, /* Parsing context */ SrcList *pSrc, /* List of tables in FROM clause */ int iLeft, /* Index of first table to join in pSrc */ int iColLeft, /* Index of column in first table */ int iRight, /* Index of second table in pSrc */ int iColRight, /* Index of column in second table */ int isOuterJoin, /* True if this is an OUTER join */ Expr **ppWhere /* IN/OUT: The WHERE clause to add to */ ){ sqlite3 *db = pParse->db; Expr *pE1; Expr *pE2; Expr *pEq; assert( iLeft<iRight ); assert( pSrc->nSrc>iRight ); assert( pSrc->a[iLeft].pTab ); assert( pSrc->a[iRight].pTab ); pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft); pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight); pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); if( pEq && isOuterJoin ){ ExprSetProperty(pEq, EP_FromJoin); assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(pEq, EP_NoReduce); pEq->iRightJoinTable = (i16)pE2->iTable; } *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq); } /* ** Set the EP_FromJoin property on all terms of the given expression. ** And set the Expr.iRightJoinTable to iTable for every term in the ** expression. ** ** The EP_FromJoin property is used on terms of an expression to tell ** the LEFT OUTER JOIN processing logic that this term is part of the ** join restriction specified in the ON or USING clause and not a part ** of the more general WHERE clause. These terms are moved over to the ** WHERE clause during join processing but we need to remember that they ** originated in the ON or USING clause. ** ** The Expr.iRightJoinTable tells the WHERE clause processing that the ** expression depends on table iRightJoinTable even if that table is not ** explicitly mentioned in the expression. That information is needed ** for cases like this: ** ** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5 ** ** The where clause needs to defer the handling of the t1.x=5 ** term until after the t2 loop of the join. In that way, a ** NULL t2 row will be inserted whenever t1.x!=5. If we do not ** defer the handling of t1.x=5, it will be processed immediately ** after the t1 loop and rows with t1.x!=5 will never appear in ** the output, which is incorrect. */ void sqlite3SetJoinExpr(Expr *p, int iTable){ while( p ){ ExprSetProperty(p, EP_FromJoin); assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(p, EP_NoReduce); p->iRightJoinTable = (i16)iTable; if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; i<p->x.pList->nExpr; i++){ sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable); } } sqlite3SetJoinExpr(p->pLeft, iTable); p = p->pRight; } } /* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every ** term that is marked with EP_FromJoin and iRightJoinTable==iTable into ** an ordinary term that omits the EP_FromJoin mark. ** ** This happens when a LEFT JOIN is simplified into an ordinary JOIN. */ static void unsetJoinExpr(Expr *p, int iTable){ while( p ){ if( ExprHasProperty(p, EP_FromJoin) && (iTable<0 || p->iRightJoinTable==iTable) ){ ExprClearProperty(p, EP_FromJoin); } if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; i<p->x.pList->nExpr; i++){ unsetJoinExpr(p->x.pList->a[i].pExpr, iTable); } } unsetJoinExpr(p->pLeft, iTable); p = p->pRight; } } /* ** This routine processes the join information for a SELECT statement. ** ON and USING clauses are converted into extra terms of the WHERE clause. ** NATURAL joins also create extra WHERE clause terms. ** ** The terms of a FROM clause are contained in the Select.pSrc structure. ** The left most table is the first entry in Select.pSrc. The right-most ** table is the last entry. The join operator is held in the entry to ** the left. Thus entry 0 contains the join operator for the join between ** entries 0 and 1. Any ON or USING clauses associated with the join are ** also attached to the left entry. ** ** This routine returns the number of errors encountered. */ static int sqliteProcessJoin(Parse *pParse, Select *p){ SrcList *pSrc; /* All tables in the FROM clause */ int i, j; /* Loop counters */ struct SrcList_item *pLeft; /* Left table being joined */ struct SrcList_item *pRight; /* Right table being joined */ pSrc = p->pSrc; pLeft = &pSrc->a[0]; pRight = &pLeft[1]; for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){ Table *pRightTab = pRight->pTab; int isOuter; if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; isOuter = (pRight->fg.jointype & JT_OUTER)!=0; /* When the NATURAL keyword is present, add WHERE clause terms for ** every column that the two tables have in common. */ if( pRight->fg.jointype & JT_NATURAL ){ if( pRight->pOn || pRight->pUsing ){ sqlite3ErrorMsg(pParse, "a NATURAL join may not have " "an ON or USING clause", 0); return 1; } for(j=0; j<pRightTab->nCol; j++){ char *zName; /* Name of column in the right table */ int iLeft; /* Matching left table */ int iLeftCol; /* Matching column in the left table */ if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue; zName = pRightTab->aCol[j].zName; if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 1) ){ addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j, isOuter, &p->pWhere); } } } /* Disallow both ON and USING clauses in the same join */ if( pRight->pOn && pRight->pUsing ){ sqlite3ErrorMsg(pParse, "cannot have both ON and USING " "clauses in the same join"); return 1; } /* Add the ON clause to the end of the WHERE clause, connected by ** an AND operator. */ if( pRight->pOn ){ if( isOuter ) sqlite3SetJoinExpr(pRight->pOn, pRight->iCursor); p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn); pRight->pOn = 0; } /* Create extra terms on the WHERE clause for each column named ** in the USING clause. Example: If the two tables to be joined are ** A and B and the USING clause names X, Y, and Z, then add this ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z ** Report an error if any column mentioned in the USING clause is ** not contained in both tables to be joined. */ if( pRight->pUsing ){ IdList *pList = pRight->pUsing; for(j=0; j<pList->nId; j++){ char *zName; /* Name of the term in the USING clause */ int iLeft; /* Table on the left with matching column name */ int iLeftCol; /* Column number of matching column on the left */ int iRightCol; /* Column number of matching column on the right */ zName = pList->a[j].zName; iRightCol = columnIndex(pRightTab, zName); if( iRightCol<0 || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0) ){ sqlite3ErrorMsg(pParse, "cannot join using column %s - column " "not present in both tables", zName); return 1; } addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol, isOuter, &p->pWhere); } } } return 0; } /* ** An instance of this object holds information (beyond pParse and pSelect) ** needed to load the next result row that is to be added to the sorter. */ typedef struct RowLoadInfo RowLoadInfo; struct RowLoadInfo { int regResult; /* Store results in array of registers here */ u8 ecelFlags; /* Flag argument to ExprCodeExprList() */ #ifdef SQLITE_ENABLE_SORTER_REFERENCES ExprList *pExtra; /* Extra columns needed by sorter refs */ int regExtraResult; /* Where to load the extra columns */ #endif }; /* ** This routine does the work of loading query data into an array of ** registers so that it can be added to the sorter. */ static void innerLoopLoadRow( Parse *pParse, /* Statement under construction */ Select *pSelect, /* The query being coded */ RowLoadInfo *pInfo /* Info needed to complete the row load */ ){ sqlite3ExprCodeExprList(pParse, pSelect->pEList, pInfo->regResult, 0, pInfo->ecelFlags); #ifdef SQLITE_ENABLE_SORTER_REFERENCES if( pInfo->pExtra ){ sqlite3ExprCodeExprList(pParse, pInfo->pExtra, pInfo->regExtraResult, 0, 0); sqlite3ExprListDelete(pParse->db, pInfo->pExtra); } #endif } /* ** Code the OP_MakeRecord instruction that generates the entry to be ** added into the sorter. ** ** Return the register in which the result is stored. */ static int makeSorterRecord( Parse *pParse, SortCtx *pSort, Select *pSelect, int regBase, int nBase ){ int nOBSat = pSort->nOBSat; Vdbe *v = pParse->pVdbe; int regOut = ++pParse->nMem; if( pSort->pDeferredRowLoad ){ innerLoopLoadRow(pParse, pSelect, pSort->pDeferredRowLoad); } sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regOut); return regOut; } /* ** Generate code that will push the record in registers regData ** through regData+nData-1 onto the sorter. */ static void pushOntoSorter( Parse *pParse, /* Parser context */ SortCtx *pSort, /* Information about the ORDER BY clause */ Select *pSelect, /* The whole SELECT statement */ int regData, /* First register holding data to be sorted */ int regOrigData, /* First register holding data before packing */ int nData, /* Number of elements in the regData data array */ int nPrefixReg /* No. of reg prior to regData available for use */ ){ Vdbe *v = pParse->pVdbe; /* Stmt under construction */ int bSeq = ((pSort->sortFlags & SORTFLAG_UseSorter)==0); int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */ int nBase = nExpr + bSeq + nData; /* Fields in sorter record */ int regBase; /* Regs for sorter record */ int regRecord = 0; /* Assembled sorter record */ int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */ int op; /* Opcode to add sorter record to sorter */ int iLimit; /* LIMIT counter */ int iSkip = 0; /* End of the sorter insert loop */ assert( bSeq==0 || bSeq==1 ); /* Three cases: ** (1) The data to be sorted has already been packed into a Record ** by a prior OP_MakeRecord. In this case nData==1 and regData ** will be completely unrelated to regOrigData. ** (2) All output columns are included in the sort record. In that ** case regData==regOrigData. ** (3) Some output columns are omitted from the sort record due to ** the SQLITE_ENABLE_SORTER_REFERENCE optimization, or due to the ** SQLITE_ECEL_OMITREF optimization, or due to the ** SortCtx.pDeferredRowLoad optimiation. In any of these cases ** regOrigData is 0 to prevent this routine from trying to copy ** values that might not yet exist. */ assert( nData==1 || regData==regOrigData || regOrigData==0 ); if( nPrefixReg ){ assert( nPrefixReg==nExpr+bSeq ); regBase = regData - nPrefixReg; }else{ regBase = pParse->nMem + 1; pParse->nMem += nBase; } assert( pSelect->iOffset==0 || pSelect->iLimit!=0 ); iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit; pSort->labelDone = sqlite3VdbeMakeLabel(pParse); sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData, SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0)); if( bSeq ){ sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); } if( nPrefixReg==0 && nData>0 ){ sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData); } if( nOBSat>0 ){ int regPrevKey; /* The first nOBSat columns of the previous row */ int addrFirst; /* Address of the OP_IfNot opcode */ int addrJmp; /* Address of the OP_Jump opcode */ VdbeOp *pOp; /* Opcode that opens the sorter */ int nKey; /* Number of sorting key columns, including OP_Sequence */ KeyInfo *pKI; /* Original KeyInfo on the sorter table */ regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase); regPrevKey = pParse->nMem+1; pParse->nMem += pSort->nOBSat; nKey = nExpr - pSort->nOBSat + bSeq; if( bSeq ){ addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); }else{ addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor); } VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat); pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); if( pParse->db->mallocFailed ) return; pOp->p2 = nKey + nData; pKI = pOp->p4.pKeyInfo; memset(pKI->aSortFlags, 0, pKI->nKeyField); /* Makes OP_Jump testable */ sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); testcase( pKI->nAllField > pKI->nKeyField+2 ); pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, pKI->nAllField-pKI->nKeyField-1); pOp = 0; /* Ensure pOp not used after sqltie3VdbeAddOp3() */ addrJmp = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse); pSort->regReturn = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor); if( iLimit ){ sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, pSort->labelDone); VdbeCoverage(v); } sqlite3VdbeJumpHere(v, addrFirst); sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat); sqlite3VdbeJumpHere(v, addrJmp); } if( iLimit ){ /* At this point the values for the new sorter entry are stored ** in an array of registers. They need to be composed into a record ** and inserted into the sorter if either (a) there are currently ** less than LIMIT+OFFSET items or (b) the new record is smaller than ** the largest record currently in the sorter. If (b) is true and there ** are already LIMIT+OFFSET items in the sorter, delete the largest ** entry before inserting the new one. This way there are never more ** than LIMIT+OFFSET items in the sorter. ** ** If the new record does not need to be inserted into the sorter, ** jump to the next iteration of the loop. If the pSort->labelOBLopt ** value is not zero, then it is a label of where to jump. Otherwise, ** just bypass the row insert logic. See the header comment on the ** sqlite3WhereOrderByLimitOptLabel() function for additional info. */ int iCsr = pSort->iECursor; sqlite3VdbeAddOp2(v, OP_IfNotZero, iLimit, sqlite3VdbeCurrentAddr(v)+4); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Last, iCsr, 0); iSkip = sqlite3VdbeAddOp4Int(v, OP_IdxLE, iCsr, 0, regBase+nOBSat, nExpr-nOBSat); VdbeCoverage(v); sqlite3VdbeAddOp1(v, OP_Delete, iCsr); } if( regRecord==0 ){ regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase); } if( pSort->sortFlags & SORTFLAG_UseSorter ){ op = OP_SorterInsert; }else{ op = OP_IdxInsert; } sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord, regBase+nOBSat, nBase-nOBSat); if( iSkip ){ sqlite3VdbeChangeP2(v, iSkip, pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v)); } } /* ** Add code to implement the OFFSET */ static void codeOffset( Vdbe *v, /* Generate code into this VM */ int iOffset, /* Register holding the offset counter */ int iContinue /* Jump here to skip the current record */ ){ if( iOffset>0 ){ sqlite3VdbeAddOp3(v, OP_IfPos, iOffset, iContinue, 1); VdbeCoverage(v); VdbeComment((v, "OFFSET")); } } /* ** Add code that will check to make sure the N registers starting at iMem ** form a distinct entry. iTab is a sorting index that holds previously ** seen combinations of the N values. A new entry is made in iTab ** if the current N values are new. ** ** A jump to addrRepeat is made and the N+1 values are popped from the ** stack if the top N elements are not distinct. */ static void codeDistinct( Parse *pParse, /* Parsing and code generating context */ int iTab, /* A sorting index used to test for distinctness */ int addrRepeat, /* Jump to here if not distinct */ int N, /* Number of elements */ int iMem /* First element */ ){ Vdbe *v; int r1; v = pParse->pVdbe; r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r1, iMem, N); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); sqlite3ReleaseTempReg(pParse, r1); } #ifdef SQLITE_ENABLE_SORTER_REFERENCES /* ** This function is called as part of inner-loop generation for a SELECT ** statement with an ORDER BY that is not optimized by an index. It ** determines the expressions, if any, that the sorter-reference ** optimization should be used for. The sorter-reference optimization ** is used for SELECT queries like: ** ** SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10 ** ** If the optimization is used for expression "bigblob", then instead of ** storing values read from that column in the sorter records, the PK of ** the row from table t1 is stored instead. Then, as records are extracted from ** the sorter to return to the user, the required value of bigblob is ** retrieved directly from table t1. If the values are very large, this ** can be more efficient than storing them directly in the sorter records. ** ** The ExprList_item.bSorterRef flag is set for each expression in pEList ** for which the sorter-reference optimization should be enabled. ** Additionally, the pSort->aDefer[] array is populated with entries ** for all cursors required to evaluate all selected expressions. Finally. ** output variable (*ppExtra) is set to an expression list containing ** expressions for all extra PK values that should be stored in the ** sorter records. */ static void selectExprDefer( Parse *pParse, /* Leave any error here */ SortCtx *pSort, /* Sorter context */ ExprList *pEList, /* Expressions destined for sorter */ ExprList **ppExtra /* Expressions to append to sorter record */ ){ int i; int nDefer = 0; ExprList *pExtra = 0; for(i=0; i<pEList->nExpr; i++){ struct ExprList_item *pItem = &pEList->a[i]; if( pItem->u.x.iOrderByCol==0 ){ Expr *pExpr = pItem->pExpr; Table *pTab = pExpr->y.pTab; if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab) && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF) ){ int j; for(j=0; j<nDefer; j++){ if( pSort->aDefer[j].iCsr==pExpr->iTable ) break; } if( j==nDefer ){ if( nDefer==ArraySize(pSort->aDefer) ){ continue; }else{ int nKey = 1; int k; Index *pPk = 0; if( !HasRowid(pTab) ){ pPk = sqlite3PrimaryKeyIndex(pTab); nKey = pPk->nKeyCol; } for(k=0; k<nKey; k++){ Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0); if( pNew ){ pNew->iTable = pExpr->iTable; pNew->y.pTab = pExpr->y.pTab; pNew->iColumn = pPk ? pPk->aiColumn[k] : -1; pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew); } } pSort->aDefer[nDefer].pTab = pExpr->y.pTab; pSort->aDefer[nDefer].iCsr = pExpr->iTable; pSort->aDefer[nDefer].nKey = nKey; nDefer++; } } pItem->bSorterRef = 1; } } } pSort->nDefer = (u8)nDefer; *ppExtra = pExtra; } #endif /* ** This routine generates the code for the inside of the inner loop ** of a SELECT. ** ** If srcTab is negative, then the p->pEList expressions ** are evaluated in order to get the data for this row. If srcTab is ** zero or more, then data is pulled from srcTab and p->pEList is used only ** to get the number of columns and the collation sequence for each column. */ static void selectInnerLoop( Parse *pParse, /* The parser context */ Select *p, /* The complete select statement being coded */ int srcTab, /* Pull data from this table if non-negative */ SortCtx *pSort, /* If not NULL, info on how to process ORDER BY */ DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */ SelectDest *pDest, /* How to dispose of the results */ int iContinue, /* Jump here to continue with next row */ int iBreak /* Jump here to break out of the inner loop */ ){ Vdbe *v = pParse->pVdbe; int i; int hasDistinct; /* True if the DISTINCT keyword is present */ int eDest = pDest->eDest; /* How to dispose of results */ int iParm = pDest->iSDParm; /* First argument to disposal method */ int nResultCol; /* Number of result columns */ int nPrefixReg = 0; /* Number of extra registers before regResult */ RowLoadInfo sRowLoadInfo; /* Info for deferred row loading */ /* Usually, regResult is the first cell in an array of memory cells ** containing the current result row. In this case regOrig is set to the ** same value. However, if the results are being sent to the sorter, the ** values for any expressions that are also part of the sort-key are omitted ** from this array. In this case regOrig is set to zero. */ int regResult; /* Start of memory holding current results */ int regOrig; /* Start of memory holding full result (or 0) */ assert( v ); assert( p->pEList!=0 ); hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; if( pSort && pSort->pOrderBy==0 ) pSort = 0; if( pSort==0 && !hasDistinct ){ assert( iContinue!=0 ); codeOffset(v, p->iOffset, iContinue); } /* Pull the requested columns. */ nResultCol = p->pEList->nExpr; if( pDest->iSdst==0 ){ if( pSort ){ nPrefixReg = pSort->pOrderBy->nExpr; if( !(pSort->sortFlags & SORTFLAG_UseSorter) ) nPrefixReg++; pParse->nMem += nPrefixReg; } pDest->iSdst = pParse->nMem+1; pParse->nMem += nResultCol; }else if( pDest->iSdst+nResultCol > pParse->nMem ){ /* This is an error condition that can result, for example, when a SELECT ** on the right-hand side of an INSERT contains more result columns than ** there are columns in the table on the left. The error will be caught ** and reported later. But we need to make sure enough memory is allocated ** to avoid other spurious errors in the meantime. */ pParse->nMem += nResultCol; } pDest->nSdst = nResultCol; regOrig = regResult = pDest->iSdst; if( srcTab>=0 ){ for(i=0; i<nResultCol; i++){ sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i); VdbeComment((v, "%s", p->pEList->a[i].zEName)); } }else if( eDest!=SRT_Exists ){ #ifdef SQLITE_ENABLE_SORTER_REFERENCES ExprList *pExtra = 0; #endif /* If the destination is an EXISTS(...) expression, the actual ** values returned by the SELECT are not required. */ u8 ecelFlags; /* "ecel" is an abbreviation of "ExprCodeExprList" */ ExprList *pEList; if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){ ecelFlags = SQLITE_ECEL_DUP; }else{ ecelFlags = 0; } if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){ /* For each expression in p->pEList that is a copy of an expression in ** the ORDER BY clause (pSort->pOrderBy), set the associated ** iOrderByCol value to one more than the index of the ORDER BY ** expression within the sort-key that pushOntoSorter() will generate. ** This allows the p->pEList field to be omitted from the sorted record, ** saving space and CPU cycles. */ ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF); for(i=pSort->nOBSat; i<pSort->pOrderBy->nExpr; i++){ int j; if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){ p->pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat; } } #ifdef SQLITE_ENABLE_SORTER_REFERENCES selectExprDefer(pParse, pSort, p->pEList, &pExtra); if( pExtra && pParse->db->mallocFailed==0 ){ /* If there are any extra PK columns to add to the sorter records, ** allocate extra memory cells and adjust the OpenEphemeral ** instruction to account for the larger records. This is only ** required if there are one or more WITHOUT ROWID tables with ** composite primary keys in the SortCtx.aDefer[] array. */ VdbeOp *pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); pOp->p2 += (pExtra->nExpr - pSort->nDefer); pOp->p4.pKeyInfo->nAllField += (pExtra->nExpr - pSort->nDefer); pParse->nMem += pExtra->nExpr; } #endif /* Adjust nResultCol to account for columns that are omitted ** from the sorter by the optimizations in this branch */ pEList = p->pEList; for(i=0; i<pEList->nExpr; i++){ if( pEList->a[i].u.x.iOrderByCol>0 #ifdef SQLITE_ENABLE_SORTER_REFERENCES || pEList->a[i].bSorterRef #endif ){ nResultCol--; regOrig = 0; } |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |