/ Check-in [5e8611e1]
Login

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

Overview
Comment:Fix the origin APIs so that they correctly handle views and subqueries that cannot be flattened. (CVS 3072)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:5e8611e13de08d704cea6c9c4466c3af842a7a1a
User & Date: danielk1977 2006-02-10 07:07:14
Context
2006-02-10
08:24
Work around the case where the pending-byte page is also a a pointer-map page. Ticket #1667. (CVS 3073) check-in: 5ea87fbb user: danielk1977 tags: trunk
07:07
Fix the origin APIs so that they correctly handle views and subqueries that cannot be flattened. (CVS 3072) check-in: 5e8611e1 user: danielk1977 tags: trunk
04:33
Fix deadlock problem in the unix mutex. Ticket #1672. (CVS 3071) check-in: a6c30be2 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
....
2843
2844
2845
2846
2847
2848
2849

2850
2851
2852
2853
2854
2855
2856
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.384 2006/02/05 18:55:20 drh 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.
................................................................................
    Token *pTemp = pDatabase;
    pDatabase = pTable;
    pTable = pTemp;
  }
  pItem->zName = sqlite3NameFromToken(pTable);
  pItem->zDatabase = sqlite3NameFromToken(pDatabase);
  pItem->iCursor = -1;

  pList->nSrc++;
  return pList;
}

/*
** Assign cursors to all tables in a SrcList
*/







|







 







>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
....
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.385 2006/02/10 07:07:14 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.
................................................................................
    Token *pTemp = pDatabase;
    pDatabase = pTable;
    pTable = pTemp;
  }
  pItem->zName = sqlite3NameFromToken(pTable);
  pItem->zDatabase = sqlite3NameFromToken(pDatabase);
  pItem->iCursor = -1;
  pItem->isPopulated = 0;
  pList->nSrc++;
  return pList;
}

/*
** Assign cursors to all tables in a SrcList
*/

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
491
492
493
494
495
496
497

498
499
500
501
502
503
504
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.253 2006/01/30 14:36:59 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
    struct SrcList_item *pOldItem = &p->a[i];
    Table *pTab;
    pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase);
    pNewItem->zName = sqliteStrDup(pOldItem->zName);
    pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
    pNewItem->jointype = pOldItem->jointype;
    pNewItem->iCursor = pOldItem->iCursor;

    pTab = pNewItem->pTab = pOldItem->pTab;
    if( pTab ){
      pTab->nRef++;
    }
    pNewItem->pSelect = sqlite3SelectDup(pOldItem->pSelect);
    pNewItem->pOn = sqlite3ExprDup(pOldItem->pOn);
    pNewItem->pUsing = sqlite3IdListDup(pOldItem->pUsing);







|







 







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.254 2006/02/10 07:07:15 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
    struct SrcList_item *pOldItem = &p->a[i];
    Table *pTab;
    pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase);
    pNewItem->zName = sqliteStrDup(pOldItem->zName);
    pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
    pNewItem->jointype = pOldItem->jointype;
    pNewItem->iCursor = pOldItem->iCursor;
    pNewItem->isPopulated = pOldItem->isPopulated;
    pTab = pNewItem->pTab = pOldItem->pTab;
    if( pTab ){
      pTab->nRef++;
    }
    pNewItem->pSelect = sqlite3SelectDup(pOldItem->pSelect);
    pNewItem->pOn = sqlite3ExprDup(pOldItem->pOn);
    pNewItem->pUsing = sqlite3IdListDup(pOldItem->pUsing);

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
....
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.303 2006/02/10 03:06:10 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
  */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  for(i=0; i<pTabList->nSrc; i++){
    const char *zSavedAuthContext = 0;
    int needRestoreContext;
    struct SrcList_item *pItem = &pTabList->a[i];

    if( pItem->pSelect==0 ) continue;
    if( pItem->zName!=0 ){
      zSavedAuthContext = pParse->zAuthContext;
      pParse->zAuthContext = pItem->zName;
      needRestoreContext = 1;
    }else{
      needRestoreContext = 0;
    }
................................................................................
  */
  if( pOrderBy ){
    generateSortTail(pParse, p, v, pEList->nExpr, eDest, iParm);
  }

#ifndef SQLITE_OMIT_SUBQUERY
  /* If this was a subquery, we have now converted the subquery into a
  ** temporary table.  So delete the subquery structure from the parent
  ** to prevent this subquery from being evaluated again and to force the
  ** the use of the temporary table.
  */
  if( pParent ){
    assert( pParent->pSrc->nSrc>parentTab );
    assert( pParent->pSrc->a[parentTab].pSelect==p );
    sqlite3SelectDelete(p);
    pParent->pSrc->a[parentTab].pSelect = 0;
  }
#endif

  /* Jump here to skip this query
  */
  sqlite3VdbeResolveLabel(v, iEnd);








|







 







|







 







|
|
|




<
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
....
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268

3269
3270
3271
3272
3273
3274
3275
3276
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.304 2006/02/10 07:07:16 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
  */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  for(i=0; i<pTabList->nSrc; i++){
    const char *zSavedAuthContext = 0;
    int needRestoreContext;
    struct SrcList_item *pItem = &pTabList->a[i];

    if( pItem->pSelect==0 || pItem->isPopulated ) continue;
    if( pItem->zName!=0 ){
      zSavedAuthContext = pParse->zAuthContext;
      pParse->zAuthContext = pItem->zName;
      needRestoreContext = 1;
    }else{
      needRestoreContext = 0;
    }
................................................................................
  */
  if( pOrderBy ){
    generateSortTail(pParse, p, v, pEList->nExpr, eDest, iParm);
  }

#ifndef SQLITE_OMIT_SUBQUERY
  /* If this was a subquery, we have now converted the subquery into a
  ** temporary table.  So set the SrcList_item.isPopulated flag to prevent
  ** this subquery from being evaluated again and to force the use of
  ** the temporary table.
  */
  if( pParent ){
    assert( pParent->pSrc->nSrc>parentTab );
    assert( pParent->pSrc->a[parentTab].pSelect==p );

    pParent->pSrc->a[parentTab].isPopulated = 1;
  }
#endif

  /* Jump here to skip this query
  */
  sqlite3VdbeResolveLabel(v, iEnd);

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1065
1066
1067
1068
1069
1070
1071

1072
1073
1074
1075
1076
1077
1078
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.479 2006/01/24 16:37:58 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Extra interface definitions for those who need them
*/
................................................................................
  i16 nAlloc;      /* Number of entries allocated in a[] below */
  struct SrcList_item {
    char *zDatabase;  /* Name of database holding this table */
    char *zName;      /* Name of the table */
    char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
    Table *pTab;      /* An SQL table corresponding to zName */
    Select *pSelect;  /* A SELECT statement used in place of a table name */

    u8 jointype;      /* Type of join between this table and the next */
    i16 iCursor;      /* The VDBE cursor number used to access this table */
    Expr *pOn;        /* The ON clause of a join */
    IdList *pUsing;   /* The USING clause of a join */
    Bitmask colUsed;  /* Bit N (1<<N) set if column N or pTab is used */
  } a[1];             /* One entry for each identifier on the list */
};







|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.480 2006/02/10 07:07:16 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Extra interface definitions for those who need them
*/
................................................................................
  i16 nAlloc;      /* Number of entries allocated in a[] below */
  struct SrcList_item {
    char *zDatabase;  /* Name of database holding this table */
    char *zName;      /* Name of the table */
    char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
    Table *pTab;      /* An SQL table corresponding to zName */
    Select *pSelect;  /* A SELECT statement used in place of a table name */
    u8 isPopulated;   /* Temporary table associated with SELECT is populated */
    u8 jointype;      /* Type of join between this table and the next */
    i16 iCursor;      /* The VDBE cursor number used to access this table */
    Expr *pOn;        /* The ON clause of a join */
    IdList *pUsing;   /* The USING clause of a join */
    Bitmask colUsed;  /* Bit N (1<<N) set if column N or pTab is used */
  } a[1];             /* One entry for each identifier on the list */
};

Changes to test/capi2.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
718
719
720
721
722
723
724










725




726










































727
728

729
#    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 testing the callback-free C/C++ API.
#
# $Id: capi2.test,v 1.29 2006/02/10 03:06:10 danielk1977 Exp $
#

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

# Return the text values from the current row pointed at by STMT as a list.
proc get_row_values {STMT} {
................................................................................
} [list {main tab1 col2} {main tab1 col1}]
do_test capi2-12.5 {
  check_origins {SELECT (SELECT col2 FROM view1), (SELECT col1 FROM view1)}
} [list {main tab1 col2} {main tab1 col1}]
do_test capi2-12.6 {
  check_origins {SELECT (SELECT col2), (SELECT col1) FROM view1}
} [list {main tab1 col2} {main tab1 col1}]










db2 close















































} ;# ifcapable columnmetadata


finish_test







|







 







>
>
>
>
>
>
>
>
>
>
|
>
>
>
>

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


>

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
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
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
#    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 testing the callback-free C/C++ API.
#
# $Id: capi2.test,v 1.30 2006/02/10 07:07:16 danielk1977 Exp $
#

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

# Return the text values from the current row pointed at by STMT as a list.
proc get_row_values {STMT} {
................................................................................
} [list {main tab1 col2} {main tab1 col1}]
do_test capi2-12.5 {
  check_origins {SELECT (SELECT col2 FROM view1), (SELECT col1 FROM view1)}
} [list {main tab1 col2} {main tab1 col1}]
do_test capi2-12.6 {
  check_origins {SELECT (SELECT col2), (SELECT col1) FROM view1}
} [list {main tab1 col2} {main tab1 col1}]
do_test capi2-12.7 {
  check_origins {SELECT * FROM view1}
} [list {main tab1 col1} {main tab1 col2}]
do_test capi2-12.8 {
  check_origins {select * from (select * from view1)}
} [list {main tab1 col1} {main tab1 col2}]
do_test capi2-12.9 {
  check_origins {select * from (select * from (select * from view1))}
} [list {main tab1 col1} {main tab1 col2}]
do_test capi2-12.10 {
  db close
  sqlite3 db test.db
  set ::DB [sqlite3_connection_pointer db]
  check_origins {select * from (select * from (select * from view1))}
} [list {main tab1 col1} {main tab1 col2}]

# This view will thwart the flattening optimization.
do_test capi2-13.1 {
  execsql {
    CREATE VIEW view2 AS SELECT * FROM tab1 limit 10 offset 10;
  }
} {}
breakpoint
do_test capi2-13.2 {
  check_origins {SELECT col2, col1 FROM view2}
} [list {main tab1 col2} {main tab1 col1}]
do_test capi2-13.3 {
  check_origins {SELECT col2 AS hello, col1 AS world FROM view2}
} [list {main tab1 col2} {main tab1 col1}]
do_test capi2-13.4 {
  check_origins {SELECT b, a FROM (SELECT col1 AS a, col2 AS b FROM view2)}
} [list {main tab1 col2} {main tab1 col1}]
do_test capi2-13.5 {
  check_origins {SELECT (SELECT col2 FROM view2), (SELECT col1 FROM view2)}
} [list {main tab1 col2} {main tab1 col1}]
do_test capi2-13.6 {
  check_origins {SELECT (SELECT col2), (SELECT col1) FROM view2}
} [list {main tab1 col2} {main tab1 col1}]
do_test capi2-13.7 {
  check_origins {SELECT * FROM view2}
} [list {main tab1 col1} {main tab1 col2}]
do_test capi2-13.8 {
  check_origins {select * from (select * from view2)}
} [list {main tab1 col1} {main tab1 col2}]
do_test capi2-13.9 {
  check_origins {select * from (select * from (select * from view2))}
} [list {main tab1 col1} {main tab1 col2}]
do_test capi2-13.10 {
  db close
  sqlite3 db test.db
  set ::DB [sqlite3_connection_pointer db]
  check_origins {select * from (select * from (select * from view2))}
} [list {main tab1 col1} {main tab1 col2}]
do_test capi2-13.11 {
  check_origins {select * from (select * from tab1 limit 10 offset 10)}
} [list {main tab1 col1} {main tab1 col2}]


} ;# ifcapable columnmetadata

db2 close
finish_test

Changes to test/capi3.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
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
#    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 testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.42 2006/02/10 02:27:47 danielk1977 Exp $
#

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

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
#
# Example:
#
# set STMT [sqlite3_prepare "SELECT 1, 2, 2;" -1 DUMMY]
# check_header test1.1 {1 2 3} {"" "" ""}
#
proc check_origin_header {STMT test dbs tables cols} {




  # Use the return value of sqlite3_column_count() to build
  # a list of column indexes. i.e. If sqlite3_column_count
  # is 3, build the list {0 1 2}.
  set ::idxlist [list]
  set ::numcols [sqlite3_column_count $STMT]
  for {set i 0} {$i < $::numcols} {incr i} {lappend ::idxlist $i}

  # Database names in UTF-8
  do_test $test.8 {
    set cnamelist [list]
    foreach i $idxlist {
      lappend cnamelist [sqlite3_column_database_name $STMT $i]
    } 
    set cnamelist
  } $dbs

  # Database names in UTF-16
  ifcapable {utf16} {
    do_test $test.9 {
      set cnamelist [list]
      foreach i $idxlist {
        lappend cnamelist [utf8 [sqlite3_column_database_name16 $STMT $i]]
      }
      set cnamelist
    } $dbs
  }

  # Table names in UTF-8
  do_test $test.10 {
    set cnamelist [list]

    foreach i $idxlist {lappend cnamelist [sqlite3_column_table_name $STMT $i]} 

    set cnamelist
  } $tables

  # Table names in UTF-16
  ifcapable {utf16} {
    do_test $test.11 {
      set cnamelist [list]
      foreach i $idxlist {
        lappend cnamelist [utf8 [sqlite3_column_table_name16 $STMT $i]]
      }
      set cnamelist
    } $tables
  }

  # Origin names in UTF-8
  do_test $test.12 {
    set cnamelist [list]
    foreach i $idxlist {
      lappend cnamelist [sqlite3_column_origin_name $STMT $i]
    } 
    set cnamelist
  } $cols

  # Origin declaration types in UTF-16
  ifcapable {utf16} {
    do_test $test.13 {
      set cnamelist [list]
      foreach i $idxlist {
        lappend cnamelist [utf8 [sqlite3_column_origin_name16 $STMT $i]]
      }
      set cnamelist
    } $cols

  }
}

# This proc is used to test the following APIs:
#
# sqlite3_data_count
# sqlite3_column_type







|







 







>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
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
#    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 testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.43 2006/02/10 07:07:16 danielk1977 Exp $
#

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

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
#
# Example:
#
# set STMT [sqlite3_prepare "SELECT 1, 2, 2;" -1 DUMMY]
# check_header test1.1 {1 2 3} {"" "" ""}
#
proc check_origin_header {STMT test dbs tables cols} {
  # If sqlite3_column_origin_name() and friends are not compiled into
  # this build, this proc is a no-op.
ifcapable columnmetadata {

    # Use the return value of sqlite3_column_count() to build
    # a list of column indexes. i.e. If sqlite3_column_count
    # is 3, build the list {0 1 2}.
    set ::idxlist [list]
    set ::numcols [sqlite3_column_count $STMT]
    for {set i 0} {$i < $::numcols} {incr i} {lappend ::idxlist $i}
  
    # Database names in UTF-8
    do_test $test.8 {
      set cnamelist [list]
      foreach i $idxlist {
        lappend cnamelist [sqlite3_column_database_name $STMT $i]
      } 
      set cnamelist
    } $dbs
  
    # Database names in UTF-16
    ifcapable {utf16} {
      do_test $test.9 {
        set cnamelist [list]
        foreach i $idxlist {
          lappend cnamelist [utf8 [sqlite3_column_database_name16 $STMT $i]]
        }
        set cnamelist
      } $dbs
    }
  
    # Table names in UTF-8
    do_test $test.10 {
      set cnamelist [list]
      foreach i $idxlist {
        lappend cnamelist [sqlite3_column_table_name $STMT $i]
      } 
      set cnamelist
    } $tables
  
    # Table names in UTF-16
    ifcapable {utf16} {
      do_test $test.11 {
        set cnamelist [list]
        foreach i $idxlist {
          lappend cnamelist [utf8 [sqlite3_column_table_name16 $STMT $i]]
        }
        set cnamelist
      } $tables
    }
  
    # Origin names in UTF-8
    do_test $test.12 {
      set cnamelist [list]
      foreach i $idxlist {
        lappend cnamelist [sqlite3_column_origin_name $STMT $i]
      } 
      set cnamelist
    } $cols
  
    # Origin declaration types in UTF-16
    ifcapable {utf16} {
      do_test $test.13 {
        set cnamelist [list]
        foreach i $idxlist {
          lappend cnamelist [utf8 [sqlite3_column_origin_name16 $STMT $i]]
        }
        set cnamelist
      } $cols
    }
  }
}

# This proc is used to test the following APIs:
#
# sqlite3_data_count
# sqlite3_column_type