duckdb 0.6.2-dev904.0 → 0.6.2-dev910.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
4
  "types": "./lib/duckdb.d.ts",
5
- "version": "0.6.2-dev904.0",
5
+ "version": "0.6.2-dev910.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
@@ -1,6 +1,7 @@
1
1
  #include "duckdb/common/types/date.hpp"
2
2
  #include "duckdb/common/types/time.hpp"
3
3
  #include "duckdb/common/types/timestamp.hpp"
4
+ #include "duckdb/function/cast/cast_function_set.hpp"
4
5
  #include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
5
6
  #include "duckdb/parser/parsed_data/create_table_function_info.hpp"
6
7
  #include "include/icu-datefunc.hpp"
@@ -85,12 +86,16 @@ static void ICUTimeZoneFunction(ClientContext &context, TableFunctionInput &data
85
86
  output.SetCardinality(index);
86
87
  }
87
88
 
88
- struct ICUFromLocalTimestamp : public ICUDateFunc {
89
- static inline timestamp_t Operation(icu::Calendar *calendar, timestamp_t local) {
89
+ struct ICUFromNaiveTimestamp : public ICUDateFunc {
90
+ static inline timestamp_t Operation(icu::Calendar *calendar, timestamp_t naive) {
91
+ if (!Timestamp::IsFinite(naive)) {
92
+ return naive;
93
+ }
94
+
90
95
  // Extract the parts from the "instant"
91
96
  date_t local_date;
92
97
  dtime_t local_time;
93
- Timestamp::Convert(local, local_date, local_time);
98
+ Timestamp::Convert(naive, local_date, local_time);
94
99
 
95
100
  int32_t year;
96
101
  int32_t mm;
@@ -116,19 +121,52 @@ struct ICUFromLocalTimestamp : public ICUDateFunc {
116
121
 
117
122
  return GetTime(calendar, micros);
118
123
  }
124
+
125
+ static bool CastFromNaive(Vector &source, Vector &result, idx_t count, CastParameters &parameters) {
126
+ auto &cast_data = (CastData &)*parameters.cast_data;
127
+ auto info = (BindData *)cast_data.info.get();
128
+ CalendarPtr calendar(info->calendar->clone());
129
+
130
+ UnaryExecutor::Execute<timestamp_t, timestamp_t>(
131
+ source, result, count, [&](timestamp_t input) { return Operation(calendar.get(), input); });
132
+ return true;
133
+ }
134
+
135
+ static BoundCastInfo BindCastFromNaive(BindCastInput &input, const LogicalType &source, const LogicalType &target) {
136
+ if (!input.context) {
137
+ throw InternalException("Missing context for TIMESTAMP to TIMESTAMPTZ cast.");
138
+ }
139
+
140
+ auto cast_data = make_unique<CastData>(make_unique<BindData>(*input.context));
141
+
142
+ return BoundCastInfo(CastFromNaive, move(cast_data));
143
+ }
144
+
145
+ static void AddCasts(ClientContext &context) {
146
+ auto &config = DBConfig::GetConfig(context);
147
+ auto &casts = config.GetCastFunctions();
148
+
149
+ casts.RegisterCastFunction(LogicalType::TIMESTAMP, LogicalType::TIMESTAMP_TZ, BindCastFromNaive);
150
+ }
119
151
  };
120
152
 
121
- struct ICUToLocalTimestamp : public ICUDateFunc {
153
+ struct ICUToNaiveTimestamp : public ICUDateFunc {
122
154
  static inline timestamp_t Operation(icu::Calendar *calendar, timestamp_t instant) {
155
+ if (!Timestamp::IsFinite(instant)) {
156
+ return instant;
157
+ }
158
+
123
159
  // Extract the time zone parts
124
160
  auto micros = SetTime(calendar, instant);
161
+ const auto era = ExtractField(calendar, UCAL_ERA);
125
162
  const auto year = ExtractField(calendar, UCAL_YEAR);
126
163
  const auto mm = ExtractField(calendar, UCAL_MONTH) + 1;
127
164
  const auto dd = ExtractField(calendar, UCAL_DATE);
128
165
 
166
+ const auto yyyy = era ? year : (-year + 1);
129
167
  date_t local_date;
130
- if (!Date::TryFromDate(year, mm, dd, local_date)) {
131
- throw ConversionException("Unable to create local date in TIMEZONE function");
168
+ if (!Date::TryFromDate(yyyy, mm, dd, local_date)) {
169
+ throw ConversionException("Unable to convert TIMESTAMPTZ to local date");
132
170
  }
133
171
 
134
172
  const auto hr = ExtractField(calendar, UCAL_HOUR_OF_DAY);
@@ -139,12 +177,39 @@ struct ICUToLocalTimestamp : public ICUDateFunc {
139
177
  micros += millis * Interval::MICROS_PER_MSEC;
140
178
  dtime_t local_time = Time::FromTime(hr, mn, secs, micros);
141
179
 
142
- timestamp_t result;
143
- if (!Timestamp::TryFromDatetime(local_date, local_time, result)) {
144
- throw ConversionException("Unable to create local timestamp in TIMEZONE function");
180
+ timestamp_t naive;
181
+ if (!Timestamp::TryFromDatetime(local_date, local_time, naive)) {
182
+ throw ConversionException("Unable to convert TIMESTAMPTZ to local TIMESTAMP");
145
183
  }
146
184
 
147
- return result;
185
+ return naive;
186
+ }
187
+
188
+ static bool CastToNaive(Vector &source, Vector &result, idx_t count, CastParameters &parameters) {
189
+ auto &cast_data = (CastData &)*parameters.cast_data;
190
+ auto info = (BindData *)cast_data.info.get();
191
+ CalendarPtr calendar(info->calendar->clone());
192
+
193
+ UnaryExecutor::Execute<timestamp_t, timestamp_t>(
194
+ source, result, count, [&](timestamp_t input) { return Operation(calendar.get(), input); });
195
+ return true;
196
+ }
197
+
198
+ static BoundCastInfo BindCastToNaive(BindCastInput &input, const LogicalType &source, const LogicalType &target) {
199
+ if (!input.context) {
200
+ throw InternalException("Missing context for TIMESTAMPTZ to TIMESTAMP cast.");
201
+ }
202
+
203
+ auto cast_data = make_unique<CastData>(make_unique<BindData>(*input.context));
204
+
205
+ return BoundCastInfo(CastToNaive, move(cast_data));
206
+ }
207
+
208
+ static void AddCasts(ClientContext &context) {
209
+ auto &config = DBConfig::GetConfig(context);
210
+ auto &casts = config.GetCastFunctions();
211
+
212
+ casts.RegisterCastFunction(LogicalType::TIMESTAMP_TZ, LogicalType::TIMESTAMP, BindCastToNaive);
148
213
  }
149
214
  };
150
215
 
@@ -186,7 +251,7 @@ struct ICULocalTimestampFunc : public ICUDateFunc {
186
251
  auto calendar = calendar_ptr.get();
187
252
 
188
253
  const auto now = info.now;
189
- return ICUToLocalTimestamp::Operation(calendar, now);
254
+ return ICUToNaiveTimestamp::Operation(calendar, now);
190
255
  }
191
256
 
192
257
  static void Execute(DataChunk &input, ExpressionState &state, Vector &result) {
@@ -244,13 +309,8 @@ struct ICUTimeZoneFunc : public ICUDateFunc {
244
309
  ConstantVector::SetNull(result, true);
245
310
  } else {
246
311
  SetTimeZone(calendar, *ConstantVector::GetData<string_t>(tz_vec));
247
- UnaryExecutor::Execute<timestamp_t, timestamp_t>(ts_vec, result, input.size(), [&](timestamp_t ts) {
248
- if (Timestamp::IsFinite(ts)) {
249
- return OP::Operation(calendar, ts);
250
- } else {
251
- return ts;
252
- }
253
- });
312
+ UnaryExecutor::Execute<timestamp_t, timestamp_t>(
313
+ ts_vec, result, input.size(), [&](timestamp_t ts) { return OP::Operation(calendar, ts); });
254
314
  }
255
315
  } else {
256
316
  BinaryExecutor::Execute<string_t, timestamp_t, timestamp_t>(tz_vec, ts_vec, result, input.size(),
@@ -268,9 +328,9 @@ struct ICUTimeZoneFunc : public ICUDateFunc {
268
328
  static void AddFunction(const string &name, ClientContext &context) {
269
329
  ScalarFunctionSet set(name);
270
330
  set.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::TIMESTAMP}, LogicalType::TIMESTAMP_TZ,
271
- Execute<ICUFromLocalTimestamp>, Bind));
331
+ Execute<ICUFromNaiveTimestamp>, Bind));
272
332
  set.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::TIMESTAMP_TZ}, LogicalType::TIMESTAMP,
273
- Execute<ICUToLocalTimestamp>, Bind));
333
+ Execute<ICUToNaiveTimestamp>, Bind));
274
334
 
275
335
  CreateScalarFunctionInfo func_info(set);
276
336
  auto &catalog = Catalog::GetSystemCatalog(context);
@@ -279,14 +339,20 @@ struct ICUTimeZoneFunc : public ICUDateFunc {
279
339
  };
280
340
 
281
341
  void RegisterICUTimeZoneFunctions(ClientContext &context) {
342
+ // Table functions
282
343
  auto &catalog = Catalog::GetSystemCatalog(context);
283
344
  TableFunction tz_names("pg_timezone_names", {}, ICUTimeZoneFunction, ICUTimeZoneBind, ICUTimeZoneInit);
284
345
  CreateTableFunctionInfo tz_names_info(move(tz_names));
285
346
  catalog.CreateTableFunction(context, &tz_names_info);
286
347
 
348
+ // Scalar functions
287
349
  ICUTimeZoneFunc::AddFunction("timezone", context);
288
350
  ICULocalTimestampFunc::AddFunction("current_localtimestamp", context);
289
351
  ICULocalTimeFunc::AddFunction("current_localtime", context);
352
+
353
+ // Casts
354
+ ICUFromNaiveTimestamp::AddCasts(context);
355
+ ICUToNaiveTimestamp::AddCasts(context);
290
356
  }
291
357
 
292
358
  } // namespace duckdb
@@ -58,7 +58,7 @@ int Comparators::CompareVal(const data_ptr_t l_ptr, const data_ptr_t r_ptr, cons
58
58
  case PhysicalType::STRUCT: {
59
59
  auto l_nested_ptr = Load<data_ptr_t>(l_ptr);
60
60
  auto r_nested_ptr = Load<data_ptr_t>(r_ptr);
61
- return CompareValAndAdvance(l_nested_ptr, r_nested_ptr, type);
61
+ return CompareValAndAdvance(l_nested_ptr, r_nested_ptr, type, true);
62
62
  }
63
63
  default:
64
64
  throw NotImplementedException("Unimplemented CompareVal for type %s", type.ToString());
@@ -113,7 +113,7 @@ int Comparators::TemplatedCompareVal(const data_ptr_t &left_ptr, const data_ptr_
113
113
  }
114
114
  }
115
115
 
116
- int Comparators::CompareValAndAdvance(data_ptr_t &l_ptr, data_ptr_t &r_ptr, const LogicalType &type) {
116
+ int Comparators::CompareValAndAdvance(data_ptr_t &l_ptr, data_ptr_t &r_ptr, const LogicalType &type, bool valid) {
117
117
  switch (type.InternalType()) {
118
118
  case PhysicalType::BOOL:
119
119
  case PhysicalType::INT8:
@@ -141,11 +141,11 @@ int Comparators::CompareValAndAdvance(data_ptr_t &l_ptr, data_ptr_t &r_ptr, cons
141
141
  case PhysicalType::INTERVAL:
142
142
  return TemplatedCompareAndAdvance<interval_t>(l_ptr, r_ptr);
143
143
  case PhysicalType::VARCHAR:
144
- return CompareStringAndAdvance(l_ptr, r_ptr);
144
+ return CompareStringAndAdvance(l_ptr, r_ptr, valid);
145
145
  case PhysicalType::LIST:
146
- return CompareListAndAdvance(l_ptr, r_ptr, ListType::GetChildType(type));
146
+ return CompareListAndAdvance(l_ptr, r_ptr, ListType::GetChildType(type), valid);
147
147
  case PhysicalType::STRUCT:
148
- return CompareStructAndAdvance(l_ptr, r_ptr, StructType::GetChildTypes(type));
148
+ return CompareStructAndAdvance(l_ptr, r_ptr, StructType::GetChildTypes(type), valid);
149
149
  default:
150
150
  throw NotImplementedException("Unimplemented CompareValAndAdvance for type %s", type.ToString());
151
151
  }
@@ -159,7 +159,10 @@ int Comparators::TemplatedCompareAndAdvance(data_ptr_t &left_ptr, data_ptr_t &ri
159
159
  return result;
160
160
  }
161
161
 
162
- int Comparators::CompareStringAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr) {
162
+ int Comparators::CompareStringAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, bool valid) {
163
+ if (!valid) {
164
+ return 0;
165
+ }
163
166
  // Construct the string_t
164
167
  uint32_t left_string_size = Load<uint32_t>(left_ptr);
165
168
  uint32_t right_string_size = Load<uint32_t>(right_ptr);
@@ -174,7 +177,7 @@ int Comparators::CompareStringAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right
174
177
  }
175
178
 
176
179
  int Comparators::CompareStructAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr,
177
- const child_list_t<LogicalType> &types) {
180
+ const child_list_t<LogicalType> &types, bool valid) {
178
181
  idx_t count = types.size();
179
182
  // Load validity masks
180
183
  ValidityBytes left_validity(left_ptr);
@@ -193,8 +196,8 @@ int Comparators::CompareStructAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right
193
196
  left_valid = left_validity.RowIsValid(left_validity.GetValidityEntry(entry_idx), idx_in_entry);
194
197
  right_valid = right_validity.RowIsValid(right_validity.GetValidityEntry(entry_idx), idx_in_entry);
195
198
  auto &type = types[i].second;
196
- if ((left_valid && right_valid) || TypeIsConstantSize(type.InternalType())) {
197
- comp_res = CompareValAndAdvance(left_ptr, right_ptr, types[i].second);
199
+ if ((left_valid == right_valid) || TypeIsConstantSize(type.InternalType())) {
200
+ comp_res = CompareValAndAdvance(left_ptr, right_ptr, types[i].second, left_valid && valid);
198
201
  }
199
202
  if (!left_valid && !right_valid) {
200
203
  comp_res = 0;
@@ -210,7 +213,11 @@ int Comparators::CompareStructAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right
210
213
  return comp_res;
211
214
  }
212
215
 
213
- int Comparators::CompareListAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, const LogicalType &type) {
216
+ int Comparators::CompareListAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, const LogicalType &type,
217
+ bool valid) {
218
+ if (!valid) {
219
+ return 0;
220
+ }
214
221
  // Load list lengths
215
222
  auto left_len = Load<idx_t>(left_ptr);
216
223
  auto right_len = Load<idx_t>(right_ptr);
@@ -284,13 +291,14 @@ int Comparators::CompareListAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_p
284
291
  if (left_valid && right_valid) {
285
292
  switch (type.InternalType()) {
286
293
  case PhysicalType::LIST:
287
- comp_res = CompareListAndAdvance(left_ptr, right_ptr, ListType::GetChildType(type));
294
+ comp_res = CompareListAndAdvance(left_ptr, right_ptr, ListType::GetChildType(type), left_valid);
288
295
  break;
289
296
  case PhysicalType::VARCHAR:
290
- comp_res = CompareStringAndAdvance(left_ptr, right_ptr);
297
+ comp_res = CompareStringAndAdvance(left_ptr, right_ptr, left_valid);
291
298
  break;
292
299
  case PhysicalType::STRUCT:
293
- comp_res = CompareStructAndAdvance(left_ptr, right_ptr, StructType::GetChildTypes(type));
300
+ comp_res =
301
+ CompareStructAndAdvance(left_ptr, right_ptr, StructType::GetChildTypes(type), left_valid);
294
302
  break;
295
303
  default:
296
304
  throw NotImplementedException("CompareListAndAdvance for variable-size type %s", type.ToString());
@@ -1,8 +1,8 @@
1
1
  #ifndef DUCKDB_VERSION
2
- #define DUCKDB_VERSION "0.6.2-dev904"
2
+ #define DUCKDB_VERSION "0.6.2-dev910"
3
3
  #endif
4
4
  #ifndef DUCKDB_SOURCE_ID
5
- #define DUCKDB_SOURCE_ID "b844a10312"
5
+ #define DUCKDB_SOURCE_ID "e74e2471a5"
6
6
  #endif
7
7
  #include "duckdb/function/table/system_functions.hpp"
8
8
  #include "duckdb/main/database.hpp"
@@ -38,17 +38,17 @@ private:
38
38
  static int TemplatedCompareVal(const data_ptr_t &left_ptr, const data_ptr_t &right_ptr);
39
39
 
40
40
  //! Compare two values at the pointers (can be recursive if nested type)
41
- static int CompareValAndAdvance(data_ptr_t &l_ptr, data_ptr_t &r_ptr, const LogicalType &type);
41
+ static int CompareValAndAdvance(data_ptr_t &l_ptr, data_ptr_t &r_ptr, const LogicalType &type, bool valid);
42
42
  //! Compares two fixed-size values at the given pointers
43
43
  template <class T>
44
44
  static int TemplatedCompareAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr);
45
45
  //! Compares two string values at the given pointers
46
- static int CompareStringAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr);
46
+ static int CompareStringAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, bool valid);
47
47
  //! Compares two struct values at the given pointers (recursive)
48
48
  static int CompareStructAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr,
49
- const child_list_t<LogicalType> &types);
49
+ const child_list_t<LogicalType> &types, bool valid);
50
50
  //! Compare two list values at the pointers (can be recursive if nested type)
51
- static int CompareListAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, const LogicalType &type);
51
+ static int CompareListAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, const LogicalType &type, bool valid);
52
52
  //! Compares a list of fixed-size values
53
53
  template <class T>
54
54
  static int TemplatedCompareListLoop(data_ptr_t &left_ptr, data_ptr_t &right_ptr, const ValidityBytes &left_validity,