/ Check-in [5f04b016]
Login

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

Overview
Comment:Omit all window-function related code when building with SQLITE_OMIT_WINDOWFUNC.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | exp-window-functions
Files: files | file ages | folders
SHA3-256: 5f04b016467342b5a796bf702ed25b621eb86f2961c1e703d276c93f2cb6aa89
User & Date: dan 2018-06-22 20:51:35
Context
2018-06-23
07:59
Fix a problem with using a window-function SELECT as a FROM clause sub-query in some circumstances. check-in: 11d73339 user: dan tags: exp-window-functions
2018-06-22
20:51
Omit all window-function related code when building with SQLITE_OMIT_WINDOWFUNC. check-in: 5f04b016 user: dan tags: exp-window-functions
17:57
Merge latest trunk changes. check-in: ebe65b23 user: dan tags: exp-window-functions
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/btree.c.

5186
5187
5188
5189
5190
5191
5192

5193
5194
5195
5196
5197
5198

5199
5200
5201
5202
5203
5204
5205
}

/*
** This function is a no-op if cursor pCur does not point to a valid row.
** Otherwise, if pCur is valid, configure it so that the next call to
** sqlite3BtreeNext() is a no-op.
*/

void sqlite3BtreeSkipNext(BtCursor *pCur){
  if( pCur->eState==CURSOR_VALID ){
    pCur->eState = CURSOR_SKIPNEXT;
    pCur->skipNext = 1;
  }
}


/* Move the cursor to the last entry in the table.  Return SQLITE_OK
** on success.  Set *pRes to 0 if the cursor actually points to something
** or set *pRes to 1 if the table is empty.
*/
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
  int rc;







>






>







5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
}

/*
** This function is a no-op if cursor pCur does not point to a valid row.
** Otherwise, if pCur is valid, configure it so that the next call to
** sqlite3BtreeNext() is a no-op.
*/
#ifndef SQLITE_OMIT_WINDOWFUNC
void sqlite3BtreeSkipNext(BtCursor *pCur){
  if( pCur->eState==CURSOR_VALID ){
    pCur->eState = CURSOR_SKIPNEXT;
    pCur->skipNext = 1;
  }
}
#endif /* SQLITE_OMIT_WINDOWFUNC */

/* Move the cursor to the last entry in the table.  Return SQLITE_OK
** on success.  Set *pRes to 0 if the cursor actually points to something
** or set *pRes to 1 if the table is empty.
*/
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
  int rc;

Changes to src/btree.h.

297
298
299
300
301
302
303

304

305
306
307
308
309
310
311
  int nData;              /* Size of pData.  0 if none. */
  int nZero;              /* Extra zero data appended after pData,nData */
};

int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
                       int flags, int seekResult);
int sqlite3BtreeFirst(BtCursor*, int *pRes);

void sqlite3BtreeSkipNext(BtCursor*);

int sqlite3BtreeLast(BtCursor*, int *pRes);
int sqlite3BtreeNext(BtCursor*, int flags);
int sqlite3BtreeEof(BtCursor*);
int sqlite3BtreePrevious(BtCursor*, int flags);
i64 sqlite3BtreeIntegerKey(BtCursor*);
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
i64 sqlite3BtreeOffset(BtCursor*);







>

>







297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
  int nData;              /* Size of pData.  0 if none. */
  int nZero;              /* Extra zero data appended after pData,nData */
};

int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
                       int flags, int seekResult);
int sqlite3BtreeFirst(BtCursor*, int *pRes);
#ifndef SQLITE_OMIT_WINDOWFUNC
void sqlite3BtreeSkipNext(BtCursor*);
#endif
int sqlite3BtreeLast(BtCursor*, int *pRes);
int sqlite3BtreeNext(BtCursor*, int flags);
int sqlite3BtreeEof(BtCursor*);
int sqlite3BtreePrevious(BtCursor*, int flags);
i64 sqlite3BtreeIntegerKey(BtCursor*);
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
i64 sqlite3BtreeOffset(BtCursor*);

Changes to src/expr.c.

768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
...
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
....
1124
1125
1126
1127
1128
1129
1130
1131




1132
1133
1134
1135
1136
1137
1138
....
1264
1265
1266
1267
1268
1269
1270

1271
1272
1273
1274
1275

1276
1277
1278
1279
1280
1281
1282
....
1475
1476
1477
1478
1479
1480
1481

1482
1483

1484
1485
1486
1487
1488
1489
1490
....
3796
3797
3798
3799
3800
3801
3802

3803
3804
3805

3806
3807
3808
3809
3810
3811
3812
    }
  }
  pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra);
  if( pNew ){
    memset(pNew, 0, sizeof(Expr));
    pNew->op = (u8)op;
    pNew->iAgg = -1;
    pNew->pWin = 0;
    if( pToken ){
      if( nExtra==0 ){
        pNew->flags |= EP_IntValue|EP_Leaf;
        pNew->u.iValue = iValue;
      }else{
        pNew->u.zToken = (char*)&pNew[1];
        assert( pToken->z!=0 || pToken->n==0 );
................................................................................
    p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
  }else{
    p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
    if( p ){
      memset(p, 0, sizeof(Expr));
      p->op = op & TKFLG_MASK;
      p->iAgg = -1;
      p->pWin = 0;
    }
    sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
  }
  if( p ) {
    sqlite3ExprCheckHeight(pParse, p->nHeight);
  }
  return p;
................................................................................
** to enforce this constraint.
*/
static int dupedExprStructSize(Expr *p, int flags){
  int nSize;
  assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
  assert( EXPR_FULLSIZE<=0xfff );
  assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
  if( 0==flags || p->op==TK_SELECT_COLUMN || p->pWin ){




    nSize = EXPR_FULLSIZE;
  }else{
    assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
    assert( !ExprHasProperty(p, EP_FromJoin) ); 
    assert( !ExprHasProperty(p, EP_MemToken) );
    assert( !ExprHasProperty(p, EP_NoReduce) );
    if( p->pLeft || p->x.pList ){
................................................................................
        pNew->pRight = p->pRight ?
                       exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
      }
      if( pzBuffer ){
        *pzBuffer = zAlloc;
      }
    }else{

      if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
        pNew->pWin = 0;
      }else{
        pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin);
      }

      if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
        if( pNew->op==TK_SELECT_COLUMN ){
          pNew->pLeft = p->pLeft;
          assert( p->iColumn==0 || p->pRight==0 );
          assert( p->pRight==0  || p->pRight==p->pLeft );
        }else{
          pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
................................................................................
    pNew->iLimit = 0;
    pNew->iOffset = 0;
    pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
    pNew->addrOpenEphm[0] = -1;
    pNew->addrOpenEphm[1] = -1;
    pNew->nSelectRow = p->nSelectRow;
    pNew->pWith = withDup(db, p->pWith);

    pNew->pWin = 0;
    pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);

    sqlite3SelectSetName(pNew, p->zSelName);
    *pp = pNew;
    pp = &pNew->pPrior;
    pNext = pNew;
  }

  return pRet;
................................................................................
      const char *zId;       /* The function name */
      u32 constMask = 0;     /* Mask of function arguments that are constant */
      int i;                 /* Loop counter */
      sqlite3 *db = pParse->db;  /* The database connection */
      u8 enc = ENC(db);      /* The text encoding used by this database */
      CollSeq *pColl = 0;    /* A collating sequence */


      if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){
        return pExpr->pWin->regResult;
      }


      if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
        /* SQL functions can be expensive. So try to move constant functions
        ** out of the inner loop, even if that means an extra OP_Copy. */
        return sqlite3ExprCodeAtInit(pParse, pExpr, -1);
      }
      assert( !ExprHasProperty(pExpr, EP_xIsSelect) );







<







 







<







 







|
>
>
>
>







 







>





>







 







>


>







 







>



>







768
769
770
771
772
773
774

775
776
777
778
779
780
781
...
857
858
859
860
861
862
863

864
865
866
867
868
869
870
....
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
....
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
....
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
....
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
    }
  }
  pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra);
  if( pNew ){
    memset(pNew, 0, sizeof(Expr));
    pNew->op = (u8)op;
    pNew->iAgg = -1;

    if( pToken ){
      if( nExtra==0 ){
        pNew->flags |= EP_IntValue|EP_Leaf;
        pNew->u.iValue = iValue;
      }else{
        pNew->u.zToken = (char*)&pNew[1];
        assert( pToken->z!=0 || pToken->n==0 );
................................................................................
    p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
  }else{
    p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
    if( p ){
      memset(p, 0, sizeof(Expr));
      p->op = op & TKFLG_MASK;
      p->iAgg = -1;

    }
    sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
  }
  if( p ) {
    sqlite3ExprCheckHeight(pParse, p->nHeight);
  }
  return p;
................................................................................
** to enforce this constraint.
*/
static int dupedExprStructSize(Expr *p, int flags){
  int nSize;
  assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
  assert( EXPR_FULLSIZE<=0xfff );
  assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
  if( 0==flags || p->op==TK_SELECT_COLUMN 
#ifndef SQLITE_OMIT_WINDOWFUNC
   || p->pWin 
#endif
  ){
    nSize = EXPR_FULLSIZE;
  }else{
    assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
    assert( !ExprHasProperty(p, EP_FromJoin) ); 
    assert( !ExprHasProperty(p, EP_MemToken) );
    assert( !ExprHasProperty(p, EP_NoReduce) );
    if( p->pLeft || p->x.pList ){
................................................................................
        pNew->pRight = p->pRight ?
                       exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
      }
      if( pzBuffer ){
        *pzBuffer = zAlloc;
      }
    }else{
#ifndef SQLITE_OMIT_WINDOWFUNC
      if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
        pNew->pWin = 0;
      }else{
        pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin);
      }
#endif /* SQLITE_OMIT_WINDOWFUNC */
      if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
        if( pNew->op==TK_SELECT_COLUMN ){
          pNew->pLeft = p->pLeft;
          assert( p->iColumn==0 || p->pRight==0 );
          assert( p->pRight==0  || p->pRight==p->pLeft );
        }else{
          pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
................................................................................
    pNew->iLimit = 0;
    pNew->iOffset = 0;
    pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
    pNew->addrOpenEphm[0] = -1;
    pNew->addrOpenEphm[1] = -1;
    pNew->nSelectRow = p->nSelectRow;
    pNew->pWith = withDup(db, p->pWith);
#ifndef SQLITE_OMIT_WINDOWFUNC
    pNew->pWin = 0;
    pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
#endif
    sqlite3SelectSetName(pNew, p->zSelName);
    *pp = pNew;
    pp = &pNew->pPrior;
    pNext = pNew;
  }

  return pRet;
................................................................................
      const char *zId;       /* The function name */
      u32 constMask = 0;     /* Mask of function arguments that are constant */
      int i;                 /* Loop counter */
      sqlite3 *db = pParse->db;  /* The database connection */
      u8 enc = ENC(db);      /* The text encoding used by this database */
      CollSeq *pColl = 0;    /* A collating sequence */

#ifndef SQLITE_OMIT_WINDOWFUNC
      if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){
        return pExpr->pWin->regResult;
      }
#endif

      if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
        /* SQL functions can be expensive. So try to move constant functions
        ** out of the inner loop, even if that means an extra OP_Copy. */
        return sqlite3ExprCodeAtInit(pParse, pExpr, -1);
      }
      assert( !ExprHasProperty(pExpr, EP_xIsSelect) );

Changes to src/func.c.

1509
1510
1511
1512
1513
1514
1515

1516
1517
1518
1519
1520
1521
1522
....
1530
1531
1532
1533
1534
1535
1536



1537
1538
1539
1540
1541
1542
1543
....
1642
1643
1644
1645
1646
1647
1648

1649
1650
1651



1652
1653
1654
1655
1656
1657
1658
....
1684
1685
1686
1687
1688
1689
1690

1691
1692
1693
1694
1695
1696
1697
....
1708
1709
1710
1711
1712
1713
1714



1715
1716
1717
1718
1719
1720
1721
....
1722
1723
1724
1725
1726
1727
1728

1729
1730
1731
1732
1733
1734
1735
....
1736
1737
1738
1739
1740
1741
1742



1743
1744
1745
1746
1747
1748
1749
      }
    }else{
      p->rSum += sqlite3_value_double(argv[0]);
      p->approx = 1;
    }
  }
}

static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){
  SumCtx *p;
  int type;
  assert( argc==1 );
  UNUSED_PARAMETER(argc);
  p = sqlite3_aggregate_context(context, sizeof(*p));
  type = sqlite3_value_numeric_type(argv[0]);
................................................................................
      }
    }else{
      p->rSum += sqlite3_value_double(argv[0]);
      p->approx = 1;
    }
  }
}



static void sumFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>0 ){
    if( p->overflow ){
      sqlite3_result_error(context,"integer overflow",-1);
    }else if( p->approx ){
................................................................................
  if( pRes ){
    if( pRes->flags ){
      sqlite3_result_value(context, pRes);
    }
    if( bValue==0 ) sqlite3VdbeMemRelease(pRes);
  }
}

static void minMaxValue(sqlite3_context *context){
  return minMaxValueFinalize(context, 1);
}



static void minMaxFinalize(sqlite3_context *context){
  return minMaxValueFinalize(context, 0);
}

/*
** group_concat(EXPR, ?SEPARATOR?)
*/
................................................................................
      if( zSep ) sqlite3_str_append(pAccum, zSep, nSep);
    }
    zVal = (char*)sqlite3_value_text(argv[0]);
    nVal = sqlite3_value_bytes(argv[0]);
    if( zVal ) sqlite3_str_append(pAccum, zVal, nVal);
  }
}

static void groupConcatInverse(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int n;
  assert( argc==1 || argc==2 );
................................................................................
    }else{
      pAccum->nChar -= n;
      memmove(pAccum->zText, &pAccum->zText[n], pAccum->nChar);
    }
    if( pAccum->nChar==0 ) pAccum->mxAlloc = 0;
  }
}



static void groupConcatFinalize(sqlite3_context *context){
  StrAccum *pAccum;
  pAccum = sqlite3_aggregate_context(context, 0);
  if( pAccum ){
    if( pAccum->accError==SQLITE_TOOBIG ){
      sqlite3_result_error_toobig(context);
    }else if( pAccum->accError==SQLITE_NOMEM ){
................................................................................
      sqlite3_result_error_nomem(context);
    }else{    
      sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
                          sqlite3_free);
    }
  }
}

static void groupConcatValue(sqlite3_context *context){
  sqlite3_str *pAccum;
  pAccum = (sqlite3_str*)sqlite3_aggregate_context(context, 0);
  if( pAccum ){
    if( pAccum->accError==SQLITE_TOOBIG ){
      sqlite3_result_error_toobig(context);
    }else if( pAccum->accError==SQLITE_NOMEM ){
................................................................................
      sqlite3_result_error_nomem(context);
    }else{    
      const char *zText = sqlite3_str_value(pAccum);
      sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
    }
  }
}




/*
** This routine does per-connection function registration.  Most
** of the built-in functions above are part of the global function set.
** This routine only deals with those that are not global.
*/
void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){







>







 







>
>
>







 







>



>
>
>







 







>







 







>
>
>







 







>







 







>
>
>







1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
....
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
....
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
....
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
....
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
....
1734
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
      }
    }else{
      p->rSum += sqlite3_value_double(argv[0]);
      p->approx = 1;
    }
  }
}
#ifndef SQLITE_OMIT_WINDOWFUNC
static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){
  SumCtx *p;
  int type;
  assert( argc==1 );
  UNUSED_PARAMETER(argc);
  p = sqlite3_aggregate_context(context, sizeof(*p));
  type = sqlite3_value_numeric_type(argv[0]);
................................................................................
      }
    }else{
      p->rSum += sqlite3_value_double(argv[0]);
      p->approx = 1;
    }
  }
}
#else
# define sumInverse 0
#endif /* SQLITE_OMIT_WINDOWFUNC */
static void sumFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>0 ){
    if( p->overflow ){
      sqlite3_result_error(context,"integer overflow",-1);
    }else if( p->approx ){
................................................................................
  if( pRes ){
    if( pRes->flags ){
      sqlite3_result_value(context, pRes);
    }
    if( bValue==0 ) sqlite3VdbeMemRelease(pRes);
  }
}
#ifndef SQLITE_OMIT_WINDOWFUNC
static void minMaxValue(sqlite3_context *context){
  return minMaxValueFinalize(context, 1);
}
#else
# define minMaxValue 0
#endif /* SQLITE_OMIT_WINDOWFUNC */
static void minMaxFinalize(sqlite3_context *context){
  return minMaxValueFinalize(context, 0);
}

/*
** group_concat(EXPR, ?SEPARATOR?)
*/
................................................................................
      if( zSep ) sqlite3_str_append(pAccum, zSep, nSep);
    }
    zVal = (char*)sqlite3_value_text(argv[0]);
    nVal = sqlite3_value_bytes(argv[0]);
    if( zVal ) sqlite3_str_append(pAccum, zVal, nVal);
  }
}
#ifndef SQLITE_OMIT_WINDOWFUNC
static void groupConcatInverse(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int n;
  assert( argc==1 || argc==2 );
................................................................................
    }else{
      pAccum->nChar -= n;
      memmove(pAccum->zText, &pAccum->zText[n], pAccum->nChar);
    }
    if( pAccum->nChar==0 ) pAccum->mxAlloc = 0;
  }
}
#else
# define groupConcatInverse 0
#endif /* SQLITE_OMIT_WINDOWFUNC */
static void groupConcatFinalize(sqlite3_context *context){
  StrAccum *pAccum;
  pAccum = sqlite3_aggregate_context(context, 0);
  if( pAccum ){
    if( pAccum->accError==SQLITE_TOOBIG ){
      sqlite3_result_error_toobig(context);
    }else if( pAccum->accError==SQLITE_NOMEM ){
................................................................................
      sqlite3_result_error_nomem(context);
    }else{    
      sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
                          sqlite3_free);
    }
  }
}
#ifndef SQLITE_OMIT_WINDOWFUNC
static void groupConcatValue(sqlite3_context *context){
  sqlite3_str *pAccum;
  pAccum = (sqlite3_str*)sqlite3_aggregate_context(context, 0);
  if( pAccum ){
    if( pAccum->accError==SQLITE_TOOBIG ){
      sqlite3_result_error_toobig(context);
    }else if( pAccum->accError==SQLITE_NOMEM ){
................................................................................
      sqlite3_result_error_nomem(context);
    }else{    
      const char *zText = sqlite3_str_value(pAccum);
      sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
    }
  }
}
#else
# define groupConcatValue 0
#endif /* SQLITE_OMIT_WINDOWFUNC */

/*
** This routine does per-connection function registration.  Most
** of the built-in functions above are part of the global function set.
** This routine only deals with those that are not global.
*/
void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){

Changes to src/parse.y.

525
526
527
528
529
530
531
532



533
534
535
536
537

538
539
540
541
542

543
544
545
546
547
548
549
....
1007
1008
1009
1010
1011
1012
1013
1014




1015
1016
1017
1018
1019
1020
1021
1022
1023
1024




1025
1026
1027
1028
1029
1030


1031
1032
1033
1034
1035
1036
1037
....
1117
1118
1119
1120
1121
1122
1123

1124
1125
1126
1127
1128
1129
1130
}
%type multiselect_op {int}
multiselect_op(A) ::= UNION(OP).             {A = @OP; /*A-overwrites-OP*/}
multiselect_op(A) ::= UNION ALL.             {A = TK_ALL;}
multiselect_op(A) ::= EXCEPT|INTERSECT(OP).  {A = @OP; /*A-overwrites-OP*/}
%endif SQLITE_OMIT_COMPOUND_SELECT
oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y)
                 groupby_opt(P) having_opt(Q) windowdefn_opt(R)



                 orderby_opt(Z) limit_opt(L). {
#if SELECTTRACE_ENABLED
  Token s = S; /*A-overwrites-S*/
#endif
  A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L);

  if( A ){
    A->pWinDefn = R;
  }else{
    sqlite3WindowListDelete(pParse->db, R);
  }

#if SELECTTRACE_ENABLED
  /* Populate the Select.zSelName[] string that is used to help with
  ** query planner debugging, to differentiate between multiple Select
  ** objects in a complex query.
  **
  ** If the SELECT keyword is immediately followed by a C-style comment
  ** then extract the first few alphanumeric characters from within that
................................................................................
}
%ifndef SQLITE_OMIT_CAST
expr(A) ::= CAST LP expr(E) AS typetoken(T) RP. {
  A = sqlite3ExprAlloc(pParse->db, TK_CAST, &T, 1);
  sqlite3ExprAttachSubtrees(pParse->db, A, E, 0);
}
%endif  SQLITE_OMIT_CAST
expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP over_opt(Z). {




  if( Y && Y->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
    sqlite3ErrorMsg(pParse, "too many arguments on function %T", &X);
  }
  A = sqlite3ExprFunction(pParse, Y, &X);
  sqlite3WindowAttach(pParse, A, Z);
  if( D==SF_Distinct && A ){
    A->flags |= EP_Distinct;
  }
}
expr(A) ::= id(X) LP STAR RP over_opt(Z). {




  A = sqlite3ExprFunction(pParse, 0, &X);
  sqlite3WindowAttach(pParse, A, Z);
}
term(A) ::= CTIME_KW(OP). {
  A = sqlite3ExprFunction(pParse, 0, &OP);
}



%type windowdefn_opt {Window*}
%destructor windowdefn_opt {sqlite3WindowDelete(pParse->db, $$);}
windowdefn_opt(A) ::= . { A = 0; }
windowdefn_opt(A) ::= WINDOW windowdefn_list(B). { A = B; }

%type windowdefn_list {Window*}
................................................................................

frame_bound(A) ::= UNBOUNDED PRECEDING. { A.eType = TK_UNBOUNDED; A.pExpr = 0; }
frame_bound(A) ::= expr(X) PRECEDING.   { A.eType = TK_PRECEDING; A.pExpr = X; }
frame_bound(A) ::= CURRENT ROW.         { A.eType = TK_CURRENT  ; A.pExpr = 0; }
frame_bound(A) ::= expr(X) FOLLOWING.   { A.eType = TK_FOLLOWING; A.pExpr = X; }
frame_bound(A) ::= UNBOUNDED FOLLOWING. { A.eType = TK_UNBOUNDED; A.pExpr = 0; }



expr(A) ::= LP nexprlist(X) COMMA expr(Y) RP. {
  ExprList *pList = sqlite3ExprListAppend(pParse, X, Y);
  A = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
  if( A ){
    A->x.pList = pList;
  }else{







|
>
>
>





>





>







 







|
>
>
>
>









|
>
>
>
>






>
>







 







>







525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
....
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
....
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
}
%type multiselect_op {int}
multiselect_op(A) ::= UNION(OP).             {A = @OP; /*A-overwrites-OP*/}
multiselect_op(A) ::= UNION ALL.             {A = TK_ALL;}
multiselect_op(A) ::= EXCEPT|INTERSECT(OP).  {A = @OP; /*A-overwrites-OP*/}
%endif SQLITE_OMIT_COMPOUND_SELECT
oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y)
                 groupby_opt(P) having_opt(Q) 
%ifndef SQLITE_OMIT_WINDOWFUNC
                 windowdefn_opt(R)
%endif
                 orderby_opt(Z) limit_opt(L). {
#if SELECTTRACE_ENABLED
  Token s = S; /*A-overwrites-S*/
#endif
  A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L);
#ifndef SQLITE_OMIT_WINDOWFUNC
  if( A ){
    A->pWinDefn = R;
  }else{
    sqlite3WindowListDelete(pParse->db, R);
  }
#endif // SQLITE_OMIT_WINDOWFUNC
#if SELECTTRACE_ENABLED
  /* Populate the Select.zSelName[] string that is used to help with
  ** query planner debugging, to differentiate between multiple Select
  ** objects in a complex query.
  **
  ** If the SELECT keyword is immediately followed by a C-style comment
  ** then extract the first few alphanumeric characters from within that
................................................................................
}
%ifndef SQLITE_OMIT_CAST
expr(A) ::= CAST LP expr(E) AS typetoken(T) RP. {
  A = sqlite3ExprAlloc(pParse->db, TK_CAST, &T, 1);
  sqlite3ExprAttachSubtrees(pParse->db, A, E, 0);
}
%endif  SQLITE_OMIT_CAST
expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP 
%ifndef SQLITE_OMIT_WINDOWFUNC
  over_opt(Z)
%endif
. {
  if( Y && Y->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
    sqlite3ErrorMsg(pParse, "too many arguments on function %T", &X);
  }
  A = sqlite3ExprFunction(pParse, Y, &X);
  sqlite3WindowAttach(pParse, A, Z);
  if( D==SF_Distinct && A ){
    A->flags |= EP_Distinct;
  }
}
expr(A) ::= id(X) LP STAR RP
%ifndef SQLITE_OMIT_WINDOWFUNC
  over_opt(Z)
%endif
. {
  A = sqlite3ExprFunction(pParse, 0, &X);
  sqlite3WindowAttach(pParse, A, Z);
}
term(A) ::= CTIME_KW(OP). {
  A = sqlite3ExprFunction(pParse, 0, &OP);
}

%ifndef SQLITE_OMIT_WINDOWFUNC

%type windowdefn_opt {Window*}
%destructor windowdefn_opt {sqlite3WindowDelete(pParse->db, $$);}
windowdefn_opt(A) ::= . { A = 0; }
windowdefn_opt(A) ::= WINDOW windowdefn_list(B). { A = B; }

%type windowdefn_list {Window*}
................................................................................

frame_bound(A) ::= UNBOUNDED PRECEDING. { A.eType = TK_UNBOUNDED; A.pExpr = 0; }
frame_bound(A) ::= expr(X) PRECEDING.   { A.eType = TK_PRECEDING; A.pExpr = X; }
frame_bound(A) ::= CURRENT ROW.         { A.eType = TK_CURRENT  ; A.pExpr = 0; }
frame_bound(A) ::= expr(X) FOLLOWING.   { A.eType = TK_FOLLOWING; A.pExpr = X; }
frame_bound(A) ::= UNBOUNDED FOLLOWING. { A.eType = TK_UNBOUNDED; A.pExpr = 0; }

%endif // SQLITE_OMIT_WINDOWFUNC

expr(A) ::= LP nexprlist(X) COMMA expr(Y) RP. {
  ExprList *pList = sqlite3ExprListAppend(pParse, X, Y);
  A = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
  if( A ){
    A->x.pList = pList;
  }else{

Changes to src/resolve.c.

753
754
755
756
757
758
759

760
761
762
763
764
765
766
...
769
770
771
772
773
774
775




776
777
778
779
780
781
782
...
787
788
789
790
791
792
793

794
795
796
797
798
799
800
801
802
803


804
805
806
807
808
809
810
....
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
          ** sqlite_version() that might change over time cannot be used
          ** in an index. */
          notValid(pParse, pNC, "non-deterministic functions",
                   NC_IdxExpr|NC_PartIdx);
        }
      }


      if( is_agg==0 && pExpr->pWin ){
        sqlite3ErrorMsg(pParse, 
            "%.*s() may not be used as a window function", nId, zId
        );
        pNC->nErr++;
      }else if( 
            (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
................................................................................
      ){
        const char *zType;
        if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){
          zType = "window";
        }else{
          zType = "aggregate";
        }




        sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()", zType, nId,zId);
        pNC->nErr++;
        is_agg = 0;
      }else if( no_such_func && pParse->db->init.busy==0
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
                && pParse->explain==0
#endif
................................................................................
        sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
             nId, zId);
        pNC->nErr++;
      }
      if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
      sqlite3WalkExprList(pWalker, pList);
      if( is_agg ){

        if( pExpr->pWin ){
          Select *pSel = pNC->pWinSelect;
          sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef);
          if( 0==pSel->pWin 
           || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin) 
          ){
            pExpr->pWin->pNextWin = pSel->pWin;
            pSel->pWin = pExpr->pWin;
          }
        }else{


          NameContext *pNC2 = pNC;
          pExpr->op = TK_AGG_FUNCTION;
          pExpr->op2 = 0;
          while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
            pExpr->op2++;
            pNC2 = pNC2->pNext;
          }
................................................................................
    return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune;
  }

  isCompound = p->pPrior!=0;
  nCompound = 0;
  pLeftmost = p;
  while( p ){
    assert( p->pWin==0 );
    assert( (p->selFlags & SF_Expanded)!=0 );
    assert( (p->selFlags & SF_Resolved)==0 );
    p->selFlags |= SF_Resolved;

    /* Resolve the expressions in the LIMIT and OFFSET clauses. These
    ** are not allowed to refer to any names, so pass an empty NameContext.
    */







>







 







>
>
>
>







 







>









|
>
>







 







<







753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
...
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
...
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
....
1268
1269
1270
1271
1272
1273
1274

1275
1276
1277
1278
1279
1280
1281
          ** sqlite_version() that might change over time cannot be used
          ** in an index. */
          notValid(pParse, pNC, "non-deterministic functions",
                   NC_IdxExpr|NC_PartIdx);
        }
      }

#ifndef SQLITE_OMIT_WINDOWFUNC
      if( is_agg==0 && pExpr->pWin ){
        sqlite3ErrorMsg(pParse, 
            "%.*s() may not be used as a window function", nId, zId
        );
        pNC->nErr++;
      }else if( 
            (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
................................................................................
      ){
        const char *zType;
        if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){
          zType = "window";
        }else{
          zType = "aggregate";
        }
#else
      if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){
        const char *zType = "aggregate";
#endif
        sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()", zType, nId,zId);
        pNC->nErr++;
        is_agg = 0;
      }else if( no_such_func && pParse->db->init.busy==0
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
                && pParse->explain==0
#endif
................................................................................
        sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
             nId, zId);
        pNC->nErr++;
      }
      if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
      sqlite3WalkExprList(pWalker, pList);
      if( is_agg ){
#ifndef SQLITE_OMIT_WINDOWFUNC
        if( pExpr->pWin ){
          Select *pSel = pNC->pWinSelect;
          sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef);
          if( 0==pSel->pWin 
           || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin) 
          ){
            pExpr->pWin->pNextWin = pSel->pWin;
            pSel->pWin = pExpr->pWin;
          }
        }else
#endif /* SQLITE_OMIT_WINDOWFUNC */
        {
          NameContext *pNC2 = pNC;
          pExpr->op = TK_AGG_FUNCTION;
          pExpr->op2 = 0;
          while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
            pExpr->op2++;
            pNC2 = pNC2->pNext;
          }
................................................................................
    return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune;
  }

  isCompound = p->pPrior!=0;
  nCompound = 0;
  pLeftmost = p;
  while( p ){

    assert( (p->selFlags & SF_Expanded)!=0 );
    assert( (p->selFlags & SF_Resolved)==0 );
    p->selFlags |= SF_Resolved;

    /* Resolve the expressions in the LIMIT and OFFSET clauses. These
    ** are not allowed to refer to any names, so pass an empty NameContext.
    */

Changes to src/select.c.

92
93
94
95
96
97
98

99
100
101

102
103
104
105
106
107
108
...
161
162
163
164
165
166
167

168
169

170
171
172
173
174
175
176
....
3716
3717
3718
3719
3720
3721
3722

3723

3724
3725
3726
3727
3728
3729
3730
....
5483
5484
5485
5486
5487
5488
5489

5490
5491
5492
5493
5494
5495
5496
5497
5498

5499
5500
5501
5502
5503
5504
5505
....
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882


5883
5884
5885



5886
5887
5888
5889
5890
5891
5892
....
5908
5909
5910
5911
5912
5913
5914

5915
5916
5917
5918
5919
5920
5921
....
5923
5924
5925
5926
5927
5928
5929
5930


5931
5932
5933
5934
5935
5936
5937
    sqlite3ExprListDelete(db, p->pEList);
    sqlite3SrcListDelete(db, p->pSrc);
    sqlite3ExprDelete(db, p->pWhere);
    sqlite3ExprListDelete(db, p->pGroupBy);
    sqlite3ExprDelete(db, p->pHaving);
    sqlite3ExprListDelete(db, p->pOrderBy);
    sqlite3ExprDelete(db, p->pLimit);

    if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
      sqlite3WindowListDelete(db, p->pWinDefn);
    }

    if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
    if( bFree ) sqlite3DbFreeNN(db, p);
    p = pPrior;
    bFree = 1;
  }
}

................................................................................
  pNew->pGroupBy = pGroupBy;
  pNew->pHaving = pHaving;
  pNew->pOrderBy = pOrderBy;
  pNew->pPrior = 0;
  pNew->pNext = 0;
  pNew->pLimit = pLimit;
  pNew->pWith = 0;

  pNew->pWin = 0;
  pNew->pWinDefn = 0;

  if( pParse->db->mallocFailed ) {
    clearSelect(pParse->db, pNew, pNew!=&standin);
    pNew = 0;
  }else{
    assert( pNew->pSrc!=0 || pParse->nErr>0 );
  }
  assert( pNew!=&standin );
................................................................................
  pSrc = p->pSrc;
  assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
  pSubitem = &pSrc->a[iFrom];
  iParent = pSubitem->iCursor;
  pSub = pSubitem->pSelect;
  assert( pSub!=0 );


  if( p->pWin || pSub->pWin ) return 0;                  /* Restriction (25) */


  pSubSrc = pSub->pSrc;
  assert( pSubSrc );
  /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
  ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET
  ** because they could be computed at compile-time.  But when LIMIT and OFFSET
  ** became arbitrary expressions, we were forced to add restrictions (13)
................................................................................
  }
#endif

  if( pDest->eDest==SRT_Output ){
    generateColumnNames(pParse, p);
  }


  if( (rc = sqlite3WindowRewrite(pParse, p)) ){
    goto select_end;
  }
#if SELECTTRACE_ENABLED
  if( sqlite3SelectTrace & 0x108 ){
    SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif

  pTabList = p->pSrc;
  isAgg = (p->selFlags & SF_Aggregate)!=0;

  /* Try to various optimizations (flattening subqueries, and strength
  ** reduction of join operators) in the FROM clause up into the main query
  */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
................................................................................
    sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
    sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
  }else{
    sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
  }

  if( !isAgg && pGroupBy==0 ){
    Window *pWin = p->pWin;      /* Master window object (or NULL) */

    /* No aggregate functions and no GROUP BY clause */
    u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
    assert( WHERE_USE_LIMIT==SF_FixedLimit );
    wctrlFlags |= p->selFlags & SF_FixedLimit;



    if( pWin ){
      sqlite3WindowCodeInit(pParse, pWin);
    }




    /* Begin the database scan. */
    SELECTTRACE(1,pParse,p,("WhereBegin\n"));
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
                               p->pEList, wctrlFlags, p->nSelectRow);
    if( pWInfo==0 ) goto select_end;
    if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
................................................................................
    ** into an OP_Noop.
    */
    if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){
      sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
    }

    assert( p->pEList==pEList );

    if( pWin ){
      int addrGosub = sqlite3VdbeMakeLabel(v);
      int iCont = sqlite3VdbeMakeLabel(v);
      int regGosub = ++pParse->nMem;
      int addr = 0;

      sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub);
................................................................................
      addr = sqlite3VdbeAddOp0(v, OP_Goto);
      sqlite3VdbeResolveLabel(v, addrGosub);
      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, iCont, 0);
      sqlite3VdbeResolveLabel(v, iCont);
      sqlite3VdbeAddOp1(v, OP_Return, regGosub);
      sqlite3VdbeJumpHere(v, addr);

    }else{


      /* Use the standard inner loop. */
      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest,
          sqlite3WhereContinueLabel(pWInfo),
          sqlite3WhereBreakLabel(pWInfo));

      /* End the database scan loop.
      */







>



>







 







>


>







 







>

>







 







>
|








>







 







<
<

|
<
|
<
>
>



>
>
>







 







>







 







|
>
>







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
....
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
....
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
....
5877
5878
5879
5880
5881
5882
5883


5884
5885

5886

5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
....
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
....
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
    sqlite3ExprListDelete(db, p->pEList);
    sqlite3SrcListDelete(db, p->pSrc);
    sqlite3ExprDelete(db, p->pWhere);
    sqlite3ExprListDelete(db, p->pGroupBy);
    sqlite3ExprDelete(db, p->pHaving);
    sqlite3ExprListDelete(db, p->pOrderBy);
    sqlite3ExprDelete(db, p->pLimit);
#ifndef SQLITE_OMIT_WINDOWFUNC
    if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
      sqlite3WindowListDelete(db, p->pWinDefn);
    }
#endif
    if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
    if( bFree ) sqlite3DbFreeNN(db, p);
    p = pPrior;
    bFree = 1;
  }
}

................................................................................
  pNew->pGroupBy = pGroupBy;
  pNew->pHaving = pHaving;
  pNew->pOrderBy = pOrderBy;
  pNew->pPrior = 0;
  pNew->pNext = 0;
  pNew->pLimit = pLimit;
  pNew->pWith = 0;
#ifndef SQLITE_OMIT_WINDOWFUNC
  pNew->pWin = 0;
  pNew->pWinDefn = 0;
#endif
  if( pParse->db->mallocFailed ) {
    clearSelect(pParse->db, pNew, pNew!=&standin);
    pNew = 0;
  }else{
    assert( pNew->pSrc!=0 || pParse->nErr>0 );
  }
  assert( pNew!=&standin );
................................................................................
  pSrc = p->pSrc;
  assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
  pSubitem = &pSrc->a[iFrom];
  iParent = pSubitem->iCursor;
  pSub = pSubitem->pSelect;
  assert( pSub!=0 );

#ifndef SQLITE_OMIT_WINDOWFUNC
  if( p->pWin || pSub->pWin ) return 0;                  /* Restriction (25) */
#endif

  pSubSrc = pSub->pSrc;
  assert( pSubSrc );
  /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
  ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET
  ** because they could be computed at compile-time.  But when LIMIT and OFFSET
  ** became arbitrary expressions, we were forced to add restrictions (13)
................................................................................
  }
#endif

  if( pDest->eDest==SRT_Output ){
    generateColumnNames(pParse, p);
  }

#ifndef SQLITE_OMIT_WINDOWFUNC
  if( sqlite3WindowRewrite(pParse, p) ){
    goto select_end;
  }
#if SELECTTRACE_ENABLED
  if( sqlite3SelectTrace & 0x108 ){
    SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
#endif /* SQLITE_OMIT_WINDOWFUNC */
  pTabList = p->pSrc;
  isAgg = (p->selFlags & SF_Aggregate)!=0;

  /* Try to various optimizations (flattening subqueries, and strength
  ** reduction of join operators) in the FROM clause up into the main query
  */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
................................................................................
    sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
    sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
  }else{
    sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
  }

  if( !isAgg && pGroupBy==0 ){


    /* No aggregate functions and no GROUP BY clause */
    u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0)

                   | (p->selFlags & SF_FixedLimit);

#ifndef SQLITE_OMIT_WINDOWFUNC
    Window *pWin = p->pWin;      /* Master window object (or NULL) */
    if( pWin ){
      sqlite3WindowCodeInit(pParse, pWin);
    }
#endif
    assert( WHERE_USE_LIMIT==SF_FixedLimit );


    /* Begin the database scan. */
    SELECTTRACE(1,pParse,p,("WhereBegin\n"));
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
                               p->pEList, wctrlFlags, p->nSelectRow);
    if( pWInfo==0 ) goto select_end;
    if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
................................................................................
    ** into an OP_Noop.
    */
    if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){
      sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
    }

    assert( p->pEList==pEList );
#ifndef SQLITE_OMIT_WINDOWFUNC
    if( pWin ){
      int addrGosub = sqlite3VdbeMakeLabel(v);
      int iCont = sqlite3VdbeMakeLabel(v);
      int regGosub = ++pParse->nMem;
      int addr = 0;

      sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub);
................................................................................
      addr = sqlite3VdbeAddOp0(v, OP_Goto);
      sqlite3VdbeResolveLabel(v, addrGosub);
      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, iCont, 0);
      sqlite3VdbeResolveLabel(v, iCont);
      sqlite3VdbeAddOp1(v, OP_Return, regGosub);
      sqlite3VdbeJumpHere(v, addr);

    }else
#endif /* SQLITE_OMIT_WINDOWFUNC */
    {
      /* Use the standard inner loop. */
      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest,
          sqlite3WhereContinueLabel(pWInfo),
          sqlite3WhereBreakLabel(pWInfo));

      /* End the database scan loop.
      */

Changes to src/sqliteInt.h.

2462
2463
2464
2465
2466
2467
2468

2469

2470
2471
2472
2473
2474
2475
2476
....
2815
2816
2817
2818
2819
2820
2821

2822
2823

2824
2825
2826
2827
2828
2829
2830
....
3513
3514
3515
3516
3517
3518
3519

3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532





3533
3534
3535
3536
3537
3538
3539
  i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  u8 op2;                /* TK_REGISTER: original value of Expr.op
                         ** TK_COLUMN: the value of p5 for OP_Column
                         ** TK_AGG_FUNCTION: nesting depth */
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  Table *pTab;           /* Table for TK_COLUMN expressions.  Can be NULL
                         ** for a column of an index on an expression */

  Window *pWin;          /* Window definition for window functions */

};

/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
#define EP_Agg       0x000002 /* Contains one or more aggregate functions */
................................................................................
  ExprList *pGroupBy;    /* The GROUP BY clause */
  Expr *pHaving;         /* The HAVING clause */
  ExprList *pOrderBy;    /* The ORDER BY clause */
  Select *pPrior;        /* Prior select in a compound select statement */
  Select *pNext;         /* Next select to the left in a compound */
  Expr *pLimit;          /* LIMIT expression. NULL means not used. */
  With *pWith;           /* WITH clause attached to this select. Or NULL. */

  Window *pWin;          /* List of window functions */
  Window *pWinDefn;      /* List of named window definitions */

};

/*
** Allowed values for Select.selFlags.  The "SF" prefix stands for
** "Select Flag".
**
** Value constraints (all checked via assert())
................................................................................

  int regPart;
  Expr *pOwner;           /* Expression object this window is attached to */
  int nBufferCol;         /* Number of columns in buffer table */
  int iArgCol;            /* Offset of first argument for this function */
};


void sqlite3WindowDelete(sqlite3*, Window*);
void sqlite3WindowListDelete(sqlite3 *db, Window *p);
Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*);
void sqlite3WindowAttach(Parse*, Expr*, Window*);
int sqlite3WindowCompare(Parse*, Window*, Window*);
void sqlite3WindowCodeInit(Parse*, Window*);
void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
int sqlite3WindowRewrite(Parse*, Select*);
int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
void sqlite3WindowFunctions(void);






/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/
#define SQLITE_SKIP_UTF8(zIn) {                        \
  if( (*(zIn++))>=0xc0 ){                              \







>

>







 







>


>







 







>













>
>
>
>
>







2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
....
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
....
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
  i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  u8 op2;                /* TK_REGISTER: original value of Expr.op
                         ** TK_COLUMN: the value of p5 for OP_Column
                         ** TK_AGG_FUNCTION: nesting depth */
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  Table *pTab;           /* Table for TK_COLUMN expressions.  Can be NULL
                         ** for a column of an index on an expression */
#ifndef SQLITE_OMIT_WINDOWFUNC
  Window *pWin;          /* Window definition for window functions */
#endif
};

/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
#define EP_Agg       0x000002 /* Contains one or more aggregate functions */
................................................................................
  ExprList *pGroupBy;    /* The GROUP BY clause */
  Expr *pHaving;         /* The HAVING clause */
  ExprList *pOrderBy;    /* The ORDER BY clause */
  Select *pPrior;        /* Prior select in a compound select statement */
  Select *pNext;         /* Next select to the left in a compound */
  Expr *pLimit;          /* LIMIT expression. NULL means not used. */
  With *pWith;           /* WITH clause attached to this select. Or NULL. */
#ifndef SQLITE_OMIT_WINDOWFUNC
  Window *pWin;          /* List of window functions */
  Window *pWinDefn;      /* List of named window definitions */
#endif
};

/*
** Allowed values for Select.selFlags.  The "SF" prefix stands for
** "Select Flag".
**
** Value constraints (all checked via assert())
................................................................................

  int regPart;
  Expr *pOwner;           /* Expression object this window is attached to */
  int nBufferCol;         /* Number of columns in buffer table */
  int iArgCol;            /* Offset of first argument for this function */
};

#ifndef SQLITE_OMIT_WINDOWFUNC
void sqlite3WindowDelete(sqlite3*, Window*);
void sqlite3WindowListDelete(sqlite3 *db, Window *p);
Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*);
void sqlite3WindowAttach(Parse*, Expr*, Window*);
int sqlite3WindowCompare(Parse*, Window*, Window*);
void sqlite3WindowCodeInit(Parse*, Window*);
void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
int sqlite3WindowRewrite(Parse*, Select*);
int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
void sqlite3WindowFunctions(void);
#else
# define sqlite3WindowDelete(a,b)
# define sqlite3WindowFunctions()
# define sqlite3WindowAttach(a,b,c)
#endif

/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/
#define SQLITE_SKIP_UTF8(zIn) {                        \
  if( (*(zIn++))>=0xc0 ){                              \

Changes to src/test_config.c.

757
758
759
760
761
762
763






764
765
766
767
768
769
770
#endif

#ifdef SQLITE_ENABLE_URI_00_ERROR
  Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "0", TCL_GLOBAL_ONLY);
#endif







#define LINKVAR(x) { \
    static const int cv_ ## x = SQLITE_ ## x; \
    Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \
                TCL_LINK_INT | TCL_LINK_READ_ONLY); }

  LINKVAR( MAX_LENGTH );







>
>
>
>
>
>







757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
#endif

#ifdef SQLITE_ENABLE_URI_00_ERROR
  Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "0", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_WINDOWFUNC
  Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "1", TCL_GLOBAL_ONLY);
#endif

#define LINKVAR(x) { \
    static const int cv_ ## x = SQLITE_ ## x; \
    Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \
                TCL_LINK_INT | TCL_LINK_READ_ONLY); }

  LINKVAR( MAX_LENGTH );

Changes to src/vdbe.c.

5114
5115
5116
5117
5118
5119
5120

5121

5122
5123
5124
5125
5126
5127
5128
....
6365
6366
6367
6368
6369
6370
6371


6372


6373

6374
6375
6376
6377
6378
6379
6380
....
6408
6409
6410
6411
6412
6413
6414

6415
6416
6417
6418

6419
6420
6421
6422
6423
6424
6425
6426
6427
  if( isSorter(pC) ){
    rc = sqlite3VdbeSorterRewind(pC, &res);
  }else{
    assert( pC->eCurType==CURTYPE_BTREE );
    pCrsr = pC->uc.pCursor;
    assert( pCrsr );
    rc = sqlite3BtreeFirst(pCrsr, &res);

    if( pOp->p5 ) sqlite3BtreeSkipNext(pCrsr);

    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;
  }
  if( rc ) goto abort_due_to_error;
  pC->nullRow = (u8)res;
  assert( pOp->p2>0 && pOp->p2<p->nOp );
  VdbeBranchTaken(res!=0,2);
................................................................................
  }
#endif

  pMem->n++;
  assert( pCtx->pOut->flags==MEM_Null );
  assert( pCtx->isError==0 );
  assert( pCtx->skipFlag==0 );


  (pOp->p1 ? (pCtx->pFunc->xInverse) : (pCtx->pFunc->xSFunc))


    (pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */

  if( pCtx->isError ){
    if( pCtx->isError>0 ){
      sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
      rc = pCtx->isError;
    }
    if( pCtx->skipFlag ){
      assert( pOp[-1].opcode==OP_CollSeq );
................................................................................
** the step function was not previously called.
*/
case OP_AggFinal: {
  Mem *pMem;
  assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
  pMem = &aMem[pOp->p1];
  assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );

  if( pOp->p3 ){
    rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc);
    pMem = &aMem[pOp->p3];
  }else{

    rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
  }
  if( rc ){
    sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
    goto abort_due_to_error;
  }
  sqlite3VdbeChangeEncoding(pMem, encoding);
  UPDATE_MAX_BLOBSIZE(pMem);
  if( sqlite3VdbeMemTooBig(pMem) ){







>

>







 







>
>
|
>
>
|
>







 







>



|
>
|
|







5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
....
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
....
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
  if( isSorter(pC) ){
    rc = sqlite3VdbeSorterRewind(pC, &res);
  }else{
    assert( pC->eCurType==CURTYPE_BTREE );
    pCrsr = pC->uc.pCursor;
    assert( pCrsr );
    rc = sqlite3BtreeFirst(pCrsr, &res);
#ifndef SQLITE_OMIT_WINDOWFUNC
    if( pOp->p5 ) sqlite3BtreeSkipNext(pCrsr);
#endif
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;
  }
  if( rc ) goto abort_due_to_error;
  pC->nullRow = (u8)res;
  assert( pOp->p2>0 && pOp->p2<p->nOp );
  VdbeBranchTaken(res!=0,2);
................................................................................
  }
#endif

  pMem->n++;
  assert( pCtx->pOut->flags==MEM_Null );
  assert( pCtx->isError==0 );
  assert( pCtx->skipFlag==0 );
#ifndef SQLITE_OMIT_WINDOWFUNC
  if( pOp->p1 ){
    (pCtx->pFunc->xInverse)(pCtx,pCtx->argc,pCtx->argv);
  }else
#endif
  (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */

  if( pCtx->isError ){
    if( pCtx->isError>0 ){
      sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
      rc = pCtx->isError;
    }
    if( pCtx->skipFlag ){
      assert( pOp[-1].opcode==OP_CollSeq );
................................................................................
** the step function was not previously called.
*/
case OP_AggFinal: {
  Mem *pMem;
  assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
  pMem = &aMem[pOp->p1];
  assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
#ifndef SQLITE_OMIT_WINDOWFUNC
  if( pOp->p3 ){
    rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc);
    pMem = &aMem[pOp->p3];
  }else
#endif
  rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
  
  if( rc ){
    sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
    goto abort_due_to_error;
  }
  sqlite3VdbeChangeEncoding(pMem, encoding);
  UPDATE_MAX_BLOBSIZE(pMem);
  if( sqlite3VdbeMemTooBig(pMem) ){

Changes to src/vdbeInt.h.

493
494
495
496
497
498
499

500

501
502
503
504
505
506
507
void sqlite3VdbeIntegerAffinity(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemNumerify(Mem*);
void sqlite3VdbeMemCast(Mem*,u8,u8);
int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);

int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);

const char *sqlite3OpcodeName(int);
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
int sqlite3VdbeCloseStatement(Vdbe *, int);
void sqlite3VdbeFrameDelete(VdbeFrame*);
int sqlite3VdbeFrameRestore(VdbeFrame *);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK







>

>







493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
void sqlite3VdbeIntegerAffinity(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemNumerify(Mem*);
void sqlite3VdbeMemCast(Mem*,u8,u8);
int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
#ifndef SQLITE_OMIT_WINDOWFUNC
int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
#endif
const char *sqlite3OpcodeName(int);
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
int sqlite3VdbeCloseStatement(Vdbe *, int);
void sqlite3VdbeFrameDelete(VdbeFrame*);
int sqlite3VdbeFrameRestore(VdbeFrame *);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK

Changes to src/vdbemem.c.

419
420
421
422
423
424
425

426
427
428
429
430
431
432
...
436
437
438
439
440
441
442

443
444
445
446
447
448
449
** Memory cell pAccum contains the context of an aggregate function.
** This routine calls the xValue method for that function and stores
** the results in memory cell pMem.
**
** SQLITE_ERROR is returned if xValue() reports an error. SQLITE_OK 
** otherwise.
*/

int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){
  sqlite3_context ctx;
  Mem t;
  assert( pFunc!=0 );
  assert( pFunc->xValue!=0 );
  assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef );
  assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) );
................................................................................
  t.db = pAccum->db;
  ctx.pOut = pOut;
  ctx.pMem = pAccum;
  ctx.pFunc = pFunc;
  pFunc->xValue(&ctx);
  return ctx.isError;
}


/*
** If the memory cell contains a value that must be freed by
** invoking the external callback in Mem.xDel, then this routine
** will free that value.  It also sets Mem.flags to MEM_Null.
**
** This is a helper routine for sqlite3VdbeMemSetNull() and







>







 







>







419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
...
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
** Memory cell pAccum contains the context of an aggregate function.
** This routine calls the xValue method for that function and stores
** the results in memory cell pMem.
**
** SQLITE_ERROR is returned if xValue() reports an error. SQLITE_OK 
** otherwise.
*/
#ifndef SQLITE_OMIT_WINDOWFUNC
int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){
  sqlite3_context ctx;
  Mem t;
  assert( pFunc!=0 );
  assert( pFunc->xValue!=0 );
  assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef );
  assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) );
................................................................................
  t.db = pAccum->db;
  ctx.pOut = pOut;
  ctx.pMem = pAccum;
  ctx.pFunc = pFunc;
  pFunc->xValue(&ctx);
  return ctx.isError;
}
#endif /* SQLITE_OMIT_WINDOWFUNC */

/*
** If the memory cell contains a value that must be freed by
** invoking the external callback in Mem.xDel, then this routine
** will free that value.  It also sets Mem.flags to MEM_Null.
**
** This is a helper routine for sqlite3VdbeMemSetNull() and

Changes to src/window.c.

8
9
10
11
12
13
14


15
16
17
18
19
20
21
....
2062
2063
2064
2065
2066
2067
2068

**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
*/
#include "sqliteInt.h"



/*
** SELECT REWRITING
**
**   Any SELECT statement that contains one or more window functions in
**   either the select list or ORDER BY clause (the only two places window
**   functions may be used) is transformed by function sqlite3WindowRewrite()
**   in order to support window function processing. For example, with the
................................................................................
      windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub);
    }else{
      windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub);
    }
  }
}









>
>







 







>
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
2064
2065
2066
2067
2068
2069
2070
2071
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_WINDOWFUNC

/*
** SELECT REWRITING
**
**   Any SELECT statement that contains one or more window functions in
**   either the select list or ORDER BY clause (the only two places window
**   functions may be used) is transformed by function sqlite3WindowRewrite()
**   in order to support window function processing. For example, with the
................................................................................
      windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub);
    }else{
      windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub);
    }
  }
}

#endif /* SQLITE_OMIT_WINDOWFUNC */

Changes to test/pg_common.tcl.

126
127
128
129
130
131
132
133




  puts $::fd ""
}

proc finish_test {} {
  puts $::fd finish_test
  close $::fd
}













>
>
>
>
126
127
128
129
130
131
132
133
134
135
136
137
  puts $::fd ""
}

proc finish_test {} {
  puts $::fd finish_test
  close $::fd
}

proc ifcapable {arg} {
   puts $::fd "ifcapable $arg { finish_test ; return }"
}

Changes to test/window1.test.

11
12
13
14
15
16
17




18
19
20
21
22
23
24
# This file implements regression tests for SQLite library.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix window1






do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c, d);
  INSERT INTO t1 VALUES(1, 2, 3, 4);
  INSERT INTO t1 VALUES(5, 6, 7, 8);
  INSERT INTO t1 VALUES(9, 10, 11, 12);
}







>
>
>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# This file implements regression tests for SQLite library.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix window1

ifcapable !windowfunc {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c, d);
  INSERT INTO t1 VALUES(1, 2, 3, 4);
  INSERT INTO t1 VALUES(5, 6, 7, 8);
  INSERT INTO t1 VALUES(9, 10, 11, 12);
}

Changes to test/window2.tcl.

12
13
14
15
16
17
18


19
20
21
22
23
24
25

source [file join [file dirname $argv0] pg_common.tcl]

#=========================================================================


start_test window2 "2018 May 19"



execsql_test 1.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER);
  INSERT INTO t1 VALUES(1, 'odd',  'one',   1);
  INSERT INTO t1 VALUES(2, 'even', 'two',   2);
  INSERT INTO t1 VALUES(3, 'odd',  'three', 3);







>
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

source [file join [file dirname $argv0] pg_common.tcl]

#=========================================================================


start_test window2 "2018 May 19"

ifcapable !windowfunc

execsql_test 1.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER);
  INSERT INTO t1 VALUES(1, 'odd',  'one',   1);
  INSERT INTO t1 VALUES(2, 'even', 'two',   2);
  INSERT INTO t1 VALUES(3, 'odd',  'three', 3);

Changes to test/window2.test.

15
16
17
18
19
20
21

22
23
24
25
26
27
28
# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED!
####################################################

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix window2


do_execsql_test 1.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER);
  INSERT INTO t1 VALUES(1, 'odd',  'one',   1);
  INSERT INTO t1 VALUES(2, 'even', 'two',   2);
  INSERT INTO t1 VALUES(3, 'odd',  'three', 3);
  INSERT INTO t1 VALUES(4, 'even', 'four',  4);







>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED!
####################################################

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix window2

ifcapable !windowfunc { finish_test ; return }
do_execsql_test 1.0 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER);
  INSERT INTO t1 VALUES(1, 'odd',  'one',   1);
  INSERT INTO t1 VALUES(2, 'even', 'two',   2);
  INSERT INTO t1 VALUES(3, 'odd',  'three', 3);
  INSERT INTO t1 VALUES(4, 'even', 'four',  4);

Changes to test/window3.tcl.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
#

source [file join [file dirname $argv0] pg_common.tcl]

#=========================================================================

start_test window3 "2018 May 31"


execsql_test 1.0 {
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER);
  INSERT INTO t2(a, b) VALUES
  (1,0), (2,74), (3,41), (4,74), (5,23), (6,99), (7,26), (8,33), (9,2),
  (10,89), (11,81), (12,96), (13,59), (14,38), (15,68), (16,39), (17,62),







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#

source [file join [file dirname $argv0] pg_common.tcl]

#=========================================================================

start_test window3 "2018 May 31"
ifcapable !windowfunc

execsql_test 1.0 {
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER);
  INSERT INTO t2(a, b) VALUES
  (1,0), (2,74), (3,41), (4,74), (5,23), (6,99), (7,26), (8,33), (9,2),
  (10,89), (11,81), (12,96), (13,59), (14,38), (15,68), (16,39), (17,62),

Changes to test/window3.test.

cannot compute difference between binary files

Changes to test/window4.tcl.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
#

source [file join [file dirname $argv0] pg_common.tcl]

#=========================================================================

start_test window4 "2018 June 04"


execsql_test 1.0 {
  DROP TABLE IF EXISTS t3;
  CREATE TABLE t3(a TEXT PRIMARY KEY);
  INSERT INTO t3 VALUES('a'), ('b'), ('c'), ('d'), ('e');
  INSERT INTO t3 VALUES('f'), ('g'), ('h'), ('i'), ('j');
}







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#

source [file join [file dirname $argv0] pg_common.tcl]

#=========================================================================

start_test window4 "2018 June 04"
ifcapable !windowfunc

execsql_test 1.0 {
  DROP TABLE IF EXISTS t3;
  CREATE TABLE t3(a TEXT PRIMARY KEY);
  INSERT INTO t3 VALUES('a'), ('b'), ('c'), ('d'), ('e');
  INSERT INTO t3 VALUES('f'), ('g'), ('h'), ('i'), ('j');
}

Changes to test/window4.test.

15
16
17
18
19
20
21

22
23
24
25
26
27
28
# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED!
####################################################

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix window4


do_execsql_test 1.0 {
  DROP TABLE IF EXISTS t3;
  CREATE TABLE t3(a TEXT PRIMARY KEY);
  INSERT INTO t3 VALUES('a'), ('b'), ('c'), ('d'), ('e');
  INSERT INTO t3 VALUES('f'), ('g'), ('h'), ('i'), ('j');
} {}








>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED!
####################################################

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix window4

ifcapable !windowfunc { finish_test ; return }
do_execsql_test 1.0 {
  DROP TABLE IF EXISTS t3;
  CREATE TABLE t3(a TEXT PRIMARY KEY);
  INSERT INTO t3 VALUES('a'), ('b'), ('c'), ('d'), ('e');
  INSERT INTO t3 VALUES('f'), ('g'), ('h'), ('i'), ('j');
} {}

Changes to test/window5.test.

10
11
12
13
14
15
16
17





18
19
20
21
22
23
24
#***********************************************************************
# This file implements regression tests for SQLite library. Specifically,
# it tests the sqlite3_create_window_function() API.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix window1






proc m_step {ctx val} {
  lappend ctx $val
  return $ctx
}
proc m_value {ctx} {
  set lSort [lsort $ctx]







|
>
>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#***********************************************************************
# This file implements regression tests for SQLite library. Specifically,
# it tests the sqlite3_create_window_function() API.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix window5

ifcapable !windowfunc {
  finish_test
  return
}

proc m_step {ctx val} {
  lappend ctx $val
  return $ctx
}
proc m_value {ctx} {
  set lSort [lsort $ctx]

Changes to test/windowfault.test.

11
12
13
14
15
16
17




18
19
20
21
22
23
24
# This file implements regression tests for SQLite library.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix windowfault






do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c, d);
  INSERT INTO t1 VALUES(1, 2, 3, 4);
  INSERT INTO t1 VALUES(5, 6, 7, 8);
  INSERT INTO t1 VALUES(9, 10, 11, 12);
}







>
>
>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# This file implements regression tests for SQLite library.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix windowfault

ifcapable !windowfunc {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c, d);
  INSERT INTO t1 VALUES(1, 2, 3, 4);
  INSERT INTO t1 VALUES(5, 6, 7, 8);
  INSERT INTO t1 VALUES(9, 10, 11, 12);
}

Changes to tool/mkkeywordhash.c.

144
145
146
147
148
149
150





151
152
153
154
155
156
157
...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
...
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
...
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#  define CTE        0x00040000
#endif
#ifdef SQLITE_OMIT_UPSERT
#  define UPSERT     0
#else
#  define UPSERT     0x00080000
#endif






/*
** These are the keywords
*/
static Keyword aKeywordTable[] = {
  { "ABORT",            "TK_ABORT",        CONFLICT|TRIGGER       },
  { "ACTION",           "TK_ACTION",       FKEY                   },
................................................................................
  { "COLLATE",          "TK_COLLATE",      ALWAYS                 },
  { "COLUMN",           "TK_COLUMNKW",     ALTER                  },
  { "COMMIT",           "TK_COMMIT",       ALWAYS                 },
  { "CONFLICT",         "TK_CONFLICT",     CONFLICT               },
  { "CONSTRAINT",       "TK_CONSTRAINT",   ALWAYS                 },
  { "CREATE",           "TK_CREATE",       ALWAYS                 },
  { "CROSS",            "TK_JOIN_KW",      ALWAYS                 },
  { "CURRENT",          "TK_CURRENT",      ALWAYS                 },
  { "CURRENT_DATE",     "TK_CTIME_KW",     ALWAYS                 },
  { "CURRENT_TIME",     "TK_CTIME_KW",     ALWAYS                 },
  { "CURRENT_TIMESTAMP","TK_CTIME_KW",     ALWAYS                 },
  { "DATABASE",         "TK_DATABASE",     ATTACH                 },
  { "DEFAULT",          "TK_DEFAULT",      ALWAYS                 },
  { "DEFERRED",         "TK_DEFERRED",     ALWAYS                 },
  { "DEFERRABLE",       "TK_DEFERRABLE",   FKEY                   },
................................................................................
  { "ELSE",             "TK_ELSE",         ALWAYS                 },
  { "ESCAPE",           "TK_ESCAPE",       ALWAYS                 },
  { "EXCEPT",           "TK_EXCEPT",       COMPOUND               },
  { "EXCLUSIVE",        "TK_EXCLUSIVE",    ALWAYS                 },
  { "EXISTS",           "TK_EXISTS",       ALWAYS                 },
  { "EXPLAIN",          "TK_EXPLAIN",      EXPLAIN                },
  { "FAIL",             "TK_FAIL",         CONFLICT|TRIGGER       },
  { "FILTER",           "TK_FILTER",       ALWAYS                 },
  { "FOLLOWING",        "TK_FOLLOWING",    ALWAYS                 },
  { "FOR",              "TK_FOR",          TRIGGER                },
  { "FOREIGN",          "TK_FOREIGN",      FKEY                   },
  { "FROM",             "TK_FROM",         ALWAYS                 },
  { "FULL",             "TK_JOIN_KW",      ALWAYS                 },
  { "GLOB",             "TK_LIKE_KW",      ALWAYS                 },
  { "GROUP",            "TK_GROUP",        ALWAYS                 },
  { "HAVING",           "TK_HAVING",       ALWAYS                 },
................................................................................
  { "NULL",             "TK_NULL",         ALWAYS                 },
  { "OF",               "TK_OF",           ALWAYS                 },
  { "OFFSET",           "TK_OFFSET",       ALWAYS                 },
  { "ON",               "TK_ON",           ALWAYS                 },
  { "OR",               "TK_OR",           ALWAYS                 },
  { "ORDER",            "TK_ORDER",        ALWAYS                 },
  { "OUTER",            "TK_JOIN_KW",      ALWAYS                 },
  { "OVER",             "TK_OVER",         ALWAYS                 },
  { "PARTITION",        "TK_PARTITION",    ALWAYS                 },
  { "PLAN",             "TK_PLAN",         EXPLAIN                },
  { "PRAGMA",           "TK_PRAGMA",       PRAGMA                 },
  { "PRECEDING",        "TK_PRECEDING",    ALWAYS                 },
  { "PRIMARY",          "TK_PRIMARY",      ALWAYS                 },
  { "QUERY",            "TK_QUERY",        EXPLAIN                },
  { "RAISE",            "TK_RAISE",        TRIGGER                },
  { "RANGE",            "TK_RANGE",        ALWAYS                 },
  { "RECURSIVE",        "TK_RECURSIVE",    CTE                    },
  { "REFERENCES",       "TK_REFERENCES",   FKEY                   },
  { "REGEXP",           "TK_LIKE_KW",      ALWAYS                 },
  { "REINDEX",          "TK_REINDEX",      REINDEX                },
  { "RELEASE",          "TK_RELEASE",      ALWAYS                 },
  { "RENAME",           "TK_RENAME",       ALTER                  },
  { "REPLACE",          "TK_REPLACE",      CONFLICT               },
................................................................................
  { "TABLE",            "TK_TABLE",        ALWAYS                 },
  { "TEMP",             "TK_TEMP",         ALWAYS                 },
  { "TEMPORARY",        "TK_TEMP",         ALWAYS                 },
  { "THEN",             "TK_THEN",         ALWAYS                 },
  { "TO",               "TK_TO",           ALWAYS                 },
  { "TRANSACTION",      "TK_TRANSACTION",  ALWAYS                 },
  { "TRIGGER",          "TK_TRIGGER",      TRIGGER                },
  { "UNBOUNDED",        "TK_UNBOUNDED",    ALWAYS                 },
  { "UNION",            "TK_UNION",        COMPOUND               },
  { "UNIQUE",           "TK_UNIQUE",       ALWAYS                 },
  { "UPDATE",           "TK_UPDATE",       ALWAYS                 },
  { "USING",            "TK_USING",        ALWAYS                 },
  { "VACUUM",           "TK_VACUUM",       VACUUM                 },
  { "VALUES",           "TK_VALUES",       ALWAYS                 },
  { "VIEW",             "TK_VIEW",         VIEW                   },
  { "VIRTUAL",          "TK_VIRTUAL",      VTAB                   },
  { "WINDOW",           "TK_WINDOW",       ALWAYS                 },
  { "WITH",             "TK_WITH",         CTE                    },
  { "WITHOUT",          "TK_WITHOUT",      ALWAYS                 },
  { "WHEN",             "TK_WHEN",         ALWAYS                 },
  { "WHERE",            "TK_WHERE",        ALWAYS                 },
};

/* Number of keywords */







>
>
>
>
>







 







|







 







|
|







 







|
|


|



|







 







|








|







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
...
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
...
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
...
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
...
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
#  define CTE        0x00040000
#endif
#ifdef SQLITE_OMIT_UPSERT
#  define UPSERT     0
#else
#  define UPSERT     0x00080000
#endif
#ifdef SQLITE_OMIT_WINDOWFUNC
#  define WINDOWFUNC 0
#else
#  define WINDOWFUNC 0x00100000
#endif

/*
** These are the keywords
*/
static Keyword aKeywordTable[] = {
  { "ABORT",            "TK_ABORT",        CONFLICT|TRIGGER       },
  { "ACTION",           "TK_ACTION",       FKEY                   },
................................................................................
  { "COLLATE",          "TK_COLLATE",      ALWAYS                 },
  { "COLUMN",           "TK_COLUMNKW",     ALTER                  },
  { "COMMIT",           "TK_COMMIT",       ALWAYS                 },
  { "CONFLICT",         "TK_CONFLICT",     CONFLICT               },
  { "CONSTRAINT",       "TK_CONSTRAINT",   ALWAYS                 },
  { "CREATE",           "TK_CREATE",       ALWAYS                 },
  { "CROSS",            "TK_JOIN_KW",      ALWAYS                 },
  { "CURRENT",          "TK_CURRENT",      WINDOWFUNC             },
  { "CURRENT_DATE",     "TK_CTIME_KW",     ALWAYS                 },
  { "CURRENT_TIME",     "TK_CTIME_KW",     ALWAYS                 },
  { "CURRENT_TIMESTAMP","TK_CTIME_KW",     ALWAYS                 },
  { "DATABASE",         "TK_DATABASE",     ATTACH                 },
  { "DEFAULT",          "TK_DEFAULT",      ALWAYS                 },
  { "DEFERRED",         "TK_DEFERRED",     ALWAYS                 },
  { "DEFERRABLE",       "TK_DEFERRABLE",   FKEY                   },
................................................................................
  { "ELSE",             "TK_ELSE",         ALWAYS                 },
  { "ESCAPE",           "TK_ESCAPE",       ALWAYS                 },
  { "EXCEPT",           "TK_EXCEPT",       COMPOUND               },
  { "EXCLUSIVE",        "TK_EXCLUSIVE",    ALWAYS                 },
  { "EXISTS",           "TK_EXISTS",       ALWAYS                 },
  { "EXPLAIN",          "TK_EXPLAIN",      EXPLAIN                },
  { "FAIL",             "TK_FAIL",         CONFLICT|TRIGGER       },
  { "FILTER",           "TK_FILTER",       WINDOWFUNC             },
  { "FOLLOWING",        "TK_FOLLOWING",    WINDOWFUNC             },
  { "FOR",              "TK_FOR",          TRIGGER                },
  { "FOREIGN",          "TK_FOREIGN",      FKEY                   },
  { "FROM",             "TK_FROM",         ALWAYS                 },
  { "FULL",             "TK_JOIN_KW",      ALWAYS                 },
  { "GLOB",             "TK_LIKE_KW",      ALWAYS                 },
  { "GROUP",            "TK_GROUP",        ALWAYS                 },
  { "HAVING",           "TK_HAVING",       ALWAYS                 },
................................................................................
  { "NULL",             "TK_NULL",         ALWAYS                 },
  { "OF",               "TK_OF",           ALWAYS                 },
  { "OFFSET",           "TK_OFFSET",       ALWAYS                 },
  { "ON",               "TK_ON",           ALWAYS                 },
  { "OR",               "TK_OR",           ALWAYS                 },
  { "ORDER",            "TK_ORDER",        ALWAYS                 },
  { "OUTER",            "TK_JOIN_KW",      ALWAYS                 },
  { "OVER",             "TK_OVER",         WINDOWFUNC             },
  { "PARTITION",        "TK_PARTITION",    WINDOWFUNC             },
  { "PLAN",             "TK_PLAN",         EXPLAIN                },
  { "PRAGMA",           "TK_PRAGMA",       PRAGMA                 },
  { "PRECEDING",        "TK_PRECEDING",    WINDOWFUNC             },
  { "PRIMARY",          "TK_PRIMARY",      ALWAYS                 },
  { "QUERY",            "TK_QUERY",        EXPLAIN                },
  { "RAISE",            "TK_RAISE",        TRIGGER                },
  { "RANGE",            "TK_RANGE",        WINDOWFUNC             },
  { "RECURSIVE",        "TK_RECURSIVE",    CTE                    },
  { "REFERENCES",       "TK_REFERENCES",   FKEY                   },
  { "REGEXP",           "TK_LIKE_KW",      ALWAYS                 },
  { "REINDEX",          "TK_REINDEX",      REINDEX                },
  { "RELEASE",          "TK_RELEASE",      ALWAYS                 },
  { "RENAME",           "TK_RENAME",       ALTER                  },
  { "REPLACE",          "TK_REPLACE",      CONFLICT               },
................................................................................
  { "TABLE",            "TK_TABLE",        ALWAYS                 },
  { "TEMP",             "TK_TEMP",         ALWAYS                 },
  { "TEMPORARY",        "TK_TEMP",         ALWAYS                 },
  { "THEN",             "TK_THEN",         ALWAYS                 },
  { "TO",               "TK_TO",           ALWAYS                 },
  { "TRANSACTION",      "TK_TRANSACTION",  ALWAYS                 },
  { "TRIGGER",          "TK_TRIGGER",      TRIGGER                },
  { "UNBOUNDED",        "TK_UNBOUNDED",    WINDOWFUNC             },
  { "UNION",            "TK_UNION",        COMPOUND               },
  { "UNIQUE",           "TK_UNIQUE",       ALWAYS                 },
  { "UPDATE",           "TK_UPDATE",       ALWAYS                 },
  { "USING",            "TK_USING",        ALWAYS                 },
  { "VACUUM",           "TK_VACUUM",       VACUUM                 },
  { "VALUES",           "TK_VALUES",       ALWAYS                 },
  { "VIEW",             "TK_VIEW",         VIEW                   },
  { "VIRTUAL",          "TK_VIRTUAL",      VTAB                   },
  { "WINDOW",           "TK_WINDOW",       WINDOWFUNC             },
  { "WITH",             "TK_WITH",         CTE                    },
  { "WITHOUT",          "TK_WITHOUT",      ALWAYS                 },
  { "WHEN",             "TK_WHEN",         ALWAYS                 },
  { "WHERE",            "TK_WHERE",        ALWAYS                 },
};

/* Number of keywords */