SQLite4
Check-in [eddeadfc27]
Not logged in

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

Overview
SHA1 Hash:eddeadfc272239803fc87d0fd5d1dcc02b8a070c
Date: 2013-07-30 12:14:42
User: drh
Comment:Simplification of the ORDER BY code generator logic, requiring fewer calls to OP_Column.
Tags And Properties
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/select.c

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
...
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
  SelectDest *pDest               /* Write the sorted results here */
){
  int addrBreak = sqlite4VdbeMakeLabel(v);     /* Jump here to exit loop */
  int addrContinue = sqlite4VdbeMakeLabel(v);  /* Jump here for next cycle */
  int addr;
  int iTab;                       /* Sorter object cursor */
  ExprList *pOrderBy = p->pOrderBy;

  int eDest = pDest->eDest;
  int iParm = pDest->iParm;


  int regRow;
  int regRowid = 0;

  iTab = pOrderBy->iECursor;
  regRow = sqlite4GetTempReg(pParse);
  if( eDest!=SRT_Output && eDest!=SRT_Coroutine ){
    regRowid = sqlite4GetTempReg(pParse);
  }

  if( p->selFlags & SF_UseSorter ){
    addr = 1 + sqlite4VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
    codeOffset(v, p, addrContinue);
    sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, regRow);
    sqlite4VdbeChangeP5(v, OPFLAG_CLEARCACHE);
  }else{
    addr = 1 + sqlite4VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
    codeOffset(v, p, addrContinue);
    sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, regRow);
  }
  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {


      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
      sqlite4VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
      sqlite4VdbeAddOp2(v, OP_RowData, iTab, regRow);
      sqlite4VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
      sqlite4VdbeChangeP5(v, OPFLAG_APPEND);


      break;
    }
#ifndef SQLITE4_OMIT_SUBQUERY
    case SRT_Set: {
      assert( nColumn==1 );
      int regKey = sqlite4GetTempReg(pParse);



      sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, regKey);
      sqlite4VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1);
      sqlite4ExprCacheAffinityChange(pParse, regRow, 1);
      sqlite4VdbeAddOp3(v, OP_Insert, iParm, regRowid, regKey);
      sqlite4ReleaseTempReg(pParse, regKey);


      break;
    }
    case SRT_Mem: {
      assert( nColumn==1 );
      sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, iParm);
      /* The LIMIT clause will terminate the loop for us */
      break;
................................................................................
        sqlite4ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
      }else{
        sqlite4VdbeAddOp1(v, OP_Yield, pDest->iParm);
      }
      break;
    }
  }
  sqlite4ReleaseTempReg(pParse, regRow);
  sqlite4ReleaseTempReg(pParse, regRowid);

  /* The bottom of the loop
  */
  sqlite4VdbeResolveLabel(v, addrContinue);
  if( p->selFlags & SF_UseSorter ){
    sqlite4VdbeAddOp2(v, OP_SorterNext, iTab, addr);
  }else{







<


>

<
<
<

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



>
>






>
>




|

>
>
>

|
<
|

>
>







 







<
<







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
...
982
983
984
985
986
987
988


989
990
991
992
993
994
995
  SelectDest *pDest               /* Write the sorted results here */
){
  int addrBreak = sqlite4VdbeMakeLabel(v);     /* Jump here to exit loop */
  int addrContinue = sqlite4VdbeMakeLabel(v);  /* Jump here for next cycle */
  int addr;
  int iTab;                       /* Sorter object cursor */
  ExprList *pOrderBy = p->pOrderBy;

  int eDest = pDest->eDest;
  int iParm = pDest->iParm;
  int op;                         /* Opcode use to sort results */




  iTab = pOrderBy->iECursor;





  op = (p->selFlags & SF_UseSorter) ? OP_SorterSort : OP_Sort;





  addr = 1 + sqlite4VdbeAddOp2(v, op, iTab, addrBreak);
  codeOffset(v, p, addrContinue);


  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {
      int regRowid = sqlite4GetTempReg(pParse);
      int regRow = sqlite4GetTempReg(pParse);
      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
      sqlite4VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
      sqlite4VdbeAddOp2(v, OP_RowData, iTab, regRow);
      sqlite4VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
      sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
      sqlite4ReleaseTempReg(pParse, regRow);
      sqlite4ReleaseTempReg(pParse, regRowid);
      break;
    }
#ifndef SQLITE4_OMIT_SUBQUERY
    case SRT_Set: {
      int regRes = sqlite4GetTempReg(pParse);
      int regKey = sqlite4GetTempReg(pParse);
      int regValue = sqlite4GetTempReg(pParse);
      assert( nColumn==1 );
      sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, regRes);
      sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, regKey);
      sqlite4VdbeAddOp4(v, OP_MakeRecord, regRes, 1, regValue, &p->affinity, 1);

      sqlite4VdbeAddOp3(v, OP_Insert, iParm, regValue, regKey);
      sqlite4ReleaseTempReg(pParse, regKey);
      sqlite4ReleaseTempReg(pParse, regRes);
      sqlite4ReleaseTempReg(pParse, regValue);
      break;
    }
    case SRT_Mem: {
      assert( nColumn==1 );
      sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, iParm);
      /* The LIMIT clause will terminate the loop for us */
      break;
................................................................................
        sqlite4ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
      }else{
        sqlite4VdbeAddOp1(v, OP_Yield, pDest->iParm);
      }
      break;
    }
  }



  /* The bottom of the loop
  */
  sqlite4VdbeResolveLabel(v, addrContinue);
  if( p->selFlags & SF_UseSorter ){
    sqlite4VdbeAddOp2(v, OP_SorterNext, iTab, addr);
  }else{