Compare commits

...

1 Commits

Author SHA1 Message Date
drh 4bf96311af Take care to clear the subtype on VDBE registers when the value of the
register is overwritten with new content.
Fix for ticket [f45ac567eaa9f93].

FossilOrigin-Name: ec653cbcae74ecab4ec9df0548d5836e81dc5d14
2016-01-30 14:53:06 +00:00
7 changed files with 51 additions and 23 deletions
+10 -10
View File
@@ -1,5 +1,5 @@
C Output\ssubtype\sinformation\son\sregister\straces\sfor\sPRAGMA\svdbe_trace.
D 2016-01-30T14:17:10.486
C Take\scare\sto\sclear\sthe\ssubtype\son\sVDBE\sregisters\swhen\sthe\svalue\sof\sthe\nregister\sis\soverwritten\swith\snew\scontent.\nFix\sfor\sticket\s[f45ac567eaa9f93].
D 2016-01-30T14:53:06.723
F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845
@@ -412,13 +412,13 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3
F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3
F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c bd4d2cabbafe49bd8e04d7bf57d8e480393268d9
F src/vdbe.c dadd57758548a100024ba6f353fadc4eb3c40262
F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337
F src/vdbeInt.h 716df83ac45b70ff000b515040ea606d0cb5d0f3
F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e
F src/vdbeInt.h 6c34fac6099bea72be4d6f95e39869e53543e555
F src/vdbeapi.c 59412373ec89e075bd7b4c5e497527c8d2d9ad5b
F src/vdbeaux.c 221631e40111b5efa96ea557c6e2e7f62fd32b2a
F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75
F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0
F src/vdbemem.c e0a3c3641efb3aec29cf3aaad8bc1a2d4c207e51
F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174
F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484
F src/vtab.c 320682cca733115b4cbe71320b5c5eeb1074ebde
@@ -834,7 +834,7 @@ F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/json101.test f0178422b3a2418f423fd0d3caf3571c8d1b9863
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
F test/json103.test 923b288a0610ec86c0951778f7db19cbcca36ad1
F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
@@ -1422,7 +1422,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 85c467041c9378cae3038756da815e9117ee8c7d
R 694b551c33162b646e920ddc57abdc60
P 96b780209cc95c3f3769bb880591380d94bfe38d
R cda843daa207cb621eb4e573d679a633
U drh
Z fd54d0de297ea145965f78cad2cde9ad
Z e2b95eab505f3941b006aa1f7f82d1ae
+1 -1
View File
@@ -1 +1 @@
96b780209cc95c3f3769bb880591380d94bfe38d
ec653cbcae74ecab4ec9df0548d5836e81dc5d14
+2 -2
View File
@@ -532,7 +532,7 @@ static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
assert( pOp->p2<=(p->nMem-p->nCursor) );
pOut = &p->aMem[pOp->p2];
memAboutToChange(p, pOut);
if( VdbeMemDynamic(pOut) ){
if( VdbeMemDynamicOrSubtype(pOut) ){
return out2PrereleaseWithClear(pOut);
}else{
pOut->flags = MEM_Int;
@@ -2558,7 +2558,7 @@ case OP_Column: {
assert( p2<pC->nHdrParsed );
assert( rc==SQLITE_OK );
assert( sqlite3VdbeCheckMemInvariants(pDest) );
if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest);
if( VdbeMemDynamicOrSubtype(pDest) ) sqlite3VdbeMemSetNull(pDest);
assert( t==pC->aType[p2] );
pDest->enc = encoding;
if( pC->szRow>=aOffset[p2+1] ){
+14 -2
View File
@@ -252,11 +252,25 @@ struct Mem {
#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */
#define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */
#define MEM_Subtype 0x8000 /* Mem.eSubtype might be non-zero */
#ifdef SQLITE_OMIT_INCRBLOB
#undef MEM_Zero
#define MEM_Zero 0x0000
#endif
/* Return TRUE if Mem X contains dynamically allocated content - anything
** that needs to be deallocated to avoid a leak.
*/
#define VdbeMemDynamic(X) \
(((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
/* Return TRUE if MEM x contains dynamically allocated content, or if
** x might have a non-zero subtype
*/
#define VdbeMemDynamicOrSubtype(X) \
(((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame|MEM_Subtype))!=0)
/*
** Clear any existing type flags from a Mem and replace them with f
*/
@@ -472,8 +486,6 @@ int sqlite3VdbeMemNumerify(Mem*);
void sqlite3VdbeMemCast(Mem*,u8,u8);
int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
#define VdbeMemDynamic(X) \
(((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
const char *sqlite3OpcodeName(int);
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
+4 -2
View File
@@ -369,8 +369,10 @@ void sqlite3_result_null(sqlite3_context *pCtx){
sqlite3VdbeMemSetNull(pCtx->pOut);
}
void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->pOut->eSubtype = eSubtype & 0xff;
Mem *pOut = pCtx->pOut;
assert( sqlite3_mutex_held(pOut->db->mutex) );
pOut->eSubtype = eSubtype & 0xff;
pOut->flags |= MEM_Subtype;
}
void sqlite3_result_text(
sqlite3_context *pCtx,
+6 -5
View File
@@ -358,7 +358,7 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
*/
static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){
assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
assert( VdbeMemDynamic(p) );
assert( VdbeMemDynamicOrSubtype(p) );
if( p->flags&MEM_Agg ){
sqlite3VdbeMemFinalize(p, p->u.pDef);
assert( (p->flags & MEM_Agg)==0 );
@@ -376,6 +376,7 @@ static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){
pFrame->v->pDelFrame = pFrame;
}
p->flags = MEM_Null;
p->eSubtype = 0;
}
/*
@@ -387,7 +388,7 @@ static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){
** to be freed.
*/
static SQLITE_NOINLINE void vdbeMemClear(Mem *p){
if( VdbeMemDynamic(p) ){
if( VdbeMemDynamicOrSubtype(p) ){
vdbeMemClearExternAndSetNull(p);
}
if( p->szMalloc ){
@@ -409,7 +410,7 @@ static SQLITE_NOINLINE void vdbeMemClear(Mem *p){
*/
void sqlite3VdbeMemRelease(Mem *p){
assert( sqlite3VdbeCheckMemInvariants(p) );
if( VdbeMemDynamic(p) || p->szMalloc ){
if( VdbeMemDynamicOrSubtype(p) || p->szMalloc ){
vdbeMemClear(p);
}
}
@@ -648,7 +649,7 @@ void sqlite3VdbeMemInit(Mem *pMem, sqlite3 *db, u16 flags){
** Use sqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it.
*/
void sqlite3VdbeMemSetNull(Mem *pMem){
if( VdbeMemDynamic(pMem) ){
if( VdbeMemDynamicOrSubtype(pMem) ){
vdbeMemClearExternAndSetNull(pMem);
}else{
pMem->flags = MEM_Null;
@@ -688,7 +689,7 @@ static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){
** manifest type INTEGER.
*/
void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
if( VdbeMemDynamic(pMem) ){
if( VdbeMemDynamicOrSubtype(pMem) ){
vdbeReleaseAndSetInt64(pMem, val);
}else{
pMem->u.i = val;
+14 -1
View File
@@ -60,6 +60,19 @@ do_execsql_test json103-220 {
WHERE rowid<7 GROUP BY b ORDER BY b;
} {0 {{"n3":3,"n6":6}} 1 {{"n1":1,"n4":4}} 2 {{"n2":2,"n5":5}}}
# ticket https://www.sqlite.org/src/info/f45ac567eaa9f93c 2016-01-30
# Invalid JSON generated by json_group_array()
#
# The underlying problem is a failure to reset Mem.eSubtype
#
do_execsql_test json103-300 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(1),('abc');
SELECT
json_group_array(x),
json_group_array(json_object('x',x))
FROM t1;
} {{[1,"abc"]} {[{"x":1},{"x":"abc"}]}}
finish_test