Changeset: 17fa2fc84053 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=17fa2fc84053
Modified Files:
        sql/server/rel_select.c
        sql/server/rel_select.h
        sql/test/BugTracker-2020/Tests/All
Branch: octbugs
Log Message:

Merged with Oct2020


diffs (truncated from 29018 to 300 lines):

diff --git a/clients/Tests/MAL-signatures.stable.out 
b/clients/Tests/MAL-signatures.stable.out
--- a/clients/Tests/MAL-signatures.stable.out
+++ b/clients/Tests/MAL-signatures.stable.out
@@ -6175,6 +6175,10 @@ stdout of test 'MAL-signatures` in direc
 [ "batmtime",  "epoch",        "command 
batmtime.epoch(X_1:bat[:timestamp]):bat[:int] ",       
"MTIMEseconds_since_epoch_bulk;",       ""      ]
 [ "batmtime",  "epoch",        "command 
batmtime.epoch(X_1:bat[:lng]):bat[:timestamp] ",       
"MTIMEtimestamp_frommsec_bulk;",        ""      ]
 [ "batmtime",  "epoch",        "command 
batmtime.epoch(X_1:bat[:int]):bat[:timestamp] ",       
"MTIMEtimestamp_fromsecond_bulk;",      ""      ]
+[ "batmtime",  "epoch_ms",     "command 
batmtime.epoch_ms(X_1:bat[:date]):bat[:lng] ", 
"MTIMEdate_extract_epoch_ms_bulk;",     ""      ]
+[ "batmtime",  "epoch_ms",     "command 
batmtime.epoch_ms(X_1:bat[:daytime]):bat[:lng] ",      
"MTIMEdaytime_extract_epoch_ms_bulk;",  ""      ]
+[ "batmtime",  "epoch_ms",     "command 
batmtime.epoch_ms(X_1:bat[:lng]):bat[:lng] ",  
"MTIMEmsec_extract_epoch_ms_bulk;",     ""      ]
+[ "batmtime",  "epoch_ms",     "command 
batmtime.epoch_ms(X_1:bat[:timestamp]):bat[:lng] ",    
"MTIMEtimestamp_extract_epoch_ms_bulk;",        ""      ]
 [ "batmtime",  "hours",        "command 
batmtime.hours(X_1:bat[:daytime]):bat[:int] ", 
"MTIMEdaytime_extract_hours_bulk;",     ""      ]
 [ "batmtime",  "hours",        "command 
batmtime.hours(X_1:bat[:lng]):bat[:int] ",     "MTIMEsql_hours_bulk;", ""      ]
 [ "batmtime",  "hours",        "command 
batmtime.hours(X_1:bat[:timestamp]):bat[:int] ",       
"MTIMEtimestamp_hours_bulk;",   ""      ]
@@ -8930,6 +8934,10 @@ stdout of test 'MAL-signatures` in direc
 [ "mtime",     "epoch",        "command mtime.epoch(X_1:timestamp):int ",      
"MTIMEseconds_since_epoch;",    ""      ]
 [ "mtime",     "epoch",        "command mtime.epoch(X_1:lng):timestamp ",      
"MTIMEtimestamp_frommsec;",     ""      ]
 [ "mtime",     "epoch",        "command mtime.epoch(X_1:int):timestamp ",      
"MTIMEtimestamp_fromsecond;",   ""      ]
+[ "mtime",     "epoch_ms",     "command mtime.epoch_ms(X_1:date):lng ",        
"MTIMEdate_extract_epoch_ms;",  ""      ]
+[ "mtime",     "epoch_ms",     "command mtime.epoch_ms(X_1:daytime):lng ",     
"MTIMEdaytime_extract_epoch_ms;",       ""      ]
+[ "mtime",     "epoch_ms",     "command mtime.epoch_ms(X_1:lng):lng ", 
"MTIMEmsec_extract_epoch_ms;",  ""      ]
+[ "mtime",     "epoch_ms",     "command mtime.epoch_ms(X_1:timestamp):lng ",   
"MTIMEtimestamp_extract_epoch_ms;",     ""      ]
 [ "mtime",     "hours",        "command mtime.hours(X_1:daytime):int ",        
"MTIMEdaytime_extract_hours;",  ""      ]
 [ "mtime",     "hours",        "command mtime.hours(X_1:lng):int ",    
"MTIMEsql_hours;",      ""      ]
 [ "mtime",     "hours",        "command mtime.hours(X_1:timestamp):int ",      
"MTIMEtimestamp_hours;",        ""      ]
diff --git a/clients/Tests/MAL-signatures.stable.out.int128 
b/clients/Tests/MAL-signatures.stable.out.int128
--- a/clients/Tests/MAL-signatures.stable.out.int128
+++ b/clients/Tests/MAL-signatures.stable.out.int128
@@ -8744,6 +8744,10 @@ stdout of test 'MAL-signatures` in direc
 [ "batmtime",  "epoch",        "command 
batmtime.epoch(X_1:bat[:timestamp]):bat[:int] ",       
"MTIMEseconds_since_epoch_bulk;",       ""      ]
 [ "batmtime",  "epoch",        "command 
batmtime.epoch(X_1:bat[:lng]):bat[:timestamp] ",       
"MTIMEtimestamp_frommsec_bulk;",        ""      ]
 [ "batmtime",  "epoch",        "command 
batmtime.epoch(X_1:bat[:int]):bat[:timestamp] ",       
"MTIMEtimestamp_fromsecond_bulk;",      ""      ]
+[ "batmtime",  "epoch_ms",     "command 
batmtime.epoch_ms(X_1:bat[:date]):bat[:lng] ", 
"MTIMEdate_extract_epoch_ms_bulk;",     ""      ]
+[ "batmtime",  "epoch_ms",     "command 
batmtime.epoch_ms(X_1:bat[:daytime]):bat[:lng] ",      
"MTIMEdaytime_extract_epoch_ms_bulk;",  ""      ]
+[ "batmtime",  "epoch_ms",     "command 
batmtime.epoch_ms(X_1:bat[:lng]):bat[:lng] ",  
"MTIMEmsec_extract_epoch_ms_bulk;",     ""      ]
+[ "batmtime",  "epoch_ms",     "command 
batmtime.epoch_ms(X_1:bat[:timestamp]):bat[:lng] ",    
"MTIMEtimestamp_extract_epoch_ms_bulk;",        ""      ]
 [ "batmtime",  "hours",        "command 
batmtime.hours(X_1:bat[:daytime]):bat[:int] ", 
"MTIMEdaytime_extract_hours_bulk;",     ""      ]
 [ "batmtime",  "hours",        "command 
batmtime.hours(X_1:bat[:lng]):bat[:int] ",     "MTIMEsql_hours_bulk;", ""      ]
 [ "batmtime",  "hours",        "command 
batmtime.hours(X_1:bat[:timestamp]):bat[:int] ",       
"MTIMEtimestamp_hours_bulk;",   ""      ]
@@ -12271,6 +12275,10 @@ stdout of test 'MAL-signatures` in direc
 [ "mtime",     "epoch",        "command mtime.epoch(X_1:timestamp):int ",      
"MTIMEseconds_since_epoch;",    ""      ]
 [ "mtime",     "epoch",        "command mtime.epoch(X_1:lng):timestamp ",      
"MTIMEtimestamp_frommsec;",     ""      ]
 [ "mtime",     "epoch",        "command mtime.epoch(X_1:int):timestamp ",      
"MTIMEtimestamp_fromsecond;",   ""      ]
+[ "mtime",     "epoch_ms",     "command mtime.epoch_ms(X_1:date):lng ",        
"MTIMEdate_extract_epoch_ms;",  ""      ]
+[ "mtime",     "epoch_ms",     "command mtime.epoch_ms(X_1:daytime):lng ",     
"MTIMEdaytime_extract_epoch_ms;",       ""      ]
+[ "mtime",     "epoch_ms",     "command mtime.epoch_ms(X_1:lng):lng ", 
"MTIMEmsec_extract_epoch_ms;",  ""      ]
+[ "mtime",     "epoch_ms",     "command mtime.epoch_ms(X_1:timestamp):lng ",   
"MTIMEtimestamp_extract_epoch_ms;",     ""      ]
 [ "mtime",     "hours",        "command mtime.hours(X_1:daytime):int ",        
"MTIMEdaytime_extract_hours;",  ""      ]
 [ "mtime",     "hours",        "command mtime.hours(X_1:lng):int ",    
"MTIMEsql_hours;",      ""      ]
 [ "mtime",     "hours",        "command mtime.hours(X_1:timestamp):int ",      
"MTIMEtimestamp_hours;",        ""      ]
diff --git a/clients/mapiclient/mhelp.c b/clients/mapiclient/mhelp.c
--- a/clients/mapiclient/mhelp.c
+++ b/clients/mapiclient/mhelp.c
@@ -399,7 +399,7 @@ SQLhelp sqlhelp1[] = {
         "See also 
https://www.monetdb.org/Documentation/Manuals/SQLreference/Explain"},
        {"EXTRACT",
         "Built-in function",
-        "EXTRACT '(' { YEAR | MONTH | DAY | HOUR | MINUTE | SECOND | CENTURY | 
DECADE | QUARTER | WEEK | DOW | DOY } FROM scalar_expression ')'",
+        "EXTRACT '(' { YEAR | MONTH | DAY | HOUR | MINUTE | SECOND | CENTURY | 
DECADE | QUARTER | WEEK | DOW | DOY | EPOCH } FROM scalar_expression ')'",
         NULL,
         NULL},
        {"INSERT",
diff --git a/monetdb5/modules/atoms/mtime.c b/monetdb5/modules/atoms/mtime.c
--- a/monetdb5/modules/atoms/mtime.c
+++ b/monetdb5/modules/atoms/mtime.c
@@ -496,6 +496,8 @@ func2(MTIMEdate_submonths, MTIMEdate_sub
 func2(MTIMEdate_addmonths, MTIMEdate_addmonths_bulk, "date_addmonths", date, 
int, date, date_addmonths, func2_except, \
          DEC_VAR_R, DEC_VAR_R, DEC_VAR_R, DEC_VAR_R, DEC_VAR_R, INIT_VAR, 
INIT_VAR, INIT_VAR, GET_NEXT_VAR, GET_NEXT_VAR, APPEND_VAR)
 
+#define date_to_msec_since_epoch(t) is_date_nil(t) ? lng_nil : 
(timestamp_diff(timestamp_create(t, daytime_create(0, 0, 0, 0)), unixepoch) / 
1000)
+#define daytime_to_msec_since_epoch(t) daytime_diff(t, daytime_create(0, 0, 0, 
0))
 func1(MTIMEdate_extract_century, MTIMEdate_extract_century_bulk, 
"date_century", date, int, date_century, COPYFLAGS, func1_noexcept, \
          DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
 func1(MTIMEdate_extract_decade, MTIMEdate_extract_decade_bulk, "date_decade", 
date, int, date_decade, COPYFLAGS, func1_noexcept, \
@@ -514,12 +516,16 @@ func1(MTIMEdate_extract_weekofyear, MTIM
          DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
 func1(MTIMEdate_extract_dayofweek, MTIMEdate_extract_dayofweek_bulk, 
"date_dayofweek", date, int, date_dayofweek, SETFLAGS, func1_noexcept, \
          DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
+func1(MTIMEdate_extract_epoch_ms, MTIMEdate_extract_epoch_ms_bulk, "epoch_ms", 
date, lng, date_to_msec_since_epoch, COPYFLAGS, func1_noexcept, \
+         DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
 func1(MTIMEdaytime_extract_hours, MTIMEdaytime_extract_hours_bulk, 
"daytime_hour", daytime, int, daytime_hour, COPYFLAGS, func1_noexcept, \
          DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
 func1(MTIMEdaytime_extract_minutes, MTIMEdaytime_extract_minutes_bulk, 
"daytime_minutes", daytime, int, daytime_min, SETFLAGS, func1_noexcept, \
          DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
 func1(MTIMEdaytime_extract_sql_seconds, MTIMEdaytime_extract_sql_seconds_bulk, 
"daytime_seconds", daytime, int, daytime_sec_usec, SETFLAGS, func1_noexcept, \
          DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
+func1(MTIMEdaytime_extract_epoch_ms, MTIMEdaytime_extract_epoch_ms_bulk, 
"epoch_ms", daytime, lng, daytime_to_msec_since_epoch, COPYFLAGS, 
func1_noexcept, \
+         DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
 
 static inline lng
 TSDIFF(timestamp t1, timestamp t2)
@@ -559,6 +565,7 @@ timestamp_century(const timestamp t)
 #define timestamp_hours(t) daytime_hour(timestamp_daytime(t))
 #define timestamp_minutes(t) daytime_min(timestamp_daytime(t))
 #define timestamp_extract_usecond(ts)  daytime_sec_usec(timestamp_daytime(ts))
+#define timestamp_to_msec_since_epoch(t) is_timestamp_nil(t) ? lng_nil : 
(timestamp_diff(t, unixepoch) / 1000)
 func1(MTIMEtimestamp_century, MTIMEtimestamp_century_bulk, 
"timestamp_century", timestamp, int, timestamp_century, COPYFLAGS, 
func1_noexcept, \
          DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
 func1(MTIMEtimestamp_decade, MTIMEtimestamp_decade_bulk, "timestamp_decade", 
timestamp, int, timestamp_decade, COPYFLAGS, func1_noexcept, \
@@ -577,6 +584,8 @@ func1(MTIMEtimestamp_minutes, MTIMEtimes
          DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
 func1(MTIMEtimestamp_sql_seconds, MTIMEtimestamp_sql_seconds_bulk, 
"sql_seconds", timestamp, int, timestamp_extract_usecond, SETFLAGS, 
func1_noexcept, \
          DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
+func1(MTIMEtimestamp_extract_epoch_ms, MTIMEtimestamp_extract_epoch_ms_bulk, 
"epoch_ms", timestamp, lng, timestamp_to_msec_since_epoch, COPYFLAGS, 
func1_noexcept, \
+         DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
 
 #define sql_year(m) is_int_nil(m) ? int_nil : m / 12
 #define sql_month(m) is_int_nil(m) ? int_nil : m % 12
@@ -584,6 +593,7 @@ func1(MTIMEtimestamp_sql_seconds, MTIMEt
 #define sql_hours(m) is_lng_nil(m) ? int_nil : (int) ((m % (24*60*60*1000)) / 
(60*60*1000))
 #define sql_minutes(m) is_lng_nil(m) ? int_nil : (int) ((m % (60*60*1000)) / 
(60*1000))
 #define sql_seconds(m) is_lng_nil(m) ? int_nil : (int) ((m % (60*1000)) / 1000)
+#define msec_since_epoch(ts)   ts
 func1(MTIMEsql_year, MTIMEsql_year_bulk, "sql_year", int, int, sql_year, 
COPYFLAGS, func1_noexcept, \
          DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
 func1(MTIMEsql_month, MTIMEsql_month_bulk, "sql_month", int, int, sql_month, 
SETFLAGS, func1_noexcept, \
@@ -596,6 +606,8 @@ func1(MTIMEsql_minutes, MTIMEsql_minutes
          DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
 func1(MTIMEsql_seconds, MTIMEsql_seconds_bulk, "sql_seconds", lng, int, 
sql_seconds, SETFLAGS, func1_noexcept, \
          DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
+func1(MTIMEmsec_extract_epoch_ms, MTIMEmsec_extract_epoch_ms_bulk, "msepoch", 
lng, lng, msec_since_epoch, COPYFLAGS, func1_noexcept, \
+         DEC_VAR_R, DEC_VAR_R, INIT_VAR, INIT_VAR, GET_NEXT_VAR)
 
 static inline str
 date_fromstr_func(date *ret, str s)
@@ -983,12 +995,16 @@ static mel_func mtime_init_funcs[] = {
  command("batmtime", "month", MTIMEdate_extract_month_bulk, false, "", 
args(1,2, batarg("",int),batarg("d",date))),
  command("mtime", "day", MTIMEdate_extract_day, false, "extracts day from date 
", args(1,2, arg("",int),arg("d",date))),
  command("batmtime", "day", MTIMEdate_extract_day_bulk, false, "", args(1,2, 
batarg("",int),batarg("d",date))),
+ command("mtime", "epoch_ms", MTIMEdate_extract_epoch_ms, false, "", args(1,2, 
arg("",lng),arg("d",date))),
+ command("batmtime", "epoch_ms", MTIMEdate_extract_epoch_ms_bulk, false, "", 
args(1,2, batarg("",lng),batarg("d",date))),
  command("mtime", "hours", MTIMEdaytime_extract_hours, false, "extracts hour 
from daytime", args(1,2, arg("",int),arg("h",daytime))),
  command("batmtime", "hours", MTIMEdaytime_extract_hours_bulk, false, "", 
args(1,2, batarg("",int),batarg("d",daytime))),
  command("mtime", "minutes", MTIMEdaytime_extract_minutes, false, "extracts 
minutes from daytime", args(1,2, arg("",int),arg("d",daytime))),
  command("batmtime", "minutes", MTIMEdaytime_extract_minutes_bulk, false, "", 
args(1,2, batarg("",int),batarg("d",daytime))),
  command("mtime", "sql_seconds", MTIMEdaytime_extract_sql_seconds, false, 
"extracts seconds (with fractional milliseconds) from daytime", args(1,2, 
arg("",int),arg("d",daytime))),
  command("batmtime", "sql_seconds", MTIMEdaytime_extract_sql_seconds_bulk, 
false, "", args(1,2, batarg("",int),batarg("d",daytime))),
+ command("mtime", "epoch_ms", MTIMEdaytime_extract_epoch_ms, false, "", 
args(1,2, arg("",lng),arg("d",daytime))),
+ command("batmtime", "epoch_ms", MTIMEdaytime_extract_epoch_ms_bulk, false, 
"", args(1,2, batarg("",lng),batarg("d",daytime))),
  command("mtime", "addmonths", MTIMEdate_addmonths, false, "returns the date 
after a number of\nmonths (possibly negative).", args(1,3, 
arg("",date),arg("value",date),arg("months",int))),
  command("batmtime", "addmonths", MTIMEdate_addmonths_bulk, false, "", 
args(1,3, batarg("",date),batarg("value",date),batarg("months",int))),
  command("batmtime", "addmonths", MTIMEdate_addmonths_bulk_p1, false, "", 
args(1,3, batarg("",date),arg("value",date),batarg("months",int))),
@@ -1052,6 +1068,8 @@ static mel_func mtime_init_funcs[] = {
  command("batmtime", "minutes", MTIMEtimestamp_minutes_bulk, false, "", 
args(1,2, batarg("",int),batarg("t",timestamp))),
  command("mtime", "sql_seconds", MTIMEtimestamp_sql_seconds, false, "", 
args(1,2, arg("",int),arg("t",timestamp))),
  command("batmtime", "sql_seconds", MTIMEtimestamp_sql_seconds_bulk, false, 
"", args(1,2, batarg("",int),batarg("d",timestamp))),
+ command("mtime", "epoch_ms", MTIMEtimestamp_extract_epoch_ms, false, "", 
args(1,2, arg("",lng),arg("t",timestamp))),
+ command("batmtime", "epoch_ms", MTIMEtimestamp_extract_epoch_ms_bulk, false, 
"", args(1,2, batarg("",lng),batarg("t",timestamp))),
  command("mtime", "year", MTIMEsql_year, false, "", args(1,2, 
arg("",int),arg("months",int))),
  command("batmtime", "year", MTIMEsql_year_bulk, false, "", args(1,2, 
batarg("",int),batarg("months",int))),
  command("mtime", "month", MTIMEsql_month, false, "", args(1,2, 
arg("",int),arg("months",int))),
@@ -1064,6 +1082,8 @@ static mel_func mtime_init_funcs[] = {
  command("batmtime", "minutes", MTIMEsql_minutes_bulk, false, "", args(1,2, 
batarg("",int),batarg("msecs",lng))),
  command("mtime", "seconds", MTIMEsql_seconds, false, "", args(1,2, 
arg("",int),arg("msecs",lng))),
  command("batmtime", "seconds", MTIMEsql_seconds_bulk, false, "", args(1,2, 
batarg("",int),batarg("msecs",lng))),
+ command("mtime", "epoch_ms", MTIMEmsec_extract_epoch_ms, false, "", args(1,2, 
arg("",lng),arg("msecs",lng))),
+ command("batmtime", "epoch_ms", MTIMEmsec_extract_epoch_ms_bulk, false, "", 
args(1,2, batarg("",lng),batarg("msecs",lng))),
  command("calc", "date", MTIMEdate_fromstr, false, "", args(1,2, 
arg("",date),arg("s",str))),
  command("calc", "date", MTIMEdate_date, false, "", args(1,2, 
arg("",date),arg("d",date))),
  command("calc", "date", MTIMEtimestamp_extract_date, false, "", args(1,2, 
arg("",date),arg("t",timestamp))),
diff --git a/sql/ChangeLog.Oct2020 b/sql/ChangeLog.Oct2020
--- a/sql/ChangeLog.Oct2020
+++ b/sql/ChangeLog.Oct2020
@@ -56,9 +56,20 @@
   Instead do SET current_timezone = interval '1' hour;
   Casting between interval and other numeric types is no longer possible
   as well, because they are not compatible.
-  
+- Because of incompatibilities this change may create, if an user intents
+  to convert a numeric value to an interval, the multiplication function
+  can be used in the form: <numeric value> * interval '1' <interval length>
+  e.g. 10 * interval '1' second = interval '10' second.
+  As for the other way around, the 'EPOCH' option was added to the extract
+  syntax. This option returns the number of milliseconds since the UNIX
+  epoch 1970-01-01 00:00:00 UTC for date, timestamp and time values (it
+  can be negative). Meanwhile, for day and second intervals, it returns the
+  total number of milliseconds on the interval. As a side note, the 'EPOCH'
+  option is not available for month intervals, because this conversion is
+  not transparent for this type.
+
 * Mon Aug 31 2020 Pedro Ferreira <pedro.ferre...@monetdbsolutions.com>
 - Made general logarithm function log(x,base) compliant with the SQL 
   standard, by swapping the input parameters.
   Instead of log(x,base), now is log(base,x).
-  
+
diff --git a/sql/backends/monet5/sql_upgrades.c 
b/sql/backends/monet5/sql_upgrades.c
--- a/sql/backends/monet5/sql_upgrades.c
+++ b/sql/backends/monet5/sql_upgrades.c
@@ -2365,11 +2365,11 @@ static str
 sql_update_oct2020(Client c, mvc *sql, const char *prev_schema, bool 
*systabfixed)
 {
        size_t bufsize = 4096, pos = 0;
-       char *buf, *err;
+       char *buf = NULL, *err = NULL;
        sql_schema *s = mvc_bind_schema(sql, "sys");
        sql_table *t;
-       res_table *output;
-       BAT *b;
+       res_table *output = NULL;
+       BAT *b = NULL;
 
        if ((buf = GDKmalloc(bufsize)) == NULL)
                throw(SQL, __func__, SQLSTATE(HY013) MAL_MALLOC_FAIL);
@@ -2475,22 +2475,37 @@ sql_update_oct2020(Client c, mvc *sql, c
                                        " external name generator.series;\n"
                                        "update sys.functions set system = true 
where system <> true and name in ('generate_series') and schema_id = (select id 
from sys.schemas where name = 'sys') and type = %d;\n", (int) F_UNION);
 
+                       /* 51_sys_schema_extensions.sql */
+                       pos += snprintf(buf + pos, bufsize - pos,
+                                       "ALTER TABLE sys.keywords SET READ 
WRITE;\n"
+                                       "insert into sys.keywords values 
('EPOCH');\n");
+
+                       pos += snprintf(buf + pos, bufsize - pos, "commit;\n");
                        pos += snprintf(buf + pos, bufsize - pos, "set schema 
\"%s\";\n", prev_schema);
 
                        assert(pos < bufsize);
                        printf("Running database upgrade commands:\n%s\n", buf);
                        err = SQLstatementIntern(c, buf, "update", true, false, 
NULL);
-                       if (err) {
-                               BBPunfix(b->batCacheid);
-                               res_table_destroy(output);
-                               GDKfree(buf);
-                               return err;
-                       }
+                       if (err != MAL_SUCCEED)
+                               goto bailout;
+
+                       pos = snprintf(buf, bufsize, "set schema \"sys\";\n"
+                                       "ALTER TABLE sys.keywords SET READ 
ONLY;\n");
+                       pos += snprintf(buf + pos, bufsize - pos, "set schema 
\"%s\";\n", prev_schema);
+                       assert(pos < bufsize);
+                       printf("Running database upgrade commands:\n%s\n", buf);
+                       err = SQLstatementIntern(c, buf, "update", true, false, 
NULL);
+                       if (err != MAL_SUCCEED)
+                               goto bailout;
                        err = sql_update_storagemodel(c, sql, prev_schema, 
true); /* because of day interval addition, we have to recreate the storagmodel 
views */
                }
+       }
+
+bailout:
+       if (b)
                BBPunfix(b->batCacheid);
-       }
-       res_table_destroy(output);
+       if (output)
+               res_table_destroy(output);
        GDKfree(buf);
        return err;             /* usually MAL_SUCCEED */
 }
diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c
--- a/sql/common/sql_types.c
+++ b/sql/common/sql_types.c
@@ -1802,13 +1802,16 @@ sqltypeinit( sql_allocator *sa)
        sql_create_func(sa, "dayofweek", "mtime", "dayofweek", FALSE, FALSE, 
SCALE_FIX, 0, INT, 1, DTE);
        sql_create_func(sa, "dayofmonth", "mtime", "day", FALSE, FALSE, 
SCALE_FIX, 0, INT, 1, DTE);
        sql_create_func(sa, "week", "mtime", "weekofyear", FALSE, FALSE, 
SCALE_FIX, 0, INT, 1, DTE);
+       sql_create_func(sa, "epoch_ms", "mtime", "epoch_ms", FALSE, FALSE, 
SCALE_NONE, 0, LNG, 1, DTE);
 
        sql_create_func(sa, "hour", "mtime", "hours", FALSE, FALSE, SCALE_FIX, 
0, INT, 1, TME);
        sql_create_func(sa, "minute", "mtime", "minutes", FALSE, FALSE, 
SCALE_FIX, 0, INT, 1, TME);
        sql_create_func(sa, "second", "mtime", "sql_seconds", FALSE, FALSE, 
SCALE_NONE, 6, DEC, 1, TME);
+       sql_create_func(sa, "epoch_ms", "mtime", "epoch_ms", FALSE, FALSE, 
SCALE_NONE, 0, LNG, 1, TME);
        sql_create_func(sa, "hour", "mtime", "hours", FALSE, FALSE, SCALE_FIX, 
0, INT, 1, TMETZ);
        sql_create_func(sa, "minute", "mtime", "minutes", FALSE, FALSE, 
SCALE_FIX, 0, INT, 1, TMETZ);
        sql_create_func(sa, "second", "mtime", "sql_seconds", FALSE, FALSE, 
SCALE_NONE, 6, DEC, 1, TMETZ);
+       sql_create_func(sa, "epoch_ms", "mtime", "epoch_ms", FALSE, FALSE, 
SCALE_NONE, 0, LNG, 1, TMETZ);
 
        sql_create_func(sa, "century", "mtime", "century", FALSE, FALSE, 
SCALE_FIX, 0, INT, 1, TMESTAMP);
        sql_create_func(sa, "decade", "mtime", "decade", FALSE, FALSE, 
SCALE_FIX, 0, INT, 1, TMESTAMP);
@@ -1819,6 +1822,7 @@ sqltypeinit( sql_allocator *sa)
        sql_create_func(sa, "hour", "mtime", "hours", FALSE, FALSE, SCALE_FIX, 
0, INT, 1, TMESTAMP);
        sql_create_func(sa, "minute", "mtime", "minutes", FALSE, FALSE, 
SCALE_FIX, 0, INT, 1, TMESTAMP);
        sql_create_func(sa, "second", "mtime", "sql_seconds", FALSE, FALSE, 
SCALE_NONE, 6, DEC, 1, TMESTAMP);
+       sql_create_func(sa, "epoch_ms", "mtime", "epoch_ms", FALSE, FALSE, 
SCALE_NONE, 0, LNG, 1, TMESTAMP);
 
        sql_create_func(sa, "century", "mtime", "century", FALSE, FALSE, 
SCALE_FIX, 0, INT, 1, TMESTAMPTZ);
        sql_create_func(sa, "decade", "mtime", "decade", FALSE, FALSE, 
SCALE_FIX, 0, INT, 1, TMESTAMPTZ);
@@ -1829,6 +1833,7 @@ sqltypeinit( sql_allocator *sa)
        sql_create_func(sa, "hour", "mtime", "hours", FALSE, FALSE, SCALE_FIX, 
0, INT, 1, TMESTAMPTZ);
        sql_create_func(sa, "minute", "mtime", "minutes", FALSE, FALSE, 
SCALE_FIX, 0, INT, 1, TMESTAMPTZ);
        sql_create_func(sa, "second", "mtime", "sql_seconds", FALSE, FALSE, 
SCALE_NONE, 6, DEC, 1, TMESTAMPTZ);
+       sql_create_func(sa, "epoch_ms", "mtime", "epoch_ms", FALSE, FALSE, 
SCALE_NONE, 0, LNG, 1, TMESTAMPTZ);
 
        sql_create_func(sa, "year", "mtime", "year", FALSE, FALSE, SCALE_NONE, 
0, INT, 1, MONINT);
        sql_create_func(sa, "month", "mtime", "month", FALSE, FALSE, 
SCALE_NONE, 0, INT, 1, MONINT);
@@ -1836,10 +1841,12 @@ sqltypeinit( sql_allocator *sa)
        sql_create_func(sa, "hour", "mtime", "hours", FALSE, FALSE, SCALE_NONE, 
0, INT, 1, DAYINT);
        sql_create_func(sa, "minute", "mtime", "minutes", FALSE, FALSE, 
SCALE_NONE, 0, INT, 1, DAYINT);
        sql_create_func(sa, "second", "mtime", "seconds", FALSE, FALSE, 
SCALE_NONE, 0, INT, 1, DAYINT);
+       sql_create_func(sa, "epoch_ms", "mtime", "epoch_ms", FALSE, FALSE, 
SCALE_NONE, 0, LNG, 1, DAYINT);
        sql_create_func(sa, "day", "mtime", "day", FALSE, FALSE, SCALE_NONE, 0, 
LNG, 1, SECINT);
        sql_create_func(sa, "hour", "mtime", "hours", FALSE, FALSE, SCALE_NONE, 
0, INT, 1, SECINT);
        sql_create_func(sa, "minute", "mtime", "minutes", FALSE, FALSE, 
SCALE_NONE, 0, INT, 1, SECINT);
        sql_create_func(sa, "second", "mtime", "seconds", FALSE, FALSE, 
SCALE_NONE, 0, INT, 1, SECINT);
+       sql_create_func(sa, "epoch_ms", "mtime", "epoch_ms", FALSE, FALSE, 
SCALE_NONE, 0, LNG, 1, SECINT);
 
        for (t = strings; t < numerical; t++) {
                sql_create_func(sa, "next_value_for", "sql", "next_value", 
TRUE, TRUE, SCALE_NONE, 0, LNG, 2, *t, *t);
diff --git a/sql/scripts/51_sys_schema_extension.sql 
b/sql/scripts/51_sys_schema_extension.sql
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to