From 9351862b6d269c96c18df8519bfd1a6ddb029e07 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 30 Sep 2010 14:48:06 +0000 Subject: [PATCH] Fix the handling of default values for ALTER TABLE ADD COLUMN columns so that is able to deal with negative numbers, including large negative numbers. Ticket [8454a207b9fd2243c4] FossilOrigin-Name: ce6cc16e3a151a0c67855abde1411422dfcc8828 --- manifest | 25 +++++++-------- manifest.uuid | 2 +- src/vdbe.c | 4 +-- src/vdbemem.c | 47 ++++++++++++++++++---------- test/tkt-8454a207b9.test | 67 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 34 deletions(-) create mode 100644 test/tkt-8454a207b9.test diff --git a/manifest b/manifest index 39e52bb943..ba581099d8 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Rework\sthe\stext\sto\snumeric\sconversion\sroutines\sso\sthat\sthey\swork\swith\seither\nUTF8\sor\sUTF16\sand\sdo\snot\srequire\sa\sNULL\sterminator.\s\sThis\sallowed\stext\sto\nnumeric\sconversion\swithout\sreallocating\sthe\sstring. -D 2010-09-30T00:50:50 +C Fix\sthe\shandling\sof\sdefault\svalues\sfor\sALTER\sTABLE\sADD\sCOLUMN\scolumns\sso\nthat\sis\sable\sto\sdeal\swith\snegative\snumbers,\sincluding\slarge\snegative\snumbers.\nTicket\s[8454a207b9fd2243c4] +D 2010-09-30T14:48:06 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -228,13 +228,13 @@ F src/update.c 227e6cd512108b84f69421fc6c7aa1b83d60d6e0 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 F src/util.c 7a5fb16c0b9a3e4c9fa6c375c8f514bc3bb155b6 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 04cf7c1b0b7a7dc825ddde202307ca15c1115fbb +F src/vdbe.c 597ef9aceeb4d695eb65a61453dc1139175cf893 F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 F src/vdbeInt.h 7f4cf1b2b69bef3a432b1f23dfebef57275436b4 F src/vdbeapi.c 03cddfa4f85cadf608c0d28ff6b622b7da432446 F src/vdbeaux.c de0b06b11a25293e820a49159eca9f1c51a64716 F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256 -F src/vdbemem.c cfb178242f38fb03a44672268afa05716d55e769 +F src/vdbemem.c 09b637201d66dae067f2beb838996a7e8adae44f F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2 F src/vtab.c 6c90e3e65b2f026fc54703a8f3c917155f419d87 F src/wal.c 7081f148cb52b0cf2280e6384196402dc58130a3 @@ -669,6 +669,7 @@ F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 F test/tkt-5ee23731f.test 3581260f2a71e51db94e1506ba6b0f7311d002a9 F test/tkt-78e04e52ea.test fb5430c675e708f5cbafdf3e7e5593da5145a527 F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7 +F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c F test/tkt-94c04eaadb.test be5ea61cb04dfdc047d19b5c5a9e75fa3da67a7f F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67 F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0 @@ -872,18 +873,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P f34dc54d46d05adf1f52db51442195b3285a26b9 -R 5e9e2523f82be46cc8ebbb892165bffa -T *bgcolor * #c0ffc0 -T *branch * experimental -T *sym-experimental * -T -sym-trunk * +P 14eed3a0e0a45c6f2904a3a134aa27c159916f7b +R 4d517dec75ee1dd489234109dd0359e9 U drh -Z 0c6ebf88312d1668689f16e4194172bb +Z 470c7c5b24a8c0836423cc96a5b1f790 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFMo97toxKgR168RlERAi5jAJsFDVqJu9wdOQNwlT2y3q2TNuHUGQCdFwrP -sR9IRwN4k3Y2ZVtzQE0tnsY= -=6xoC +iD8DBQFMpKMqoxKgR168RlERAvkLAJ0XiYNxedhD7GFhtTggvRsz2xpfLQCgjac7 +zIAfAuf6n9xnxhw6RMuzDI0= +=1JR8 -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 59c95200ea..3ddafafe18 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14eed3a0e0a45c6f2904a3a134aa27c159916f7b \ No newline at end of file +ce6cc16e3a151a0c67855abde1411422dfcc8828 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 79dfff3ea9..8c5f8c8d9a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1610,9 +1610,7 @@ case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */ case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */ pIn1 = &aMem[pOp->p1]; memAboutToChange(p, pIn1); - if( (pIn1->flags & (MEM_Null|MEM_Int|MEM_Real))==0 ){ - sqlite3VdbeMemNumerify(pIn1); - } + sqlite3VdbeMemNumerify(pIn1); break; } #endif /* SQLITE_OMIT_CAST */ diff --git a/src/vdbemem.c b/src/vdbemem.c index bab2ff3c0f..ec7086ed38 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -473,21 +473,19 @@ int sqlite3VdbeMemRealify(Mem *pMem){ ** as much of the string as we can and ignore the rest. */ int sqlite3VdbeMemNumerify(Mem *pMem){ - int rc; - assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ); - assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - rc = sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8); - if( rc ) return rc; - rc = sqlite3VdbeMemNulTerminate(pMem); - if( rc ) return rc; - if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, SQLITE_UTF8) ){ - MemSetTypeFlag(pMem, MEM_Int); - }else{ - pMem->r = sqlite3VdbeRealValue(pMem); - MemSetTypeFlag(pMem, MEM_Real); - sqlite3VdbeIntegerAffinity(pMem); + if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){ + assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){ + MemSetTypeFlag(pMem, MEM_Int); + }else{ + pMem->r = sqlite3VdbeRealValue(pMem); + MemSetTypeFlag(pMem, MEM_Real); + sqlite3VdbeIntegerAffinity(pMem); + } } + assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 ); + pMem->flags &= ~(MEM_Str|MEM_Blob); return SQLITE_OK; } @@ -1030,6 +1028,8 @@ int sqlite3ValueFromExpr( int op; char *zVal = 0; sqlite3_value *pVal = 0; + int negInt = 1; + const char *zNeg = ""; if( !pExpr ){ *ppVal = 0; @@ -1047,13 +1047,24 @@ int sqlite3ValueFromExpr( if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; #endif + /* Handle negative integers in a single step. This is needed in the + ** case when the value is -9223372036854775808. + */ + if( op==TK_UMINUS + && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){ + pExpr = pExpr->pLeft; + op = pExpr->op; + negInt = -1; + zNeg = "-"; + } + if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ pVal = sqlite3ValueNew(db); if( pVal==0 ) goto no_mem; if( ExprHasProperty(pExpr, EP_IntValue) ){ - sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue); + sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); }else{ - zVal = sqlite3DbStrDup(db, pExpr->u.zToken); + zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); if( zVal==0 ) goto no_mem; sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT; @@ -1063,14 +1074,18 @@ int sqlite3ValueFromExpr( }else{ sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); } + if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str; if( enc!=SQLITE_UTF8 ){ sqlite3VdbeChangeEncoding(pVal, enc); } }else if( op==TK_UMINUS ) { + /* This branch happens for multiple negative signs. Ex: -(-5) */ if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){ + sqlite3VdbeMemNumerify(pVal); pVal->u.i = -1 * pVal->u.i; /* (double)-1 In case of SQLITE_OMIT_FLOATING_POINT... */ pVal->r = (double)-1 * pVal->r; + sqlite3ValueApplyAffinity(pVal, affinity, enc); } } #ifndef SQLITE_OMIT_BLOB_LITERAL diff --git a/test/tkt-8454a207b9.test b/test/tkt-8454a207b9.test new file mode 100644 index 0000000000..88a8614f82 --- /dev/null +++ b/test/tkt-8454a207b9.test @@ -0,0 +1,67 @@ +# 2010 September 30 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements regression tests for SQLite library. Specifically, +# it tests that ticket [8454a207b9fd2243c4c6b7a73f67ea0315717c1a]. Verify +# that a negative default value on an added text column actually comes +# out negative. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_test tkt-8454a207b9.1 { + db eval { + CREATE TABLE t1(a); + INSERT INTO t1 VALUES(1); + ALTER TABLE t1 ADD COLUMN b TEXT DEFAULT -123.0; + SELECT b, typeof(b) FROM t1; + } +} {-123.0 text} +do_test tkt-8454a207b9.2 { + db eval { + ALTER TABLE t1 ADD COLUMN c TEXT DEFAULT -123.5; + SELECT c, typeof(c) FROM t1; + } +} {-123.5 text} +do_test tkt-8454a207b9.3 { + db eval { + ALTER TABLE t1 ADD COLUMN d TEXT DEFAULT -'hello'; + SELECT d, typeof(d) FROM t1; + } +} {0 text} +do_test tkt-8454a207b9.4 { + db eval { + ALTER TABLE t1 ADD COLUMN e DEFAULT -123.0; + SELECT e, typeof(e) FROM t1; + } +} {-123 integer} +do_test tkt-8454a207b9.5 { + db eval { + ALTER TABLE t1 ADD COLUMN f DEFAULT -123.5; + SELECT f, typeof(f) FROM t1; + } +} {-123.5 real} +do_test tkt-8454a207b9.6 { + db eval { + ALTER TABLE t1 ADD COLUMN g DEFAULT -9223372036854775808; + SELECT g, typeof(g) FROM t1; + } +} {-9223372036854775808 integer} +do_test tkt-8454a207b9.7 { + db eval { + ALTER TABLE t1 ADD COLUMN h DEFAULT 9223372036854775807; + SELECT h, typeof(h) FROM t1; + } +} {9223372036854775807 integer} + + +finish_test -- 2.47.2