aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <Dan Kennedy>2024-01-20 18:45:30 +0000
committerdan <Dan Kennedy>2024-01-20 18:45:30 +0000
commitb75dc61a531bd5ec7141c9adc3a7c0c5586426e7 (patch)
treea2330baf307854d69b057aac476caeee84451d26 /src
parent95295a7e9b59e90029ae7a90ebee1667c51a3139 (diff)
parentf28bff745c778598ef1740e4cbb1a44b176aac83 (diff)
downloadsqlite-b75dc61a531bd5ec7141c9adc3a7c0c5586426e7.tar.gz
sqlite-b75dc61a531bd5ec7141c9adc3a7c0c5586426e7.zip
Merge trunk changes into this branch.
FossilOrigin-Name: 03ade4a810516ff84bc5c1a716b0e454cc8a89374100415ff21a82449112811b
Diffstat (limited to 'src')
-rw-r--r--src/date.c64
-rw-r--r--src/memdb.c8
-rw-r--r--src/vdbemem.c13
3 files changed, 57 insertions, 28 deletions
diff --git a/src/date.c b/src/date.c
index 76e1894f8..e468925d5 100644
--- a/src/date.c
+++ b/src/date.c
@@ -1237,10 +1237,14 @@ static void dateFunc(
}
/*
-** Compute the one-based day of the year for the DateTime pDate.
-** Jan01 = 1, Jan02 = 2, ... Dec31 = 356 or 366.
+** Compute the number of days after the most recent January 1.
+**
+** In other words, compute the zero-based day number for the
+** current year:
+**
+** Jan01 = 0, Jan02 = 2, ... Dec31 = 364 or 365.
*/
-static int dayOfYear(DateTime *pDate){
+static int daysAfterJan01(DateTime *pDate){
DateTime jan01 = *pDate;
assert( jan01.validYMD );
assert( jan01.validHMS );
@@ -1249,18 +1253,33 @@ static int dayOfYear(DateTime *pDate){
jan01.M = 1;
jan01.D = 1;
computeJD(&jan01);
- return (int)((pDate->iJD-jan01.iJD+43200000)/86400000) + 1;
+ return (int)((pDate->iJD-jan01.iJD+43200000)/86400000);
}
/*
-** Return the day of the week. 1==Monday, 2=Tues, ..., 7=Sunday.
+** Return the number of days after the most recent Monday.
+**
+** In other words, return the day of the week according
+** to this code:
+**
+** 0=Monday, 1=Tuesday, 2=Wednesday, ..., 6=Sunday.
+*/
+static int daysAfterMonday(DateTime *pDate){
+ assert( pDate->validJD );
+ return (int)((pDate->iJD+43200000)/86400000) % 7;
+}
+
+/*
+** Return the number of days after the most recent Sunday.
+**
+** In other words, return the day of the week according
+** to this code:
+**
+** 0=Sunday, 1=Monday, 2=Tues, ..., 6=Saturday
*/
-static int dayOfWeek(DateTime *pDate){
- int w;
+static int daysAfterSunday(DateTime *pDate){
assert( pDate->validJD );
- w = ((pDate->iJD+129600000)/86400000) % 7;
- if( w==0 ) w = 7;
- return w;
+ return (int)((pDate->iJD+129600000)/86400000) % 7;
}
/*
@@ -1344,7 +1363,7 @@ static void strftimeFunc(
DateTime y = x;
assert( y.validJD );
/* Move y so that it is the Thursday in the same week as x */
- y.iJD += (4 - dayOfWeek(&x))*86400000;
+ y.iJD += (3 - daysAfterMonday(&x))*86400000;
y.validYMD = 0;
computeYMD(&y);
if( cf=='g' ){
@@ -1368,8 +1387,7 @@ static void strftimeFunc(
break;
}
case 'j': { /* Day of year. Jan01==1, Jan02==2, and so forth */
- int nDay = dayOfYear(&x);
- sqlite3_str_appendf(&sRes,"%03d",nDay);
+ sqlite3_str_appendf(&sRes,"%03d",daysAfterJan01(&x)+1);
break;
}
case 'J': { /* Julian day number. (Non-standard) */
@@ -1417,35 +1435,29 @@ static void strftimeFunc(
}
case 'u': /* Day of week. 1 to 7. Monday==1, Sunday==7 */
case 'w': { /* Day of week. 0 to 6. Sunday==0, Monday==1 */
- char c = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
+ char c = (char)daysAfterSunday(&x) + '0';
if( c=='0' && cf=='u' ) c = '7';
sqlite3_str_appendchar(&sRes, 1, c);
break;
}
case 'U': { /* Week num. 00-53. First Sun of the year is week 01 */
- int wd; /* 0=Sunday, 1=Monday, 2=Tuesday, ... 7=Saturday */
- int nDay; /* Day of the year. 0..364 or 0..365 for leapyears */
- nDay = dayOfYear(&x);
- wd = (int)(((x.iJD+43200000)/86400000 + 1)%7);
- sqlite3_str_appendf(&sRes,"%02d",(nDay+6-wd)/7);
+ sqlite3_str_appendf(&sRes,"%02d",
+ (daysAfterJan01(&x)-daysAfterSunday(&x)+7)/7);
break;
}
case 'V': { /* Week num. 01-53. First week with a Thur is week 01 */
DateTime y = x;
/* Adjust y so that is the Thursday in the same week as x */
assert( y.validJD );
- y.iJD += (4 - dayOfWeek(&x))*86400000;
+ y.iJD += (3 - daysAfterMonday(&x))*86400000;
y.validYMD = 0;
computeYMD(&y);
- sqlite3_str_appendf(&sRes,"%02d", (dayOfYear(&y)-1)/7+1);
+ sqlite3_str_appendf(&sRes,"%02d", daysAfterJan01(&y)/7+1);
break;
}
case 'W': { /* Week num. 00-53. First Mon of the year is week 01 */
- int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */
- int nDay; /* Day of the year. 0..364 or 0..365 for leapyears */
- nDay = dayOfYear(&x);
- wd = (int)(((x.iJD+43200000)/86400000)%7);
- sqlite3_str_appendf(&sRes,"%02d",(nDay+6-wd)/7);
+ sqlite3_str_appendf(&sRes,"%02d",
+ (daysAfterJan01(&x)-daysAfterMonday(&x)+7)/7);
break;
}
case 'Y': {
diff --git a/src/memdb.c b/src/memdb.c
index 657cb9ca6..d83a51d54 100644
--- a/src/memdb.c
+++ b/src/memdb.c
@@ -799,6 +799,14 @@ unsigned char *sqlite3_serialize(
pOut = 0;
}else{
sz = sqlite3_column_int64(pStmt, 0)*szPage;
+ if( sz==0 ){
+ sqlite3_reset(pStmt);
+ sqlite3_exec(db, "BEGIN IMMEDIATE; COMMIT;", 0, 0, 0);
+ rc = sqlite3_step(pStmt);
+ if( rc==SQLITE_ROW ){
+ sz = sqlite3_column_int64(pStmt, 0)*szPage;
+ }
+ }
if( piSize ) *piSize = sz;
if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
pOut = 0;
diff --git a/src/vdbemem.c b/src/vdbemem.c
index 2d10cda8d..cbc6712bf 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -1662,8 +1662,17 @@ static int valueFromExpr(
sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
}
}
- if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){
- sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
+ if( affinity==SQLITE_AFF_BLOB ){
+ if( op==TK_FLOAT ){
+ assert( pVal && pVal->z && pVal->flags==(MEM_Str|MEM_Term) );
+ sqlite3AtoF(pVal->z, &pVal->u.r, pVal->n, SQLITE_UTF8);
+ pVal->flags = MEM_Real;
+ }else if( op==TK_INTEGER ){
+ /* This case is required by -9223372036854775808 and other strings
+ ** that look like integers but cannot be handled by the
+ ** sqlite3DecOrHexToI64() call above. */
+ sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
+ }
}else{
sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
}