mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-01 06:27:03 +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:
35
src/select.c
35
src/select.c
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** 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"
|
||||
|
||||
@ -689,25 +689,29 @@ static void generateColumnNames(
|
||||
int i;
|
||||
if( pParse->colNamesSet || v==0 || sqlite_malloc_failed ) return;
|
||||
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++){
|
||||
Expr *p;
|
||||
char *zType = 0;
|
||||
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 ){
|
||||
char *zName = pEList->a[i].zName;
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
|
||||
sqliteVdbeChangeP3(v, -1, zName, strlen(zName));
|
||||
continue;
|
||||
}
|
||||
p = pEList->a[i].pExpr;
|
||||
if( p==0 ) continue;
|
||||
showFullNames = (pParse->db->flags & SQLITE_FullColNames)!=0;
|
||||
if( p->op==TK_COLUMN && pTabList ){
|
||||
Table *pTab = pTabList->a[p->iTable - base].pTab;
|
||||
@ -751,17 +755,6 @@ static void generateColumnNames(
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
57
src/test1.c
57
src/test1.c
@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** 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 "tcl.h"
|
||||
@ -506,6 +506,60 @@ static int test_register_func(
|
||||
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.
|
||||
*/
|
||||
@ -527,6 +581,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite_create_aggregate", (Tcl_CmdProc*)test_create_aggregate },
|
||||
{ "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func },
|
||||
{ "sqlite_abort", (Tcl_CmdProc*)sqlite_abort },
|
||||
{ "sqlite_datatypes", (Tcl_CmdProc*)sqlite_datatypes },
|
||||
#ifdef MEMORY_DEBUG
|
||||
{ "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail },
|
||||
{ "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat },
|
||||
|
Reference in New Issue
Block a user