/ Check-in [cb236cb9]
Login

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

Overview
Comment:Enhance the virtual table in test_schemapool.c so that it can be used to check that SHARED_SCHEMA connections are not allocating and freeing schemas when they should not be.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | reuse-schema
Files: files | file ages | folders
SHA3-256:cb236cb98564b870317ba3e481a3c7d7f9769b0294a01246bcb724f04e1e7b10
User & Date: dan 2019-02-15 19:36:47
Wiki:reuse-schema
Context
2019-02-18
18:16
Ensure that creating temp schema items does not cause an OPEN_SHARABLE_SCHEMA connection to load all schemas into memory. check-in: 88cbf54e user: dan tags: reuse-schema
2019-02-15
19:36
Enhance the virtual table in test_schemapool.c so that it can be used to check that SHARED_SCHEMA connections are not allocating and freeing schemas when they should not be. check-in: cb236cb9 user: dan tags: reuse-schema
19:00
Fix a problem with eponymous virtual tables and SHARED_SCHEMA databases. Also, after preparing statements that require all database schemas (REINDEX, ANALYZE, CREATE, DROP and some PRAGMA statements), do not allow the database connection to return more than one schema to each schema-pool. check-in: ecf6251e user: dan tags: reuse-schema
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/callback.c.

29
30
31
32
33
34
35

36
37
38
39
40
41
42
...
618
619
620
621
622
623
624

625
626
627
628
629
630
631
**      SchemaPool. DB_SchemaLoaded flag is set.
**
**   3) pSPool!=0, pSchema points to the SchemaPool's static object
**      (SchemaPool.sSchema).
*/
struct SchemaPool {
  int nRef;                       /* Number of pointers to this object */

  u64 cksum;                      /* Checksum for this Schema contents */
  Schema *pSchema;                /* Linked list of Schema objects */
  Schema sSchema;                 /* The single dummy schema object */
  SchemaPool *pNext;              /* Next element in schemaPoolList */
};

#ifdef SQLITE_DEBUG
................................................................................
  ** at least one other copy of the schema being released, delete it instead
  ** of returning it to the schema-pool.  */
  if( db->mDbFlags & DBFLAG_FreeSchema ){
    int i;
    for(i=0; i<db->nDb; i++){
      Db *p = &db->aDb[i];
      if( p!=pDb && p->pSchema!=&pSPool->sSchema && pDb->pSPool==p->pSPool ){

        schemaDelete(pRelease);
        return;
      }
    }
  }

  pRelease->pNext = pDb->pSPool->pSchema;







>







 







>







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
...
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
**      SchemaPool. DB_SchemaLoaded flag is set.
**
**   3) pSPool!=0, pSchema points to the SchemaPool's static object
**      (SchemaPool.sSchema).
*/
struct SchemaPool {
  int nRef;                       /* Number of pointers to this object */
  int nDelete;                    /* Schema objects deleted by ReleaseAll() */
  u64 cksum;                      /* Checksum for this Schema contents */
  Schema *pSchema;                /* Linked list of Schema objects */
  Schema sSchema;                 /* The single dummy schema object */
  SchemaPool *pNext;              /* Next element in schemaPoolList */
};

#ifdef SQLITE_DEBUG
................................................................................
  ** at least one other copy of the schema being released, delete it instead
  ** of returning it to the schema-pool.  */
  if( db->mDbFlags & DBFLAG_FreeSchema ){
    int i;
    for(i=0; i<db->nDb; i++){
      Db *p = &db->aDb[i];
      if( p!=pDb && p->pSchema!=&pSPool->sSchema && pDb->pSPool==p->pSPool ){
        pSPool->nDelete++;
        schemaDelete(pRelease);
        return;
      }
    }
  }

  pRelease->pNext = pDb->pSPool->pSchema;

Changes to src/test_schemapool.c.

25
26
27
28
29
30
31
32

33


34
35
36
37
38
39
40
...
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
...
132
133
134
135
136
137
138

139
140
141
142
143
144
145
...
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
/* The code in this file defines a sqlite3 virtual-table module with
** the following schema.
*/
#define SCHEMAPOOL_SCHEMA \
"CREATE TABLE x("         \
"  cksum   INTEGER, "     \
"  nref    INTEGER, "     \
"  nschema INTEGER  "     \

")"



typedef struct schemapool_vtab schemapool_vtab;
typedef struct schemapool_cursor schemapool_cursor;

/* A schema table object */
struct schemapool_vtab {
  sqlite3_vtab base;
................................................................................
}

/*
** Retrieve a column of data.
*/
static int schemaPoolColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
  schemapool_cursor *pCur = (schemapool_cursor*)cur;
  assert( i==0 || i==1 || i==2 );
  sqlite3_result_int64(ctx, pCur->aData[pCur->iRow*3 + i]);
  return SQLITE_OK;
}

/*
** Retrieve the current rowid.
*/
static int schemaPoolRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
................................................................................
  schemapool_cursor *pCur = (schemapool_cursor*)cur;
  pCur->iRow++;
  return SQLITE_OK;
}

struct SchemaPool {
  int nRef;                       /* Number of pointers to this object */

  u64 cksum;                      /* Checksum for this Schema contents */
  Schema *pSchema;                /* Linked list of Schema objects */
  Schema sSchema;                 /* The single dummy schema object */
  SchemaPool *pNext;              /* Next element in schemaPoolList */
};
extern SchemaPool *sqlite3SchemaPoolList(void);

................................................................................

  for(pSPool = sqlite3SchemaPoolList(); pSPool; pSPool=pSPool->pNext){
    pCur->nRow++;
  }

  if( pCur->nRow ){
    int iRow = 0;

    pCur->aData = (i64*)sqlite3_malloc(3 * pCur->nRow * sizeof(i64));
    if( pCur->aData==0 ) return SQLITE_NOMEM;
    for(pSPool = sqlite3SchemaPoolList(); pSPool; pSPool=pSPool->pNext){
      Schema *p;
      i64 nSchema = 0;
      for(p=pSPool->pSchema; p; p=p->pNext){
        nSchema++;
      }
      pCur->aData[0 + iRow*3] = pSPool->cksum;
      pCur->aData[1 + iRow*3] = (i64)pSPool->nRef;
      pCur->aData[2 + iRow*3] = nSchema;

      iRow++;
    }
  }

  return SQLITE_OK;
}








|
>

>
>







 







|
|







 







>







 







>
|







|
|
|
>







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
...
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/* The code in this file defines a sqlite3 virtual-table module with
** the following schema.
*/
#define SCHEMAPOOL_SCHEMA \
"CREATE TABLE x("         \
"  cksum   INTEGER, "     \
"  nref    INTEGER, "     \
"  nschema INTEGER, "     \
"  ndelete INTEGER  "     \
")"

#define SCHEMAPOOL_NFIELD 4

typedef struct schemapool_vtab schemapool_vtab;
typedef struct schemapool_cursor schemapool_cursor;

/* A schema table object */
struct schemapool_vtab {
  sqlite3_vtab base;
................................................................................
}

/*
** Retrieve a column of data.
*/
static int schemaPoolColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
  schemapool_cursor *pCur = (schemapool_cursor*)cur;
  assert( i==0 || i==1 || i==2 || i==3 );
  sqlite3_result_int64(ctx, pCur->aData[pCur->iRow*SCHEMAPOOL_NFIELD + i]);
  return SQLITE_OK;
}

/*
** Retrieve the current rowid.
*/
static int schemaPoolRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
................................................................................
  schemapool_cursor *pCur = (schemapool_cursor*)cur;
  pCur->iRow++;
  return SQLITE_OK;
}

struct SchemaPool {
  int nRef;                       /* Number of pointers to this object */
  int nDelete;                    /* Schema objects deleted by ReleaseAll() */
  u64 cksum;                      /* Checksum for this Schema contents */
  Schema *pSchema;                /* Linked list of Schema objects */
  Schema sSchema;                 /* The single dummy schema object */
  SchemaPool *pNext;              /* Next element in schemaPoolList */
};
extern SchemaPool *sqlite3SchemaPoolList(void);

................................................................................

  for(pSPool = sqlite3SchemaPoolList(); pSPool; pSPool=pSPool->pNext){
    pCur->nRow++;
  }

  if( pCur->nRow ){
    int iRow = 0;
    int nByte = SCHEMAPOOL_NFIELD * pCur->nRow * sizeof(i64);
    pCur->aData = (i64*)sqlite3_malloc(nByte);
    if( pCur->aData==0 ) return SQLITE_NOMEM;
    for(pSPool = sqlite3SchemaPoolList(); pSPool; pSPool=pSPool->pNext){
      Schema *p;
      i64 nSchema = 0;
      for(p=pSPool->pSchema; p; p=p->pNext){
        nSchema++;
      }
      pCur->aData[0 + iRow*SCHEMAPOOL_NFIELD] = pSPool->cksum;
      pCur->aData[1 + iRow*SCHEMAPOOL_NFIELD] = (i64)pSPool->nRef;
      pCur->aData[2 + iRow*SCHEMAPOOL_NFIELD] = nSchema;
      pCur->aData[3 + iRow*SCHEMAPOOL_NFIELD] = (i64)pSPool->nDelete;
      iRow++;
    }
  }

  return SQLITE_OK;
}

Changes to test/reuse2.test.

70
71
72
73
74
75
76
77

78
79
80
81
82
83
84

85
86
87
88
89

90
91
92
93
94
95
96
97

98
99
100
101
102

103
104
105
106
107

108
109
110
111
112

113
114
115
116
117
118
119
120
...
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

157
158
159
160
161
162

163
164
165
166
167
168

169
170
171
172
173
174
175

176
177
178
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213
214
215
216
217

218
219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
254
...
265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297
298

299
300
301
302
303
304

305
306
307
308
} {}

do_execsql_test -db db1 3.2.1 { SELECT * FROM t1 }
do_execsql_test -db db2 3.2.2 { SELECT * FROM t1 }

register_schemapool_module db
do_execsql_test 3.3 { 
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool;

} {nref=2 nschema=1}

sqlite3 db3 test.db -shared-schema 1
register_schemapool_module db3

do_execsql_test 3.5 { 
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool;

} {nref=2 nschema=1}

do_execsql_test -db db3 3.6 { 
  SELECT * FROM t1;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool;

} {nref=3 nschema=1}

do_execsql_test 3.7 { 
  CREATE TABLE t2(x);
}

do_execsql_test 3.8 { 
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool;

} {nref=3 nschema=1}

do_execsql_test -db db1 3.9.1 { SELECT * FROM t1 }
do_execsql_test 3.9.2 { 
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {nref=1 nschema=1 nref=2 nschema=1}

do_execsql_test -db db2 3.10.1 { SELECT * FROM t1 }
do_execsql_test 3.10.2 { 
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {nref=1 nschema=1 nref=2 nschema=1}

do_execsql_test -db db3 3.11.1 { SELECT * FROM t1 }
do_execsql_test 3.11.2 { 
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {nref=3 nschema=1}

#--------------------------------------------------------------------------
catch {db1 close}
catch {db2 close}
catch {db3 close}
reset_db
do_execsql_test 4.0.1 {
................................................................................
  }
  sqlite3 db  test.db
  sqlite3 db2 test.db -shared-schema 1
} {}

register_schemapool_module db
do_execsql_test 4.0.3 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {}

do_test 4.1.1 {
  execsql { 
    ATTACH 'test.db1' AS db1; 
    ATTACH 'test.db2' AS db2;
    ATTACH 'test.db3' AS db3;
    ATTACH 'test.db4' AS db4;
    ATTACH 'test.db5' AS db5;
  } db2
} {}
do_execsql_test 4.1.2 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {}
do_execsql_test -db db2 4.1.3 {
  SELECT * FROM db3.x1
}
do_execsql_test 4.1.4 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {nref=1 nschema=1}
do_execsql_test -db db2 4.1.5 {
  SELECT * FROM db2.x1
}
do_execsql_test 4.1.6 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {nref=2 nschema=1}
do_execsql_test -db db2 4.1.7 {
  SELECT * FROM x1
}
do_execsql_test 4.1.8 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {nref=6 nschema=1}

do_test 4.2.1 {
  catchsql { SELECT * FROM abc } db2
} {1 {no such table: abc}}
do_execsql_test 4.2.2 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {nref=6 nschema=1}

register_schemapool_module db2
do_execsql_test -db db2 4.3.1 {
  INSERT INTO x1 VALUES(1, 2, 3);
  INSERT INTO db1.x1 VALUES(4, 5, 6);
  INSERT INTO db2.x1 VALUES(7, 8, 9);
  INSERT INTO db3.x1 VALUES(10, 11, 12);
  INSERT INTO db4.x1 VALUES(13, 14, 15);
  INSERT INTO db5.x1 VALUES(16, 17, 18);
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {nref=6 nschema=1}

do_execsql_test -db db2 4.3.2 {
  SELECT * FROM db5.x1;
  SELECT * FROM db4.x1;
  SELECT * FROM db3.x1;
  SELECT * FROM db2.x1;
  SELECT * FROM db1.x1;
  SELECT * FROM x1;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {
  16 17 18  13 14 15  10 11 12  7 8 9  4 5 6  1 2 3
  nref=6 nschema=1
}

do_execsql_test -db db2 4.3.3 {
  UPDATE x1 SET a=a+10;
  UPDATE db5.x1 SET a=a+10;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {
  nref=6 nschema=1
}

do_execsql_test -db db2 4.3.4 {
  SELECT * FROM db5.x1;
  SELECT * FROM db4.x1;
  SELECT * FROM db3.x1;
  SELECT * FROM db2.x1;
  SELECT * FROM db1.x1;
  SELECT * FROM x1;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {
  26 17 18  13 14 15  10 11 12  7 8 9  4 5 6  11 2 3
  nref=6 nschema=1
}

do_execsql_test -db db2 4.3.5 {
  DELETE FROM db3.x1;
  DELETE FROM x1;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {
  nref=6 nschema=1
}

do_execsql_test -db db2 4.3.6 {
  SELECT * FROM db5.x1;
  SELECT * FROM db4.x1;
  SELECT * FROM db3.x1;
  SELECT * FROM db2.x1;
  SELECT * FROM db1.x1;
  SELECT * FROM x1;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {
  26 17 18  13 14 15  7 8 9  4 5 6 
  nref=6 nschema=1
}

do_execsql_test -db db2 4.3.6 {
  SELECT * FROM db5.x1, db4.x1, db1.x1;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {26 17 18 13 14 15 4 5 6 nref=6 nschema=3}

#--------------------------------------------------------------------------
# Test the incremental-blob API with REUSE_SCHEMA connections.
#
catch {db1 close}
catch {db2 close}
catch {db3 close}
................................................................................
    forcecopy test.db test.db${i}
    sqlite3 db test.db${i}
    db eval { INSERT INTO bbb VALUES(123, 'database_' || $i) }
    db close
    db2 eval "ATTACH 'test.db${i}' AS db${i}"
  }
  execsql {
    SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

  } db2
} {nref=6 nschema=1}

do_test 5.1.1 {
  set res [list]
  for {set i 1} {$i<6} {incr i} {
    set chan [db2 incrblob db${i} bbb b 123]
    lappend res [gets $chan]
    close $chan
  }
  set res
} {database_1 database_2 database_3 database_4 database_5}

do_execsql_test -db db2 5.1.2 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {nref=6 nschema=1}

do_test 5.2.1 {
  sqlite3_table_column_metadata db2 main bbb a
} {INTEGER BINARY 0 1 0}
do_test 5.2.2 {
  sqlite3_table_column_metadata db2 main bbb b
} {{} BINARY 0 0 0}

do_execsql_test -db db2 5.2.3 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {nref=6 nschema=1}

breakpoint
do_execsql_test -db db2 5.2.4 {
  PRAGMA integrity_check;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;

} {ok nref=6 nschema=1}

finish_test








|
>
|





|
>
|



|
>
|






|
>
|



|
>
|



|
>
|



|
>
|







 







|
>












|
>





|
>
|




|
>
|




|
>
|





|
>
|









|
>
|








|
>


|





|
>

|









|
>


|





|
>

|









|
>


|




|
>
|







 







|
>

|












|
>
|









|
>
|

<


|
>
|



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
...
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
...
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

324
325
326
327
328
329
330
331
} {}

do_execsql_test -db db1 3.2.1 { SELECT * FROM t1 }
do_execsql_test -db db2 3.2.2 { SELECT * FROM t1 }

register_schemapool_module db
do_execsql_test 3.3 { 
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {nref=2 nschema=1 ndelete=0}

sqlite3 db3 test.db -shared-schema 1
register_schemapool_module db3

do_execsql_test 3.5 { 
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {nref=2 nschema=1 ndelete=0}

do_execsql_test -db db3 3.6 { 
  SELECT * FROM t1;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {nref=3 nschema=1 ndelete=0}

do_execsql_test 3.7 { 
  CREATE TABLE t2(x);
}

do_execsql_test 3.8 { 
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {nref=3 nschema=1 ndelete=0}

do_execsql_test -db db1 3.9.1 { SELECT * FROM t1 }
do_execsql_test 3.9.2 { 
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {nref=1 nschema=1 ndelete=0 nref=2 nschema=1 ndelete=0}

do_execsql_test -db db2 3.10.1 { SELECT * FROM t1 }
do_execsql_test 3.10.2 { 
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool ORDER BY 1;
} {nref=1 nschema=1 ndelete=0 nref=2 nschema=1 ndelete=0}

do_execsql_test -db db3 3.11.1 { SELECT * FROM t1 }
do_execsql_test 3.11.2 { 
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {nref=3 nschema=1 ndelete=0}

#--------------------------------------------------------------------------
catch {db1 close}
catch {db2 close}
catch {db3 close}
reset_db
do_execsql_test 4.0.1 {
................................................................................
  }
  sqlite3 db  test.db
  sqlite3 db2 test.db -shared-schema 1
} {}

register_schemapool_module db
do_execsql_test 4.0.3 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {}

do_test 4.1.1 {
  execsql { 
    ATTACH 'test.db1' AS db1; 
    ATTACH 'test.db2' AS db2;
    ATTACH 'test.db3' AS db3;
    ATTACH 'test.db4' AS db4;
    ATTACH 'test.db5' AS db5;
  } db2
} {}
do_execsql_test 4.1.2 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {}
do_execsql_test -db db2 4.1.3 {
  SELECT * FROM db3.x1
}
do_execsql_test 4.1.4 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {nref=1 nschema=1 ndelete=0}
do_execsql_test -db db2 4.1.5 {
  SELECT * FROM db2.x1
}
do_execsql_test 4.1.6 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {nref=2 nschema=1 ndelete=0}
do_execsql_test -db db2 4.1.7 {
  SELECT * FROM x1
}
do_execsql_test 4.1.8 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {nref=6 nschema=1 ndelete=0}

do_test 4.2.1 {
  catchsql { SELECT * FROM abc } db2
} {1 {no such table: abc}}
do_execsql_test 4.2.2 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {nref=6 nschema=1 ndelete=0}

register_schemapool_module db2
do_execsql_test -db db2 4.3.1 {
  INSERT INTO x1 VALUES(1, 2, 3);
  INSERT INTO db1.x1 VALUES(4, 5, 6);
  INSERT INTO db2.x1 VALUES(7, 8, 9);
  INSERT INTO db3.x1 VALUES(10, 11, 12);
  INSERT INTO db4.x1 VALUES(13, 14, 15);
  INSERT INTO db5.x1 VALUES(16, 17, 18);
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {nref=6 nschema=1 ndelete=0}

do_execsql_test -db db2 4.3.2 {
  SELECT * FROM db5.x1;
  SELECT * FROM db4.x1;
  SELECT * FROM db3.x1;
  SELECT * FROM db2.x1;
  SELECT * FROM db1.x1;
  SELECT * FROM x1;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {
  16 17 18  13 14 15  10 11 12  7 8 9  4 5 6  1 2 3
  nref=6 nschema=1 ndelete=0
}

do_execsql_test -db db2 4.3.3 {
  UPDATE x1 SET a=a+10;
  UPDATE db5.x1 SET a=a+10;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {
  nref=6 nschema=1 ndelete=0
}

do_execsql_test -db db2 4.3.4 {
  SELECT * FROM db5.x1;
  SELECT * FROM db4.x1;
  SELECT * FROM db3.x1;
  SELECT * FROM db2.x1;
  SELECT * FROM db1.x1;
  SELECT * FROM x1;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {
  26 17 18  13 14 15  10 11 12  7 8 9  4 5 6  11 2 3
  nref=6 nschema=1 ndelete=0
}

do_execsql_test -db db2 4.3.5 {
  DELETE FROM db3.x1;
  DELETE FROM x1;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {
  nref=6 nschema=1 ndelete=0
}

do_execsql_test -db db2 4.3.6 {
  SELECT * FROM db5.x1;
  SELECT * FROM db4.x1;
  SELECT * FROM db3.x1;
  SELECT * FROM db2.x1;
  SELECT * FROM db1.x1;
  SELECT * FROM x1;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {
  26 17 18  13 14 15  7 8 9  4 5 6 
  nref=6 nschema=1 ndelete=0
}

do_execsql_test -db db2 4.3.6 {
  SELECT * FROM db5.x1, db4.x1, db1.x1;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {26 17 18 13 14 15 4 5 6 nref=6 nschema=3 ndelete=0}

#--------------------------------------------------------------------------
# Test the incremental-blob API with REUSE_SCHEMA connections.
#
catch {db1 close}
catch {db2 close}
catch {db3 close}
................................................................................
    forcecopy test.db test.db${i}
    sqlite3 db test.db${i}
    db eval { INSERT INTO bbb VALUES(123, 'database_' || $i) }
    db close
    db2 eval "ATTACH 'test.db${i}' AS db${i}"
  }
  execsql {
    SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
      FROM schemapool;
  } db2
} {nref=6 nschema=1 ndelete=0}

do_test 5.1.1 {
  set res [list]
  for {set i 1} {$i<6} {incr i} {
    set chan [db2 incrblob db${i} bbb b 123]
    lappend res [gets $chan]
    close $chan
  }
  set res
} {database_1 database_2 database_3 database_4 database_5}

do_execsql_test -db db2 5.1.2 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {nref=6 nschema=1 ndelete=0}

do_test 5.2.1 {
  sqlite3_table_column_metadata db2 main bbb a
} {INTEGER BINARY 0 1 0}
do_test 5.2.2 {
  sqlite3_table_column_metadata db2 main bbb b
} {{} BINARY 0 0 0}

do_execsql_test -db db2 5.2.3 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {nref=6 nschema=1 ndelete=0}


do_execsql_test -db db2 5.2.4 {
  PRAGMA integrity_check;
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
  FROM schemapool;
} {ok nref=6 nschema=1 ndelete=5}

finish_test

Changes to test/reuse3.test.

152
153
154
155
156
157
158

159


160
161

162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
  for {set i 1} {$i < 5} {incr i} {
    forcedelete test.db${i} test.db${i}-wal test.db${i}-journal
    forcecopy test.db test.db${i}
    execsql "ATTACH 'test.db${i}' AS db${i}"
  }
  register_schemapool_module db
  set {} {}

  execsql { SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool }


} {nref=5 nschema=1}


do_execsql_test 4.1.3 {
  REINDEX x1;
  REINDEX x1a;
  REINDEX x1b;
  REINDEX x1c;
  REINDEX db1.x1a;
  REINDEX db2.x1b;
  REINDEX db3.x1c;
  REINDEX;
}

do_execsql_test 4.1.4 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool;

} {nref=5 nschema=1}

finish_test








>
|
>
>
|

>








<



|
>
|



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
  for {set i 1} {$i < 5} {incr i} {
    forcedelete test.db${i} test.db${i}-wal test.db${i}-journal
    forcecopy test.db test.db${i}
    execsql "ATTACH 'test.db${i}' AS db${i}"
  }
  register_schemapool_module db
  set {} {}
  execsql { 
    SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete 
    FROM schemapool 
  }
} {nref=5 nschema=1 ndelete=0}

breakpoint
do_execsql_test 4.1.3 {
  REINDEX  x1;
  REINDEX  x1a;
  REINDEX  x1b;
  REINDEX  x1c;
  REINDEX  db1.x1a;
  REINDEX  db2.x1b;
  REINDEX  db3.x1c;

}

do_execsql_test 4.1.4 {
  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete 
    FROM schemapool 
} {nref=5 nschema=1 ndelete=28}

finish_test