/ Changes On Branch experimental-namelist
Login

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

Changes In Branch experimental-namelist Excluding Merge-Ins

This is equivalent to a diff from c5ed5ebdf6 to f4229857a1

2017-07-07
14:54
Fix an obsolete comment on the sqlite3_namelist() function implementation. (Closed-Leaf check-in: f4229857a1 user: drh tags: experimental-namelist)
2017-07-06
22:43
Small adjustment to main.mk that facilitates giving non-standard compile-time options to the shell. (check-in: 7c7d53a9bb user: drh tags: trunk)
22:40
Always load the schema before starting tab-completion. (check-in: 907fd3aab6 user: drh tags: experimental-namelist)
17:36
Initial implementation of a highly experimental interface for listing all keywords and symbolic names for an SQLite database connection. (check-in: 04ef6783a5 user: drh tags: experimental-namelist)
16:33
Change the (machine-generated) keywordhash.h file to increase the scope of the tables used for keyword matching, so that the tables are accessible to functions other then keywordCode(). (check-in: c5ed5ebdf6 user: drh tags: trunk)
13:51
More compact implementation of the typeof() SQL function. (check-in: efb4aab0ca user: drh tags: trunk)

Changes to main.mk.

470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

# Standard options to testfixture
#
TESTOPTS = --verbose=file --output=test-out.txt

# Extra compiler options for various shell tools
#
SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
DBFUZZ_OPT =







|







470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

# Standard options to testfixture
#
TESTOPTS = --verbose=file --output=test-out.txt

# Extra compiler options for various shell tools
#
SHELL_OPT += -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
DBFUZZ_OPT =

Changes to src/hash.h.

87
88
89
90
91
92
93
94
95
96
#define sqliteHashData(E)   ((E)->data)
/* #define sqliteHashKey(E)    ((E)->pKey) // NOT USED */
/* #define sqliteHashKeysize(E) ((E)->nKey)  // NOT USED */

/*
** Number of entries in a hash table
*/
/* #define sqliteHashCount(H)  ((H)->count) // NOT USED */

#endif /* SQLITE_HASH_H */







|


87
88
89
90
91
92
93
94
95
96
#define sqliteHashData(E)   ((E)->data)
/* #define sqliteHashKey(E)    ((E)->pKey) // NOT USED */
/* #define sqliteHashKeysize(E) ((E)->nKey)  // NOT USED */

/*
** Number of entries in a hash table
*/
#define sqliteHashCount(H)  ((H)->count)

#endif /* SQLITE_HASH_H */

Changes to src/shell.c.

3595
3596
3597
3598
3599
3600
3601


























































3602
3603
3604
3605
3606
3607
3608
                            sha3QueryFunc, 0, 0);
    sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0,
                            shellAddSchemaName, 0, 0);
                            
  }
}



























































/*
** Do C-language style dequoting.
**
**    \a    -> alarm
**    \b    -> backspace
**    \t    -> tab
**    \n    -> newline







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







3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
                            sha3QueryFunc, 0, 0);
    sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0,
                            shellAddSchemaName, 0, 0);
                            
  }
}

#if HAVE_READLINE || HAVE_EDITLINE
/*
** Readline completion callbacks
*/
static char *readline_completion_generator(const char *text, int state){
  static char **azCompletions = 0;
  static int iCompletion = 0;
  char *zRet;
  if( state==0 ){
    sqlite3_free(azCompletions);
    sqlite3_exec(globalDb, "PRAGMA page_count", 0, 0, 0); /* Load the schema */
    azCompletions = sqlite3_namelist(globalDb, text, -1, 0);
    iCompletion = 0;
  }
  zRet = azCompletions[iCompletion++];
  if( zRet==0 ){
    sqlite3_free(azCompletions);
    azCompletions = 0;
  }else{
    zRet = strdup(zRet);
  }
  return zRet;
}
static char **readline_completion(const char *zText, int iStart, int iEnd){
  rl_attempted_completion_over = 1;
  return rl_completion_matches(zText, readline_completion_generator);
}

#elif HAVE_LINENOISE
/*
** Linenoise completion callback
*/
static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
  int nLine = (int)strlen(zLine);
  int i, n, iStart;
  char **az;
  char zBuf[1000];
  if( nLine>sizeof(zBuf)-30 ) return;
  if( zLine[0]=='.' ) return;
  for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
  if( i==nLine-1 ) return;
  iStart = i+1;
  sqlite3_exec(globalDb, "PRAGMA page_count", 0, 0, 0); /* Load the schema */
  az = sqlite3_namelist(globalDb, &zLine[iStart], -1, &n);
  if( n>0 ){
    qsort(az, n, sizeof(az[0]),(int(*)(const void*,const void*))sqlite3_stricmp);
    memcpy(zBuf, zLine, iStart);
    for(i=0; az[i]; i++){
      n = (int)strlen(az[i]);
      if( iStart+n+1 >= sizeof(zBuf) ) continue;
      memcpy(zBuf+iStart, az[i], n+1);
      linenoiseAddCompletion(lc, zBuf);
    }
  }
  sqlite3_free(az);
}
#endif

/*
** Do C-language style dequoting.
**
**    \a    -> alarm
**    \b    -> backspace
**    \t    -> tab
**    \n    -> newline
7632
7633
7634
7635
7636
7637
7638





7639
7640
7641
7642
7643
7644
7645
      if( zHome ){
        nHistory = strlen30(zHome) + 20;
        if( (zHistory = malloc(nHistory))!=0 ){
          sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
        }
      }
      if( zHistory ){ shell_read_history(zHistory); }





      rc = process_input(&data, 0);
      if( zHistory ){
        shell_stifle_history(100);
        shell_write_history(zHistory);
        free(zHistory);
      }
    }else{







>
>
>
>
>







7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
      if( zHome ){
        nHistory = strlen30(zHome) + 20;
        if( (zHistory = malloc(nHistory))!=0 ){
          sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
        }
      }
      if( zHistory ){ shell_read_history(zHistory); }
#if HAVE_READLINE || HAVE_EDITLINE
      rl_attempted_completion_function = readline_completion;
#elif HAVE_LINENOISE
      linenoiseSetCompletionCallback(linenoise_completion);
#endif
      rc = process_input(&data, 0);
      if( zHistory ){
        shell_stifle_history(100);
        shell_write_history(zHistory);
        free(zHistory);
      }
    }else{

Changes to src/sqlite.h.in.

8465
8466
8467
8468
8469
8470
8471










































8472
8473
8474
8475
8476
8477
8478
);
int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
int sqlite3_preupdate_count(sqlite3 *);
int sqlite3_preupdate_depth(sqlite3 *);
int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
#endif











































/*
** CAPI3REF: Low-level system error code
**
** ^Attempt to return the underlying operating system error code or error
** number that caused the most recent I/O error or failure to open a file.
** The return value is OS-dependent.  For example, on unix systems, after
** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be







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







8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
);
int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
int sqlite3_preupdate_count(sqlite3 *);
int sqlite3_preupdate_depth(sqlite3 *);
int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
#endif

/*
** CAPI3REF: List Of Symbolic Names
**
** ^The sqlite3_namelist(D,P,F,N) interface returns a list of symbolic names
** and keywords that might appear in valid SQL statements for [connection]
** D and that all begin with the prefix P.  ^The F parameter is a bitmask
** that determines the kinds of symbolic names and keywords that are found
** in the list.  ^Matching against the prefix P is performed using
** [sqlite3_strnicmp()] and is thus case insensitive for ASCII characters.
** ^If the pointer N is not NULL, then the number of matching names is
** stored in *N.
**
** ^The value returned by sqlite3_namelist() is stored in memory obtained
** from [sqlite3_malloc()] and must be released by the caller using
** [sqlite3_free()].  ^The sqlite3_namelist() interface returns NULL if a
** memory allocation error occurs.
**
** ^Elements of the list are unique but are in no particular order.
**
** This interface is intended to facilitate tab-completion for interactive
** interfaces for SQLite.
*/
char **sqlite3_namelist(sqlite3 *db, const char *zPrefix, int typeMask, int*);

/*
** CAPI3REF: Symbolic Name Typemask Values
**
** ^These bitmask values are used to determine the kinds of symbolic names
** and keywords that are returned by [sqlite3_namelist()].  The third
** parameter to [sqlite3_namelist()] should be an OR-ed combination of
** one or more of the following value.
*/
#define SQLITE_NAMETYPE_KEYWORD    0x0001
#define SQLITE_NAMETYPE_SCHEMA     0x0002
#define SQLITE_NAMETYPE_TABLE      0x0004
#define SQLITE_NAMETYPE_INDEX      0x0008
#define SQLITE_NAMETYPE_TRIGGER    0x0010
#define SQLITE_NAMETYPE_FUNCTION   0x0020
#define SQLITE_NAMETYPE_MODULE     0x0040
#define SQLITE_NAMETYPE_COLLATION  0x0080
#define SQLITE_NAMETYPE_COLUMN     0x0100

/*
** CAPI3REF: Low-level system error code
**
** ^Attempt to return the underlying operating system error code or error
** number that caused the most recent I/O error or failure to open a file.
** The return value is OS-dependent.  For example, on unix systems, after
** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be

Changes to src/tclsqlite.c.

1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
  static const char *DB_strs[] = {
    "authorizer",         "backup",            "busy",
    "cache",              "changes",           "close",
    "collate",            "collation_needed",  "commit_hook",
    "complete",           "copy",              "enable_load_extension",
    "errorcode",          "eval",              "exists",
    "function",           "incrblob",          "interrupt",
    "last_insert_rowid",  "nullvalue",         "onecolumn",
    "preupdate",          "profile",           "progress",
    "rekey",              "restore",           "rollback_hook",
    "status",             "timeout",           "total_changes",
    "trace",              "trace_v2",          "transaction",
    "unlock_notify",      "update_hook",       "version",
    "wal_hook",
    0
  };
  enum DB_enum {
    DB_AUTHORIZER,        DB_BACKUP,           DB_BUSY,
    DB_CACHE,             DB_CHANGES,          DB_CLOSE,
    DB_COLLATE,           DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
    DB_COMPLETE,          DB_COPY,             DB_ENABLE_LOAD_EXTENSION,
    DB_ERRORCODE,         DB_EVAL,             DB_EXISTS,
    DB_FUNCTION,          DB_INCRBLOB,         DB_INTERRUPT,
    DB_LAST_INSERT_ROWID, DB_NULLVALUE,        DB_ONECOLUMN,
    DB_PREUPDATE,         DB_PROFILE,          DB_PROGRESS,
    DB_REKEY,             DB_RESTORE,          DB_ROLLBACK_HOOK,
    DB_STATUS,            DB_TIMEOUT,          DB_TOTAL_CHANGES,
    DB_TRACE,             DB_TRACE_V2,         DB_TRANSACTION,
    DB_UNLOCK_NOTIFY,     DB_UPDATE_HOOK,      DB_VERSION,
    DB_WAL_HOOK,
  };
  /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
    return TCL_ERROR;
  }







|
|
|
|
|
|
|
<








|
|
|
|
|
|
|







1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859

1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
  static const char *DB_strs[] = {
    "authorizer",         "backup",            "busy",
    "cache",              "changes",           "close",
    "collate",            "collation_needed",  "commit_hook",
    "complete",           "copy",              "enable_load_extension",
    "errorcode",          "eval",              "exists",
    "function",           "incrblob",          "interrupt",
    "last_insert_rowid",  "namelist",          "nullvalue",
    "onecolumn",          "preupdate",         "profile",
    "progress",           "rekey",             "restore",
    "rollback_hook",      "status",            "timeout",
    "total_changes",      "trace",             "trace_v2",
    "transaction",        "unlock_notify",     "update_hook",
    "version",            "wal_hook",          0

  };
  enum DB_enum {
    DB_AUTHORIZER,        DB_BACKUP,           DB_BUSY,
    DB_CACHE,             DB_CHANGES,          DB_CLOSE,
    DB_COLLATE,           DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
    DB_COMPLETE,          DB_COPY,             DB_ENABLE_LOAD_EXTENSION,
    DB_ERRORCODE,         DB_EVAL,             DB_EXISTS,
    DB_FUNCTION,          DB_INCRBLOB,         DB_INTERRUPT,
    DB_LAST_INSERT_ROWID, DB_NAMELIST,         DB_NULLVALUE,
    DB_ONECOLUMN,         DB_PREUPDATE,        DB_PROFILE,
    DB_PROGRESS,          DB_REKEY,            DB_RESTORE,
    DB_ROLLBACK_HOOK,     DB_STATUS,           DB_TIMEOUT,
    DB_TOTAL_CHANGES,     DB_TRACE,            DB_TRACE_V2,
    DB_TRANSACTION,       DB_UNLOCK_NOTIFY,    DB_UPDATE_HOOK,
    DB_VERSION,           DB_WAL_HOOK,         
  };
  /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
    return TCL_ERROR;
  }
2660
2661
2662
2663
2664
2665
2666




























2667
2668
2669
2670
2671
2672
2673
  ** Interrupt the execution of the inner-most SQL interpreter.  This
  ** causes the SQL statement to return an error of SQLITE_INTERRUPT.
  */
  case DB_INTERRUPT: {
    sqlite3_interrupt(pDb->db);
    break;
  }





























  /*
  **     $db nullvalue ?STRING?
  **
  ** Change text used when a NULL comes back from the database. If ?STRING?
  ** is not present, then the current string used for NULL is returned.
  ** If STRING is present, then STRING is returned.







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







2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
  ** Interrupt the execution of the inner-most SQL interpreter.  This
  ** causes the SQL statement to return an error of SQLITE_INTERRUPT.
  */
  case DB_INTERRUPT: {
    sqlite3_interrupt(pDb->db);
    break;
  }

  /*
  **     $db namelist PREFIX MASK
  */
  case DB_NAMELIST: {
    const char *zPrefix;
    int mask;
    char **azList;
    int nList, i;
    if( objc!=4 ){
      Tcl_WrongNumArgs(interp, 2, objv, "PREFIX MASK");
      return TCL_ERROR;
    }
    zPrefix = Tcl_GetString(objv[2]);
    if( Tcl_GetIntFromObj(interp, objv[3], &mask) ) return TCL_ERROR;
    azList = sqlite3_namelist(pDb->db, zPrefix, mask, &nList);
    if( azList ){
      Tcl_Obj *pList = Tcl_NewListObj(nList, 0);
      for(i=0; azList[i]; i++){
        Tcl_ListObjAppendElement(interp, pList,
                                 Tcl_NewStringObj(azList[i],-1));
      }
      assert( i==nList );
      sqlite3_free(azList);
      Tcl_SetObjResult(interp, pList);
    }
    break;
  }

  /*
  **     $db nullvalue ?STRING?
  **
  ** Change text used when a NULL comes back from the database. If ?STRING?
  ** is not present, then the current string used for NULL is returned.
  ** If STRING is present, then STRING is returned.

Changes to src/tokenize.c.

610
611
612
613
614
615
616





















































































































































    Table *p = pParse->pZombieTab;
    pParse->pZombieTab = p->pNextZombie;
    sqlite3DeleteTable(db, p);
  }
  assert( nErr==0 || pParse->rc!=SQLITE_OK );
  return nErr;
}




























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
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
696
697
698
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
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
    Table *p = pParse->pZombieTab;
    pParse->pZombieTab = p->pNextZombie;
    sqlite3DeleteTable(db, p);
  }
  assert( nErr==0 || pParse->rc!=SQLITE_OK );
  return nErr;
}

/* An instance of the following object is used to accumulate a list
** of names for the sqlite3_namelist() interface
*/
struct NameAccum {
  Hash x;                  /* Hash table of all names */
  const char *zPrefix;     /* All names must start with this prefix */
  int nPrefix;             /* Size of the prefix in bytes */
};

/*
** Examine zName to see if it belongs on the list (if it has a matching
** prefix) and add it to the list if it belongs.  nName is the length
** of the name in bytes, or -1 if zName is zero-terminated.
*/
static void addName(struct NameAccum *p, const char *zName, int nName){
  char *zCopy;
  char *zOld;
  if( nName<0 ) nName = sqlite3Strlen30(zName);
  if( nName<p->nPrefix ) return;
  if( sqlite3StrNICmp(p->zPrefix, zName, p->nPrefix)!=0 ) return;
  zCopy = sqlite3_mprintf("%.*s", nName, zName);
  zOld = sqlite3HashInsert(&p->x, zCopy, zCopy);
  sqlite3_free(zOld);  
}

/*
** Return a list of text words or identifiers that might appear in an
** SQL statement.  The typeMask parameter is a bitmask that determines
** specifically what kinds of names should be returned.  All names
** returned must begin with zPrefix.
**
** The returned list is from a single memory allocation.  The caller owns
** the allocation and should release it using sqlite3_free() when it has
** finished using the list.
**
** The returned list is an array of pointers to strings.  The list is
** terminated by a single NULL pointer.
*/
char **sqlite3_namelist(
  sqlite3 *db,             /* Database from which to extract names */
  const char *zPrefix,     /* Only extract names matching this prefix */
  int typeMask,            /* Mask of the types of names to extract */
  int *pCount              /* Write the number of names here */
){
  struct NameAccum x;
  int i, n, nEntry;
  HashElem *j;
  char **azAns;
  char *zFree;
  x.zPrefix = zPrefix;
  x.nPrefix = sqlite3Strlen30(zPrefix);
  sqlite3HashInit(&x.x);
  if( typeMask & SQLITE_NAMETYPE_KEYWORD ){
    for(i=0; i<ArraySize(aKWOffset); i++){
      addName(&x, zKWText + aKWOffset[i], aKWLen[i]);
    }
  }
  if( typeMask & SQLITE_NAMETYPE_FUNCTION ){
    for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
      FuncDef *p;
      for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash){
        addName(&x, p->zName, -1);
      }
    }
    for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
      FuncDef *p = (FuncDef*)sqliteHashData(j);
      addName(&x, p->zName, -1);
    }
  }
  if( typeMask & SQLITE_NAMETYPE_COLLATION ){
    for(j=sqliteHashFirst(&db->aCollSeq); j; j=sqliteHashNext(j)){
      CollSeq *p = (CollSeq*)sqliteHashData(j);
      addName(&x, p->zName, -1);
    }
  }
  if( typeMask & SQLITE_NAMETYPE_MODULE ){
    for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){
      Module *p = (Module*)sqliteHashData(j);
      addName(&x, p->zName, -1);
    }
  }
  if( typeMask & (SQLITE_NAMETYPE_SCHEMA|
                  SQLITE_NAMETYPE_TABLE|
                  SQLITE_NAMETYPE_INDEX|
                  SQLITE_NAMETYPE_TRIGGER|
                  SQLITE_NAMETYPE_COLUMN) ){
    int iDb;
    for(iDb=0; iDb<db->nDb; iDb++){
      Db *pDb = &db->aDb[iDb];
      if( typeMask & SQLITE_NAMETYPE_SCHEMA ){
         addName(&x, pDb->zDbSName, -1);
      }
      if( typeMask & (SQLITE_NAMETYPE_TABLE|SQLITE_NAMETYPE_COLUMN) ){
        for(j=sqliteHashFirst(&pDb->pSchema->tblHash); j; j=sqliteHashNext(j)){
          Table *p = (Table*)sqliteHashData(j);
          if( typeMask & SQLITE_NAMETYPE_TABLE ){
            addName(&x, p->zName, -1);
          }
          if( typeMask & SQLITE_NAMETYPE_COLUMN ){
            int k;
            for(k=0; k<p->nCol; k++){
              addName(&x, p->aCol[k].zName, -1);
            }
          }
        }
      }
      if( typeMask & SQLITE_NAMETYPE_INDEX ){
        for(j=sqliteHashFirst(&pDb->pSchema->idxHash); j; j=sqliteHashNext(j)){
          Index *p = (Index*)sqliteHashData(j);
          addName(&x, p->zName, -1);
        }
      }
      if( typeMask & SQLITE_NAMETYPE_TRIGGER ){
        for(j=sqliteHashFirst(&pDb->pSchema->trigHash); j; j=sqliteHashNext(j)){
          Trigger *p = (Trigger*)sqliteHashData(j);
          addName(&x, p->zName, -1);
        }
      }
    }
    if( typeMask & SQLITE_NAMETYPE_COLUMN ){
      addName(&x, "rowid", -1);
    }
  }
  nEntry = sqliteHashCount(&x.x);
  if( pCount ) *pCount = nEntry;
  n = 0;
  for(j=sqliteHashFirst(&x.x); j; j=sqliteHashNext(j)){
    n += sqlite3Strlen30((const char*)sqliteHashData(j));
  }
  zFree = sqlite3_malloc( (nEntry+1)*sizeof(char*) + n + nEntry );
  azAns = (char**)zFree;
  if( zFree ){
    memset(zFree, 0, (nEntry+1)*sizeof(char*) + n + nEntry );
    zFree += (nEntry+1)*sizeof(char*);
    for(i=0, j=sqliteHashFirst(&x.x); j; i++, j=sqliteHashNext(j)){
      const char *zName = (const char*)sqliteHashData(j);
      azAns[i] = zFree;
      n = sqlite3Strlen30(zName);
      memcpy(zFree, zName, n+1);
      zFree += n+1;
    }
  }
  for(j=sqliteHashFirst(&x.x); j; j=sqliteHashNext(j)){
    sqlite3_free(sqliteHashData(j));
  }
  sqlite3HashClear(&x.x);
  return azAns;
}