Add an experimental API for retrieving the SQL source from a compiled statement: sqlite3_sql(). Ticket #2769. (CVS 4543)

FossilOrigin-Name: d31f1e0d74a871d66cf7d3ef35faae5171d5cbc3
diff --git a/src/prepare.c b/src/prepare.c
index ea6a4f4..28621fa 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -13,7 +13,7 @@
 ** interface, and routines that contribute to loading the database schema
 ** from disk.
 **
-** $Id: prepare.c,v 1.63 2007/11/13 10:30:26 danielk1977 Exp $
+** $Id: prepare.c,v 1.64 2007/11/14 06:48:48 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -629,7 +629,7 @@
   sqlite3 *db;
 
   assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) );
-  zSql = sqlite3VdbeGetSql(p);
+  zSql = sqlite3_sql((sqlite3_stmt *)p);
   if( zSql==0 ){
     return 0;
   }
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index cb1adf2..a169b8c 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -30,7 +30,7 @@
 ** the version number) and changes its name to "sqlite3.h" as
 ** part of the build process.
 **
-** @(#) $Id: sqlite.h.in,v 1.269 2007/11/05 17:54:17 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.270 2007/11/14 06:48:48 danielk1977 Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -1595,6 +1595,23 @@
 );
 
 /*
+** Retrieve the original SQL statement associated with a compiled statement
+** in UTF-8 encoding.
+**
+** If the compiled SQL statement passed as an argument was compiled using
+** either sqlite3_prepare_v2 or sqlite3_prepare16_v2, then this function
+** returns a pointer to a nul-terminated string containing a copy of
+** the original SQL statement. The pointer is valid until the statement
+** is deleted using sqlite3_finalize().
+**
+** If the statement was compiled using either of the legacy interfaces 
+** sqlite3_prepare() or sqlite3_prepare16(), this function returns NULL.
+** 
+****** EXPERIMENTAL - subject to change without notice **************
+*/
+const char *sqlite3_sql(sqlite3_stmt *pStmt);
+
+/*
 ** CAPI3REF:  Dynamically Typed Value Object
 **
 ** SQLite uses dynamic typing for the values it stores.  Values can 
diff --git a/src/tclsqlite.c b/src/tclsqlite.c
index 6a94341..a151bb6 100644
--- a/src/tclsqlite.c
+++ b/src/tclsqlite.c
@@ -12,7 +12,7 @@
 ** A TCL Interface to SQLite.  Append this file to sqlite3.c and
 ** compile the whole thing to build a TCL-enabled version of SQLite.
 **
-** $Id: tclsqlite.c,v 1.206 2007/11/13 10:30:26 danielk1977 Exp $
+** $Id: tclsqlite.c,v 1.207 2007/11/14 06:48:48 danielk1977 Exp $
 */
 #include "tcl.h"
 #include <errno.h>
@@ -85,7 +85,7 @@
   SqlPreparedStmt *pPrev;  /* Previous on the list */
   sqlite3_stmt *pStmt;     /* The prepared statement */
   int nSql;                /* chars in zSql[] */
-  char zSql[1];            /* Text of the SQL statement */
+  const char *zSql;        /* Text of the SQL statement */
 };
 
 typedef struct IncrblobChannel IncrblobChannel;
@@ -1813,12 +1813,13 @@
         */
         if( pPreStmt==0 ){
           len = zLeft - zSql;
-          pPreStmt = (SqlPreparedStmt*)Tcl_Alloc( sizeof(*pPreStmt) + len );
+          pPreStmt = (SqlPreparedStmt*)Tcl_Alloc( sizeof(*pPreStmt) );
           if( pPreStmt==0 ) return TCL_ERROR;
           pPreStmt->pStmt = pStmt;
           pPreStmt->nSql = len;
-          memcpy(pPreStmt->zSql, zSql, len);
-          pPreStmt->zSql[len] = 0;
+          pPreStmt->zSql = sqlite3_sql(pStmt);
+          assert( strlen(pPreStmt->zSql)==len );
+          assert( 0==memcmp(pPreStmt->zSql, zSql, len) );
         }
 
         /* Add the prepared statement to the beginning of the cache list
diff --git a/src/vdbe.h b/src/vdbe.h
index c228076..eee9db2 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.114 2007/10/23 15:39:45 drh Exp $
+** $Id: vdbe.h,v 1.115 2007/11/14 06:48:48 danielk1977 Exp $
 */
 #ifndef _SQLITE_VDBE_H_
 #define _SQLITE_VDBE_H_
@@ -140,7 +140,6 @@
 void sqlite3VdbeCountChanges(Vdbe*);
 sqlite3 *sqlite3VdbeDb(Vdbe*);
 void sqlite3VdbeSetSql(Vdbe*, const char *z, int n);
-const char *sqlite3VdbeGetSql(Vdbe*);
 void sqlite3VdbeSwap(Vdbe*,Vdbe*);
 
 #ifndef NDEBUG
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 14f6637..a0a7874 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -60,8 +60,8 @@
 /*
 ** Return the SQL associated with a prepared statement
 */
-const char *sqlite3VdbeGetSql(Vdbe *p){
-  return p->zSql;
+const char *sqlite3_sql(sqlite3_stmt *pStmt){
+  return ((Vdbe *)pStmt)->zSql;
 }
 
 /*