1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Document the SHOW_DATATYPES pragma and add tests for it to the test suite.

Make sure datatypes are show even for aliased columns.
Tickets #220 and #221. (CVS 822)

FossilOrigin-Name: e84d3afe7b9153d003fdcca98221f446c004ffa2
This commit is contained in:
drh
2003-01-11 14:19:51 +00:00
parent 836faa4843
commit 5a38705ecb
7 changed files with 160 additions and 44 deletions

View File

@ -1,5 +1,5 @@
C Remove\sthe\sColumnCount\sopcode,\swhich\shad\sbecome\sa\sno-op.\s(CVS\s821) C Document\sthe\sSHOW_DATATYPES\spragma\sand\sadd\stests\sfor\sit\sto\sthe\stest\ssuite.\nMake\ssure\sdatatypes\sare\sshow\seven\sfor\saliased\scolumns.\nTickets\s#220\sand\s#221.\s(CVS\s822)
D 2003-01-11T13:30:57 D 2003-01-11T14:19:52
F Makefile.in 868c17a1ae1c07603d491274cc8f86c04acf2a1e F Makefile.in 868c17a1ae1c07603d491274cc8f86c04acf2a1e
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@ -37,14 +37,14 @@ F src/pager.h 540833e8cb826b80ce2e39aa917deee5e12db626
F src/parse.y 427a17888c117cc9cc35311eda0603d55437f02b F src/parse.y 427a17888c117cc9cc35311eda0603d55437f02b
F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167 F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
F src/select.c 754af8fabcdfae2fd0f49a5b4cce6bc2bcc370f8 F src/select.c b52c1dccbfc35ff13c84b4321a0bd2ac3a23d2f2
F src/shell.c c9946847b81b8b7f32ad195498dafbc623c6874f F src/shell.c c9946847b81b8b7f32ad195498dafbc623c6874f
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in 98b1574b2362abe02c4a4c73b9dbf99bcd713ab3 F src/sqlite.h.in 98b1574b2362abe02c4a4c73b9dbf99bcd713ab3
F src/sqliteInt.h 4f7511446a7616ffa24542dda5bf596776852c2d F src/sqliteInt.h 4f7511446a7616ffa24542dda5bf596776852c2d
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63 F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
F src/tclsqlite.c 9f2c00a92338c51171ded8943bd42d77f7e69e64 F src/tclsqlite.c 9f2c00a92338c51171ded8943bd42d77f7e69e64
F src/test1.c a46e9f61915b32787c5d5a05a4b92e4dacc437d9 F src/test1.c 5efd7a8b18ff63e570e94cd7c842a74fb08dd511
F src/test2.c 03f05e984c8e2f2badc44644d42baf72b249096b F src/test2.c 03f05e984c8e2f2badc44644d42baf72b249096b
F src/test3.c c12ea7f1c3fbbd58904e81e6cb10ad424e6fc728 F src/test3.c c12ea7f1c3fbbd58904e81e6cb10ad424e6fc728
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
@ -86,8 +86,8 @@ F test/misc1.test 828ea289e37d396432064ab23d2efc6ce660a0f9
F test/misuse.test a3aa2b18a97e4c409a1fcaff5151a4dd804a0162 F test/misuse.test a3aa2b18a97e4c409a1fcaff5151a4dd804a0162
F test/notnull.test b1f3e42fc475b0b5827b27b2e9b562081995ff30 F test/notnull.test b1f3e42fc475b0b5827b27b2e9b562081995ff30
F test/null.test 5c2b57307e4b6178aae825eb65ddbee01e76b0fd F test/null.test 5c2b57307e4b6178aae825eb65ddbee01e76b0fd
F test/pager.test b0c0d00cd5dce0ce21f16926956b195c0ab5044c F test/pager.test d3a2e2f00999f97e056822a39d5ee2fad18bf12c
F test/pragma.test 0b9675ef1f5ba5b43abfa337744445fc5b01a34a F test/pragma.test 94c82c75af9c237866ce5290494a7bc08b661092
F test/printf.test a29b8afa24edb4411adfe473b12ac32c84098fce F test/printf.test a29b8afa24edb4411adfe473b12ac32c84098fce
F test/quick.test b372c8dad4fa1554747e90683fc72e59c0c98502 F test/quick.test b372c8dad4fa1554747e90683fc72e59c0c98502
F test/quote.test 08f23385c685d3dc7914ec760d492cacea7f6e3d F test/quote.test 08f23385c685d3dc7914ec760d492cacea7f6e3d
@ -142,7 +142,7 @@ F www/faq.tcl 06276ff6c3e369374bb83034cc9d4a7d3a2a34a1
F www/fileformat.tcl a4b5c2c6e89b7d42d09f97fd4d7bbd39cbf24936 F www/fileformat.tcl a4b5c2c6e89b7d42d09f97fd4d7bbd39cbf24936
F www/formatchng.tcl b4449e065d2da38b6563bdf12cf46cfe1d4d765e F www/formatchng.tcl b4449e065d2da38b6563bdf12cf46cfe1d4d765e
F www/index.tcl 7764032a802318a916ae747b047c9ad5149658a5 F www/index.tcl 7764032a802318a916ae747b047c9ad5149658a5
F www/lang.tcl 6be4254a751ab183ec974fe65375f50230c777f3 F www/lang.tcl 1ea38a9fe867e4fed2220f519f5c0862e7022c53
F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc
F www/nulls.tcl 29497dac2bc5b437aa7e2e94577dad4d8933ed26 F www/nulls.tcl 29497dac2bc5b437aa7e2e94577dad4d8933ed26
F www/omitted.tcl 118062f40a203fcb88b8d68ef1d7c0073ac191ec F www/omitted.tcl 118062f40a203fcb88b8d68ef1d7c0073ac191ec
@ -152,7 +152,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
P 13f82d67f60ae869d5bf2e31d9357a860aa62bad P 86deb12d68026913d181f9498144fa56445899f2
R 739d9eedd846bdcebaf53de604e2ab96 R c01866c76545ca162ef63d830c027659
U drh U drh
Z 10fbc95a42ce97941079cb975b1ac545 Z 9785e9756356084c0f8bc12f51b8fd40

View File

@ -1 +1 @@
86deb12d68026913d181f9498144fa56445899f2 e84d3afe7b9153d003fdcca98221f446c004ffa2

View File

@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser ** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite. ** to handle SELECT statements in SQLite.
** **
** $Id: select.c,v 1.118 2003/01/11 13:30:58 drh Exp $ ** $Id: select.c,v 1.119 2003/01/11 14:19:52 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@ -689,25 +689,29 @@ static void generateColumnNames(
int i; int i;
if( pParse->colNamesSet || v==0 || sqlite_malloc_failed ) return; if( pParse->colNamesSet || v==0 || sqlite_malloc_failed ) return;
pParse->colNamesSet = 1; pParse->colNamesSet = 1;
#if 0
if( pParse->db->flags & SQLITE_ReportTypes ){
sqliteVdbeAddOp(v, OP_ColumnCount, pEList->nExpr*2, 0);
}else{
sqliteVdbeAddOp(v, OP_ColumnCount, pEList->nExpr, 0);
}
#endif
for(i=0; i<pEList->nExpr; i++){ for(i=0; i<pEList->nExpr; i++){
Expr *p; Expr *p;
char *zType = 0; char *zType = 0;
int showFullNames; int showFullNames;
p = pEList->a[i].pExpr;
if( p==0 ) continue;
if( pParse->db->flags & SQLITE_ReportTypes ){
if( zType==0 ){
if( sqliteExprType(p)==SQLITE_SO_TEXT ){
zType = "TEXT";
}else{
zType = "NUMERIC";
}
}
sqliteVdbeAddOp(v, OP_ColumnName, i + pEList->nExpr, 0);
sqliteVdbeChangeP3(v, -1, zType, P3_STATIC);
}
if( pEList->a[i].zName ){ if( pEList->a[i].zName ){
char *zName = pEList->a[i].zName; char *zName = pEList->a[i].zName;
sqliteVdbeAddOp(v, OP_ColumnName, i, 0); sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
sqliteVdbeChangeP3(v, -1, zName, strlen(zName)); sqliteVdbeChangeP3(v, -1, zName, strlen(zName));
continue; continue;
} }
p = pEList->a[i].pExpr;
if( p==0 ) continue;
showFullNames = (pParse->db->flags & SQLITE_FullColNames)!=0; showFullNames = (pParse->db->flags & SQLITE_FullColNames)!=0;
if( p->op==TK_COLUMN && pTabList ){ if( p->op==TK_COLUMN && pTabList ){
Table *pTab = pTabList->a[p->iTable - base].pTab; Table *pTab = pTabList->a[p->iTable - base].pTab;
@ -751,17 +755,6 @@ static void generateColumnNames(
sqliteVdbeAddOp(v, OP_ColumnName, i, 0); sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
sqliteVdbeChangeP3(v, -1, zName, strlen(zName)); sqliteVdbeChangeP3(v, -1, zName, strlen(zName));
} }
if( pParse->db->flags & SQLITE_ReportTypes ){
if( zType==0 ){
if( sqliteExprType(p)==SQLITE_SO_TEXT ){
zType = "TEXT";
}else{
zType = "NUMERIC";
}
}
sqliteVdbeAddOp(v, OP_ColumnName, i + pEList->nExpr, 0);
sqliteVdbeChangeP3(v, -1, zType, P3_STATIC);
}
} }
} }

View File

@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated ** is not included in the SQLite library. It is used for automated
** testing of the SQLite library. ** testing of the SQLite library.
** **
** $Id: test1.c,v 1.13 2002/08/31 18:53:08 drh Exp $ ** $Id: test1.c,v 1.14 2003/01/11 14:19:52 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "tcl.h" #include "tcl.h"
@ -506,6 +506,60 @@ static int test_register_func(
return TCL_OK; return TCL_OK;
} }
/*
** This SQLite callback records the datatype of all columns.
**
** The pArg argument is really a pointer to a TCL interpreter. The
** column names are inserted as the result of this interpreter.
**
** This routine returns non-zero which causes the query to abort.
*/
static int rememberDataTypes(void *pArg, int nCol, char **argv, char **colv){
int i;
Tcl_Interp *interp = (Tcl_Interp*)pArg;
Tcl_Obj *pList, *pElem;
if( colv[nCol+1]==0 ){
return 1;
}
pList = Tcl_NewObj();
for(i=0; i<nCol; i++){
pElem = Tcl_NewStringObj(colv[i+nCol] ? colv[i+nCol] : "NULL", -1);
Tcl_ListObjAppendElement(interp, pList, pElem);
}
Tcl_SetObjResult(interp, pList);
return 1;
}
/*
** Invoke an SQL statement but ignore all the data in the result. Instead,
** return a list that consists of the datatypes of the various columns.
**
** This only works if "PRAGMA show_datatypes=on" has been executed against
** the database connection.
*/
static int sqlite_datatypes(
void *NotUsed,
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
char **argv /* Text of each argument */
){
sqlite *db;
int rc;
if( argc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" DB SQL", 0);
return TCL_ERROR;
}
db = (sqlite*)strtol(argv[1], 0, 0);
rc = sqlite_exec(db, argv[2], rememberDataTypes, interp, 0);
if( rc!=0 && rc!=SQLITE_ABORT ){
Tcl_AppendResult(interp, sqlite_error_string(rc), 0);
return TCL_ERROR;
}
return TCL_OK;
}
/* /*
** Register commands with the TCL interpreter. ** Register commands with the TCL interpreter.
*/ */
@ -527,6 +581,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, { "sqlite_create_aggregate", (Tcl_CmdProc*)test_create_aggregate },
{ "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func },
{ "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort },
{ "sqlite_datatypes", (Tcl_CmdProc*)sqlite_datatypes },
#ifdef MEMORY_DEBUG #ifdef MEMORY_DEBUG
{ "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail }, { "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail },
{ "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat }, { "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat },

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The # This file implements regression tests for SQLite library. The
# focus of this script is page cache subsystem. # focus of this script is page cache subsystem.
# #
# $Id: pager.test,v 1.11 2002/02/02 18:49:21 drh Exp $ # $Id: pager.test,v 1.12 2003/01/11 14:19:52 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
@ -48,12 +48,12 @@ do_test pager-2.1 {
set ::p1 [pager_open ptf1.db 10] set ::p1 [pager_open ptf1.db 10]
} msg] } msg]
} {0} } {0}
do_test pager-2.2 { #do_test pager-2.2 {
set v [catch { # set v [catch {
set ::g1 [page_get $::p1 0] # set ::g1 [page_get $::p1 0]
} msg] # } msg]
lappend v $msg # lappend v $msg
} {1 SQLITE_ERROR} #} {1 SQLITE_ERROR}
do_test pager-2.3.1 { do_test pager-2.3.1 {
set ::gx [page_lookup $::p1 1] set ::gx [page_lookup $::p1 1]
} {} } {}

View File

@ -12,7 +12,7 @@
# #
# This file implements tests for the PRAGMA command. # This file implements tests for the PRAGMA command.
# #
# $Id: pragma.test,v 1.1 2002/03/06 22:01:37 drh Exp $ # $Id: pragma.test,v 1.2 2003/01/11 14:19:52 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@ -22,7 +22,7 @@ source $testdir/tester.tcl
# #
db close db close
file delete test.db file delete test.db
sqlite db test.db set DB [sqlite db test.db]
do_test pragma-1.1 { do_test pragma-1.1 {
execsql { execsql {
@ -108,7 +108,7 @@ do_test pragma-1.9 {
} {123 123 0 0} } {123 123 0 0}
do_test pragma-1.10 { do_test pragma-1.10 {
db close db close
sqlite db test.db set ::DB [sqlite db test.db]
execsql { execsql {
PRAGMA cache_size; PRAGMA cache_size;
PRAGMA default_cache_size; PRAGMA default_cache_size;
@ -117,4 +117,43 @@ do_test pragma-1.10 {
} }
} {123 123 0 0} } {123 123 0 0}
do_test pragma-1.11 {
execsql {
PRAGMA show_datatypes=on;
PRAGMA empty_result_callbacks=off;
}
sqlite_datatypes $::DB {SELECT * FROM sqlite_master}
} {}
do_test pragma-1.12 {
execsql {
PRAGMA empty_result_callbacks=on;
}
sqlite_datatypes $::DB {SELECT * FROM sqlite_master}
} {NUMERIC NUMERIC NUMERIC NUMERIC NUMERIC}
do_test pragma-1.13 {
execsql {
CREATE TABLE t1(
a INTEGER,
b TEXT,
c WHATEVER,
d CLOB,
e BLOB,
f VARCHAR(123),
g nVaRcHaR(432)
);
}
sqlite_datatypes $::DB {SELECT * FROM t1}
} {NUMERIC TEXT NUMERIC TEXT TEXT TEXT TEXT}
do_test pragma-1.14 {
sqlite_datatypes $::DB {
SELECT 1, 'hello', NULL
}
} {NUMERIC TEXT TEXT}
do_test pragma-1.15 {
sqlite_datatypes $::DB {
SELECT 1+2 AS X, 'hello' || 5 AS Y, NULL AS Z
}
} {NUMERIC TEXT TEXT}
finish_test finish_test

View File

@ -1,7 +1,7 @@
# #
# Run this Tcl script to generate the sqlite.html file. # Run this Tcl script to generate the sqlite.html file.
# #
set rcsid {$Id: lang.tcl,v 1.46 2002/09/12 14:08:32 drh Exp $} set rcsid {$Id: lang.tcl,v 1.47 2003/01/11 14:19:52 drh Exp $}
puts {<html> puts {<html>
<head> <head>
@ -1117,6 +1117,35 @@ with caution.</p>
a description of all problems. If everything is in order, "ok" is a description of all problems. If everything is in order, "ok" is
returned.</p> returned.</p>
<li><p><b>PRAGMA show_datatypes = ON;<br>PRAGMA show_datatypes = OFF;</b></p>
<p>When turned on, the SHOW_DATATYPES pragma causes extra entries containing
the names of <a href="datatypes.html">datatypes</a> of columns to be
appended to the 4th ("columnNames") argument to <b>sqlite_exec()</b>
callbacks. When
turned off, the 4th argument to callbacks contains only the column names.
SQLite <a href="datatypes.html">datatypes</a> are always either "TEXT"
or "NUMERIC".
The following chart illustrates the difference for the query
"SELECT 'xyzzy', 5, NULL AS empty ":</p>
<blockquote><table border=0>
<tr><th>show_datatypes=OFF</th><th width=30></th>
<th>show_datatypes=ON</th></tr>
<tr><td valign="top">
azCol[0] = "xyzzy";<br>
azCol[1] = "5";<br>
azCol[2] = "empty";<br>
azCol[3] = 0;
</td><td></td><td valign="top">
azCol[0] = "xyzzy";<br>
azCol[1] = "5";<br>
azCol[2] = "empty";<br>
azCol[3] = "TEXT";<br>
azCol[4] = "NUMERIC";<br>
azCol[5] = "TEXT";<br>
azCol[6] = 0;
</td></table></blockquote></li>
<li><p><b>PRAGMA synchronous; <li><p><b>PRAGMA synchronous;
<br>PRAGMA synchronous = ON; <br>PRAGMA synchronous = ON;
<br>PRAGMA synchronous = OFF;</b></p> <br>PRAGMA synchronous = OFF;</b></p>