/ Check-in [9c4d0e13]
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:Improve test coverage for minimum feature builds. (CVS 2254)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9c4d0e13e8c5f3fc4d7fd8f495898372293f7fad
User & Date: danielk1977 2005-01-21 11:55:26
Context
2005-01-21
15:52
Final preparations for the 3.1.0 alpha release. (CVS 2255) check-in: 17122c7e user: drh tags: trunk
11:55
Improve test coverage for minimum feature builds. (CVS 2254) check-in: 9c4d0e13 user: danielk1977 tags: trunk
08:13
Exclude a few more lines of code using OMIT macros. (CVS 2253) check-in: c6fc49e6 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1327
1328
1329
1330
1331
1332
1333

1334
1335
1336
1337
1338
1339
1340
....
1368
1369
1370
1371
1372
1373
1374

1375
1376
1377
1378
1379
1380
1381
** 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.243 2005/01/21 08:13: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.
................................................................................
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
int sqlite3BtreeSetSafetyLevel(Btree *pBt, int level){
  sqlite3pager_set_safety_level(pBt->pPager, level);
  return SQLITE_OK;
}
#endif


/*
** Change the default pages size and the number of reserved bytes per page.
**
** The page size must be a power of 2 between 512 and 65536.  If the page
** size supplied does not meet this constraint then the page size is not
** changed.
**
................................................................................
*/
int sqlite3BtreeGetPageSize(Btree *pBt){
  return pBt->pageSize;
}
int sqlite3BtreeGetReserve(Btree *pBt){
  return pBt->pageSize - pBt->usableSize;
}


/*
** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
** is disabled. The default value for the auto-vacuum property is 
** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
*/







|







 







>







 







>







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
....
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
** 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.244 2005/01/21 11:55:26 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.
................................................................................
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
int sqlite3BtreeSetSafetyLevel(Btree *pBt, int level){
  sqlite3pager_set_safety_level(pBt->pPager, level);
  return SQLITE_OK;
}
#endif

#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
/*
** Change the default pages size and the number of reserved bytes per page.
**
** The page size must be a power of 2 between 512 and 65536.  If the page
** size supplied does not meet this constraint then the page size is not
** changed.
**
................................................................................
*/
int sqlite3BtreeGetPageSize(Btree *pBt){
  return pBt->pageSize;
}
int sqlite3BtreeGetReserve(Btree *pBt){
  return pBt->pageSize - pBt->usableSize;
}
#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */

/*
** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
** is disabled. The default value for the auto-vacuum property is 
** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
*/

Changes to src/build.c.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
423
424
425
426
427
428
429

430
431
432
433
434
435
436
437
438
439

440
441
442
443
444
445
446
...
458
459
460
461
462
463
464

465
466
467
468
469
470
471
472
473
474
475
476

477
478
479
480
481
482
483
...
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
....
1057
1058
1059
1060
1061
1062
1063

1064
1065
1066
1067
1068
1069
1070
1071

1072
1073
1074
1075
1076
1077
1078
....
1398
1399
1400
1401
1402
1403
1404

1405
1406
1407
1408
1409

1410
1411
1412
1413
1414
1415
1416
....
1492
1493
1494
1495
1496
1497
1498

1499
1500
1501
1502
1503

1504
1505
1506
1507
1508
1509
1510
....
1807
1808
1809
1810
1811
1812
1813





1814
1815
1816
1817
1818
1819
1820
1821

1822
1823
1824
1825
1826
1827
1828
....
2140
2141
2142
2143
2144
2145
2146

2147
2148
2149
2150

2151
2152
2153
2154
2155
2156
2157
....
2802
2803
2804
2805
2806
2807
2808

2809
2810
2811
2812
2813
2814
2815
2816
2817
2818

2819
2820
2821
2822
2823
2824
2825
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.296 2005/01/21 00:44:22 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
  */
  for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
    pNext = pIndex->pNext;
    assert( pIndex->iDb==pTable->iDb || (pTable->iDb==0 && pIndex->iDb==1) );
    sqliteDeleteIndex(db, pIndex);
  }


  /* Delete all foreign keys associated with this table.  The keys
  ** should have already been unlinked from the db->aFKey hash table 
  */
  for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
    pNextFKey = pFKey->pNextFrom;
    assert( pTable->iDb<db->nDb );
    assert( sqlite3HashFind(&db->aDb[pTable->iDb].aFKey,
                           pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );
    sqliteFree(pFKey);
  }


  /* Delete the Table structure itself.
  */
  sqliteResetColumnNames(pTable);
  sqliteFree(pTable->zName);
  sqliteFree(pTable->zColAff);
  sqlite3SelectDelete(pTable->pSelect);
................................................................................

  assert( db!=0 );
  assert( iDb>=0 && iDb<db->nDb );
  assert( zTabName && zTabName[0] );
  pDb = &db->aDb[iDb];
  p = sqlite3HashInsert(&pDb->tblHash, zTabName, strlen(zTabName)+1, 0);
  if( p ){

    for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){
      int nTo = strlen(pF1->zTo) + 1;
      pF2 = sqlite3HashFind(&pDb->aFKey, pF1->zTo, nTo);
      if( pF2==pF1 ){
        sqlite3HashInsert(&pDb->aFKey, pF1->zTo, nTo, pF1->pNextTo);
      }else{
        while( pF2 && pF2->pNextTo!=pF1 ){ pF2=pF2->pNextTo; }
        if( pF2 ){
          pF2->pNextTo = pF1->pNextTo;
        }
      }
    }

    sqlite3DeleteTable(db, p);
  }
  db->flags |= SQLITE_InternChanges;
}

/*
** Given a token, return a string that consists of the text of that
................................................................................
/*
** The token *pName contains the name of a database (either "main" or
** "temp" or the name of an attached db). This routine returns the
** index of the named database in db->aDb[], or -1 if the named db 
** does not exist.
*/
static int findDb(sqlite3 *db, Token *pName){
  int i;         /* Database number */
  int n;         /* Number of characters in the name */
  Db *pDb;       /* A database whose name space is being searched */
  char *zName;   /* Name we are searching for */

  zName = sqlite3NameFromToken(pName);
  if( zName ){
    n = strlen(zName);
    for(pDb=db->aDb, i=0; i<db->nDb; i++, pDb++){
      if( n==strlen(pDb->zName) && 0==sqlite3StrICmp(pDb->zName, zName) ){
        sqliteFree(zName);
        return i;
      }
    }
    sqliteFree(zName);
  }
  return -1;
}

/* The table or view or trigger name is passed to this routine via tokens
** pName1 and pName2. If the table name was fully qualified, for example:
**
** CREATE TABLE xxx.yyy (...);
** 
................................................................................
  if( nName<0 ) nName = strlen(zName);
  if( db->xCollNeeded ){
    char *zExternal = sqliteStrNDup(zName, nName);
    if( !zExternal ) return;
    db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal);
    sqliteFree(zExternal);
  }

  if( db->xCollNeeded16 ){
    char const *zExternal;
    sqlite3_value *pTmp = sqlite3GetTransientValue(db);
    sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
    zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
    if( !zExternal ) return;
    db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal);
  }

}

/*
** This routine is called if the collation factory fails to deliver a
** collation function in the best encoding but there may be other versions
** of this collation function (for other text encodings) available. Use one
** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
................................................................................
    ** views.  Initialize zType at the same time.
    */
    if( p->pSelect==0 ){
      /* A regular table */
      sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0);
      zType = "table";
      zType2 = "TABLE";

    }else{
      /* A view */
      sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
      zType = "view";
      zType2 = "VIEW";

    }

    /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
    ** statement to populate the new table. The root-page number for the
    ** new table is on the top of the vdbe stack.
    **
    ** Once the SELECT has been coded by sqlite3Select(), it is in a
................................................................................
    FKey *pFKey; 
    Db *pDb = &db->aDb[p->iDb];
    pOld = sqlite3HashInsert(&pDb->tblHash, p->zName, strlen(p->zName)+1, p);
    if( pOld ){
      assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
      return;
    }

    for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){
      int nTo = strlen(pFKey->zTo) + 1;
      pFKey->pNextTo = sqlite3HashFind(&pDb->aFKey, pFKey->zTo, nTo);
      sqlite3HashInsert(&pDb->aFKey, pFKey->zTo, nTo, pFKey);
    }

    pParse->pNewTable = 0;
    db->nTable++;
    db->flags |= SQLITE_InternChanges;
  }
}

#ifndef SQLITE_OMIT_VIEW
................................................................................
    }
  }
#endif
  if( pTab->readOnly || pTab==db->aDb[iDb].pSeqTab ){
    sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
    goto exit_drop_table;
  }





  if( isView && pTab->pSelect==0 ){
    sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName);
    goto exit_drop_table;
  }
  if( !isView && pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName);
    goto exit_drop_table;
  }


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

  if( pTab==0 || pParse->nErr ) goto exit_create_index;
  if( pTab->readOnly ){
    sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
    goto exit_create_index;
  }

  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "views may not be indexed");
    goto exit_create_index;
  }

  isTemp = pTab->iDb==1;

  /*
  ** Find the name of the index.  Make sure there is not already another
  ** index or table with the same name.  
  **
  ** Exception:  If we are reading the names of permanent indices from the
................................................................................
    sqlite3VdbeAddOp(v, OP_Statement, iDb, 0);
  }
  if( iDb!=1 && pParse->db->aDb[1].pBt!=0 ){
    sqlite3BeginWriteOperation(pParse, setStatement, 1);
  }
}


/* 
** Return the transient sqlite3_value object used for encoding conversions
** during SQL compilation.
*/
sqlite3_value *sqlite3GetTransientValue(sqlite3 *db){
  if( !db->pValue ){
    db->pValue = sqlite3ValueNew();
  }
  return db->pValue;
}


/*
** Check to see if pIndex uses the collating sequence pColl.  Return
** true if it does and false if it does not.
*/
#ifndef SQLITE_OMIT_REINDEX
static int collationMatch(CollSeq *pColl, Index *pIndex){







|







 







>










>







 







>












>







 







|







|

|
<




|







 







>








>







 







>





>







 







>





>







 







>
>
>
>
>








>







 







>




>







 







>










>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
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
...
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
...
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534

535
536
537
538
539
540
541
542
543
544
545
546
....
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
....
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
....
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
....
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
....
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
....
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.297 2005/01/21 11:55:27 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
  */
  for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
    pNext = pIndex->pNext;
    assert( pIndex->iDb==pTable->iDb || (pTable->iDb==0 && pIndex->iDb==1) );
    sqliteDeleteIndex(db, pIndex);
  }

#ifndef SQLITE_OMIT_FOREIGN_KEY
  /* Delete all foreign keys associated with this table.  The keys
  ** should have already been unlinked from the db->aFKey hash table 
  */
  for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
    pNextFKey = pFKey->pNextFrom;
    assert( pTable->iDb<db->nDb );
    assert( sqlite3HashFind(&db->aDb[pTable->iDb].aFKey,
                           pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );
    sqliteFree(pFKey);
  }
#endif

  /* Delete the Table structure itself.
  */
  sqliteResetColumnNames(pTable);
  sqliteFree(pTable->zName);
  sqliteFree(pTable->zColAff);
  sqlite3SelectDelete(pTable->pSelect);
................................................................................

  assert( db!=0 );
  assert( iDb>=0 && iDb<db->nDb );
  assert( zTabName && zTabName[0] );
  pDb = &db->aDb[iDb];
  p = sqlite3HashInsert(&pDb->tblHash, zTabName, strlen(zTabName)+1, 0);
  if( p ){
#ifndef SQLITE_OMIT_FOREIGN_KEY
    for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){
      int nTo = strlen(pF1->zTo) + 1;
      pF2 = sqlite3HashFind(&pDb->aFKey, pF1->zTo, nTo);
      if( pF2==pF1 ){
        sqlite3HashInsert(&pDb->aFKey, pF1->zTo, nTo, pF1->pNextTo);
      }else{
        while( pF2 && pF2->pNextTo!=pF1 ){ pF2=pF2->pNextTo; }
        if( pF2 ){
          pF2->pNextTo = pF1->pNextTo;
        }
      }
    }
#endif
    sqlite3DeleteTable(db, p);
  }
  db->flags |= SQLITE_InternChanges;
}

/*
** Given a token, return a string that consists of the text of that
................................................................................
/*
** The token *pName contains the name of a database (either "main" or
** "temp" or the name of an attached db). This routine returns the
** index of the named database in db->aDb[], or -1 if the named db 
** does not exist.
*/
static int findDb(sqlite3 *db, Token *pName){
  int i = -1;    /* Database number */
  int n;         /* Number of characters in the name */
  Db *pDb;       /* A database whose name space is being searched */
  char *zName;   /* Name we are searching for */

  zName = sqlite3NameFromToken(pName);
  if( zName ){
    n = strlen(zName);
    for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
      if( n==strlen(pDb->zName) && 0==sqlite3StrICmp(pDb->zName, zName) ){
        break;

      }
    }
    sqliteFree(zName);
  }
  return i;
}

/* The table or view or trigger name is passed to this routine via tokens
** pName1 and pName2. If the table name was fully qualified, for example:
**
** CREATE TABLE xxx.yyy (...);
** 
................................................................................
  if( nName<0 ) nName = strlen(zName);
  if( db->xCollNeeded ){
    char *zExternal = sqliteStrNDup(zName, nName);
    if( !zExternal ) return;
    db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal);
    sqliteFree(zExternal);
  }
#ifndef SQLITE_OMIT_UTF16
  if( db->xCollNeeded16 ){
    char const *zExternal;
    sqlite3_value *pTmp = sqlite3GetTransientValue(db);
    sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
    zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
    if( !zExternal ) return;
    db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal);
  }
#endif
}

/*
** This routine is called if the collation factory fails to deliver a
** collation function in the best encoding but there may be other versions
** of this collation function (for other text encodings) available. Use one
** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
................................................................................
    ** views.  Initialize zType at the same time.
    */
    if( p->pSelect==0 ){
      /* A regular table */
      sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0);
      zType = "table";
      zType2 = "TABLE";
#ifndef SQLITE_OMIT_VIEW
    }else{
      /* A view */
      sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
      zType = "view";
      zType2 = "VIEW";
#endif
    }

    /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
    ** statement to populate the new table. The root-page number for the
    ** new table is on the top of the vdbe stack.
    **
    ** Once the SELECT has been coded by sqlite3Select(), it is in a
................................................................................
    FKey *pFKey; 
    Db *pDb = &db->aDb[p->iDb];
    pOld = sqlite3HashInsert(&pDb->tblHash, p->zName, strlen(p->zName)+1, p);
    if( pOld ){
      assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
      return;
    }
#ifndef SQLITE_OMIT_FOREIGN_KEY
    for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){
      int nTo = strlen(pFKey->zTo) + 1;
      pFKey->pNextTo = sqlite3HashFind(&pDb->aFKey, pFKey->zTo, nTo);
      sqlite3HashInsert(&pDb->aFKey, pFKey->zTo, nTo, pFKey);
    }
#endif
    pParse->pNewTable = 0;
    db->nTable++;
    db->flags |= SQLITE_InternChanges;
  }
}

#ifndef SQLITE_OMIT_VIEW
................................................................................
    }
  }
#endif
  if( pTab->readOnly || pTab==db->aDb[iDb].pSeqTab ){
    sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
    goto exit_drop_table;
  }

#ifndef SQLITE_OMIT_VIEW
  /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
  ** on a table.
  */
  if( isView && pTab->pSelect==0 ){
    sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName);
    goto exit_drop_table;
  }
  if( !isView && pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName);
    goto exit_drop_table;
  }
#endif

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

  if( pTab==0 || pParse->nErr ) goto exit_create_index;
  if( pTab->readOnly ){
    sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
    goto exit_create_index;
  }
#ifndef SQLITE_OMIT_VIEW
  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "views may not be indexed");
    goto exit_create_index;
  }
#endif
  isTemp = pTab->iDb==1;

  /*
  ** Find the name of the index.  Make sure there is not already another
  ** index or table with the same name.  
  **
  ** Exception:  If we are reading the names of permanent indices from the
................................................................................
    sqlite3VdbeAddOp(v, OP_Statement, iDb, 0);
  }
  if( iDb!=1 && pParse->db->aDb[1].pBt!=0 ){
    sqlite3BeginWriteOperation(pParse, setStatement, 1);
  }
}

#ifndef SQLITE_OMIT_UTF16
/* 
** Return the transient sqlite3_value object used for encoding conversions
** during SQL compilation.
*/
sqlite3_value *sqlite3GetTransientValue(sqlite3 *db){
  if( !db->pValue ){
    db->pValue = sqlite3ValueNew();
  }
  return db->pValue;
}
#endif

/*
** Check to see if pIndex uses the collating sequence pColl.  Return
** true if it does and false if it does not.
*/
#ifndef SQLITE_OMIT_REINDEX
static int collationMatch(CollSeq *pColl, Index *pIndex){

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
...
490
491
492
493
494
495
496

497
498
499
500
501
502
503
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.125 2005/01/21 03:12:16 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  int rc;
  sqlite3 *db;
  sqlite3_value *pVal;
  extern void Md5_Register(sqlite3*);

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " DB\"", 0);
    return TCL_ERROR;
  }
................................................................................
  rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0, 
        ifnullFunc, 0, 0);

#ifndef SQLITE_OMIT_UTF16
  /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 
  ** because it is not tested anywhere else. */
  if( rc==SQLITE_OK ){

    pVal = sqlite3ValueNew();
    sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
    rc = sqlite3_create_function16(db, 
              sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
              1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
    sqlite3ValueFree(pVal);
  }







|







 







<







 







>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
474
475
476
477
478
479
480

481
482
483
484
485
486
487
...
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.126 2005/01/21 11:55:27 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  int rc;
  sqlite3 *db;

  extern void Md5_Register(sqlite3*);

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " DB\"", 0);
    return TCL_ERROR;
  }
................................................................................
  rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0, 
        ifnullFunc, 0, 0);

#ifndef SQLITE_OMIT_UTF16
  /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 
  ** because it is not tested anywhere else. */
  if( rc==SQLITE_OK ){
    sqlite3_value *pVal;
    pVal = sqlite3ValueNew();
    sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
    rc = sqlite3_create_function16(db, 
              sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
              1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
    sqlite3ValueFree(pVal);
  }

Changes to test/attach.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
675
676
677
678
679
680
681













682
683
684
685
686
687
688
689
690
691
#    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: attach.test,v 1.33 2005/01/21 04:25:47 danielk1977 Exp $
#

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

for {set i 2} {$i<=15} {incr i} {
  file delete -force test$i.db
................................................................................
    file attributes cannot-read -permission 0000
    catchsql {
      ATTACH DATABASE 'cannot-read' AS noread;
    }
  } {1 {unable to open database: cannot-read}}
  file delete -force cannot-read
}














for {set i 2} {$i<=15} {incr i} {
  catch {db$i close}
}
db close
file delete -force test2.db
file delete -force no-such-file


finish_test







|







 







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










8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
#    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: attach.test,v 1.34 2005/01/21 11:55:27 danielk1977 Exp $
#

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

for {set i 2} {$i<=15} {incr i} {
  file delete -force test$i.db
................................................................................
    file attributes cannot-read -permission 0000
    catchsql {
      ATTACH DATABASE 'cannot-read' AS noread;
    }
  } {1 {unable to open database: cannot-read}}
  file delete -force cannot-read
}

# Check the error message if we try to access a database that has
# not been attached.
do_test attach-6.3 {
  catchsql {
    CREATE TABLE no_such_db.t1(a, b, c);
  }
} {1 {unknown database no_such_db}}
do_test attach-6.4 {
  catchsql {
    CREATE TEMP TABLE db2.temp1(a, b, c);
  }
} {1 {temporary table name must be unqualified}}

for {set i 2} {$i<=15} {incr i} {
  catch {db$i close}
}
db close
file delete -force test2.db
file delete -force no-such-file


finish_test

Changes to test/autoinc.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
471
472
473
474
475
476
477








478
479
480
#    May you find forgiveness for yourself and forgive others.
#    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 AUTOINCREMENT features.
#
# $Id: autoinc.test,v 1.2 2004/11/22 13:35:42 danielk1977 Exp $
#

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

# If the library is not compiled with autoincrement support then
# skip all tests in this file.
................................................................................
    INSERT INTO t7(y) VALUES(123);
    INSERT INTO t7(y) VALUES(234);
    DELETE FROM t7;
    INSERT INTO t7(y) VALUES(345);
    SELECT * FROM t7;
  }
} {3 345}









catch {db2 close}
finish_test







|







 







>
>
>
>
>
>
>
>



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
#    May you find forgiveness for yourself and forgive others.
#    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 AUTOINCREMENT features.
#
# $Id: autoinc.test,v 1.3 2005/01/21 11:55:27 danielk1977 Exp $
#

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

# If the library is not compiled with autoincrement support then
# skip all tests in this file.
................................................................................
    INSERT INTO t7(y) VALUES(123);
    INSERT INTO t7(y) VALUES(234);
    DELETE FROM t7;
    INSERT INTO t7(y) VALUES(345);
    SELECT * FROM t7;
  }
} {3 345}

# Test that if the AUTOINCREMENT is applied to a non integer primary key
# the error message is sensible.
do_test autoinc-7.2 {
  catchsql {
    CREATE TABLE t8(x TEXT PRIMARY KEY AUTOINCREMENT);
  }
} {1 {AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY}}

catch {db2 close}
finish_test

Changes to test/expr.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
548
549
550
551
552
553
554
555








556
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing expressions.
#
# $Id: expr.test,v 1.42 2005/01/21 03:12:16 danielk1977 Exp $

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

# Create a table to work with.
#
execsql {CREATE TABLE test1(i1 int, i2 int, r1 real, r2 real, t1 text, t2 text)}
................................................................................
  } 1
}
set sqlite_current_time 0

do_test expr-9.1 {
  execsql {SELECT round(-('-'||'123'))}
} 123









finish_test







|







 








>
>
>
>
>
>
>
>

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing expressions.
#
# $Id: expr.test,v 1.43 2005/01/21 11:55:27 danielk1977 Exp $

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

# Create a table to work with.
#
execsql {CREATE TABLE test1(i1 int, i2 int, r1 real, r2 real, t1 text, t2 text)}
................................................................................
  } 1
}
set sqlite_current_time 0

do_test expr-9.1 {
  execsql {SELECT round(-('-'||'123'))}
} 123

# Test an error message that can be generated by the LIKE expression
do_test expr-10.1 {
  catchsql {SELECT 'abc' LIKE 'abc' ESCAPE ''}
} {1 {ESCAPE expression must be a single character}}
do_test expr-10.2 {
  catchsql {SELECT 'abc' LIKE 'abc' ESCAPE 'ab'}
} {1 {ESCAPE expression must be a single character}}

finish_test

Changes to test/func.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
457
458
459
460
461
462
463














464

#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing built-in functions.
#
# $Id: func.test,v 1.32 2005/01/20 02:17:02 danielk1977 Exp $

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

# Create a table to work with.
#
do_test func-0.0 {
................................................................................

do_test func-15.1 {
  catchsql {
    select test_error(NULL);
  }
} {1 {user function error}}















finish_test








|







 







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

>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing built-in functions.
#
# $Id: func.test,v 1.33 2005/01/21 11:55:28 danielk1977 Exp $

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

# Create a table to work with.
#
do_test func-0.0 {
................................................................................

do_test func-15.1 {
  catchsql {
    select test_error(NULL);
  }
} {1 {user function error}}

# Test the quote function for BLOB and NULL values.
do_test func-16.1 {
  execsql {
    CREATE TABLE tbl2(a, b);
  }
  set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL]
  sqlite3_bind_blob $::STMT 1 abc 3
  sqlite3_step $::STMT
  sqlite3_finalize $::STMT
  execsql {
    SELECT quote(a), quote(b) FROM tbl2;
  }
} {X'616263' NULL}

finish_test

Changes to test/subquery.test.

7
8
9
10
11
12
13
14
15
16
17
18





19
20
21
22
23
24
25
#    May you find forgiveness for yourself and forgive others.
#    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 correlated subqueries
#
# $Id: subquery.test,v 1.1 2005/01/21 02:34:44 drh Exp $
#

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






do_test subquery-1.1 {
  execsql {
    BEGIN;
    CREATE TABLE t1(a,b);
    INSERT INTO t1 VALUES(1,2);
    INSERT INTO t1 VALUES(3,4);







|




>
>
>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#    May you find forgiveness for yourself and forgive others.
#    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 correlated subqueries
#
# $Id: subquery.test,v 1.2 2005/01/21 11:55:28 danielk1977 Exp $
#

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

ifcapable !subquery {
  finish_test
  return
}

do_test subquery-1.1 {
  execsql {
    BEGIN;
    CREATE TABLE t1(a,b);
    INSERT INTO t1 VALUES(1,2);
    INSERT INTO t1 VALUES(3,4);