/ Check-in [173698c9]
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:Continuing work toward registerizing the code generator. (CVS 4703)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 173698c963473ab1b9db88b23a2de82e4097b96d
User & Date: drh 2008-01-10 03:46:36
Context
2008-01-10
23:50
More work toward converting the VM into a register-based machine. (CVS 4704) check-in: 8cbd4651 user: drh tags: trunk
03:46
Continuing work toward registerizing the code generator. (CVS 4703) check-in: 173698c9 user: drh tags: trunk
00:08
Fix mixing quote excapes in an awk script. Ticket #2877. (CVS 4702) check-in: 05fbca91 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
....
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
....
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
....
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
....
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
....
2174
2175
2176
2177
2178
2179
2180


2181



2182
2183
2184
2185
2186
2187
2188
....
2398
2399
2400
2401
2402
2403
2404
2405

2406
2407
2408
2409
2410
2411
2412
2413
2414
2415

2416



2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
....
2884
2885
2886
2887
2888
2889
2890






































**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.340 2008/01/09 23:04:12 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
    if( iCol<0 ){
      int iMem = ++pParse->nMem;
      int iAddr;
      Table *pTab = p->pSrc->a[0].pTab;
      int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
      sqlite3VdbeUsesBtree(v, iDb);

      sqlite3VdbeAddOp1(v, OP_SCopy, iMem);
      iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
      sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);

      sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
      eType = IN_INDEX_ROWID;

      sqlite3VdbeJumpHere(v, iAddr);
    }else{
................................................................................
          int iAddr;
          char *pKey;
  
          pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx);
          iDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
          sqlite3VdbeUsesBtree(v, iDb);

          sqlite3VdbeAddOp1(v, OP_SCopy, iMem);
          iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
          sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
  
          sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
                               pKey,P4_KEYINFO_HANDOFF);
          VdbeComment((v, "%s", pIdx->zName));
          eType = IN_INDEX_INDEX;
          sqlite3VdbeAddOp2(v, OP_SetNumColumns, iTab, pIdx->nColumn);
................................................................................
  **    *  We are inside a trigger
  **
  ** If all of the above are false, then we can run this code just once
  ** save the results, and reuse the same result on subsequent invocations.
  */
  if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
    int mem = ++pParse->nMem;
    sqlite3VdbeAddOp1(v, OP_SCopy, mem);
    testAddr = sqlite3VdbeAddOp0(v, OP_If);
    assert( testAddr>0 || pParse->db->mallocFailed );
    sqlite3VdbeAddOp2(v, OP_Integer, 1, mem);
  }

  switch( pExpr->op ){
    case TK_IN: {
      char affinity;
      KeyInfo keyInfo;
      int addr;        /* Address of OP_OpenEphemeral instruction */
................................................................................
          Expr *pE2 = pItem->pExpr;

          /* If the expression is not constant then we will need to
          ** disable the test that was generated above that makes sure
          ** this code only executes once.  Because for a non-constant
          ** expression we need to rerun this code each time.
          */
          if( testAddr>0 && !sqlite3ExprIsConstant(pE2) ){
            sqlite3VdbeChangeToNoop(v, testAddr-1, 3);
            testAddr = 0;
          }

          /* Evaluate the expression and insert it into the temp table */
          sqlite3ExprCode(pParse, pE2, 0);
          sqlite3VdbeAddOp4(v, OP_MakeRecord, 1, 0, 0, &affinity, 1);
          sqlite3VdbeAddOp1(v, OP_IdxInsert, pExpr->iTable);
................................................................................
      }
      pExpr->iColumn = dest.iParm;
      break;
    }
  }

  if( testAddr ){
    sqlite3VdbeJumpHere(v, testAddr);
  }

  return;
}
#endif /* SQLITE_OMIT_SUBQUERY */

/*
................................................................................
      u8 enc = ENC(db);
      CollSeq *pColl = 0;

      zId = (char*)pExpr->token.z;
      nId = pExpr->token.n;
      pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);
      assert( pDef!=0 );


      nExpr = sqlite3ExprCodeExprList(pParse, pList, 0);



#ifndef SQLITE_OMIT_VIRTUALTABLE
      /* Possibly overload the function if the first argument is
      ** a virtual table column.
      **
      ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the
      ** second argument, not the first, as the argument to test to
      ** see if it is a column in a virtual table.  This is done because
................................................................................
    pExpr->op = TK_REGISTER;
  }
}
#endif

/*
** Generate code that pushes the value of every element of the given
** expression list onto the stack.

**
** Return the number of elements pushed onto the stack.
*/
int sqlite3ExprCodeExprList(
  Parse *pParse,     /* Parsing context */
  ExprList *pList,   /* The expression list to be coded */
  int target         /* Where to write results */
){
  struct ExprList_item *pItem;
  int i, n, incr = 1;

  if( pList==0 ) return 0;



  n = pList->nExpr;
  if( target<0 ){
    target = pParse->nMem+1;
    pParse->nMem += n;
  }else if( target==0 ){
    incr = 0;
  }
  for(pItem=pList->a, i=n; i>0; i--, pItem++){
    sqlite3ExprCode(pParse, pItem->pExpr, target);
    target += incr; 
  }
  return n;
................................................................................
  if( pList ){
    for(pItem=pList->a, i=0; nErr==0 && i<pList->nExpr; i++, pItem++){
      nErr += sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr);
    }
  }
  return nErr;
}













































|







 







|
<







 







|
<







 







|
|

<







 







|
|







 







|







 







>
>
|
>
>
>







 







|
>

|








>
|
>
>
>

<
<
<
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1606
1607
1608
1609
1610
1611
1612
1613

1614
1615
1616
1617
1618
1619
1620
....
1642
1643
1644
1645
1646
1647
1648
1649

1650
1651
1652
1653
1654
1655
1656
....
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707

1708
1709
1710
1711
1712
1713
1714
....
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
....
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
....
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
....
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424



2425
2426
2427
2428
2429
2430
2431
2432
....
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.341 2008/01/10 03:46:36 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
    if( iCol<0 ){
      int iMem = ++pParse->nMem;
      int iAddr;
      Table *pTab = p->pSrc->a[0].pTab;
      int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
      sqlite3VdbeUsesBtree(v, iDb);

      iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem);

      sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);

      sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
      eType = IN_INDEX_ROWID;

      sqlite3VdbeJumpHere(v, iAddr);
    }else{
................................................................................
          int iAddr;
          char *pKey;
  
          pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx);
          iDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
          sqlite3VdbeUsesBtree(v, iDb);

          iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem);

          sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
  
          sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
                               pKey,P4_KEYINFO_HANDOFF);
          VdbeComment((v, "%s", pIdx->zName));
          eType = IN_INDEX_INDEX;
          sqlite3VdbeAddOp2(v, OP_SetNumColumns, iTab, pIdx->nColumn);
................................................................................
  **    *  We are inside a trigger
  **
  ** If all of the above are false, then we can run this code just once
  ** save the results, and reuse the same result on subsequent invocations.
  */
  if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
    int mem = ++pParse->nMem;
    sqlite3VdbeAddOp1(v, OP_If, mem);
    testAddr = sqlite3VdbeAddOp2(v, OP_Integer, 1, mem);
    assert( testAddr>0 || pParse->db->mallocFailed );

  }

  switch( pExpr->op ){
    case TK_IN: {
      char affinity;
      KeyInfo keyInfo;
      int addr;        /* Address of OP_OpenEphemeral instruction */
................................................................................
          Expr *pE2 = pItem->pExpr;

          /* If the expression is not constant then we will need to
          ** disable the test that was generated above that makes sure
          ** this code only executes once.  Because for a non-constant
          ** expression we need to rerun this code each time.
          */
          if( testAddr && !sqlite3ExprIsConstant(pE2) ){
            sqlite3VdbeChangeToNoop(v, testAddr-1, 2);
            testAddr = 0;
          }

          /* Evaluate the expression and insert it into the temp table */
          sqlite3ExprCode(pParse, pE2, 0);
          sqlite3VdbeAddOp4(v, OP_MakeRecord, 1, 0, 0, &affinity, 1);
          sqlite3VdbeAddOp1(v, OP_IdxInsert, pExpr->iTable);
................................................................................
      }
      pExpr->iColumn = dest.iParm;
      break;
    }
  }

  if( testAddr ){
    sqlite3VdbeJumpHere(v, testAddr-1);
  }

  return;
}
#endif /* SQLITE_OMIT_SUBQUERY */

/*
................................................................................
      u8 enc = ENC(db);
      CollSeq *pColl = 0;

      zId = (char*)pExpr->token.z;
      nId = pExpr->token.n;
      pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);
      assert( pDef!=0 );
      if( pList ){
        nExpr = pList->nExpr;
        sqlite3ExprCodeExprList(pParse, pList, 0);
      }else{
        nExpr = 0;
      }
#ifndef SQLITE_OMIT_VIRTUALTABLE
      /* Possibly overload the function if the first argument is
      ** a virtual table column.
      **
      ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the
      ** second argument, not the first, as the argument to test to
      ** see if it is a column in a virtual table.  This is done because
................................................................................
    pExpr->op = TK_REGISTER;
  }
}
#endif

/*
** Generate code that pushes the value of every element of the given
** expression list onto the stack if target==0 or into a sequence of
** registers beginning at target.
**
** Return the number of elements evaluated.
*/
int sqlite3ExprCodeExprList(
  Parse *pParse,     /* Parsing context */
  ExprList *pList,   /* The expression list to be coded */
  int target         /* Where to write results */
){
  struct ExprList_item *pItem;
  int i, n, incr = 1;
  assert( pList!=0 || pParse->db->mallocFailed );
  if( pList==0 ){
    return 0;
  }
  assert( target>=0 );
  n = pList->nExpr;



  if( target==0 ){
    incr = 0;
  }
  for(pItem=pList->a, i=n; i>0; i--, pItem++){
    sqlite3ExprCode(pParse, pItem->pExpr, target);
    target += incr; 
  }
  return n;
................................................................................
  if( pList ){
    for(pItem=pList->a, i=0; nErr==0 && i<pList->nExpr; i++, pItem++){
      nErr += sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr);
    }
  }
  return nErr;
}

/*
** Allocate or deallocate temporary use registers during code generation.
*/
int sqlite3GetTempReg(Parse *pParse){
  if( pParse->nTempReg ){
    return pParse->aTempReg[--pParse->nTempReg];
  }else{
    return ++pParse->nMem;
  }
}
void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
  if( pParse->nTempReg<sizeof(pParse->aTempReg)/sizeof(pParse->aTempReg[0]) ){
    pParse->aTempReg[pParse->nTempReg++] = iReg;
  }
}

/*
** Allocate or deallocate a block of nReg consecutive registers
*/
int sqlite3GetTempRange(Parse *pParse, int nReg){
  int i;
  if( nReg<=pParse->nRangeReg ){
    i  = pParse->iRangeReg;
    pParse->iRangeReg += nReg;
    pParse->nRangeReg -= nReg;
  }else{
    i = pParse->nMem+1;
    pParse->nMem += nReg;
  }
  return i;
}
void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
  if( nReg>pParse->nRangeReg ){
    pParse->nRangeReg = nReg;
    pParse->iRangeReg = iReg;
  }
}

Changes to src/insert.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
....
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
**    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 INSERT statements in SQLite.
**
** $Id: insert.c,v 1.220 2008/01/09 23:04:12 drh Exp $
*/
#include "sqliteInt.h"

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    
    if( isUpdate ){
      sqlite3VdbeAddOp1(v, OP_SCopy, regRowid-1);
      sqlite3VdbeAddOp1(v, OP_SCopy, regRowid);
      j2 = sqlite3VdbeAddOp2(v, OP_Eq, 0, 0);
    }
    j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
    switch( onError ){
      default: {
        onError = OE_Abort;
        /* Fall thru into the next case */
      }
................................................................................
        sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
                         "PRIMARY KEY must be unique", P4_STATIC);
        break;
      }
      case OE_Replace: {
        sqlite3GenerateRowIndexDelete(v, pTab, baseCur, 0);
        if( isUpdate ){
          sqlite3VdbeAddOp1(v, OP_SCopy, regRowid-hasTwoRowids);
          sqlite3VdbeAddOp2(v, OP_MoveGe, baseCur, 0);
        }
        seenReplace = 1;
        break;
      }
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
        break;
      }
    }
    sqlite3VdbeJumpHere(v, j3);
    if( isUpdate ){
      sqlite3VdbeJumpHere(v, j2);
      sqlite3VdbeAddOp1(v, OP_SCopy, regRowid-1);
      sqlite3VdbeAddOp2(v, OP_MoveGe, baseCur, 0);
    }
  }

  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Add the new records to the indices as we go.
  */







|







 







<
<
|







 







<
|













<
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1103
1104
1105
1106
1107
1108
1109


1110
1111
1112
1113
1114
1115
1116
1117
....
1121
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
**    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 INSERT statements in SQLite.
**
** $Id: insert.c,v 1.221 2008/01/10 03:46:36 drh Exp $
*/
#include "sqliteInt.h"

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    
    if( isUpdate ){


      j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, regRowid-1);
    }
    j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
    switch( onError ){
      default: {
        onError = OE_Abort;
        /* Fall thru into the next case */
      }
................................................................................
        sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
                         "PRIMARY KEY must be unique", P4_STATIC);
        break;
      }
      case OE_Replace: {
        sqlite3GenerateRowIndexDelete(v, pTab, baseCur, 0);
        if( isUpdate ){

          sqlite3VdbeAddOp3(v, OP_MoveGe, baseCur, 0, regRowid-hasTwoRowids);
        }
        seenReplace = 1;
        break;
      }
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
        break;
      }
    }
    sqlite3VdbeJumpHere(v, j3);
    if( isUpdate ){
      sqlite3VdbeJumpHere(v, j2);

      sqlite3VdbeAddOp3(v, OP_MoveGe, baseCur, 0, regRowid-1);
    }
  }

  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Add the new records to the indices as we go.
  */

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
393
394
395
396
397
398
399



400
401
402
403


404


405
406
407
408
409
410
411
....
2998
2999
3000
3001
3002
3003
3004

3005
3006
3007
3008
3009
3010
3011
3012
3013
....
3025
3026
3027
3028
3029
3030
3031

3032
3033
3034
3035
3036
3037
3038
....
3541
3542
3543
3544
3545
3546
3547





3548










3549
3550
3551
3552
3553
3554
3555

3556
3557
3558



3559


3560
3561
3562
3563
3564
3565
3566
**    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.395 2008/01/09 23:04:12 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
*/
static void pushOntoSorter(
  Parse *pParse,         /* Parser context */
  ExprList *pOrderBy,    /* The ORDER BY clause */
  Select *pSelect        /* The whole SELECT statement */
){
  Vdbe *v = pParse->pVdbe;



  sqlite3ExprCodeExprList(pParse, pOrderBy, 0);
  sqlite3VdbeAddOp1(v, OP_Sequence, pOrderBy->iECursor);
  sqlite3VdbeAddOp1(v, OP_Pull, pOrderBy->nExpr + 1);
  sqlite3VdbeAddOp1(v, OP_MakeRecord, pOrderBy->nExpr + 2);


  sqlite3VdbeAddOp1(v, OP_IdxInsert, pOrderBy->iECursor);


  if( pSelect->iLimit>=0 ){
    int addr1, addr2;
    addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, pSelect->iLimit+1);
    sqlite3VdbeAddOp2(v, OP_AddImm, pSelect->iLimit+1, -1);
    addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
    sqlite3VdbeJumpHere(v, addr1);
    sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor);
................................................................................
  for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
    int nArg;
    int addrNext = 0;
    int regAgg;
    ExprList *pList = pF->pExpr->pList;
    if( pList ){
      nArg = pList->nExpr;

      sqlite3ExprCodeExprList(pParse, pList, 0);
      regAgg = sqlite3StackToReg(pParse, nArg);
    }else{
      nArg = 0;
      regAgg = 0;
    }
    if( pF->iDistinct>=0 ){
      addrNext = sqlite3VdbeMakeLabel(v);
      assert( nArg==1 );
................................................................................
        pColl = pParse->db->pDfltColl;
      }
      sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
    }
    sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem,
                      (void*)pF->pFunc, P4_FUNCDEF);
    sqlite3VdbeChangeP5(v, nArg);

    if( addrNext ){
      sqlite3VdbeResolveLabel(v, addrNext);
    }
  }
  for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
    sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
  }
................................................................................
        groupBySort = 0;
      }else{
        /* Rows are coming out in undetermined order.  We have to push
        ** each row into a sorting index, terminate the first loop,
        ** then loop over the sorting index in order to get the output
        ** in sorted order
        */





        groupBySort = 1;










        sqlite3ExprCodeExprList(pParse, pGroupBy, 0);
        sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx, 0);
        j = pGroupBy->nExpr+1;
        for(i=0; i<sAggInfo.nColumn; i++){
          struct AggInfo_col *pCol = &sAggInfo.aCol[i];
          if( pCol->iSorterColumn<j ) continue;
          sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn,pCol->iTable,0);

          j++;
        }
        sqlite3VdbeAddOp2(v, OP_MakeRecord, j, 0);



        sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, 0);


        sqlite3WhereEnd(pWInfo);
        sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd);
        VdbeComment((v, "GROUP BY sort"));
        sAggInfo.useSortingIdx = 1;
      }

      /* Evaluate the current GROUP BY terms and store in b0, b1, b2...







|







 







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







 







>
|
<







 







>







 







>
>
>
>
>

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


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







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
393
394
395
396
397
398
399
400
401
402
403
404


405
406
407
408
409
410
411
412
413
414
415
416
....
3003
3004
3005
3006
3007
3008
3009
3010
3011

3012
3013
3014
3015
3016
3017
3018
....
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
....
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579

3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
**    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.396 2008/01/10 03:46:36 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
*/
static void pushOntoSorter(
  Parse *pParse,         /* Parser context */
  ExprList *pOrderBy,    /* The ORDER BY clause */
  Select *pSelect        /* The whole SELECT statement */
){
  Vdbe *v = pParse->pVdbe;
  int nExpr = pOrderBy->nExpr;
  int regBase = sqlite3GetTempRange(pParse, nExpr+2);
  int regRecord = sqlite3GetTempReg(pParse);
  sqlite3ExprCodeExprList(pParse, pOrderBy, regBase);
  sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);


  sqlite3VdbeAddOp2(v, OP_Move, 0, regBase+nExpr+1);
  sqlite3VdbeAddOp3(v, OP_RegMakeRec, regBase, nExpr + 2, regRecord);
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord);
  sqlite3ReleaseTempReg(pParse, regRecord);
  sqlite3ReleaseTempRange(pParse, regBase, nExpr+2);
  if( pSelect->iLimit>=0 ){
    int addr1, addr2;
    addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, pSelect->iLimit+1);
    sqlite3VdbeAddOp2(v, OP_AddImm, pSelect->iLimit+1, -1);
    addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
    sqlite3VdbeJumpHere(v, addr1);
    sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor);
................................................................................
  for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
    int nArg;
    int addrNext = 0;
    int regAgg;
    ExprList *pList = pF->pExpr->pList;
    if( pList ){
      nArg = pList->nExpr;
      regAgg = sqlite3GetTempRange(pParse, nArg);
      sqlite3ExprCodeExprList(pParse, pList, regAgg);

    }else{
      nArg = 0;
      regAgg = 0;
    }
    if( pF->iDistinct>=0 ){
      addrNext = sqlite3VdbeMakeLabel(v);
      assert( nArg==1 );
................................................................................
        pColl = pParse->db->pDfltColl;
      }
      sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
    }
    sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem,
                      (void*)pF->pFunc, P4_FUNCDEF);
    sqlite3VdbeChangeP5(v, nArg);
    sqlite3ReleaseTempRange(pParse, regAgg, nArg);
    if( addrNext ){
      sqlite3VdbeResolveLabel(v, addrNext);
    }
  }
  for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
    sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
  }
................................................................................
        groupBySort = 0;
      }else{
        /* Rows are coming out in undetermined order.  We have to push
        ** each row into a sorting index, terminate the first loop,
        ** then loop over the sorting index in order to get the output
        ** in sorted order
        */
        int regBase;
        int regRecord;
        int nCol;
        int nGroupBy;

        groupBySort = 1;
        nGroupBy = pGroupBy->nExpr;
        nCol = nGroupBy + 1;
        j = nGroupBy+1;
        for(i=0; i<sAggInfo.nColumn; i++){
          if( sAggInfo.aCol[i].iSorterColumn>=j ){
            nCol++;
            j++;
          }
        }
        regBase = sqlite3GetTempRange(pParse, nCol);
        sqlite3ExprCodeExprList(pParse, pGroupBy, regBase);
        sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy);
        j = nGroupBy+1;
        for(i=0; i<sAggInfo.nColumn; i++){
          struct AggInfo_col *pCol = &sAggInfo.aCol[i];
          if( pCol->iSorterColumn>=j ){
            sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn, pCol->iTable,
                                     j + regBase);
            j++;
          }

        }
        regRecord = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp3(v, OP_RegMakeRec, regBase, nCol, regRecord);
        sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, regRecord);
        sqlite3ReleaseTempReg(pParse, regRecord);
        sqlite3ReleaseTempRange(pParse, regBase, nCol);
        sqlite3WhereEnd(pWInfo);
        sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd);
        VdbeComment((v, "GROUP BY sort"));
        sAggInfo.useSortingIdx = 1;
      }

      /* Evaluate the current GROUP BY terms and store in b0, b1, b2...

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1395
1396
1397
1398
1399
1400
1401




1402
1403
1404
1405
1406
1407
1408
....
1688
1689
1690
1691
1692
1693
1694




1695
1696
1697
1698
1699
1700
1701
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.645 2008/01/09 23:04:12 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** The macro unlikely() is a hint that surrounds a boolean
** expression that is usually false.  Macro likely() surrounds
................................................................................
  char *zErrMsg;       /* An error message */
  Vdbe *pVdbe;         /* An engine for executing database bytecode */
  u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
  u8 nameClash;        /* A permanent table name clashes with temp table name */
  u8 checkSchema;      /* Causes schema cookie check after an error */
  u8 nested;           /* Number of nested calls to the parser/code generator */
  u8 parseError;       /* True after a parsing error.  Ticket #1794 */




  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  int ckBase;          /* Base register of data during check constraints */
  u32 writeMask;       /* Start a write transaction on these databases */
  u32 cookieMask;      /* Bitmask of schema verified databases */
................................................................................
void sqlite3ErrorMsg(Parse*, const char*, ...);
void sqlite3ErrorClear(Parse*);
void sqlite3Dequote(char*);
void sqlite3DequoteExpr(sqlite3*, Expr*);
int sqlite3KeywordCode(const unsigned char*, int);
int sqlite3RunParser(Parse*, const char*, char **);
void sqlite3FinishCoding(Parse*);




Expr *sqlite3Expr(sqlite3*, int, Expr*, Expr*, const Token*);
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
Expr *sqlite3RegisterExpr(Parse*,Token*);
Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
void sqlite3ExprSpan(Expr*,Token*,Token*);
Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*);







|







 







>
>
>
>







 







>
>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
....
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.646 2008/01/10 03:46:36 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** The macro unlikely() is a hint that surrounds a boolean
** expression that is usually false.  Macro likely() surrounds
................................................................................
  char *zErrMsg;       /* An error message */
  Vdbe *pVdbe;         /* An engine for executing database bytecode */
  u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
  u8 nameClash;        /* A permanent table name clashes with temp table name */
  u8 checkSchema;      /* Causes schema cookie check after an error */
  u8 nested;           /* Number of nested calls to the parser/code generator */
  u8 parseError;       /* True after a parsing error.  Ticket #1794 */
  u8 nTempReg;         /* Number of temporary registers in aTempReg[] */
  int aTempReg[8];     /* Holding area for temporary registers */
  int nRangeReg;       /* Size of the temporary register block */
  int iRangeReg;       /* First register in temporary register block */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  int ckBase;          /* Base register of data during check constraints */
  u32 writeMask;       /* Start a write transaction on these databases */
  u32 cookieMask;      /* Bitmask of schema verified databases */
................................................................................
void sqlite3ErrorMsg(Parse*, const char*, ...);
void sqlite3ErrorClear(Parse*);
void sqlite3Dequote(char*);
void sqlite3DequoteExpr(sqlite3*, Expr*);
int sqlite3KeywordCode(const unsigned char*, int);
int sqlite3RunParser(Parse*, const char*, char **);
void sqlite3FinishCoding(Parse*);
int sqlite3GetTempReg(Parse*);
void sqlite3ReleaseTempReg(Parse*,int);
int sqlite3GetTempRange(Parse*,int);
void sqlite3ReleaseTempRange(Parse*,int,int);
Expr *sqlite3Expr(sqlite3*, int, Expr*, Expr*, const Token*);
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
Expr *sqlite3RegisterExpr(Parse*,Token*);
Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
void sqlite3ExprSpan(Expr*,Token*,Token*);
Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*);