/ Check-in [5acad2e9]
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:Add a PRAGMA that restores the legacy ALTER TABLE RENAME TO behaviour.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | legacy-alter-table
Files: files | file ages | folders
SHA3-256: 5acad2e92c11c209bedc6ac8a709595e8070eed028ffc82af61499e5ceaa5e2b
User & Date: dan 2018-09-20 08:28:01
Context
2018-09-20
17:21
By default, make all "ALTER TABLE RENAME" statements executed within a virtual table xRename() method exhibit the legacy behaviour. Closed-Leaf check-in: 71947337 user: dan tags: legacy-alter-table
08:28
Add a PRAGMA that restores the legacy ALTER TABLE RENAME TO behaviour. check-in: 5acad2e9 user: dan tags: legacy-alter-table
2018-09-19
17:09
Fix a compilation issue in the "userauth" extension. Also fix a few test script errors that occur with SQLITE_USER_AUTHENTICATION=1 builds. check-in: 221f3f57 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/alter.c.

1418
1419
1420
1421
1422
1423
1424

1425
1426
1427
1428

1429
1430
1431
1432
1433
1434
1435

1436
1437
1438
1439
1440
1441
1442
....
1447
1448
1449
1450
1451
1452
1453

1454

1455
1456
1457
1458
1459
1460
1461

1462

1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474

1475
1476
1477
1478
1479
1480

1481
1482
1483
1484
1485
1486
1487
....
1531
1532
1533
1534
1535
1536
1537

1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558

1559

1560
1561
1562
1563
1564
1565
1566
    sWalker.xExprCallback = renameTableExprCb;
    sWalker.xSelectCallback = renameTableSelectCb;
    sWalker.u.pRename = &sCtx;

    rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);

    if( rc==SQLITE_OK ){

      if( sParse.pNewTable ){
        Table *pTab = sParse.pNewTable;

        if( pTab->pSelect ){

          NameContext sNC;
          memset(&sNC, 0, sizeof(sNC));
          sNC.pParse = &sParse;

          sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC);
          if( sParse.nErr ) rc = sParse.rc;
          sqlite3WalkSelect(&sWalker, pTab->pSelect);

        }else{
          /* Modify any FK definitions to point to the new table. */
#ifndef SQLITE_OMIT_FOREIGN_KEY
          if( db->flags & SQLITE_ForeignKeys ){
            FKey *pFKey;
            for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
              if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
................................................................................
#endif

          /* If this is the table being altered, fix any table refs in CHECK
          ** expressions. Also update the name that appears right after the
          ** "CREATE [VIRTUAL] TABLE" bit. */
          if( sqlite3_stricmp(zOld, pTab->zName)==0 ){
            sCtx.pTab = pTab;

            sqlite3WalkExprList(&sWalker, pTab->pCheck);

            renameTokenFind(&sParse, &sCtx, pTab->zName);
          }
        }
      }

      else if( sParse.pNewIndex ){
        renameTokenFind(&sParse, &sCtx, sParse.pNewIndex->zName);

        sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere);

      }

#ifndef SQLITE_OMIT_TRIGGER
      else{
        Trigger *pTrigger = sParse.pNewTrigger;
        TriggerStep *pStep;
        if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld) 
            && sCtx.pTab->pSchema==pTrigger->pTabSchema
          ){
          renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table);
        }


        rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb);
        if( rc==SQLITE_OK ){
          renameWalkTrigger(&sWalker, pTrigger);
          for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){
            if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){
              renameTokenFind(&sParse, &sCtx, pStep->zTarget);

            }
          }
        }
      }
#endif
    }

................................................................................
  int NotUsed,
  sqlite3_value **argv
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  char const *zDb = (const char*)sqlite3_value_text(argv[0]);
  char const *zInput = (const char*)sqlite3_value_text(argv[1]);
  int bTemp = sqlite3_value_int(argv[4]);


#ifndef SQLITE_OMIT_AUTHORIZATION
  sqlite3_xauth xAuth = db->xAuth;
  db->xAuth = 0;
#endif

  UNUSED_PARAMETER(NotUsed);
  if( zDb && zInput ){
    int rc;
    Parse sParse;
    rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);
    if( rc==SQLITE_OK ){
      if( sParse.pNewTable && sParse.pNewTable->pSelect ){
        NameContext sNC;
        memset(&sNC, 0, sizeof(sNC));
        sNC.pParse = &sParse;
        sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, &sNC);
        if( sParse.nErr ) rc = sParse.rc;
      }

      else if( sParse.pNewTrigger ){

        rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb);

        if( rc==SQLITE_OK ){
          int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
          int i2 = sqlite3FindDbName(db, zDb);
          if( i1==i2 ) sqlite3_result_int(context, 1);
        }
      }
    }







>




>
|
|
|

|
|
|
>







 







>
|
>







>
|
>












>
|
|
|
|
|
|
>







 







>












|








>
|
>







1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
....
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
....
1540
1541
1542
1543
1544
1545
1546
1547
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
1573
1574
1575
1576
1577
1578
    sWalker.xExprCallback = renameTableExprCb;
    sWalker.xSelectCallback = renameTableSelectCb;
    sWalker.u.pRename = &sCtx;

    rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);

    if( rc==SQLITE_OK ){
      int isLegacy = (db->flags & SQLITE_LegacyAlter);
      if( sParse.pNewTable ){
        Table *pTab = sParse.pNewTable;

        if( pTab->pSelect ){
          if( isLegacy==0 ){
            NameContext sNC;
            memset(&sNC, 0, sizeof(sNC));
            sNC.pParse = &sParse;

            sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC);
            if( sParse.nErr ) rc = sParse.rc;
            sqlite3WalkSelect(&sWalker, pTab->pSelect);
          }
        }else{
          /* Modify any FK definitions to point to the new table. */
#ifndef SQLITE_OMIT_FOREIGN_KEY
          if( db->flags & SQLITE_ForeignKeys ){
            FKey *pFKey;
            for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
              if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
................................................................................
#endif

          /* If this is the table being altered, fix any table refs in CHECK
          ** expressions. Also update the name that appears right after the
          ** "CREATE [VIRTUAL] TABLE" bit. */
          if( sqlite3_stricmp(zOld, pTab->zName)==0 ){
            sCtx.pTab = pTab;
            if( isLegacy==0 ){
              sqlite3WalkExprList(&sWalker, pTab->pCheck);
            }
            renameTokenFind(&sParse, &sCtx, pTab->zName);
          }
        }
      }

      else if( sParse.pNewIndex ){
        renameTokenFind(&sParse, &sCtx, sParse.pNewIndex->zName);
        if( isLegacy==0 ){
          sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere);
        }
      }

#ifndef SQLITE_OMIT_TRIGGER
      else{
        Trigger *pTrigger = sParse.pNewTrigger;
        TriggerStep *pStep;
        if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld) 
            && sCtx.pTab->pSchema==pTrigger->pTabSchema
          ){
          renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table);
        }

        if( isLegacy==0 ){
          rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb);
          if( rc==SQLITE_OK ){
            renameWalkTrigger(&sWalker, pTrigger);
            for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){
              if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){
                renameTokenFind(&sParse, &sCtx, pStep->zTarget);
              }
            }
          }
        }
      }
#endif
    }

................................................................................
  int NotUsed,
  sqlite3_value **argv
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  char const *zDb = (const char*)sqlite3_value_text(argv[0]);
  char const *zInput = (const char*)sqlite3_value_text(argv[1]);
  int bTemp = sqlite3_value_int(argv[4]);
  int isLegacy = (db->flags & SQLITE_LegacyAlter);

#ifndef SQLITE_OMIT_AUTHORIZATION
  sqlite3_xauth xAuth = db->xAuth;
  db->xAuth = 0;
#endif

  UNUSED_PARAMETER(NotUsed);
  if( zDb && zInput ){
    int rc;
    Parse sParse;
    rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);
    if( rc==SQLITE_OK ){
      if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){
        NameContext sNC;
        memset(&sNC, 0, sizeof(sNC));
        sNC.pParse = &sParse;
        sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, &sNC);
        if( sParse.nErr ) rc = sParse.rc;
      }

      else if( sParse.pNewTrigger ){
        if( isLegacy==0 ){
          rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb);
        }
        if( rc==SQLITE_OK ){
          int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
          int i2 = sqlite3FindDbName(db, zDb);
          if( i1==i2 ) sqlite3_result_int(context, 1);
        }
      }
    }

Changes to src/pragma.h.

389
390
391
392
393
394
395





396
397
398
399
400
401
402
...
642
643
644
645
646
647
648
649
 {/* zName:     */ "key",
  /* ePragTyp:  */ PragTyp_KEY,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)





 {/* zName:     */ "legacy_file_format",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_LegacyFileFmt },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
................................................................................
 {/* zName:     */ "writable_schema",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_WriteSchema },
#endif
};
/* Number of pragmas: 60 on by default, 77 total. */







>
>
>
>
>







 







|
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
...
647
648
649
650
651
652
653
654
 {/* zName:     */ "key",
  /* ePragTyp:  */ PragTyp_KEY,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 {/* zName:     */ "legacy_alter_table",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_LegacyAlter },
 {/* zName:     */ "legacy_file_format",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_LegacyFileFmt },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
................................................................................
 {/* zName:     */ "writable_schema",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_WriteSchema },
#endif
};
/* Number of pragmas: 61 on by default, 78 total. */

Changes to src/sqliteInt.h.

1532
1533
1534
1535
1536
1537
1538

1539
1540
1541
1542
1543
1544
1545
#define SQLITE_DeferFKs       0x00080000  /* Defer all FK constraints */
#define SQLITE_QueryOnly      0x00100000  /* Disable database changes */
#define SQLITE_CellSizeCk     0x00200000  /* Check btree cell sizes on load */
#define SQLITE_Fts3Tokenizer  0x00400000  /* Enable fts3_tokenizer(2) */
#define SQLITE_EnableQPSG     0x00800000  /* Query Planner Stability Guarantee*/
#define SQLITE_TriggerEQP     0x01000000  /* Show trigger EXPLAIN QUERY PLAN */
#define SQLITE_ResetDatabase  0x02000000  /* Reset the database */


/* Flags used only if debugging */
#ifdef SQLITE_DEBUG
#define SQLITE_SqlTrace       0x08000000  /* Debug print SQL as it executes */
#define SQLITE_VdbeListing    0x10000000  /* Debug listings of VDBE programs */
#define SQLITE_VdbeTrace      0x20000000  /* True to trace VDBE execution */
#define SQLITE_VdbeAddopTrace 0x40000000  /* Trace sqlite3VdbeAddOp() calls */







>







1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
#define SQLITE_DeferFKs       0x00080000  /* Defer all FK constraints */
#define SQLITE_QueryOnly      0x00100000  /* Disable database changes */
#define SQLITE_CellSizeCk     0x00200000  /* Check btree cell sizes on load */
#define SQLITE_Fts3Tokenizer  0x00400000  /* Enable fts3_tokenizer(2) */
#define SQLITE_EnableQPSG     0x00800000  /* Query Planner Stability Guarantee*/
#define SQLITE_TriggerEQP     0x01000000  /* Show trigger EXPLAIN QUERY PLAN */
#define SQLITE_ResetDatabase  0x02000000  /* Reset the database */
#define SQLITE_LegacyAlter    0x04000000  /* Legacy ALTER TABLE behaviour */

/* Flags used only if debugging */
#ifdef SQLITE_DEBUG
#define SQLITE_SqlTrace       0x08000000  /* Debug print SQL as it executes */
#define SQLITE_VdbeListing    0x10000000  /* Debug listings of VDBE programs */
#define SQLITE_VdbeTrace      0x20000000  /* True to trace VDBE execution */
#define SQLITE_VdbeAddopTrace 0x40000000  /* Trace sqlite3VdbeAddOp() calls */

Added test/alterlegacy.test.













































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
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
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
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
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
# 2018 September 20
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
#

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

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
  finish_test
  return
}

do_execsql_test 1.0 {
  PRAGMA legacy_alter_table = 1;
  CREATE TABLE t1(a, b, CHECK(t1.a != t1.b));
  CREATE TABLE t2(a, b);
  CREATE INDEX t2expr ON t2(a) WHERE t2.b>0;
}

do_execsql_test 1.1 {
  SELECT sql FROM sqlite_master
} {
  {CREATE TABLE t1(a, b, CHECK(t1.a != t1.b))}
  {CREATE TABLE t2(a, b)}
  {CREATE INDEX t2expr ON t2(a) WHERE t2.b>0}
}

# Legacy behavior is to corrupt the schema in this case, as the table name in
# the CHECK constraint is incorrect after "t1" is renamed. This version is
# slightly different - it rejects the change and rolls back the transaction.
do_catchsql_test 1.2 {
  ALTER TABLE t1 RENAME TO t1new;
} {1 {no such column: t1.a}}

do_execsql_test 1.3 {
  CREATE TABLE t3(c, d);
  ALTER TABLE t3 RENAME TO t3new;
  DROP TABLE t3new;
}

do_execsql_test 1.4 {
  SELECT sql FROM sqlite_master
} {
  {CREATE TABLE t1(a, b, CHECK(t1.a != t1.b))}
  {CREATE TABLE t2(a, b)}
  {CREATE INDEX t2expr ON t2(a) WHERE t2.b>0}
}


do_catchsql_test 1.3 {
  ALTER TABLE t2 RENAME TO t2new;
} {1 {no such column: t2.b}}
do_execsql_test 1.4 {
  SELECT sql FROM sqlite_master
} {
  {CREATE TABLE t1(a, b, CHECK(t1.a != t1.b))}
  {CREATE TABLE t2(a, b)}
  {CREATE INDEX t2expr ON t2(a) WHERE t2.b>0}
}


#-------------------------------------------------------------------------
reset_db
ifcapable vtab {
  register_echo_module db

  do_execsql_test 2.0 {
    PRAGMA legacy_alter_table = 1;
    CREATE TABLE abc(a, b, c);
    INSERT INTO abc VALUES(1, 2, 3);
    CREATE VIRTUAL TABLE eee USING echo('abc');
    SELECT * FROM eee;
  } {1 2 3}

  do_execsql_test 2.1 {
    ALTER TABLE eee RENAME TO fff;
    SELECT * FROM fff;
  } {1 2 3}

  db close
  sqlite3 db test.db

  do_catchsql_test 2.2 {
    ALTER TABLE fff RENAME TO ggg;
  } {1 {no such module: echo}}
}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 3.0 {
  PRAGMA legacy_alter_table = 1;
  CREATE TABLE txx(a, b, c);
  INSERT INTO txx VALUES(1, 2, 3);
  CREATE VIEW vvv AS SELECT main.txx.a, txx.b, c FROM txx;
  CREATE VIEW uuu AS SELECT main.one.a, one.b, c FROM txx AS one;
  CREATE VIEW temp.ttt AS SELECT main.txx.a, txx.b, one.b, main.one.a FROM txx AS one, txx;
}

do_execsql_test 3.1.1 {
  SELECT * FROM vvv;
} {1 2 3}
do_execsql_test 3.1.2a {
  ALTER TABLE txx RENAME TO "t xx";
}
do_catchsql_test 3.1.2b {
  SELECT * FROM vvv;
} {1 {no such table: main.txx}}
do_execsql_test 3.1.3 {
  SELECT sql FROM sqlite_master WHERE name='vvv';
} {{CREATE VIEW vvv AS SELECT main.txx.a, txx.b, c FROM txx}}


do_catchsql_test 3.2.1 {
  SELECT * FROM uuu;
} {1 {no such table: main.txx}}
do_execsql_test 3.2.2 {
  SELECT sql FROM sqlite_master WHERE name='uuu';;
} {{CREATE VIEW uuu AS SELECT main.one.a, one.b, c FROM txx AS one}}

do_catchsql_test 3.3.1 {
  SELECT * FROM ttt;
} {1 {no such table: txx}}
do_execsql_test 3.3.2 {
  SELECT sql FROM sqlite_temp_master WHERE name='ttt';
} {{CREATE VIEW ttt AS SELECT main.txx.a, txx.b, one.b, main.one.a FROM txx AS one, txx}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
  PRAGMA legacy_alter_table = 1;
  CREATE table t1(x, y);
  CREATE table t2(a, b);

  CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
    SELECT t1.x, * FROM t1, t2;
    INSERT INTO t2 VALUES(new.x, new.y);
  END;
}

do_execsql_test 4.1 {
  INSERT INTO t1 VALUES(1, 1);
  ALTER TABLE t1 RENAME TO t11;
} 
do_catchsql_test 4.1a {
  INSERT INTO t11 VALUES(2, 2);
} {1 {no such table: main.t1}}
do_execsql_test 4.1b {
  ALTER TABLE t11 RENAME TO t1;
  ALTER TABLE t2 RENAME TO t22;
}
do_catchsql_test 4.1c {
  INSERT INTO t1 VALUES(3, 3);
} {1 {no such table: main.t2}}

proc squish {a} {
  string trim [regsub -all {[[:space:]][[:space:]]*} $a { }]
}
db func squish squish
do_test 4.2 {
  execsql { SELECT squish(sql) FROM sqlite_master WHERE name = 'tr1' }
} [list [squish {
  CREATE TRIGGER tr1 AFTER INSERT ON "t1" BEGIN
    SELECT t1.x, * FROM t1, t2;
    INSERT INTO t2 VALUES(new.x, new.y);
  END
}]]

#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
  PRAGMA legacy_alter_table = 1;
  CREATE TABLE t9(a, b, c);
  CREATE TABLE t10(a, b, c);
  CREATE TEMP TABLE t9(a, b, c);

  CREATE TRIGGER temp.t9t AFTER INSERT ON temp.t9 BEGIN
    INSERT INTO t10 VALUES(new.a, new.b, new.c);
  END;

  INSERT INTO temp.t9 VALUES(1, 2, 3);
  SELECT * FROM t10;
} {1 2 3}

do_execsql_test 5.1 {
  ALTER TABLE temp.t9 RENAME TO 't1234567890'
}

do_execsql_test 5.2 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(a, b);
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t2 VALUES(3, 4);
  CREATE VIEW v AS SELECT one.a, one.b, t2.a, t2.b FROM t1 AS one, t2;
  SELECT * FROM v;
} {1 2 3 4}

do_execsql_test 5.3 {
  ALTER TABLE t2 RENAME TO one;
} {}

do_catchsql_test 5.4 {
  SELECT  *  FROM v
} {1 {no such table: main.t2}}

do_execsql_test 5.5 {
  ALTER TABLE one RENAME TO t2;
  DROP VIEW v;
  CREATE VIEW temp.vv AS SELECT one.a, one.b, t2.a, t2.b FROM t1 AS one, t2;
  SELECT * FROM vv;
} {1 2 3 4}

do_execsql_test 5.6 {
  ALTER TABLE t2 RENAME TO one;
} {}
do_catchsql_test 5.7 {
  SELECT  *  FROM vv
} {1 {no such table: t2}}

#-------------------------------------------------------------------------

ifcapable vtab {
  register_tcl_module db
  proc tcl_command {method args} {
    switch -- $method {
      xConnect {
        return "CREATE TABLE t1(a, b, c)"
      }
    }
    return {}
  }
  
  do_execsql_test 6.0 {
    CREATE VIRTUAL TABLE x1 USING tcl(tcl_command);
  }
  
  do_execsql_test 6.1 {
    ALTER TABLE x1 RENAME TO x2;
    SELECT sql FROM sqlite_master WHERE name = 'x2'
  } {{CREATE VIRTUAL TABLE "x2" USING tcl(tcl_command)}}
  
  do_execsql_test 7.1 {
    CREATE TABLE ddd(db, sql, zOld, zNew, bTemp);
    INSERT INTO ddd VALUES(
        'main', 'CREATE TABLE x1(i INTEGER, t TEXT)', 'ddd', NULL, 0
    ), (
        'main', 'CREATE TABLE x1(i INTEGER, t TEXT)', NULL, 'eee', 0
    ), (
        'main', NULL, 'ddd', 'eee', 0
    );
  } {}
}

#-------------------------------------------------------------------------
#
reset_db
forcedelete test.db2
do_execsql_test 8.1 {
  PRAGMA legacy_alter_table = 1;
  ATTACH 'test.db2' AS aux;
  PRAGMA foreign_keys = on;
  CREATE TABLE aux.p1(a INTEGER PRIMARY KEY, b);
  CREATE TABLE aux.c1(x INTEGER PRIMARY KEY, y REFERENCES p1(a));
  INSERT INTO aux.p1 VALUES(1, 1);
  INSERT INTO aux.p1 VALUES(2, 2);
  INSERT INTO aux.c1 VALUES(NULL, 2);
  CREATE TABLE aux.c2(x INTEGER PRIMARY KEY, y REFERENCES c1(a));
}

do_execsql_test 8.2 {
  ALTER TABLE aux.p1 RENAME TO ppp;
}

do_execsql_test 8.2 {
  INSERT INTO aux.c1 VALUES(NULL, 1);
  SELECT sql FROM aux.sqlite_master WHERE name = 'c1';
} {{CREATE TABLE c1(x INTEGER PRIMARY KEY, y REFERENCES "ppp"(a))}}

reset_db
do_execsql_test 9.0 {
  PRAGMA legacy_alter_table = 1;
  CREATE TABLE t1(a, b, c);
  CREATE VIEW v1 AS SELECT * FROM t2;
}
do_execsql_test 9.1 {
  ALTER TABLE t1 RENAME TO t3;
} {}
do_execsql_test 9.1b {
  ALTER TABLE t3 RENAME TO t1;
} {}
do_execsql_test 9.2 {
  DROP VIEW v1;
  CREATE TRIGGER tr AFTER INSERT ON t1 BEGIN
    INSERT INTO t2 VALUES(new.a);
  END;
}
do_execsql_test 9.3 {
  ALTER TABLE t1 RENAME TO t3;
} {}

forcedelete test.db2
do_execsql_test 9.4 {
  ALTER TABLE t3 RENAME TO t1;
  DROP TRIGGER tr;

  ATTACH 'test.db2' AS aux;
  CREATE TRIGGER tr AFTER INSERT ON t1 WHEN new.a IS NULL BEGIN SELECT 1, 2, 3; END;

  CREATE TABLE aux.t1(x);
  CREATE TEMP TRIGGER tr AFTER INSERT ON aux.t1 BEGIN SELECT 1, 2, 3; END;
}
do_execsql_test 9.5 {
  ALTER TABLE main.t1 RENAME TO t3;
}
do_execsql_test 9.6 {
  SELECT sql FROM sqlite_temp_master;
  SELECT sql FROM sqlite_master WHERE type='trigger';
} {
  {CREATE TRIGGER tr AFTER INSERT ON aux.t1 BEGIN SELECT 1, 2, 3; END}
  {CREATE TRIGGER tr AFTER INSERT ON "t3" WHEN new.a IS NULL BEGIN SELECT 1, 2, 3; END}
}

#-------------------------------------------------------------------------
reset_db
ifcapable fts5 {
  do_execsql_test 10.0 {
    PRAGMA legacy_alter_table = 1;
    CREATE VIRTUAL TABLE fff USING fts5(x, y, z);
  }

  do_execsql_test 10.1 {
    BEGIN;
      INSERT INTO fff VALUES('a', 'b', 'c');
      ALTER TABLE fff RENAME TO ggg;
    COMMIT;
  }

  do_execsql_test 10.2 {
    SELECT * FROM ggg;
  } {a b c}
}

#-------------------------------------------------------------------------
reset_db
forcedelete test.db2
db func trigger trigger
set ::trigger [list]
proc trigger {args} {
  lappend ::trigger $args
}
do_execsql_test 11.0 {
  PRAGMA legacy_alter_table = 1;
  ATTACH 'test.db2' AS aux;
  CREATE TABLE aux.t1(a, b, c);
  CREATE TABLE main.t1(a, b, c);
  CREATE TEMP TRIGGER tr AFTER INSERT ON aux.t1 BEGIN
    SELECT trigger(new.a, new.b, new.c);
  END;
}

do_execsql_test 11.1 {
  INSERT INTO main.t1 VALUES(1, 2, 3);
  INSERT INTO aux.t1 VALUES(4, 5, 6);
}
do_test 11.2 { set ::trigger } {{4 5 6}}

do_execsql_test 11.3 {
  SELECT name, tbl_name FROM sqlite_temp_master;
} {tr t1}

do_execsql_test 11.4 {
  ALTER TABLE main.t1 RENAME TO t2;
  SELECT name, tbl_name FROM sqlite_temp_master;
} {tr t1}

do_execsql_test 11.5 {
  ALTER TABLE aux.t1 RENAME TO t2;
  SELECT name, tbl_name FROM sqlite_temp_master;
} {tr t2}

do_execsql_test 11.6 {
  INSERT INTO aux.t2 VALUES(7, 8, 9);
}
do_test 11.7 { set ::trigger } {{4 5 6} {7 8 9}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 12.0 {
  PRAGMA legacy_alter_table = 1;
  CREATE TABLE t1(a);
  CREATE TABLE t2(w);
  CREATE TRIGGER temp.r1 AFTER INSERT ON main.t2 BEGIN
    INSERT INTO t1(a) VALUES(new.w);
  END;
  CREATE TEMP TABLE t2(x);
}

do_execsql_test 12.1 {
  ALTER TABLE main.t2 RENAME TO t3;
}

do_execsql_test 12.2 {
  INSERT INTO t3 VALUES('WWW');
  SELECT * FROM t1;
} {WWW}


#-------------------------------------------------------------------------
reset_db

ifcapable rtree {
  do_execsql_test 14.0 {
    PRAGMA legacy_alter_table = 1;
    CREATE VIRTUAL TABLE rt USING rtree(id, minx, maxx, miny, maxy);

    CREATE TABLE "mytable" ( "fid" INTEGER PRIMARY KEY, "geom" BLOB);

    CREATE TRIGGER tr1 AFTER UPDATE OF "geom" ON "mytable" 
          WHEN OLD."fid" = NEW."fid" AND NEW."geom" IS NULL BEGIN 
      DELETE FROM rt WHERE id = OLD."fid"; 
    END;

    INSERT INTO mytable VALUES(1, X'abcd');
  }

  do_execsql_test 14.1 {
    UPDATE mytable SET geom = X'1234'
  }

  do_execsql_test 14.2 {
    ALTER TABLE mytable RENAME TO mytable_renamed;
  }

  do_execsql_test 14.3 {
    CREATE TRIGGER tr2 AFTER INSERT ON mytable_renamed BEGIN
      DELETE FROM rt WHERE id=(SELECT min(id) FROM rt);
    END;
  }

  do_execsql_test 14.4 {
    ALTER TABLE mytable_renamed RENAME TO mytable2;
  }
}

reset_db
do_execsql_test 14.5 {
  PRAGMA legacy_alter_table = 1;
  CREATE TABLE t1(a, b, c);
  CREATE VIEW v1 AS SELECT * FROM t1;
  CREATE TRIGGER xyz AFTER INSERT ON t1 BEGIN
    SELECT a, b FROM v1;
  END;
}
do_execsql_test 14.6 {
  ALTER TABLE t1 RENAME TO tt1;
}


finish_test

Changes to tool/mkpragmatab.tcl.

378
379
380
381
382
383
384





385
386
387
388
389
390
391
  FLAG: Result0

  NAME: threads
  FLAG: Result0

  NAME: optimize
  FLAG: Result1 NeedSchema





}

# Open the output file
#
set destfile "[file dir [file dir [file normal $argv0]]]/src/pragma.h"
puts "Overwriting $destfile with new pragma table..."
set fd [open $destfile wb]







>
>
>
>
>







378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
  FLAG: Result0

  NAME: threads
  FLAG: Result0

  NAME: optimize
  FLAG: Result1 NeedSchema

  NAME: legacy_alter_table
  TYPE: FLAG
  ARG:  SQLITE_LegacyAlter
  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
}

# Open the output file
#
set destfile "[file dir [file dir [file normal $argv0]]]/src/pragma.h"
puts "Overwriting $destfile with new pragma table..."
set fd [open $destfile wb]