/ Check-in [44ded2ea]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 44ded2ea67374f187a111df69c3f51f866735400
User & Date: drh 2009-04-08 13:51:51
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: 6fe8b5d7 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: 44ded2ea user: drh tags: trunk
12:21
Do not attempt to walk a TokenOnly or SpanOnly expression tree node. Ticket #3791. (CVS 6469) check-in: 8362d883 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/attach.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
**    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.83 2009/02/19 14:39:25 danielk1977 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
................................................................................
  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_SpanOnly) ) 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;







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
**    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
................................................................................
  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
25
26
27
28
29
30
31
32
....
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.527 2009/03/31 03:41:57 shane Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
*/
................................................................................
          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_DISTINCTSPAN
      );
    }
  }
  sqlite3ExprDelete(db, pExpr);
}

/*
** Designate the PRIMARY KEY for the table.  pList is a list of names 







|







 







|
<
<







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
....
1108
1109
1110
1111
1112
1113
1114
1115


1116
1117
1118
1119
1120
1121
1122
**     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.
*/
................................................................................
          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
15
16
17
18
19
20
21
22
...
625
626
627
628
629
630
631
632
633
634

635
636
637

638
639
640

641
642
643
644
645
646
647
...
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
...
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
...
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
...
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
...
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
...
783
784
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
....
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
**    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.425 2009/04/02 17:23:33 danielk1977 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,
................................................................................

/*
** 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_SpanOnly) ){
    if( p->span.dyn ) sqlite3DbFree(db, (char*)p->span.z);
    if( ExprHasProperty(p, EP_Reduced) ){

      if( p->pLeft ) sqlite3ExprClear(db, p->pLeft);
      if( p->pRight ) sqlite3ExprClear(db, p->pRight);
    }else{

      sqlite3ExprDelete(db, p->pLeft);
      sqlite3ExprDelete(db, p->pRight);
    }

    if( ExprHasProperty(p, EP_xIsSelect) ){
      sqlite3SelectDelete(db, p->x.pSelect);
    }else{
      sqlite3ExprListDelete(db, p->x.pList);
    }
  }
}
................................................................................
/*
** 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_SpanOnly) ) return EXPR_SPANONLYSIZE;
  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 
................................................................................
*/
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|EXPRDUP_DISTINCTSPAN) ){
    nSize = EXPR_SPANONLYSIZE;
  }else{
    nSize = EXPR_TOKENONLYSIZE;
  }
  return nSize;
}

/*
................................................................................
** 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_DISTINCTSPAN)
   || (flags&EXPRDUP_SPAN && (p->token.z!=p->span.z || p->token.n!=p->span.n)) 
  ){
    nByte += p->span.n;
  }
  return ROUND8(nByte);
}

/*
................................................................................
** 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|EXPRDUP_DISTINCTSPAN));
      nByte += dupedExprSize(p->pLeft, f) + dupedExprSize(p->pRight, f);
    }
  }
  return nByte;
}

/*
................................................................................
** (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 isRequireDistinctSpan = (flags&EXPRDUP_DISTINCTSPAN);
    const int isRequireSpan = (flags&(EXPRDUP_SPAN|EXPRDUP_DISTINCTSPAN));
    const int isReduced = (flags&EXPRDUP_REDUCE);
    u8 *zAlloc;

    assert( pzBuffer==0 || isReduced );

    /* Figure out where to write the new Expr structure. */
    if( pzBuffer ){
................................................................................
      }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_SpanOnly);
      switch( nNewSize ){
        case EXPR_REDUCEDSIZE:   pNew->flags |= EP_Reduced; break;
        case EXPR_TOKENONLYSIZE: pNew->flags |= EP_TokenOnly; break;
        case EXPR_SPANONLYSIZE:  pNew->flags |= EP_SpanOnly; 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( isRequireDistinctSpan 
           || 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_SpanOnly)) ){
        /* 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_SpanOnly) ){
        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_SpanOnly) ){
        pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
        pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
      }
    }
  }
  return pNew;
}
................................................................................
      }else{
        inReg = pInfo->aFunc[pExpr->iAgg].iMem;
      }
      break;
    }
    case TK_CONST_FUNC:
    case TK_FUNCTION: {
      ExprList *pList = (
        ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanOnly) ? 0 : pExpr->x.pList
      );
      int nExpr = pList ? pList->nExpr : 0;
      FuncDef *pDef;
      int nId;

      const char *zId;
      int constMask = 0;
      int i;

      u8 enc = ENC(db);
      CollSeq *pColl = 0;

      assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
      testcase( op==TK_CONST_FUNC );
      testcase( op==TK_FUNCTION );






      zId = (char*)pExpr->token.z;
      nId = pExpr->token.n;
      pDef = sqlite3FindFunction(db, zId, nId, nExpr, enc, 0);
      assert( pDef!=0 );
      if( pList ){
        nExpr = pList->nExpr;
        r1 = sqlite3GetTempRange(pParse, nExpr);
        sqlite3ExprCodeExprList(pParse, pList, r1, 1);
      }else{
        nExpr = 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( nExpr>=2 && (pExpr->flags & EP_InfixFunc) ){
        pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[1].pExpr);
      }else if( nExpr>0 ){
        pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[0].pExpr);
      }
#endif
      for(i=0; i<nExpr && i<32; i++){
        if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){
          constMask |= (1<<i);
        }
        if( (pDef->flags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
          pColl = sqlite3ExprCollSeq(pParse, pList->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)nExpr);
      if( nExpr ){
        sqlite3ReleaseTempRange(pParse, r1, nExpr);
      }
      sqlite3ExprCacheAffinityChange(pParse, r1, nExpr);
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_EXISTS:
    case TK_SELECT: {
      testcase( op==TK_EXISTS );
      testcase( op==TK_SELECT );







|







 







|


>



>



>







 







|







 







|
|







 







|
|







 







|







 







<
|







 







|



|







 







<
|
<













|









|








|







 







|
|
<
<
|
<
>
|
|
<
>
|
|




>
>
>
>
>
>


|

|
<
|
|

|







 







|
|
|
|


|
|



|








|
|
|

|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
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
...
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
...
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
...
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
...
753
754
755
756
757
758
759

760
761
762
763
764
765
766
767
...
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
....
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
**    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,
................................................................................

/*
** 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);
    }
  }
}
................................................................................
/*
** 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 
................................................................................
*/
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;
}

/*
................................................................................
** 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);
}

/*
................................................................................
** 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;
}

/*
................................................................................
** (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 ){
................................................................................
      }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;
}
................................................................................
      }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.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
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
....
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
....
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
....
1549
1550
1551
1552
1553
1554
1555
1556
1557

1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
**    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.853 2009/04/07 22:06:57 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
................................................................................
**
** 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 structures may be stored as part of the in-memory database schema,
** for example as part of trigger, view or table definitions. In this case,
** the amount of memory consumed by complex expressions may be significant.
** For this reason, less than sizeof(Expr) bytes may be allocated for some 
** Expr structs stored as part of the in-memory database schema.
**
** If the EP_Reduced flag is set in Expr.flags, then only EXPR_REDUCEDSIZE
** bytes of space are allocated for the expression structure. This is enough
** space to store all fields up to and including the "Token span;" field.
**
** If the EP_TokenOnly flag is set in Expr.flags, then only EXPR_TOKENONLYSIZE
** bytes of space are allocated for the expression structure. This is enough
** space to store all fields up to and including the "Token token;" field.
*/
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_SpanOnly 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 {
................................................................................
#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_SpanOnly   0x8000  /* Expr struct is EXPR_SPANONLYSIZE bytes only */

/*
** 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
................................................................................
#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)
#define EXPR_REDUCEDSIZE        offsetof(Expr,iTable)

#define EXPR_TOKENONLYSIZE      offsetof(Expr,span)
#define EXPR_SPANONLYSIZE       offsetof(Expr,pLeft)

/*
** Flags passed to the sqlite3ExprDup() function. See the header comment 
** above sqlite3ExprDup() for details.
*/
#define EXPRDUP_REDUCE         0x0001
#define EXPRDUP_SPAN           0x0002
#define EXPRDUP_DISTINCTSPAN   0x0004

/*
** 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







|







 







|
|
|
|
|

|
|
|
|
|
|
<







 







|







 







|







 







|
|
>
|
<





|
|
<







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
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
....
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
....
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
....
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
**    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
................................................................................
**
** 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 {
................................................................................
#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
................................................................................
#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
15
16
17
18
19
20
21
22
..
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
**    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.3 2009/04/08 12:21:31 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>
#include <string.h>


/*
................................................................................
** 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_SpanOnly) );
  testcase( ExprHasProperty(pExpr, EP_Reduced) );
  rc = pWalker->xExprCallback(pWalker, pExpr);

  if( rc==WRC_Continue && !ExprHasAnyProperty(pExpr,EP_TokenOnly|EP_SpanOnly) ){
    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;
    }







|







 







|


>
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
**    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>


/*
................................................................................
** 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;
    }