/ Check-in [8bbfa978]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:The compound-select merge optimization passes quick.test with no errors. (CVS 5299)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8bbfa97837a74ef0514e0c92ea2a6576f02cc361
User & Date: drh 2008-06-25 00:12:41
References
2013-05-06
15:21 New ticket [6709574d] COLLATE clause in ORDER BY causes incorrect EXCEPT. artifact: 5bbf9ac1 user: drh
Context
2008-06-25
02:22
Add new test script for compound select statements. (CVS 5300) check-in: a193b161 user: drh tags: trunk
00:12
The compound-select merge optimization passes quick.test with no errors. (CVS 5299) check-in: 8bbfa978 user: drh tags: trunk
2008-06-24
22:50
OS/2 fixes for pre-C99 compilers and a return code correction in os2Access(). (CVS 5298) check-in: 3241a3bd user: pweilbacher tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
...
557
558
559
560
561
562
563
564
565

566
567
568
569
570
571
572
....
1783
1784
1785
1786
1787
1788
1789

1790
1791
1792
1793
1794
1795
1796
....
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
....
2308
2309
2310
2311
2312
2313
2314
















2315
2316
2317
2318
2319
2320
2321



2322
2323
2324
2325
2326
2327
2328
2329
2330
















2331
2332
2333
2334
2335
2336
2337
....
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
....
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488


2489







2490
2491
2492
2493
2494
2495
2496
....
2517
2518
2519
2520
2521
2522
2523

2524
2525
2526
2527
2528
2529
2530
....
2538
2539
2540
2541
2542
2543
2544

2545
2546
2547
2548
2549
2550
2551
2552





2553
2554

2555
2556
2557
2558
2559
2560
2561

2562
2563
2564
2565
2566


2567
2568
2569






































































2570
2571
























2572
2573
2574
2575



2576

2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587




2588
2589
2590
2591
2592
2593
2594
....
2596
2597
2598
2599
2600
2601
2602
2603

2604
2605

2606
2607
2608
2609
2610
2611
2612
....
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633

2634

2635
2636
2637
2638
2639

2640

2641


2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
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
2735
2736
2737
2738
2739
2740

2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757

2758
2759
2760
2761






2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
**    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.
**
** $Id: select.c,v 1.435 2008/06/24 12:46:31 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
  sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord);
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord);
  sqlite3ReleaseTempReg(pParse, regRecord);
  sqlite3ReleaseTempRange(pParse, regBase, nExpr+2);
  if( pSelect->iLimit ){
    int addr1, addr2;
    int iLimit;
    if( pSelect->pOffset ){
      iLimit = pSelect->iOffset+1;
    }else{
      iLimit = pSelect->iLimit;
    }
    addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit);
    sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1);
    addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
................................................................................
  */
  if( nColumn>0 ){
    nResultCol = nColumn;
  }else{
    nResultCol = pEList->nExpr;
  }
  if( pDest->iMem==0 ){
    pDest->iMem = sqlite3GetTempRange(pParse, nResultCol);
    pDest->nMem = nResultCol;

  }else if( pDest->nMem!=nResultCol ){
    /* This happens when two SELECTs of a compound SELECT have differing
    ** numbers of result columns.  The error message will be generated by
    ** a higher-level routine. */
    return;
  }
  regResult = pDest->iMem;
................................................................................
** SELECT statements.
*/
static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
  Vdbe *v = 0;
  int iLimit = 0;
  int iOffset;
  int addr1;


  /* 
  ** "LIMIT -1" always shows all rows.  There is some
  ** contraversy about what the correct behavior should be.
  ** The current implementation interprets "LIMIT 0" to mean
  ** no rows.
  */
................................................................................
  if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
      " do not have the same number of result columns", selectOpName(p->op));
    rc = 1;
    goto multi_select_end;
  }

#if 0
  if( p->pOrderBy ){
    return multiSelectOrderBy(pParse, p, pDest, aff);
  }
#endif

  /* Generate code for the left and right SELECT statements.
  */
................................................................................
  return rc;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */

/*
** Code an output subroutine for a coroutine implementation of a
** SELECT statment.
















*/
static int outputSubroutine(
  Parse *pParse,          /* Parsing context */
  Select *p,              /* The SELECT statement */
  SelectDest *pIn,        /* Coroutine supplying data */
  SelectDest *pDest,      /* Where to send the data */
  int regReturn,          /* The return address register */



  int iBreak              /* Jump here if we hit the LIMIT */
){
  Vdbe *v = pParse->pVdbe;
  int iContinue;
  int addr;
  if( v==0 ) return 0;

  addr = sqlite3VdbeCurrentAddr(v);
  iContinue = sqlite3VdbeMakeLabel(v);
















  codeOffset(v, p, iContinue);

  switch( pDest->eDest ){
    /* Store the result as data using a unique key.
    */
    case SRT_Table:
    case SRT_EphemTab: {
................................................................................
  /* Jump to the end of the loop if the LIMIT is reached.
  */
  if( p->iLimit ){
    sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
    sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak);
  }

  /* Advance the coroutine to its next value.
  */
  sqlite3VdbeResolveLabel(v, iContinue);
  sqlite3VdbeAddOp1(v, OP_Yield, pIn->iParm);

  /* Generate the subroutine return
  */
  sqlite3VdbeAddOp1(v, OP_Return, regReturn);

  return addr;
}

/*
** Alternative compound select code generator for cases when there
................................................................................
**
** The implementation of the latter five subroutines depend on which 
** <operator> is used:
**
**
**             UNION ALL         UNION            EXCEPT          INTERSECT
**          -------------  -----------------  --------------  -----------------
**   AltB:   outA, nextA      outA, nextA       outA, nextA        nextA
**
**   AeqB:   outA, nextA         nextA             nextA           outA
**                                                            nextA while A==B
**
**   AgtB:   outB, nextB      outB, nextB          nextB           nextB
**
**   EofA:   outB, nextB      A<-B, outB,          halt            halt
**                          nextB while A==B
**
**   EofB:   outA, nextA      B<-A, outA        outA, nextA        halt


**                          nextA while A==B







**
** The implementation plan is to implement the two coroutines and seven
** subroutines first, then put the control logic at the bottom.  Like this:
**
**          goto Init
**     coA: coroutine for left query (A)
**     coB: coroutine for right query (B)
................................................................................
*/
static int multiSelectOrderBy(
  Parse *pParse,        /* Parsing context */
  Select *p,            /* The right-most of SELECTs to be coded */
  SelectDest *pDest,    /* What to do with query results */
  char *aff             /* If eDest is SRT_Union, the affinity string */
){

  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 */
  int regEofA;          /* Flag to indicate when select-A is complete */
  int regAddrB;         /* Address register for select-B coroutine */
................................................................................
  int addrEofA;         /* Address of the select-A-exhausted subroutine */
  int addrEofB;         /* Address of the select-B-exhausted subroutine */
  int addrAltB;         /* Address of the A<B subroutine */
  int addrAeqB;         /* Address of the A==B subroutine */
  int addrAgtB;         /* Address of the A>B subroutine */
  int regLimitA;        /* Limit register for select-A */
  int regLimitB;        /* Limit register for select-A */

  int savedLimit;       /* Saved value of p->iLimit */
  int savedOffset;      /* Saved value of p->iOffset */
  int labelCmpr;        /* Label for the start of the merge algorithm */
  int labelEnd;         /* Label for the end of the overall SELECT stmt */
  int j1, j2, j3;       /* Jump instructions that get retargetted */
  int op;               /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
  KeyInfo *pKeyInfo;    /* Type data for comparisons */
  int p4type;           /* P4 type used for pKeyInfo */






  assert( p->pOrderBy!=0 );

  v = pParse->pVdbe;
  if( v==0 ) return SQLITE_NOMEM;
  labelEnd = sqlite3VdbeMakeLabel(v);
  labelCmpr = sqlite3VdbeMakeLabel(v);
  pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
  p4type = P4_KEYINFO_HANDOFF;


  /* Patch up the ORDER BY clause
  */
  op = p->op;  
  pPrior = p->pPrior;
  assert( pPrior->pOrderBy==0 );


  if( processCompoundOrderBy(pParse, p, 0) ){
    return SQLITE_ERROR;
  }






































































  pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy);
 
























  /* Separate the left and the right query from one another
  */
  p->pPrior = 0;
  pPrior->pRightmost = 0;



  

  /* Compute the limit registers */
  computeLimitRegisters(pParse, p, labelEnd);
  if( p->iLimit ){
    regLimitA = ++pParse->nMem;
    regLimitB = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit,
                                  regLimitA);
    sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB);
  }else{
    regLimitA = regLimitB = 0;
  }





  regAddrA = ++pParse->nMem;
  regEofA = ++pParse->nMem;
  regAddrB = ++pParse->nMem;
  regEofB = ++pParse->nMem;
  regOutA = ++pParse->nMem;
  regOutB = ++pParse->nMem;
................................................................................
  sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);

  /* Jump past the various subroutines and coroutines to the main
  ** merge loop
  */
  j1 = sqlite3VdbeAddOp0(v, OP_Goto);
  addrSelectA = sqlite3VdbeCurrentAddr(v);


  /* Generate a coroutine to evaluate the SELECT statement to the
  ** left of the compound operator - the "A" select. */

  VdbeNoopComment((v, "Begin coroutine for left SELECT"));
  pPrior->iLimit = regLimitA;
  sqlite3Select(pParse, pPrior, &destA, 0, 0, 0, 0);
  sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofA);
  sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
  VdbeNoopComment((v, "End coroutine for left SELECT"));

................................................................................
  p->iLimit = savedLimit;
  p->iOffset = savedOffset;
  sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofB);
  sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
  VdbeNoopComment((v, "End coroutine for right SELECT"));

  /* Generate a subroutine that outputs the current row of the A
  ** select as the next output row of the compound select and then
  ** advances the A select to its next row
  */
  VdbeNoopComment((v, "Output routine for A"));

  addrOutA = outputSubroutine(pParse, p, &destA, pDest, regOutA, labelEnd);

  
  /* Generate a subroutine that outputs the current row of the B
  ** select as the next output row of the compound select and then
  ** advances the B select to its next row
  */

  VdbeNoopComment((v, "Output routine for B"));

  addrOutB = outputSubroutine(pParse, p, &destB, pDest, regOutB, labelEnd);



  /* Generate a subroutine to run when the results from select A
  ** are exhausted and only data in select B remains.
  */
  VdbeNoopComment((v, "eof-A subroutine"));
  addrEofA = sqlite3VdbeCurrentAddr(v);
  if( op==TK_EXCEPT || op==TK_INTERSECT ){
    sqlite3VdbeAddOp2(v, OP_Goto, 0, labelEnd);
  }else{  
    if( op==TK_ALL ){
      j2 = sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd);
      sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
      sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
    }else{
      assert( op==TK_UNION );
      sqlite3ExprCodeCopy(pParse, destB.iMem, destA.iMem, destB.nMem);
      j2 = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
      sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd);
      sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, destB.nMem,
                           (char*)pKeyInfo, p4type);
      p4type = P4_KEYINFO_STATIC;
      sqlite3VdbeAddOp3(v, OP_Jump, j2, j2+4, j2);
      sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
      sqlite3VdbeAddOp2(v, OP_Goto, 0, j2+1);
    }
  }

  /* Generate a subroutine to run when the results from select B
  ** are exhausted and only data in select A remains.
  */
  if( op==TK_INTERSECT ){
    addrEofB = addrEofA;
  }else{  
    VdbeNoopComment((v, "eof-B subroutine"));
    addrEofB = sqlite3VdbeCurrentAddr(v);
    if( op==TK_ALL || op==TK_EXCEPT ){
      j2 = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd);
      sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
      sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
    }else{
      assert( op==TK_UNION );
      sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd);
      sqlite3ExprCodeCopy(pParse, destA.iMem, destB.iMem, destA.nMem);
      j2 = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
      sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd);
      sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, destB.nMem,
                           (char*)pKeyInfo, p4type);
      p4type = P4_KEYINFO_STATIC;
      sqlite3VdbeAddOp3(v, OP_Jump, j2, j2+4, j2);
      sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
      sqlite3VdbeAddOp2(v, OP_Goto, 0, j2+1);
    }
  }

  /* Generate code to handle the case of A<B
  */
  VdbeNoopComment((v, "A-lt-B subroutine"));
  addrAltB = sqlite3VdbeCurrentAddr(v);
  if( op==TK_INTERSECT ){
    sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
  }else{
    sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
  }
  sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
  sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);

  /* Generate code to handle the case of A==B
  */
  if( op==TK_ALL ){
    addrAeqB = addrAltB;



  }else{
    VdbeNoopComment((v, "A-eq-B subroutine"));
    addrAeqB = sqlite3VdbeCurrentAddr(v);
    if( op==TK_INTERSECT ){
      sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
      j2 = sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
      sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
      sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, destA.nMem,
                           (char*)pKeyInfo, p4type);
      p4type = P4_KEYINFO_STATIC;
      j3 = sqlite3VdbeCurrentAddr(v)+1;
      sqlite3VdbeAddOp3(v, OP_Jump, j3, j2, j3);
      sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
    }else{
      sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
      sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
      sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
    }
  }

  /* Generate code to handle the case of A>B
  */
  VdbeNoopComment((v, "A-gt-B subroutine"));
  addrAgtB = sqlite3VdbeCurrentAddr(v);
  if( op==TK_ALL || op==TK_UNION ){
    sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
  }else{
    sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
  }

  sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);
  sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);

  /* This code runs once to initialize everything.
  */
  sqlite3VdbeJumpHere(v, j1);
  sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofA);
  sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofB);
  sqlite3VdbeAddOp2(v, OP_Integer, addrSelectB, regAddrB);
  sqlite3VdbeAddOp2(v, OP_Gosub, regAddrA, addrSelectA);
  sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
  sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
  sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);

  /* Implement the main merge loop
  */
  sqlite3VdbeResolveLabel(v, labelCmpr);

  sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, destA.nMem,
                         (char*)pKeyInfo, p4type);
  p4type = P4_KEYINFO_STATIC;
  sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);







  /* Jump to the this point in order to terminate the query.
  */
  sqlite3VdbeResolveLabel(v, labelEnd);

  /* Set the number of output columns
  */
  if( pDest->eDest==SRT_Callback ){
    Select *pFirst = p;
    while( pFirst->pPrior ) pFirst = pFirst->pPrior;
    generateColumnNames(pParse, 0, pFirst->pEList);
  }

  /* Free the KeyInfo if unused.
  */
  if( p4type==P4_KEYINFO_HANDOFF ){
    sqlite3_free(pKeyInfo);
  }

  /*** TBD:  Insert subroutine calls to close cursors on incomplete
  **** subqueries ****/
  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_VIEW







|







 







|







 







|

>







 







>







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|





>
>
>









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|


<
<
<
<







 







|

|
<

|

|
<

|
>
>
|
>
>
>
>
>
>
>







 







>







 







>




|

|
|
>
>
>
>
>


>




<
<

>





>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>
>
>
|
>


|








>
>
>
>







 








>

|
>







 







|
<


>
|
>


|
<

>
|
>
|
>
>





<

|

<
|
|
<
<
<
<
<
<
<
<
<
<
|
|
<









<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
|
|
<





|
<
|
<
<
<







>
>
>


|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<








<
<

>








|
|

<





>
|
<
|

>
>
>
>
>
>








|




|
|
|
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
...
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
....
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
....
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
....
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
....
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467




2468
2469
2470
2471
2472
2473
2474
....
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513

2514
2515
2516
2517

2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
....
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
....
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606


2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
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
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
....
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
....
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
2838
2839
2840
2841
2842
2843











2844
2845
2846

2847
2848
2849
2850
2851
2852
2853
2854


2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867

2868
2869
2870
2871
2872
2873
2874

2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898


2899
2900
2901
2902
2903
2904
2905
**    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.
**
** $Id: select.c,v 1.436 2008/06/25 00:12:41 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
  sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord);
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord);
  sqlite3ReleaseTempReg(pParse, regRecord);
  sqlite3ReleaseTempRange(pParse, regBase, nExpr+2);
  if( pSelect->iLimit ){
    int addr1, addr2;
    int iLimit;
    if( pSelect->iOffset ){
      iLimit = pSelect->iOffset+1;
    }else{
      iLimit = pSelect->iLimit;
    }
    addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit);
    sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1);
    addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
................................................................................
  */
  if( nColumn>0 ){
    nResultCol = nColumn;
  }else{
    nResultCol = pEList->nExpr;
  }
  if( pDest->iMem==0 ){
    pDest->iMem = pParse->nMem+1;
    pDest->nMem = nResultCol;
    pParse->nMem += nResultCol;
  }else if( pDest->nMem!=nResultCol ){
    /* This happens when two SELECTs of a compound SELECT have differing
    ** numbers of result columns.  The error message will be generated by
    ** a higher-level routine. */
    return;
  }
  regResult = pDest->iMem;
................................................................................
** SELECT statements.
*/
static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
  Vdbe *v = 0;
  int iLimit = 0;
  int iOffset;
  int addr1;
  if( p->iLimit ) return;

  /* 
  ** "LIMIT -1" always shows all rows.  There is some
  ** contraversy about what the correct behavior should be.
  ** The current implementation interprets "LIMIT 0" to mean
  ** no rows.
  */
................................................................................
  if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
      " do not have the same number of result columns", selectOpName(p->op));
    rc = 1;
    goto multi_select_end;
  }

#if 1
  if( p->pOrderBy ){
    return multiSelectOrderBy(pParse, p, pDest, aff);
  }
#endif

  /* Generate code for the left and right SELECT statements.
  */
................................................................................
  return rc;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */

/*
** Code an output subroutine for a coroutine implementation of a
** SELECT statment.
**
** The data to be output is contained in pIn->iMem.  There are
** pIn->nMem columns to be output.  pDest is where the output should
** be sent.
**
** regReturn is the number of the register holding the subroutine
** return address.
**
** If regPrev>0 then it is a the first register in a vector that
** records the previous output.  mem[regPrev] is a flag that is false
** if there has been no previous output.  If regPrev>0 then code is
** generated to suppress duplicates.  pKeyInfo is used for comparing
** keys.
**
** If the LIMIT found in p->iLimit is reached, jump immediately to
** iBreak.
*/
static int generateOutputSubroutine(
  Parse *pParse,          /* Parsing context */
  Select *p,              /* The SELECT statement */
  SelectDest *pIn,        /* Coroutine supplying data */
  SelectDest *pDest,      /* Where to send the data */
  int regReturn,          /* The return address register */
  int regPrev,            /* Previous result register.  No uniqueness if 0 */
  KeyInfo *pKeyInfo,      /* For comparing with previous entry */
  int p4type,             /* The p4 type for pKeyInfo */
  int iBreak              /* Jump here if we hit the LIMIT */
){
  Vdbe *v = pParse->pVdbe;
  int iContinue;
  int addr;
  if( v==0 ) return 0;

  addr = sqlite3VdbeCurrentAddr(v);
  iContinue = sqlite3VdbeMakeLabel(v);

  /* Suppress duplicates for UNION, EXCEPT, and INTERSECT 
  */
  if( regPrev ){
    int j1, j2;
    j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
    j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem,
                              (char*)pKeyInfo, p4type);
    sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
    sqlite3VdbeJumpHere(v, j1);
    sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem);
    sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
  }

  /* Suppress the the first OFFSET entries if there is an OFFSET clause
  */
  codeOffset(v, p, iContinue);

  switch( pDest->eDest ){
    /* Store the result as data using a unique key.
    */
    case SRT_Table:
    case SRT_EphemTab: {
................................................................................
  /* Jump to the end of the loop if the LIMIT is reached.
  */
  if( p->iLimit ){
    sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
    sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak);
  }

  /* Generate the subroutine return
  */
  sqlite3VdbeResolveLabel(v, iContinue);




  sqlite3VdbeAddOp1(v, OP_Return, regReturn);

  return addr;
}

/*
** Alternative compound select code generator for cases when there
................................................................................
**
** The implementation of the latter five subroutines depend on which 
** <operator> is used:
**
**
**             UNION ALL         UNION            EXCEPT          INTERSECT
**          -------------  -----------------  --------------  -----------------
**   AltB:   outA, nextA      outA, nextA       outA, nextA         nextA
**
**   AeqB:   outA, nextA         nextA             nextA         outA, nextA

**
**   AgtB:   outB, nextB      outB, nextB          nextB            nextB
**
**   EofA:   outB, nextB      outB, nextB          halt             halt

**
**   EofB:   outA, nextA      outA, nextA       outA, nextA         halt
**
** In the AltB, AeqB, and AgtB subroutines, an EOF on A following nextA
** causes an immediate jump to EofA and an EOF on B following nextB causes
** an immediate jump to EofB.  Within EofA and EofB, and EOF on entry or
** following nextX causes a jump to the end of the select processing.
**
** Duplicate removal in the UNION, EXCEPT, and INTERSECT cases is handled
** within the output subroutine.  The regPrev register set holds the previously
** output value.  A comparison is made against this value and the output
** is skipped if the next results would be the same as the previous.
**
** The implementation plan is to implement the two coroutines and seven
** subroutines first, then put the control logic at the bottom.  Like this:
**
**          goto Init
**     coA: coroutine for left query (A)
**     coB: coroutine for right query (B)
................................................................................
*/
static int multiSelectOrderBy(
  Parse *pParse,        /* Parsing context */
  Select *p,            /* The right-most of SELECTs to be coded */
  SelectDest *pDest,    /* What to do with query results */
  char *aff             /* If eDest is SRT_Union, the affinity string */
){
  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 */
  int regEofA;          /* Flag to indicate when select-A is complete */
  int regAddrB;         /* Address register for select-B coroutine */
................................................................................
  int addrEofA;         /* Address of the select-A-exhausted subroutine */
  int addrEofB;         /* Address of the select-B-exhausted subroutine */
  int addrAltB;         /* Address of the A<B subroutine */
  int addrAeqB;         /* Address of the A==B subroutine */
  int addrAgtB;         /* Address of the A>B subroutine */
  int regLimitA;        /* Limit register for select-A */
  int regLimitB;        /* Limit register for select-A */
  int regPrev;          /* A range of registers to hold previous output */
  int savedLimit;       /* Saved value of p->iLimit */
  int savedOffset;      /* Saved value of p->iOffset */
  int labelCmpr;        /* Label for the start of the merge algorithm */
  int labelEnd;         /* Label for the end of the overall SELECT stmt */
  int j1;               /* Jump instructions that get retargetted */
  int op;               /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
  KeyInfo *pKeyDup;     /* Comparison information for duplicate removal */
  KeyInfo *pKeyMerge;   /* Comparison information for merging rows */
  sqlite3 *db;          /* Database connection */
  ExprList *pOrderBy;   /* The ORDER BY clause */
  int nOrderBy;         /* Number of terms in the ORDER BY clause */
  int *aPermute;        /* Mapping from ORDER BY terms to result set columns */
  u8 NotUsed;           /* Dummy variables */

  assert( p->pOrderBy!=0 );
  db = pParse->db;
  v = pParse->pVdbe;
  if( v==0 ) return SQLITE_NOMEM;
  labelEnd = sqlite3VdbeMakeLabel(v);
  labelCmpr = sqlite3VdbeMakeLabel(v);




  /* Patch up the ORDER BY clause
  */
  op = p->op;  
  pPrior = p->pPrior;
  assert( pPrior->pOrderBy==0 );
  pOrderBy = p->pOrderBy;
  if( pOrderBy ){
    if( processCompoundOrderBy(pParse, p, 0) ){
      return SQLITE_ERROR;
    }
    nOrderBy = pOrderBy->nExpr;
  }else{
    nOrderBy = 0;
  }
  /* For operators other than UNION ALL we have to make sure that
  ** the ORDER BY clause covers every term of the result set.  Add
  ** terms to the ORDER BY clause as necessary.
  */
  if( op!=TK_ALL ){
    for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
      for(j=0; j<nOrderBy; j++){
        Expr *pTerm = pOrderBy->a[j].pExpr;
        assert( pTerm->op==TK_INTEGER );
        assert( (pTerm->flags & EP_IntValue)!=0 );
        if( pTerm->iTable==i ) break;
      }
      if( j==nOrderBy ){
        Expr *pNew = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, 0);
        if( pNew==0 ) return SQLITE_NOMEM;
        pNew->flags |= EP_IntValue;
        pNew->iTable = i;
        pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew, 0);
        nOrderBy++;
      }
    }
  }

  /* Compute the comparison permutation and keyinfo that is used with
  ** the permutation in order to comparisons to determine if the next
  ** row of results comes from selectA or selectB.  Also add explicit
  ** collations to the ORDER BY clause terms so that when the subqueries
  ** to the right and the left are evaluated, they use the correct
  ** collation.
  */
  aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
  if( aPermute ){
    for(i=0; i<nOrderBy; i++){
      Expr *pTerm = pOrderBy->a[i].pExpr;
      assert( pTerm->op==TK_INTEGER );
      assert( (pTerm->flags & EP_IntValue)!=0 );
      aPermute[i] = pTerm->iTable-1;
      assert( aPermute[i]>=0 && aPermute[i]<p->pEList->nExpr );
    }
    pKeyMerge =
      sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
    if( pKeyMerge ){
      pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
      pKeyMerge->nField = nOrderBy;
      pKeyMerge->enc = ENC(db);
      for(i=0; i<nOrderBy; i++){
        CollSeq *pColl;
        Expr *pTerm = pOrderBy->a[i].pExpr;
        if( pTerm->flags & EP_ExpCollate ){
          pColl = pTerm->pColl;
        }else{
          pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
          pTerm->flags |= EP_ExpCollate;
          pTerm->pColl = pColl;
        }
        pKeyMerge->aColl[i] = pColl;
        pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
      }
    }
  }else{
    pKeyMerge = 0;
  }

  /* Reattach the ORDER BY clause to the query.
  */
  p->pOrderBy = pOrderBy;
  pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy);

  /* Allocate a range of temporary registers and the KeyInfo needed
  ** for the logic that removes duplicate result rows when the
  ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL).
  */
  if( op==TK_ALL ){
    regPrev = 0;
  }else{
    int nExpr = p->pEList->nExpr;
    assert( nOrderBy>=nExpr );
    regPrev = sqlite3GetTempRange(pParse, nExpr+1);
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
    pKeyDup = sqlite3DbMallocZero(db,
                  sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
    if( pKeyDup ){
      pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
      pKeyDup->nField = nExpr;
      pKeyDup->enc = ENC(db);
      for(i=0; i<nExpr; i++){
        pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
        pKeyDup->aSortOrder[i] = 0;
      }
    }
  }
 
  /* Separate the left and the right query from one another
  */
  p->pPrior = 0;
  pPrior->pRightmost = 0;
  processOrderGroupBy(pParse, p, p->pOrderBy, 1, &NotUsed);
  if( pPrior->pPrior==0 ){
    processOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, 1, &NotUsed);
  }

  /* Compute the limit registers */
  computeLimitRegisters(pParse, p, labelEnd);
  if( p->iLimit && op==TK_ALL ){
    regLimitA = ++pParse->nMem;
    regLimitB = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit,
                                  regLimitA);
    sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB);
  }else{
    regLimitA = regLimitB = 0;
  }
  sqlite3ExprDelete(p->pLimit);
  p->pLimit = 0;
  sqlite3ExprDelete(p->pOffset);
  p->pOffset = 0;

  regAddrA = ++pParse->nMem;
  regEofA = ++pParse->nMem;
  regAddrB = ++pParse->nMem;
  regEofB = ++pParse->nMem;
  regOutA = ++pParse->nMem;
  regOutB = ++pParse->nMem;
................................................................................
  sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);

  /* Jump past the various subroutines and coroutines to the main
  ** merge loop
  */
  j1 = sqlite3VdbeAddOp0(v, OP_Goto);
  addrSelectA = sqlite3VdbeCurrentAddr(v);


  /* Generate a coroutine to evaluate the SELECT statement to the
  ** left of the compound operator - the "A" select.
  */
  VdbeNoopComment((v, "Begin coroutine for left SELECT"));
  pPrior->iLimit = regLimitA;
  sqlite3Select(pParse, pPrior, &destA, 0, 0, 0, 0);
  sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofA);
  sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
  VdbeNoopComment((v, "End coroutine for left SELECT"));

................................................................................
  p->iLimit = savedLimit;
  p->iOffset = savedOffset;
  sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofB);
  sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
  VdbeNoopComment((v, "End coroutine for right SELECT"));

  /* Generate a subroutine that outputs the current row of the A
  ** select as the next output row of the compound select.

  */
  VdbeNoopComment((v, "Output routine for A"));
  addrOutA = generateOutputSubroutine(pParse,
                 p, &destA, pDest, regOutA,
                 regPrev, pKeyDup, P4_KEYINFO_HANDOFF, labelEnd);
  
  /* Generate a subroutine that outputs the current row of the B
  ** select as the next output row of the compound select.

  */
  if( op==TK_ALL || op==TK_UNION ){
    VdbeNoopComment((v, "Output routine for B"));
    addrOutB = generateOutputSubroutine(pParse,
                 p, &destB, pDest, regOutB,
                 regPrev, pKeyDup, P4_KEYINFO_STATIC, labelEnd);
  }

  /* Generate a subroutine to run when the results from select A
  ** are exhausted and only data in select B remains.
  */
  VdbeNoopComment((v, "eof-A subroutine"));

  if( op==TK_EXCEPT || op==TK_INTERSECT ){
    addrEofA = sqlite3VdbeAddOp2(v, OP_Goto, 0, labelEnd);
  }else{  

    addrEofA = sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd);
    sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);










    sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA);

  }

  /* Generate a subroutine to run when the results from select B
  ** are exhausted and only data in select A remains.
  */
  if( op==TK_INTERSECT ){
    addrEofB = addrEofA;
  }else{  
    VdbeNoopComment((v, "eof-B subroutine"));


    addrEofB = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd);
    sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);











    sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB);

  }

  /* Generate code to handle the case of A<B
  */
  VdbeNoopComment((v, "A-lt-B subroutine"));
  addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);

  sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);



  sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
  sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);

  /* Generate code to handle the case of A==B
  */
  if( op==TK_ALL ){
    addrAeqB = addrAltB;
  }else if( op==TK_INTERSECT ){
    addrAeqB = addrAltB;
    addrAltB++;
  }else{
    VdbeNoopComment((v, "A-eq-B subroutine"));
    addrAeqB =











    sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
    sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
    sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);

  }

  /* Generate code to handle the case of A>B
  */
  VdbeNoopComment((v, "A-gt-B subroutine"));
  addrAgtB = sqlite3VdbeCurrentAddr(v);
  if( op==TK_ALL || op==TK_UNION ){
    sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);


  }
  sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
  sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);
  sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);

  /* This code runs once to initialize everything.
  */
  sqlite3VdbeJumpHere(v, j1);
  sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofA);
  sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofB);
  sqlite3VdbeAddOp2(v, OP_Gosub, regAddrA, addrSelectA);
  sqlite3VdbeAddOp2(v, OP_Gosub, regAddrB, addrSelectB);
  sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);

  sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);

  /* Implement the main merge loop
  */
  sqlite3VdbeResolveLabel(v, labelCmpr);
  sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
  sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy,

                         (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
  sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);

  /* Release temporary registers
  */
  if( regPrev ){
    sqlite3ReleaseTempRange(pParse, regPrev, nOrderBy+1);
  }

  /* Jump to the this point in order to terminate the query.
  */
  sqlite3VdbeResolveLabel(v, labelEnd);

  /* Set the number of output columns
  */
  if( pDest->eDest==SRT_Callback ){
    Select *pFirst = pPrior;
    while( pFirst->pPrior ) pFirst = pFirst->pPrior;
    generateColumnNames(pParse, 0, pFirst->pEList);
  }

  /* Reassembly the compound query so that it will be freed correctly
  ** by the calling function */
  p->pPrior = pPrior;



  /*** TBD:  Insert subroutine calls to close cursors on incomplete
  **** subqueries ****/
  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_VIEW

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
542
543
544
545
546
547
548


549
550
551
552
553
554
555
...
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
....
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
....
1079
1080
1081
1082
1083
1084
1085

1086
1087
1088
1089
1090
1091
1092
....
1735
1736
1737
1738
1739
1740
1741
















1742
1743
1744
1745
1746
1747
1748
1749
1750



1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763




1764
1765








1766
1767
1768


1769


1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.754 2008/06/23 18:49:44 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
  Op *pOp;                   /* Current operation */
  int rc = SQLITE_OK;        /* Value to return */
  sqlite3 *db = p->db;       /* The database */
  u8 encoding = ENC(db);     /* The database encoding */
  Mem *pIn1, *pIn2, *pIn3;   /* Input operands */
  Mem *pOut;                 /* Output operand */
  u8 opProperty;


#ifdef VDBE_PROFILE
  u64 start;                 /* CPU clock count at start of opcode */
  int origPc;                /* Program counter at start of opcode */
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  int nProgressOps = 0;      /* Opcodes executed since progress callback. */
#endif
................................................................................
  assert( p1+n<p->nMem );
  pIn1 = &p->aMem[p1];
  assert( p2>0 );
  assert( p2+n<p->nMem );
  pOut = &p->aMem[p2];
  assert( p1+n<=p2 || p2+n<=p1 );
  while( n-- ){
    REGISTER_TRACE(p1++, pIn1);
    zMalloc = pOut->zMalloc;
    pOut->zMalloc = 0;
    sqlite3VdbeMemMove(pOut, pIn1);
    pIn1->zMalloc = zMalloc;
    REGISTER_TRACE(p2++, pOut);
    pIn1++;
    pOut++;
................................................................................
** This instruction makes a deep copy of the value.  A duplicate
** is made of any string or blob constant.  See also OP_SCopy.
*/
case OP_Copy: {
  assert( pOp->p1>0 );
  assert( pOp->p1<=p->nMem );
  pIn1 = &p->aMem[pOp->p1];
  REGISTER_TRACE(pOp->p1, pIn1);
  assert( pOp->p2>0 );
  assert( pOp->p2<=p->nMem );
  pOut = &p->aMem[pOp->p2];
  assert( pOut!=pIn1 );
  sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
  Deephemeralize(pOut);
  REGISTER_TRACE(pOp->p2, pOut);
................................................................................
  ** and have an assigned type.  The results are de-ephemeralized as
  ** as side effect.
  */
  pMem = p->pResultSet = &p->aMem[pOp->p1];
  for(i=0; i<pOp->p2; i++){
    sqlite3VdbeMemNulTerminate(&pMem[i]);
    storeTypeInfo(&pMem[i], encoding);

  }
  if( db->mallocFailed ) goto no_mem;

  /* Return SQLITE_ROW
  */
  p->nCallback++;
  p->pc = pc + 1;
................................................................................
    pOut->u.i = res;
    REGISTER_TRACE(pOp->p2, pOut);
  }else if( res ){
    pc = pOp->p2-1;
  }
  break;
}

















/* Opcode: Compare P1 P2 P3 P4 *
**
** Compare to vectors of registers in reg(P1)..reg(P1+P3-1) (all this
** one "A") and in reg(P2)..reg(P2+P3-1) ("B").  Save the result of
** the comparison for use by the next OP_Jump instruct.
**
** P4 is a KeyInfo structure that defines collating sequences usedused for affinity purposes.  The
** comparison is done for sorting purposes, so NULLs compare



** equal, NULLs are less than numbers, numbers are less than strings,
** and strings are less than blobs.
*/
case OP_Compare: {
  int n = pOp->p3;
  int i, p1, p2;
  const KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
  assert( n>0 );
  p1 = pOp->p1;
  assert( p1>0 && p1+n-1<p->nMem );
  p2 = pOp->p2;
  assert( p2>0 && p2+n-1<p->nMem );
  for(i=0; i<n; i++, p1++, p2++){




    REGISTER_TRACE(p1, &p->aMem[p1]);
    REGISTER_TRACE(p2, &p->aMem[p2]);








    p->iCompare = sqlite3MemCompare(&p->aMem[p1], &p->aMem[p2],
                   pKeyInfo && i<pKeyInfo->nField ? pKeyInfo->aColl[i] : 0);
    if( p->iCompare ) break;


  }


  break;
}

/* Opcode: Jump P1 P2 P3 * *
**
** Jump to the instruction at address P1, P2, or P3 depending on whether
** in the most recent OP_Compare instruction the P1 vector was less than
** equal to, or greater than the P2 vector, respectively.
*/
case OP_Jump: {
  if( p->iCompare<0 ){
    pc = pOp->p1 - 1;
  }else if( p->iCompare==0 ){
    pc = pOp->p2 - 1;
  }else{
    pc = pOp->p3 - 1;
  }
  break;
}








|







 







>
>







 







<







 







<







 







>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
|
>
>
>
|











|
>
>
>
>
|
|
>
>
>
>
>
>
>
>
|
<
|
>
>
|
>
>









|
|

|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
...
995
996
997
998
999
1000
1001

1002
1003
1004
1005
1006
1007
1008
....
1017
1018
1019
1020
1021
1022
1023

1024
1025
1026
1027
1028
1029
1030
....
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
....
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798

1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.755 2008/06/25 00:12:41 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
  Op *pOp;                   /* Current operation */
  int rc = SQLITE_OK;        /* Value to return */
  sqlite3 *db = p->db;       /* The database */
  u8 encoding = ENC(db);     /* The database encoding */
  Mem *pIn1, *pIn2, *pIn3;   /* Input operands */
  Mem *pOut;                 /* Output operand */
  u8 opProperty;
  int iCompare = 0;          /* Result of last OP_Compare operation */
  int *aPermute = 0;         /* Permuation of columns for OP_Compare */
#ifdef VDBE_PROFILE
  u64 start;                 /* CPU clock count at start of opcode */
  int origPc;                /* Program counter at start of opcode */
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  int nProgressOps = 0;      /* Opcodes executed since progress callback. */
#endif
................................................................................
  assert( p1+n<p->nMem );
  pIn1 = &p->aMem[p1];
  assert( p2>0 );
  assert( p2+n<p->nMem );
  pOut = &p->aMem[p2];
  assert( p1+n<=p2 || p2+n<=p1 );
  while( n-- ){

    zMalloc = pOut->zMalloc;
    pOut->zMalloc = 0;
    sqlite3VdbeMemMove(pOut, pIn1);
    pIn1->zMalloc = zMalloc;
    REGISTER_TRACE(p2++, pOut);
    pIn1++;
    pOut++;
................................................................................
** This instruction makes a deep copy of the value.  A duplicate
** is made of any string or blob constant.  See also OP_SCopy.
*/
case OP_Copy: {
  assert( pOp->p1>0 );
  assert( pOp->p1<=p->nMem );
  pIn1 = &p->aMem[pOp->p1];

  assert( pOp->p2>0 );
  assert( pOp->p2<=p->nMem );
  pOut = &p->aMem[pOp->p2];
  assert( pOut!=pIn1 );
  sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
  Deephemeralize(pOut);
  REGISTER_TRACE(pOp->p2, pOut);
................................................................................
  ** and have an assigned type.  The results are de-ephemeralized as
  ** as side effect.
  */
  pMem = p->pResultSet = &p->aMem[pOp->p1];
  for(i=0; i<pOp->p2; i++){
    sqlite3VdbeMemNulTerminate(&pMem[i]);
    storeTypeInfo(&pMem[i], encoding);
    REGISTER_TRACE(pOp->p1+i, &pMem[i]);
  }
  if( db->mallocFailed ) goto no_mem;

  /* Return SQLITE_ROW
  */
  p->nCallback++;
  p->pc = pc + 1;
................................................................................
    pOut->u.i = res;
    REGISTER_TRACE(pOp->p2, pOut);
  }else if( res ){
    pc = pOp->p2-1;
  }
  break;
}

/* Opcode: Permutation * * * P4 *
**
** Set the permuation used by the OP_Compare operator to be the array
** of integers in P4.
**
** The permutation is only valid until the next OP_Permutation, OP_Compare,
** OP_Halt, or OP_ResultRow.  Typically the OP_Permutation should occur
** immediately prior to the OP_Compare.
*/
case OP_Permutation: {
  assert( pOp->p4type==P4_INTARRAY );
  assert( pOp->p4.ai );
  aPermute = pOp->p4.ai;
  break;
}

/* Opcode: Compare P1 P2 P3 P4 *
**
** Compare to vectors of registers in reg(P1)..reg(P1+P3-1) (all this
** one "A") and in reg(P2)..reg(P2+P3-1) ("B").  Save the result of
** the comparison for use by the next OP_Jump instruct.
**
** P4 is a KeyInfo structure that defines collating sequences and sort
** orders for the comparison.  The permutation applies to registers
** only.  The KeyInfo elements are used sequentially.
**
** The comparison is a sort comparison, so NULLs compare equal,
** NULLs are less than numbers, numbers are less than strings,
** and strings are less than blobs.
*/
case OP_Compare: {
  int n = pOp->p3;
  int i, p1, p2;
  const KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
  assert( n>0 );
  p1 = pOp->p1;
  assert( p1>0 && p1+n-1<p->nMem );
  p2 = pOp->p2;
  assert( p2>0 && p2+n-1<p->nMem );
  for(i=0; i<n; i++){
    int idx = aPermute ? aPermute[i] : i;
    CollSeq *pColl;    /* Collating sequence to use on this term */
    int bRev;          /* True for DESCENDING sort order */
    assert( pKeyInfo==0 || i<pKeyInfo->nField );
    REGISTER_TRACE(p1+idx, &p->aMem[p1+idx]);
    REGISTER_TRACE(p2+idx, &p->aMem[p2+idx]);
    if( pKeyInfo ){
      assert( i<pKeyInfo->nField );
      pColl = pKeyInfo->aColl[i];
      bRev = pKeyInfo->aSortOrder[i];
    }else{
      pColl = 0;
      bRev = 0;
    }
    iCompare = sqlite3MemCompare(&p->aMem[p1+idx], &p->aMem[p2+idx], pColl);

    if( iCompare ){
      if( bRev ) iCompare = -iCompare;
      break;
    }
  }
  aPermute = 0;
  break;
}

/* Opcode: Jump P1 P2 P3 * *
**
** Jump to the instruction at address P1, P2, or P3 depending on whether
** in the most recent OP_Compare instruction the P1 vector was less than
** equal to, or greater than the P2 vector, respectively.
*/
case OP_Jump: {             /* jump */
  if( iCompare<0 ){
    pc = pOp->p1 - 1;
  }else if( iCompare==0 ){
    pc = pOp->p2 - 1;
  }else{
    pc = pOp->p3 - 1;
  }
  break;
}

Changes to src/vdbe.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
57
58
59
60
61
62
63

64
65
66
67
68
69
70
..
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.133 2008/06/20 18:13:25 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
    double *pReal;         /* Used when p4type is P4_REAL */
    FuncDef *pFunc;        /* Used when p4type is P4_FUNCDEF */
    VdbeFunc *pVdbeFunc;   /* Used when p4type is P4_VDBEFUNC */
    CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
    Mem *pMem;             /* Used when p4type is P4_MEM */
    sqlite3_vtab *pVtab;   /* Used when p4type is P4_VTAB */
    KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */

  } p4;
#ifdef SQLITE_DEBUG
  char *zComment;          /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
  int cnt;                 /* Number of times this instruction was executed */
  u64 cycles;              /* Total time spent executing this instruction */
................................................................................
#define P4_MEM      (-8)  /* P4 is a pointer to a Mem*    structure */
#define P4_TRANSIENT (-9) /* P4 is a pointer to a transient string */
#define P4_VTAB     (-10) /* P4 is a pointer to an sqlite3_vtab structure */
#define P4_MPRINTF  (-11) /* P4 is a string obtained from sqlite3_mprintf() */
#define P4_REAL     (-12) /* P4 is a 64-bit floating point value */
#define P4_INT64    (-13) /* P4 is a 64-bit signed integer */
#define P4_INT32    (-14) /* P4 is a 32-bit signed integer */


/* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
** is made.  That copy is freed when the Vdbe is finalized.  But if the
** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used.  It still
** gets freed when the Vdbe is finalized so it still should be obtained
** from a single sqliteMalloc().  But no copy is made and the calling
** function should *not* try to free the KeyInfo.
*/
#define P4_KEYINFO_HANDOFF (-15)
#define P4_KEYINFO_STATIC  (-16)

/*
** The Vdbe.aColName array contains 5n Mem structures, where n is the 
** number of columns of data returned by the statement.
*/
#define COLNAME_NAME     0
#define COLNAME_DECLTYPE 1







|







 







>







 







>








|
|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
..
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
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.134 2008/06/25 00:12:41 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
    double *pReal;         /* Used when p4type is P4_REAL */
    FuncDef *pFunc;        /* Used when p4type is P4_FUNCDEF */
    VdbeFunc *pVdbeFunc;   /* Used when p4type is P4_VDBEFUNC */
    CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
    Mem *pMem;             /* Used when p4type is P4_MEM */
    sqlite3_vtab *pVtab;   /* Used when p4type is P4_VTAB */
    KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
    int *ai;               /* Used when p4type is P4_INTARRAY */
  } p4;
#ifdef SQLITE_DEBUG
  char *zComment;          /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
  int cnt;                 /* Number of times this instruction was executed */
  u64 cycles;              /* Total time spent executing this instruction */
................................................................................
#define P4_MEM      (-8)  /* P4 is a pointer to a Mem*    structure */
#define P4_TRANSIENT (-9) /* P4 is a pointer to a transient string */
#define P4_VTAB     (-10) /* P4 is a pointer to an sqlite3_vtab structure */
#define P4_MPRINTF  (-11) /* P4 is a string obtained from sqlite3_mprintf() */
#define P4_REAL     (-12) /* P4 is a 64-bit floating point value */
#define P4_INT64    (-13) /* P4 is a 64-bit signed integer */
#define P4_INT32    (-14) /* P4 is a 32-bit signed integer */
#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */

/* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
** is made.  That copy is freed when the Vdbe is finalized.  But if the
** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used.  It still
** gets freed when the Vdbe is finalized so it still should be obtained
** from a single sqliteMalloc().  But no copy is made and the calling
** function should *not* try to free the KeyInfo.
*/
#define P4_KEYINFO_HANDOFF (-16)
#define P4_KEYINFO_STATIC  (-17)

/*
** The Vdbe.aColName array contains 5n Mem structures, where n is the 
** number of columns of data returned by the statement.
*/
#define COLNAME_NAME     0
#define COLNAME_DECLTYPE 1

Changes to src/vdbeInt.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
*************************************************************************
** This is the header file for information that is private to the
** VDBE.  This information used to all be at the top of the single
** source code file "vdbe.c".  When that file became too big (over
** 6000 lines long) it was split up into several smaller files and
** this header information was factored out.
**
** $Id: vdbeInt.h,v 1.148 2008/06/20 18:13:25 drh Exp $
*/
#ifndef _VDBEINT_H_
#define _VDBEINT_H_

/*
** intToKey() and keyToInt() used to transform the rowid.  But with
** the latest versions of the design they are no-ops.
................................................................................
  Mem *pResultSet;        /* Pointer to an array of results */
  u8 explain;             /* True if EXPLAIN present on SQL command */
  u8 changeCntOn;         /* True to update the change-counter */
  u8 aborted;             /* True if ROLLBACK in another VM causes an abort */
  u8 expired;             /* True if the VM needs to be recompiled */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
  u8 inVtabMethod;        /* See comments above */
  int iCompare;           /* Result of most recent OP_Compare comparison */
  int nChange;            /* Number of db changes made since last reset */
  i64 startTime;          /* Time when query started - used for profiling */
  int btreeMask;          /* Bitmask of db->aDb[] entries referenced */
  BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
  int nSql;             /* Number of bytes in zSql */
  char *zSql;           /* Text of the SQL statement that generated this */
#ifdef SQLITE_DEBUG







|







 







<







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
317
318
319
320
321
322
323

324
325
326
327
328
329
330
*************************************************************************
** This is the header file for information that is private to the
** VDBE.  This information used to all be at the top of the single
** source code file "vdbe.c".  When that file became too big (over
** 6000 lines long) it was split up into several smaller files and
** this header information was factored out.
**
** $Id: vdbeInt.h,v 1.149 2008/06/25 00:12:41 drh Exp $
*/
#ifndef _VDBEINT_H_
#define _VDBEINT_H_

/*
** intToKey() and keyToInt() used to transform the rowid.  But with
** the latest versions of the design they are no-ops.
................................................................................
  Mem *pResultSet;        /* Pointer to an array of results */
  u8 explain;             /* True if EXPLAIN present on SQL command */
  u8 changeCntOn;         /* True to update the change-counter */
  u8 aborted;             /* True if ROLLBACK in another VM causes an abort */
  u8 expired;             /* True if the VM needs to be recompiled */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
  u8 inVtabMethod;        /* See comments above */

  int nChange;            /* Number of db changes made since last reset */
  i64 startTime;          /* Time when query started - used for profiling */
  int btreeMask;          /* Bitmask of db->aDb[] entries referenced */
  BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
  int nSql;             /* Number of bytes in zSql */
  char *zSql;           /* Text of the SQL statement that generated this */
#ifdef SQLITE_DEBUG

Changes to src/vdbeaux.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
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
...
693
694
695
696
697
698
699




700
701
702
703
704
705
706
**
*************************************************************************
** This file contains code used for creating, destroying, and populating
** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out.
**
** $Id: vdbeaux.c,v 1.392 2008/06/23 13:57:22 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"



................................................................................
    sqlite3_free(pDef);
  }
}

/*
** Delete a P4 value if necessary.
*/
static void freeP4(int p4type, void *p3){
  if( p3 ){
    switch( p4type ){
      case P4_REAL:
      case P4_INT64:
      case P4_MPRINTF:
      case P4_DYNAMIC:
      case P4_KEYINFO:

      case P4_KEYINFO_HANDOFF: {
        sqlite3_free(p3);
        break;
      }
      case P4_VDBEFUNC: {
        VdbeFunc *pVdbeFunc = (VdbeFunc *)p3;
        freeEphemeralFunction(pVdbeFunc->pFunc);
        sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
        sqlite3_free(pVdbeFunc);
        break;
      }
      case P4_FUNCDEF: {
        freeEphemeralFunction((FuncDef*)p3);
        break;
      }
      case P4_MEM: {
        sqlite3ValueFree((sqlite3_value*)p3);
        break;
      }
    }
  }
}


................................................................................
#ifndef SQLITE_OMIT_VIRTUALTABLE
    case P4_VTAB: {
      sqlite3_vtab *pVtab = pOp->p4.pVtab;
      sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
      break;
    }
#endif




    default: {
      zP4 = pOp->p4.z;
      if( zP4==0 ){
        zP4 = zTemp;
        zTemp[0] = 0;
      }
    }







|







 







|
|






>

|



|






|



|







 







>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
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
...
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
**
*************************************************************************
** This file contains code used for creating, destroying, and populating
** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out.
**
** $Id: vdbeaux.c,v 1.393 2008/06/25 00:12:42 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"



................................................................................
    sqlite3_free(pDef);
  }
}

/*
** Delete a P4 value if necessary.
*/
static void freeP4(int p4type, void *p4){
  if( p4 ){
    switch( p4type ){
      case P4_REAL:
      case P4_INT64:
      case P4_MPRINTF:
      case P4_DYNAMIC:
      case P4_KEYINFO:
      case P4_INTARRAY:
      case P4_KEYINFO_HANDOFF: {
        sqlite3_free(p4);
        break;
      }
      case P4_VDBEFUNC: {
        VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
        freeEphemeralFunction(pVdbeFunc->pFunc);
        sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
        sqlite3_free(pVdbeFunc);
        break;
      }
      case P4_FUNCDEF: {
        freeEphemeralFunction((FuncDef*)p4);
        break;
      }
      case P4_MEM: {
        sqlite3ValueFree((sqlite3_value*)p4);
        break;
      }
    }
  }
}


................................................................................
#ifndef SQLITE_OMIT_VIRTUALTABLE
    case P4_VTAB: {
      sqlite3_vtab *pVtab = pOp->p4.pVtab;
      sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
      break;
    }
#endif
    case P4_INTARRAY: {
      sqlite3_snprintf(nTemp, zTemp, "intarray");
      break;
    }
    default: {
      zP4 = pOp->p4.z;
      if( zP4==0 ){
        zP4 = zTemp;
        zTemp[0] = 0;
      }
    }