/ Check-in [a352f628]
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:Merge with [0291ed974d]. Merge with [0291ed974d]. Merge with [0291ed974d].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wal
Files: files | file ages | folders
SHA1: a352f6285e33a806fbe4475e720e763fdc5bb47d
User & Date: dan 2010-04-24 14:33:08
Context
2010-04-24
18:44
Fix bugs in WAL mode rollback. check-in: 31215969 user: dan tags: wal
14:33
Merge with [0291ed974d]. Merge with [0291ed974d]. Merge with [0291ed974d]. check-in: a352f628 user: dan tags: wal
14:02
When commands such as ALTER TABLE and VACUUM use SQL internally, make sure they use only the built-in functions and not application-defined overrides for those functions. check-in: 0291ed97 user: drh tags: trunk
04:53
Merge with [e79dac3c2f]. check-in: 1e793d3a user: dan tags: wal
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/alter.c.

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
...
376
377
378
379
380
381
382

383

384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
...
552
553
554
555
556
557
558

559
560
561
562
563
564
565
...
671
672
673
674
675
676
677

678
679
680

681
682
683
684
685
686
687
688

689
690
691
692
693
694
695
  }
}
#endif   /* !SQLITE_OMIT_TRIGGER */

/*
** Register built-in functions used to help implement ALTER TABLE
*/
void sqlite3AlterFunctions(sqlite3 *db){
  sqlite3CreateFunc(db, "sqlite_rename_table", 2, SQLITE_UTF8, 0,
                         renameTableFunc, 0, 0);
#ifndef SQLITE_OMIT_TRIGGER
  sqlite3CreateFunc(db, "sqlite_rename_trigger", 2, SQLITE_UTF8, 0,
                         renameTriggerFunc, 0, 0);
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
  sqlite3CreateFunc(db, "sqlite_rename_parent", 3, SQLITE_UTF8, 0,
                         renameParentFunc, 0, 0);

#endif








}

/*
** This function is used to create the text of expressions of the form:
**
**   name=<constant1> OR name=<constant2> OR ...
**
................................................................................
  int nTabName;             /* Number of UTF-8 characters in zTabName */
  const char *zTabName;     /* Original name of the table */
  Vdbe *v;
#ifndef SQLITE_OMIT_TRIGGER
  char *zWhere = 0;         /* Where clause to locate temp triggers */
#endif
  VTable *pVTab = 0;        /* Non-zero if this is a v-tab with an xRename() */

  

  if( NEVER(db->mallocFailed) ) goto exit_rename_table;
  assert( pSrc->nSrc==1 );
  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );

  pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
  if( !pTab ) goto exit_rename_table;
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  zDb = db->aDb[iDb].zName;


  /* Get a NULL terminated version of the new table name. */
  zName = sqlite3NameFromToken(db, pName);
  if( !zName ) goto exit_rename_table;

  /* Check that a table or index named 'zName' does not already exist
  ** in database iDb. If so, this is an error.
................................................................................

  /* Drop and reload the internal table schema. */
  reloadTableSchema(pParse, pTab, zName);

exit_rename_table:
  sqlite3SrcListDelete(db, pSrc);
  sqlite3DbFree(db, zName);

}


/*
** Generate code to make sure the file format number is at least minFormat.
** The generated code will increase the file format number if necessary.
*/
................................................................................
    sqlite3ValueFree(pVal);
  }

  /* Modify the CREATE TABLE statement. */
  zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
  if( zCol ){
    char *zEnd = &zCol[pColDef->n-1];

    while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
      *zEnd-- = '\0';
    }

    sqlite3NestedParse(pParse, 
        "UPDATE \"%w\".%s SET "
          "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
        "WHERE type = 'table' AND name = %Q", 
      zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
      zTab
    );
    sqlite3DbFree(db, zCol);

  }

  /* If the default value of the new column is NULL, then set the file
  ** format to 2. If the default value of the new column is not NULL,
  ** the file format becomes 3.
  */
  sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);







|
|
|

|
<


<
<
>

>
>
>
>
>
>
>
>







 







>
|
>








>







 







>







 







>



>








>







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
...
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
...
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
...
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
  }
}
#endif   /* !SQLITE_OMIT_TRIGGER */

/*
** Register built-in functions used to help implement ALTER TABLE
*/
void sqlite3AlterFunctions(void){
  static SQLITE_WSD FuncDef aAlterTableFuncs[] = {
    FUNCTION(sqlite_rename_table,   2, 0, 0, renameTableFunc),
#ifndef SQLITE_OMIT_TRIGGER
    FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),

#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY


    FUNCTION(sqlite_rename_parent,  3, 0, 0, renameParentFunc),
#endif
  };
  int i;
  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAlterTableFuncs);

  for(i=0; i<ArraySize(aAlterTableFuncs); i++){
    sqlite3FuncDefInsert(pHash, &aFunc[i]);
  }
}

/*
** This function is used to create the text of expressions of the form:
**
**   name=<constant1> OR name=<constant2> OR ...
**
................................................................................
  int nTabName;             /* Number of UTF-8 characters in zTabName */
  const char *zTabName;     /* Original name of the table */
  Vdbe *v;
#ifndef SQLITE_OMIT_TRIGGER
  char *zWhere = 0;         /* Where clause to locate temp triggers */
#endif
  VTable *pVTab = 0;        /* Non-zero if this is a v-tab with an xRename() */
  int savedDbFlags;         /* Saved value of db->flags */

  savedDbFlags = db->flags;  
  if( NEVER(db->mallocFailed) ) goto exit_rename_table;
  assert( pSrc->nSrc==1 );
  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );

  pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
  if( !pTab ) goto exit_rename_table;
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  zDb = db->aDb[iDb].zName;
  db->flags |= SQLITE_PreferBuiltin;

  /* Get a NULL terminated version of the new table name. */
  zName = sqlite3NameFromToken(db, pName);
  if( !zName ) goto exit_rename_table;

  /* Check that a table or index named 'zName' does not already exist
  ** in database iDb. If so, this is an error.
................................................................................

  /* Drop and reload the internal table schema. */
  reloadTableSchema(pParse, pTab, zName);

exit_rename_table:
  sqlite3SrcListDelete(db, pSrc);
  sqlite3DbFree(db, zName);
  db->flags = savedDbFlags;
}


/*
** Generate code to make sure the file format number is at least minFormat.
** The generated code will increase the file format number if necessary.
*/
................................................................................
    sqlite3ValueFree(pVal);
  }

  /* Modify the CREATE TABLE statement. */
  zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
  if( zCol ){
    char *zEnd = &zCol[pColDef->n-1];
    int savedDbFlags = db->flags;
    while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
      *zEnd-- = '\0';
    }
    db->flags |= SQLITE_PreferBuiltin;
    sqlite3NestedParse(pParse, 
        "UPDATE \"%w\".%s SET "
          "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
        "WHERE type = 'table' AND name = %Q", 
      zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
      zTab
    );
    sqlite3DbFree(db, zCol);
    db->flags = savedDbFlags;
  }

  /* If the default value of the new column is NULL, then set the file
  ** format to 2. If the default value of the new column is not NULL,
  ** the file format becomes 3.
  */
  sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);

Changes to src/callback.c.

348
349
350
351
352
353
354




355
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370
      pBest = p;
      bestScore = score;
    }
    p = p->pNext;
  }

  /* If no match is found, search the built-in functions.




  **
  ** Except, if createFlag is true, that means that we are trying to
  ** install a new function.  Whatever FuncDef structure is returned will
  ** have fields overwritten with new information appropriate for the
  ** new function.  But the FuncDefs for built-in functions are read-only.
  ** So we must not search for built-ins when creating a new function.
  */ 
  if( !createFlag && !pBest ){
    FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);

    p = functionSearch(pHash, h, zName, nName);
    while( p ){
      int score = matchQuality(p, nArg, enc);
      if( score>bestScore ){
        pBest = p;
        bestScore = score;
      }







>
>
>
>







|

>







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
      pBest = p;
      bestScore = score;
    }
    p = p->pNext;
  }

  /* If no match is found, search the built-in functions.
  **
  ** If the SQLITE_PreferBuiltin flag is set, then search the built-in
  ** functions even if a prior app-defined function was found.  And give
  ** priority to built-in functions.
  **
  ** Except, if createFlag is true, that means that we are trying to
  ** install a new function.  Whatever FuncDef structure is returned will
  ** have fields overwritten with new information appropriate for the
  ** new function.  But the FuncDefs for built-in functions are read-only.
  ** So we must not search for built-ins when creating a new function.
  */ 
  if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
    FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
    bestScore = 0;
    p = functionSearch(pHash, h, zName, nName);
    while( p ){
      int score = matchQuality(p, nArg, enc);
      if( score>bestScore ){
        pBest = p;
        bestScore = score;
      }

Changes to src/func.c.

1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
....
1588
1589
1590
1591
1592
1593
1594



1595

/*
** This function registered all of the above C functions as SQL
** functions.  This should be the only routine in this file with
** external linkage.
*/
void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
#ifndef SQLITE_OMIT_ALTERTABLE
  sqlite3AlterFunctions(db);
#endif
  if( !db->mallocFailed ){
    int rc = sqlite3_overload_function(db, "MATCH", 2);
    assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
    if( rc==SQLITE_NOMEM ){
      db->mallocFailed = 1;
    }
  }
................................................................................
  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aBuiltinFunc);

  for(i=0; i<ArraySize(aBuiltinFunc); i++){
    sqlite3FuncDefInsert(pHash, &aFunc[i]);
  }
  sqlite3RegisterDateTimeFunctions();



}







<
<
<







 







>
>
>

1412
1413
1414
1415
1416
1417
1418



1419
1420
1421
1422
1423
1424
1425
....
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595

/*
** This function registered all of the above C functions as SQL
** functions.  This should be the only routine in this file with
** external linkage.
*/
void sqlite3RegisterBuiltinFunctions(sqlite3 *db){



  if( !db->mallocFailed ){
    int rc = sqlite3_overload_function(db, "MATCH", 2);
    assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
    if( rc==SQLITE_NOMEM ){
      db->mallocFailed = 1;
    }
  }
................................................................................
  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aBuiltinFunc);

  for(i=0; i<ArraySize(aBuiltinFunc); i++){
    sqlite3FuncDefInsert(pHash, &aFunc[i]);
  }
  sqlite3RegisterDateTimeFunctions();
#ifndef SQLITE_OMIT_ALTERTABLE
  sqlite3AlterFunctions();
#endif
}

Changes to src/sqliteInt.h.

911
912
913
914
915
916
917

918
919
920
921
922
923
924
....
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
#define SQLITE_FullFSync      0x00200000  /* Use full fsync on the backend */
#define SQLITE_LoadExtension  0x00400000  /* Enable load_extension */
#define SQLITE_RecoveryMode   0x00800000  /* Ignore schema errors */
#define SQLITE_ReverseOrder   0x01000000  /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers    0x02000000  /* Enable recursive triggers */
#define SQLITE_ForeignKeys    0x04000000  /* Enforce foreign key constraints  */
#define SQLITE_AutoIndex      0x08000000  /* Enable automatic indexes */


/*
** Bits of the sqlite3.flags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface.
** These must be the low-order bits of the flags field.
*/
#define SQLITE_QueryFlattener 0x01        /* Disable query flattening */
................................................................................
extern const unsigned char sqlite3CtypeMap[];
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
extern SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
extern int sqlite3PendingByte;
#endif
void sqlite3RootPageMoved(Db*, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(sqlite3*);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*);
int sqlite3CodeSubselect(Parse *, Expr *, int, int);
void sqlite3SelectPrep(Parse*, Select*, NameContext*);
int sqlite3ResolveExprNames(NameContext*, Expr*);







>







 







|







911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
....
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
#define SQLITE_FullFSync      0x00200000  /* Use full fsync on the backend */
#define SQLITE_LoadExtension  0x00400000  /* Enable load_extension */
#define SQLITE_RecoveryMode   0x00800000  /* Ignore schema errors */
#define SQLITE_ReverseOrder   0x01000000  /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers    0x02000000  /* Enable recursive triggers */
#define SQLITE_ForeignKeys    0x04000000  /* Enforce foreign key constraints  */
#define SQLITE_AutoIndex      0x08000000  /* Enable automatic indexes */
#define SQLITE_PreferBuiltin  0x10000000  /* Preference to built-in funcs */

/*
** Bits of the sqlite3.flags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface.
** These must be the low-order bits of the flags field.
*/
#define SQLITE_QueryFlattener 0x01        /* Disable query flattening */
................................................................................
extern const unsigned char sqlite3CtypeMap[];
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
extern SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
extern int sqlite3PendingByte;
#endif
void sqlite3RootPageMoved(Db*, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(void);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*);
int sqlite3CodeSubselect(Parse *, Expr *, int, int);
void sqlite3SelectPrep(Parse*, Select*, NameContext*);
int sqlite3ResolveExprNames(NameContext*, Expr*);

Changes to src/vacuum.c.

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  /* Save the current value of the database flags so that it can be 
  ** restored before returning. Then set the writable-schema flag, and
  ** disable CHECK and foreign key constraints.  */
  saved_flags = db->flags;
  saved_nChange = db->nChange;
  saved_nTotalChange = db->nTotalChange;
  saved_xTrace = db->xTrace;
  db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
  db->xTrace = 0;

  pMain = db->aDb[0].pBt;
  isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));

  /* Attach the temporary database as 'vacuum_db'. The synchronous pragma







|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  /* Save the current value of the database flags so that it can be 
  ** restored before returning. Then set the writable-schema flag, and
  ** disable CHECK and foreign key constraints.  */
  saved_flags = db->flags;
  saved_nChange = db->nChange;
  saved_nTotalChange = db->nTotalChange;
  saved_xTrace = db->xTrace;
  db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
  db->xTrace = 0;

  pMain = db->aDb[0].pBt;
  isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));

  /* Attach the temporary database as 'vacuum_db'. The synchronous pragma

Changes to test/alter.test.

168
169
170
171
172
173
174














175
176
177
178
179
180
181
...
563
564
565
566
567
568
569
570

571
572
573
574
575
576
577
...
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
...
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
       index {sqlite_autoindex_T2_2}      T2          \
    ]
} else {
  execsql {
    DROP TABLE TempTab;
  }
}















# Make sure the ALTER TABLE statements work with the
# non-callback API
#
do_test alter-1.7 {
  stepsql $DB {
    ALTER TABLE [-t1-] RENAME to [*t1*];
................................................................................
  } db2
} {x y z}
do_test alter-5.3 {
  db2 close
} {}

foreach tblname [execsql {
  SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite%'

}] {
  execsql "DROP TABLE \"$tblname\""
}

set ::tbl_name "abc\uABCDdef"
do_test alter-6.1 {
  string length $::tbl_name
................................................................................
#------------------------------------------------------------------------
# alter-10.X - Make sure ALTER TABLE works with multi-byte UTF-8 characters 
# in the names.
#
do_test alter-10.1 {
  execsql "CREATE TABLE xyz(x UNIQUE)"
  execsql "ALTER TABLE xyz RENAME TO xyz\u1234abc"
  execsql {SELECT name FROM sqlite_master WHERE name LIKE 'xyz%'}
} [list xyz\u1234abc]
do_test alter-10.2 {
  execsql {SELECT name FROM sqlite_master WHERE name LIKE 'sqlite_autoindex%'}
} [list sqlite_autoindex_xyz\u1234abc_1]
do_test alter-10.3 {
  execsql "ALTER TABLE xyz\u1234abc RENAME TO xyzabc"
  execsql {SELECT name FROM sqlite_master WHERE name LIKE 'xyz%'}
} [list xyzabc]
do_test alter-10.4 {
  execsql {SELECT name FROM sqlite_master WHERE name LIKE 'sqlite_autoindex%'}
} [list sqlite_autoindex_xyzabc_1]

do_test alter-11.1 {
  sqlite3_exec db {CREATE TABLE t11(%c6%c6)}
  execsql {
    ALTER TABLE t11 ADD COLUMN abc;
  }
................................................................................
#
do_test alter-13.1 {
  execsql {
    CREATE TABLE /* hi */ t3102a(x);
    CREATE TABLE t3102b -- comment
    (y);
    CREATE INDEX t3102c ON t3102a(x);
    SELECT name FROM sqlite_master WHERE name LIKE 't3102%' ORDER BY 1;
  }
} {t3102a t3102b t3102c}
do_test alter-13.2 {
  execsql {
    ALTER TABLE t3102a RENAME TO t3102a_rename;
    SELECT name FROM sqlite_master WHERE name LIKE 't3102%' ORDER BY 1;
  }
} {t3102a_rename t3102b t3102c}
do_test alter-13.3 {
  execsql {
    ALTER TABLE t3102b RENAME TO t3102b_rename;
    SELECT name FROM sqlite_master WHERE name LIKE 't3102%' ORDER BY 1;
  }
} {t3102a_rename t3102b_rename t3102c}

# Ticket #3651
do_test alter-14.1 {
  catchsql {
    CREATE TABLE t3651(a UNIQUE);







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







 







|
>







 







|


|



|


|







 







|





|





|







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
...
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
...
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
...
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
       index {sqlite_autoindex_T2_2}      T2          \
    ]
} else {
  execsql {
    DROP TABLE TempTab;
  }
}

# Create bogus application-defined functions for functions used 
# internally by ALTER TABLE, to ensure that ALTER TABLE falls back
# to the built-in functions.
#
proc failing_app_func {args} {error "bad function"}
do_test alter-1.7-prep {
  db func substr failing_app_func
  db func like failing_app_func
  db func sqlite_rename_table failing_app_func
  db func sqlite_rename_trigger failing_app_func
  db func sqlite_rename_parent failing_app_func
  catchsql {SELECT substr(name,1,3) FROM sqlite_master}
} {1 {bad function}}

# Make sure the ALTER TABLE statements work with the
# non-callback API
#
do_test alter-1.7 {
  stepsql $DB {
    ALTER TABLE [-t1-] RENAME to [*t1*];
................................................................................
  } db2
} {x y z}
do_test alter-5.3 {
  db2 close
} {}

foreach tblname [execsql {
  SELECT name FROM sqlite_master
   WHERE type='table' AND name NOT GLOB 'sqlite*'
}] {
  execsql "DROP TABLE \"$tblname\""
}

set ::tbl_name "abc\uABCDdef"
do_test alter-6.1 {
  string length $::tbl_name
................................................................................
#------------------------------------------------------------------------
# alter-10.X - Make sure ALTER TABLE works with multi-byte UTF-8 characters 
# in the names.
#
do_test alter-10.1 {
  execsql "CREATE TABLE xyz(x UNIQUE)"
  execsql "ALTER TABLE xyz RENAME TO xyz\u1234abc"
  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
} [list xyz\u1234abc]
do_test alter-10.2 {
  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_autoindex*'}
} [list sqlite_autoindex_xyz\u1234abc_1]
do_test alter-10.3 {
  execsql "ALTER TABLE xyz\u1234abc RENAME TO xyzabc"
  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
} [list xyzabc]
do_test alter-10.4 {
  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_autoindex*'}
} [list sqlite_autoindex_xyzabc_1]

do_test alter-11.1 {
  sqlite3_exec db {CREATE TABLE t11(%c6%c6)}
  execsql {
    ALTER TABLE t11 ADD COLUMN abc;
  }
................................................................................
#
do_test alter-13.1 {
  execsql {
    CREATE TABLE /* hi */ t3102a(x);
    CREATE TABLE t3102b -- comment
    (y);
    CREATE INDEX t3102c ON t3102a(x);
    SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
  }
} {t3102a t3102b t3102c}
do_test alter-13.2 {
  execsql {
    ALTER TABLE t3102a RENAME TO t3102a_rename;
    SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
  }
} {t3102a_rename t3102b t3102c}
do_test alter-13.3 {
  execsql {
    ALTER TABLE t3102b RENAME TO t3102b_rename;
    SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
  }
} {t3102a_rename t3102b_rename t3102c}

# Ticket #3651
do_test alter-14.1 {
  catchsql {
    CREATE TABLE t3651(a UNIQUE);

Changes to test/alter2.test.

67
68
69
70
71
72
73















74
75
76
77
78
79
80
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master SET sql = '$s' WHERE name = '$t' AND type = 'table';
    PRAGMA writable_schema = 0;
  }]
  dbat close
  set_file_format 2
}
















#-----------------------------------------------------------------------
# Some basic tests to make sure short rows are handled.
#
do_test alter2-1.1 {
  execsql {
    CREATE TABLE abc(a, b);







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







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
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master SET sql = '$s' WHERE name = '$t' AND type = 'table';
    PRAGMA writable_schema = 0;
  }]
  dbat close
  set_file_format 2
}

# Create bogus application-defined functions for functions used 
# internally by ALTER TABLE, to ensure that ALTER TABLE falls back
# to the built-in functions.
#
proc failing_app_func {args} {error "bad function"}
do_test alter2-1.0 {
  db func substr failing_app_func
  db func like failing_app_func
  db func sqlite_rename_table failing_app_func
  db func sqlite_rename_trigger failing_app_func
  db func sqlite_rename_parent failing_app_func
  catchsql {SELECT substr('abcdefg',1,3)}
} {1 {bad function}}


#-----------------------------------------------------------------------
# Some basic tests to make sure short rows are handled.
#
do_test alter2-1.1 {
  execsql {
    CREATE TABLE abc(a, b);

Changes to test/vacuum.test.

50
51
52
53
54
55
56













57
58
59
60
61
62
63
    COMMIT;
    DROP TABLE t2;
  }
  set ::size1 [file size test.db]
  set ::cksum [cksum]
  expr {$::cksum!=""}
} {1}













do_test vacuum-1.2 {
  execsql {
    VACUUM;
  }
  cksum
} $cksum
ifcapable vacuum {







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







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
    COMMIT;
    DROP TABLE t2;
  }
  set ::size1 [file size test.db]
  set ::cksum [cksum]
  expr {$::cksum!=""}
} {1}

# Create bogus application-defined functions for functions used 
# internally by VACUUM, to ensure that VACUUM falls back
# to the built-in functions.
#
proc failing_app_func {args} {error "bad function"}
do_test vacuum-1.1b {
  db func substr failing_app_func
  db func like failing_app_func
  db func quote failing_app_func
  catchsql {SELECT substr(name,1,3) FROM sqlite_master}
} {1 {bad function}}

do_test vacuum-1.2 {
  execsql {
    VACUUM;
  }
  cksum
} $cksum
ifcapable vacuum {