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
|
@@ -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
|
|
89
|
-
static inline timestamp_t Operation(icu::Calendar *calendar, timestamp_t
|
|
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(
|
|
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 ¶meters) {
|
|
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
|
|
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(
|
|
131
|
-
throw ConversionException("Unable to
|
|
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
|
|
143
|
-
if (!Timestamp::TryFromDatetime(local_date, local_time,
|
|
144
|
-
throw ConversionException("Unable to
|
|
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
|
|
185
|
+
return naive;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
static bool CastToNaive(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) {
|
|
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
|
|
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>(
|
|
248
|
-
|
|
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<
|
|
331
|
+
Execute<ICUFromNaiveTimestamp>, Bind));
|
|
272
332
|
set.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::TIMESTAMP_TZ}, LogicalType::TIMESTAMP,
|
|
273
|
-
Execute<
|
|
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
|
|
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 =
|
|
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-
|
|
2
|
+
#define DUCKDB_VERSION "0.6.2-dev910"
|
|
3
3
|
#endif
|
|
4
4
|
#ifndef DUCKDB_SOURCE_ID
|
|
5
|
-
#define DUCKDB_SOURCE_ID "
|
|
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,
|