Compare commits

...

2 Commits

Author SHA1 Message Date
drh 2a4cf03423 An early attempt at refactoring Expr
FossilOrigin-Name: fc90a53de7ebca5d4cd3aac40d6e9d001350a932eb99fdaedb6826597c8a973c
2018-07-28 13:37:44 +00:00
drh 35284b6c48 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.

FossilOrigin-Name: 81f25d5c84e4d2d0cd3c6a7c105c7c93d310218feeea4e023dbc32e7e96b2a52
2018-07-28 01:30:43 +00:00
4 changed files with 60 additions and 29 deletions
+7 -7
View File
@@ -1,5 +1,5 @@
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
C An\searly\sattempt\sat\srefactoring\sExpr
D 2018-07-28T13:37:44.333
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 907d7de6cac23e55e32f22133a4fa8ca1558d7fe7c9a37e01feebb1106416fe7
F src/expr.c dff6636152ebc54e394a2133b2c4cc1c3f7de2130d7933362487be07cf19264b
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c f59253c0be4b1e9dfcb073b6d6d6ab83090ae50c08b5c113b76013c4b157cd6a
F src/func.c 7c288b4ce309b5a8b8473514b88e1f8e69a80134509a8c0db8e39c858e367e7f
@@ -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 de37aae03c6a4e4f1e1eff15c04292153dbba015ad8e0dc0dffe82ea0fe76d5e
F src/sqliteInt.h d9e843d00aee15d12c5d67556b3d61688103c945da5bedd071d2a5966df907dc
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -1753,7 +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 7efdba2bbc8547ee9292a1bbd1e61d38b40d7aabc0860ceba188bdec539f5114
R 471a9deda4100ce593be82a25e7c7930
P 81f25d5c84e4d2d0cd3c6a7c105c7c93d310218feeea4e023dbc32e7e96b2a52
R 2f4d5976ed1b9b3eff7341b424df6edf
U drh
Z 49ba2c803564fb9ad5a228c53691471f
Z 2ce8b95bf3ceede5076a1330ec36f69d
+1 -1
View File
@@ -1 +1 @@
02204f8b246c868846f39bd44f2e3bc0fab0275aa09ef3a0e5a8e3d58f484ca8
fc90a53de7ebca5d4cd3aac40d6e9d001350a932eb99fdaedb6826597c8a973c
+25 -11
View File
@@ -1060,6 +1060,17 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
assert( p->pRight==0 );
assert( p->x.pSelect==0 );
}
if( !ExprHasProperty(p, EP_TokenOnly) ){
assert( p->op!=TK_FUNCTION || p->pLeft==0 );
assert( p->pRight==0 || p->x.pSelect==0 );
}
if( !ExprHasProperty(p, (EP_TokenOnly|EP_Reduced)) ){
assert( p->pWin==0 || p->pLeft==0 );
assert( p->pWin==0 || p->pTab==0 );
assert( p->pWin==0 || p->op==TK_FUNCTION );
assert( p->pWin==0 || !ExprHasProperty(p, EP_xIsSelect) );
assert( p->pTab==0 || (p->pRight==0 && p->x.pSelect==0) );
}
#endif
if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
/* The Expr.x union is never used at the same time as Expr.pRight */
@@ -1135,21 +1146,16 @@ static int dupedExprStructSize(Expr *p, int flags){
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
){
if( 0==flags || p->op==TK_SELECT_COLUMN ){
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 ){
if( p->eV || p->eX ){
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
}else{
assert( p->pRight==0 );
nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
}
}
@@ -1178,7 +1184,7 @@ static int dupedExprNodeSize(Expr *p, int flags){
** itself and the buffer referred to by Expr.u.zToken, if any.
**
** If the EXPRDUP_REDUCE flag is set, then the return value includes
** space to duplicate all Expr nodes in the tree formed by Expr.pLeft
** space to duplicate all Expr nodes in the tree formed by Expr.v.pLeft
** and Expr.pRight variables (but not for any structures pointed to or
** descended from the Expr.x.pList or Expr.x.pSelect variables).
*/
@@ -1187,7 +1193,8 @@ static int dupedExprSize(Expr *p, int flags){
if( p ){
nByte = dupedExprNodeSize(p, flags);
if( flags&EXPRDUP_REDUCE ){
nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags);
if( p->eV==EV_Left ) nByte += dupedExprSize(p->v.pLeft, flags);
if( p->eV==EX_Right ) nByte += dupedExprSize(p->x.pRight, flags);
}
}
return nByte;
@@ -1197,7 +1204,7 @@ static int dupedExprSize(Expr *p, int flags){
** This function is similar to sqlite3ExprDup(), except that if pzBuffer
** is not NULL then *pzBuffer is assumed to point to a buffer large enough
** to store the copy of expression p, the copies of p->u.zToken
** (if applicable), and the copies of the p->pLeft and p->pRight expressions,
** (if applicable), and the copies of the p->v.pLeft and p->pRight expressions,
** if any. Before returning, *pzBuffer is set to the first byte past the
** portion of the buffer copied into by this function.
*/
@@ -1257,6 +1264,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
memcpy(zToken, p->u.zToken, nToken);
}
#if 0
if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
if( ExprHasProperty(p, EP_xIsSelect) ){
@@ -1265,8 +1273,14 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
}
}
#endif
if( p->eX==EX_Select ){
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
}else if( p->eX==EX_List ){
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
}
/* Fill in pNew->pLeft and pNew->pRight. */
/* Fill in pNew->v.pLeft and pNew->x.pRight. */
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
zAlloc += dupedExprNodeSize(p, dupFlags);
if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
+27 -10
View File
@@ -2426,6 +2426,8 @@ typedef int ynVar;
struct Expr {
u8 op; /* Operation performed by this node */
char affinity; /* The affinity of the column or 0 if not a column */
u8 eV; /* Which element of v-union is used */
u8 eX; /* Which element of x-union is used */
u32 flags; /* Various flags. EP_* See below */
union {
char *zToken; /* Token value. Zero terminated and dequoted */
@@ -2437,11 +2439,17 @@ struct Expr {
** access them will result in a segfault or malfunction.
*********************************************************************/
Expr *pLeft; /* Left subnode */
Expr *pRight; /* Right subnode */
union {
ExprList *pList; /* op = IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */
Select *pSelect; /* EP_xIsSelect and op = IN, EXISTS, SELECT */
union { /* Usage determined by Expr.eV */
Expr *pLeft; /* Left subnode */
Expr *pVector; /* TK_SELECT_COLUMN: The SELECT */
Window *pWin; /* TK_FUNCTION: Window definition */
} v;
union { /* Usage determined by Expr.eX */
Expr *pRight; /* Right subnode */
ExprList *pList; /* IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */
Select *pSelect; /* IN, EXISTS, SELECT */
Table *pTab; /* Table for TK_COLUMN expressions. Can be NULL
** for a column of an index on an expression */
} x;
/* If the EP_Reduced flag is set in the Expr.flags mask, then no
@@ -2466,13 +2474,22 @@ struct Expr {
** 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
};
/*
** Allowed values for the Expr.eV and Expr.eX fields:
*/
#define EV_None 0 /* Expr.v is not used */
#define EV_Left 1 /* Expr.v.pLeft */
#define EV_Vector 2 /* Expr.v.pVector */
#dfeine EV_Win 3 /* Expr.v.pWin */
#define EX_None 0 /* Expr.x is not used */
#define EX_Right 1 /* Expr.x.pRight */
#define EX_List 2 /* Expr.x.pList */
#define EX_Select 3 /* Expr.x.pSelect */
#define EX_Tab 4 /* Expr.x.pTab */
/*
** The following are the meanings of bits in the Expr.flags field.
*/