1
0
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:
drh
2012-10-09 14:58:15 +00:00
41 changed files with 1105 additions and 565 deletions

View File

@@ -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;
}