/ Check-in [a568f9c9]
Login

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

Overview
Comment:Simplification to the grammar rules for window functions. Fix a memory leak that can follow an OOM while parsing a comma-separated list of window definitions.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a568f9c9db594f3b194c6e870305c9d6f2392ce6bc8ac00e9688883e97560fff
User & Date: drh 2018-07-09 16:24:00
Context
2018-07-09
17:33
Remove redundant branches in window function processing. check-in: 8fdaf3f3 user: drh tags: trunk
16:24
Simplification to the grammar rules for window functions. Fix a memory leak that can follow an OOM while parsing a comma-separated list of window definitions. check-in: a568f9c9 user: drh tags: trunk
13:31
Throw an error if the second argument passed to nth_value() is not a positive integer. check-in: 1a06e57a user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/parse.y.

  1601   1601   // These must be at the end of this file. Specifically, the rules that
  1602   1602   // introduce tokens WINDOW, OVER and FILTER must appear last. This causes 
  1603   1603   // the integer values assigned to these tokens to be larger than all other 
  1604   1604   // tokens that may be output by the tokenizer except TK_SPACE and TK_ILLEGAL.
  1605   1605   //
  1606   1606   %ifndef SQLITE_OMIT_WINDOWFUNC
  1607   1607   %type windowdefn_list {Window*}
  1608         -%destructor windowdefn_list {sqlite3WindowDelete(pParse->db, $$);}
         1608  +%destructor windowdefn_list {sqlite3WindowListDelete(pParse->db, $$);}
  1609   1609   windowdefn_list(A) ::= windowdefn(Z). { A = Z; }
  1610   1610   windowdefn_list(A) ::= windowdefn_list(Y) COMMA windowdefn(Z). {
  1611         -  if( Z ) Z->pNextWin = Y;
         1611  +  assert( Z!=0 );
         1612  +  Z->pNextWin = Y;
  1612   1613     A = Z;
  1613   1614   }
  1614   1615   
  1615   1616   %type windowdefn {Window*}
  1616   1617   %destructor windowdefn {sqlite3WindowDelete(pParse->db, $$);}
  1617   1618   windowdefn(A) ::= nm(X) AS window(Y). {
  1618         -  if( Y ){
         1619  +  if( ALWAYS(Y) ){
  1619   1620       Y->zName = sqlite3DbStrNDup(pParse->db, X.z, X.n);
  1620   1621     }
  1621   1622     A = Y;
  1622   1623   }
  1623   1624   
  1624   1625   %type window {Window*}
  1625   1626   %destructor window {sqlite3WindowDelete(pParse->db, $$);}
  1626   1627   
  1627   1628   %type frame_opt {Window*}
  1628   1629   %destructor frame_opt {sqlite3WindowDelete(pParse->db, $$);}
  1629   1630   
  1630         -%type window_or_nm {Window*}
  1631         -%destructor window_or_nm {
  1632         -sqlite3WindowDelete(pParse->db, $$);}
  1633         -
  1634   1631   %type part_opt {ExprList*}
  1635   1632   %destructor part_opt {sqlite3ExprListDelete(pParse->db, $$);}
  1636   1633   
  1637   1634   %type filter_opt {Expr*}
  1638   1635   %destructor filter_opt {sqlite3ExprDelete(pParse->db, $$);}
  1639   1636   
  1640   1637   %type range_or_rows {int}
................................................................................
  1642   1639   %type frame_bound {struct FrameBound}
  1643   1640   %destructor frame_bound {sqlite3ExprDelete(pParse->db, $$.pExpr);}
  1644   1641   %type frame_bound_s {struct FrameBound}
  1645   1642   %destructor frame_bound_s {sqlite3ExprDelete(pParse->db, $$.pExpr);}
  1646   1643   %type frame_bound_e {struct FrameBound}
  1647   1644   %destructor frame_bound_e {sqlite3ExprDelete(pParse->db, $$.pExpr);}
  1648   1645   
  1649         -window_or_nm(A) ::= window(Z). {A = Z;}
  1650         -window_or_nm(A) ::= nm(Z). {
  1651         -  A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  1652         -  if( A ){
  1653         -    A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n);
  1654         -  }
  1655         -}
  1656         -
  1657   1646   window(A) ::= LP part_opt(X) orderby_opt(Y) frame_opt(Z) RP. {
  1658   1647     A = Z;
  1659         -  if( A ){
         1648  +  if( ALWAYS(A) ){
  1660   1649       A->pPartition = X;
  1661   1650       A->pOrderBy = Y;
  1662   1651     }
  1663   1652   }
  1664   1653   
  1665   1654   part_opt(A) ::= PARTITION BY exprlist(X). { A = X; }
  1666   1655   part_opt(A) ::= .                         { A = 0; }
................................................................................
  1685   1674   frame_bound_e(A) ::= UNBOUNDED FOLLOWING. {A.eType = TK_UNBOUNDED; A.pExpr = 0;}
  1686   1675   
  1687   1676   frame_bound(A) ::= expr(X) PRECEDING.   { A.eType = TK_PRECEDING; A.pExpr = X; }
  1688   1677   frame_bound(A) ::= CURRENT ROW.         { A.eType = TK_CURRENT  ; A.pExpr = 0; }
  1689   1678   frame_bound(A) ::= expr(X) FOLLOWING.   { A.eType = TK_FOLLOWING; A.pExpr = X; }
  1690   1679   
  1691   1680   %type windowdefn_opt {Window*}
  1692         -%destructor windowdefn_opt {sqlite3WindowDelete(pParse->db, $$);}
         1681  +%destructor windowdefn_opt {sqlite3WindowListDelete(pParse->db, $$);}
  1693   1682   windowdefn_opt(A) ::= . { A = 0; }
  1694   1683   windowdefn_opt(A) ::= WINDOW windowdefn_list(B). { A = B; }
  1695   1684   
  1696   1685   %type over_opt {Window*}
  1697   1686   %destructor over_opt {sqlite3WindowDelete(pParse->db, $$);}
  1698   1687   over_opt(A) ::= . { A = 0; }
  1699         -over_opt(A) ::= filter_opt(W) OVER window_or_nm(Z). {
         1688  +over_opt(A) ::= filter_opt(W) OVER window(Z). {
  1700   1689     A = Z;
  1701         -  if( A ) A->pFilter = W;
         1690  +  assert( A!=0 );
         1691  +  A->pFilter = W;
         1692  +}
         1693  +over_opt(A) ::= filter_opt(W) OVER nm(Z). {
         1694  +  A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
         1695  +  if( A ){
         1696  +    A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n);
         1697  +    A->pFilter = W;
         1698  +  }else{
         1699  +    sqlite3ExprDelete(pParse->db, W);
         1700  +  }
  1702   1701   }
  1703   1702   
  1704   1703   filter_opt(A) ::= .                            { A = 0; }
  1705   1704   filter_opt(A) ::= FILTER LP WHERE expr(X) RP.  { A = X; }
  1706   1705   %endif // SQLITE_OMIT_WINDOWFUNC
  1707         -