/ Check-in [fc90a53d]
Login

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

Overview
Comment:An early attempt at refactoring Expr
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | expr-simplify-branch1
Files: files | file ages | folders
SHA3-256:fc90a53de7ebca5d4cd3aac40d6e9d001350a932eb99fdaedb6826597c8a973c
User & Date: drh 2018-07-28 13:37:44
Context
2018-07-28
13:37
An early attempt at refactoring Expr Closed-Leaf check-in: fc90a53d user: drh tags: expr-simplify-branch1
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
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

  1142   1142   ** to enforce this constraint.
  1143   1143   */
  1144   1144   static int dupedExprStructSize(Expr *p, int flags){
  1145   1145     int nSize;
  1146   1146     assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
  1147   1147     assert( EXPR_FULLSIZE<=0xfff );
  1148   1148     assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
  1149         -  if( 0==flags || p->op==TK_SELECT_COLUMN 
  1150         -#ifndef SQLITE_OMIT_WINDOWFUNC
  1151         -   || p->pWin 
  1152         -#endif
  1153         -  ){
         1149  +  if( 0==flags || p->op==TK_SELECT_COLUMN ){
  1154   1150       nSize = EXPR_FULLSIZE;
  1155   1151     }else{
  1156   1152       assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
  1157   1153       assert( !ExprHasProperty(p, EP_FromJoin) ); 
  1158   1154       assert( !ExprHasProperty(p, EP_MemToken) );
  1159   1155       assert( !ExprHasProperty(p, EP_NoReduce) );
  1160         -    if( p->pLeft || p->x.pList ){
         1156  +    if( p->eV || p->eX ){
  1161   1157         nSize = EXPR_REDUCEDSIZE | EP_Reduced;
  1162   1158       }else{
  1163         -      assert( p->pRight==0 );
  1164   1159         nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
  1165   1160       }
  1166   1161     }
  1167   1162     return nSize;
  1168   1163   }
  1169   1164   
  1170   1165   /*
................................................................................
  1185   1180   ** expression passed as the first argument. The second argument is a
  1186   1181   ** mask containing EXPRDUP_XXX flags.
  1187   1182   **
  1188   1183   ** The value returned includes space to create a copy of the Expr struct
  1189   1184   ** itself and the buffer referred to by Expr.u.zToken, if any.
  1190   1185   **
  1191   1186   ** If the EXPRDUP_REDUCE flag is set, then the return value includes 
  1192         -** space to duplicate all Expr nodes in the tree formed by Expr.pLeft 
         1187  +** space to duplicate all Expr nodes in the tree formed by Expr.v.pLeft 
  1193   1188   ** and Expr.pRight variables (but not for any structures pointed to or 
  1194   1189   ** descended from the Expr.x.pList or Expr.x.pSelect variables).
  1195   1190   */
  1196   1191   static int dupedExprSize(Expr *p, int flags){
  1197   1192     int nByte = 0;
  1198   1193     if( p ){
  1199   1194       nByte = dupedExprNodeSize(p, flags);
  1200   1195       if( flags&EXPRDUP_REDUCE ){
  1201         -      nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags);
         1196  +      if( p->eV==EV_Left ) nByte += dupedExprSize(p->v.pLeft, flags);
         1197  +      if( p->eV==EX_Right ) nByte += dupedExprSize(p->x.pRight, flags);
  1202   1198       }
  1203   1199     }
  1204   1200     return nByte;
  1205   1201   }
  1206   1202   
  1207   1203   /*
  1208   1204   ** This function is similar to sqlite3ExprDup(), except that if pzBuffer 
  1209   1205   ** is not NULL then *pzBuffer is assumed to point to a buffer large enough 
  1210   1206   ** to store the copy of expression p, the copies of p->u.zToken
  1211         -** (if applicable), and the copies of the p->pLeft and p->pRight expressions,
         1207  +** (if applicable), and the copies of the p->v.pLeft and p->pRight expressions,
  1212   1208   ** if any. Before returning, *pzBuffer is set to the first byte past the
  1213   1209   ** portion of the buffer copied into by this function.
  1214   1210   */
  1215   1211   static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
  1216   1212     Expr *pNew;           /* Value to return */
  1217   1213     u8 *zAlloc;           /* Memory space from which to build Expr object */
  1218   1214     u32 staticFlag;       /* EP_Static if space not obtained from malloc */
................................................................................
  1264   1260   
  1265   1261       /* Copy the p->u.zToken string, if any. */
  1266   1262       if( nToken ){
  1267   1263         char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
  1268   1264         memcpy(zToken, p->u.zToken, nToken);
  1269   1265       }
  1270   1266   
         1267  +#if 0
  1271   1268       if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
  1272   1269         /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
  1273   1270         if( ExprHasProperty(p, EP_xIsSelect) ){
  1274   1271           pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
  1275   1272         }else{
  1276   1273           pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
  1277   1274         }
  1278   1275       }
         1276  +#endif
         1277  +    if( p->eX==EX_Select ){
         1278  +      pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
         1279  +    }else if( p->eX==EX_List ){
         1280  +      pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
         1281  +    }
  1279   1282   
  1280         -    /* Fill in pNew->pLeft and pNew->pRight. */
         1283  +    /* Fill in pNew->v.pLeft and pNew->x.pRight. */
  1281   1284       if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
  1282   1285         zAlloc += dupedExprNodeSize(p, dupFlags);
  1283   1286         if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
  1284   1287           pNew->pLeft = p->pLeft ?
  1285   1288                         exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
  1286   1289           pNew->pRight = p->pRight ?
  1287   1290                          exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;

Changes to src/sqliteInt.h.

  2422   2422   ** are contained within the same memory allocation.  Note, however, that
  2423   2423   ** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately
  2424   2424   ** allocated, regardless of whether or not EP_Reduced is set.
  2425   2425   */
  2426   2426   struct Expr {
  2427   2427     u8 op;                 /* Operation performed by this node */
  2428   2428     char affinity;         /* The affinity of the column or 0 if not a column */
         2429  +  u8 eV;                 /* Which element of v-union is used */
         2430  +  u8 eX;                 /* Which element of x-union is used */
  2429   2431     u32 flags;             /* Various flags.  EP_* See below */
  2430   2432     union {
  2431   2433       char *zToken;          /* Token value. Zero terminated and dequoted */
  2432   2434       int iValue;            /* Non-negative integer value if EP_IntValue */
  2433   2435     } u;
  2434   2436   
  2435   2437     /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
  2436   2438     ** space is allocated for the fields below this point. An attempt to
  2437   2439     ** access them will result in a segfault or malfunction.
  2438   2440     *********************************************************************/
  2439   2441   
  2440         -  Expr *pLeft;           /* Left subnode */
  2441         -  Expr *pRight;          /* Right subnode */
  2442         -  union {
  2443         -    ExprList *pList;     /* op = IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */
  2444         -    Select *pSelect;     /* EP_xIsSelect and op = IN, EXISTS, SELECT */
         2442  +  union {                /* Usage determined by Expr.eV */
         2443  +    Expr *pLeft;           /* Left subnode */
         2444  +    Expr *pVector;         /* TK_SELECT_COLUMN: The SELECT */
         2445  +    Window *pWin;          /* TK_FUNCTION: Window definition */
         2446  +  } v;
         2447  +  union {                /* Usage determined by Expr.eX */
         2448  +    Expr *pRight;          /* Right subnode */
         2449  +    ExprList *pList;       /* IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */
         2450  +    Select *pSelect;       /* IN, EXISTS, SELECT */
         2451  +    Table *pTab;           /* Table for TK_COLUMN expressions. Can be NULL
         2452  +                           ** for a column of an index on an expression */
  2445   2453     } x;
  2446   2454   
  2447   2455     /* If the EP_Reduced flag is set in the Expr.flags mask, then no
  2448   2456     ** space is allocated for the fields below this point. An attempt to
  2449   2457     ** access them will result in a segfault or malfunction.
  2450   2458     *********************************************************************/
  2451   2459   
................................................................................
  2462   2470                            ** TK_SELECT_COLUMN: column of the result vector */
  2463   2471     i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  2464   2472     i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  2465   2473     u8 op2;                /* TK_REGISTER: original value of Expr.op
  2466   2474                            ** TK_COLUMN: the value of p5 for OP_Column
  2467   2475                            ** TK_AGG_FUNCTION: nesting depth */
  2468   2476     AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  2469         -  Table *pTab;           /* Table for TK_COLUMN expressions.  Can be NULL
  2470         -                         ** for a column of an index on an expression */
  2471         -#ifndef SQLITE_OMIT_WINDOWFUNC
  2472         -  Window *pWin;          /* Window definition for window functions */
  2473         -#endif
  2474   2477   };
  2475   2478   
         2479  +/*
         2480  +** Allowed values for the Expr.eV and Expr.eX fields:
         2481  +*/
         2482  +#define EV_None     0    /* Expr.v is not used */
         2483  +#define EV_Left     1    /* Expr.v.pLeft */
         2484  +#define EV_Vector   2    /* Expr.v.pVector */
         2485  +#dfeine EV_Win      3    /* Expr.v.pWin */
         2486  +
         2487  +#define EX_None     0    /* Expr.x is not used */
         2488  +#define EX_Right    1    /* Expr.x.pRight */
         2489  +#define EX_List     2    /* Expr.x.pList */
         2490  +#define EX_Select   3    /* Expr.x.pSelect */
         2491  +#define EX_Tab      4    /* Expr.x.pTab */
         2492  +
  2476   2493   /*
  2477   2494   ** The following are the meanings of bits in the Expr.flags field.
  2478   2495   */
  2479   2496   #define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
  2480   2497   #define EP_Agg       0x000002 /* Contains one or more aggregate functions */
  2481   2498   #define EP_HasFunc   0x000004 /* Contains one or more functions of any kind */
  2482   2499   #define EP_FixedCol  0x000008 /* TK_Column with a known fixed value */