/ Check-in [afadddc3]
Login

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

Overview
Comment:Fix a problem that could cause a crash when a shared-cache schema contains column default values. (CVS 6353)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:afadddc34eee3d6a39102b790ce1a869b33d4286
User & Date: danielk1977 2009-03-17 17:49:00
Context
2009-03-17
22:33
Move the rowid cache out of VdbeCursor and into BtCursor. When multiple BtCursors are open on the same table, set their rowid cache all at the same time. Ticket #3731. (CVS 6354) check-in: 18978583 user: drh tags: trunk
17:49
Fix a problem that could cause a crash when a shared-cache schema contains column default values. (CVS 6353) check-in: afadddc3 user: danielk1977 tags: trunk
15:39
Fix test script bugs in the thread002.test and thread_common.tcl. (CVS 6352) check-in: d137e841 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/build.c.

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


1115
1116
1117
1118
1119
1120
1121
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.522 2009/03/14 08:37:24 danielk1977 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 







|







 







|
>
>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
....
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.523 2009/03/17 17:49:00 danielk1977 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 

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
645
646
647
648
649
650
651
652


653
654
655
656
657
658
659
...
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
...
692
693
694
695
696
697
698

699

700
701
702
703
704
705
706
...
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
...
736
737
738
739
740
741
742

743
744
745
746
747
748
749
750
...
787
788
789
790
791
792
793

794

795
796
797
798
799
800
801
**    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.418 2009/03/05 14:53:18 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,
................................................................................
** If so, remove the quotation marks.
*/
void sqlite3DequoteExpr(sqlite3 *db, Expr *p){
  if( ExprHasAnyProperty(p, EP_Dequoted) ){
    return;
  }
  ExprSetProperty(p, EP_Dequoted);
  if( p->token.dyn==0 && !ExprHasProperty(p, EP_Reduced) ){


    sqlite3TokenCopy(db, &p->token, &p->token);
  }
  sqlite3Dequote((char*)p->token.z);
}

/*
** Return the number of bytes allocated for the expression structure 
................................................................................
*/
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_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_SPAN && (p->token.z!=p->span.z || p->token.n!=p->span.n) ){

    nByte += p->span.n;
  }
  return (nByte+7)&~7;
}

/*
** Return the number of bytes required to create a duplicate of the 
................................................................................
** 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 ){
................................................................................
        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;
          }







|







 







|
>
>







 







|







 







>
|
>







 







|







 







>
|







 







>
|
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
...
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
...
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
...
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
...
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
...
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
**    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.419 2009/03/17 17:49:00 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,
................................................................................
** If so, remove the quotation marks.
*/
void sqlite3DequoteExpr(sqlite3 *db, Expr *p){
  if( ExprHasAnyProperty(p, EP_Dequoted) ){
    return;
  }
  ExprSetProperty(p, EP_Dequoted);
  if( p->token.dyn==0
   && !ExprHasAnyProperty(p, EP_Reduced|EP_TokenOnly|EP_SpanOnly) 
  ){
    sqlite3TokenCopy(db, &p->token, &p->token);
  }
  sqlite3Dequote((char*)p->token.z);
}

/*
** Return the number of bytes allocated for the expression structure 
................................................................................
*/
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 (nByte+7)&~7;
}

/*
** Return the number of bytes required to create a duplicate of the 
................................................................................
** 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 ){
................................................................................
        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;
          }

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1520
1521
1522
1523
1524
1525
1526

1527
1528
1529
1530
1531
1532
1533
**    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.841 2009/03/16 13:19:36 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
................................................................................

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


/*
** 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
....
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
**    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.842 2009/03/17 17:49:00 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
................................................................................

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

Changes to test/shared2.test.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
122
123
124
125
126
127
128
129
























130
131

#
#    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.
#
#***********************************************************************
#
# $Id: shared2.test,v 1.5 2007/08/23 02:47:54 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
db close

ifcapable !shared_cache {
  finish_test
................................................................................

db1 close
db2 close

do_test shared2-3.2 {
  sqlite3_enable_shared_cache 1
} {1}

























sqlite3_enable_shared_cache $::enable_shared_cache
finish_test








|







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#
#    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.
#
#***********************************************************************
#
# $Id: shared2.test,v 1.6 2009/03/17 17:49:00 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
db close

ifcapable !shared_cache {
  finish_test
................................................................................

db1 close
db2 close

do_test shared2-3.2 {
  sqlite3_enable_shared_cache 1
} {1}

file delete -force test.db

sqlite3 db test.db
do_test shared2-4.1 {
  execsql {
    CREATE TABLE t0(a, b);
    CREATE TABLE t1(a, b DEFAULT 'hello world');
  }
} {}
db close

sqlite3 db test.db
sqlite3 db2 test.db

do_test shared2-4.2 {
  execsql { SELECT a, b FROM t0 } db
  execsql { INSERT INTO t1(a) VALUES(1) } db2
} {}

do_test shared2-4.3 {
  db2 close
  db close
} {}

sqlite3_enable_shared_cache $::enable_shared_cache
finish_test