Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions Sources/CSQLite/decimal.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ static void decimal_free(Decimal *p){
/*
** Allocate a new Decimal object initialized to the text in zIn[].
** Return NULL if any kind of error occurs.
**
** Note that zIn[] is not necessarily zero-terminated. Always
** respect the boundary imposed by the n argument.
*/
static Decimal *decimalNewFromText(const char *zIn, int n){
Decimal *p = 0;
Expand All @@ -84,11 +87,11 @@ static Decimal *decimalNewFromText(const char *zIn, int n){
p->nFrac = 0;
p->a = sqlite3_malloc64( n+1 );
if( p->a==0 ) goto new_from_text_failed;
for(i=0; IsSpace(zIn[i]); i++){}
if( zIn[i]=='-' ){
for(i=0; i<n && IsSpace(zIn[i]); i++){}
if( i<n && zIn[i]=='-' ){
p->sign = 1;
i++;
}else if( zIn[i]=='+' ){
}else if( i<n && zIn[i]=='+' ){
i++;
}
while( i<n && zIn[i]=='0' ) i++;
Expand Down Expand Up @@ -299,28 +302,37 @@ static void decimal_result(sqlite3_context *pCtx, Decimal *p){
sqlite3_result_text(pCtx, z, i, sqlite3_free);
}

/* Forward declaration */
static void decimal_expand(Decimal *p, int nDigit, int nFrac);

/*
** Round a decimal value to N significant digits. N must be positive.
*/
static void decimal_round(Decimal *p, int N){
int i;
int nZero;
int nZero; /* Number of leading zeros */
if( N<1 ) return;
if( p==0 ) return;
if( p->nDigit<=N ) return;
for(nZero=0; nZero<p->nDigit && p->a[nZero]==0; nZero++){}
N += nZero;
if( p->nDigit<=N ) return;
if( p->a[N]>4 ){
if( p->a[N]>=5 ){
/* If all leading digits are 9, increase the number of digits
** by adding a new 0 to the front */
for(i=0; i<N && p->a[i]==9; i++){}
if( i==N ){
decimal_expand(p, p->nDigit+1, p->nFrac);
if( p->oom ) return;
}

/* Do the rounding */
p->a[N-1]++;
for(i=N-1; i>0 && p->a[i]>9; i--){
p->a[i] = 0;
p->a[i-1]++;
}
if( p->a[0]>9 ){
p->a[0] = 1;
p->nFrac--;
}
assert( p->a[0]<=9 );
}
memset(&p->a[N], 0, p->nDigit - N);
}
Expand Down Expand Up @@ -468,6 +480,7 @@ static void decimal_expand(Decimal *p, int nDigit, int nFrac){
signed char *a;
if( p==0 ) return;
nAddFrac = nFrac - p->nFrac;
assert( nAddFrac>=0 );
nAddSig = (nDigit - p->nDigit) - nAddFrac;
if( nAddFrac==0 && nAddSig==0 ) return;
if( nDigit+1>SQLITE_DECIMAL_MAX_DIGIT ){ p->oom = 1; return; }
Expand Down
16 changes: 9 additions & 7 deletions Sources/CSQLite/include/sqlite3.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,12 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.53.2"
#define SQLITE_VERSION_NUMBER 3053002
#define SQLITE_SOURCE_ID "2026-06-03 19:12:13 d6e03d8c777cfa2d35e3b60d8ec3e0187f3e9f99d8e2ee9cac695fd6fcdf1a24"
#define SQLITE_VERSION "3.53.3"
#define SQLITE_VERSION_NUMBER 3053003
#define SQLITE_SOURCE_ID "2026-06-26 20:14:12 d4c0e51e4aeb96955b99185ab9cde75c339e2c29c3f3f12428d364a10d782c62"
#define SQLITE_SCM_BRANCH "branch-3.53"
#define SQLITE_SCM_TAGS "release version-3.53.2"
#define SQLITE_SCM_DATETIME "2026-06-03T19:12:13.350Z"
#define SQLITE_SCM_TAGS "release version-3.53.3"
#define SQLITE_SCM_DATETIME "2026-06-26T20:14:12.354Z"

/*
** CAPI3REF: Run-Time Library Version Numbers
Expand Down Expand Up @@ -4366,7 +4366,8 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** or in an ORDER BY or GROUP BY clause.</dd>)^
**
** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
** <dd>The maximum depth of the parse tree on any expression.</dd>)^
** <dd>The maximum depth of the parse tree on any expression and
** the maximum nesting depth for subqueries and VIEWs</dd>)^
**
** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(<dt>SQLITE_LIMIT_PARSER_DEPTH</dt>
** <dd>The maximum depth of the LALR(1) parser stack used to analyze
Expand Down Expand Up @@ -4397,7 +4398,8 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** <dd>The maximum index number of any [parameter] in an SQL statement.)^
**
** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
** <dd>The maximum depth of recursion for triggers.</dd>)^
** <dd>The maximum depth of recursion for triggers, and the maximum
** nesting depth for separate triggers.</dd>)^
**
** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
** <dd>The maximum number of auxiliary worker threads that a single
Expand Down
40 changes: 29 additions & 11 deletions Sources/CSQLite/series.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,16 @@ static double seriesFloor(double r){
}
#endif

/* Convert a floating point value to its closest integer. Do so in
** a way that avoids 'outside the range of representable values' warnings
** from UBSAN.
*/
sqlite3_int64 seriesRealToI64(double r){
if( r<-9223372036854774784.0 ) return SMALLEST_INT64;
if( r>+9223372036854774784.0 ) return LARGEST_INT64;
return (sqlite3_int64)r;
}

/*
** This method is called to "rewind" the series_cursor object back
** to the first row of output. This method is always called at least
Expand Down Expand Up @@ -522,23 +532,27 @@ static int seriesFilter(
&& r>=(double)SMALLEST_INT64
&& r<=(double)LARGEST_INT64
){
iMin = iMax = (sqlite3_int64)r;
iMin = iMax = seriesRealToI64(r);
}else{
goto series_no_rows;
}
}else{
iMin = iMax = sqlite3_value_int64(argv[iArg++]);
}
}else{
if( idxNum & 0x0300 ){ /* value>X or value>=X */
if( idxNum & 0x0300 ){ /* value>X (0x200) or value>=X (0x100) */
if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[iArg++]);
if( r<(double)SMALLEST_INT64 ){
if( r<=(double)SMALLEST_INT64 ){
iMin = SMALLEST_INT64;
}else if( (idxNum & 0x0200)!=0 && r==seriesCeil(r) ){
iMin = (sqlite3_int64)seriesCeil(r)+1;
}else if( r>(double)LARGEST_INT64 ){
goto series_no_rows;
}else{
iMin = (sqlite3_int64)seriesCeil(r);
iMin = seriesRealToI64(seriesCeil(r));
if( (idxNum & 0x0200)!=0 && r==seriesCeil(r) ){
if( iMin==LARGEST_INT64 ) goto series_no_rows;
iMin++;
}
}
}else{
iMin = sqlite3_value_int64(argv[iArg++]);
Expand All @@ -551,15 +565,19 @@ static int seriesFilter(
}
}
}
if( idxNum & 0x3000 ){ /* value<X or value<=X */
if( idxNum & 0x3000 ){ /* value<X (0x2000) or value<=X (0x1000) */
if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[iArg++]);
if( r>(double)LARGEST_INT64 ){
if( r>=(double)LARGEST_INT64 ){
iMax = LARGEST_INT64;
}else if( (idxNum & 0x2000)!=0 && r==seriesFloor(r) ){
iMax = ((sqlite3_int64)r)-1;
}else if( r<=(double)SMALLEST_INT64 ){
goto series_no_rows;
}else{
iMax = (sqlite3_int64)seriesFloor(r);
iMax = seriesRealToI64(seriesFloor(r));
if( (idxNum & 0x2000)!=0 && r==seriesFloor(r) ){
if( iMax==SMALLEST_INT64 ) goto series_no_rows;
iMax--;
}
}
}else{
iMax = sqlite3_value_int64(argv[iArg++]);
Expand Down
Loading
Loading