/ Check-in [e7188fad]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Further enhancements to generated VDBE code for ORDER BY.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | orderby-planning
Files: files | file ages | folders
SHA1: e7188fad87ec82d36a39b80ccaf8006bf45a9bcd
User & Date: drh 2014-03-24 01:43:50
Original Comment: Further enhancements to geneverated VDBE code for ORDER BY.
Context
2014-03-24
02:20
Remove a pointless OP_Once operation in ORDER BY clauses with LIMIT. check-in: e6c59d23 user: drh tags: orderby-planning
01:43
Further enhancements to generated VDBE code for ORDER BY. check-in: e7188fad user: drh tags: orderby-planning
2014-03-23
18:47
merge fixes from trunk check-in: faf7f9ca user: drh tags: orderby-planning
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/select.c.

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
....
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140



1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
....
1176
1177
1178
1179
1180
1181
1182

1183
1184
1185
1186
1187
1188
1189
  int nExpr = pSort->pOrderBy->nExpr;              /* No. of ORDER BY terms */
  int nBase = nExpr + 1 + nData;                   /* Fields in sorter record */
  int regBase = sqlite3GetTempRange(pParse, nBase); /* Regs for sorter record */
  int regRecord = sqlite3GetTempReg(pParse);       /* Assemblied sorter record */
  int nOBSat = pSort->nOBSat;                      /* No. ORDER BY terms to skip */
  int op;                               /* Opcode to add sorter record to sorter */

  sqlite3ExprCacheClear(pParse);
  sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, 0);
  sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
  sqlite3VdbeAddOp3(v, OP_Move, regData, regBase+nExpr+1, nData);
  sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
  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 */
................................................................................
){
  Vdbe *v = pParse->pVdbe;                     /* The prepared statement */
  int addrBreak = sqlite3VdbeMakeLabel(v);     /* Jump here to exit loop */
  int addrContinue = sqlite3VdbeMakeLabel(v);  /* Jump here for next cycle */
  int addr;
  int addrOnce = 0;
  int iTab;
  int pseudoTab = 0;
  ExprList *pOrderBy = pSort->pOrderBy;
  int eDest = pDest->eDest;
  int iParm = pDest->iSDParm;
  int regRow;
  int regRowid;
  int nKey;
  int iSortTab;                   /* Sorter cursor to read from */
  int nSortData;                  /* Trailing values to read from sorter */
  u8 p5;                          /* p5 parameter for 1st OP_Column */
  int i;




  if( pSort->labelBkOut ){
    sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBreak);
    sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
    addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
  }
  iTab = pSort->iECursor;
  regRow = sqlite3GetTempReg(pParse);
  if( eDest==SRT_Output || eDest==SRT_Coroutine ){
    pseudoTab = pParse->nTab++;
    sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn);
    regRowid = 0;
    regRow = pDest->iSdst;
    nSortData = nColumn;
  }else{
    regRowid = sqlite3GetTempReg(pParse);
    regRow = sqlite3GetTempReg(pParse);
    nSortData = 1;
................................................................................
    sqlite3VdbeAddOp3(v, OP_Column, iTab, nKey+1, regRow);
    iSortTab = iTab;
    p5 = 0;
  }
  for(i=0; i<nSortData; i++){
    sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+1+i, regRow+i);
    if( i==0 ) sqlite3VdbeChangeP5(v, p5);

  }
  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {
      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
      sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);







<
|







 







<










>
>
>










<
<







 







>







469
470
471
472
473
474
475

476
477
478
479
480
481
482
483
....
1122
1123
1124
1125
1126
1127
1128

1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151


1152
1153
1154
1155
1156
1157
1158
....
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
  int nExpr = pSort->pOrderBy->nExpr;              /* No. of ORDER BY terms */
  int nBase = nExpr + 1 + nData;                   /* Fields in sorter record */
  int regBase = sqlite3GetTempRange(pParse, nBase); /* Regs for sorter record */
  int regRecord = sqlite3GetTempReg(pParse);       /* Assemblied sorter record */
  int nOBSat = pSort->nOBSat;                      /* No. ORDER BY terms to skip */
  int op;                               /* Opcode to add sorter record to sorter */


  sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, SQLITE_ECEL_DUP);
  sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
  sqlite3VdbeAddOp3(v, OP_Move, regData, regBase+nExpr+1, nData);
  sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
  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 */
................................................................................
){
  Vdbe *v = pParse->pVdbe;                     /* The prepared statement */
  int addrBreak = sqlite3VdbeMakeLabel(v);     /* Jump here to exit loop */
  int addrContinue = sqlite3VdbeMakeLabel(v);  /* Jump here for next cycle */
  int addr;
  int addrOnce = 0;
  int iTab;

  ExprList *pOrderBy = pSort->pOrderBy;
  int eDest = pDest->eDest;
  int iParm = pDest->iSDParm;
  int regRow;
  int regRowid;
  int nKey;
  int iSortTab;                   /* Sorter cursor to read from */
  int nSortData;                  /* Trailing values to read from sorter */
  u8 p5;                          /* p5 parameter for 1st OP_Column */
  int i;
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  struct ExprList_item *aOutEx = p->pEList->a;
#endif

  if( pSort->labelBkOut ){
    sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBreak);
    sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
    addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
  }
  iTab = pSort->iECursor;
  regRow = sqlite3GetTempReg(pParse);
  if( eDest==SRT_Output || eDest==SRT_Coroutine ){


    regRowid = 0;
    regRow = pDest->iSdst;
    nSortData = nColumn;
  }else{
    regRowid = sqlite3GetTempReg(pParse);
    regRow = sqlite3GetTempReg(pParse);
    nSortData = 1;
................................................................................
    sqlite3VdbeAddOp3(v, OP_Column, iTab, nKey+1, regRow);
    iSortTab = iTab;
    p5 = 0;
  }
  for(i=0; i<nSortData; i++){
    sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+1+i, regRow+i);
    if( i==0 ) sqlite3VdbeChangeP5(v, p5);
    VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
  }
  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {
      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
      sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);