mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Update the SUBSTR function so that works consistently when the
2nd parameter is 0. Ticket #3628. (CVS 6230) FossilOrigin-Name: 5fc125d362df4b8525c7e1ab34a14f505756af24
This commit is contained in:
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
|||||||
C Restrict\sthe\sRANDOM()\sfunction\sto\shave\szero\sarguments.\s\sTicket\s#3627.\s(CVS\s6229)
|
C Update\sthe\sSUBSTR\sfunction\sso\sthat\sworks\sconsistently\swhen\sthe\n2nd\sparameter\sis\s0.\s\sTicket\s#3628.\s(CVS\s6230)
|
||||||
D 2009-02-02T01:50:40
|
D 2009-02-02T16:32:55
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 3871d308188cefcb7c5ab20da4c7b6aad023bc52
|
F Makefile.in 3871d308188cefcb7c5ab20da4c7b6aad023bc52
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@ -113,7 +113,7 @@ F src/date.c 870770dde3fb56772ab247dfb6a6eda44d16cfbc
|
|||||||
F src/delete.c 6249005bdd8f85db6ec5f31ddb5c07de023693cc
|
F src/delete.c 6249005bdd8f85db6ec5f31ddb5c07de023693cc
|
||||||
F src/expr.c 76dc3dc83b56ab8db50a772714fac49def8bbf12
|
F src/expr.c 76dc3dc83b56ab8db50a772714fac49def8bbf12
|
||||||
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
|
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
|
||||||
F src/func.c a3aac94811d3d02ba9f4e79b429d011c3e921910
|
F src/func.c f58648e196e86a1c7dfced3f1c82a7fbc714ebd0
|
||||||
F src/global.c ab003581ea4ff193cfe17a00e1303bc51db619a5
|
F src/global.c ab003581ea4ff193cfe17a00e1303bc51db619a5
|
||||||
F src/hash.c 5824e6ff7ba78cd34c8d6cd724367713583e5b55
|
F src/hash.c 5824e6ff7ba78cd34c8d6cd724367713583e5b55
|
||||||
F src/hash.h 28f38ebb1006a5beedcb013bcdfe31befe7437ae
|
F src/hash.h 28f38ebb1006a5beedcb013bcdfe31befe7437ae
|
||||||
@ -538,7 +538,7 @@ F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
|||||||
F test/sqllimits1.test 2f7ca3c7e7cef39a9c499e941e98b7f1708c4780
|
F test/sqllimits1.test 2f7ca3c7e7cef39a9c499e941e98b7f1708c4780
|
||||||
F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796
|
F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796
|
||||||
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
|
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
|
||||||
F test/substr.test d08879fe398c4d2d332cbf8f5a112861635e3278
|
F test/substr.test c23b84173371337f6b847ef2ede100bdded0fbec
|
||||||
F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
|
F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
|
||||||
F test/table.test 0aac9468b69d2683e68ee2682cdae28d82a453ec
|
F test/table.test 0aac9468b69d2683e68ee2682cdae28d82a453ec
|
||||||
F test/tableapi.test 505031f15b18a750184d967d2c896cf88fcc969c
|
F test/tableapi.test 505031f15b18a750184d967d2c896cf88fcc969c
|
||||||
@ -693,7 +693,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P 779fce82b7a89b972da488ce8bd35e23ca120c04
|
P b8b546b6ed799dc1621ef7b06273249af1042fb2
|
||||||
R 451a04d06310737a09d46869e6ee15cb
|
R b631440e88a8d4df13cea097fdad8929
|
||||||
U drh
|
U drh
|
||||||
Z e2350e0a9b291ec6aab2df9bc3d08f44
|
Z bb04b6d0ebe7bcb9aeeb21b9182eef4e
|
||||||
|
@ -1 +1 @@
|
|||||||
b8b546b6ed799dc1621ef7b06273249af1042fb2
|
5fc125d362df4b8525c7e1ab34a14f505756af24
|
22
src/func.c
22
src/func.c
@ -16,7 +16,7 @@
|
|||||||
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
|
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
|
||||||
** All other code has file scope.
|
** All other code has file scope.
|
||||||
**
|
**
|
||||||
** $Id: func.c,v 1.215 2009/02/02 01:50:40 drh Exp $
|
** $Id: func.c,v 1.216 2009/02/02 16:32:55 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -43,7 +43,7 @@ static void minmaxFunc(
|
|||||||
int iBest;
|
int iBest;
|
||||||
CollSeq *pColl;
|
CollSeq *pColl;
|
||||||
|
|
||||||
if( argc==0 ) return;
|
assert( argc>1 );
|
||||||
mask = sqlite3_user_data(context)==0 ? 0 : -1;
|
mask = sqlite3_user_data(context)==0 ? 0 : -1;
|
||||||
pColl = sqlite3GetFuncCollSeq(context);
|
pColl = sqlite3GetFuncCollSeq(context);
|
||||||
assert( pColl );
|
assert( pColl );
|
||||||
@ -53,6 +53,7 @@ static void minmaxFunc(
|
|||||||
for(i=1; i<argc; i++){
|
for(i=1; i<argc; i++){
|
||||||
if( sqlite3_value_type(argv[i])==SQLITE_NULL ) return;
|
if( sqlite3_value_type(argv[i])==SQLITE_NULL ) return;
|
||||||
if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){
|
if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){
|
||||||
|
testcase( mask==0 );
|
||||||
iBest = i;
|
iBest = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,11 +71,11 @@ static void typeofFunc(
|
|||||||
const char *z = 0;
|
const char *z = 0;
|
||||||
UNUSED_PARAMETER(NotUsed);
|
UNUSED_PARAMETER(NotUsed);
|
||||||
switch( sqlite3_value_type(argv[0]) ){
|
switch( sqlite3_value_type(argv[0]) ){
|
||||||
case SQLITE_NULL: z = "null"; break;
|
|
||||||
case SQLITE_INTEGER: z = "integer"; break;
|
case SQLITE_INTEGER: z = "integer"; break;
|
||||||
case SQLITE_TEXT: z = "text"; break;
|
case SQLITE_TEXT: z = "text"; break;
|
||||||
case SQLITE_FLOAT: z = "real"; break;
|
case SQLITE_FLOAT: z = "real"; break;
|
||||||
case SQLITE_BLOB: z = "blob"; break;
|
case SQLITE_BLOB: z = "blob"; break;
|
||||||
|
default: z = "null"; break;
|
||||||
}
|
}
|
||||||
sqlite3_result_text(context, z, -1, SQLITE_STATIC);
|
sqlite3_result_text(context, z, -1, SQLITE_STATIC);
|
||||||
}
|
}
|
||||||
@ -169,6 +170,7 @@ static void substrFunc(
|
|||||||
int len;
|
int len;
|
||||||
int p0type;
|
int p0type;
|
||||||
i64 p1, p2;
|
i64 p1, p2;
|
||||||
|
int negP2 = 0;
|
||||||
|
|
||||||
assert( argc==3 || argc==2 );
|
assert( argc==3 || argc==2 );
|
||||||
if( sqlite3_value_type(argv[1])==SQLITE_NULL
|
if( sqlite3_value_type(argv[1])==SQLITE_NULL
|
||||||
@ -193,6 +195,10 @@ static void substrFunc(
|
|||||||
p1 = sqlite3_value_int(argv[1]);
|
p1 = sqlite3_value_int(argv[1]);
|
||||||
if( argc==3 ){
|
if( argc==3 ){
|
||||||
p2 = sqlite3_value_int(argv[2]);
|
p2 = sqlite3_value_int(argv[2]);
|
||||||
|
if( p2<0 ){
|
||||||
|
p2 = -p2;
|
||||||
|
negP2 = 1;
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH];
|
p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH];
|
||||||
}
|
}
|
||||||
@ -200,19 +206,22 @@ static void substrFunc(
|
|||||||
p1 += len;
|
p1 += len;
|
||||||
if( p1<0 ){
|
if( p1<0 ){
|
||||||
p2 += p1;
|
p2 += p1;
|
||||||
|
if( p2<0 ) p2 = 0;
|
||||||
p1 = 0;
|
p1 = 0;
|
||||||
}
|
}
|
||||||
}else if( p1>0 ){
|
}else if( p1>0 ){
|
||||||
p1--;
|
p1--;
|
||||||
|
}else if( p2>0 ){
|
||||||
|
p2--;
|
||||||
}
|
}
|
||||||
if( p2<0 ){
|
if( negP2 ){
|
||||||
p1 += p2;
|
p1 -= p2;
|
||||||
p2 = -p2;
|
|
||||||
if( p1<0 ){
|
if( p1<0 ){
|
||||||
p2 += p1;
|
p2 += p1;
|
||||||
p1 = 0;
|
p1 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assert( p1>=0 && p2>=0 );
|
||||||
if( p1+p2>len ){
|
if( p1+p2>len ){
|
||||||
p2 = len-p1;
|
p2 = len-p1;
|
||||||
}
|
}
|
||||||
@ -226,7 +235,6 @@ static void substrFunc(
|
|||||||
}
|
}
|
||||||
sqlite3_result_text(context, (char*)z, (int)(z2-z), SQLITE_TRANSIENT);
|
sqlite3_result_text(context, (char*)z, (int)(z2-z), SQLITE_TRANSIENT);
|
||||||
}else{
|
}else{
|
||||||
if( p2<0 ) p2 = 0;
|
|
||||||
sqlite3_result_blob(context, (char*)&z[p1], (int)p2, SQLITE_TRANSIENT);
|
sqlite3_result_blob(context, (char*)&z[p1], (int)p2, SQLITE_TRANSIENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing the built-in SUBSTR() functions.
|
# focus of this file is testing the built-in SUBSTR() functions.
|
||||||
#
|
#
|
||||||
# $Id: substr.test,v 1.5 2009/02/01 19:42:38 drh Exp $
|
# $Id: substr.test,v 1.6 2009/02/02 16:32:55 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -66,7 +66,7 @@ substr-test 1.1 abcdefg 1 1 a
|
|||||||
substr-test 1.2 abcdefg 2 1 b
|
substr-test 1.2 abcdefg 2 1 b
|
||||||
substr-test 1.3 abcdefg 1 2 ab
|
substr-test 1.3 abcdefg 1 2 ab
|
||||||
substr-test 1.4 abcdefg 1 100 abcdefg
|
substr-test 1.4 abcdefg 1 100 abcdefg
|
||||||
substr-test 1.5 abcdefg 0 1 a
|
substr-test 1.5 abcdefg 0 2 a
|
||||||
substr-test 1.6 abcdefg -1 1 g
|
substr-test 1.6 abcdefg -1 1 g
|
||||||
substr-test 1.7 abcdefg -1 10 g
|
substr-test 1.7 abcdefg -1 10 g
|
||||||
substr-test 1.8 abcdefg -5 3 cde
|
substr-test 1.8 abcdefg -5 3 cde
|
||||||
@ -112,7 +112,7 @@ subblob-test 3.1 61626364656667 1 1 61
|
|||||||
subblob-test 3.2 61626364656667 2 1 62
|
subblob-test 3.2 61626364656667 2 1 62
|
||||||
subblob-test 3.3 61626364656667 1 2 6162
|
subblob-test 3.3 61626364656667 1 2 6162
|
||||||
subblob-test 3.4 61626364656667 1 100 61626364656667
|
subblob-test 3.4 61626364656667 1 100 61626364656667
|
||||||
subblob-test 3.5 61626364656667 0 1 61
|
subblob-test 3.5 61626364656667 0 2 61
|
||||||
subblob-test 3.6 61626364656667 -1 1 67
|
subblob-test 3.6 61626364656667 -1 1 67
|
||||||
subblob-test 3.7 61626364656667 -1 10 67
|
subblob-test 3.7 61626364656667 -1 10 67
|
||||||
subblob-test 3.8 61626364656667 -5 3 636465
|
subblob-test 3.8 61626364656667 -5 3 636465
|
||||||
|
Reference in New Issue
Block a user