/ Check-in [02204f8b]
Login

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

Overview
Comment:Improvements to the parser to increase coverage. Fix the parser so that at least one expresssion is required after PARTITION BY and within the list of expressions on VALUES().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 02204f8b246c868846f39bd44f2e3bc0fab0275aa09ef3a0e5a8e3d58f484ca8
User & Date: drh 2018-07-27 23:33:16
Context
2018-07-28
14:34
Improved debugging output when the ".selecttrace" option is used in the shell. check-in: fcb88dd6 user: drh tags: trunk
01:30
Add assert() statements to sqlite3ExprDelete() that prove various symmetry properties of the Expr object that might be exploited to make the Expr object smaller and faster. check-in: 81f25d5c user: drh tags: expr-simplify
2018-07-27
23:33
Improvements to the parser to increase coverage. Fix the parser so that at least one expresssion is required after PARTITION BY and within the list of expressions on VALUES(). check-in: 02204f8b user: drh tags: trunk
22:55
When doing a DROP VIEW do not try to delete entries from the sqlite_stat1 table as there are none. check-in: 7efdba2b user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

937
938
939
940
941
942
943
944





945
946
947
948
949
950
951
952



953
954
955
956

957
958
959
960
961
962
963
  }
}

/*
** Construct a new expression node for a function with multiple
** arguments.
*/
Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){





  Expr *pNew;
  sqlite3 *db = pParse->db;
  assert( pToken );
  pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
  if( pNew==0 ){
    sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
    return 0;
  }



  pNew->x.pList = pList;
  ExprSetProperty(pNew, EP_HasFunc);
  assert( !ExprHasProperty(pNew, EP_xIsSelect) );
  sqlite3ExprSetHeightAndFlags(pParse, pNew);

  return pNew;
}

/*
** Assign a variable number to an expression that encodes a wildcard
** in the original SQL statement.  
**







|
>
>
>
>
>








>
>
>




>







937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
  }
}

/*
** Construct a new expression node for a function with multiple
** arguments.
*/
Expr *sqlite3ExprFunction(
  Parse *pParse,        /* Parsing context */
  ExprList *pList,      /* Argument list */
  Token *pToken,        /* Name of the function */
  int eDistinct         /* SF_Distinct or SF_ALL or 0 */
){
  Expr *pNew;
  sqlite3 *db = pParse->db;
  assert( pToken );
  pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
  if( pNew==0 ){
    sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
    return 0;
  }
  if( pList && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
    sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
  }
  pNew->x.pList = pList;
  ExprSetProperty(pNew, EP_HasFunc);
  assert( !ExprHasProperty(pNew, EP_xIsSelect) );
  sqlite3ExprSetHeightAndFlags(pParse, pNew);
  if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct);
  return pNew;
}

/*
** Assign a variable number to an expression that encodes a wildcard
** in the original SQL statement.  
**

Changes to src/parse.y.

554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
...
997
998
999
1000
1001
1002
1003
1004
1005
1006
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
1038
1039
1040
1041
....
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
....
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
oneselect(A) ::= values(A).

%type values {Select*}
%destructor values {sqlite3SelectDelete(pParse->db, $$);}
values(A) ::= VALUES LP nexprlist(X) RP. {
  A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0);
}
values(A) ::= values(A) COMMA LP exprlist(Y) RP. {
  Select *pRight, *pLeft = A;
  pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0);
  if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
  if( pRight ){
    pRight->op = TK_ALL;
    pRight->pPrior = pLeft;
    A = pRight;
................................................................................
  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. {
  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);
  if( D==SF_Distinct && A ){
    A->flags |= EP_Distinct;
  }
}
expr(A) ::= id(X) LP STAR RP. {
  A = sqlite3ExprFunction(pParse, 0, &X);
}

%ifndef SQLITE_OMIT_WINDOWFUNC
expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP over_clause(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);
  if( D==SF_Distinct && A ){
    A->flags |= EP_Distinct;
  }
  sqlite3WindowAttach(pParse, A, Z);
}
expr(A) ::= id(X) LP STAR RP over_clause(Z). {
  A = sqlite3ExprFunction(pParse, 0, &X);
  sqlite3WindowAttach(pParse, A, Z);
}
%endif

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

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;
................................................................................
likeop(A) ::= NOT LIKE_KW|MATCH(X). {A=X; A.n|=0x80000000; /*A-overwrite-X*/}
expr(A) ::= expr(A) likeop(OP) expr(Y).  [LIKE_KW]  {
  ExprList *pList;
  int bNot = OP.n & 0x80000000;
  OP.n &= 0x7fffffff;
  pList = sqlite3ExprListAppend(pParse,0, Y);
  pList = sqlite3ExprListAppend(pParse,pList, A);
  A = sqlite3ExprFunction(pParse, pList, &OP);
  if( bNot ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
  if( A ) A->flags |= EP_InfixFunc;
}
expr(A) ::= expr(A) likeop(OP) expr(Y) ESCAPE expr(E).  [LIKE_KW]  {
  ExprList *pList;
  int bNot = OP.n & 0x80000000;
  OP.n &= 0x7fffffff;
  pList = sqlite3ExprListAppend(pParse,0, Y);
  pList = sqlite3ExprListAppend(pParse,pList, A);
  pList = sqlite3ExprListAppend(pParse,pList, E);
  A = sqlite3ExprFunction(pParse, pList, &OP);
  if( bNot ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
  if( A ) A->flags |= EP_InfixFunc;
}

expr(A) ::= expr(A) ISNULL|NOTNULL(E).   {A = sqlite3PExpr(pParse,@E,A,0);}
expr(A) ::= expr(A) NOT NULL.    {A = sqlite3PExpr(pParse,TK_NOTNULL,A,0);}

................................................................................
  A = Z;
  if( ALWAYS(A) ){
    A->pPartition = X;
    A->pOrderBy = Y;
  }
}

part_opt(A) ::= PARTITION BY exprlist(X). { A = X; }
part_opt(A) ::= .                         { A = 0; }

frame_opt(A) ::= .                             { 
  A = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
}
frame_opt(A) ::= range_or_rows(X) frame_bound_s(Y). { 
  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, TK_CURRENT, 0);
}







|







 







<
<
<
|
<
<
|
<

|




<
<
<
|
<
<
<



|





|







 







|










|







 







|
|







554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
...
997
998
999
1000
1001
1002
1003



1004


1005

1006
1007
1008
1009
1010
1011



1012



1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
....
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
....
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
oneselect(A) ::= values(A).

%type values {Select*}
%destructor values {sqlite3SelectDelete(pParse->db, $$);}
values(A) ::= VALUES LP nexprlist(X) RP. {
  A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0);
}
values(A) ::= values(A) COMMA LP nexprlist(Y) RP. {
  Select *pRight, *pLeft = A;
  pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0);
  if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
  if( pRight ){
    pRight->op = TK_ALL;
    pRight->pPrior = pLeft;
    A = pRight;
................................................................................
  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. {



  A = sqlite3ExprFunction(pParse, Y, &X, D);


}

expr(A) ::= id(X) LP STAR RP. {
  A = sqlite3ExprFunction(pParse, 0, &X, 0);
}

%ifndef SQLITE_OMIT_WINDOWFUNC
expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP over_clause(Z). {



  A = sqlite3ExprFunction(pParse, Y, &X, D);



  sqlite3WindowAttach(pParse, A, Z);
}
expr(A) ::= id(X) LP STAR RP over_clause(Z). {
  A = sqlite3ExprFunction(pParse, 0, &X, 0);
  sqlite3WindowAttach(pParse, A, Z);
}
%endif

term(A) ::= CTIME_KW(OP). {
  A = sqlite3ExprFunction(pParse, 0, &OP, 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;
................................................................................
likeop(A) ::= NOT LIKE_KW|MATCH(X). {A=X; A.n|=0x80000000; /*A-overwrite-X*/}
expr(A) ::= expr(A) likeop(OP) expr(Y).  [LIKE_KW]  {
  ExprList *pList;
  int bNot = OP.n & 0x80000000;
  OP.n &= 0x7fffffff;
  pList = sqlite3ExprListAppend(pParse,0, Y);
  pList = sqlite3ExprListAppend(pParse,pList, A);
  A = sqlite3ExprFunction(pParse, pList, &OP, 0);
  if( bNot ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
  if( A ) A->flags |= EP_InfixFunc;
}
expr(A) ::= expr(A) likeop(OP) expr(Y) ESCAPE expr(E).  [LIKE_KW]  {
  ExprList *pList;
  int bNot = OP.n & 0x80000000;
  OP.n &= 0x7fffffff;
  pList = sqlite3ExprListAppend(pParse,0, Y);
  pList = sqlite3ExprListAppend(pParse,pList, A);
  pList = sqlite3ExprListAppend(pParse,pList, E);
  A = sqlite3ExprFunction(pParse, pList, &OP, 0);
  if( bNot ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
  if( A ) A->flags |= EP_InfixFunc;
}

expr(A) ::= expr(A) ISNULL|NOTNULL(E).   {A = sqlite3PExpr(pParse,@E,A,0);}
expr(A) ::= expr(A) NOT NULL.    {A = sqlite3PExpr(pParse,TK_NOTNULL,A,0);}

................................................................................
  A = Z;
  if( ALWAYS(A) ){
    A->pPartition = X;
    A->pOrderBy = Y;
  }
}

part_opt(A) ::= PARTITION BY nexprlist(X). { A = X; }
part_opt(A) ::= .                          { A = 0; }

frame_opt(A) ::= .                             { 
  A = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
}
frame_opt(A) ::= range_or_rows(X) frame_bound_s(Y). { 
  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, TK_CURRENT, 0);
}

Changes to src/sqliteInt.h.

3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
#endif
Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
Expr *sqlite3Expr(sqlite3*,int,const char*);
void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
void sqlite3ExprDelete(sqlite3*, Expr*);
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
void sqlite3ExprListSetSortOrder(ExprList*,int);
void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);







|







3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
#endif
Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
Expr *sqlite3Expr(sqlite3*,int,const char*);
void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
void sqlite3ExprDelete(sqlite3*, Expr*);
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
void sqlite3ExprListSetSortOrder(ExprList*,int);
void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);

Changes to src/window.c.

955
956
957
958
959
960
961
962



963
964
965
966
967
968
969
}

/*
** Attach window object pWin to expression p.
*/
void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
  if( p ){
    if( pWin ){



      p->pWin = pWin;
      pWin->pOwner = p;
      if( p->flags & EP_Distinct ){
        sqlite3ErrorMsg(pParse,
           "DISTINCT is not supported for window functions");
      }
    }







|
>
>
>







955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
}

/*
** Attach window object pWin to expression p.
*/
void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
  if( p ){
    /* This routine is only called for the parser.  If pWin was not
    ** allocated due to an OOM, then the parser would fail before ever
    ** invoking this routine */
    if( ALWAYS(pWin) ){
      p->pWin = pWin;
      pWin->pOwner = p;
      if( p->flags & EP_Distinct ){
        sqlite3ErrorMsg(pParse,
           "DISTINCT is not supported for window functions");
      }
    }