From d705a70eb4e33f4d264720fc54ab4bc486d9a34a Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 22 Mar 2025 23:03:58 +0000 Subject: [PATCH] Fixes for two problems with the generate_series() table-valued function. FossilOrigin-Name: f5aea14e6e20ede782500615c4378725680c235eb8f6bbfbcdb1efd4adf6112e --- ext/misc/series.c | 56 ++++++++++++++++++++++++++---------- manifest | 18 ++++++------ manifest.uuid | 2 +- test/tabfunc01.test | 70 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 25 deletions(-) diff --git a/ext/misc/series.c b/ext/misc/series.c index 2d662c727e..06f1fd2811 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -115,6 +115,7 @@ SQLITE_EXTENSION_INIT1 #include #include #include +#include #ifndef SQLITE_OMIT_VIRTUALTABLE /* @@ -480,25 +481,52 @@ static int seriesFilter( ** constraints on the "value" column. */ if( idxNum & 0x0080 ){ - iMin = iMax = sqlite3_value_int64(argv[i++]); + if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){ + double r = sqlite3_value_double(argv[i++]); + if( r==ceil(r) ){ + iMin = iMax = (sqlite3_int64)r; + }else{ + returnNoRows = 1; + } + }else{ + iMin = iMax = sqlite3_value_int64(argv[i++]); + } }else{ if( idxNum & 0x0300 ){ - iMin = sqlite3_value_int64(argv[i++]); - if( idxNum & 0x0200 ){ - if( iMin==LARGEST_INT64 ){ - returnNoRows = 1; + if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){ + double r = sqlite3_value_double(argv[i++]); + if( idxNum & 0x0200 && r==ceil(r) ){ + iMin = (sqlite3_int64)ceil(r+1.0); }else{ - iMin++; + iMin = (sqlite3_int64)ceil(r); + } + }else{ + iMin = sqlite3_value_int64(argv[i++]); + if( idxNum & 0x0200 ){ + if( iMin==LARGEST_INT64 ){ + returnNoRows = 1; + }else{ + iMin++; + } } } } if( idxNum & 0x3000 ){ - iMax = sqlite3_value_int64(argv[i++]); - if( idxNum & 0x2000 ){ - if( iMax==SMALLEST_INT64 ){ - returnNoRows = 1; + if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){ + double r = sqlite3_value_double(argv[i++]); + if( (idxNum & 0x2000)!=0 && r==floor(r) ){ + iMax = (sqlite3_int64)(r-1.0); }else{ - iMax--; + iMax = (sqlite3_int64)floor(r); + } + }else{ + iMax = sqlite3_value_int64(argv[i++]); + if( idxNum & 0x2000 ){ + if( iMax==SMALLEST_INT64 ){ + returnNoRows = 1; + }else{ + iMax--; + } } } } @@ -517,8 +545,7 @@ static int seriesFilter( pCur->ss.iBase += ((d+szStep-1)/szStep)*szStep; } if( pCur->ss.iTerm>iMax ){ - sqlite3_uint64 d = pCur->ss.iTerm - iMax; - pCur->ss.iTerm -= ((d+szStep-1)/szStep)*szStep; + pCur->ss.iTerm = iMax; } }else{ sqlite3_int64 szStep = -pCur->ss.iStep; @@ -528,8 +555,7 @@ static int seriesFilter( pCur->ss.iBase -= ((d+szStep-1)/szStep)*szStep; } if( pCur->ss.iTermss.iTerm; - pCur->ss.iTerm += ((d+szStep-1)/szStep)*szStep; + pCur->ss.iTerm = iMin; } } } diff --git a/manifest b/manifest index aa58e9f941..1135cfd0c5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stwo\sobscure\slogic\sproblems\sthat\scause\sincorrect\sanswers,\sfound\sby\sa\nthird-party\sfuzzer. -D 2025-03-18T20:28:53.715 +C Fixes\sfor\stwo\sproblems\swith\sthe\sgenerate_series()\stable-valued\sfunction. +D 2025-03-22T23:03:58.992 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -436,7 +436,7 @@ F ext/misc/regexp.c 388e7f237307c7dfbfb8dde44e097946f6c437801d63f0d7ad63f3320d4e F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 -F ext/misc/series.c cb6b6ad58231ebc8003603195056a6aa3eddf7bda503fed97dbb908d2b261708 +F ext/misc/series.c 2ef2f7452d63a8c59295d8503456576882e4de444c06f17f94c1a6c1ca9be6bb F ext/misc/sha1.c cb5002148c2661b5946f34561701e9105e9d339b713ec8ac057fd888b196dcb9 F ext/misc/shathree.c f3a778f27bf3e71b666a77f28e463a3b931c4dbe4219447e61bb678b4bc121c3 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 @@ -1715,7 +1715,7 @@ F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d433309 F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039 F test/syscall.test a067468b43b8cb2305e9f9fe414e5f40c875bb5d2cba5f00b8154396e95fcf37 F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test 80496e856c22b063e3599291166445730cd6b2ff9d307567c09b60385eba7062 +F test/tabfunc01.test e85679a3800aa632dee787966b8482fce0bd47629dad82f102fd52f319d2c281 F test/table.test 7862a00b58b5541511a26757ea9c5c7c3f8298766e98aa099deec703d9c0a8e0 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -2209,10 +2209,10 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bae270b988139e070ac52fe8e12ddb946ae9c3be6d4229dfb3169ddc6ed6b121 -Q +7101ccd5331e36fd1a539f540e79ce0ce159be76ec422e1d9436eec6f3908c6e -Q +77db4d85e70fbf358ae2321c2601966666bdb4d971d7c113ce30a3e541458ee8 -R 38cdc42417211974f2d105684aa857ce +P 1a8f763c31be5603862d20f1ee2a71bde159516bb6025fc254a43e3076e882df +Q +75e72e3b0d0d689d39e00a01dc361dd6ce2649e68d200bf501ddcf04063041b2 +Q +c113e31b818d16770bec1edc980f6833dfb27c4d74178e66a778fbb5671c3a13 +R 1b6e386a4d5b596b2722675295470f92 U drh -Z 1539ad3876f6427e82fb6e412315437e +Z 60650cd8db8d35368d4944a33f657402 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6fb5811240..1cf0cd5901 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1a8f763c31be5603862d20f1ee2a71bde159516bb6025fc254a43e3076e882df +f5aea14e6e20ede782500615c4378725680c235eb8f6bbfbcdb1efd4adf6112e diff --git a/test/tabfunc01.test b/test/tabfunc01.test index f58ecacd49..5938ec6cb6 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -181,6 +181,76 @@ do_execsql_test tabfunc01-4.4 { SELECT * FROM (generate_series(1,5,2)) AS x LIMIT 10; } {1 3 5} +# 2025-03-13 forum post bf2dc8e909983511 +# +do_execsql_test tabfunc01-5.1 { + SELECT value + FROM generate_series(60,73,6) + WHERE value=66; +} 66 +do_execsql_test tabfunc01-5.2 { + SELECT value + FROM generate_series(73,60,-6) + WHERE value=67; +} 67 + +# 2025-03-22 forum post 0d5d63257e3ff4f6 +# +do_execsql_test tabfunc01-6.1 { + SELECT value FROM generate_series(1,10) WHERE value<5.5; +} {1 2 3 4 5} +do_execsql_test tabfunc01-6.2 { + SELECT value FROM generate_series(1,10) WHERE value<5.0; +} {1 2 3 4} +do_execsql_test tabfunc01-6.3 { + SELECT value FROM generate_series(1,10) WHERE value<=5.5; +} {1 2 3 4 5} +do_execsql_test tabfunc01-6.4 { + SELECT value FROM generate_series(1,10) WHERE value<=5.0; +} {1 2 3 4 5} +do_execsql_test tabfunc01-6.5 { + SELECT value FROM generate_series(1,10) WHERE value>5.5; +} {6 7 8 9 10} +do_execsql_test tabfunc01-6.6 { + SELECT value FROM generate_series(1,10) WHERE value>5.0; +} {6 7 8 9 10} +do_execsql_test tabfunc01-6.7 { + SELECT value FROM generate_series(1,10) WHERE value>=5.5; +} {6 7 8 9 10} +do_execsql_test tabfunc01-6.8 { + SELECT value FROM generate_series(1,10) WHERE value>=5.0; +} {5 6 7 8 9 10} +do_execsql_test tabfunc01-6.9 { + SELECT value FROM generate_series(10,1,-1) WHERE value<5.5; +} {5 4 3 2 1} +do_execsql_test tabfunc01-6.10 { + SELECT value FROM generate_series(10,1,-1) WHERE value<5.0; +} {4 3 2 1} +do_execsql_test tabfunc01-6.11 { + SELECT value FROM generate_series(10,1,-1) WHERE value<=5.5; +} {5 4 3 2 1} +do_execsql_test tabfunc01-6.12 { + SELECT value FROM generate_series(10,1,-1) WHERE value<=5.0; +} {5 4 3 2 1} +do_execsql_test tabfunc01-6.13 { + SELECT value FROM generate_series(10,1,-1) WHERE value>5.5; +} {10 9 8 7 6} +do_execsql_test tabfunc01-6.14 { + SELECT value FROM generate_series(10,1,-1) WHERE value>5.0; +} {10 9 8 7 6} +do_execsql_test tabfunc01-6.15 { + SELECT value FROM generate_series(10,1,-1) WHERE value>=5.5; +} {10 9 8 7 6} +do_execsql_test tabfunc01-6.16 { + SELECT value FROM generate_series(10,1,-1) WHERE value>=5.0; +} {10 9 8 7 6 5} +do_execsql_test tabfunc01-6.17 { + SELECT value FROM generate_series(1,10) WHERE value==5.5; +} {} +do_execsql_test tabfunc01-6.18 { + SELECT value FROM generate_series(1,10) WHERE value==5.0; +} {5} + # The next series of tests is verifying that virtual table are able # to optimize the IN operator, even on terms that are not marked "omit". # When the generate_series virtual table is compiled for the testfixture, -- 2.47.2