duckdb 0.7.1-dev2.0 → 0.7.1-dev240.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/binding.gyp +7 -7
- package/package.json +1 -1
- package/src/duckdb/extension/json/buffered_json_reader.cpp +50 -9
- package/src/duckdb/extension/json/include/buffered_json_reader.hpp +7 -2
- package/src/duckdb/extension/json/include/json_common.hpp +2 -2
- package/src/duckdb/extension/json/include/json_scan.hpp +29 -10
- package/src/duckdb/extension/json/json_functions/copy_json.cpp +35 -22
- package/src/duckdb/extension/json/json_functions/json_create.cpp +8 -8
- package/src/duckdb/extension/json/json_functions/json_transform.cpp +47 -8
- package/src/duckdb/extension/json/json_functions/read_json.cpp +104 -49
- package/src/duckdb/extension/json/json_functions/read_json_objects.cpp +5 -3
- package/src/duckdb/extension/json/json_functions.cpp +6 -0
- package/src/duckdb/extension/json/json_scan.cpp +144 -34
- package/src/duckdb/extension/parquet/parquet-extension.cpp +3 -2
- package/src/duckdb/src/common/enums/logical_operator_type.cpp +2 -0
- package/src/duckdb/src/common/enums/physical_operator_type.cpp +2 -0
- package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
- package/src/duckdb/src/common/file_system.cpp +14 -0
- package/src/duckdb/src/common/hive_partitioning.cpp +1 -0
- package/src/duckdb/src/common/operator/cast_operators.cpp +14 -8
- package/src/duckdb/src/common/printer.cpp +1 -1
- package/src/duckdb/src/common/types/time.cpp +1 -1
- package/src/duckdb/src/common/types/timestamp.cpp +35 -4
- package/src/duckdb/src/common/types.cpp +36 -10
- package/src/duckdb/src/execution/column_binding_resolver.cpp +5 -2
- package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +7 -9
- package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +6 -11
- package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +13 -13
- package/src/duckdb/src/execution/operator/persistent/parallel_csv_reader.cpp +1 -1
- package/src/duckdb/src/execution/operator/schema/physical_detach.cpp +37 -0
- package/src/duckdb/src/execution/operator/schema/physical_drop.cpp +0 -5
- package/src/duckdb/src/execution/physical_plan/plan_simple.cpp +4 -0
- package/src/duckdb/src/execution/physical_plan_generator.cpp +1 -0
- package/src/duckdb/src/function/pragma/pragma_queries.cpp +36 -9
- package/src/duckdb/src/function/table/read_csv.cpp +15 -4
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/common/enums/logical_operator_type.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/enums/physical_operator_type.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +3 -2
- package/src/duckdb/src/include/duckdb/common/exception.hpp +10 -0
- package/src/duckdb/src/include/duckdb/common/file_system.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/hive_partitioning.hpp +9 -1
- package/src/duckdb/src/include/duckdb/common/radix_partitioning.hpp +4 -4
- package/src/duckdb/src/include/duckdb/common/types/timestamp.hpp +5 -1
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/base_csv_reader.hpp +1 -3
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/buffered_csv_reader.hpp +0 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +2 -0
- package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_detach.hpp +32 -0
- package/src/duckdb/src/include/duckdb/main/client_data.hpp +2 -2
- package/src/duckdb/src/include/duckdb/main/config.hpp +0 -3
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_database_info.hpp +0 -4
- package/src/duckdb/src/include/duckdb/parser/parsed_data/detach_info.hpp +32 -0
- package/src/duckdb/src/include/duckdb/parser/query_node/select_node.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/sql_statement.hpp +2 -2
- package/src/duckdb/src/include/duckdb/parser/statement/copy_statement.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/statement/detach_statement.hpp +29 -0
- package/src/duckdb/src/include/duckdb/parser/statement/list.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/statement/select_statement.hpp +3 -3
- package/src/duckdb/src/include/duckdb/parser/tableref/subqueryref.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/tokens.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/transformer.hpp +1 -0
- package/src/duckdb/src/include/duckdb/planner/binder.hpp +1 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_execute.hpp +1 -5
- package/src/duckdb/src/include/duckdb/planner/operator/logical_show.hpp +1 -2
- package/src/duckdb/src/include/duckdb/storage/storage_extension.hpp +7 -0
- package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -0
- package/src/duckdb/src/main/client_context.cpp +2 -0
- package/src/duckdb/src/main/extension/extension_alias.cpp +2 -1
- package/src/duckdb/src/optimizer/statistics/operator/propagate_join.cpp +2 -6
- package/src/duckdb/src/parser/statement/copy_statement.cpp +2 -13
- package/src/duckdb/src/parser/statement/delete_statement.cpp +3 -0
- package/src/duckdb/src/parser/statement/detach_statement.cpp +15 -0
- package/src/duckdb/src/parser/statement/insert_statement.cpp +9 -0
- package/src/duckdb/src/parser/statement/update_statement.cpp +3 -0
- package/src/duckdb/src/parser/transform/expression/transform_case.cpp +3 -3
- package/src/duckdb/src/parser/transform/statement/transform_create_database.cpp +0 -1
- package/src/duckdb/src/parser/transform/statement/transform_detach.cpp +19 -0
- package/src/duckdb/src/parser/transformer.cpp +2 -0
- package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +3 -0
- package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +6 -3
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +16 -14
- package/src/duckdb/src/planner/binder/statement/bind_detach.cpp +19 -0
- package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +29 -4
- package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +22 -1
- package/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp +2 -1
- package/src/duckdb/src/planner/binder.cpp +2 -0
- package/src/duckdb/src/planner/expression_binder/lateral_binder.cpp +21 -5
- package/src/duckdb/src/planner/logical_operator.cpp +4 -0
- package/src/duckdb/src/planner/planner.cpp +1 -0
- package/src/duckdb/src/storage/storage_info.cpp +2 -1
- package/src/duckdb/src/storage/table/column_data.cpp +4 -2
- package/src/duckdb/src/storage/table/update_segment.cpp +15 -0
- package/src/duckdb/third_party/fmt/include/fmt/core.h +1 -2
- package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +1 -0
- package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +14 -0
- package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +530 -1006
- package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +17659 -17626
- package/src/duckdb/third_party/thrift/thrift/Thrift.h +8 -2
- package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
- package/src/duckdb/ub_src_execution_operator_schema.cpp +2 -0
- package/src/duckdb/ub_src_parser_statement.cpp +2 -0
- package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
- package/src/duckdb/ub_src_planner_binder_statement.cpp +2 -0
- package/src/duckdb/src/include/duckdb/function/create_database_extension.hpp +0 -37
|
@@ -100,6 +100,8 @@ string LogicalOperatorToString(LogicalOperatorType type) {
|
|
|
100
100
|
return "CREATE_SCHEMA";
|
|
101
101
|
case LogicalOperatorType::LOGICAL_ATTACH:
|
|
102
102
|
return "ATTACH";
|
|
103
|
+
case LogicalOperatorType::LOGICAL_DETACH:
|
|
104
|
+
return "ATTACH";
|
|
103
105
|
case LogicalOperatorType::LOGICAL_DROP:
|
|
104
106
|
return "DROP";
|
|
105
107
|
case LogicalOperatorType::LOGICAL_PRAGMA:
|
|
@@ -133,6 +133,8 @@ string PhysicalOperatorToString(PhysicalOperatorType type) {
|
|
|
133
133
|
return "CREATE_TYPE";
|
|
134
134
|
case PhysicalOperatorType::ATTACH:
|
|
135
135
|
return "ATTACH";
|
|
136
|
+
case PhysicalOperatorType::DETACH:
|
|
137
|
+
return "DETACH";
|
|
136
138
|
case PhysicalOperatorType::RESULT_COLLECTOR:
|
|
137
139
|
return "RESULT_COLLECTOR";
|
|
138
140
|
case PhysicalOperatorType::EXTENSION:
|
|
@@ -335,6 +335,20 @@ bool FileSystem::CanHandleFile(const string &fpath) {
|
|
|
335
335
|
throw NotImplementedException("%s: CanHandleFile is not implemented!", GetName());
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
+
IOException FileSystem::MissingFileException(const string &file_path, ClientContext &context) {
|
|
339
|
+
const string prefixes[] = {"http://", "https://", "s3://"};
|
|
340
|
+
for (auto &prefix : prefixes) {
|
|
341
|
+
if (StringUtil::StartsWith(file_path, prefix)) {
|
|
342
|
+
if (!context.db->LoadedExtensions().count("httpfs")) {
|
|
343
|
+
return MissingExtensionException("No files found that match the pattern \"%s\", because the httpfs "
|
|
344
|
+
"extension is not loaded. Try loading the extension: LOAD HTTPFS",
|
|
345
|
+
file_path);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return IOException("No files found that match the pattern \"%s\"", file_path);
|
|
350
|
+
}
|
|
351
|
+
|
|
338
352
|
void FileSystem::Seek(FileHandle &handle, idx_t location) {
|
|
339
353
|
throw NotImplementedException("%s: Seek is not implemented!", GetName());
|
|
340
354
|
}
|
|
@@ -150,6 +150,7 @@ HivePartitionedColumnData::HivePartitionedColumnData(const HivePartitionedColumn
|
|
|
150
150
|
void HivePartitionedColumnData::ComputePartitionIndices(PartitionedColumnDataAppendState &state, DataChunk &input) {
|
|
151
151
|
Vector hashes(LogicalType::HASH, input.size());
|
|
152
152
|
input.Hash(group_by_columns, hashes);
|
|
153
|
+
hashes.Flatten(input.size());
|
|
153
154
|
|
|
154
155
|
for (idx_t i = 0; i < input.size(); i++) {
|
|
155
156
|
HivePartitionKey key;
|
|
@@ -946,13 +946,13 @@ static bool IntegerCastLoop(const char *buf, idx_t len, T &result, bool strict)
|
|
|
946
946
|
ExponentData exponent {0, false};
|
|
947
947
|
int negative = buf[pos] == '-';
|
|
948
948
|
if (negative) {
|
|
949
|
-
if (!IntegerCastLoop<ExponentData, true, false, IntegerCastOperation>(
|
|
950
|
-
|
|
949
|
+
if (!IntegerCastLoop<ExponentData, true, false, IntegerCastOperation, decimal_separator>(
|
|
950
|
+
buf + pos, len - pos, exponent, strict)) {
|
|
951
951
|
return false;
|
|
952
952
|
}
|
|
953
953
|
} else {
|
|
954
|
-
if (!IntegerCastLoop<ExponentData, false, false, IntegerCastOperation>(
|
|
955
|
-
|
|
954
|
+
if (!IntegerCastLoop<ExponentData, false, false, IntegerCastOperation, decimal_separator>(
|
|
955
|
+
buf + pos, len - pos, exponent, strict)) {
|
|
956
956
|
return false;
|
|
957
957
|
}
|
|
958
958
|
}
|
|
@@ -1554,16 +1554,22 @@ dtime_t Cast::Operation(string_t input) {
|
|
|
1554
1554
|
//===--------------------------------------------------------------------===//
|
|
1555
1555
|
template <>
|
|
1556
1556
|
bool TryCastErrorMessage::Operation(string_t input, timestamp_t &result, string *error_message, bool strict) {
|
|
1557
|
-
|
|
1557
|
+
auto cast_result = Timestamp::TryConvertTimestamp(input.GetDataUnsafe(), input.GetSize(), result);
|
|
1558
|
+
if (cast_result == TimestampCastResult::SUCCESS) {
|
|
1559
|
+
return true;
|
|
1560
|
+
}
|
|
1561
|
+
if (cast_result == TimestampCastResult::ERROR_INCORRECT_FORMAT) {
|
|
1558
1562
|
HandleCastError::AssignError(Timestamp::ConversionError(input), error_message);
|
|
1559
|
-
|
|
1563
|
+
} else {
|
|
1564
|
+
HandleCastError::AssignError(Timestamp::UnsupportedTimezoneError(input), error_message);
|
|
1560
1565
|
}
|
|
1561
|
-
return
|
|
1566
|
+
return false;
|
|
1562
1567
|
}
|
|
1563
1568
|
|
|
1564
1569
|
template <>
|
|
1565
1570
|
bool TryCast::Operation(string_t input, timestamp_t &result, bool strict) {
|
|
1566
|
-
return Timestamp::TryConvertTimestamp(input.GetDataUnsafe(), input.GetSize(), result)
|
|
1571
|
+
return Timestamp::TryConvertTimestamp(input.GetDataUnsafe(), input.GetSize(), result) ==
|
|
1572
|
+
TimestampCastResult::SUCCESS;
|
|
1567
1573
|
}
|
|
1568
1574
|
|
|
1569
1575
|
template <>
|
|
@@ -65,7 +65,7 @@ idx_t Printer::TerminalWidth() {
|
|
|
65
65
|
int columns, rows;
|
|
66
66
|
|
|
67
67
|
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
|
|
68
|
-
rows = csbi.srWindow.
|
|
68
|
+
rows = csbi.srWindow.Right - csbi.srWindow.Left + 1;
|
|
69
69
|
return rows;
|
|
70
70
|
#else
|
|
71
71
|
struct winsize w;
|
|
@@ -115,7 +115,7 @@ bool Time::TryConvertTime(const char *buf, idx_t len, idx_t &pos, dtime_t &resul
|
|
|
115
115
|
if (!strict) {
|
|
116
116
|
// last chance, check if we can parse as timestamp
|
|
117
117
|
timestamp_t timestamp;
|
|
118
|
-
if (Timestamp::TryConvertTimestamp(buf, len, timestamp)) {
|
|
118
|
+
if (Timestamp::TryConvertTimestamp(buf, len, timestamp) == TimestampCastResult::SUCCESS) {
|
|
119
119
|
if (!Timestamp::IsFinite(timestamp)) {
|
|
120
120
|
return false;
|
|
121
121
|
}
|
|
@@ -88,11 +88,27 @@ bool Timestamp::TryConvertTimestampTZ(const char *str, idx_t len, timestamp_t &r
|
|
|
88
88
|
return true;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
TimestampCastResult Timestamp::TryConvertTimestamp(const char *str, idx_t len, timestamp_t &result) {
|
|
92
92
|
string_t tz(nullptr, 0);
|
|
93
93
|
bool has_offset = false;
|
|
94
94
|
// We don't understand TZ without an extension, so fail if one was provided.
|
|
95
|
-
|
|
95
|
+
auto success = TryConvertTimestampTZ(str, len, result, has_offset, tz);
|
|
96
|
+
if (!success) {
|
|
97
|
+
return TimestampCastResult::ERROR_INCORRECT_FORMAT;
|
|
98
|
+
}
|
|
99
|
+
if (tz.GetSize() == 0) {
|
|
100
|
+
// no timezone provided - success!
|
|
101
|
+
return TimestampCastResult::SUCCESS;
|
|
102
|
+
}
|
|
103
|
+
if (tz.GetSize() == 3) {
|
|
104
|
+
// we can ONLY handle UTC without ICU being loaded
|
|
105
|
+
auto tz_ptr = tz.GetDataUnsafe();
|
|
106
|
+
if ((tz_ptr[0] == 'u' || tz_ptr[0] == 'U') && (tz_ptr[1] == 't' || tz_ptr[1] == 'T') &&
|
|
107
|
+
(tz_ptr[2] == 'c' || tz_ptr[2] == 'C')) {
|
|
108
|
+
return TimestampCastResult::SUCCESS;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return TimestampCastResult::ERROR_NON_UTC_TIMEZONE;
|
|
96
112
|
}
|
|
97
113
|
|
|
98
114
|
string Timestamp::ConversionError(const string &str) {
|
|
@@ -101,16 +117,31 @@ string Timestamp::ConversionError(const string &str) {
|
|
|
101
117
|
str);
|
|
102
118
|
}
|
|
103
119
|
|
|
120
|
+
string Timestamp::UnsupportedTimezoneError(const string &str) {
|
|
121
|
+
return StringUtil::Format("timestamp field value \"%s\" has a timestamp that is not UTC.\nUse the TIMESTAMPTZ type "
|
|
122
|
+
"with the ICU extension loaded to handle non-UTC timestamps.",
|
|
123
|
+
str);
|
|
124
|
+
}
|
|
125
|
+
|
|
104
126
|
string Timestamp::ConversionError(string_t str) {
|
|
105
127
|
return Timestamp::ConversionError(str.GetString());
|
|
106
128
|
}
|
|
107
129
|
|
|
130
|
+
string Timestamp::UnsupportedTimezoneError(string_t str) {
|
|
131
|
+
return Timestamp::UnsupportedTimezoneError(str.GetString());
|
|
132
|
+
}
|
|
133
|
+
|
|
108
134
|
timestamp_t Timestamp::FromCString(const char *str, idx_t len) {
|
|
109
135
|
timestamp_t result;
|
|
110
|
-
|
|
136
|
+
auto cast_result = Timestamp::TryConvertTimestamp(str, len, result);
|
|
137
|
+
if (cast_result == TimestampCastResult::SUCCESS) {
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
if (cast_result == TimestampCastResult::ERROR_NON_UTC_TIMEZONE) {
|
|
141
|
+
throw ConversionException(Timestamp::UnsupportedTimezoneError(string(str, len)));
|
|
142
|
+
} else {
|
|
111
143
|
throw ConversionException(Timestamp::ConversionError(string(str, len)));
|
|
112
144
|
}
|
|
113
|
-
return result;
|
|
114
145
|
}
|
|
115
146
|
|
|
116
147
|
bool Timestamp::TryParseUTCOffset(const char *str, idx_t &pos, idx_t len, int &hour_offset, int &minute_offset) {
|
|
@@ -504,11 +504,32 @@ LogicalType TransformStringToLogicalType(const string &str) {
|
|
|
504
504
|
return Parser::ParseColumnList("dummy " + str).GetColumn(LogicalIndex(0)).Type();
|
|
505
505
|
}
|
|
506
506
|
|
|
507
|
+
LogicalType GetUserTypeRecursive(const LogicalType &type, ClientContext &context) {
|
|
508
|
+
if (type.id() == LogicalTypeId::USER && type.HasAlias()) {
|
|
509
|
+
return Catalog::GetSystemCatalog(context).GetType(context, SYSTEM_CATALOG, DEFAULT_SCHEMA, type.GetAlias());
|
|
510
|
+
}
|
|
511
|
+
// Look for LogicalTypeId::USER in nested types
|
|
512
|
+
if (type.id() == LogicalTypeId::STRUCT) {
|
|
513
|
+
child_list_t<LogicalType> children;
|
|
514
|
+
children.reserve(StructType::GetChildCount(type));
|
|
515
|
+
for (auto &child : StructType::GetChildTypes(type)) {
|
|
516
|
+
children.emplace_back(child.first, GetUserTypeRecursive(child.second, context));
|
|
517
|
+
}
|
|
518
|
+
return LogicalType::STRUCT(std::move(children));
|
|
519
|
+
}
|
|
520
|
+
if (type.id() == LogicalTypeId::LIST) {
|
|
521
|
+
return LogicalType::LIST(GetUserTypeRecursive(ListType::GetChildType(type), context));
|
|
522
|
+
}
|
|
523
|
+
if (type.id() == LogicalTypeId::MAP) {
|
|
524
|
+
return LogicalType::MAP(GetUserTypeRecursive(MapType::KeyType(type), context),
|
|
525
|
+
GetUserTypeRecursive(MapType::ValueType(type), context));
|
|
526
|
+
}
|
|
527
|
+
// Not LogicalTypeId::USER or a nested type
|
|
528
|
+
return type;
|
|
529
|
+
}
|
|
530
|
+
|
|
507
531
|
LogicalType TransformStringToLogicalType(const string &str, ClientContext &context) {
|
|
508
|
-
|
|
509
|
-
return type.id() == LogicalTypeId::USER
|
|
510
|
-
? Catalog::GetSystemCatalog(context).GetType(context, SYSTEM_CATALOG, DEFAULT_SCHEMA, str)
|
|
511
|
-
: type;
|
|
532
|
+
return GetUserTypeRecursive(TransformStringToLogicalType(str), context);
|
|
512
533
|
}
|
|
513
534
|
|
|
514
535
|
bool LogicalType::IsIntegral() const {
|
|
@@ -888,18 +909,23 @@ void LogicalType::SetAlias(string alias) {
|
|
|
888
909
|
}
|
|
889
910
|
|
|
890
911
|
string LogicalType::GetAlias() const {
|
|
891
|
-
if (
|
|
892
|
-
return
|
|
893
|
-
}
|
|
912
|
+
if (id() == LogicalTypeId::USER) {
|
|
913
|
+
return UserType::GetTypeName(*this);
|
|
914
|
+
}
|
|
915
|
+
if (type_info_) {
|
|
894
916
|
return type_info_->alias;
|
|
895
917
|
}
|
|
918
|
+
return string();
|
|
896
919
|
}
|
|
897
920
|
|
|
898
921
|
bool LogicalType::HasAlias() const {
|
|
899
|
-
if (
|
|
900
|
-
return
|
|
922
|
+
if (id() == LogicalTypeId::USER) {
|
|
923
|
+
return !UserType::GetTypeName(*this).empty();
|
|
924
|
+
}
|
|
925
|
+
if (type_info_ && !type_info_->alias.empty()) {
|
|
926
|
+
return true;
|
|
901
927
|
}
|
|
902
|
-
return
|
|
928
|
+
return false;
|
|
903
929
|
}
|
|
904
930
|
|
|
905
931
|
void LogicalType::SetCatalog(LogicalType &type, TypeCatalogEntry *catalog_entry) {
|
|
@@ -65,9 +65,12 @@ void ColumnBindingResolver::VisitOperator(LogicalOperator &op) {
|
|
|
65
65
|
// ON CONFLICT DO UPDATE clause
|
|
66
66
|
auto &insert_op = (LogicalInsert &)op;
|
|
67
67
|
if (insert_op.action_type != OnConflictAction::THROW) {
|
|
68
|
+
// Get the bindings from the children
|
|
68
69
|
VisitOperatorChildren(op);
|
|
69
|
-
auto
|
|
70
|
-
|
|
70
|
+
auto column_count = insert_op.table->GetColumns().PhysicalColumnCount();
|
|
71
|
+
auto dummy_bindings = LogicalOperator::GenerateColumnBindings(insert_op.excluded_table_index, column_count);
|
|
72
|
+
// Now insert our dummy bindings at the start of the bindings,
|
|
73
|
+
// so the first 'column_count' indices of the chunk are reserved for our 'excluded' columns
|
|
71
74
|
bindings.insert(bindings.begin(), dummy_bindings.begin(), dummy_bindings.end());
|
|
72
75
|
if (insert_op.on_conflict_condition) {
|
|
73
76
|
VisitExpression(&insert_op.on_conflict_condition);
|
|
@@ -664,6 +664,7 @@ public:
|
|
|
664
664
|
if (!matches[outer_idx]) {
|
|
665
665
|
true_sel.set_index(count++, outer_idx);
|
|
666
666
|
if (count >= STANDARD_VECTOR_SIZE) {
|
|
667
|
+
outer_idx++;
|
|
667
668
|
break;
|
|
668
669
|
}
|
|
669
670
|
}
|
|
@@ -847,8 +848,6 @@ public:
|
|
|
847
848
|
|
|
848
849
|
lstate.joiner = make_unique<IEJoinUnion>(client, op, left_table, b1, right_table, b2);
|
|
849
850
|
return;
|
|
850
|
-
} else {
|
|
851
|
-
--next_pair;
|
|
852
851
|
}
|
|
853
852
|
|
|
854
853
|
// Outer joins
|
|
@@ -864,6 +863,7 @@ public:
|
|
|
864
863
|
// Left outer blocks
|
|
865
864
|
const auto l = next_left++;
|
|
866
865
|
if (l < left_outers) {
|
|
866
|
+
lstate.joiner = nullptr;
|
|
867
867
|
lstate.left_block_index = l;
|
|
868
868
|
lstate.left_base = left_bases[l];
|
|
869
869
|
|
|
@@ -873,12 +873,12 @@ public:
|
|
|
873
873
|
return;
|
|
874
874
|
} else {
|
|
875
875
|
lstate.left_matches = nullptr;
|
|
876
|
-
--next_left;
|
|
877
876
|
}
|
|
878
877
|
|
|
879
878
|
// Right outer block
|
|
880
879
|
const auto r = next_right++;
|
|
881
880
|
if (r < right_outers) {
|
|
881
|
+
lstate.joiner = nullptr;
|
|
882
882
|
lstate.right_block_index = r;
|
|
883
883
|
lstate.right_base = right_bases[r];
|
|
884
884
|
|
|
@@ -888,7 +888,6 @@ public:
|
|
|
888
888
|
return;
|
|
889
889
|
} else {
|
|
890
890
|
lstate.right_matches = nullptr;
|
|
891
|
-
--next_right;
|
|
892
891
|
}
|
|
893
892
|
}
|
|
894
893
|
|
|
@@ -936,7 +935,7 @@ void PhysicalIEJoin::GetData(ExecutionContext &context, DataChunk &result, Globa
|
|
|
936
935
|
|
|
937
936
|
ie_gstate.Initialize(ie_sink);
|
|
938
937
|
|
|
939
|
-
if (!ie_lstate.joiner) {
|
|
938
|
+
if (!ie_lstate.joiner && !ie_lstate.left_matches && !ie_lstate.right_matches) {
|
|
940
939
|
ie_gstate.GetNextPair(context.client, ie_sink, ie_lstate);
|
|
941
940
|
}
|
|
942
941
|
|
|
@@ -959,8 +958,7 @@ void PhysicalIEJoin::GetData(ExecutionContext &context, DataChunk &result, Globa
|
|
|
959
958
|
ie_gstate.GetNextPair(context.client, ie_sink, ie_lstate);
|
|
960
959
|
continue;
|
|
961
960
|
}
|
|
962
|
-
|
|
963
|
-
SliceSortedPayload(result, ie_sink.tables[0]->global_sort_state, ie_lstate.left_base, ie_lstate.true_sel,
|
|
961
|
+
SliceSortedPayload(result, ie_sink.tables[0]->global_sort_state, ie_lstate.left_block_index, ie_lstate.true_sel,
|
|
964
962
|
count);
|
|
965
963
|
|
|
966
964
|
// Fill in NULLs to the right
|
|
@@ -983,8 +981,8 @@ void PhysicalIEJoin::GetData(ExecutionContext &context, DataChunk &result, Globa
|
|
|
983
981
|
continue;
|
|
984
982
|
}
|
|
985
983
|
|
|
986
|
-
SliceSortedPayload(result, ie_sink.tables[1]->global_sort_state, ie_lstate.
|
|
987
|
-
count, left_cols);
|
|
984
|
+
SliceSortedPayload(result, ie_sink.tables[1]->global_sort_state, ie_lstate.right_block_index,
|
|
985
|
+
ie_lstate.true_sel, count, left_cols);
|
|
988
986
|
|
|
989
987
|
// Fill in NULLs to the left
|
|
990
988
|
for (idx_t col_idx = 0; col_idx < left_cols; ++col_idx) {
|
|
@@ -30,15 +30,10 @@ string BaseCSVReader::GetLineNumberStr(idx_t linenr, bool linenr_estimated) {
|
|
|
30
30
|
return to_string(linenr + 1) + estimated;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
BaseCSVReader::BaseCSVReader(
|
|
34
|
-
BufferedCSVReaderOptions options_p, const vector<LogicalType> &requested_types)
|
|
35
|
-
: fs(fs_p), allocator(allocator), opener(opener_p), options(std::move(options_p)) {
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
BaseCSVReader::BaseCSVReader(ClientContext &context, BufferedCSVReaderOptions options_p,
|
|
33
|
+
BaseCSVReader::BaseCSVReader(ClientContext &context_p, BufferedCSVReaderOptions options_p,
|
|
39
34
|
const vector<LogicalType> &requested_types)
|
|
40
|
-
:
|
|
41
|
-
|
|
35
|
+
: context(context_p), fs(FileSystem::GetFileSystem(context)), allocator(Allocator::Get(context)),
|
|
36
|
+
opener(FileSystem::GetFileOpener(context)), options(std::move(options_p)) {
|
|
42
37
|
}
|
|
43
38
|
|
|
44
39
|
BaseCSVReader::~BaseCSVReader() {
|
|
@@ -144,7 +139,7 @@ bool BaseCSVReader::TryCastValue(const Value &value, const LogicalType &sql_type
|
|
|
144
139
|
} else {
|
|
145
140
|
Value new_value;
|
|
146
141
|
string error_message;
|
|
147
|
-
return value.
|
|
142
|
+
return value.TryCastAs(context, sql_type, new_value, &error_message, true);
|
|
148
143
|
}
|
|
149
144
|
}
|
|
150
145
|
|
|
@@ -481,8 +476,8 @@ bool BaseCSVReader::Flush(DataChunk &insert_chunk, bool try_add_line) {
|
|
|
481
476
|
error_message, return_types[col_idx]);
|
|
482
477
|
} else {
|
|
483
478
|
// target type is not varchar: perform a cast
|
|
484
|
-
success = VectorOperations::
|
|
485
|
-
|
|
479
|
+
success = VectorOperations::TryCast(context, parse_chunk.data[col_idx], insert_chunk.data[insert_idx],
|
|
480
|
+
parse_chunk.size(), &error_message);
|
|
486
481
|
}
|
|
487
482
|
if (success) {
|
|
488
483
|
continue;
|
|
@@ -23,25 +23,16 @@
|
|
|
23
23
|
|
|
24
24
|
namespace duckdb {
|
|
25
25
|
|
|
26
|
-
BufferedCSVReader::BufferedCSVReader(FileSystem &fs_p, Allocator &allocator, FileOpener *opener_p,
|
|
27
|
-
BufferedCSVReaderOptions options_p, const vector<LogicalType> &requested_types)
|
|
28
|
-
: BaseCSVReader(fs_p, allocator, opener_p, std::move(options_p), requested_types), buffer_size(0), position(0),
|
|
29
|
-
start(0) {
|
|
30
|
-
file_handle = OpenCSV(options);
|
|
31
|
-
Initialize(requested_types);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
26
|
BufferedCSVReader::BufferedCSVReader(ClientContext &context, BufferedCSVReaderOptions options_p,
|
|
35
27
|
const vector<LogicalType> &requested_types)
|
|
36
|
-
:
|
|
37
|
-
|
|
28
|
+
: BaseCSVReader(context, std::move(options_p), requested_types), buffer_size(0), position(0), start(0) {
|
|
29
|
+
file_handle = OpenCSV(options);
|
|
30
|
+
Initialize(requested_types);
|
|
38
31
|
}
|
|
39
32
|
|
|
40
33
|
BufferedCSVReader::BufferedCSVReader(ClientContext &context, string filename, BufferedCSVReaderOptions options_p,
|
|
41
34
|
const vector<LogicalType> &requested_types)
|
|
42
|
-
: BaseCSVReader(
|
|
43
|
-
std::move(options_p), requested_types),
|
|
44
|
-
buffer_size(0), position(0), start(0) {
|
|
35
|
+
: BaseCSVReader(context, std::move(options_p), requested_types), buffer_size(0), position(0), start(0) {
|
|
45
36
|
options.file_path = std::move(filename);
|
|
46
37
|
file_handle = OpenCSV(options);
|
|
47
38
|
Initialize(requested_types);
|
|
@@ -730,6 +721,9 @@ void BufferedCSVReader::DetectHeader(const vector<vector<LogicalType>> &best_sql
|
|
|
730
721
|
names.push_back(column_name);
|
|
731
722
|
}
|
|
732
723
|
}
|
|
724
|
+
for (idx_t i = 0; i < MinValue<idx_t>(names.size(), options.name_list.size()); i++) {
|
|
725
|
+
names[i] = options.name_list[i];
|
|
726
|
+
}
|
|
733
727
|
}
|
|
734
728
|
|
|
735
729
|
vector<LogicalType> BufferedCSVReader::RefineTypeDetection(const vector<LogicalType> &type_candidates,
|
|
@@ -899,6 +893,12 @@ vector<LogicalType> BufferedCSVReader::SniffCSV(const vector<LogicalType> &reque
|
|
|
899
893
|
DetectCandidateTypes(type_candidates, format_template_candidates, info_candidates, original_options, best_num_cols,
|
|
900
894
|
best_sql_types_candidates, best_format_candidates, best_header_row);
|
|
901
895
|
|
|
896
|
+
if (best_format_candidates.empty() || best_header_row.size() == 0) {
|
|
897
|
+
throw InvalidInputException(
|
|
898
|
+
"Error in file \"%s\": CSV options could not be auto-detected. Consider setting parser options manually.",
|
|
899
|
+
original_options.file_path);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
902
|
// #######
|
|
903
903
|
// ### header detection
|
|
904
904
|
// #######
|
|
@@ -60,7 +60,7 @@ bool ParallelCSVReader::SetPosition(DataChunk &insert_chunk) {
|
|
|
60
60
|
verification_positions.end_of_last_line = position_buffer;
|
|
61
61
|
// First buffer doesn't need any setting
|
|
62
62
|
// Unless we have a header
|
|
63
|
-
if (options.header
|
|
63
|
+
if (options.header) {
|
|
64
64
|
for (; position_buffer < end_buffer; position_buffer++) {
|
|
65
65
|
if (StringUtil::CharacterIsNewline((*buffer)[position_buffer])) {
|
|
66
66
|
bool carrier_return = (*buffer)[position_buffer] == '\r';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#include "duckdb/execution/operator/schema/physical_detach.hpp"
|
|
2
|
+
#include "duckdb/parser/parsed_data/detach_info.hpp"
|
|
3
|
+
#include "duckdb/catalog/catalog.hpp"
|
|
4
|
+
#include "duckdb/main/database_manager.hpp"
|
|
5
|
+
#include "duckdb/main/attached_database.hpp"
|
|
6
|
+
#include "duckdb/main/database.hpp"
|
|
7
|
+
#include "duckdb/storage/storage_extension.hpp"
|
|
8
|
+
|
|
9
|
+
namespace duckdb {
|
|
10
|
+
|
|
11
|
+
//===--------------------------------------------------------------------===//
|
|
12
|
+
// Source
|
|
13
|
+
//===--------------------------------------------------------------------===//
|
|
14
|
+
class DetachSourceState : public GlobalSourceState {
|
|
15
|
+
public:
|
|
16
|
+
DetachSourceState() : finished(false) {
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
bool finished;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
unique_ptr<GlobalSourceState> PhysicalDetach::GetGlobalSourceState(ClientContext &context) const {
|
|
23
|
+
return make_unique<DetachSourceState>();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
void PhysicalDetach::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate,
|
|
27
|
+
LocalSourceState &lstate) const {
|
|
28
|
+
auto &state = (DetachSourceState &)gstate;
|
|
29
|
+
if (state.finished) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
auto &db_manager = DatabaseManager::Get(context.client);
|
|
33
|
+
db_manager.DetachDatabase(context.client, info->name, info->if_exists);
|
|
34
|
+
state.finished = true;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
} // namespace duckdb
|
|
@@ -38,11 +38,6 @@ void PhysicalDrop::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSo
|
|
|
38
38
|
}
|
|
39
39
|
break;
|
|
40
40
|
}
|
|
41
|
-
case CatalogType::DATABASE_ENTRY: {
|
|
42
|
-
auto &db_manager = DatabaseManager::Get(context.client);
|
|
43
|
-
db_manager.DetachDatabase(context.client, info->name, info->if_exists);
|
|
44
|
-
break;
|
|
45
|
-
}
|
|
46
41
|
case CatalogType::SCHEMA_ENTRY: {
|
|
47
42
|
auto &catalog = Catalog::GetCatalog(context.client, info->catalog);
|
|
48
43
|
catalog.DropEntry(context.client, info.get());
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
#include "duckdb/execution/operator/schema/physical_create_schema.hpp"
|
|
7
7
|
#include "duckdb/execution/operator/schema/physical_create_sequence.hpp"
|
|
8
8
|
#include "duckdb/execution/operator/schema/physical_create_view.hpp"
|
|
9
|
+
#include "duckdb/execution/operator/schema/physical_detach.hpp"
|
|
9
10
|
#include "duckdb/execution/operator/schema/physical_drop.hpp"
|
|
10
11
|
#include "duckdb/execution/physical_plan_generator.hpp"
|
|
11
12
|
#include "duckdb/planner/logical_operator.hpp"
|
|
@@ -39,6 +40,9 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalSimple &op
|
|
|
39
40
|
case LogicalOperatorType::LOGICAL_ATTACH:
|
|
40
41
|
return make_unique<PhysicalAttach>(unique_ptr_cast<ParseInfo, AttachInfo>(std::move(op.info)),
|
|
41
42
|
op.estimated_cardinality);
|
|
43
|
+
case LogicalOperatorType::LOGICAL_DETACH:
|
|
44
|
+
return make_unique<PhysicalDetach>(unique_ptr_cast<ParseInfo, DetachInfo>(std::move(op.info)),
|
|
45
|
+
op.estimated_cardinality);
|
|
42
46
|
default:
|
|
43
47
|
throw NotImplementedException("Unimplemented type for logical simple operator");
|
|
44
48
|
}
|
|
@@ -184,6 +184,7 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalOperator &
|
|
|
184
184
|
case LogicalOperatorType::LOGICAL_VACUUM:
|
|
185
185
|
case LogicalOperatorType::LOGICAL_LOAD:
|
|
186
186
|
case LogicalOperatorType::LOGICAL_ATTACH:
|
|
187
|
+
case LogicalOperatorType::LOGICAL_DETACH:
|
|
187
188
|
plan = CreatePlan((LogicalSimple &)op);
|
|
188
189
|
break;
|
|
189
190
|
case LogicalOperatorType::LOGICAL_RECURSIVE_CTE:
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
#include "duckdb/
|
|
2
|
-
#include "duckdb/common/string_util.hpp"
|
|
1
|
+
#include "duckdb/common/constants.hpp"
|
|
3
2
|
#include "duckdb/common/file_system.hpp"
|
|
4
|
-
#include "duckdb/
|
|
5
|
-
#include "duckdb/
|
|
6
|
-
#include "duckdb/parser/parser.hpp"
|
|
3
|
+
#include "duckdb/common/string_util.hpp"
|
|
4
|
+
#include "duckdb/function/pragma/pragma_functions.hpp"
|
|
7
5
|
#include "duckdb/main/config.hpp"
|
|
6
|
+
#include "duckdb/parser/parser.hpp"
|
|
7
|
+
#include "duckdb/parser/qualified_name.hpp"
|
|
8
|
+
#include "duckdb/parser/statement/copy_statement.hpp"
|
|
9
|
+
#include "duckdb/parser/statement/export_statement.hpp"
|
|
8
10
|
|
|
9
11
|
namespace duckdb {
|
|
10
12
|
|
|
@@ -58,10 +60,35 @@ string PragmaFunctionsQuery(ClientContext &context, const FunctionParameters &pa
|
|
|
58
60
|
|
|
59
61
|
string PragmaShow(ClientContext &context, const FunctionParameters ¶meters) {
|
|
60
62
|
// PRAGMA table_info but with some aliases
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
auto table = QualifiedName::Parse(parameters.values[0].ToString());
|
|
64
|
+
|
|
65
|
+
// clang-format off
|
|
66
|
+
string sql = R"(
|
|
67
|
+
SELECT
|
|
68
|
+
name AS "column_name",
|
|
69
|
+
type as "column_type",
|
|
70
|
+
CASE WHEN "notnull" THEN 'NO' ELSE 'YES' END AS "null",
|
|
71
|
+
(SELECT
|
|
72
|
+
MIN(CASE
|
|
73
|
+
WHEN constraint_type='PRIMARY KEY' THEN 'PRI'
|
|
74
|
+
WHEN constraint_type='UNIQUE' THEN 'UNI'
|
|
75
|
+
ELSE NULL END)
|
|
76
|
+
FROM duckdb_constraints() c
|
|
77
|
+
WHERE c.table_oid=cols.table_oid
|
|
78
|
+
AND list_contains(constraint_column_names, cols.column_name)) AS "key",
|
|
79
|
+
dflt_value AS "default",
|
|
80
|
+
NULL AS "extra"
|
|
81
|
+
FROM pragma_table_info('%func_param_table%')
|
|
82
|
+
LEFT JOIN duckdb_columns cols
|
|
83
|
+
ON cols.column_name = pragma_table_info.name
|
|
84
|
+
AND cols.table_name='%table_name%'
|
|
85
|
+
AND cols.schema_name='%table_schema%';)";
|
|
86
|
+
// clang-format on
|
|
87
|
+
|
|
88
|
+
sql = StringUtil::Replace(sql, "%func_param_table%", parameters.values[0].ToString());
|
|
89
|
+
sql = StringUtil::Replace(sql, "%table_name%", table.name);
|
|
90
|
+
sql = StringUtil::Replace(sql, "%table_schema%", table.schema.empty() ? DEFAULT_SCHEMA : table.schema);
|
|
91
|
+
return sql;
|
|
65
92
|
}
|
|
66
93
|
|
|
67
94
|
string PragmaVersion(ClientContext &context, const FunctionParameters ¶meters) {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
#include "duckdb/parser/expression/function_expression.hpp"
|
|
11
11
|
#include "duckdb/parser/tableref/table_function_ref.hpp"
|
|
12
12
|
#include "duckdb/planner/operator/logical_get.hpp"
|
|
13
|
+
#include "duckdb/main/extension_helper.hpp"
|
|
13
14
|
|
|
14
15
|
#include <limits>
|
|
15
16
|
|
|
@@ -29,7 +30,7 @@ void ReadCSVData::InitializeFiles(ClientContext &context, const vector<string> &
|
|
|
29
30
|
for (auto &file_pattern : patterns) {
|
|
30
31
|
auto found_files = fs.Glob(file_pattern, context);
|
|
31
32
|
if (found_files.empty()) {
|
|
32
|
-
throw
|
|
33
|
+
throw FileSystem::MissingFileException(file_pattern, context);
|
|
33
34
|
}
|
|
34
35
|
files.insert(files.end(), found_files.begin(), found_files.end());
|
|
35
36
|
}
|
|
@@ -98,6 +99,17 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, TableFunctio
|
|
|
98
99
|
if (names.empty()) {
|
|
99
100
|
throw BinderException("read_csv requires at least a single column as input!");
|
|
100
101
|
}
|
|
102
|
+
} else if (loption == "column_names" || loption == "names") {
|
|
103
|
+
if (!options.name_list.empty()) {
|
|
104
|
+
throw BinderException("read_csv_auto column_names/names can only be supplied once");
|
|
105
|
+
}
|
|
106
|
+
if (kv.second.IsNull()) {
|
|
107
|
+
throw BinderException("read_csv_auto %s cannot be NULL", kv.first);
|
|
108
|
+
}
|
|
109
|
+
auto &children = ListValue::GetChildren(kv.second);
|
|
110
|
+
for (auto &child : children) {
|
|
111
|
+
options.name_list.push_back(StringValue::Get(child));
|
|
112
|
+
}
|
|
101
113
|
} else if (loption == "column_types" || loption == "types" || loption == "dtypes") {
|
|
102
114
|
auto &child_type = kv.second.type();
|
|
103
115
|
if (child_type.id() != LogicalTypeId::STRUCT && child_type.id() != LogicalTypeId::LIST) {
|
|
@@ -251,9 +263,6 @@ public:
|
|
|
251
263
|
: file_handle(std::move(file_handle_p)), system_threads(system_threads_p), buffer_size(buffer_size_p),
|
|
252
264
|
force_parallelism(force_parallelism_p) {
|
|
253
265
|
current_file_path = files_path_p[0];
|
|
254
|
-
for (idx_t i = 0; i < rows_to_skip; i++) {
|
|
255
|
-
file_handle->ReadLine();
|
|
256
|
-
}
|
|
257
266
|
estimated_linenr = rows_to_skip;
|
|
258
267
|
file_size = file_handle->FileSize();
|
|
259
268
|
first_file_size = file_size;
|
|
@@ -963,6 +972,8 @@ TableFunction ReadCSVTableFunction::GetAutoFunction(bool list_parameter) {
|
|
|
963
972
|
read_csv_auto.named_parameters["column_types"] = LogicalType::ANY;
|
|
964
973
|
read_csv_auto.named_parameters["dtypes"] = LogicalType::ANY;
|
|
965
974
|
read_csv_auto.named_parameters["types"] = LogicalType::ANY;
|
|
975
|
+
read_csv_auto.named_parameters["names"] = LogicalType::LIST(LogicalType::VARCHAR);
|
|
976
|
+
read_csv_auto.named_parameters["column_names"] = LogicalType::LIST(LogicalType::VARCHAR);
|
|
966
977
|
return read_csv_auto;
|
|
967
978
|
}
|
|
968
979
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#ifndef DUCKDB_VERSION
|
|
2
|
-
#define DUCKDB_VERSION "0.7.1-
|
|
2
|
+
#define DUCKDB_VERSION "0.7.1-dev240"
|
|
3
3
|
#endif
|
|
4
4
|
#ifndef DUCKDB_SOURCE_ID
|
|
5
|
-
#define DUCKDB_SOURCE_ID "
|
|
5
|
+
#define DUCKDB_SOURCE_ID "661b09da10"
|
|
6
6
|
#endif
|
|
7
7
|
#include "duckdb/function/table/system_functions.hpp"
|
|
8
8
|
#include "duckdb/main/database.hpp"
|