Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Minor refactoring of the expression-compaction logic for clarity of presentation. New comments added. The EXPRDUP_DISTINCTSPAN flag is removed as obsolete. (CVS 6470) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
44ded2ea67374f187a111df69c3f51f8 |
User & Date: | drh 2009-04-08 13:51:51.000 |
Context
2009-04-08
| ||
15:45 | Remove a pair unnecessary conditions from printf.c. The "db" parameter is now required for sqlite3MPrintf(). (CVS 6471) (check-in: 6fe8b5d702 user: drh tags: trunk) | |
13:51 | Minor refactoring of the expression-compaction logic for clarity of presentation. New comments added. The EXPRDUP_DISTINCTSPAN flag is removed as obsolete. (CVS 6470) (check-in: 44ded2ea67 user: drh tags: trunk) | |
12:21 | Do not attempt to walk a TokenOnly or SpanOnly expression tree node. Ticket #3791. (CVS 6469) (check-in: 8362d88324 user: drh tags: trunk) | |
Changes
Changes to src/attach.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** ** $Id: attach.c,v 1.84 2009/04/08 13:51:51 drh Exp $ */ #include "sqliteInt.h" #ifndef SQLITE_OMIT_ATTACH /* ** Resolve an expression that was part of an ATTACH or DETACH statement. This ** is slightly different from resolving a normal SQL expression, because simple |
︙ | ︙ | |||
484 485 486 487 488 489 490 | return 0; } int sqlite3FixExpr( DbFixer *pFix, /* Context of the fixation */ Expr *pExpr /* The expression to be fixed to one database */ ){ while( pExpr ){ | | | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 | return 0; } int sqlite3FixExpr( DbFixer *pFix, /* Context of the fixation */ Expr *pExpr /* The expression to be fixed to one database */ ){ while( pExpr ){ if( ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanToken) ) break; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; }else{ if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; } if( sqlite3FixExpr(pFix, pExpr->pRight) ){ return 1; |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.528 2009/04/08 13:51:51 drh Exp $ */ #include "sqliteInt.h" /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. */ |
︙ | ︙ | |||
1108 1109 1110 1111 1112 1113 1114 | pCol->zName); }else{ /* A copy of pExpr is used instead of the original, as pExpr contains ** tokens that point to volatile memory. The 'span' of the expression ** is required by pragma table_info. */ sqlite3ExprDelete(db, pCol->pDflt); | | < < | 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 | pCol->zName); }else{ /* A copy of pExpr is used instead of the original, as pExpr contains ** tokens that point to volatile memory. The 'span' of the expression ** is required by pragma table_info. */ sqlite3ExprDelete(db, pCol->pDflt); pCol->pDflt = sqlite3ExprDup(db, pExpr, EXPRDUP_REDUCE|EXPRDUP_SPAN); } } sqlite3ExprDelete(db, pExpr); } /* ** Designate the PRIMARY KEY for the table. pList is a list of names |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.426 2009/04/08 13:51:51 drh Exp $ */ #include "sqliteInt.h" /* ** Return the 'affinity' of the expression pExpr if any. ** ** If pExpr is a column, a reference to a column via an 'AS' alias, |
︙ | ︙ | |||
625 626 627 628 629 630 631 | /* ** Clear an expression structure without deleting the structure itself. ** Substructure is deleted. */ void sqlite3ExprClear(sqlite3 *db, Expr *p){ if( p->token.dyn ) sqlite3DbFree(db, (char*)p->token.z); | | > > > | 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 | /* ** Clear an expression structure without deleting the structure itself. ** Substructure is deleted. */ void sqlite3ExprClear(sqlite3 *db, Expr *p){ if( p->token.dyn ) sqlite3DbFree(db, (char*)p->token.z); if( !ExprHasAnyProperty(p, EP_TokenOnly|EP_SpanToken) ){ if( p->span.dyn ) sqlite3DbFree(db, (char*)p->span.z); if( ExprHasProperty(p, EP_Reduced) ){ /* Subtrees are part of the same memory allocation when EP_Reduced set */ if( p->pLeft ) sqlite3ExprClear(db, p->pLeft); if( p->pRight ) sqlite3ExprClear(db, p->pRight); }else{ /* Subtrees are separate allocations when EP_Reduced is clear */ sqlite3ExprDelete(db, p->pLeft); sqlite3ExprDelete(db, p->pRight); } /* x.pSelect and x.pList are always separately allocated */ if( ExprHasProperty(p, EP_xIsSelect) ){ sqlite3SelectDelete(db, p->x.pSelect); }else{ sqlite3ExprListDelete(db, p->x.pList); } } } |
︙ | ︙ | |||
670 671 672 673 674 675 676 | /* ** Return the number of bytes allocated for the expression structure ** passed as the first argument. This is always one of EXPR_FULLSIZE, ** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE. */ static int exprStructSize(Expr *p){ if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE; | | | | | | | 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 | /* ** Return the number of bytes allocated for the expression structure ** passed as the first argument. This is always one of EXPR_FULLSIZE, ** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE. */ static int exprStructSize(Expr *p){ if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE; if( ExprHasProperty(p, EP_SpanToken) ) return EXPR_SPANTOKENSIZE; if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE; return EXPR_FULLSIZE; } /* ** sqlite3ExprDup() has been called to create a copy of expression p with ** the EXPRDUP_XXX flags passed as the second argument. This function ** returns the space required for the copy of the Expr structure only. ** This is always one of EXPR_FULLSIZE, EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE. */ static int dupedExprStructSize(Expr *p, int flags){ int nSize; if( 0==(flags&EXPRDUP_REDUCE) ){ nSize = EXPR_FULLSIZE; }else if( p->pLeft || p->pRight || p->pColl || p->x.pList ){ nSize = EXPR_REDUCEDSIZE; }else if( flags&EXPRDUP_SPAN ){ nSize = EXPR_SPANTOKENSIZE; }else{ nSize = EXPR_TOKENONLYSIZE; } return nSize; } /* ** sqlite3ExprDup() has been called to create a copy of expression p with ** the EXPRDUP_XXX passed as the second argument. This function returns ** the space in bytes required to store the copy of the Expr structure ** and the copies of the Expr.token.z and Expr.span.z (if applicable) ** string buffers. */ static int dupedExprNodeSize(Expr *p, int flags){ int nByte = dupedExprStructSize(p, flags) + (p->token.z ? p->token.n + 1 : 0); if( (flags&EXPRDUP_SPAN)!=0 && (p->token.z!=p->span.z || p->token.n!=p->span.n) ){ nByte += p->span.n; } return ROUND8(nByte); } /* |
︙ | ︙ | |||
732 733 734 735 736 737 738 | ** descended from the Expr.x.pList or Expr.x.pSelect variables). */ static int dupedExprSize(Expr *p, int flags){ int nByte = 0; if( p ){ nByte = dupedExprNodeSize(p, flags); if( flags&EXPRDUP_REDUCE ){ | | < | | 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 | ** descended from the Expr.x.pList or Expr.x.pSelect variables). */ static int dupedExprSize(Expr *p, int flags){ int nByte = 0; if( p ){ nByte = dupedExprNodeSize(p, flags); if( flags&EXPRDUP_REDUCE ){ int f = flags&(~EXPRDUP_SPAN); nByte += dupedExprSize(p->pLeft, f) + dupedExprSize(p->pRight, f); } } return nByte; } /* ** 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->token and p->span ** (if applicable), and the copies of the p->pLeft and p->pRight expressions, ** if any. Before returning, *pzBuffer is set to the first byte passed the ** portion of the buffer copied into by this function. */ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ Expr *pNew = 0; /* Value to return */ if( p ){ const int isRequireSpan = (flags&EXPRDUP_SPAN); const int isReduced = (flags&EXPRDUP_REDUCE); u8 *zAlloc; assert( pzBuffer==0 || isReduced ); /* Figure out where to write the new Expr structure. */ if( pzBuffer ){ |
︙ | ︙ | |||
783 784 785 786 787 788 789 | }else{ int nSize = exprStructSize(p); memcpy(zAlloc, p, nSize); memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize); } /* Set the EP_Reduced and EP_TokenOnly flags appropriately. */ | | | < | < | | | | 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 | }else{ int nSize = exprStructSize(p); memcpy(zAlloc, p, nSize); memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize); } /* Set the EP_Reduced and EP_TokenOnly flags appropriately. */ pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_SpanToken); switch( nNewSize ){ case EXPR_REDUCEDSIZE: pNew->flags |= EP_Reduced; break; case EXPR_TOKENONLYSIZE: pNew->flags |= EP_TokenOnly; break; case EXPR_SPANTOKENSIZE: pNew->flags |= EP_SpanToken; break; } /* Copy the p->token string, if any. */ if( nToken ){ unsigned char *zToken = &zAlloc[nNewSize]; memcpy(zToken, p->token.z, nToken-1); zToken[nToken-1] = '\0'; pNew->token.dyn = 0; pNew->token.z = zToken; } if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){ /* Fill in the pNew->span token, if required. */ if( isRequireSpan ){ if( p->token.z!=p->span.z || p->token.n!=p->span.n ){ pNew->span.z = &zAlloc[nNewSize+nToken]; memcpy((char *)pNew->span.z, p->span.z, p->span.n); pNew->span.dyn = 0; }else{ pNew->span.z = pNew->token.z; pNew->span.n = pNew->token.n; } }else{ pNew->span.z = 0; pNew->span.n = 0; } } if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_SpanToken)) ){ /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ if( ExprHasProperty(p, EP_xIsSelect) ){ pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced); }else{ pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced); } } /* Fill in pNew->pLeft and pNew->pRight. */ if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly|EP_SpanToken) ){ zAlloc += dupedExprNodeSize(p, flags); if( ExprHasProperty(pNew, EP_Reduced) ){ pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc); pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc); } if( pzBuffer ){ *pzBuffer = zAlloc; } }else if( !ExprHasAnyProperty(p, EP_TokenOnly|EP_SpanToken) ){ pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); } } } return pNew; } |
︙ | ︙ | |||
2201 2202 2203 2204 2205 2206 2207 | }else{ inReg = pInfo->aFunc[pExpr->iAgg].iMem; } break; } case TK_CONST_FUNC: case TK_FUNCTION: { | | < < | | | | | | | | > > > > > > | | < | | | | | | | | | | | | | | | 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 | }else{ inReg = pInfo->aFunc[pExpr->iAgg].iMem; } break; } case TK_CONST_FUNC: case TK_FUNCTION: { ExprList *pFarg; /* List of function arguments */ int nFarg; /* Number of function arguments */ FuncDef *pDef; /* The function definition object */ int nId; /* Length of the function name in bytes */ const char *zId; /* The function name */ int constMask = 0; /* Mask of function arguments that are constant */ int i; /* Loop counter */ u8 enc = ENC(db); /* The text encoding used by this database */ CollSeq *pColl = 0; /* A collating sequence */ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); testcase( op==TK_CONST_FUNC ); testcase( op==TK_FUNCTION ); if( ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanToken) ){ pFarg = 0; }else{ pFarg = pExpr->x.pList; } nFarg = pFarg ? pFarg->nExpr : 0; zId = (char*)pExpr->token.z; nId = pExpr->token.n; pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0); assert( pDef!=0 ); if( pFarg ){ r1 = sqlite3GetTempRange(pParse, nFarg); sqlite3ExprCodeExprList(pParse, pFarg, r1, 1); }else{ r1 = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* Possibly overload the function if the first argument is ** a virtual table column. ** ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the ** second argument, not the first, as the argument to test to ** see if it is a column in a virtual table. This is done because ** the left operand of infix functions (the operand we want to ** control overloading) ends up as the second argument to the ** function. The expression "A glob B" is equivalent to ** "glob(B,A). We want to use the A in "A glob B" to test ** for function overloading. But we use the B term in "glob(B,A)". */ if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){ pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr); }else if( nFarg>0 ){ pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); } #endif for(i=0; i<nFarg && i<32; i++){ if( sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){ constMask |= (1<<i); } if( (pDef->flags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); } } if( pDef->flags & SQLITE_FUNC_NEEDCOLL ){ if( !pColl ) pColl = db->pDfltColl; sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); } sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target, (char*)pDef, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nFarg); if( nFarg ){ sqlite3ReleaseTempRange(pParse, r1, nFarg); } sqlite3ExprCacheAffinityChange(pParse, r1, nFarg); break; } #ifndef SQLITE_OMIT_SUBQUERY case TK_EXISTS: case TK_SELECT: { testcase( op==TK_EXISTS ); testcase( op==TK_SELECT ); |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.854 2009/04/08 13:51:51 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build |
︙ | ︙ | |||
1448 1449 1450 1451 1452 1453 1454 | ** ** If the Expr is of type OP_Column, and the table it is selecting from ** is a disk table or the "old.*" pseudo-table, then pTab points to the ** corresponding table definition. ** ** ALLOCATION NOTES: ** | | | | | | | | | | | | < | | 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 | ** ** If the Expr is of type OP_Column, and the table it is selecting from ** is a disk table or the "old.*" pseudo-table, then pTab points to the ** corresponding table definition. ** ** ALLOCATION NOTES: ** ** Expr objects can use a lot of memory space in database schema. To ** help reduce memory requirements, sometimes an Expr object will be ** truncated. And to reduce the number of memory allocations, sometimes ** two or more Expr objects will be stored in a single memory allocation, ** together with Expr.token and/or Expr.span strings. ** ** If the EP_Reduced, EP_SpanToken, and EP_TokenOnly flags are set when ** an Expr object is truncated. When EP_Reduced is set, then all ** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees ** are contained within the same memory allocation. Note, however, that ** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately ** allocated, regardless of whether or not EP_Reduced is set. */ struct Expr { u8 op; /* Operation performed by this node */ char affinity; /* The affinity of the column or 0 if not a column */ VVA_ONLY(u8 vvaFlags;) /* Flags used for VV&A only. EVVA_* below. */ u16 flags; /* Various flags. EP_* See below */ Token token; /* An operand token */ /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no ** space is allocated for the fields below this point. An attempt to ** access them will result in a segfault or malfunction. *********************************************************************/ Token span; /* Complete text of the expression */ /* If the EP_SpanToken flag is set in the Expr.flags mask, then no ** space is allocated for the fields below this point. An attempt to ** access them will result in a segfault or malfunction. *********************************************************************/ Expr *pLeft; /* Left subnode */ Expr *pRight; /* Right subnode */ union { |
︙ | ︙ | |||
1524 1525 1526 1527 1528 1529 1530 | #define EP_AnyAff 0x0200 /* Can take a cached column of any affinity */ #define EP_FixedDest 0x0400 /* Result needed in a specific register */ #define EP_IntValue 0x0800 /* Integer value contained in iTable */ #define EP_xIsSelect 0x1000 /* x.pSelect is valid (otherwise x.pList is) */ #define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */ #define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */ | | | 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 | #define EP_AnyAff 0x0200 /* Can take a cached column of any affinity */ #define EP_FixedDest 0x0400 /* Result needed in a specific register */ #define EP_IntValue 0x0800 /* Integer value contained in iTable */ #define EP_xIsSelect 0x1000 /* x.pSelect is valid (otherwise x.pList is) */ #define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */ #define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */ #define EP_SpanToken 0x8000 /* Expr size is EXPR_SPANTOKENSIZE bytes */ /* ** The following are the meanings of bits in the Expr.vvaFlags field. ** This information is only used when SQLite is compiled with ** SQLITE_DEBUG defined. */ #ifndef NDEBUG |
︙ | ︙ | |||
1549 1550 1551 1552 1553 1554 1555 | #define ExprClearProperty(E,P) (E)->flags&=~(P) /* ** Macros to determine the number of bytes required by a normal Expr ** struct, an Expr struct with the EP_Reduced flag set in Expr.flags ** and an Expr struct with the EP_TokenOnly flag set. */ | | | > | < | | < | 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 | #define ExprClearProperty(E,P) (E)->flags&=~(P) /* ** Macros to determine the number of bytes required by a normal Expr ** struct, an Expr struct with the EP_Reduced flag set in Expr.flags ** and an Expr struct with the EP_TokenOnly flag set. */ #define EXPR_FULLSIZE sizeof(Expr) /* Full size */ #define EXPR_REDUCEDSIZE offsetof(Expr,iTable) /* Common features */ #define EXPR_SPANTOKENSIZE offsetof(Expr,pLeft) /* Fewer features */ #define EXPR_TOKENONLYSIZE offsetof(Expr,span) /* Smallest possible */ /* ** Flags passed to the sqlite3ExprDup() function. See the header comment ** above sqlite3ExprDup() for details. */ #define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */ #define EXPRDUP_SPAN 0x0002 /* Make a copy of Expr.span */ /* ** A list of expressions. Each expression may optionally have a ** name. An expr/name combination can be used in several ways, such ** as the list of "expr AS ID" fields following a "SELECT" or in the ** list of "ID = expr" items in an UPDATE. A list of expressions can ** also be used as the argument to a function, in which case the a.zName |
︙ | ︙ |
Changes to src/walker.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for walking the parser tree for ** an SQL statement. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for walking the parser tree for ** an SQL statement. ** ** $Id: walker.c,v 1.4 2009/04/08 13:51:52 drh Exp $ */ #include "sqliteInt.h" #include <stdlib.h> #include <string.h> /* |
︙ | ︙ | |||
38 39 40 41 42 43 44 | ** The return value from this routine is WRC_Abort to abandon the tree walk ** and WRC_Continue to continue. */ int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ int rc; if( pExpr==0 ) return WRC_Continue; testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); | | > | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | ** The return value from this routine is WRC_Abort to abandon the tree walk ** and WRC_Continue to continue. */ int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ int rc; if( pExpr==0 ) return WRC_Continue; testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); testcase( ExprHasProperty(pExpr, EP_SpanToken) ); testcase( ExprHasProperty(pExpr, EP_Reduced) ); rc = pWalker->xExprCallback(pWalker, pExpr); if( rc==WRC_Continue && !ExprHasAnyProperty(pExpr,EP_TokenOnly|EP_SpanToken) ){ if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; }else{ if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; } |
︙ | ︙ |