duckdb 0.7.1-dev7.0 → 0.7.1-dev90.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 +1 -1
- package/src/duckdb/extension/json/json_scan.cpp +2 -1
- 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/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/execution/operator/persistent/base_csv_reader.cpp +6 -11
- package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +4 -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/table/read_csv.cpp +2 -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 +2 -1
- 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/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/schema/physical_detach.hpp +32 -0
- 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/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/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/storage/storage_extension.hpp +7 -0
- package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -0
- package/src/duckdb/src/parser/statement/detach_statement.cpp +15 -0
- 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/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/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 +2 -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/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_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
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#include "duckdb/main/database.hpp"
|
|
4
4
|
#include "duckdb/parallel/task_scheduler.hpp"
|
|
5
5
|
#include "duckdb/storage/buffer_manager.hpp"
|
|
6
|
+
#include "duckdb/main/extension_helper.hpp"
|
|
6
7
|
|
|
7
8
|
namespace duckdb {
|
|
8
9
|
|
|
@@ -75,7 +76,7 @@ void JSONScanData::InitializeFilePaths(ClientContext &context, const vector<stri
|
|
|
75
76
|
for (auto &file_pattern : patterns) {
|
|
76
77
|
auto found_files = fs.Glob(file_pattern, context);
|
|
77
78
|
if (found_files.empty()) {
|
|
78
|
-
throw
|
|
79
|
+
throw FileSystem::MissingFileException(file_pattern, context);
|
|
79
80
|
}
|
|
80
81
|
file_paths.insert(file_paths.end(), found_files.begin(), found_files.end());
|
|
81
82
|
}
|
|
@@ -223,7 +223,7 @@ public:
|
|
|
223
223
|
FileSystem &fs = FileSystem::GetFileSystem(context);
|
|
224
224
|
auto files = fs.Glob(info.file_path, context);
|
|
225
225
|
if (files.empty()) {
|
|
226
|
-
throw
|
|
226
|
+
throw FileSystem::MissingFileException(info.file_path, context);
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
// The most likely path (Parquet read without union by name option)
|
|
@@ -363,8 +363,9 @@ public:
|
|
|
363
363
|
|
|
364
364
|
static vector<string> ParquetGlob(FileSystem &fs, const string &glob, ClientContext &context) {
|
|
365
365
|
auto files = fs.Glob(glob, FileSystem::GetFileOpener(context));
|
|
366
|
+
|
|
366
367
|
if (files.empty()) {
|
|
367
|
-
throw
|
|
368
|
+
throw FileSystem::MissingFileException(glob, context);
|
|
368
369
|
}
|
|
369
370
|
return files;
|
|
370
371
|
}
|
|
@@ -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
|
}
|
|
@@ -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) {
|
|
@@ -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);
|
|
@@ -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:
|
|
@@ -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
|
}
|
|
@@ -251,9 +252,6 @@ public:
|
|
|
251
252
|
: file_handle(std::move(file_handle_p)), system_threads(system_threads_p), buffer_size(buffer_size_p),
|
|
252
253
|
force_parallelism(force_parallelism_p) {
|
|
253
254
|
current_file_path = files_path_p[0];
|
|
254
|
-
for (idx_t i = 0; i < rows_to_skip; i++) {
|
|
255
|
-
file_handle->ReadLine();
|
|
256
|
-
}
|
|
257
255
|
estimated_linenr = rows_to_skip;
|
|
258
256
|
file_size = file_handle->FileSize();
|
|
259
257
|
first_file_size = file_size;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#ifndef DUCKDB_VERSION
|
|
2
|
-
#define DUCKDB_VERSION "0.7.1-
|
|
2
|
+
#define DUCKDB_VERSION "0.7.1-dev90"
|
|
3
3
|
#endif
|
|
4
4
|
#ifndef DUCKDB_SOURCE_ID
|
|
5
|
-
#define DUCKDB_SOURCE_ID "
|
|
5
|
+
#define DUCKDB_SOURCE_ID "1b87fb94ca"
|
|
6
6
|
#endif
|
|
7
7
|
#include "duckdb/function/table/system_functions.hpp"
|
|
8
8
|
#include "duckdb/main/database.hpp"
|
|
@@ -262,6 +262,16 @@ public:
|
|
|
262
262
|
}
|
|
263
263
|
};
|
|
264
264
|
|
|
265
|
+
class MissingExtensionException : public IOException {
|
|
266
|
+
public:
|
|
267
|
+
DUCKDB_API explicit MissingExtensionException(const string &msg);
|
|
268
|
+
|
|
269
|
+
template <typename... Args>
|
|
270
|
+
explicit MissingExtensionException(const string &msg, Args... params)
|
|
271
|
+
: IOException(ConstructMessage(msg, params...)) {
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
|
|
265
275
|
class SerializationException : public Exception {
|
|
266
276
|
public:
|
|
267
277
|
DUCKDB_API explicit SerializationException(const string &msg);
|
|
@@ -201,6 +201,7 @@ public:
|
|
|
201
201
|
|
|
202
202
|
//! Whether or not a sub-system can handle a specific file path
|
|
203
203
|
DUCKDB_API virtual bool CanHandleFile(const string &fpath);
|
|
204
|
+
DUCKDB_API static IOException MissingFileException(const string &file_path, ClientContext &context);
|
|
204
205
|
|
|
205
206
|
//! Set the file pointer of a file handle to a specified location. Reads and writes will happen from this location
|
|
206
207
|
DUCKDB_API virtual void Seek(FileHandle &handle, idx_t location);
|
|
@@ -93,6 +93,8 @@ struct timestamp_ns_t : public timestamp_t {}; // NOLINT
|
|
|
93
93
|
struct timestamp_ms_t : public timestamp_t {}; // NOLINT
|
|
94
94
|
struct timestamp_sec_t : public timestamp_t {}; // NOLINT
|
|
95
95
|
|
|
96
|
+
enum class TimestampCastResult : uint8_t { SUCCESS, ERROR_INCORRECT_FORMAT, ERROR_NON_UTC_TIMEZONE };
|
|
97
|
+
|
|
96
98
|
//! The Timestamp class is a static class that holds helper functions for the Timestamp
|
|
97
99
|
//! type.
|
|
98
100
|
class Timestamp {
|
|
@@ -110,7 +112,7 @@ public:
|
|
|
110
112
|
//! If the tz is not empty, the result is still an instant, but the parts can be extracted and applied to the TZ
|
|
111
113
|
DUCKDB_API static bool TryConvertTimestampTZ(const char *str, idx_t len, timestamp_t &result, bool &has_offset,
|
|
112
114
|
string_t &tz);
|
|
113
|
-
DUCKDB_API static
|
|
115
|
+
DUCKDB_API static TimestampCastResult TryConvertTimestamp(const char *str, idx_t len, timestamp_t &result);
|
|
114
116
|
DUCKDB_API static timestamp_t FromCString(const char *str, idx_t len);
|
|
115
117
|
//! Convert a date object to a string in the format "YYYY-MM-DD hh:mm:ss"
|
|
116
118
|
DUCKDB_API static string ToString(timestamp_t timestamp);
|
|
@@ -161,6 +163,8 @@ public:
|
|
|
161
163
|
|
|
162
164
|
DUCKDB_API static string ConversionError(const string &str);
|
|
163
165
|
DUCKDB_API static string ConversionError(string_t str);
|
|
166
|
+
DUCKDB_API static string UnsupportedTimezoneError(const string &str);
|
|
167
|
+
DUCKDB_API static string UnsupportedTimezoneError(string_t str);
|
|
164
168
|
};
|
|
165
169
|
|
|
166
170
|
} // namespace duckdb
|
|
@@ -35,11 +35,9 @@ class BaseCSVReader {
|
|
|
35
35
|
public:
|
|
36
36
|
BaseCSVReader(ClientContext &context, BufferedCSVReaderOptions options,
|
|
37
37
|
const vector<LogicalType> &requested_types = vector<LogicalType>());
|
|
38
|
-
|
|
39
|
-
BaseCSVReader(FileSystem &fs, Allocator &allocator, FileOpener *opener, BufferedCSVReaderOptions options,
|
|
40
|
-
const vector<LogicalType> &requested_types = vector<LogicalType>());
|
|
41
38
|
~BaseCSVReader();
|
|
42
39
|
|
|
40
|
+
ClientContext &context;
|
|
43
41
|
FileSystem &fs;
|
|
44
42
|
Allocator &allocator;
|
|
45
43
|
FileOpener *opener;
|
|
@@ -55,8 +55,6 @@ class BufferedCSVReader : public BaseCSVReader {
|
|
|
55
55
|
public:
|
|
56
56
|
BufferedCSVReader(ClientContext &context, BufferedCSVReaderOptions options,
|
|
57
57
|
const vector<LogicalType> &requested_types = vector<LogicalType>());
|
|
58
|
-
BufferedCSVReader(FileSystem &fs, Allocator &allocator, FileOpener *opener, BufferedCSVReaderOptions options,
|
|
59
|
-
const vector<LogicalType> &requested_types = vector<LogicalType>());
|
|
60
58
|
BufferedCSVReader(ClientContext &context, string filename, BufferedCSVReaderOptions options,
|
|
61
59
|
const vector<LogicalType> &requested_types = vector<LogicalType>());
|
|
62
60
|
~BufferedCSVReader();
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//===----------------------------------------------------------------------===//
|
|
2
|
+
// DuckDB
|
|
3
|
+
//
|
|
4
|
+
// duckdb/execution/operator/schema/physical_detach.hpp
|
|
5
|
+
//
|
|
6
|
+
//
|
|
7
|
+
//===----------------------------------------------------------------------===//
|
|
8
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
|
|
11
|
+
#include "duckdb/execution/physical_operator.hpp"
|
|
12
|
+
#include "duckdb/parser/parsed_data/detach_info.hpp"
|
|
13
|
+
|
|
14
|
+
namespace duckdb {
|
|
15
|
+
|
|
16
|
+
class PhysicalDetach : public PhysicalOperator {
|
|
17
|
+
public:
|
|
18
|
+
explicit PhysicalDetach(unique_ptr<DetachInfo> info, idx_t estimated_cardinality)
|
|
19
|
+
: PhysicalOperator(PhysicalOperatorType::DETACH, {LogicalType::BOOLEAN}, estimated_cardinality),
|
|
20
|
+
info(std::move(info)) {
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
unique_ptr<DetachInfo> info;
|
|
24
|
+
|
|
25
|
+
public:
|
|
26
|
+
// Source interface
|
|
27
|
+
unique_ptr<GlobalSourceState> GetGlobalSourceState(ClientContext &context) const override;
|
|
28
|
+
void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate,
|
|
29
|
+
LocalSourceState &lstate) const override;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
} // namespace duckdb
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
#include "duckdb/storage/compression/bitpacking.hpp"
|
|
26
26
|
#include "duckdb/function/cast/default_casts.hpp"
|
|
27
27
|
#include "duckdb/function/replacement_scan.hpp"
|
|
28
|
-
#include "duckdb/function/create_database_extension.hpp"
|
|
29
28
|
#include "duckdb/optimizer/optimizer_extension.hpp"
|
|
30
29
|
#include "duckdb/parser/parser_extension.hpp"
|
|
31
30
|
#include "duckdb/planner/operator_extension.hpp"
|
|
@@ -185,8 +184,6 @@ public:
|
|
|
185
184
|
vector<std::unique_ptr<OperatorExtension>> operator_extensions;
|
|
186
185
|
//! Extensions made to storage
|
|
187
186
|
case_insensitive_map_t<std::unique_ptr<StorageExtension>> storage_extensions;
|
|
188
|
-
//! Extensions made to binder to implement the create_database functionality
|
|
189
|
-
vector<CreateDatabaseExtension> create_database_extensions;
|
|
190
187
|
|
|
191
188
|
public:
|
|
192
189
|
DUCKDB_API static DBConfig &GetConfig(ClientContext &context);
|
|
@@ -16,9 +16,6 @@ struct CreateDatabaseInfo : public CreateInfo {
|
|
|
16
16
|
CreateDatabaseInfo() : CreateInfo(CatalogType::DATABASE_ENTRY) {
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
//! Extension name which creates databases
|
|
20
|
-
string extension_name;
|
|
21
|
-
|
|
22
19
|
//! Name of the database
|
|
23
20
|
string name;
|
|
24
21
|
|
|
@@ -29,7 +26,6 @@ public:
|
|
|
29
26
|
unique_ptr<CreateInfo> Copy() const override {
|
|
30
27
|
auto result = make_unique<CreateDatabaseInfo>();
|
|
31
28
|
CopyProperties(*result);
|
|
32
|
-
result->extension_name = extension_name;
|
|
33
29
|
result->name = name;
|
|
34
30
|
result->path = path;
|
|
35
31
|
return unique_ptr<CreateInfo>(result.release());
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//===----------------------------------------------------------------------===//
|
|
2
|
+
// DuckDB
|
|
3
|
+
//
|
|
4
|
+
// duckdb/parser/parsed_data/detach_info.hpp
|
|
5
|
+
//
|
|
6
|
+
//
|
|
7
|
+
//===----------------------------------------------------------------------===//
|
|
8
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
|
|
11
|
+
#include "duckdb/parser/parsed_data/parse_info.hpp"
|
|
12
|
+
|
|
13
|
+
namespace duckdb {
|
|
14
|
+
|
|
15
|
+
struct DetachInfo : public ParseInfo {
|
|
16
|
+
DetachInfo() {
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//! The alias of the attached database
|
|
20
|
+
string name;
|
|
21
|
+
//! Whether to throw an exception if alias is not found
|
|
22
|
+
bool if_exists;
|
|
23
|
+
|
|
24
|
+
public:
|
|
25
|
+
unique_ptr<DetachInfo> Copy() const {
|
|
26
|
+
auto result = make_unique<DetachInfo>();
|
|
27
|
+
result->name = name;
|
|
28
|
+
result->if_exists = if_exists;
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
} // namespace duckdb
|