/ Check-in [2d302931]
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:Begin using sqlite3NestedParse() to generate sections of code. (CVS 2059)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2d302931a69d1add1dae9f820133872b4fefe93e
User & Date: drh 2004-11-05 03:56:01
Context
2004-11-05
05:10
More use of sqlite3NestedParse. This version of the code does not work. (CVS 2060) check-in: ac2d5a60 user: drh tags: trunk
03:56
Begin using sqlite3NestedParse() to generate sections of code. (CVS 2059) check-in: 2d302931 user: drh tags: trunk
01:45
Fix bug introduced with (2057). (CVS 2058) check-in: aed2e623 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
** 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.
**
*************************************************************************
** $Id: btree.c,v 1.206 2004/11/05 01:45:14 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
    cellptr += 2;
    cellbody += aSize[i];
  }
  assert( cellbody==pPage->pBt->usableSize );
  pPage->nCell = nCell;
}

/*
** GCC does not define the offsetof() macro so we'll have to do it
** ourselves.
*/
#ifndef offsetof
#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
#endif

/*
** The following parameters determine how many adjacent pages get involved
** in a balancing operation.  NN is the number of neighbors on either side
** of the page that participate in the balancing operation.  NB is the
** total number of pages that participate, including the target page and
** NN neighbors on either side.
**







|







 







<
<
<
<
<
<
<
<







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
3388
3389
3390
3391
3392
3393
3394








3395
3396
3397
3398
3399
3400
3401
** 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.
**
*************************************************************************
** $Id: btree.c,v 1.207 2004/11/05 03:56:01 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
    cellptr += 2;
    cellbody += aSize[i];
  }
  assert( cellbody==pPage->pBt->usableSize );
  pPage->nCell = nCell;
}









/*
** The following parameters determine how many adjacent pages get involved
** in a balancing operation.  NN is the number of neighbors on either side
** of the page that participate in the balancing operation.  NB is the
** total number of pages that participate, including the target page and
** NN neighbors on either side.
**

Changes to src/build.c.

19
20
21
22
23
24
25

26



27
28
29
30
31
32
33
...
119
120
121
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
...
569
570
571
572
573
574
575

576
577
578
579
580
581
582
583
....
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
....
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
....
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
....
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
....
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**

** $Id: build.c,v 1.262 2004/11/05 01:24:13 danielk1977 Exp $



*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
** currently under construction.  When the parser is run recursively
** this way, the final OP_Halt is not appended and other initialization
** and finalization steps are omitted because those are handling by the
** outermost parser.
**
** Not everything is nestable.  This facility is designed to permit
** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER.  Use
** care if you decide to try to use this routine for some other purpose.
*/
void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  char *zSql;
  int rc;
  Parse savedState;


  if( pParse->nErr ) return;
  assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
  va_start(ap, zFormat);
  zSql = sqlite3VMPrintf(zFormat, ap);
  va_end(ap);
  pParse->nested++;
  savedState = *pParse;

  rc = sqlite3RunParser(pParse, zSql, 0);
  sqliteFree(zSql);

  pParse->nested--;
}

/*
** Locate the in-memory structure that describes a particular database
** table given the name of that table and (optionally) the name of the
** database containing the table.  Return NULL if not found.
................................................................................
** This routine is used to check if the UTF-8 string zName is a legal
** unqualified name for a new schema object (table, index, view or
** trigger). All names are legal except those that begin with the string
** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
** is reserved for internal use.
*/
int sqlite3CheckObjectName(Parse *pParse, const char *zName){

  if( !pParse->db->init.busy && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
    sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
    return SQLITE_ERROR;
  }
  return SQLITE_OK;
}

/*
................................................................................
  /* If SQLITE_OMIT_AUTOVACUUM is not defined, then OP_Destroy pushes
  ** an integer onto the stack. If this integer is non-zero, then it is
  ** the root page number of a table moved to location iTable. The 
  ** following writes VDBE code to modify the sqlite_master table to
  ** reflect this. It is assumed that cursor number 0 is a write-cursor
  ** opened on the sqlite_master table.
  */
  static const VdbeOpList updateMaster[] = {
    /* If the Op_Destroy pushed a 0 onto the stack, then skip the following
    ** code. sqlite_master does not need updating in this case.
    */
    { OP_Dup,        0, 0,        0},
    { OP_Integer,    0, 0,        0},
    { OP_Eq,         0, ADDR(17), 0},

................................................................................
    { OP_Column,     0, 4,       0},
    { OP_MakeRecord, 5, 0,       0},
    { OP_PutIntKey,  0, 0,       0}  /* 16 */
  };
#endif

  sqlite3VdbeAddOp(v, OP_Destroy, iTable, iDb);
  sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
#ifndef SQLITE_OMIT_AUTOVACUUM
  base = sqlite3VdbeAddOpList(v, ArraySize(updateMaster), updateMaster);
  sqlite3VdbeChangeP1(v, base+13, iTable);
#endif
}

/*
................................................................................
/*
** This routine is called to do the work of a DROP TABLE statement.
** pName is the name of the table to be dropped.
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
  Table *pTab;
  Vdbe *v;
  int base;
  sqlite3 *db = pParse->db;
  int iDb;

  if( pParse->nErr || sqlite3_malloc_failed ) goto exit_drop_table;
  assert( pName->nSrc==1 );
  pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase);

................................................................................
  }

  /* Generate code to remove the table from the master table
  ** on disk.
  */
  v = sqlite3GetVdbe(pParse);
  if( v ){
    static const VdbeOpList dropTable[] = {
      { OP_Rewind,     0, ADDR(13), 0},
      { OP_String8,    0, 0,        0}, /* 1 */
      { OP_MemStore,   1, 1,        0},
      { OP_MemLoad,    1, 0,        0}, /* 3 */
      { OP_Column,     0, 2,        0}, /* sqlite_master.tbl_name */
      { OP_Ne,         0, ADDR(12), 0},
      { OP_String8,    0, 0,        "trigger"},
      { OP_Column,     0, 2,        0}, /* sqlite_master.type */
      { OP_Eq,         0, ADDR(12), 0},
      { OP_Delete,     0, 0,        0},
      { OP_Rewind,     0, ADDR(13), 0},
      { OP_Goto,       0, ADDR(3),  0},
      { OP_Next,       0, ADDR(3),  0}, /* 12 */
    };
    /* Index *pIdx; */
    Trigger *pTrigger;
    sqlite3BeginWriteOperation(pParse, 0, pTab->iDb);

    /* Drop all triggers associated with the table being dropped. Code
    ** is generated to remove entries from sqlite_master and/or
    ** sqlite_temp_master if required.
    */
................................................................................
    /* Drop all SQLITE_MASTER table and index entries that refer to the
    ** table. The program name loops through the master table and deletes
    ** every row that refers to a table of the same name as the one being
    ** dropped. Triggers are handled seperately because a trigger can be
    ** created in the temp database that refers to a table in another
    ** database.
    */
    sqlite3OpenMasterTable(v, pTab->iDb);
    base = sqlite3VdbeAddOpList(v, ArraySize(dropTable), dropTable);
    sqlite3VdbeChangeP3(v, base+1, pTab->zName, 0);
    sqlite3ChangeCookie(db, v, pTab->iDb);
    if( !isView ){
/*
      sqlite3VdbeAddOp(v, OP_Destroy, pTab->tnum, pTab->iDb);
      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
        sqlite3VdbeAddOp(v, OP_Destroy, pIdx->tnum, pIdx->iDb);
      }
*/
      destroyTable(v, pTab);
    }
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeOp3(v, OP_DropTable, pTab->iDb, 0, pTab->zName, 0);
  }
  sqliteViewResetAll(db, iDb);

exit_drop_table:
  sqlite3SrcListDelete(pName);
}







>
|
>
>
>







 







|





|
>
>






|
>


>







 







>
|







 







|







 







|







 







<







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|
|
|
<

<
<
<
<
<
<


<







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...
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
...
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
....
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
....
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
....
1740
1741
1742
1743
1744
1745
1746

1747
1748
1749
1750
1751
1752
1753
....
1798
1799
1800
1801
1802
1803
1804
















1805
1806
1807
1808
1809
1810
1811
....
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828

1829






1830
1831

1832
1833
1834
1835
1836
1837
1838
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
<<<<<<< build.c
** $Id: build.c,v 1.263 2004/11/05 03:56:02 drh Exp $
=======
** $Id: build.c,v 1.263 2004/11/05 03:56:02 drh Exp $
>>>>>>> 1.262
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
** currently under construction.  When the parser is run recursively
** this way, the final OP_Halt is not appended and other initialization
** and finalization steps are omitted because those are handling by the
** outermost parser.
**
** Not everything is nestable.  This facility is designed to permit
** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER.  Use
** care if you decide to try to use this routine for some other purposes.
*/
void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  char *zSql;
  int rc;
# define SAVE_SZ  (sizeof(Parse) - offsetof(Parse,nVar))
  char saveBuf[SAVE_SZ];

  if( pParse->nErr ) return;
  assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
  va_start(ap, zFormat);
  zSql = sqlite3VMPrintf(zFormat, ap);
  va_end(ap);
  pParse->nested++;
  memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
  memset(&pParse->nVar, 0, SAVE_SZ);
  rc = sqlite3RunParser(pParse, zSql, 0);
  sqliteFree(zSql);
  memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
  pParse->nested--;
}

/*
** Locate the in-memory structure that describes a particular database
** table given the name of that table and (optionally) the name of the
** database containing the table.  Return NULL if not found.
................................................................................
** This routine is used to check if the UTF-8 string zName is a legal
** unqualified name for a new schema object (table, index, view or
** trigger). All names are legal except those that begin with the string
** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
** is reserved for internal use.
*/
int sqlite3CheckObjectName(Parse *pParse, const char *zName){
  if( !pParse->db->init.busy && pParse->nested==0 
          && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
    sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
    return SQLITE_ERROR;
  }
  return SQLITE_OK;
}

/*
................................................................................
  /* If SQLITE_OMIT_AUTOVACUUM is not defined, then OP_Destroy pushes
  ** an integer onto the stack. If this integer is non-zero, then it is
  ** the root page number of a table moved to location iTable. The 
  ** following writes VDBE code to modify the sqlite_master table to
  ** reflect this. It is assumed that cursor number 0 is a write-cursor
  ** opened on the sqlite_master table.
  */
  static /*const*/ VdbeOpList updateMaster[] = {
    /* If the Op_Destroy pushed a 0 onto the stack, then skip the following
    ** code. sqlite_master does not need updating in this case.
    */
    { OP_Dup,        0, 0,        0},
    { OP_Integer,    0, 0,        0},
    { OP_Eq,         0, ADDR(17), 0},

................................................................................
    { OP_Column,     0, 4,       0},
    { OP_MakeRecord, 5, 0,       0},
    { OP_PutIntKey,  0, 0,       0}  /* 16 */
  };
#endif

  sqlite3VdbeAddOp(v, OP_Destroy, iTable, iDb);
  /* sqlite3VdbeAddOp(v, OP_Pop, 1, 0); */
#ifndef SQLITE_OMIT_AUTOVACUUM
  base = sqlite3VdbeAddOpList(v, ArraySize(updateMaster), updateMaster);
  sqlite3VdbeChangeP1(v, base+13, iTable);
#endif
}

/*
................................................................................
/*
** This routine is called to do the work of a DROP TABLE statement.
** pName is the name of the table to be dropped.
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
  Table *pTab;
  Vdbe *v;

  sqlite3 *db = pParse->db;
  int iDb;

  if( pParse->nErr || sqlite3_malloc_failed ) goto exit_drop_table;
  assert( pName->nSrc==1 );
  pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase);

................................................................................
  }

  /* Generate code to remove the table from the master table
  ** on disk.
  */
  v = sqlite3GetVdbe(pParse);
  if( v ){
















    Trigger *pTrigger;
    sqlite3BeginWriteOperation(pParse, 0, pTab->iDb);

    /* Drop all triggers associated with the table being dropped. Code
    ** is generated to remove entries from sqlite_master and/or
    ** sqlite_temp_master if required.
    */
................................................................................
    /* Drop all SQLITE_MASTER table and index entries that refer to the
    ** table. The program name loops through the master table and deletes
    ** every row that refers to a table of the same name as the one being
    ** dropped. Triggers are handled seperately because a trigger can be
    ** created in the temp database that refers to a table in another
    ** database.
    */
    sqlite3NestedParse(pParse, 
        "DELETE FROM %Q.%Q WHERE tbl_name=%Q and type!='trigger'",
        db->aDb[pTab->iDb].zName, SCHEMA_TABLE(pTab->iDb), pTab->zName);

    if( !isView ){






      destroyTable(v, pTab);
    }

    sqlite3VdbeOp3(v, OP_DropTable, pTab->iDb, 0, pTab->zName, 0);
  }
  sqliteViewResetAll(db, iDb);

exit_drop_table:
  sqlite3SrcListDelete(pName);
}

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
103
104
105
106
107
108
109








110
111
112
113
114
115
116
...
989
990
991
992
993
994
995





996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019







1020
1021
1022
1023




1024
1025






1026
1027
1028
1029
1030
1031

1032
1033
1034
1035
1036
1037
1038
**    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.331 2004/11/05 00:43:12 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it.  If the OS lacks
................................................................................
*/
/* #define SQLITE_OMIT_AUTHORIZATION  1 */
/* #define SQLITE_OMIT_INMEMORYDB     1 */
/* #define SQLITE_OMIT_VACUUM         1 */
/* #define SQLITE_OMIT_DATETIME_FUNCS 1 */
/* #define SQLITE_OMIT_PROGRESS_CALLBACK 1 */









/*
** Integers of known sizes.  These typedefs might change for architectures
** where the sizes very.  Preprocessor macros are available so that the
** types can be conveniently redefined at compile-type.  Like this:
**
**         cc '-DUINTPTR_TYPE=long long int' ...
*/
................................................................................
  FuncDef *pFunc;   /* Information about the aggregate function */
};

/*
** An SQL parser context.  A copy of this structure is passed through
** the parser and down into all the parser action routine in order to
** carry around information that is global to the entire parse.





*/
struct Parse {
  sqlite3 *db;         /* The main database structure */
  int rc;              /* Return code from execution */
  char *zErrMsg;       /* An error message */
  Token sErrToken;     /* The token at which the error occurred */
  Token sNameToken;    /* Token with unqualified schema object name */
  Token sLastToken;    /* The last token parsed */
  const char *zSql;    /* All SQL text */
  const char *zTail;   /* All SQL text past the last semicolon parsed */
  Table *pNewTable;    /* A table being constructed by CREATE TABLE */
  Vdbe *pVdbe;         /* An engine for executing database bytecode */
  u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
  u8 explain;          /* True if the EXPLAIN flag is found on the query */
  u8 nameClash;        /* A permanent table name clashes with temp table name */
  u8 useAgg;           /* If true, extract field values from the aggregator
                       ** while generating expressions.  Normally false */
  u8 checkSchema;      /* Causes schema cookie check after an error */
  u8 nested;           /* Number of nested calls to the parser/code generator */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  int nAgg;            /* Number of aggregate expressions */







  int nVar;            /* Number of '?' variables seen in the SQL so far */
  int nVarExpr;        /* Number of used slots in apVarExpr[] */
  int nVarExprAlloc;   /* Number of allocated slots in apVarExpr[] */
  Expr **apVarExpr;    /* Pointers to :aaa and $aaaa wildcard expressions */




  AggExpr *aAgg;       /* An array of aggregate expressions */
  const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */






  Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
  TriggerStack *trigStack;  /* Trigger actions being coded */
  u32 cookieMask;      /* Bitmask of schema verified databases */
  int cookieValue[MAX_ATTACHED+2];  /* Values of cookies to verify */
  int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
  u32 writeMask;       /* Start a write transaction on these databases */

};

/*
** An instance of the following structure can be declared on a stack and used
** to save the Parse.zAuthContext value so that it can be restored later.
*/
struct AuthContext {







|







 







>
>
>
>
>
>
>
>







 







>
>
>
>
>





<
<
<
<
<
<


<

<
<






|
>
>
>
>
>
>
>




>
>
>
>

<
>
>
>
>
>
>


<
<
<
<
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
...
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013






1014
1015

1016


1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039

1040
1041
1042
1043
1044
1045
1046
1047




1048
1049
1050
1051
1052
1053
1054
1055
**    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.332 2004/11/05 03:56:02 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it.  If the OS lacks
................................................................................
*/
/* #define SQLITE_OMIT_AUTHORIZATION  1 */
/* #define SQLITE_OMIT_INMEMORYDB     1 */
/* #define SQLITE_OMIT_VACUUM         1 */
/* #define SQLITE_OMIT_DATETIME_FUNCS 1 */
/* #define SQLITE_OMIT_PROGRESS_CALLBACK 1 */

/*
** GCC does not define the offsetof() macro so we'll have to do it
** ourselves.
*/
#ifndef offsetof
#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
#endif

/*
** Integers of known sizes.  These typedefs might change for architectures
** where the sizes very.  Preprocessor macros are available so that the
** types can be conveniently redefined at compile-type.  Like this:
**
**         cc '-DUINTPTR_TYPE=long long int' ...
*/
................................................................................
  FuncDef *pFunc;   /* Information about the aggregate function */
};

/*
** An SQL parser context.  A copy of this structure is passed through
** the parser and down into all the parser action routine in order to
** carry around information that is global to the entire parse.
**
** The structure is divided into two parts.  When the parser and code
** generate call themselves recursively, the first part of the structure
** is constant but the second part is reset at the beginning and end of
** each recursion.
*/
struct Parse {
  sqlite3 *db;         /* The main database structure */
  int rc;              /* Return code from execution */
  char *zErrMsg;       /* An error message */






  Vdbe *pVdbe;         /* An engine for executing database bytecode */
  u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */

  u8 nameClash;        /* A permanent table name clashes with temp table name */


  u8 checkSchema;      /* Causes schema cookie check after an error */
  u8 nested;           /* Number of nested calls to the parser/code generator */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  u32 cookieMask;      /* Bitmask of schema verified databases */
  int cookieValue[MAX_ATTACHED+2];  /* Values of cookies to verify */
  int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
  u32 writeMask;       /* Start a write transaction on these databases */

  /* Above is constant between recursions.  Below is reset before and after
  ** each recursion */

  int nVar;            /* Number of '?' variables seen in the SQL so far */
  int nVarExpr;        /* Number of used slots in apVarExpr[] */
  int nVarExprAlloc;   /* Number of allocated slots in apVarExpr[] */
  Expr **apVarExpr;    /* Pointers to :aaa and $aaaa wildcard expressions */
  u8 explain;          /* True if the EXPLAIN flag is found on the query */
  u8 useAgg;           /* If true, extract field values from the aggregator
                       ** while generating expressions.  Normally false */
  int nAgg;            /* Number of aggregate expressions */
  AggExpr *aAgg;       /* An array of aggregate expressions */

  Token sErrToken;     /* The token at which the error occurred */
  Token sNameToken;    /* Token with unqualified schema object name */
  Token sLastToken;    /* The last token parsed */
  const char *zSql;    /* All SQL text */
  const char *zTail;   /* All SQL text past the last semicolon parsed */
  Table *pNewTable;    /* A table being constructed by CREATE TABLE */
  Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
  TriggerStack *trigStack;  /* Trigger actions being coded */




  const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
};

/*
** An instance of the following structure can be declared on a stack and used
** to save the Parse.zAuthContext value so that it can be restored later.
*/
struct AuthContext {

Changes to test/attach2.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
321
322
323
324
325
326
327

328
329
330
331
332
333
334
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
# $Id: attach2.test,v 1.27 2004/10/07 22:22:39 drh Exp $
#

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


# Ticket #354
................................................................................
    CREATE TABLE aux.tbl(a, b, c);
    COMMIT;
  }
} {}
do_test attach2-5.3 {
  lsort [glob test.db*]
} {test.db test.db2}

do_test attach2-5.4 {
  execsql {
    BEGIN;
    DROP TABLE aux.tbl;
    DROP TABLE tbl;
    ROLLBACK;
  }







|







 







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
# $Id: attach2.test,v 1.28 2004/11/05 03:56:02 drh Exp $
#

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


# Ticket #354
................................................................................
    CREATE TABLE aux.tbl(a, b, c);
    COMMIT;
  }
} {}
do_test attach2-5.3 {
  lsort [glob test.db*]
} {test.db test.db2}
execsql {pragma vdbe_trace=on}
do_test attach2-5.4 {
  execsql {
    BEGIN;
    DROP TABLE aux.tbl;
    DROP TABLE tbl;
    ROLLBACK;
  }