/ Check-in [5eb47765]
Login

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

Overview
Comment:Further performance related tweaks for sqlite3RunParser().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | weak-fallback
Files: files | file ages | folders
SHA3-256:5eb4776598f5bba7ef21a2c58c03105544da73d642d7ffc146f84eff1993d71e
User & Date: dan 2018-06-29 20:43:33
Context
2018-06-30
18:54
Have the tokenizer handle fallback for tokens "OVER" and "FILTER" in the same way as it does for "WINDOW". Leaf check-in: 12d819e1 user: dan tags: weak-fallback
2018-06-29
20:43
Further performance related tweaks for sqlite3RunParser(). check-in: 5eb47765 user: dan tags: weak-fallback
20:21
Further tweaks to sqlite3RunParser(). check-in: eef61ffa user: dan tags: weak-fallback
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/parse.y.

  1042   1042     A = sqlite3ExprFunction(pParse, 0, &X);
  1043   1043     sqlite3WindowAttach(pParse, A, Z);
  1044   1044   }
  1045   1045   term(A) ::= CTIME_KW(OP). {
  1046   1046     A = sqlite3ExprFunction(pParse, 0, &OP);
  1047   1047   }
  1048   1048   
  1049         -%ifndef SQLITE_OMIT_WINDOWFUNC
  1050         -
  1051         -%type windowdefn_opt {Window*}
  1052         -%destructor windowdefn_opt {sqlite3WindowDelete(pParse->db, $$);}
  1053         -windowdefn_opt(A) ::= . { A = 0; }
  1054         -windowdefn_opt(A) ::= WINDOW windowdefn_list(B). { A = B; }
  1055         -
  1056         -%type windowdefn_list {Window*}
  1057         -%destructor windowdefn_list {sqlite3WindowDelete(pParse->db, $$);}
  1058         -windowdefn_list(A) ::= windowdefn(Z). { A = Z; }
  1059         -windowdefn_list(A) ::= windowdefn_list(Y) COMMA windowdefn(Z). {
  1060         -  if( Z ) Z->pNextWin = Y;
  1061         -  A = Z;
  1062         -}
  1063         -
  1064         -%type windowdefn {Window*}
  1065         -%destructor windowdefn {sqlite3WindowDelete(pParse->db, $$);}
  1066         -windowdefn(A) ::= nm(X) AS window(Y). {
  1067         -  if( Y ){
  1068         -    Y->zName = sqlite3DbStrNDup(pParse->db, X.z, X.n);
  1069         -  }
  1070         -  A = Y;
  1071         -}
  1072         -
  1073         -%type over_opt {Window*}
  1074         -%destructor over_opt {sqlite3WindowDelete(pParse->db, $$);}
  1075         -
  1076         -%type window {Window*}
  1077         -%destructor window {sqlite3WindowDelete(pParse->db, $$);}
  1078         -
  1079         -%type frame_opt {Window*}
  1080         -%destructor frame_opt {sqlite3WindowDelete(pParse->db, $$);}
  1081         -
  1082         -%type window_or_nm {Window*}
  1083         -%destructor window_or_nm {
  1084         -sqlite3WindowDelete(pParse->db, $$);}
  1085         -
  1086         -%type part_opt {ExprList*}
  1087         -%destructor part_opt {sqlite3ExprListDelete(pParse->db, $$);}
  1088         -
  1089         -%type filter_opt {Expr*}
  1090         -%destructor filter_opt {sqlite3ExprDelete(pParse->db, $$);}
  1091         -
  1092         -%type range_or_rows {int}
  1093         -
  1094         -%type frame_bound {struct FrameBound}
  1095         -%destructor frame_bound {sqlite3ExprDelete(pParse->db, $$.pExpr);}
  1096         -
  1097         -over_opt(A) ::= . { A = 0; }
  1098         -over_opt(A) ::= filter_opt(W) OVER window_or_nm(Z). {
  1099         -  A = Z;
  1100         -  if( A ) A->pFilter = W;
  1101         -}
  1102         -
  1103         -window_or_nm(A) ::= window(Z). {A = Z;}
  1104         -window_or_nm(A) ::= nm(Z). {
  1105         -  A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  1106         -  if( A ){
  1107         -    A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n);
  1108         -  }
  1109         -}
  1110         -
  1111         -window(A) ::= LP part_opt(X) orderby_opt(Y) frame_opt(Z) RP. {
  1112         -  A = Z;
  1113         -  if( A ){
  1114         -    A->pPartition = X;
  1115         -    A->pOrderBy = Y;
  1116         -  }
  1117         -}
  1118         -
  1119         -part_opt(A) ::= PARTITION BY exprlist(X). { A = X; }
  1120         -part_opt(A) ::= .                         { A = 0; }
  1121         -filter_opt(A) ::= .                            { A = 0; }
  1122         -filter_opt(A) ::= FILTER LP WHERE expr(X) RP.  { A = X; }
  1123         -
  1124         -frame_opt(A) ::= .                             { 
  1125         -  A = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
  1126         -}
  1127         -frame_opt(A) ::= range_or_rows(X) frame_bound(Y). { 
  1128         -  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, TK_CURRENT, 0);
  1129         -}
  1130         -frame_opt(A) ::= range_or_rows(X) BETWEEN frame_bound(Y) AND frame_bound(Z). { 
  1131         -  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, Z.eType, Z.pExpr);
  1132         -}
  1133         -
  1134         -range_or_rows(A) ::= RANGE.   { A = TK_RANGE; }
  1135         -range_or_rows(A) ::= ROWS.    { A = TK_ROWS;  }
  1136         -
  1137         -frame_bound(A) ::= UNBOUNDED PRECEDING. { A.eType = TK_UNBOUNDED; A.pExpr = 0; }
  1138         -frame_bound(A) ::= expr(X) PRECEDING.   { A.eType = TK_PRECEDING; A.pExpr = X; }
  1139         -frame_bound(A) ::= CURRENT ROW.         { A.eType = TK_CURRENT  ; A.pExpr = 0; }
  1140         -frame_bound(A) ::= expr(X) FOLLOWING.   { A.eType = TK_FOLLOWING; A.pExpr = X; }
  1141         -frame_bound(A) ::= UNBOUNDED FOLLOWING. { A.eType = TK_UNBOUNDED; A.pExpr = 0; }
  1142         -
  1143         -%endif // SQLITE_OMIT_WINDOWFUNC
  1144         -
  1145   1049   expr(A) ::= LP nexprlist(X) COMMA expr(Y) RP. {
  1146   1050     ExprList *pList = sqlite3ExprListAppend(pParse, X, Y);
  1147   1051     A = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
  1148   1052     if( A ){
  1149   1053       A->x.pList = pList;
  1150   1054     }else{
  1151   1055       sqlite3ExprListDelete(pParse->db, pList);
................................................................................
  1689   1593   wqlist(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
  1690   1594     A = sqlite3WithAdd(pParse, 0, &X, Y, Z); /*A-overwrites-X*/
  1691   1595   }
  1692   1596   wqlist(A) ::= wqlist(A) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
  1693   1597     A = sqlite3WithAdd(pParse, A, &X, Y, Z);
  1694   1598   }
  1695   1599   %endif  SQLITE_OMIT_CTE
         1600  +
         1601  +//////////////////////// WINDOW FUNCTION EXPRESSIONS /////////////////////////
         1602  +// These must be at the end of this file. Specifically, the windowdefn_opt
         1603  +// rule must be the very last in the file. This causes the integer value
         1604  +// assigned to the TK_WINDOW token to be larger than all other tokens that
         1605  +// may be output by the tokenizer except TK_SPACE and TK_ILLEGAL.
         1606  +//
         1607  +%ifndef SQLITE_OMIT_WINDOWFUNC
         1608  +%type windowdefn_list {Window*}
         1609  +%destructor windowdefn_list {sqlite3WindowDelete(pParse->db, $$);}
         1610  +windowdefn_list(A) ::= windowdefn(Z). { A = Z; }
         1611  +windowdefn_list(A) ::= windowdefn_list(Y) COMMA windowdefn(Z). {
         1612  +  if( Z ) Z->pNextWin = Y;
         1613  +  A = Z;
         1614  +}
         1615  +
         1616  +%type windowdefn {Window*}
         1617  +%destructor windowdefn {sqlite3WindowDelete(pParse->db, $$);}
         1618  +windowdefn(A) ::= nm(X) AS window(Y). {
         1619  +  if( Y ){
         1620  +    Y->zName = sqlite3DbStrNDup(pParse->db, X.z, X.n);
         1621  +  }
         1622  +  A = Y;
         1623  +}
         1624  +
         1625  +%type over_opt {Window*}
         1626  +%destructor over_opt {sqlite3WindowDelete(pParse->db, $$);}
         1627  +
         1628  +%type window {Window*}
         1629  +%destructor window {sqlite3WindowDelete(pParse->db, $$);}
         1630  +
         1631  +%type frame_opt {Window*}
         1632  +%destructor frame_opt {sqlite3WindowDelete(pParse->db, $$);}
         1633  +
         1634  +%type window_or_nm {Window*}
         1635  +%destructor window_or_nm {
         1636  +sqlite3WindowDelete(pParse->db, $$);}
         1637  +
         1638  +%type part_opt {ExprList*}
         1639  +%destructor part_opt {sqlite3ExprListDelete(pParse->db, $$);}
         1640  +
         1641  +%type filter_opt {Expr*}
         1642  +%destructor filter_opt {sqlite3ExprDelete(pParse->db, $$);}
         1643  +
         1644  +%type range_or_rows {int}
         1645  +
         1646  +%type frame_bound {struct FrameBound}
         1647  +%destructor frame_bound {sqlite3ExprDelete(pParse->db, $$.pExpr);}
         1648  +
         1649  +over_opt(A) ::= . { A = 0; }
         1650  +over_opt(A) ::= filter_opt(W) OVER window_or_nm(Z). {
         1651  +  A = Z;
         1652  +  if( A ) A->pFilter = W;
         1653  +}
         1654  +
         1655  +window_or_nm(A) ::= window(Z). {A = Z;}
         1656  +window_or_nm(A) ::= nm(Z). {
         1657  +  A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
         1658  +  if( A ){
         1659  +    A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n);
         1660  +  }
         1661  +}
         1662  +
         1663  +window(A) ::= LP part_opt(X) orderby_opt(Y) frame_opt(Z) RP. {
         1664  +  A = Z;
         1665  +  if( A ){
         1666  +    A->pPartition = X;
         1667  +    A->pOrderBy = Y;
         1668  +  }
         1669  +}
         1670  +
         1671  +part_opt(A) ::= PARTITION BY exprlist(X). { A = X; }
         1672  +part_opt(A) ::= .                         { A = 0; }
         1673  +filter_opt(A) ::= .                            { A = 0; }
         1674  +filter_opt(A) ::= FILTER LP WHERE expr(X) RP.  { A = X; }
         1675  +
         1676  +frame_opt(A) ::= .                             { 
         1677  +  A = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
         1678  +}
         1679  +frame_opt(A) ::= range_or_rows(X) frame_bound(Y). { 
         1680  +  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, TK_CURRENT, 0);
         1681  +}
         1682  +frame_opt(A) ::= range_or_rows(X) BETWEEN frame_bound(Y) AND frame_bound(Z). { 
         1683  +  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, Z.eType, Z.pExpr);
         1684  +}
         1685  +
         1686  +range_or_rows(A) ::= RANGE.   { A = TK_RANGE; }
         1687  +range_or_rows(A) ::= ROWS.    { A = TK_ROWS;  }
         1688  +
         1689  +frame_bound(A) ::= UNBOUNDED PRECEDING. { A.eType = TK_UNBOUNDED; A.pExpr = 0; }
         1690  +frame_bound(A) ::= expr(X) PRECEDING.   { A.eType = TK_PRECEDING; A.pExpr = X; }
         1691  +frame_bound(A) ::= CURRENT ROW.         { A.eType = TK_CURRENT  ; A.pExpr = 0; }
         1692  +frame_bound(A) ::= expr(X) FOLLOWING.   { A.eType = TK_FOLLOWING; A.pExpr = X; }
         1693  +frame_bound(A) ::= UNBOUNDED FOLLOWING. { A.eType = TK_UNBOUNDED; A.pExpr = 0; }
         1694  +
         1695  +%type windowdefn_opt {Window*}
         1696  +%destructor windowdefn_opt {sqlite3WindowDelete(pParse->db, $$);}
         1697  +windowdefn_opt(A) ::= . { A = 0; }
         1698  +windowdefn_opt(A) ::= WINDOW windowdefn_list(B). { A = B; }
         1699  +%endif // SQLITE_OMIT_WINDOWFUNC
         1700  +

Changes to src/resolve.c.

   794    794           pNC->nErr++;
   795    795         }else if( wrong_num_args ){
   796    796           sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
   797    797                nId, zId);
   798    798           pNC->nErr++;
   799    799         }
   800    800         if( is_agg ){
          801  +#ifndef SQLITE_OMIT_WINDOWFUNC
   801    802           pNC->ncFlags &= ~(pExpr->pWin ? NC_AllowWin : NC_AllowAgg);
          803  +#else
          804  +        pNC->ncFlags &= ~NC_AllowAgg;
          805  +#endif
   802    806         }
   803    807         sqlite3WalkExprList(pWalker, pList);
   804    808         if( is_agg ){
   805    809   #ifndef SQLITE_OMIT_WINDOWFUNC
   806    810           if( pExpr->pWin ){
   807    811             Select *pSel = pNC->pWinSelect;
   808    812             sqlite3WalkExprList(pWalker, pExpr->pWin->pPartition);

Changes to src/tokenize.c.

   184    184   #endif
   185    185   
   186    186   /* Make the IdChar function accessible from ctime.c */
   187    187   #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
   188    188   int sqlite3IsIdChar(u8 c){ return IdChar(c); }
   189    189   #endif
   190    190   
          191  +#ifndef SQLITE_OMIT_WINDOWFUNC
   191    192   /*
   192    193   ** Return the id of the next token in string (*pz). Before returning, set
   193    194   ** (*pz) to point to the byte following the parsed token.
   194    195   **
   195    196   ** This function assumes that any keywords that start with "w" are 
   196    197   ** actually TK_ID.
   197    198   */
................................................................................
   203    204       ret = TK_ID;
   204    205     }else{
   205    206       z += sqlite3GetToken(z, &ret);
   206    207     }
   207    208     *pz = z;
   208    209     return ret;
   209    210   }
          211  +#endif // SQLITE_OMIT_WINDOWFUNC
   210    212   
          213  +#ifndef SQLITE_OMIT_WINDOWFUNC
   211    214   /*
   212    215   ** The tokenizer has just parsed the keyword WINDOW. In this case the token
   213    216   ** may really be the keyword (TK_WINDOW), or may be an identifier (TK_ID).
   214    217   ** This function determines which it is by inspecting the next two tokens
   215    218   ** in the input stream. Specifically, the token is TK_WINDOW if the following
   216    219   ** two tokens are:
   217    220   **
................................................................................
   234    237       while( (t = windowGetToken(&z))==TK_SPACE );
   235    238       if( t!=TK_AS ){
   236    239         ret = TK_ID;
   237    240       }
   238    241     }
   239    242     return ret;
   240    243   }
          244  +#endif // SQLITE_OMIT_WINDOWFUNC
   241    245   
   242    246   /*
   243    247   ** Return the length (in bytes) of the token that begins at z[0]. 
   244    248   ** Store the token type in *tokenType before returning.
   245    249   */
   246    250   int sqlite3GetToken(const unsigned char *z, int *tokenType){
   247    251     int i, c;
................................................................................
   561    565     while( 1 ){
   562    566       n = sqlite3GetToken((u8*)zSql, &tokenType);
   563    567       mxSqlLen -= n;
   564    568       if( mxSqlLen<0 ){
   565    569         pParse->rc = SQLITE_TOOBIG;
   566    570         break;
   567    571       }
          572  +#ifndef SQLITE_OMIT_WINDOWFUNC
          573  +    if( tokenType>=TK_WINDOW ){
          574  +      assert( tokenType==TK_SPACE 
          575  +           || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW 
          576  +      );
          577  +#else
   568    578       if( tokenType>=TK_SPACE ){
   569    579         assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
          580  +#endif // SQLITE_OMIT_WINDOWFUNC
   570    581         if( db->u1.isInterrupted ){
   571    582           pParse->rc = SQLITE_INTERRUPT;
   572    583           break;
   573    584         }
   574    585         if( tokenType==TK_SPACE ){
   575    586           zSql += n;
   576    587           continue;
................................................................................
   582    593             tokenType = 0;
   583    594           }else if( lastTokenParsed==0 ){
   584    595             break;
   585    596           }else{
   586    597             tokenType = TK_SEMI;
   587    598           }
   588    599           n = 0;
          600  +#ifndef SQLITE_OMIT_WINDOWFUNC
          601  +      }else if( tokenType==TK_WINDOW ){
          602  +        tokenType = analyzeWindowKeyword((const u8*)&zSql[6]);
          603  +#endif // SQLITE_OMIT_WINDOWFUNC
   589    604         }else{
   590    605           sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
   591    606           break;
   592    607         }
   593    608       }
   594         -    else if( tokenType==TK_WINDOW ){
   595         -      tokenType = analyzeWindowKeyword((const u8*)&zSql[6]);
   596         -    }
   597    609       pParse->sLastToken.z = zSql;
   598    610       pParse->sLastToken.n = n;
   599    611       sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
   600    612       lastTokenParsed = tokenType;
   601    613       zSql += n;
   602    614       if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
   603    615     }