mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Merge the latest trunk changes, especially the ORDER BY optimizer enhancements
but also other fixes, onto the sessions branch. FossilOrigin-Name: f1fbb8c5bfa84e84e0b8e2872d83b06a0c0d5acc
This commit is contained in:
@@ -53,15 +53,8 @@
|
||||
#define NUM_PREPARED_STMTS 10
|
||||
#define MAX_PREPARED_STMTS 100
|
||||
|
||||
/*
|
||||
** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we
|
||||
** have to do a translation when going between the two. Set the
|
||||
** UTF_TRANSLATION_NEEDED macro to indicate that we need to do
|
||||
** this translation.
|
||||
*/
|
||||
#if defined(TCL_UTF_MAX) && !defined(SQLITE_UTF8)
|
||||
# define UTF_TRANSLATION_NEEDED 1
|
||||
#endif
|
||||
/* Forward declaration */
|
||||
typedef struct SqliteDb SqliteDb;
|
||||
|
||||
/*
|
||||
** New SQL functions can be created as TCL scripts. Each such function
|
||||
@@ -71,6 +64,7 @@ typedef struct SqlFunc SqlFunc;
|
||||
struct SqlFunc {
|
||||
Tcl_Interp *interp; /* The TCL interpret to execute the function */
|
||||
Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */
|
||||
SqliteDb *pDb; /* Database connection that owns this function */
|
||||
int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */
|
||||
char *zName; /* Name of this function */
|
||||
SqlFunc *pNext; /* Next function on the list of them all */
|
||||
@@ -113,7 +107,6 @@ typedef struct IncrblobChannel IncrblobChannel;
|
||||
** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
|
||||
** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
|
||||
*/
|
||||
typedef struct SqliteDb SqliteDb;
|
||||
struct SqliteDb {
|
||||
sqlite3 *db; /* The "real" database structure. MUST BE FIRST */
|
||||
Tcl_Interp *interp; /* The interpreter used for this database */
|
||||
@@ -432,6 +425,7 @@ static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
|
||||
}
|
||||
}
|
||||
pNew->interp = pDb->interp;
|
||||
pNew->pDb = pDb;
|
||||
pNew->pScript = 0;
|
||||
pNew->pNext = pDb->pFunc;
|
||||
pDb->pFunc = pNew;
|
||||
@@ -479,6 +473,7 @@ static void DbDeleteCmd(void *db){
|
||||
while( pDb->pFunc ){
|
||||
SqlFunc *pFunc = pDb->pFunc;
|
||||
pDb->pFunc = pFunc->pNext;
|
||||
assert( pFunc->pDb==pDb );
|
||||
Tcl_DecrRefCount(pFunc->pScript);
|
||||
Tcl_Free((char*)pFunc);
|
||||
}
|
||||
@@ -838,7 +833,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
|
||||
break;
|
||||
}
|
||||
case SQLITE_NULL: {
|
||||
pVal = Tcl_NewStringObj("", 0);
|
||||
pVal = Tcl_NewStringObj(p->pDb->zNull, -1);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -977,26 +972,6 @@ static int auth_callback(
|
||||
}
|
||||
#endif /* SQLITE_OMIT_AUTHORIZATION */
|
||||
|
||||
/*
|
||||
** zText is a pointer to text obtained via an sqlite3_result_text()
|
||||
** or similar interface. This routine returns a Tcl string object,
|
||||
** reference count set to 0, containing the text. If a translation
|
||||
** between iso8859 and UTF-8 is required, it is preformed.
|
||||
*/
|
||||
static Tcl_Obj *dbTextToObj(char const *zText){
|
||||
Tcl_Obj *pVal;
|
||||
#ifdef UTF_TRANSLATION_NEEDED
|
||||
Tcl_DString dCol;
|
||||
Tcl_DStringInit(&dCol);
|
||||
Tcl_ExternalToUtfDString(NULL, zText, -1, &dCol);
|
||||
pVal = Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1);
|
||||
Tcl_DStringFree(&dCol);
|
||||
#else
|
||||
pVal = Tcl_NewStringObj(zText, -1);
|
||||
#endif
|
||||
return pVal;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine reads a line of text from FILE in, stores
|
||||
** the text in memory obtained from malloc() and returns a pointer
|
||||
@@ -1184,13 +1159,13 @@ static int dbPrepareAndBind(
|
||||
int nByte;
|
||||
|
||||
if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){
|
||||
Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( pStmt==0 ){
|
||||
if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
|
||||
/* A compile-time error in the statement. */
|
||||
Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
|
||||
return TCL_ERROR;
|
||||
}else{
|
||||
/* The statement was a no-op. Continue to the next statement
|
||||
@@ -1409,7 +1384,7 @@ static void dbEvalRowInfo(
|
||||
if( nCol>0 && (papColName || p->pArray) ){
|
||||
apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
|
||||
for(i=0; i<nCol; i++){
|
||||
apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i));
|
||||
apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1);
|
||||
Tcl_IncrRefCount(apColName[i]);
|
||||
}
|
||||
p->apColName = apColName;
|
||||
@@ -1496,7 +1471,8 @@ static int dbEvalStep(DbEvalContext *p){
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
Tcl_SetObjResult(pDb->interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
|
||||
Tcl_SetObjResult(pDb->interp,
|
||||
Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
|
||||
return TCL_ERROR;
|
||||
}else{
|
||||
dbReleaseStmt(pDb, pPreStmt, 0);
|
||||
@@ -1553,11 +1529,11 @@ static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
|
||||
return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
|
||||
}
|
||||
case SQLITE_NULL: {
|
||||
return dbTextToObj(p->pDb->zNull);
|
||||
return Tcl_NewStringObj(p->pDb->zNull, -1);
|
||||
}
|
||||
}
|
||||
|
||||
return dbTextToObj((char *)sqlite3_column_text(pStmt, iCol));
|
||||
return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2452,7 +2428,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
const char *zDb = "main";
|
||||
const char *zTable;
|
||||
const char *zColumn;
|
||||
sqlite_int64 iRow;
|
||||
Tcl_WideInt iRow;
|
||||
|
||||
/* Check for the -readonly option */
|
||||
if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){
|
||||
@@ -2518,7 +2494,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
pDb->zNull = 0;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull));
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1));
|
||||
break;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user