aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/copy.c5
-rw-r--r--src/delete.c5
-rw-r--r--src/insert.c4
-rw-r--r--src/main.c7
-rw-r--r--src/pragma.c88
-rw-r--r--src/select.c41
-rw-r--r--src/test1.c147
-rw-r--r--src/update.c4
-rw-r--r--src/vdbe.c53
-rw-r--r--src/vdbe.h3
-rw-r--r--src/vdbeInt.h2
-rw-r--r--src/vdbeaux.c40
12 files changed, 274 insertions, 125 deletions
diff --git a/src/copy.c b/src/copy.c
index 72bc5ac0c..c12de507d 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the COPY command.
**
-** $Id: copy.c,v 1.12 2004/05/25 23:35:18 danielk1977 Exp $
+** $Id: copy.c,v 1.13 2004/05/26 10:11:05 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -97,10 +97,9 @@ void sqlite3Copy(
sqlite3VdbeAddOp(v, OP_Noop, 0, 0);
sqlite3EndWriteOperation(pParse);
if( db->flags & SQLITE_CountRows ){
- sqlite3VdbeAddOp(v, OP_ColumnName, 0, 1);
- sqlite3VdbeChangeP3(v, -1, "rows inserted", P3_STATIC);
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC);
}
}
diff --git a/src/delete.c b/src/delete.c
index 0922c0684..2e69961d7 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
-** $Id: delete.c,v 1.69 2004/05/25 23:35:18 danielk1977 Exp $
+** $Id: delete.c,v 1.70 2004/05/26 10:11:05 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -303,10 +303,9 @@ void sqlite3DeleteFrom(
** Return the number of rows that were deleted.
*/
if( db->flags & SQLITE_CountRows ){
- sqlite3VdbeAddOp(v, OP_ColumnName, 0, 1);
- sqlite3VdbeChangeP3(v, -1, "rows deleted", P3_STATIC);
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "rows deleted", P3_STATIC);
}
delete_from_cleanup:
diff --git a/src/insert.c b/src/insert.c
index 0091c6d0e..4741d968d 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
-** $Id: insert.c,v 1.106 2004/05/25 23:35:18 danielk1977 Exp $
+** $Id: insert.c,v 1.107 2004/05/26 10:11:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -617,10 +617,10 @@ void sqlite3Insert(
** Return the number of rows inserted.
*/
if( db->flags & SQLITE_CountRows ){
- sqlite3VdbeOp3(v, OP_ColumnName, 0, 1, "rows inserted", P3_STATIC);
sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0);
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC);
}
insert_cleanup:
diff --git a/src/main.c b/src/main.c
index fa9b22fee..8a4f5ce99 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.192 2004/05/26 06:58:44 danielk1977 Exp $
+** $Id: main.c,v 1.193 2004/05/26 10:11:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -930,6 +930,11 @@ int sqlite3_prepare(
if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
sqlite3VdbeSetNumCols(sParse.pVdbe, 5);
+ sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC);
}
prepare_out:
diff --git a/src/pragma.c b/src/pragma.c
index 4d72cad37..002408bc2 100644
--- a/src/pragma.c
+++ b/src/pragma.c
@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
-** $Id: pragma.c,v 1.31 2004/05/26 06:58:44 danielk1977 Exp $
+** $Id: pragma.c,v 1.32 2004/05/26 10:11:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -129,11 +129,9 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
Vdbe *v;
if( strcmp(zLeft,zRight)==0 && (v = sqlite3GetVdbe(pParse))!=0 ){
sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeOp3(v, OP_ColumnName, 0, 1, aPragma[i].zName, P3_STATIC);
- sqlite3VdbeOp3(v, OP_ColumnName, 1, 0, "boolean", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, aPragma[i].zName, P3_STATIC);
sqlite3VdbeCode(v, OP_Integer, (db->flags & aPragma[i].mask)!=0, 0,
- OP_Callback, 1, 0,
- 0);
+ OP_Callback, 1, 0, 0);
}else if( getBoolean(zRight) ){
db->flags |= aPragma[i].mask;
}else{
@@ -202,12 +200,12 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
{ OP_Integer, 0, 0, 0},
{ OP_Ne, 0, 6, 0},
{ OP_Integer, 0, 0, 0}, /* 5 */
- { OP_ColumnName, 0, 1, "cache_size"},
{ OP_Callback, 1, 0, 0},
};
int addr;
if( pRight->z==pLeft->z ){
sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
}else{
@@ -242,7 +240,6 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
*/
if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
static VdbeOpList getCacheSize[] = {
- { OP_ColumnName, 0, 1, "cache_size"},
{ OP_Callback, 1, 0, 0},
};
if( pRight->z==pLeft->z ){
@@ -250,6 +247,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
if( size<0 ) size = -size;
sqlite3VdbeAddOp(v, OP_Integer, size, 0);
sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
}else{
int size = atoi(zRight);
@@ -281,24 +279,24 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
*/
if( sqlite3StrICmp(zLeft,"default_synchronous")==0 ){
static VdbeOpList getSync[] = {
- { OP_ColumnName, 0, 1, "synchronous"},
{ OP_ReadCookie, 0, 3, 0},
{ OP_Dup, 0, 0, 0},
- { OP_If, 0, 0, 0}, /* 3 */
+ { OP_If, 0, 0, 0}, /* 2 */
{ OP_ReadCookie, 0, 2, 0},
{ OP_Integer, 0, 0, 0},
{ OP_Lt, 0, 5, 0},
{ OP_AddImm, 1, 0, 0},
{ OP_Callback, 1, 0, 0},
{ OP_Halt, 0, 0, 0},
- { OP_AddImm, -1, 0, 0}, /* 10 */
+ { OP_AddImm, -1, 0, 0}, /* 9 */
{ OP_Callback, 1, 0, 0}
};
int addr;
if( pRight->z==pLeft->z ){
sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
addr = sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync);
- sqlite3VdbeChangeP2(v, addr+3, addr+10);
+ sqlite3VdbeChangeP2(v, addr+2, addr+9);
}else{
int size = db->cache_size;
if( size<0 ) size = -size;
@@ -335,11 +333,11 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
*/
if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
static VdbeOpList getSync[] = {
- { OP_ColumnName, 0, 1, "synchronous"},
{ OP_Callback, 1, 0, 0},
};
if( pRight->z==pLeft->z ){
sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
sqlite3VdbeAddOp(v, OP_Integer, db->safety_level-1, 0);
sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync);
}else{
@@ -371,17 +369,14 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
Table *pTab;
pTab = sqlite3FindTable(db, zRight, 0);
if( pTab ){
- static VdbeOpList tableInfoPreface[] = {
- { OP_ColumnName, 0, 0, "cid"},
- { OP_ColumnName, 1, 0, "name"},
- { OP_ColumnName, 2, 0, "type"},
- { OP_ColumnName, 3, 0, "notnull"},
- { OP_ColumnName, 4, 0, "dflt_value"},
- { OP_ColumnName, 5, 1, "pk"},
- };
int i;
sqlite3VdbeSetNumCols(v, 6);
- sqlite3VdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
+ sqlite3VdbeSetColName(v, 0, "cid", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, "type", P3_STATIC);
+ sqlite3VdbeSetColName(v, 3, "notnull", P3_STATIC);
+ sqlite3VdbeSetColName(v, 4, "dflt_value", P3_STATIC);
+ sqlite3VdbeSetColName(v, 5, "pk", P3_STATIC);
sqlite3ViewGetColumnNames(pParse, pTab);
for(i=0; i<pTab->nCol; i++){
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
@@ -402,15 +397,12 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
Table *pTab;
pIdx = sqlite3FindIndex(db, zRight, 0);
if( pIdx ){
- static VdbeOpList tableInfoPreface[] = {
- { OP_ColumnName, 0, 0, "seqno"},
- { OP_ColumnName, 1, 0, "cid"},
- { OP_ColumnName, 2, 1, "name"},
- };
int i;
pTab = pIdx->pTable;
sqlite3VdbeSetNumCols(v, 3);
- sqlite3VdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
+ sqlite3VdbeSetColName(v, 0, "seqno", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, "cid", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, "name", P3_STATIC);
for(i=0; i<pIdx->nColumn; i++){
int cnum = pIdx->aiColumn[i];
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
@@ -432,14 +424,10 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
}
if( pTab && pIdx ){
int i = 0;
- static VdbeOpList indexListPreface[] = {
- { OP_ColumnName, 0, 0, "seq"},
- { OP_ColumnName, 1, 0, "name"},
- { OP_ColumnName, 2, 1, "unique"},
- };
-
sqlite3VdbeSetNumCols(v, 3);
- sqlite3VdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
+ sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, "unique", P3_STATIC);
while(pIdx){
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
sqlite3VdbeOp3(v, OP_String, 0, 0, pIdx->zName, 0);
@@ -461,16 +449,12 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
}
if( pTab && pFK ){
int i = 0;
- static VdbeOpList indexListPreface[] = {
- { OP_ColumnName, 0, 0, "id"},
- { OP_ColumnName, 1, 0, "seq"},
- { OP_ColumnName, 2, 0, "table"},
- { OP_ColumnName, 3, 0, "from"},
- { OP_ColumnName, 4, 1, "to"},
- };
-
- sqlite3VdbeSetNumCols(v, 6);
- sqlite3VdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
+ sqlite3VdbeSetNumCols(v, 5);
+ sqlite3VdbeSetColName(v, 0, "id", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, "seq", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, "table", P3_STATIC);
+ sqlite3VdbeSetColName(v, 3, "from", P3_STATIC);
+ sqlite3VdbeSetColName(v, 4, "to", P3_STATIC);
while(pFK){
int j;
for(j=0; j<pFK->nCol; j++){
@@ -490,14 +474,10 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
if( sqlite3StrICmp(zLeft, "database_list")==0 ){
int i;
- static VdbeOpList indexListPreface[] = {
- { OP_ColumnName, 0, 0, "seq"},
- { OP_ColumnName, 1, 0, "name"},
- { OP_ColumnName, 2, 1, "file"},
- };
-
sqlite3VdbeSetNumCols(v, 3);
- sqlite3VdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
+ sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, "file", P3_STATIC);
for(i=0; i<db->nDb; i++){
if( db->aDb[i].pBt==0 ) continue;
assert( db->aDb[i].zName!=0 );
@@ -523,12 +503,12 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
*/
if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
static VdbeOpList getTmpDbLoc[] = {
- { OP_ColumnName, 0, 1, "temp_store"},
{ OP_Callback, 1, 0, 0},
};
if( pRight->z==pLeft->z ){
sqlite3VdbeAddOp(v, OP_Integer, db->temp_store, 0);
sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "temp_store", P3_STATIC);
sqlite3VdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
}else{
changeTempStorage(pParse, zRight);
@@ -548,11 +528,11 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
*/
if( sqlite3StrICmp(zLeft, "default_temp_store")==0 ){
static VdbeOpList getTmpDbLoc[] = {
- { OP_ColumnName, 0, 1, "temp_store"},
{ OP_ReadCookie, 0, 5, 0},
{ OP_Callback, 1, 0, 0}};
if( pRight->z==pLeft->z ){
sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "temp_store", P3_STATIC);
sqlite3VdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
}else{
sqlite3BeginWriteOperation(pParse, 0, 0);
@@ -582,7 +562,6 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
static VdbeOpList initCode[] = {
{ OP_Integer, 0, 0, 0},
{ OP_MemStore, 0, 1, 0},
- { OP_ColumnName, 0, 1, "integrity_check"},
};
/* Code that appears at the end of the integrity check. If no error
@@ -599,6 +578,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
/* Initialize the VDBE program */
sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
sqlite3VdbeAddOpList(v, ArraySize(initCode), initCode);
/* Do an integrity check on each database file */
diff --git a/src/select.c b/src/select.c
index 52c35ebce..2340cb5b4 100644
--- a/src/select.c
+++ b/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.176 2004/05/26 06:18:38 danielk1977 Exp $
+** $Id: select.c,v 1.177 2004/05/26 10:11:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -682,6 +682,11 @@ static void generateColumnNames(
sqlite *db = pParse->db;
int fullNames, shortNames;
+ /* If this is an EXPLAIN, skip this step */
+ if( pParse->explain ){
+ return SQLITE_OK;
+ }
+
assert( v!=0 );
if( pParse->colNamesSet || v==0 || sqlite3_malloc_failed ) return;
pParse->colNamesSet = 1;
@@ -695,7 +700,7 @@ static void generateColumnNames(
if( p==0 ) continue;
if( pEList->a[i].zName ){
char *zName = pEList->a[i].zName;
- sqlite3VdbeOp3(v, OP_ColumnName, i, p2, zName, 0);
+ sqlite3VdbeSetColName(v, i, zName, 0);
continue;
}
if( p->op==TK_COLUMN && pTabList ){
@@ -713,8 +718,8 @@ static void generateColumnNames(
zCol = pTab->aCol[iCol].zName;
}
if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
- int addr = sqlite3VdbeOp3(v,OP_ColumnName, i, p2, p->span.z, p->span.n);
- sqlite3VdbeCompressSpace(v, addr);
+ sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
+ /* sqlite3VdbeCompressSpace(v, addr); */
}else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
char *zName = 0;
char *zTab;
@@ -722,18 +727,18 @@ static void generateColumnNames(
zTab = pTabList->a[j].zAlias;
if( fullNames || zTab==0 ) zTab = pTab->zName;
sqlite3SetString(&zName, zTab, ".", zCol, 0);
- sqlite3VdbeOp3(v, OP_ColumnName, i, p2, zName, P3_DYNAMIC);
+ sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC);
}else{
- sqlite3VdbeOp3(v, OP_ColumnName, i, p2, zCol, 0);
+ sqlite3VdbeSetColName(v, i, zCol, 0);
}
}else if( p->span.z && p->span.z[0] ){
- int addr = sqlite3VdbeOp3(v,OP_ColumnName, i, p2, p->span.z, p->span.n);
- sqlite3VdbeCompressSpace(v, addr);
+ sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
+ /* sqlite3VdbeCompressSpace(v, addr); */
}else{
char zName[30];
assert( p->op!=TK_COLUMN || pTabList==0 );
sprintf(zName, "column%d", i+1);
- sqlite3VdbeOp3(v, OP_ColumnName, i, p2, zName, 0);
+ sqlite3VdbeSetColName(v, i, zName, 0);
}
}
}
@@ -1429,7 +1434,6 @@ static int multiSelect(
assert( p->pEList );
if( eDest==SRT_Callback ){
generateColumnNames(pParse, 0, p->pEList);
- generateColumnTypes(pParse, p->pSrc, p->pEList);
}
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
@@ -1500,7 +1504,6 @@ static int multiSelect(
assert( p->pEList );
if( eDest==SRT_Callback ){
generateColumnNames(pParse, 0, p->pEList);
- generateColumnTypes(pParse, p->pSrc, p->pEList);
}
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
@@ -1942,9 +1945,6 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
*/
v = sqlite3GetVdbe(pParse);
if( v==0 ) return 0;
- if( eDest==SRT_Callback ){
- generateColumnTypes(pParse, p->pSrc, p->pEList);
- }
/* If the output is destined for a temporary table, open that table.
*/
@@ -2294,19 +2294,6 @@ int sqlite3Select(
*/
computeLimitRegisters(pParse, p);
- /* Identify column types if we will be using a callback. This
- ** step is skipped if the output is going to a destination other
- ** than a callback.
- **
- ** We have to do this separately from the creation of column names
- ** above because if the pTabList contains views then they will not
- ** have been resolved and we will not know the column types until
- ** now.
- */
- if( eDest==SRT_Callback ){
- generateColumnTypes(pParse, pTabList, pEList);
- }
-
/* If the output is destined for a temporary table, open that table.
*/
if( eDest==SRT_TempTable ){
diff --git a/src/test1.c b/src/test1.c
index cc9aa3b5b..0d3823c09 100644
--- a/src/test1.c
+++ b/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.56 2004/05/26 06:58:44 danielk1977 Exp $
+** $Id: test1.c,v 1.57 2004/05/26 10:11:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -742,6 +742,7 @@ static int test_finalize(
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
rc = sqlite3_finalize(pStmt);
+ Tcl_SetResult(interp, errorName(rc), TCL_STATIC);
if( rc ){
return TCL_ERROR;
}
@@ -1406,6 +1407,66 @@ static int test_column_data16(
}
/*
+** Usage: sqlite3_column_name STMT column
+**
+** Advance the statement to the next row.
+*/
+static int test_column_name(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ sqlite3_stmt *pStmt;
+ int col;
+
+ if( objc!=3 ){
+ Tcl_AppendResult(interp, "wrong # args: should be \"",
+ Tcl_GetString(objv[0]), " STMT column", 0);
+ return TCL_ERROR;
+ }
+
+ if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
+ if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
+
+ Tcl_SetResult(interp, (char *)sqlite3_column_name(pStmt, col), 0);
+
+ return TCL_OK;
+}
+
+/*
+** Usage: sqlite3_column_name16 STMT column
+**
+** Advance the statement to the next row.
+*/
+static int test_column_name16(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ sqlite3_stmt *pStmt;
+ int col;
+ Tcl_Obj *pRet;
+ const void *zName16;
+
+ if( objc!=3 ){
+ Tcl_AppendResult(interp, "wrong # args: should be \"",
+ Tcl_GetString(objv[0]), " STMT column", 0);
+ return TCL_ERROR;
+ }
+
+ if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
+ if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
+
+ zName16 = sqlite3_column_name16(pStmt, col);
+ pRet = Tcl_NewByteArrayObj(zName16, sqlite3utf16ByteLen(zName16, -1)+2);
+ Tcl_SetObjResult(interp, pRet);
+
+ return TCL_OK;
+}
+
+/*
** Usage: sqlite3_column_count STMT
**
** Return the number of columns returned by the sql statement STMT.
@@ -1431,6 +1492,82 @@ static int test_column_count(
}
/*
+** Usage: sqlite3_column_type STMT column
+**
+** Return the type of the data in column 'column' of the current row.
+*/
+static int test_column_type(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ sqlite3_stmt *pStmt;
+ int col;
+ int tp;
+
+ if( objc!=3 ){
+ Tcl_AppendResult(interp, "wrong # args: should be \"",
+ Tcl_GetString(objv[0]), " STMT column", 0);
+ return TCL_ERROR;
+ }
+
+ if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
+ if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
+
+ tp = sqlite3_column_type(pStmt, col);
+ switch( tp ){
+ case SQLITE3_INTEGER:
+ Tcl_SetResult(interp, "INTEGER", TCL_STATIC);
+ break;
+ case SQLITE3_NULL:
+ Tcl_SetResult(interp, "NULL", TCL_STATIC);
+ break;
+ case SQLITE3_FLOAT:
+ Tcl_SetResult(interp, "FLOAT", TCL_STATIC);
+ break;
+ case SQLITE3_TEXT:
+ Tcl_SetResult(interp, "TEXT", TCL_STATIC);
+ break;
+ case SQLITE3_BLOB:
+ Tcl_SetResult(interp, "BLOB", TCL_STATIC);
+ break;
+ default:
+ assert(0);
+ }
+
+ return TCL_OK;
+}
+
+/*
+** Usage: sqlite3_column_int STMT column
+**
+** Return the data in column 'column' of the current row cast as an
+** integer.
+*/
+static int test_column_int(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ sqlite3_stmt *pStmt;
+ int col;
+
+ if( objc!=3 ){
+ Tcl_AppendResult(interp, "wrong # args: should be \"",
+ Tcl_GetString(objv[0]), " STMT column", 0);
+ return TCL_ERROR;
+ }
+
+ if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
+ if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
+
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_column_int(pStmt, col)));
+ return TCL_OK;
+}
+
+/*
** Usage: sqlite3_data_count STMT
**
** Return the number of columns returned by the sql statement STMT.
@@ -1551,8 +1688,12 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_reset", (Tcl_ObjCmdProc*)test_reset },
{ "sqlite3_step", (Tcl_ObjCmdProc*)test_step},
{ "sqlite3_column_data", (Tcl_ObjCmdProc*)test_column_data },
- { "sqlite3_column_data16", (Tcl_ObjCmdProc*)test_column_data16 },
- { "sqlite3_column_count", (Tcl_ObjCmdProc*)test_column_count },
+ { "sqlite3_column_data16", (Tcl_ObjCmdProc*)test_column_data16 },
+ { "sqlite3_column_count", (Tcl_ObjCmdProc*)test_column_count },
+ { "sqlite3_column_name", (Tcl_ObjCmdProc*)test_column_name },
+ { "sqlite3_column_name16", (Tcl_ObjCmdProc*)test_column_name16 },
+ { "sqlite3_column_type", (Tcl_ObjCmdProc*)test_column_type },
+ { "sqlite3_column_int", (Tcl_ObjCmdProc*)test_column_int },
{ "sqlite3_data_count", (Tcl_ObjCmdProc*)test_data_count },
{ "add_reverse_collating_func", (Tcl_ObjCmdProc*)reverse_collfunc },
};
diff --git a/src/update.c b/src/update.c
index 8f3c8edb3..88c683f56 100644
--- a/src/update.c
+++ b/src/update.c
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
-** $Id: update.c,v 1.79 2004/05/25 23:35:19 danielk1977 Exp $
+** $Id: update.c,v 1.80 2004/05/26 10:11:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -446,9 +446,9 @@ void sqlite3Update(
** Return the number of rows that were changed.
*/
if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
- sqlite3VdbeOp3(v, OP_ColumnName, 0, 1, "rows updated", P3_STATIC);
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "rows updated", P3_STATIC);
}
update_cleanup:
diff --git a/src/vdbe.c b/src/vdbe.c
index f971a0308..3b1d5d060 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.332 2004/05/26 06:18:38 danielk1977 Exp $
+** $Id: vdbe.c,v 1.333 2004/05/26 10:11:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -762,16 +762,36 @@ double sqlite3_column_float(sqlite3_stmt *pStmt, int i){
*/
const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
Vdbe *p = (Vdbe *)pStmt;
+ Mem *pColName;
if( N>=sqlite3_column_count(pStmt) || N<0 ){
sqlite3Error(p->db, SQLITE_RANGE, 0);
return 0;
}
- return p->azColName[N];
+ pColName = &(p->aColName[N]);
+ return sqlite3_value_data(pColName);
}
/*
+** Return the name of the 'i'th column of the result set of SQL statement
+** pStmt, encoded as UTF-16.
+*/
+const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
+ Vdbe *p = (Vdbe *)pStmt;
+ Mem *pColName;
+
+ if( N>=sqlite3_column_count(pStmt) || N<0 ){
+ sqlite3Error(p->db, SQLITE_RANGE, 0);
+ return 0;
+ }
+
+ pColName = &(p->aColName[N]);
+ return sqlite3_value_data16(pColName);
+}
+
+
+/*
** Return the type of the value stored in the sqlite_value* object.
*/
int sqlite3_value_type(sqlite3_value* pVal){
@@ -801,7 +821,6 @@ int sqlite3_value_type(sqlite3_value* pVal){
int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
int vals;
Vdbe *p = (Vdbe *)pStmt;
- int f;
vals = sqlite3_data_count(pStmt);
if( i>=vals || i<0 ){
@@ -809,24 +828,7 @@ int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
return 0;
}
- f = p->pTos[(1-vals)+i].flags;
-
- if( f&MEM_Null ){
- return SQLITE3_NULL;
- }
- if( f&MEM_Int ){
- return SQLITE3_INTEGER;
- }
- if( f&MEM_Real ){
- return SQLITE3_FLOAT;
- }
- if( f&MEM_Str ){
- return SQLITE3_TEXT;
- }
- if( f&MEM_Blob ){
- return SQLITE3_BLOB;
- }
- assert(0);
+ return sqlite3_value_type(&(p->pTos[(1-vals)+i]));
}
/*
@@ -869,14 +871,6 @@ static const void *columnName16(sqlite3_stmt *pStmt, int i, int decltype){
}
/*
-** Return the name of the 'i'th column of the result set of SQL statement
-** pStmt, encoded as UTF-16.
-*/
-const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int i){
- return columnName16(pStmt, i, 0);
-}
-
-/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt, encoded as UTF-8.
*/
@@ -2010,6 +2004,7 @@ case OP_Push: {
** value of the OP_ColumnName that has P2==1.
*/
case OP_ColumnName: {
+ assert(0);
assert( pOp->p1>=0 && pOp->p1<p->nOp );
p->azColName[pOp->p1] = pOp->p3;
p->nCallback = 0;
diff --git a/src/vdbe.h b/src/vdbe.h
index 130aaff0a..80ecb0a78 100644
--- a/src/vdbe.h
+++ b/src/vdbe.h
@@ -15,7 +15,7 @@
** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
-** $Id: vdbe.h,v 1.82 2004/05/25 23:35:20 danielk1977 Exp $
+** $Id: vdbe.h,v 1.83 2004/05/26 10:11:07 danielk1977 Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
@@ -121,6 +121,7 @@ void sqlite3VdbeCompressSpace(Vdbe*,int);
int sqlite3VdbeReset(Vdbe*,char **);
int sqliteVdbeSetVariables(Vdbe*,int,const char**);
void sqlite3VdbeSetNumCols(Vdbe*,int);
+int sqlite3VdbeSetColName(Vdbe*, int, const char *, int);
#ifndef NDEBUG
void sqlite3VdbeComment(Vdbe*, const char*, ...);
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index 77f5f7c18..e1f5b4e9b 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -327,6 +327,7 @@ struct Vdbe {
Mem *aStack; /* The operand stack, except string values */
Mem *pTos; /* Top entry in the operand stack */
Mem **apArg; /* Arguments to currently executing user function */
+ Mem *aColName; /* Column names to return */
char **azColName; /* Becomes the 4th parameter to callbacks */
void **azColName16; /* UTF-16 encoded equivalent of azColName */
int nCursor; /* Number of slots in apCsr[] */
@@ -401,3 +402,4 @@ int sqlite3VdbeList(Vdbe*);
int sqlite3VdbeSetEncoding(Mem *, u8);
int sqlite3VdbeMemCopy(Mem*, const Mem*);
int sqlite3VdbeMemNulTerminate(Mem *);
+int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, int);
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 4167eb78c..60158fd32 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -873,10 +873,50 @@ static void Cleanup(Vdbe *p){
** be called on an SQL statement before sqlite3_step().
*/
void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
+ assert( 0==p->nResColumn );
p->nResColumn = nResColumn;
}
/*
+** Set the name of the idx'th column to be returned by the SQL statement.
+** zName must be a pointer to a nul terminated string.
+**
+** This call must be made after a call to sqlite3VdbeSetNumCols().
+**
+** Parameter N may be either P3_DYNAMIC or P3_STATIC.
+*/
+int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
+ int rc;
+ Mem *pColName;
+ assert( idx<p->nResColumn );
+
+ /* If the Vdbe.aColName array has not yet been allocated, allocate
+ ** it now.
+ */
+ if( !p->aColName ){
+ int i;
+ p->aColName = (Mem *)sqliteMalloc(sizeof(Mem)*p->nResColumn);
+ if( !p->aColName ){
+ return SQLITE_NOMEM;
+ }
+ for(i=0; i<p->nResColumn; i++){
+ p->aColName[i].flags = MEM_Null;
+ }
+ }
+
+ pColName = &(p->aColName[idx]);
+ if( N==0 ){
+ rc = MemSetStr(pColName, zName, -1, TEXT_Utf8, 1);
+ }else{
+ rc = MemSetStr(pColName, zName, N, TEXT_Utf8, N>0);
+ }
+ if( rc==SQLITE_OK && N==P3_DYNAMIC ){
+ pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn;
+ }
+ return rc;
+}
+
+/*
** Clean up a VDBE after execution but do not delete the VDBE just yet.
** Write any error messages into *pzErrMsg. Return the result code.
**