From: drh Date: Fri, 27 Jul 2018 23:33:16 +0000 (+0000) Subject: Improvements to the parser to increase coverage. Fix the parser so that X-Git-Tag: version-3.25.0~91 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=954733b3864f2659ae839dc5009a5e66469bae2c;p=thirdparty%2Fsqlite.git 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(). FossilOrigin-Name: 02204f8b246c868846f39bd44f2e3bc0fab0275aa09ef3a0e5a8e3d58f484ca8 --- diff --git a/manifest b/manifest index d470799eab..1eeed1854b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sdoing\sa\sDROP\sVIEW\sdo\snot\stry\sto\sdelete\sentries\sfrom\sthe\ssqlite_stat1\ntable\sas\sthere\sare\snone. -D 2018-07-27T22:55:58.128 +C Improvements\sto\sthe\sparser\sto\sincrease\scoverage.\s\sFix\sthe\sparser\sso\sthat\nat\sleast\sone\sexpresssion\sis\srequired\safter\sPARTITION\sBY\sand\swithin\sthe\nlist\sof\sexpressions\son\sVALUES(). +D 2018-07-27T23:33:16.472 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6 @@ -450,7 +450,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 F src/dbpage.c 4aa7f26198934dbd002e69418220eae3dbc71b010bbac32bd78faf86b52ce6c3 F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91 F src/delete.c 4c8c7604277a2041647f96b78f4b9a47858e9217e4fb333d35e7b5ab32c5b57f -F src/expr.c 5b5e7b571f377ca76fc76eec0a684384483e0bf6525f6b561a09db09d81600eb +F src/expr.c 907d7de6cac23e55e32f22133a4fa8ca1558d7fe7c9a37e01feebb1106416fe7 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c f59253c0be4b1e9dfcb073b6d6d6ab83090ae50c08b5c113b76013c4b157cd6a F src/func.c 7c288b4ce309b5a8b8473514b88e1f8e69a80134509a8c0db8e39c858e367e7f @@ -487,7 +487,7 @@ F src/os_win.c 070cdbb400097c6cda54aa005356095afdc2f3ee691d17192c54724ef146a971 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 76d29b8a960dcb8b67210f095899d91e4a90673a6674ea58cfd1115b705a7fb9 F src/pager.h c571b064df842ec8f2e90855dead9acf4cbe0d1b2c05afe0ef0d0145f7fd0388 -F src/parse.y a3020c881f558dea6dc1138c58a2a657c26c792120e019792d3e72801da0bf90 +F src/parse.y 704c94624d41d7d46a5467574130e55aa8029a563f4df538f0121475eae46e34 F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170 F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880 @@ -503,7 +503,7 @@ F src/shell.c.in f6ebd05c461805a7c708333cd645e74e0a93560d2118f5adb73a75d8c9cf6b0 F src/sqlite.h.in c6451bb876adced3aba5b1682c6317d215c5eceaba21a6ce979e71a0b8d0bf95 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7 -F src/sqliteInt.h fafe020e6fa39964ffff8ff1b48e2a7f0b394e03c722a746629751d2d31721ae +F src/sqliteInt.h de37aae03c6a4e4f1e1eff15c04292153dbba015ad8e0dc0dffe82ea0fe76d5e F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -587,7 +587,7 @@ F src/where.c fae13835da8cd457bbc50a8530b1f4bfe6eb173dec0687cf1572fc02a7aec415 F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4 F src/wherecode.c 2c552dfe50d06e0916dbd49a180e4bf0accfce6d17d46a2dfeea8f75d2b5861b F src/whereexpr.c dc34f0df69418dedb4619f7ad61b7d31f447971223540b957a1b836a62c0ce7b -F src/window.c c61434ce7e35b7d76b3321dec39e10e79061c10eed1e3d7976c87dbdd77aefb5 +F src/window.c 4b503da928dace3e845b891381a4d98eeb8c5744313ae3643df8d8d21fdcca65 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1753,8 +1753,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cfd1b00592bd550e444dfc7b6a6a93c77c07b835729c6cc69a4b6361038964ba 523ff77925f1da361cf31e3fc82bcb1708ed356a2391430ab14ef620c9bf2327 -R a2c24e054b9c8d4fae68977faa296b2b -T +closed 523ff77925f1da361cf31e3fc82bcb1708ed356a2391430ab14ef620c9bf2327 +P 7efdba2bbc8547ee9292a1bbd1e61d38b40d7aabc0860ceba188bdec539f5114 +R 471a9deda4100ce593be82a25e7c7930 U drh -Z 442a0ea187fa6114275630f524fa214c +Z 49ba2c803564fb9ad5a228c53691471f diff --git a/manifest.uuid b/manifest.uuid index cc7468b358..fbf370f762 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7efdba2bbc8547ee9292a1bbd1e61d38b40d7aabc0860ceba188bdec539f5114 \ No newline at end of file +02204f8b246c868846f39bd44f2e3bc0fab0275aa09ef3a0e5a8e3d58f484ca8 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 7767061050..986b4f9aa9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -941,7 +941,12 @@ Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){ ** Construct a new expression node for a function with multiple ** arguments. */ -Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ +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 ); @@ -950,10 +955,14 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ 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; } diff --git a/src/parse.y b/src/parse.y index f8757df6ba..ea20529340 100644 --- a/src/parse.y +++ b/src/parse.y @@ -558,7 +558,7 @@ oneselect(A) ::= values(A). 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. { +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; @@ -1001,37 +1001,25 @@ expr(A) ::= CAST LP expr(E) AS typetoken(T) RP. { 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; - } + A = sqlite3ExprFunction(pParse, Y, &X, D); } expr(A) ::= id(X) LP STAR RP. { - A = sqlite3ExprFunction(pParse, 0, &X); + A = sqlite3ExprFunction(pParse, 0, &X, 0); } %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; - } + 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); + A = sqlite3ExprFunction(pParse, 0, &X, 0); sqlite3WindowAttach(pParse, A, Z); } %endif term(A) ::= CTIME_KW(OP). { - A = sqlite3ExprFunction(pParse, 0, &OP); + A = sqlite3ExprFunction(pParse, 0, &OP, 0); } expr(A) ::= LP nexprlist(X) COMMA expr(Y) RP. { @@ -1065,7 +1053,7 @@ expr(A) ::= expr(A) likeop(OP) expr(Y). [LIKE_KW] { OP.n &= 0x7fffffff; pList = sqlite3ExprListAppend(pParse,0, Y); pList = sqlite3ExprListAppend(pParse,pList, A); - A = sqlite3ExprFunction(pParse, pList, &OP); + A = sqlite3ExprFunction(pParse, pList, &OP, 0); if( bNot ) A = sqlite3PExpr(pParse, TK_NOT, A, 0); if( A ) A->flags |= EP_InfixFunc; } @@ -1076,7 +1064,7 @@ expr(A) ::= expr(A) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] { pList = sqlite3ExprListAppend(pParse,0, Y); pList = sqlite3ExprListAppend(pParse,pList, A); pList = sqlite3ExprListAppend(pParse,pList, E); - A = sqlite3ExprFunction(pParse, pList, &OP); + A = sqlite3ExprFunction(pParse, pList, &OP, 0); if( bNot ) A = sqlite3PExpr(pParse, TK_NOT, A, 0); if( A ) A->flags |= EP_InfixFunc; } @@ -1640,8 +1628,8 @@ window(A) ::= LP part_opt(X) orderby_opt(Y) frame_opt(Z) RP. { } } -part_opt(A) ::= PARTITION BY exprlist(X). { A = X; } -part_opt(A) ::= . { A = 0; } +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); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7c4d46a40a..5d66df4c08 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3792,7 +3792,7 @@ 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*); +Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); diff --git a/src/window.c b/src/window.c index ce85c44608..ce51de790f 100644 --- a/src/window.c +++ b/src/window.c @@ -959,7 +959,10 @@ windowAllocErr: */ void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ if( p ){ - if( pWin ){ + /* 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 ){