diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vdbeInt.h | 14 | ||||
-rw-r--r-- | src/vdbeapi.c | 10 | ||||
-rw-r--r-- | src/vdbeaux.c | 30 |
3 files changed, 39 insertions, 15 deletions
diff --git a/src/vdbeInt.h b/src/vdbeInt.h index cc5fd604d..dc284fb0b 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -199,6 +199,10 @@ struct VdbeFrame { ** Internally, the vdbe manipulates nearly all SQL values as Mem ** structures. Each Mem struct may cache multiple representations (string, ** integer etc.) of the same value. +** +** Code uses offsetof() on this object. Order of the fields is important. +** Search for tag-20220228a to find all places that need to change when the +** field order changes. */ struct sqlite3_value { union MemValue { @@ -208,16 +212,16 @@ struct sqlite3_value { const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ } u; + char *z; /* String or BLOB value */ + int n; /* Number of characters in string value, excluding '\0' */ u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ u8 eSubtype; /* Subtype for this value */ - int n; /* Number of characters in string value, excluding '\0' */ - char *z; /* String or BLOB value */ /* ShallowCopy only needs to copy the information above */ - char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ + sqlite3 *db; /* The associated database connection */ int szMalloc; /* Size of the zMalloc allocation */ u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */ - sqlite3 *db; /* The associated database connection */ + char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ @@ -229,7 +233,7 @@ struct sqlite3_value { ** Size of struct Mem not including the Mem.zMalloc member or anything that ** follows. */ -#define MEMCELLSIZE offsetof(Mem,zMalloc) +#define MEMCELLSIZE offsetof(Mem,db) /* One or more of the following flags are set to indicate the validOK ** representations of the value stored in the Mem struct. diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 6939813a2..69f3d7b12 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1087,6 +1087,8 @@ int sqlite3_data_count(sqlite3_stmt *pStmt){ /* ** Return a pointer to static memory containing an SQL NULL value. +** +** Must be revised if column order for Mem changes. tag-20220228a. */ static const Mem *columnNullValue(void){ /* Even though the Mem structure contains an element @@ -1104,15 +1106,15 @@ static const Mem *columnNullValue(void){ #endif = { /* .u = */ {0}, + /* .z = */ (char*)0, + /* .n = */ (int)0, /* .flags = */ (u16)MEM_Null, /* .enc = */ (u8)0, /* .eSubtype = */ (u8)0, - /* .n = */ (int)0, - /* .z = */ (char*)0, - /* .zMalloc = */ (char*)0, + /* .db = */ (sqlite3*)0, /* .szMalloc = */ (int)0, /* .uTemp = */ (u32)0, - /* .db = */ (sqlite3*)0, + /* .zMalloc = */ (char*)0, /* .xDel = */ (void(*)(void*))0, #ifdef SQLITE_DEBUG /* .pScopyFrom = */ (Mem*)0, diff --git a/src/vdbeaux.c b/src/vdbeaux.c index dea71a3c9..0d91124c9 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1838,16 +1838,34 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ /* ** Initialize an array of N Mem element. +** +** This is a high-runner, so it is optimized by taking advantage of the +** order of the fields in a Mem object and using memcpy() rather than +** individually setting each field. For each Mem, we need to set: +** +** Mem.flags = flags +** Mem.db = db +** Mem.szMalloc = 0 +** +** All other fields of Mem can safely remain uninitialized for now. They +** will be initialized before use. The fields that are initialized by this +** routine are grouped together so that they can be set using memcpy(). +** +** tag-20220228a */ static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){ - while( (N--)>0 ){ - p->db = db; - p->flags = flags; - p->szMalloc = 0; + if( N>0 ){ + Mem x; + x.flags = flags; + x.db = db; + x.szMalloc = 0; + do{ + memcpy(&p->flags, &x.flags, offsetof(Mem,uTemp)-offsetof(Mem,flags)); #ifdef SQLITE_DEBUG - p->pScopyFrom = 0; + p->pScopyFrom = 0; #endif - p++; + p++; + }while( (--N)>0 ); } } |