mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
When doing a text-affinity comparison between two values where one or both
have both a text and a numeric type, make sure the numeric type does not confuse the answer. This is a deeper fix to the problem observed by [forum:/forumpost/3776b48e71|forum pose 3776b48e71]. The problem bisects to [25f2246be404f38b] on 2014-08-24, prior to version 3.8.7. FossilOrigin-Name: 709841f88c77276f09701bf38e25503c64b3a0afbe2fbf878136db12f31cbe21
This commit is contained in:
@ -38,6 +38,24 @@ static void noopfunc(
|
|||||||
sqlite3_result_value(context, argv[0]);
|
sqlite3_result_value(context, argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Implementation of the multitype_text() function.
|
||||||
|
**
|
||||||
|
** The function returns its argument. The result will always have a
|
||||||
|
** TEXT value. But if the original input is numeric, it will also
|
||||||
|
** have that numeric value.
|
||||||
|
*/
|
||||||
|
static void multitypeTextFunc(
|
||||||
|
sqlite3_context *context,
|
||||||
|
int argc,
|
||||||
|
sqlite3_value **argv
|
||||||
|
){
|
||||||
|
assert( argc==1 );
|
||||||
|
(void)argc;
|
||||||
|
(void)sqlite3_value_text(argv[0]);
|
||||||
|
sqlite3_result_value(context, argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
__declspec(dllexport)
|
__declspec(dllexport)
|
||||||
#endif
|
#endif
|
||||||
@ -64,5 +82,9 @@ int sqlite3_noop_init(
|
|||||||
rc = sqlite3_create_function(db, "noop_nd", 1,
|
rc = sqlite3_create_function(db, "noop_nd", 1,
|
||||||
SQLITE_UTF8,
|
SQLITE_UTF8,
|
||||||
0, noopfunc, 0, 0);
|
0, noopfunc, 0, 0);
|
||||||
|
if( rc ) return rc;
|
||||||
|
rc = sqlite3_create_function(db, "multitype_text", 1,
|
||||||
|
SQLITE_UTF8,
|
||||||
|
0, multitypeTextFunc, 0, 0);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
|||||||
C Ensure\sthat\sthe\sreplace()\sSQL\sfunction\salways\sreturns\sa\sTEXT\svalue\seven\nwhen\sits\sfirst\sargument\sis\snumeric\sand\sits\ssecond\sargument\sis\san\sempty\sstring.\nFix\sfor\sthe\sissue\sreported\sby\n[forum:/forumpost/3776b48e71|forum\spost\s3776b48e71].
|
C When\sdoing\sa\stext-affinity\scomparison\sbetween\stwo\svalues\swhere\sone\sor\sboth\nhave\sboth\sa\stext\sand\sa\snumeric\stype,\smake\ssure\sthe\snumeric\stype\sdoes\snot\nconfuse\sthe\sanswer.\s\sThis\sis\sa\sdeeper\sfix\sto\sthe\sproblem\sobserved\sby\n[forum:/forumpost/3776b48e71|forum\spose\s3776b48e71].\s\sThe\sproblem\sbisects\nto\s[25f2246be404f38b]\son\s2014-08-24,\sprior\sto\sversion\s3.8.7.
|
||||||
D 2024-01-20T13:18:22.409
|
D 2024-01-20T15:13:13.896
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@ -389,7 +389,7 @@ F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2
|
|||||||
F ext/misc/memvfs.c 7dffa8cc89c7f2d73da4bd4ccea1bcbd2bd283e3bb4cea398df7c372a197291b
|
F ext/misc/memvfs.c 7dffa8cc89c7f2d73da4bd4ccea1bcbd2bd283e3bb4cea398df7c372a197291b
|
||||||
F ext/misc/mmapwarm.c a81af4aaec00f24f308e2f4c19bf1d88f3ac3ce848c36daa7a4cd38145c4080d
|
F ext/misc/mmapwarm.c a81af4aaec00f24f308e2f4c19bf1d88f3ac3ce848c36daa7a4cd38145c4080d
|
||||||
F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58f34edd
|
F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58f34edd
|
||||||
F ext/misc/noop.c 81efe4cad9ec740e64388b14281cb983e6e2c223fed43eb77ab3e34946e0c1ab
|
F ext/misc/noop.c f1a21cc9b7a4e667e5c8458d80ba680b8bd4315a003f256006046879f679c5a0
|
||||||
F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d09ea61f
|
F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d09ea61f
|
||||||
F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405
|
F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405
|
||||||
F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691
|
F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691
|
||||||
@ -748,7 +748,7 @@ F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee
|
|||||||
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
|
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
|
||||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||||
F src/tclsqlite.c ecbc3c99c0d0c3ed122a913f143026c26d38d57f33e06bb71185dd5c1efe37cd
|
F src/tclsqlite.c ecbc3c99c0d0c3ed122a913f143026c26d38d57f33e06bb71185dd5c1efe37cd
|
||||||
F src/test1.c ac6542cddd1f405e332d869946b977b2ce8b4dc28b9f7cc61df38abe1fe49bc3
|
F src/test1.c 310f43eb17a9252a7790726ca652e4ea3197da17c19eec93b8578863a49dc7b4
|
||||||
F src/test2.c 54520d0565ef2b9bf0f8f1dcac43dc4d06baf4ffe13d10905f8d8c3ad3e4b9ab
|
F src/test2.c 54520d0565ef2b9bf0f8f1dcac43dc4d06baf4ffe13d10905f8d8c3ad3e4b9ab
|
||||||
F src/test3.c e5178558c41ff53236ae0271e9acb3d6885a94981d2eb939536ee6474598840e
|
F src/test3.c e5178558c41ff53236ae0271e9acb3d6885a94981d2eb939536ee6474598840e
|
||||||
F src/test4.c 4533b76419e7feb41b40582554663ed3cd77aaa54e135cf76b3205098cd6e664
|
F src/test4.c 4533b76419e7feb41b40582554663ed3cd77aaa54e135cf76b3205098cd6e664
|
||||||
@ -808,7 +808,7 @@ F src/upsert.c fa125a8d3410ce9a97b02cb50f7ae68a2476c405c76aa692d3acf6b8586e9242
|
|||||||
F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e
|
F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e
|
||||||
F src/util.c 078f040366d5bd5f47658d045f901c768c1c636c6eaea121f3a1cbd63c3edb5b
|
F src/util.c 078f040366d5bd5f47658d045f901c768c1c636c6eaea121f3a1cbd63c3edb5b
|
||||||
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
|
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
|
||||||
F src/vdbe.c 4a42916b14548112cb1ee9b9dea3c0ba6c21d08fa0c660cd1561c1871e25908f
|
F src/vdbe.c 92910d536e0b77505599cd6ae5d9d449e4a5d31ada61da4c0bb84f6ccb2c3189
|
||||||
F src/vdbe.h 88e19a982df9027ec1c177c793d1a5d34dc23d8f06e3b2d997f43688b05ee0eb
|
F src/vdbe.h 88e19a982df9027ec1c177c793d1a5d34dc23d8f06e3b2d997f43688b05ee0eb
|
||||||
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
|
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
|
||||||
F src/vdbeapi.c 8f57d60c89da0b60e6d4e272358c511f6bae4e24330bdb11f8b42f986d1bf21b
|
F src/vdbeapi.c 8f57d60c89da0b60e6d4e272358c511f6bae4e24330bdb11f8b42f986d1bf21b
|
||||||
@ -1866,7 +1866,7 @@ F test/tt3_stress.c f9a769ca8b026ecc76ee93ca8c9700a5619f8e51c581107c4053ba6ac97f
|
|||||||
F test/tt3_vacuum.c 71b254cde1fc49d6c8c44efd54f4668f3e57d7b3a8f4601ade069f75a999ba39
|
F test/tt3_vacuum.c 71b254cde1fc49d6c8c44efd54f4668f3e57d7b3a8f4601ade069f75a999ba39
|
||||||
F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
|
F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
|
||||||
F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac
|
F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac
|
||||||
F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a
|
F test/types3.test c9db8f9e80309edfa4252585cf16bcab7ed31f39eeb904d21e831199a3613fb0
|
||||||
F test/unhex.test b7f1b806207cb77fa31c3e434fe92fba524464e3e9356809bfcc28f15af1a8b7
|
F test/unhex.test b7f1b806207cb77fa31c3e434fe92fba524464e3e9356809bfcc28f15af1a8b7
|
||||||
F test/unionall.test 5b1c4186a661e4bf762875caf4c61d8fda3dd04a6fa9005187f6ba8900c2913f
|
F test/unionall.test 5b1c4186a661e4bf762875caf4c61d8fda3dd04a6fa9005187f6ba8900c2913f
|
||||||
F test/unionall2.test 71e8fa08d5699d50dc9f9dc0c9799c2e7a6bb7931a330d369307a4df7f157fa1
|
F test/unionall2.test 71e8fa08d5699d50dc9f9dc0c9799c2e7a6bb7931a330d369307a4df7f157fa1
|
||||||
@ -2159,8 +2159,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 666690eb433fe38fa527ccbbb8e2c00041a33939da4f6b8bfb737d664f28f0d8
|
P 01868ebcd25fadb2034da234c0636e82d07c5abc902ef66493cadfc988e74d7b
|
||||||
R 5c8274fb3e9d5dd9f1b4d6e28e9c5cce
|
R c017e3ff6a3cf5fef0c29004a344e6f7
|
||||||
U drh
|
U drh
|
||||||
Z 5fa26dddb0e1de9dbc03b74686820e2f
|
Z f4a73b0af78f34dd85f781f1eb7187c3
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
01868ebcd25fadb2034da234c0636e82d07c5abc902ef66493cadfc988e74d7b
|
709841f88c77276f09701bf38e25503c64b3a0afbe2fbf878136db12f31cbe21
|
49
src/test1.c
49
src/test1.c
@ -991,6 +991,39 @@ static void intrealFunction(
|
|||||||
sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, context);
|
sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** These SQL functions attempt to return a value (their first argument)
|
||||||
|
** that has been modified to have multiple datatypes. For example both
|
||||||
|
** TEXT and INTEGER.
|
||||||
|
*/
|
||||||
|
static void addTextTypeFunction(
|
||||||
|
sqlite3_context *context,
|
||||||
|
int argc,
|
||||||
|
sqlite3_value **argv
|
||||||
|
){
|
||||||
|
(void)sqlite3_value_text(argv[0]);
|
||||||
|
(void)argc;
|
||||||
|
sqlite3_result_value(context, argv[0]);
|
||||||
|
}
|
||||||
|
static void addIntTypeFunction(
|
||||||
|
sqlite3_context *context,
|
||||||
|
int argc,
|
||||||
|
sqlite3_value **argv
|
||||||
|
){
|
||||||
|
(void)sqlite3_value_int64(argv[0]);
|
||||||
|
(void)argc;
|
||||||
|
sqlite3_result_value(context, argv[0]);
|
||||||
|
}
|
||||||
|
static void addRealTypeFunction(
|
||||||
|
sqlite3_context *context,
|
||||||
|
int argc,
|
||||||
|
sqlite3_value **argv
|
||||||
|
){
|
||||||
|
(void)sqlite3_value_double(argv[0]);
|
||||||
|
(void)argc;
|
||||||
|
sqlite3_result_value(context, argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** SQL function: strtod(X)
|
** SQL function: strtod(X)
|
||||||
**
|
**
|
||||||
@ -1103,6 +1136,22 @@ static int SQLITE_TCLAPI test_create_function(
|
|||||||
0, intrealFunction, 0, 0);
|
0, intrealFunction, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The add_text_type(), add_int_type(), and add_real_type() functions
|
||||||
|
** attempt to return a value that has multiple datatypes.
|
||||||
|
*/
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = sqlite3_create_function(db, "add_text_type", 1, SQLITE_UTF8,
|
||||||
|
0, addTextTypeFunction, 0, 0);
|
||||||
|
}
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = sqlite3_create_function(db, "add_int_type", 1, SQLITE_UTF8,
|
||||||
|
0, addIntTypeFunction, 0, 0);
|
||||||
|
}
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = sqlite3_create_function(db, "add_real_type", 1, SQLITE_UTF8,
|
||||||
|
0, addRealTypeFunction, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Functions strtod() and dtostr() work as in the shell. These routines
|
/* Functions strtod() and dtostr() work as in the shell. These routines
|
||||||
** use the standard C library to convert between floating point and
|
** use the standard C library to convert between floating point and
|
||||||
** text. This is used to compare SQLite's internal conversion routines
|
** text. This is used to compare SQLite's internal conversion routines
|
||||||
|
@ -2301,7 +2301,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){
|
}else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){
|
||||||
if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
|
if( (flags1 & MEM_Str)!=0 ){
|
||||||
|
pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
|
||||||
|
}else if( (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
|
||||||
testcase( pIn1->flags & MEM_Int );
|
testcase( pIn1->flags & MEM_Int );
|
||||||
testcase( pIn1->flags & MEM_Real );
|
testcase( pIn1->flags & MEM_Real );
|
||||||
testcase( pIn1->flags & MEM_IntReal );
|
testcase( pIn1->flags & MEM_IntReal );
|
||||||
@ -2310,7 +2312,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
|||||||
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
|
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
|
||||||
if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str;
|
if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str;
|
||||||
}
|
}
|
||||||
if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
|
if( (flags3 & MEM_Str)!=0 ){
|
||||||
|
pIn3->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
|
||||||
|
}else if( (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
|
||||||
testcase( pIn3->flags & MEM_Int );
|
testcase( pIn3->flags & MEM_Int );
|
||||||
testcase( pIn3->flags & MEM_Real );
|
testcase( pIn3->flags & MEM_Real );
|
||||||
testcase( pIn3->flags & MEM_IntReal );
|
testcase( pIn3->flags & MEM_IntReal );
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
# of this file is testing the interaction of SQLite manifest types
|
# of this file is testing the interaction of SQLite manifest types
|
||||||
# with Tcl dual-representations.
|
# with Tcl dual-representations.
|
||||||
#
|
#
|
||||||
# $Id: types3.test,v 1.8 2008/04/28 13:02:58 drh Exp $
|
|
||||||
#
|
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -96,4 +94,32 @@ do_test types3-2.6 {
|
|||||||
tcl_variable_type V
|
tcl_variable_type V
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
|
# See https://sqlite.org/forum/forumpost/3776b48e71
|
||||||
|
#
|
||||||
|
# On a text-affinity comparison of two values where one of
|
||||||
|
# the values has both MEM_Str and a numeric type like MEM_Int,
|
||||||
|
# make sure that only the MEM_Str representation is used.
|
||||||
|
#
|
||||||
|
sqlite3_create_function db
|
||||||
|
do_execsql_test types3-3.1 {
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1(x TEXT PRIMARY KEY);
|
||||||
|
INSERT INTO t1 VALUES('1');
|
||||||
|
SELECT * FROM t1 WHERE NOT x=upper(1);
|
||||||
|
} {}
|
||||||
|
do_execsql_test types3-3.2 {
|
||||||
|
SELECT * FROM t1 WHERE NOT x=add_text_type(1);
|
||||||
|
} {}
|
||||||
|
do_execsql_test types3-3.3 {
|
||||||
|
SELECT * FROM t1 WHERE NOT x=add_int_type('1');
|
||||||
|
} {}
|
||||||
|
do_execsql_test types3-3.4 {
|
||||||
|
DELETE FROM t1;
|
||||||
|
INSERT INTO t1 VALUES(1.25);
|
||||||
|
SELECT * FROM t1 WHERE NOT x=add_real_type('1.25');
|
||||||
|
} {}
|
||||||
|
do_execsql_test types3-3.5 {
|
||||||
|
SELECT * FROM t1 WHERE NOT x=add_text_type(1.25);
|
||||||
|
} {}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
Reference in New Issue
Block a user