Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch coroutine-refactor Excluding Merge-Ins
This is equivalent to a diff from be24fbc221 to a522f364a6
2014-02-07
| ||
22:21 | Add opcodes OP_InitCoroutine and OP_EndCoroutine. Use these to remove the need for separate boolean registers to record when a co-routine has finished. (check-in: 5a88b6a7ae user: drh tags: trunk) | |
19:26 | In the TCL bindings, make sure Tcl_AppendResult() is always terminated by "(char*)0" and not just "0". (check-in: ea4d23d1c0 user: drh tags: trunk) | |
19:18 | Change the OP_InitCoroutine instruction to jump over the co-routine implementation. (Closed-Leaf check-in: a522f364a6 user: drh tags: coroutine-refactor) | |
18:27 | Get rid of the OP_Undef and OP_IsUndef opcodes in favor of higher-level OP_InitCoroutine and OP_EndCoroutine. (check-in: 1ec0e9dd4b user: drh tags: coroutine-refactor) | |
13:20 | Add the OP_Undef and OP_IsUndef opcodes. With these, use the first register in the result register range as the flag to indicate EOF on an INSERT from a SELECT, rather than allocating a separate boolean register for that task. (check-in: 6fb7448550 user: drh tags: coroutine-refactor) | |
03:28 | More comment updates. No changes to code. (check-in: be24fbc221 user: mistachkin tags: trunk) | |
02:29 | Update comments in vdbe.c. No changes to code. (check-in: 1122b410de user: drh tags: trunk) | |
Changes to src/insert.c.
︙ | |||
345 346 347 348 349 350 351 | 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 | - - - - - - - + + + - - - + - - + - - - - - - + + - - - - - - + - - - + | ** ** Registers are allocated as follows: ** ** pDest->iSDParm The register holding the next entry-point of the ** co-routine. Run the co-routine to its next breakpoint ** by calling "OP_Yield $X" where $X is pDest->iSDParm. ** |
︙ | |||
484 485 486 487 488 489 490 | 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 | - - - - + - + - - - - + - - + - | ** close cursors ** end foreach ** ** The 3rd template is for when the second template does not apply ** and the SELECT clause does not read from <table> at any time. ** The generated code follows this template: ** |
︙ | |||
572 573 574 575 576 577 578 | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 | - | /* Register allocations */ int regFromSelect = 0;/* Base register for data coming from SELECT */ int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ int regRowCount = 0; /* Memory cell used for the row counter */ int regIns; /* Block of regs holding rowid+data being inserted */ int regRowid; /* registers holding insert rowid */ int regData; /* register holding first column to insert */ |
︙ | |||
685 686 687 688 689 690 691 | 658 659 660 661 662 663 664 665 666 667 668 669 670 671 | - | ** co-routine is the common header to the 3rd and 4th templates. */ if( pSelect ){ /* Data is coming from a SELECT. Generate a co-routine to run the SELECT */ int rc = sqlite3CodeCoroutine(pParse, pSelect, &dest); if( rc ) goto insert_cleanup; |
︙ | |||
710 711 712 713 714 715 716 | 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 | - + - - - - + | if( useTempTable ){ /* Invoke the coroutine to extract information from the SELECT ** and add it to a transient table srcTab. The code generated ** here is from the 4th template: ** ** B: open temp table |
︙ | |||
843 844 845 846 847 848 849 | 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 | - + - + - - + - | } /* This is the top of the main insertion loop */ if( useTempTable ){ /* This block codes the top of loop only. The complete loop is the ** following pseudocode (template 4): ** |
︙ |
Changes to src/select.c.
︙ | |||
761 762 763 764 765 766 767 | 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 | - - - - - - + + | sqlite3ExprCodeMove(pParse, regResult, iParm, 1); /* The LIMIT clause will jump out of the loop for us */ } break; } #endif /* #ifndef SQLITE_OMIT_SUBQUERY */ |
︙ | |||
2568 2569 2570 2571 2572 2573 2574 | 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 | - - + | ){ int i, j; /* Loop counters */ Select *pPrior; /* Another SELECT immediately to our left */ Vdbe *v; /* Generate code to this VDBE */ SelectDest destA; /* Destination for coroutine A */ SelectDest destB; /* Destination for coroutine B */ int regAddrA; /* Address register for select-A coroutine */ |
︙ | |||
2714 2715 2716 2717 2718 2719 2720 | 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 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 | - - - - - - - - - + + - + - - - + + - - + + + - - + - | } sqlite3ExprDelete(db, p->pLimit); p->pLimit = 0; sqlite3ExprDelete(db, p->pOffset); p->pOffset = 0; regAddrA = ++pParse->nMem; |
︙ | |||
2779 2780 2781 2782 2783 2784 2785 | 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 | - - + - - - + + + - - - + + - - + - - + - - + - - + + - - - - | regPrev, pKeyDup, labelEnd); } sqlite3KeyInfoUnref(pKeyDup); /* Generate a subroutine to run when the results from select A ** are exhausted and only data in select B remains. */ |
︙ | |||
4555 4556 4557 4558 4559 4560 4561 | 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 | - - - + - - - - + - | }else if( pTabList->nSrc==1 && OptimizationEnabled(db, SQLITE_SubqCoroutine) ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. */ int addrTop; |
︙ |
Changes to src/vdbe.c.
︙ | |||
389 390 391 392 393 394 395 | 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | - + | #endif #ifdef SQLITE_DEBUG /* ** Print the value of a register for tracing purposes: */ static void memTracePrint(Mem *p){ |
︙ | |||
698 699 700 701 702 703 704 | 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 | - - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + - + | } #endif break; } /* Opcode: Gosub P1 P2 * * * |
︙ | |||
970 971 972 973 974 975 976 | 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 | - + | pOut->flags = nullFlag; cnt--; } break; } |
︙ | |||
5187 5188 5189 5190 5191 5192 5193 | 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 | - + | pFrame->nOp = p->nOp; pFrame->token = pProgram->token; pFrame->aOnceFlag = p->aOnceFlag; pFrame->nOnceFlag = p->nOnceFlag; pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ |
︙ |
Changes to src/vdbeInt.h.
︙ | |||
194 195 196 197 198 199 200 | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | - + | #define MEM_Null 0x0001 /* Value is NULL */ #define MEM_Str 0x0002 /* Value is a string */ #define MEM_Int 0x0004 /* Value is an integer */ #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_RowSet 0x0020 /* Value is a RowSet object */ #define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ |
︙ | |||
226 227 228 229 230 231 232 | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | - + | ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f) /* ** Return true if a memory cell is not marked as invalid. This macro ** is for use inside assert() statements only. */ #ifdef SQLITE_DEBUG |
︙ | |||
421 422 423 424 425 426 427 | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | - - - + + + + | double sqlite3VdbeRealValue(Mem*); void sqlite3VdbeIntegerAffinity(Mem*); int sqlite3VdbeMemRealify(Mem*); int sqlite3VdbeMemNumerify(Mem*); int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); void sqlite3VdbeMemReleaseExternal(Mem *p); |
︙ |
Changes to src/vdbeaux.c.
︙ | |||
1230 1231 1232 1233 1234 1235 1236 | 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 | - + | if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){ sqlite3VdbeMemRelease(p); }else if( p->zMalloc ){ sqlite3DbFree(db, p->zMalloc); p->zMalloc = 0; } |
︙ | |||
1698 1699 1700 1701 1702 1703 1704 | 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 | - + | memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0])); memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0])); } if( p->aMem ){ p->aMem--; /* aMem[] goes from 1..nMem */ p->nMem = nMem; /* not from 0..nMem-1 */ for(n=1; n<=nMem; n++){ |
︙ | |||
1810 1811 1812 1813 1814 1815 1816 | 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 | - + | #ifdef SQLITE_DEBUG /* Execute assert() statements to ensure that the Vdbe.apCsr[] and ** Vdbe.aMem[] arrays have already been cleaned up. */ int i; if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 ); if( p->aMem ){ |
︙ |
Changes to src/vdbemem.c.
︙ | |||
583 584 585 586 587 588 589 | 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 | - + | ** copies are not misused. */ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ int i; Mem *pX; for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){ if( pX->pScopyFrom==pMem ){ |
︙ |
Changes to src/where.c.
︙ | |||
2781 2782 2783 2784 2785 2786 2787 | 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 | - - + + - | sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); VdbeComment((v, "init LEFT JOIN no-match flag")); } /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->viaCoroutine ){ int regYield = pTabItem->regReturn; |
︙ |