mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-11 21:49:13 +00:00
SQLite 3.46.0.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# Embeddable Wasm build of SQLite
|
# Embeddable Wasm build of SQLite
|
||||||
|
|
||||||
This folder includes an embeddable Wasm build of SQLite 3.45.3 for use with
|
This folder includes an embeddable Wasm build of SQLite 3.46.0 for use with
|
||||||
[`github.com/ncruces/go-sqlite3`](https://pkg.go.dev/github.com/ncruces/go-sqlite3).
|
[`github.com/ncruces/go-sqlite3`](https://pkg.go.dev/github.com/ncruces/go-sqlite3).
|
||||||
|
|
||||||
The following optional features are compiled in:
|
The following optional features are compiled in:
|
||||||
@@ -10,6 +10,7 @@ The following optional features are compiled in:
|
|||||||
- [R*Tree](https://sqlite.org/rtree.html)
|
- [R*Tree](https://sqlite.org/rtree.html)
|
||||||
- [GeoPoly](https://sqlite.org/geopoly.html)
|
- [GeoPoly](https://sqlite.org/geopoly.html)
|
||||||
- [soundex](https://sqlite.org/lang_corefunc.html#soundex)
|
- [soundex](https://sqlite.org/lang_corefunc.html#soundex)
|
||||||
|
- [stat4](https://sqlite.org/compile.html#enable_stat4)
|
||||||
- [base64](https://github.com/sqlite/sqlite/blob/master/ext/misc/base64.c)
|
- [base64](https://github.com/sqlite/sqlite/blob/master/ext/misc/base64.c)
|
||||||
- [decimal](https://github.com/sqlite/sqlite/blob/master/ext/misc/decimal.c)
|
- [decimal](https://github.com/sqlite/sqlite/blob/master/ext/misc/decimal.c)
|
||||||
- [ieee754](https://github.com/sqlite/sqlite/blob/master/ext/misc/ieee754.c)
|
- [ieee754](https://github.com/sqlite/sqlite/blob/master/ext/misc/ieee754.c)
|
||||||
|
|||||||
@@ -36,10 +36,13 @@ sqlite3_collation_needed_go
|
|||||||
sqlite3_column_blob
|
sqlite3_column_blob
|
||||||
sqlite3_column_bytes
|
sqlite3_column_bytes
|
||||||
sqlite3_column_count
|
sqlite3_column_count
|
||||||
|
sqlite3_column_database_name
|
||||||
sqlite3_column_decltype
|
sqlite3_column_decltype
|
||||||
sqlite3_column_double
|
sqlite3_column_double
|
||||||
sqlite3_column_int64
|
sqlite3_column_int64
|
||||||
sqlite3_column_name
|
sqlite3_column_name
|
||||||
|
sqlite3_column_origin_name
|
||||||
|
sqlite3_column_table_name
|
||||||
sqlite3_column_text
|
sqlite3_column_text
|
||||||
sqlite3_column_type
|
sqlite3_column_type
|
||||||
sqlite3_column_value
|
sqlite3_column_value
|
||||||
|
|||||||
Binary file not shown.
@@ -2,7 +2,7 @@
|
|||||||
# This patch allows Go to handle (and interrupt) sqlite3_busy_timeout.
|
# This patch allows Go to handle (and interrupt) sqlite3_busy_timeout.
|
||||||
--- sqlite3.c.orig
|
--- sqlite3.c.orig
|
||||||
+++ sqlite3.c
|
+++ sqlite3.c
|
||||||
@@ -181581,7 +181581,7 @@
|
@@ -181614,7 +181614,7 @@
|
||||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||||
#endif
|
#endif
|
||||||
if( ms>0 ){
|
if( ms>0 ){
|
||||||
|
|||||||
@@ -1,556 +0,0 @@
|
|||||||
# Backport from 3.46.
|
|
||||||
# https://sqlite.org/draft/releaselog/current.html
|
|
||||||
--- sqlite3.c.orig
|
|
||||||
+++ sqlite3.c
|
|
||||||
@@ -71,13 +71,14 @@ struct DateTime {
|
|
||||||
int tz; /* Timezone offset in minutes */
|
|
||||||
double s; /* Seconds */
|
|
||||||
char validJD; /* True (1) if iJD is valid */
|
|
||||||
- char rawS; /* Raw numeric value stored in s */
|
|
||||||
char validYMD; /* True (1) if Y,M,D are valid */
|
|
||||||
char validHMS; /* True (1) if h,m,s are valid */
|
|
||||||
- char validTZ; /* True (1) if tz is valid */
|
|
||||||
- char tzSet; /* Timezone was set explicitly */
|
|
||||||
- char isError; /* An overflow has occurred */
|
|
||||||
- char useSubsec; /* Display subsecond precision */
|
|
||||||
+ char nFloor; /* Days to implement "floor" */
|
|
||||||
+ unsigned rawS : 1; /* Raw numeric value stored in s */
|
|
||||||
+ unsigned isError : 1; /* An overflow has occurred */
|
|
||||||
+ unsigned useSubsec : 1; /* Display subsecond precision */
|
|
||||||
+ unsigned isUtc : 1; /* Time is known to be UTC */
|
|
||||||
+ unsigned isLocal : 1; /* Time is known to be localtime */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
@@ -175,6 +176,8 @@ static int parseTimezone(const char *zDate, DateTime *p){
|
|
||||||
sgn = +1;
|
|
||||||
}else if( c=='Z' || c=='z' ){
|
|
||||||
zDate++;
|
|
||||||
+ p->isLocal = 0;
|
|
||||||
+ p->isUtc = 1;
|
|
||||||
goto zulu_time;
|
|
||||||
}else{
|
|
||||||
return c!=0;
|
|
||||||
@@ -187,7 +190,6 @@ static int parseTimezone(const char *zDate, DateTime *p){
|
|
||||||
p->tz = sgn*(nMn + nHr*60);
|
|
||||||
zulu_time:
|
|
||||||
while( sqlite3Isspace(*zDate) ){ zDate++; }
|
|
||||||
- p->tzSet = 1;
|
|
||||||
return *zDate!=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -231,7 +233,6 @@ static int parseHhMmSs(const char *zDate, DateTime *p){
|
|
||||||
p->m = m;
|
|
||||||
p->s = s + ms;
|
|
||||||
if( parseTimezone(zDate, p) ) return 1;
|
|
||||||
- p->validTZ = (p->tz!=0)?1:0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -278,15 +279,40 @@ static void computeJD(DateTime *p){
|
|
||||||
p->validJD = 1;
|
|
||||||
if( p->validHMS ){
|
|
||||||
p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5);
|
|
||||||
- if( p->validTZ ){
|
|
||||||
+ if( p->tz ){
|
|
||||||
p->iJD -= p->tz*60000;
|
|
||||||
p->validYMD = 0;
|
|
||||||
p->validHMS = 0;
|
|
||||||
- p->validTZ = 0;
|
|
||||||
+ p->tz = 0;
|
|
||||||
+ p->isUtc = 1;
|
|
||||||
+ p->isLocal = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+** Given the YYYY-MM-DD information current in p, determine if there
|
|
||||||
+** is day-of-month overflow and set nFloor to the number of days that
|
|
||||||
+** would need to be subtracted from the date in order to bring the
|
|
||||||
+** date back to the end of the month.
|
|
||||||
+*/
|
|
||||||
+static void computeFloor(DateTime *p){
|
|
||||||
+ assert( p->validYMD || p->isError );
|
|
||||||
+ assert( p->D>=0 && p->D<=31 );
|
|
||||||
+ assert( p->M>=0 && p->M<=12 );
|
|
||||||
+ if( p->D<=28 ){
|
|
||||||
+ p->nFloor = 0;
|
|
||||||
+ }else if( (1<<p->M) & 0x15aa ){
|
|
||||||
+ p->nFloor = 0;
|
|
||||||
+ }else if( p->M!=2 ){
|
|
||||||
+ p->nFloor = (p->D==31);
|
|
||||||
+ }else if( p->Y%4!=0 || (p->Y%100==0 && p->Y%400!=0) ){
|
|
||||||
+ p->nFloor = p->D - 28;
|
|
||||||
+ }else{
|
|
||||||
+ p->nFloor = p->D - 29;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
** Parse dates of the form
|
|
||||||
**
|
|
||||||
@@ -325,12 +351,16 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){
|
|
||||||
p->Y = neg ? -Y : Y;
|
|
||||||
p->M = M;
|
|
||||||
p->D = D;
|
|
||||||
- if( p->validTZ ){
|
|
||||||
+ computeFloor(p);
|
|
||||||
+ if( p->tz ){
|
|
||||||
computeJD(p);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+
|
|
||||||
+static void clearYMD_HMS_TZ(DateTime *p); /* Forward declaration */
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
** Set the time to the current time reported by the VFS.
|
|
||||||
**
|
|
||||||
@@ -340,6 +370,9 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
|
|
||||||
p->iJD = sqlite3StmtCurrentTime(context);
|
|
||||||
if( p->iJD>0 ){
|
|
||||||
p->validJD = 1;
|
|
||||||
+ p->isUtc = 1;
|
|
||||||
+ p->isLocal = 0;
|
|
||||||
+ clearYMD_HMS_TZ(p);
|
|
||||||
return 0;
|
|
||||||
}else{
|
|
||||||
return 1;
|
|
||||||
@@ -478,7 +511,7 @@ static void computeYMD_HMS(DateTime *p){
|
|
||||||
static void clearYMD_HMS_TZ(DateTime *p){
|
|
||||||
p->validYMD = 0;
|
|
||||||
p->validHMS = 0;
|
|
||||||
- p->validTZ = 0;
|
|
||||||
+ p->tz = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_LOCALTIME
|
|
||||||
@@ -610,7 +643,7 @@ static int toLocaltime(
|
|
||||||
p->validHMS = 1;
|
|
||||||
p->validJD = 0;
|
|
||||||
p->rawS = 0;
|
|
||||||
- p->validTZ = 0;
|
|
||||||
+ p->tz = 0;
|
|
||||||
p->isError = 0;
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
@@ -630,12 +663,12 @@ static const struct {
|
|
||||||
float rLimit; /* Maximum NNN value for this transform */
|
|
||||||
float rXform; /* Constant used for this transform */
|
|
||||||
} aXformType[] = {
|
|
||||||
- { 6, "second", 4.6427e+14, 1.0 },
|
|
||||||
- { 6, "minute", 7.7379e+12, 60.0 },
|
|
||||||
- { 4, "hour", 1.2897e+11, 3600.0 },
|
|
||||||
- { 3, "day", 5373485.0, 86400.0 },
|
|
||||||
- { 5, "month", 176546.0, 2592000.0 },
|
|
||||||
- { 4, "year", 14713.0, 31536000.0 },
|
|
||||||
+ /* 0 */ { 6, "second", 4.6427e+14, 1.0 },
|
|
||||||
+ /* 1 */ { 6, "minute", 7.7379e+12, 60.0 },
|
|
||||||
+ /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 },
|
|
||||||
+ /* 3 */ { 3, "day", 5373485.0, 86400.0 },
|
|
||||||
+ /* 4 */ { 5, "month", 176546.0, 30.0*86400.0 },
|
|
||||||
+ /* 5 */ { 4, "year", 14713.0, 365.0*86400.0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -667,14 +700,20 @@ static void autoAdjustDate(DateTime *p){
|
|
||||||
** NNN.NNNN seconds
|
|
||||||
** NNN months
|
|
||||||
** NNN years
|
|
||||||
+** +/-YYYY-MM-DD HH:MM:SS.SSS
|
|
||||||
+** ceiling
|
|
||||||
+** floor
|
|
||||||
** start of month
|
|
||||||
** start of year
|
|
||||||
** start of week
|
|
||||||
** start of day
|
|
||||||
** weekday N
|
|
||||||
** unixepoch
|
|
||||||
+** auto
|
|
||||||
** localtime
|
|
||||||
** utc
|
|
||||||
+** subsec
|
|
||||||
+** subsecond
|
|
||||||
**
|
|
||||||
** Return 0 on success and 1 if there is any kind of error. If the error
|
|
||||||
** is in a system call (i.e. localtime()), then an error message is written
|
|
||||||
@@ -705,6 +744,37 @@ static int parseModifier(
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
+ case 'c': {
|
|
||||||
+ /*
|
|
||||||
+ ** ceiling
|
|
||||||
+ **
|
|
||||||
+ ** Resolve day-of-month overflow by rolling forward into the next
|
|
||||||
+ ** month. As this is the default action, this modifier is really
|
|
||||||
+ ** a no-op that is only included for symmetry. See "floor".
|
|
||||||
+ */
|
|
||||||
+ if( sqlite3_stricmp(z, "ceiling")==0 ){
|
|
||||||
+ computeJD(p);
|
|
||||||
+ clearYMD_HMS_TZ(p);
|
|
||||||
+ rc = 0;
|
|
||||||
+ p->nFloor = 0;
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ case 'f': {
|
|
||||||
+ /*
|
|
||||||
+ ** floor
|
|
||||||
+ **
|
|
||||||
+ ** Resolve day-of-month overflow by rolling back to the end of the
|
|
||||||
+ ** previous month.
|
|
||||||
+ */
|
|
||||||
+ if( sqlite3_stricmp(z, "floor")==0 ){
|
|
||||||
+ computeJD(p);
|
|
||||||
+ p->iJD -= p->nFloor*86400000;
|
|
||||||
+ clearYMD_HMS_TZ(p);
|
|
||||||
+ rc = 0;
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
case 'j': {
|
|
||||||
/*
|
|
||||||
** julianday
|
|
||||||
@@ -731,7 +801,9 @@ static int parseModifier(
|
|
||||||
** show local time.
|
|
||||||
*/
|
|
||||||
if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
|
|
||||||
- rc = toLocaltime(p, pCtx);
|
|
||||||
+ rc = p->isLocal ? SQLITE_OK : toLocaltime(p, pCtx);
|
|
||||||
+ p->isUtc = 0;
|
|
||||||
+ p->isLocal = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
@@ -756,7 +828,7 @@ static int parseModifier(
|
|
||||||
}
|
|
||||||
#ifndef SQLITE_OMIT_LOCALTIME
|
|
||||||
else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
|
|
||||||
- if( p->tzSet==0 ){
|
|
||||||
+ if( p->isUtc==0 ){
|
|
||||||
i64 iOrigJD; /* Original localtime */
|
|
||||||
i64 iGuess; /* Guess at the corresponding utc time */
|
|
||||||
int cnt = 0; /* Safety to prevent infinite loop */
|
|
||||||
@@ -779,7 +851,8 @@ static int parseModifier(
|
|
||||||
memset(p, 0, sizeof(*p));
|
|
||||||
p->iJD = iGuess;
|
|
||||||
p->validJD = 1;
|
|
||||||
- p->tzSet = 1;
|
|
||||||
+ p->isUtc = 1;
|
|
||||||
+ p->isLocal = 0;
|
|
||||||
}
|
|
||||||
rc = SQLITE_OK;
|
|
||||||
}
|
|
||||||
@@ -799,7 +872,7 @@ static int parseModifier(
|
|
||||||
&& r>=0.0 && r<7.0 && (n=(int)r)==r ){
|
|
||||||
sqlite3_int64 Z;
|
|
||||||
computeYMD_HMS(p);
|
|
||||||
- p->validTZ = 0;
|
|
||||||
+ p->tz = 0;
|
|
||||||
p->validJD = 0;
|
|
||||||
computeJD(p);
|
|
||||||
Z = ((p->iJD + 129600000)/86400000) % 7;
|
|
||||||
@@ -839,7 +912,7 @@ static int parseModifier(
|
|
||||||
p->h = p->m = 0;
|
|
||||||
p->s = 0.0;
|
|
||||||
p->rawS = 0;
|
|
||||||
- p->validTZ = 0;
|
|
||||||
+ p->tz = 0;
|
|
||||||
p->validJD = 0;
|
|
||||||
if( sqlite3_stricmp(z,"month")==0 ){
|
|
||||||
p->D = 1;
|
|
||||||
@@ -910,6 +983,7 @@ static int parseModifier(
|
|
||||||
x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
|
|
||||||
p->Y += x;
|
|
||||||
p->M -= x*12;
|
|
||||||
+ computeFloor(p);
|
|
||||||
computeJD(p);
|
|
||||||
p->validHMS = 0;
|
|
||||||
p->validYMD = 0;
|
|
||||||
@@ -956,11 +1030,12 @@ static int parseModifier(
|
|
||||||
z += n;
|
|
||||||
while( sqlite3Isspace(*z) ) z++;
|
|
||||||
n = sqlite3Strlen30(z);
|
|
||||||
- if( n>10 || n<3 ) break;
|
|
||||||
+ if( n<3 || n>10 ) break;
|
|
||||||
if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--;
|
|
||||||
computeJD(p);
|
|
||||||
assert( rc==1 );
|
|
||||||
rRounder = r<0 ? -0.5 : +0.5;
|
|
||||||
+ p->nFloor = 0;
|
|
||||||
for(i=0; i<ArraySize(aXformType); i++){
|
|
||||||
if( aXformType[i].nName==n
|
|
||||||
&& sqlite3_strnicmp(aXformType[i].zName, z, n)==0
|
|
||||||
@@ -968,21 +1043,24 @@ static int parseModifier(
|
|
||||||
){
|
|
||||||
switch( i ){
|
|
||||||
case 4: { /* Special processing to add months */
|
|
||||||
- assert( strcmp(aXformType[i].zName,"month")==0 );
|
|
||||||
+ assert( strcmp(aXformType[4].zName,"month")==0 );
|
|
||||||
computeYMD_HMS(p);
|
|
||||||
p->M += (int)r;
|
|
||||||
x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
|
|
||||||
p->Y += x;
|
|
||||||
p->M -= x*12;
|
|
||||||
+ computeFloor(p);
|
|
||||||
p->validJD = 0;
|
|
||||||
r -= (int)r;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 5: { /* Special processing to add years */
|
|
||||||
int y = (int)r;
|
|
||||||
- assert( strcmp(aXformType[i].zName,"year")==0 );
|
|
||||||
+ assert( strcmp(aXformType[5].zName,"year")==0 );
|
|
||||||
computeYMD_HMS(p);
|
|
||||||
+ assert( p->M>=0 && p->M<=12 );
|
|
||||||
p->Y += y;
|
|
||||||
+ computeFloor(p);
|
|
||||||
p->validJD = 0;
|
|
||||||
r -= (int)r;
|
|
||||||
break;
|
|
||||||
@@ -1236,22 +1314,83 @@ static void dateFunc(
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+** 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 = 1, ..., Jan31 = 30, Feb01 = 31, ...
|
|
||||||
+** Dec31 = 364 or 365.
|
|
||||||
+*/
|
|
||||||
+static int daysAfterJan01(DateTime *pDate){
|
|
||||||
+ DateTime jan01 = *pDate;
|
|
||||||
+ assert( jan01.validYMD );
|
|
||||||
+ assert( jan01.validHMS );
|
|
||||||
+ assert( pDate->validJD );
|
|
||||||
+ jan01.validJD = 0;
|
|
||||||
+ jan01.M = 1;
|
|
||||||
+ jan01.D = 1;
|
|
||||||
+ computeJD(&jan01);
|
|
||||||
+ return (int)((pDate->iJD-jan01.iJD+43200000)/86400000);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+** 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 daysAfterSunday(DateTime *pDate){
|
|
||||||
+ assert( pDate->validJD );
|
|
||||||
+ return (int)((pDate->iJD+129600000)/86400000) % 7;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
|
|
||||||
**
|
|
||||||
** Return a string described by FORMAT. Conversions as follows:
|
|
||||||
**
|
|
||||||
-** %d day of month
|
|
||||||
+** %d day of month 01-31
|
|
||||||
+** %e day of month 1-31
|
|
||||||
** %f ** fractional seconds SS.SSS
|
|
||||||
+** %F ISO date. YYYY-MM-DD
|
|
||||||
+** %G ISO year corresponding to %V 0000-9999.
|
|
||||||
+** %g 2-digit ISO year corresponding to %V 00-99
|
|
||||||
** %H hour 00-24
|
|
||||||
-** %j day of year 000-366
|
|
||||||
+** %k hour 0-24 (leading zero converted to space)
|
|
||||||
+** %I hour 01-12
|
|
||||||
+** %j day of year 001-366
|
|
||||||
** %J ** julian day number
|
|
||||||
+** %l hour 1-12 (leading zero converted to space)
|
|
||||||
** %m month 01-12
|
|
||||||
** %M minute 00-59
|
|
||||||
+** %p "am" or "pm"
|
|
||||||
+** %P "AM" or "PM"
|
|
||||||
+** %R time as HH:MM
|
|
||||||
** %s seconds since 1970-01-01
|
|
||||||
** %S seconds 00-59
|
|
||||||
-** %w day of week 0-6 Sunday==0
|
|
||||||
-** %W week of year 00-53
|
|
||||||
+** %T time as HH:MM:SS
|
|
||||||
+** %u day of week 1-7 Monday==1, Sunday==7
|
|
||||||
+** %w day of week 0-6 Sunday==0, Monday==1
|
|
||||||
+** %U week of year 00-53 (First Sunday is start of week 01)
|
|
||||||
+** %V week of year 01-53 (First week containing Thursday is week 01)
|
|
||||||
+** %W week of year 00-53 (First Monday is start of week 01)
|
|
||||||
** %Y year 0000-9999
|
|
||||||
** %% %
|
|
||||||
*/
|
|
||||||
@@ -1288,7 +1427,7 @@ static void strftimeFunc(
|
|
||||||
sqlite3_str_appendf(&sRes, cf=='d' ? "%02d" : "%2d", x.D);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
- case 'f': {
|
|
||||||
+ case 'f': { /* Fractional seconds. (Non-standard) */
|
|
||||||
double s = x.s;
|
|
||||||
if( s>59.999 ) s = 59.999;
|
|
||||||
sqlite3_str_appendf(&sRes, "%06.3f", s);
|
|
||||||
@@ -1298,6 +1437,21 @@ static void strftimeFunc(
|
|
||||||
sqlite3_str_appendf(&sRes, "%04d-%02d-%02d", x.Y, x.M, x.D);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
+ case 'G': /* Fall thru */
|
|
||||||
+ case 'g': {
|
|
||||||
+ DateTime y = x;
|
|
||||||
+ assert( y.validJD );
|
|
||||||
+ /* Move y so that it is the Thursday in the same week as x */
|
|
||||||
+ y.iJD += (3 - daysAfterMonday(&x))*86400000;
|
|
||||||
+ y.validYMD = 0;
|
|
||||||
+ computeYMD(&y);
|
|
||||||
+ if( cf=='g' ){
|
|
||||||
+ sqlite3_str_appendf(&sRes, "%02d", y.Y%100);
|
|
||||||
+ }else{
|
|
||||||
+ sqlite3_str_appendf(&sRes, "%04d", y.Y);
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
case 'H':
|
|
||||||
case 'k': {
|
|
||||||
sqlite3_str_appendf(&sRes, cf=='H' ? "%02d" : "%2d", x.h);
|
|
||||||
@@ -1311,25 +1465,11 @@ static void strftimeFunc(
|
|
||||||
sqlite3_str_appendf(&sRes, cf=='I' ? "%02d" : "%2d", h);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
- case 'W': /* Fall thru */
|
|
||||||
- case 'j': {
|
|
||||||
- int nDay; /* Number of days since 1st day of year */
|
|
||||||
- DateTime y = x;
|
|
||||||
- y.validJD = 0;
|
|
||||||
- y.M = 1;
|
|
||||||
- y.D = 1;
|
|
||||||
- computeJD(&y);
|
|
||||||
- nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
|
|
||||||
- if( cf=='W' ){
|
|
||||||
- int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */
|
|
||||||
- wd = (int)(((x.iJD+43200000)/86400000)%7);
|
|
||||||
- sqlite3_str_appendf(&sRes,"%02d",(nDay+7-wd)/7);
|
|
||||||
- }else{
|
|
||||||
- sqlite3_str_appendf(&sRes,"%03d",nDay+1);
|
|
||||||
- }
|
|
||||||
+ case 'j': { /* Day of year. Jan01==1, Jan02==2, and so forth */
|
|
||||||
+ sqlite3_str_appendf(&sRes,"%03d",daysAfterJan01(&x)+1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
- case 'J': {
|
|
||||||
+ case 'J': { /* Julian day number. (Non-standard) */
|
|
||||||
sqlite3_str_appendf(&sRes,"%.16g",x.iJD/86400000.0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
@@ -1372,13 +1512,33 @@ static void strftimeFunc(
|
|
||||||
sqlite3_str_appendf(&sRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
- case 'u': /* Fall thru */
|
|
||||||
- case 'w': {
|
|
||||||
- char c = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
|
|
||||||
+ 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)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 */
|
|
||||||
+ 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 += (3 - daysAfterMonday(&x))*86400000;
|
|
||||||
+ y.validYMD = 0;
|
|
||||||
+ computeYMD(&y);
|
|
||||||
+ sqlite3_str_appendf(&sRes,"%02d", daysAfterJan01(&y)/7+1);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ case 'W': { /* Week num. 00-53. First Mon of the year is week 01 */
|
|
||||||
+ sqlite3_str_appendf(&sRes,"%02d",
|
|
||||||
+ (daysAfterJan01(&x)-daysAfterMonday(&x)+7)/7);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
case 'Y': {
|
|
||||||
sqlite3_str_appendf(&sRes,"%04d",x.Y);
|
|
||||||
break;
|
|
||||||
@@ -1525,9 +1685,7 @@ static void timediffFunc(
|
|
||||||
d1.iJD = d2.iJD - d1.iJD;
|
|
||||||
d1.iJD += (u64)1486995408 * (u64)100000;
|
|
||||||
}
|
|
||||||
- d1.validYMD = 0;
|
|
||||||
- d1.validHMS = 0;
|
|
||||||
- d1.validTZ = 0;
|
|
||||||
+ clearYMD_HMS_TZ(&d1);
|
|
||||||
computeYMD_HMS(&d1);
|
|
||||||
sqlite3StrAccumInit(&sRes, 0, 0, 0, 100);
|
|
||||||
sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f",
|
|
||||||
@@ -1596,6 +1754,36 @@ static void currentTimeFunc(
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+#if !defined(SQLITE_OMIT_DATETIME_FUNCS) && defined(SQLITE_DEBUG)
|
|
||||||
+/*
|
|
||||||
+** datedebug(...)
|
|
||||||
+**
|
|
||||||
+** This routine returns JSON that describes the internal DateTime object.
|
|
||||||
+** Used for debugging and testing only. Subject to change.
|
|
||||||
+*/
|
|
||||||
+static void datedebugFunc(
|
|
||||||
+ sqlite3_context *context,
|
|
||||||
+ int argc,
|
|
||||||
+ sqlite3_value **argv
|
|
||||||
+){
|
|
||||||
+ DateTime x;
|
|
||||||
+ if( isDate(context, argc, argv, &x)==0 ){
|
|
||||||
+ char *zJson;
|
|
||||||
+ zJson = sqlite3_mprintf(
|
|
||||||
+ "{iJD:%lld,Y:%d,M:%d,D:%d,h:%d,m:%d,tz:%d,"
|
|
||||||
+ "s:%.3f,validJD:%d,validYMS:%d,validHMS:%d,"
|
|
||||||
+ "nFloor:%d,rawS:%d,isError:%d,useSubsec:%d,"
|
|
||||||
+ "isUtc:%d,isLocal:%d}",
|
|
||||||
+ x.iJD, x.Y, x.M, x.D, x.h, x.m, x.tz,
|
|
||||||
+ x.s, x.validJD, x.validYMD, x.validHMS,
|
|
||||||
+ x.nFloor, x.rawS, x.isError, x.useSubsec,
|
|
||||||
+ x.isUtc, x.isLocal);
|
|
||||||
+ sqlite3_result_text(context, zJson, -1, sqlite3_free);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+#endif /* !SQLITE_OMIT_DATETIME_FUNCS && SQLITE_DEBUG */
|
|
||||||
+
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
** This function registered all of the above C functions as SQL
|
|
||||||
** functions. This should be the only routine in this file with
|
|
||||||
@@ -1611,6 +1799,9 @@ void sqlite3RegisterDateTimeFunctions(void){
|
|
||||||
PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
|
|
||||||
PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
|
|
||||||
PURE_DATE(timediff, 2, 0, 0, timediffFunc ),
|
|
||||||
+#ifdef SQLITE_DEBUG
|
|
||||||
+ PURE_DATE(datedebug, -1, 0, 0, datedebugFunc ),
|
|
||||||
+#endif
|
|
||||||
DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
|
|
||||||
DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
|
|
||||||
DFUNCTION(current_date, 0, 0, 0, cdateFunc ),
|
|
||||||
@@ -3,7 +3,7 @@ set -euo pipefail
|
|||||||
|
|
||||||
cd -P -- "$(dirname -- "$0")"
|
cd -P -- "$(dirname -- "$0")"
|
||||||
|
|
||||||
curl -#OL "https://sqlite.org/2024/sqlite-amalgamation-3450300.zip"
|
curl -#OL "https://sqlite.org/2024/sqlite-amalgamation-3460000.zip"
|
||||||
unzip -d . sqlite-amalgamation-*.zip
|
unzip -d . sqlite-amalgamation-*.zip
|
||||||
mv sqlite-amalgamation-*/sqlite3* .
|
mv sqlite-amalgamation-*/sqlite3* .
|
||||||
rm -rf sqlite-amalgamation-*
|
rm -rf sqlite-amalgamation-*
|
||||||
@@ -12,25 +12,25 @@ cat *.patch | patch --no-backup-if-mismatch
|
|||||||
|
|
||||||
mkdir -p ext/
|
mkdir -p ext/
|
||||||
cd ext/
|
cd ext/
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/ext/misc/anycollseq.c"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/ext/misc/anycollseq.c"
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/ext/misc/base64.c"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/ext/misc/base64.c"
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/ext/misc/decimal.c"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/ext/misc/decimal.c"
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/ext/misc/ieee754.c"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/ext/misc/ieee754.c"
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/ext/misc/regexp.c"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/ext/misc/regexp.c"
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/ext/misc/series.c"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/ext/misc/series.c"
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/ext/misc/uint.c"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/ext/misc/uint.c"
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/ext/misc/uuid.c"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/ext/misc/uuid.c"
|
||||||
cd ~-
|
cd ~-
|
||||||
|
|
||||||
cd ../vfs/tests/mptest/testdata/
|
cd ../vfs/tests/mptest/testdata/
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/mptest/mptest.c"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/mptest/mptest.c"
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/mptest/config01.test"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/mptest/config01.test"
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/mptest/config02.test"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/mptest/config02.test"
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/mptest/crash01.test"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/mptest/crash01.test"
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/mptest/crash02.subtest"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/mptest/crash02.subtest"
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/mptest/multiwrite01.test"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/mptest/multiwrite01.test"
|
||||||
cd ~-
|
cd ~-
|
||||||
|
|
||||||
cd ../vfs/tests/speedtest1/testdata/
|
cd ../vfs/tests/speedtest1/testdata/
|
||||||
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.45.3/test/speedtest1.c"
|
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.46.0/test/speedtest1.c"
|
||||||
cd ~-
|
cd ~-
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#define SQLITE_DEFAULT_FOREIGN_KEYS 1
|
#define SQLITE_DEFAULT_FOREIGN_KEYS 1
|
||||||
#define SQLITE_ENABLE_ATOMIC_WRITE
|
#define SQLITE_ENABLE_ATOMIC_WRITE
|
||||||
#define SQLITE_ENABLE_BATCH_ATOMIC_WRITE
|
#define SQLITE_ENABLE_BATCH_ATOMIC_WRITE
|
||||||
|
#define SQLITE_ENABLE_COLUMN_METADATA
|
||||||
#define SQLITE_ENABLE_STAT4 1
|
#define SQLITE_ENABLE_STAT4 1
|
||||||
|
|
||||||
// We have our own memdb VFS.
|
// We have our own memdb VFS.
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
static int time_collation(void *pArg, int nKey1, const void *pKey1, int nKey2,
|
static int time_collation(void *pArg, int nKey1, const void *pKey1, int nKey2,
|
||||||
const void *pKey2) {
|
const void *pKey2) {
|
||||||
|
UNUSED_PARAMETER(pArg);
|
||||||
|
|
||||||
// Remove a Z suffix if one key is no longer than the other.
|
// Remove a Z suffix if one key is no longer than the other.
|
||||||
// A Z suffix collates before any character but after the empty string.
|
// A Z suffix collates before any character but after the empty string.
|
||||||
// This avoids making different keys equal.
|
// This avoids making different keys equal.
|
||||||
@@ -29,8 +31,8 @@ static int time_collation(void *pArg, int nKey1, const void *pKey1, int nKey2,
|
|||||||
|
|
||||||
int sqlite3_time_init(sqlite3 *db, char **pzErrMsg,
|
int sqlite3_time_init(sqlite3 *db, char **pzErrMsg,
|
||||||
const sqlite3_api_routines *pApi) {
|
const sqlite3_api_routines *pApi) {
|
||||||
|
UNUSED_PARAMETER2(pzErrMsg, pApi);
|
||||||
sqlite3_create_collation_v2(db, "time", SQLITE_UTF8, /*arg=*/NULL,
|
sqlite3_create_collation_v2(db, "time", SQLITE_UTF8, /*arg=*/NULL,
|
||||||
time_collation,
|
time_collation, /*destroy=*/NULL);
|
||||||
/*destroy=*/NULL);
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
# This patch allows Go VFSes to be (un)registered.
|
# This patch allows Go VFSes to be (un)registered.
|
||||||
--- sqlite3.c.orig
|
--- sqlite3.c.orig
|
||||||
+++ sqlite3.c
|
+++ sqlite3.c
|
||||||
@@ -26372,7 +26372,7 @@
|
@@ -26396,7 +26396,7 @@
|
||||||
** Locate a VFS by name. If no name is given, simply return the
|
** Locate a VFS by name. If no name is given, simply return the
|
||||||
** first VFS on the list.
|
** first VFS on the list.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ static void go_mod_destroy(void *pAux) {
|
|||||||
static int go_vtab_create_wrapper(sqlite3 *db, void *pAux, int argc,
|
static int go_vtab_create_wrapper(sqlite3 *db, void *pAux, int argc,
|
||||||
const char *const *argv,
|
const char *const *argv,
|
||||||
sqlite3_vtab **ppVTab, char **pzErr) {
|
sqlite3_vtab **ppVTab, char **pzErr) {
|
||||||
|
UNUSED_PARAMETER(db);
|
||||||
|
|
||||||
struct go_vtab *vtab = calloc(1, sizeof(struct go_vtab));
|
struct go_vtab *vtab = calloc(1, sizeof(struct go_vtab));
|
||||||
if (vtab == NULL) return SQLITE_NOMEM;
|
if (vtab == NULL) return SQLITE_NOMEM;
|
||||||
*ppVTab = &vtab->base;
|
*ppVTab = &vtab->base;
|
||||||
@@ -88,6 +90,8 @@ static int go_vtab_create_wrapper(sqlite3 *db, void *pAux, int argc,
|
|||||||
static int go_vtab_connect_wrapper(sqlite3 *db, void *pAux, int argc,
|
static int go_vtab_connect_wrapper(sqlite3 *db, void *pAux, int argc,
|
||||||
const char *const *argv,
|
const char *const *argv,
|
||||||
sqlite3_vtab **ppVTab, char **pzErr) {
|
sqlite3_vtab **ppVTab, char **pzErr) {
|
||||||
|
UNUSED_PARAMETER(db);
|
||||||
|
|
||||||
struct go_vtab *vtab = calloc(1, sizeof(struct go_vtab));
|
struct go_vtab *vtab = calloc(1, sizeof(struct go_vtab));
|
||||||
if (vtab == NULL) return SQLITE_NOMEM;
|
if (vtab == NULL) return SQLITE_NOMEM;
|
||||||
*ppVTab = &vtab->base;
|
*ppVTab = &vtab->base;
|
||||||
|
|||||||
48
stmt.go
48
stmt.go
@@ -367,12 +367,10 @@ func (s *Stmt) ColumnCount() int {
|
|||||||
func (s *Stmt) ColumnName(col int) string {
|
func (s *Stmt) ColumnName(col int) string {
|
||||||
r := s.c.call("sqlite3_column_name",
|
r := s.c.call("sqlite3_column_name",
|
||||||
uint64(s.handle), uint64(col))
|
uint64(s.handle), uint64(col))
|
||||||
|
if r == 0 {
|
||||||
ptr := uint32(r)
|
|
||||||
if ptr == 0 {
|
|
||||||
panic(util.OOMErr)
|
panic(util.OOMErr)
|
||||||
}
|
}
|
||||||
return util.ReadString(s.c.mod, ptr, _MAX_NAME)
|
return util.ReadString(s.c.mod, uint32(r), _MAX_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ColumnType returns the initial [Datatype] of the result column.
|
// ColumnType returns the initial [Datatype] of the result column.
|
||||||
@@ -398,6 +396,48 @@ func (s *Stmt) ColumnDeclType(col int) string {
|
|||||||
return util.ReadString(s.c.mod, uint32(r), _MAX_NAME)
|
return util.ReadString(s.c.mod, uint32(r), _MAX_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ColumnDatabaseName returns the name of the database
|
||||||
|
// that is the origin of a particular result column.
|
||||||
|
// The leftmost column of the result set has the index 0.
|
||||||
|
//
|
||||||
|
// https://sqlite.org/c3ref/column_database_name.html
|
||||||
|
func (s *Stmt) ColumnDatabaseName(col int) string {
|
||||||
|
r := s.c.call("sqlite3_column_database_name",
|
||||||
|
uint64(s.handle), uint64(col))
|
||||||
|
if r == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return util.ReadString(s.c.mod, uint32(r), _MAX_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ColumnTableName returns the name of the table
|
||||||
|
// that is the origin of a particular result column.
|
||||||
|
// The leftmost column of the result set has the index 0.
|
||||||
|
//
|
||||||
|
// https://sqlite.org/c3ref/column_database_name.html
|
||||||
|
func (s *Stmt) ColumnTableName(col int) string {
|
||||||
|
r := s.c.call("sqlite3_column_table_name",
|
||||||
|
uint64(s.handle), uint64(col))
|
||||||
|
if r == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return util.ReadString(s.c.mod, uint32(r), _MAX_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ColumnOriginName returns the name of the table column
|
||||||
|
// that is the origin of a particular result column.
|
||||||
|
// The leftmost column of the result set has the index 0.
|
||||||
|
//
|
||||||
|
// https://sqlite.org/c3ref/column_database_name.html
|
||||||
|
func (s *Stmt) ColumnOriginName(col int) string {
|
||||||
|
r := s.c.call("sqlite3_column_origin_name",
|
||||||
|
uint64(s.handle), uint64(col))
|
||||||
|
if r == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return util.ReadString(s.c.mod, uint32(r), _MAX_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
// ColumnBool returns the value of the result column as a bool.
|
// ColumnBool returns the value of the result column as a bool.
|
||||||
// The leftmost column of the result set has the index 0.
|
// The leftmost column of the result set has the index 0.
|
||||||
// SQLite does not have a separate boolean storage class.
|
// SQLite does not have a separate boolean storage class.
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func TestStmt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
err = db.Exec(`CREATE TABLE test (col)`)
|
err = db.Exec(`CREATE TABLE test (col ANY) STRICT`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ func TestStmt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The table should have: 0, 1, 2, π, NULL, "", "text", "", "blob", NULL, "\0\0\0\0", "true", NULL
|
// The table should have: 0, 1, 2, π, NULL, "", "text", "", "blob", NULL, "\0\0\0\0", "true", NULL
|
||||||
stmt, _, err = db.Prepare(`SELECT col FROM test`)
|
stmt, _, err = db.Prepare(`SELECT col AS c FROM test`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -145,6 +145,21 @@ func TestStmt(t *testing.T) {
|
|||||||
if got := stmt.ReadOnly(); got != true {
|
if got := stmt.ReadOnly(); got != true {
|
||||||
t.Error("got false, want true")
|
t.Error("got false, want true")
|
||||||
}
|
}
|
||||||
|
if got := stmt.ColumnName(0); got != "c" {
|
||||||
|
t.Errorf(`got %q, want "c"`, got)
|
||||||
|
}
|
||||||
|
if got := stmt.ColumnDeclType(0); got != "ANY" {
|
||||||
|
t.Errorf(`got %q, want "ANY"`, got)
|
||||||
|
}
|
||||||
|
if got := stmt.ColumnOriginName(0); got != "col" {
|
||||||
|
t.Errorf(`got %q, want "col"`, got)
|
||||||
|
}
|
||||||
|
if got := stmt.ColumnTableName(0); got != "test" {
|
||||||
|
t.Errorf(`got %q, want "test"`, got)
|
||||||
|
}
|
||||||
|
if got := stmt.ColumnDatabaseName(0); got != "main" {
|
||||||
|
t.Errorf(`got %q, want "main"`, got)
|
||||||
|
}
|
||||||
|
|
||||||
if stmt.Step() {
|
if stmt.Step() {
|
||||||
if got := stmt.ColumnType(0); got != sqlite3.INTEGER {
|
if got := stmt.ColumnType(0); got != sqlite3.INTEGER {
|
||||||
|
|||||||
6
time.go
6
time.go
@@ -101,7 +101,7 @@ func (f TimeFormat) Encode(t time.Time) any {
|
|||||||
return t.UnixMicro()
|
return t.UnixMicro()
|
||||||
case TimeFormatUnixNano:
|
case TimeFormatUnixNano:
|
||||||
return t.UnixNano()
|
return t.UnixNano()
|
||||||
// Special formats
|
// Special formats.
|
||||||
case TimeFormatDefault, TimeFormatAuto:
|
case TimeFormatDefault, TimeFormatAuto:
|
||||||
f = time.RFC3339Nano
|
f = time.RFC3339Nano
|
||||||
// SQLite assumes UTC if unspecified.
|
// SQLite assumes UTC if unspecified.
|
||||||
@@ -139,7 +139,7 @@ func (f TimeFormat) Encode(t time.Time) any {
|
|||||||
// https://sqlite.org/lang_datefunc.html
|
// https://sqlite.org/lang_datefunc.html
|
||||||
func (f TimeFormat) Decode(v any) (time.Time, error) {
|
func (f TimeFormat) Decode(v any) (time.Time, error) {
|
||||||
switch f {
|
switch f {
|
||||||
// Numeric formats
|
// Numeric formats.
|
||||||
case TimeFormatJulianDay:
|
case TimeFormatJulianDay:
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
case string:
|
case string:
|
||||||
@@ -222,7 +222,7 @@ func (f TimeFormat) Decode(v any) (time.Time, error) {
|
|||||||
return time.Time{}, util.TimeErr
|
return time.Time{}, util.TimeErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special formats
|
// Special formats.
|
||||||
case TimeFormatAuto:
|
case TimeFormatAuto:
|
||||||
switch s := v.(type) {
|
switch s := v.(type) {
|
||||||
case string:
|
case string:
|
||||||
|
|||||||
4
vfs/tests/mptest/testdata/mptest.wasm.bz2
vendored
4
vfs/tests/mptest/testdata/mptest.wasm.bz2
vendored
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:db2dc210ff152cf9c03a4100064e9dd55eafbe61ac7ccf1cd0962c8ba3307300
|
oid sha256:2bca04dc69100a3ea9492f20ce8cdb796cc0a6bd3c95da6abd40c94c599c7509
|
||||||
size 470743
|
size 479477
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f994bcf2ae8eed9333e9b4d3929a52f3b2c4cf0a780311efa243986c4be6f1c1
|
oid sha256:9fc72178e4e89a735d90a0f297f22750718bc7110e9f4cd8618c2d67d9b3c6c4
|
||||||
size 484371
|
size 491944
|
||||||
|
|||||||
Reference in New Issue
Block a user