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.
Files changed (64) hide show
  1. package/package.json +1 -1
  2. package/src/duckdb/extension/json/json_scan.cpp +2 -1
  3. package/src/duckdb/extension/parquet/parquet-extension.cpp +3 -2
  4. package/src/duckdb/src/common/enums/logical_operator_type.cpp +2 -0
  5. package/src/duckdb/src/common/enums/physical_operator_type.cpp +2 -0
  6. package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
  7. package/src/duckdb/src/common/file_system.cpp +14 -0
  8. package/src/duckdb/src/common/operator/cast_operators.cpp +14 -8
  9. package/src/duckdb/src/common/printer.cpp +1 -1
  10. package/src/duckdb/src/common/types/time.cpp +1 -1
  11. package/src/duckdb/src/common/types/timestamp.cpp +35 -4
  12. package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +6 -11
  13. package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +4 -13
  14. package/src/duckdb/src/execution/operator/persistent/parallel_csv_reader.cpp +1 -1
  15. package/src/duckdb/src/execution/operator/schema/physical_detach.cpp +37 -0
  16. package/src/duckdb/src/execution/operator/schema/physical_drop.cpp +0 -5
  17. package/src/duckdb/src/execution/physical_plan/plan_simple.cpp +4 -0
  18. package/src/duckdb/src/execution/physical_plan_generator.cpp +1 -0
  19. package/src/duckdb/src/function/table/read_csv.cpp +2 -4
  20. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  21. package/src/duckdb/src/include/duckdb/common/enums/logical_operator_type.hpp +1 -0
  22. package/src/duckdb/src/include/duckdb/common/enums/physical_operator_type.hpp +1 -0
  23. package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +2 -1
  24. package/src/duckdb/src/include/duckdb/common/exception.hpp +10 -0
  25. package/src/duckdb/src/include/duckdb/common/file_system.hpp +1 -0
  26. package/src/duckdb/src/include/duckdb/common/types/timestamp.hpp +5 -1
  27. package/src/duckdb/src/include/duckdb/execution/operator/persistent/base_csv_reader.hpp +1 -3
  28. package/src/duckdb/src/include/duckdb/execution/operator/persistent/buffered_csv_reader.hpp +0 -2
  29. package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_detach.hpp +32 -0
  30. package/src/duckdb/src/include/duckdb/main/config.hpp +0 -3
  31. package/src/duckdb/src/include/duckdb/parser/parsed_data/create_database_info.hpp +0 -4
  32. package/src/duckdb/src/include/duckdb/parser/parsed_data/detach_info.hpp +32 -0
  33. package/src/duckdb/src/include/duckdb/parser/statement/detach_statement.hpp +29 -0
  34. package/src/duckdb/src/include/duckdb/parser/statement/list.hpp +1 -0
  35. package/src/duckdb/src/include/duckdb/parser/tokens.hpp +1 -0
  36. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +1 -0
  37. package/src/duckdb/src/include/duckdb/planner/binder.hpp +1 -0
  38. package/src/duckdb/src/include/duckdb/storage/storage_extension.hpp +7 -0
  39. package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -0
  40. package/src/duckdb/src/parser/statement/detach_statement.cpp +15 -0
  41. package/src/duckdb/src/parser/transform/statement/transform_create_database.cpp +0 -1
  42. package/src/duckdb/src/parser/transform/statement/transform_detach.cpp +19 -0
  43. package/src/duckdb/src/parser/transformer.cpp +2 -0
  44. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +16 -14
  45. package/src/duckdb/src/planner/binder/statement/bind_detach.cpp +19 -0
  46. package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +29 -4
  47. package/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp +2 -1
  48. package/src/duckdb/src/planner/binder.cpp +2 -0
  49. package/src/duckdb/src/planner/expression_binder/lateral_binder.cpp +21 -5
  50. package/src/duckdb/src/planner/logical_operator.cpp +2 -0
  51. package/src/duckdb/src/planner/planner.cpp +1 -0
  52. package/src/duckdb/src/storage/storage_info.cpp +2 -1
  53. package/src/duckdb/src/storage/table/column_data.cpp +4 -2
  54. package/src/duckdb/src/storage/table/update_segment.cpp +15 -0
  55. package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +1 -0
  56. package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +14 -0
  57. package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +530 -1006
  58. package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +17659 -17626
  59. package/src/duckdb/third_party/thrift/thrift/Thrift.h +8 -2
  60. package/src/duckdb/ub_src_execution_operator_schema.cpp +2 -0
  61. package/src/duckdb/ub_src_parser_statement.cpp +2 -0
  62. package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
  63. package/src/duckdb/ub_src_planner_binder_statement.cpp +2 -0
  64. package/src/duckdb/src/include/duckdb/function/create_database_extension.hpp +0 -37
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.7.1-dev7.0",
5
+ "version": "0.7.1-dev90.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
@@ -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 IOException("No files found that match the pattern \"%s\"", file_pattern);
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 IOException("No files found that match the pattern \"%s\"", info.file_path);
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 IOException("No files found that match the pattern \"%s\"", glob);
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:
@@ -57,6 +57,8 @@ string StatementTypeToString(StatementType type) {
57
57
  return "LOGICAL_PLAN";
58
58
  case StatementType::ATTACH_STATEMENT:
59
59
  return "ATTACH";
60
+ case StatementType::DETACH_STATEMENT:
61
+ return "DETACH";
60
62
  case StatementType::INVALID_STATEMENT:
61
63
  break;
62
64
  }
@@ -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>(buf + pos, len - pos,
950
- exponent, strict)) {
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>(buf + pos, len - pos,
955
- exponent, strict)) {
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
- if (!TryCast::Operation<string_t, timestamp_t>(input, result, strict)) {
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
- return false;
1563
+ } else {
1564
+ HandleCastError::AssignError(Timestamp::UnsupportedTimezoneError(input), error_message);
1560
1565
  }
1561
- return true;
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.Bottom - csbi.srWindow.Top + 1;
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
- bool Timestamp::TryConvertTimestamp(const char *str, idx_t len, timestamp_t &result) {
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
- return TryConvertTimestampTZ(str, len, result, has_offset, tz) && !tz.GetSize();
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
- if (!Timestamp::TryConvertTimestamp(str, len, result)) {
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(FileSystem &fs_p, Allocator &allocator, FileOpener *opener_p,
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
- : BaseCSVReader(FileSystem::GetFileSystem(context), Allocator::Get(context), FileSystem::GetFileOpener(context),
41
- std::move(options_p), requested_types) {
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.DefaultTryCastAs(sql_type, new_value, &error_message, true);
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::DefaultTryCast(parse_chunk.data[col_idx], insert_chunk.data[insert_idx],
485
- parse_chunk.size(), &error_message);
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
- : BufferedCSVReader(FileSystem::GetFileSystem(context), Allocator::Get(context), FileSystem::GetFileOpener(context),
37
- std::move(options_p), requested_types) {
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(FileSystem::GetFileSystem(context), Allocator::Get(context), FileSystem::GetFileOpener(context),
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 && options.auto_detect) {
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 IOException("No files found that match the pattern \"%s\"", file_pattern);
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-dev7"
2
+ #define DUCKDB_VERSION "0.7.1-dev90"
3
3
  #endif
4
4
  #ifndef DUCKDB_SOURCE_ID
5
- #define DUCKDB_SOURCE_ID "05803a9db2"
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"
@@ -79,6 +79,7 @@ enum class LogicalOperatorType : uint8_t {
79
79
  LOGICAL_TRANSACTION = 134,
80
80
  LOGICAL_CREATE_TYPE = 135,
81
81
  LOGICAL_ATTACH = 136,
82
+ LOGICAL_DETACH = 137,
82
83
 
83
84
  // -----------------------------
84
85
  // Explain
@@ -87,6 +87,7 @@ enum class PhysicalOperatorType : uint8_t {
87
87
  TRANSACTION,
88
88
  CREATE_TYPE,
89
89
  ATTACH,
90
+ DETACH,
90
91
 
91
92
  // -----------------------------
92
93
  // Helpers
@@ -43,7 +43,8 @@ enum class StatementType : uint8_t {
43
43
  RELATION_STATEMENT,
44
44
  EXTENSION_STATEMENT,
45
45
  LOGICAL_PLAN_STATEMENT,
46
- ATTACH_STATEMENT
46
+ ATTACH_STATEMENT,
47
+ DETACH_STATEMENT
47
48
 
48
49
  };
49
50
 
@@ -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 bool TryConvertTimestamp(const char *str, idx_t len, timestamp_t &result);
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