duckdb 0.9.1-dev97.0 → 0.9.1
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/.github/workflows/NodeJS.yml +250 -0
- package/Makefile +3 -9
- package/README.md +2 -2
- package/binding.gyp +8 -8
- package/package.json +4 -4
- package/scripts/install_node.sh +21 -0
- package/scripts/node_build.sh +40 -0
- package/scripts/node_build_win.sh +21 -0
- package/scripts/node_version.sh +33 -0
- package/src/duckdb/extension/icu/icu-makedate.cpp +1 -1
- package/src/duckdb/extension/icu/icu-strptime.cpp +0 -2
- package/src/duckdb/extension/icu/icu_extension.cpp +0 -1
- package/src/duckdb/extension/json/json_functions/json_create.cpp +27 -14
- package/src/duckdb/extension/json/json_functions/json_transform.cpp +26 -14
- package/src/duckdb/extension/json/json_functions.cpp +1 -10
- package/src/duckdb/extension/parquet/column_reader.cpp +26 -1
- package/src/duckdb/extension/parquet/column_writer.cpp +10 -1
- package/src/duckdb/extension/parquet/include/column_reader.hpp +2 -0
- package/src/duckdb/extension/parquet/include/parquet_bss_decoder.hpp +49 -0
- package/src/duckdb/extension/parquet/parquet_extension.cpp +3 -4
- package/src/duckdb/extension/parquet/parquet_timestamp.cpp +3 -4
- package/src/duckdb/src/common/arrow/appender/list_data.cpp +2 -2
- package/src/duckdb/src/common/arrow/appender/map_data.cpp +15 -10
- package/src/duckdb/src/common/arrow/appender/struct_data.cpp +2 -2
- package/src/duckdb/src/common/arrow/appender/union_data.cpp +2 -2
- package/src/duckdb/src/common/arrow/arrow_appender.cpp +26 -7
- package/src/duckdb/src/common/arrow/arrow_wrapper.cpp +3 -3
- package/src/duckdb/src/common/exception.cpp +60 -84
- package/src/duckdb/src/common/preserved_error.cpp +20 -0
- package/src/duckdb/src/common/types/data_chunk.cpp +1 -1
- package/src/duckdb/src/execution/expression_executor/execute_reference.cpp +1 -1
- package/src/duckdb/src/execution/expression_executor_state.cpp +8 -2
- package/src/duckdb/src/execution/operator/csv_scanner/buffered_csv_reader.cpp +1 -1
- package/src/duckdb/src/execution/operator/csv_scanner/csv_state_machine_cache.cpp +2 -0
- package/src/duckdb/src/execution/operator/csv_scanner/sniffer/csv_sniffer.cpp +5 -5
- package/src/duckdb/src/execution/operator/csv_scanner/sniffer/dialect_detection.cpp +4 -4
- package/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_replacement.cpp +2 -2
- package/src/duckdb/src/execution/operator/helper/physical_reset.cpp +1 -4
- package/src/duckdb/src/execution/operator/helper/physical_set.cpp +2 -4
- package/src/duckdb/src/function/function_binder.cpp +1 -1
- package/src/duckdb/src/function/table/arrow_conversion.cpp +2 -1
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/common/arrow/appender/append_data.hpp +4 -0
- package/src/duckdb/src/include/duckdb/common/arrow/appender/enum_data.hpp +3 -1
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_appender.hpp +2 -1
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_wrapper.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/exception.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/preserved_error.hpp +1 -3
- package/src/duckdb/src/include/duckdb/execution/expression_executor_state.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/scan/csv/base_csv_reader.hpp +0 -4
- package/src/duckdb/src/include/duckdb/execution/operator/scan/csv/csv_sniffer.hpp +10 -10
- package/src/duckdb/src/include/duckdb/function/replacement_scan.hpp +20 -0
- package/src/duckdb/src/include/duckdb/main/config.hpp +2 -0
- package/src/duckdb/src/include/duckdb/optimizer/filter_pushdown.hpp +2 -0
- package/src/duckdb/src/include/duckdb/planner/binder.hpp +1 -0
- package/src/duckdb/src/include/duckdb/planner/bound_parameter_map.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression_binder.hpp +2 -2
- package/src/duckdb/src/main/capi/arrow-c.cpp +7 -4
- package/src/duckdb/src/main/config.cpp +14 -0
- package/src/duckdb/src/main/extension/extension_install.cpp +14 -12
- package/src/duckdb/src/optimizer/filter_pushdown.cpp +1 -0
- package/src/duckdb/src/optimizer/pushdown/pushdown_distinct.cpp +19 -0
- package/src/duckdb/src/parser/transform/statement/transform_copy.cpp +4 -2
- package/src/duckdb/src/parser/transform/statement/transform_create_sequence.cpp +10 -5
- package/src/duckdb/src/planner/binder/expression/bind_between_expression.cpp +5 -7
- package/src/duckdb/src/planner/binder/expression/bind_collate_expression.cpp +4 -2
- package/src/duckdb/src/planner/binder/expression/bind_comparison_expression.cpp +17 -14
- package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +5 -12
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +15 -1
- package/src/duckdb/src/planner/bound_parameter_map.cpp +16 -5
- package/src/duckdb/src/planner/expression_binder/base_select_binder.cpp +2 -5
- package/src/duckdb/src/planner/planner.cpp +1 -1
- package/src/duckdb/src/transaction/duck_transaction_manager.cpp +13 -9
- package/src/duckdb/third_party/parquet/parquet_types.h +2 -1
- package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +5 -5
- package/src/duckdb/ub_src_optimizer_pushdown.cpp +2 -0
- package/src/statement.cpp +4 -4
- package/test/arrow.test.ts +3 -1
- package/test/parquet.test.ts +1 -1
- package/test/userdata1.parquet +0 -0
- package/{configure → vendor} +1 -1
- package/{configure.py → vendor.py} +12 -1
- package/duckdb_extension_config.cmake +0 -10
@@ -39,18 +39,18 @@ SnifferResult CSVSniffer::SniffCSV() {
|
|
39
39
|
DetectDialect();
|
40
40
|
// 2. Type Detection
|
41
41
|
DetectTypes();
|
42
|
-
// 3.
|
42
|
+
// 3. Type Refinement
|
43
|
+
RefineTypes();
|
44
|
+
// 4. Header Detection
|
43
45
|
DetectHeader();
|
44
46
|
if (explicit_set_columns) {
|
45
47
|
SetResultOptions();
|
46
48
|
// We do not need to run type refinement, since the types have been given by the user
|
47
49
|
return SnifferResult({}, {});
|
48
50
|
}
|
49
|
-
|
50
|
-
// 4. Type Replacement
|
51
|
+
// 5. Type Replacement
|
51
52
|
ReplaceTypes();
|
52
|
-
|
53
|
-
RefineTypes();
|
53
|
+
D_ASSERT(best_sql_types_candidates_per_column_idx.size() == names.size());
|
54
54
|
// We are done, Set the CSV Options in the reference. Construct and return the result.
|
55
55
|
SetResultOptions();
|
56
56
|
return SnifferResult(detected_types, names);
|
@@ -5,9 +5,9 @@ namespace duckdb {
|
|
5
5
|
|
6
6
|
struct SniffDialect {
|
7
7
|
inline static void Initialize(CSVStateMachine &machine) {
|
8
|
-
machine.state = CSVState::
|
9
|
-
machine.previous_state = CSVState::
|
10
|
-
machine.pre_previous_state = CSVState::
|
8
|
+
machine.state = CSVState::EMPTY_LINE;
|
9
|
+
machine.previous_state = CSVState::EMPTY_LINE;
|
10
|
+
machine.pre_previous_state = CSVState::EMPTY_LINE;
|
11
11
|
machine.cur_rows = 0;
|
12
12
|
machine.column_count = 1;
|
13
13
|
}
|
@@ -299,7 +299,7 @@ void CSVSniffer::DetectDialect() {
|
|
299
299
|
unordered_map<uint8_t, vector<char>> quote_candidates_map;
|
300
300
|
// Candidates for the escape option
|
301
301
|
unordered_map<uint8_t, vector<char>> escape_candidates_map;
|
302
|
-
escape_candidates_map[(uint8_t)QuoteRule::QUOTES_RFC] = {'\
|
302
|
+
escape_candidates_map[(uint8_t)QuoteRule::QUOTES_RFC] = {'\"', '\'', '\0'};
|
303
303
|
escape_candidates_map[(uint8_t)QuoteRule::QUOTES_OTHER] = {'\\'};
|
304
304
|
escape_candidates_map[(uint8_t)QuoteRule::NO_QUOTES] = {'\0'};
|
305
305
|
// Number of rows read
|
@@ -14,7 +14,7 @@ void CSVSniffer::ReplaceTypes() {
|
|
14
14
|
for (idx_t i = 0; i < names.size(); i++) {
|
15
15
|
auto it = best_candidate->options.sql_types_per_column.find(names[i]);
|
16
16
|
if (it != best_candidate->options.sql_types_per_column.end()) {
|
17
|
-
|
17
|
+
detected_types[i] = best_candidate->options.sql_type_list[it->second];
|
18
18
|
found++;
|
19
19
|
}
|
20
20
|
}
|
@@ -33,7 +33,7 @@ void CSVSniffer::ReplaceTypes() {
|
|
33
33
|
best_candidate->options.sql_type_list.size(), names.size());
|
34
34
|
}
|
35
35
|
for (idx_t i = 0; i < best_candidate->options.sql_type_list.size(); i++) {
|
36
|
-
|
36
|
+
detected_types[i] = best_candidate->options.sql_type_list[i];
|
37
37
|
}
|
38
38
|
}
|
39
39
|
} // namespace duckdb
|
@@ -21,10 +21,7 @@ void PhysicalReset::ResetExtensionVariable(ExecutionContext &context, DBConfig &
|
|
21
21
|
|
22
22
|
SourceResultType PhysicalReset::GetData(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const {
|
23
23
|
auto &config = DBConfig::GetConfig(context.client);
|
24
|
-
|
25
|
-
throw InvalidInputException("Cannot reset configuration option \"%s\" - the configuration has been locked",
|
26
|
-
name);
|
27
|
-
}
|
24
|
+
config.CheckLock(name);
|
28
25
|
auto option = DBConfig::GetOptionByName(name);
|
29
26
|
if (!option) {
|
30
27
|
// check if this is an extra extension variable
|
@@ -24,10 +24,8 @@ void PhysicalSet::SetExtensionVariable(ClientContext &context, ExtensionOption &
|
|
24
24
|
|
25
25
|
SourceResultType PhysicalSet::GetData(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const {
|
26
26
|
auto &config = DBConfig::GetConfig(context.client);
|
27
|
-
if
|
28
|
-
|
29
|
-
name);
|
30
|
-
}
|
27
|
+
// check if we are allowed to change the configuration option
|
28
|
+
config.CheckLock(name);
|
31
29
|
auto option = DBConfig::GetOptionByName(name);
|
32
30
|
if (!option) {
|
33
31
|
// check if this is an extra extension variable
|
@@ -228,7 +228,7 @@ void FunctionBinder::CastToFunctionArguments(SimpleFunction &function, vector<un
|
|
228
228
|
for (idx_t i = 0; i < children.size(); i++) {
|
229
229
|
auto target_type = i < function.arguments.size() ? function.arguments[i] : function.varargs;
|
230
230
|
target_type.Verify();
|
231
|
-
// don't cast lambda children, they get removed
|
231
|
+
// don't cast lambda children, they get removed before execution
|
232
232
|
if (children[i]->return_type.id() == LogicalTypeId::LAMBDA) {
|
233
233
|
continue;
|
234
234
|
}
|
@@ -639,10 +639,11 @@ static void ColumnArrowToDuckDB(Vector &vector, ArrowArray &array, ArrowScanLoca
|
|
639
639
|
for (idx_t type_idx = 0; type_idx < static_cast<idx_t>(array.n_children); type_idx++) {
|
640
640
|
Vector child(members[type_idx].second);
|
641
641
|
auto arrow_array = array.children[type_idx];
|
642
|
+
auto &child_type = arrow_type[type_idx];
|
642
643
|
|
643
644
|
SetValidityMask(child, *arrow_array, scan_state, size, nested_offset);
|
644
645
|
|
645
|
-
ColumnArrowToDuckDB(child, *arrow_array, scan_state, size,
|
646
|
+
ColumnArrowToDuckDB(child, *arrow_array, scan_state, size, child_type, nested_offset, &validity_mask);
|
646
647
|
|
647
648
|
children.push_back(std::move(child));
|
648
649
|
}
|
@@ -1,8 +1,8 @@
|
|
1
1
|
#ifndef DUCKDB_VERSION
|
2
|
-
#define DUCKDB_VERSION "v0.9.1
|
2
|
+
#define DUCKDB_VERSION "v0.9.1"
|
3
3
|
#endif
|
4
4
|
#ifndef DUCKDB_SOURCE_ID
|
5
|
-
#define DUCKDB_SOURCE_ID "
|
5
|
+
#define DUCKDB_SOURCE_ID "401c8061c6"
|
6
6
|
#endif
|
7
7
|
#include "duckdb/function/table/system_functions.hpp"
|
8
8
|
#include "duckdb/main/database.hpp"
|
@@ -27,6 +27,7 @@ typedef void (*finalize_t)(ArrowAppendData &append_data, const LogicalType &type
|
|
27
27
|
// ArrowAppendState
|
28
28
|
struct ArrowAppendData {
|
29
29
|
explicit ArrowAppendData(ClientProperties &options_p) : options(options_p) {
|
30
|
+
dictionary.release = nullptr;
|
30
31
|
}
|
31
32
|
// the buffers of the arrow vector
|
32
33
|
ArrowBuffer validity;
|
@@ -48,6 +49,9 @@ struct ArrowAppendData {
|
|
48
49
|
unique_ptr<ArrowArray> array;
|
49
50
|
duckdb::array<const void *, 3> buffers = {{nullptr, nullptr, nullptr}};
|
50
51
|
vector<ArrowArray *> child_pointers;
|
52
|
+
// Arrays so the children can be moved
|
53
|
+
vector<ArrowArray> child_arrays;
|
54
|
+
ArrowArray dictionary;
|
51
55
|
|
52
56
|
ClientProperties options;
|
53
57
|
};
|
@@ -62,7 +62,9 @@ struct ArrowEnumData : public ArrowScalarBaseData<TGT> {
|
|
62
62
|
result->n_buffers = 2;
|
63
63
|
result->buffers[1] = append_data.main_buffer.data();
|
64
64
|
// finalize the enum child data, and assign it to the dictionary
|
65
|
-
result->dictionary =
|
65
|
+
result->dictionary = &append_data.dictionary;
|
66
|
+
append_data.dictionary =
|
67
|
+
*ArrowAppender::FinalizeChild(LogicalType::VARCHAR, std::move(append_data.child_data[0]));
|
66
68
|
}
|
67
69
|
};
|
68
70
|
|
@@ -28,9 +28,10 @@ public:
|
|
28
28
|
|
29
29
|
public:
|
30
30
|
static void ReleaseArray(ArrowArray *array);
|
31
|
-
static ArrowArray *FinalizeChild(const LogicalType &type, ArrowAppendData
|
31
|
+
static ArrowArray *FinalizeChild(const LogicalType &type, unique_ptr<ArrowAppendData> append_data);
|
32
32
|
static unique_ptr<ArrowAppendData> InitializeChild(const LogicalType &type, idx_t capacity,
|
33
33
|
ClientProperties &options);
|
34
|
+
static void AddChildren(ArrowAppendData &data, idx_t count);
|
34
35
|
|
35
36
|
private:
|
36
37
|
//! The types of the chunks that will be appended in
|
@@ -97,6 +97,7 @@ public:
|
|
97
97
|
DUCKDB_API const string &RawMessage() const;
|
98
98
|
|
99
99
|
DUCKDB_API static string ExceptionTypeToString(ExceptionType type);
|
100
|
+
DUCKDB_API static ExceptionType StringToExceptionType(const string &type);
|
100
101
|
[[noreturn]] DUCKDB_API static void ThrowAsTypeWithMessage(ExceptionType type, const string &message,
|
101
102
|
const std::shared_ptr<Exception> &original);
|
102
103
|
virtual std::shared_ptr<Exception> Copy() const {
|
@@ -18,9 +18,7 @@ public:
|
|
18
18
|
//! Not initialized, default constructor
|
19
19
|
DUCKDB_API PreservedError();
|
20
20
|
//! From std::exception
|
21
|
-
PreservedError(const std::exception &ex)
|
22
|
-
: initialized(true), type(ExceptionType::INVALID), raw_message(SanitizeErrorMessage(ex.what())),
|
23
|
-
exception_instance(nullptr) {
|
21
|
+
PreservedError(const std::exception &ex) : PreservedError(ex.what()) {
|
24
22
|
}
|
25
23
|
//! From a raw string
|
26
24
|
DUCKDB_API explicit PreservedError(const string &raw_message);
|
@@ -51,13 +51,9 @@ public:
|
|
51
51
|
bool linenr_estimated = false;
|
52
52
|
|
53
53
|
bool row_empty = false;
|
54
|
-
idx_t sample_chunk_idx = 0;
|
55
|
-
bool jumping_samples = false;
|
56
|
-
bool end_of_file_reached = false;
|
57
54
|
bool bom_checked = false;
|
58
55
|
|
59
56
|
idx_t bytes_in_chunk = 0;
|
60
|
-
double bytes_per_line_avg = 0;
|
61
57
|
|
62
58
|
DataChunk parse_chunk;
|
63
59
|
|
@@ -34,9 +34,9 @@ public:
|
|
34
34
|
//! CSV Sniffing consists of five steps:
|
35
35
|
//! 1. Dialect Detection: Generate the CSV Options (delimiter, quote, escape, etc.)
|
36
36
|
//! 2. Type Detection: Figures out the types of the columns (For one chunk)
|
37
|
-
//! 3.
|
38
|
-
//! 4.
|
39
|
-
//! 5. Type
|
37
|
+
//! 3. Type Refinement: Refines the types of the columns for the remaining chunks
|
38
|
+
//! 4. Header Detection: Figures out if the CSV file has a header and produces the names of the columns
|
39
|
+
//! 5. Type Replacement: Replaces the types of the columns if the user specified them
|
40
40
|
SnifferResult SniffCSV();
|
41
41
|
|
42
42
|
private:
|
@@ -107,6 +107,13 @@ private:
|
|
107
107
|
idx_t best_start_without_header = 0;
|
108
108
|
vector<Value> best_header_row;
|
109
109
|
|
110
|
+
//! ------------------------------------------------------//
|
111
|
+
//! ------------------ Type Refinement ------------------ //
|
112
|
+
//! ------------------------------------------------------//
|
113
|
+
void RefineTypes();
|
114
|
+
bool TryCastVector(Vector &parse_chunk_col, idx_t size, const LogicalType &sql_type);
|
115
|
+
vector<LogicalType> detected_types;
|
116
|
+
|
110
117
|
//! ------------------------------------------------------//
|
111
118
|
//! ------------------ Header Detection ----------------- //
|
112
119
|
//! ------------------------------------------------------//
|
@@ -119,13 +126,6 @@ private:
|
|
119
126
|
//! ------------------ Type Replacement ----------------- //
|
120
127
|
//! ------------------------------------------------------//
|
121
128
|
void ReplaceTypes();
|
122
|
-
|
123
|
-
//! ------------------------------------------------------//
|
124
|
-
//! ------------------ Type Refinement ------------------ //
|
125
|
-
//! ------------------------------------------------------//
|
126
|
-
void RefineTypes();
|
127
|
-
bool TryCastVector(Vector &parse_chunk_col, idx_t size, const LogicalType &sql_type);
|
128
|
-
vector<LogicalType> detected_types;
|
129
129
|
};
|
130
130
|
|
131
131
|
} // namespace duckdb
|
@@ -9,6 +9,7 @@
|
|
9
9
|
#pragma once
|
10
10
|
|
11
11
|
#include "duckdb/common/common.hpp"
|
12
|
+
#include "duckdb/common/string_util.hpp"
|
12
13
|
|
13
14
|
namespace duckdb {
|
14
15
|
|
@@ -30,6 +31,25 @@ struct ReplacementScan {
|
|
30
31
|
: function(function), data(std::move(data_p)) {
|
31
32
|
}
|
32
33
|
|
34
|
+
static bool CanReplace(const string &table_name, const vector<string> &extensions) {
|
35
|
+
auto lower_name = StringUtil::Lower(table_name);
|
36
|
+
|
37
|
+
if (StringUtil::EndsWith(lower_name, ".gz")) {
|
38
|
+
lower_name = lower_name.substr(0, lower_name.size() - 3);
|
39
|
+
} else if (StringUtil::EndsWith(lower_name, ".zst")) {
|
40
|
+
lower_name = lower_name.substr(0, lower_name.size() - 4);
|
41
|
+
}
|
42
|
+
|
43
|
+
for (auto &extension : extensions) {
|
44
|
+
if (StringUtil::EndsWith(lower_name, "." + extension) ||
|
45
|
+
StringUtil::Contains(lower_name, "." + extension + "?")) {
|
46
|
+
return true;
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
return false;
|
51
|
+
}
|
52
|
+
|
33
53
|
replacement_scan_t function;
|
34
54
|
unique_ptr<ReplacementScanData> data;
|
35
55
|
};
|
@@ -240,6 +240,8 @@ public:
|
|
240
240
|
DUCKDB_API void SetOption(const string &name, Value value);
|
241
241
|
DUCKDB_API void ResetOption(const string &name);
|
242
242
|
|
243
|
+
DUCKDB_API void CheckLock(const string &name);
|
244
|
+
|
243
245
|
DUCKDB_API static idx_t ParseMemoryLimit(const string &arg);
|
244
246
|
|
245
247
|
//! Return the list of possible compression functions for the specific physical type
|
@@ -43,6 +43,8 @@ private:
|
|
43
43
|
|
44
44
|
//! Push down a LogicalAggregate op
|
45
45
|
unique_ptr<LogicalOperator> PushdownAggregate(unique_ptr<LogicalOperator> op);
|
46
|
+
//! Push down a distinct operator
|
47
|
+
unique_ptr<LogicalOperator> PushdownDistinct(unique_ptr<LogicalOperator> op);
|
46
48
|
//! Push down a LogicalFilter op
|
47
49
|
unique_ptr<LogicalOperator> PushdownFilter(unique_ptr<LogicalOperator> op);
|
48
50
|
//! Push down a LogicalCrossProduct op
|
@@ -362,6 +362,7 @@ private:
|
|
362
362
|
|
363
363
|
//! If only a schema name is provided (e.g. "a.b") then figure out if "a" is a schema or a catalog name
|
364
364
|
void BindSchemaOrCatalog(string &catalog_name, string &schema_name);
|
365
|
+
const string BindCatalog(string &catalog_name);
|
365
366
|
SchemaCatalogEntry &BindCreateSchema(CreateInfo &info);
|
366
367
|
|
367
368
|
unique_ptr<BoundQueryNode> BindSelectNode(SelectNode &statement, unique_ptr<BoundTableRef> from_table);
|
@@ -35,6 +35,9 @@ public:
|
|
35
35
|
|
36
36
|
unique_ptr<BoundParameterExpression> BindParameterExpression(ParameterExpression &expr);
|
37
37
|
|
38
|
+
//! Flag to indicate that we need to rebind this prepared statement before execution
|
39
|
+
bool rebind = false;
|
40
|
+
|
38
41
|
private:
|
39
42
|
shared_ptr<BoundParameterData> CreateOrGetData(const string &identifier);
|
40
43
|
void CreateNewParameter(const string &id, const shared_ptr<BoundParameterData> ¶m_data);
|
@@ -90,8 +90,8 @@ public:
|
|
90
90
|
void QualifyColumnNames(unique_ptr<ParsedExpression> &expr);
|
91
91
|
static void QualifyColumnNames(Binder &binder, unique_ptr<ParsedExpression> &expr);
|
92
92
|
|
93
|
-
static
|
94
|
-
|
93
|
+
static bool PushCollation(ClientContext &context, unique_ptr<Expression> &source, const LogicalType &sql_type,
|
94
|
+
bool equality_only = false);
|
95
95
|
static void TestCollation(ClientContext &context, const string &collation);
|
96
96
|
|
97
97
|
bool BindCorrelatedColumns(unique_ptr<ParsedExpression> &expr);
|
@@ -64,7 +64,7 @@ duckdb_state duckdb_prepared_arrow_schema(duckdb_prepared_statement prepared, du
|
|
64
64
|
if (result_schema->release) {
|
65
65
|
// Need to release the existing schema before we overwrite it
|
66
66
|
result_schema->release(result_schema);
|
67
|
-
result_schema->release
|
67
|
+
D_ASSERT(!result_schema->release);
|
68
68
|
}
|
69
69
|
|
70
70
|
ArrowConverter::ToArrowSchema(result_schema, prepared_types, prepared_names, properties);
|
@@ -155,14 +155,17 @@ struct PrivateData {
|
|
155
155
|
|
156
156
|
// LCOV_EXCL_START
|
157
157
|
// This function is never called, but used to set ArrowSchema's release functions to a non-null NOOP.
|
158
|
-
void EmptySchemaRelease(ArrowSchema *) {
|
158
|
+
void EmptySchemaRelease(ArrowSchema *schema) {
|
159
|
+
schema->release = nullptr;
|
159
160
|
}
|
160
161
|
// LCOV_EXCL_STOP
|
161
162
|
|
162
|
-
void EmptyArrayRelease(ArrowArray *) {
|
163
|
+
void EmptyArrayRelease(ArrowArray *array) {
|
164
|
+
array->release = nullptr;
|
163
165
|
}
|
164
166
|
|
165
|
-
void EmptyStreamRelease(ArrowArrayStream *) {
|
167
|
+
void EmptyStreamRelease(ArrowArrayStream *stream) {
|
168
|
+
stream->release = nullptr;
|
166
169
|
}
|
167
170
|
|
168
171
|
void FactoryGetSchema(uintptr_t stream_factory_ptr, duckdb::ArrowSchemaWrapper &schema) {
|
@@ -233,6 +233,20 @@ void DBConfig::SetDefaultMaxMemory() {
|
|
233
233
|
}
|
234
234
|
}
|
235
235
|
|
236
|
+
void DBConfig::CheckLock(const string &name) {
|
237
|
+
if (!options.lock_configuration) {
|
238
|
+
// not locked
|
239
|
+
return;
|
240
|
+
}
|
241
|
+
case_insensitive_set_t allowed_settings {"schema", "search_path"};
|
242
|
+
if (allowed_settings.find(name) != allowed_settings.end()) {
|
243
|
+
// we are always allowed to change these settings
|
244
|
+
return;
|
245
|
+
}
|
246
|
+
// not allowed!
|
247
|
+
throw InvalidInputException("Cannot change configuration option \"%s\" - the configuration has been locked", name);
|
248
|
+
}
|
249
|
+
|
236
250
|
idx_t CGroupBandwidthQuota(idx_t physical_cores, FileSystem &fs) {
|
237
251
|
static constexpr const char *CPU_MAX = "/sys/fs/cgroup/cpu.max";
|
238
252
|
static constexpr const char *CFS_QUOTA = "/sys/fs/cgroup/cpu/cpu.cfs_quota_us";
|
@@ -208,18 +208,20 @@ void ExtensionHelper::InstallExtensionInternal(DBConfig &config, ClientConfig *c
|
|
208
208
|
fs.RemoveFile(temp_path);
|
209
209
|
}
|
210
210
|
auto is_http_url = StringUtil::Contains(extension, "http://");
|
211
|
-
if (
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
fs.
|
211
|
+
if (ExtensionHelper::IsFullPath(extension)) {
|
212
|
+
if (fs.FileExists(extension)) {
|
213
|
+
idx_t file_size;
|
214
|
+
auto in_buffer = ReadExtensionFileFromDisk(fs, extension, file_size);
|
215
|
+
WriteExtensionFileToDisk(fs, temp_path, in_buffer.get(), file_size);
|
216
|
+
|
217
|
+
if (fs.FileExists(local_extension_path) && force_install) {
|
218
|
+
fs.RemoveFile(local_extension_path);
|
219
|
+
}
|
220
|
+
fs.MoveFile(temp_path, local_extension_path);
|
221
|
+
return;
|
222
|
+
} else if (!is_http_url) {
|
223
|
+
throw IOException("Failed to read extension from \"%s\": no such file", extension);
|
218
224
|
}
|
219
|
-
fs.MoveFile(temp_path, local_extension_path);
|
220
|
-
return;
|
221
|
-
} else if (StringUtil::Contains(extension, "/") && !is_http_url) {
|
222
|
-
throw IOException("Failed to read extension from \"%s\": no such file", extension);
|
223
225
|
}
|
224
226
|
|
225
227
|
#ifdef DISABLE_DUCKDB_REMOTE_INSTALL
|
@@ -280,7 +282,7 @@ void ExtensionHelper::InstallExtensionInternal(DBConfig &config, ClientConfig *c
|
|
280
282
|
// create suggestions
|
281
283
|
string message;
|
282
284
|
auto exact_match = ExtensionHelper::CreateSuggestions(extension_name, message);
|
283
|
-
if (exact_match) {
|
285
|
+
if (exact_match && !IsRelease(DuckDB::LibraryVersion())) {
|
284
286
|
message += "\nAre you using a development build? In this case, extensions might not (yet) be uploaded.";
|
285
287
|
}
|
286
288
|
if (res.error() == duckdb_httplib::Error::Success) {
|
@@ -33,6 +33,7 @@ unique_ptr<LogicalOperator> FilterPushdown::Rewrite(unique_ptr<LogicalOperator>
|
|
33
33
|
case LogicalOperatorType::LOGICAL_UNION:
|
34
34
|
return PushdownSetOperation(std::move(op));
|
35
35
|
case LogicalOperatorType::LOGICAL_DISTINCT:
|
36
|
+
return PushdownDistinct(std::move(op));
|
36
37
|
case LogicalOperatorType::LOGICAL_ORDER_BY: {
|
37
38
|
// we can just push directly through these operations without any rewriting
|
38
39
|
op->children[0] = Rewrite(std::move(op->children[0]));
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#include "duckdb/optimizer/filter_pushdown.hpp"
|
2
|
+
#include "duckdb/planner/expression_iterator.hpp"
|
3
|
+
#include "duckdb/planner/operator/logical_distinct.hpp"
|
4
|
+
|
5
|
+
namespace duckdb {
|
6
|
+
|
7
|
+
unique_ptr<LogicalOperator> FilterPushdown::PushdownDistinct(unique_ptr<LogicalOperator> op) {
|
8
|
+
D_ASSERT(op->type == LogicalOperatorType::LOGICAL_DISTINCT);
|
9
|
+
auto &distinct = op->Cast<LogicalDistinct>();
|
10
|
+
if (!distinct.order_by) {
|
11
|
+
// regular DISTINCT - can just push down
|
12
|
+
op->children[0] = Rewrite(std::move(op->children[0]));
|
13
|
+
return op;
|
14
|
+
}
|
15
|
+
// no pushdown through DISTINCT ON (yet?)
|
16
|
+
return FinishPushdown(std::move(op));
|
17
|
+
}
|
18
|
+
|
19
|
+
} // namespace duckdb
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#include "duckdb/common/string_util.hpp"
|
2
2
|
#include "duckdb/common/types/value.hpp"
|
3
3
|
#include "duckdb/core_functions/scalar/struct_functions.hpp"
|
4
|
+
#include "duckdb/function/replacement_scan.hpp"
|
4
5
|
#include "duckdb/parser/expression/constant_expression.hpp"
|
5
6
|
#include "duckdb/parser/expression/function_expression.hpp"
|
6
7
|
#include "duckdb/parser/statement/copy_statement.hpp"
|
@@ -82,9 +83,10 @@ unique_ptr<CopyStatement> Transformer::TransformCopy(duckdb_libpgquery::PGCopySt
|
|
82
83
|
// copy to a file
|
83
84
|
info.file_path = stmt.filename;
|
84
85
|
}
|
85
|
-
|
86
|
+
|
87
|
+
if (ReplacementScan::CanReplace(info.file_path, {"parquet"})) {
|
86
88
|
info.format = "parquet";
|
87
|
-
} else if (
|
89
|
+
} else if (ReplacementScan::CanReplace(info.file_path, {"json", "jsonl", "ndjson"})) {
|
88
90
|
info.format = "json";
|
89
91
|
} else {
|
90
92
|
info.format = "csv";
|
@@ -17,6 +17,8 @@ unique_ptr<CreateStatement> Transformer::TransformCreateSequence(duckdb_libpgque
|
|
17
17
|
info->name = qname.name;
|
18
18
|
|
19
19
|
if (stmt.options) {
|
20
|
+
int64_t default_start_value = info->start_value;
|
21
|
+
bool has_start_value = false;
|
20
22
|
unordered_set<SequenceInfo, EnumClassHash> used;
|
21
23
|
duckdb_libpgquery::PGListCell *cell = nullptr;
|
22
24
|
for_each_cell(cell, stmt.options->head) {
|
@@ -51,10 +53,10 @@ unique_ptr<CreateStatement> Transformer::TransformCreateSequence(duckdb_libpgque
|
|
51
53
|
throw ParserException("Increment must not be zero");
|
52
54
|
}
|
53
55
|
if (info->increment < 0) {
|
54
|
-
|
56
|
+
default_start_value = info->max_value = -1;
|
55
57
|
info->min_value = NumericLimits<int64_t>::Minimum();
|
56
58
|
} else {
|
57
|
-
|
59
|
+
default_start_value = info->min_value = 1;
|
58
60
|
info->max_value = NumericLimits<int64_t>::Maximum();
|
59
61
|
}
|
60
62
|
} else if (opt_name == "minvalue") {
|
@@ -68,7 +70,7 @@ unique_ptr<CreateStatement> Transformer::TransformCreateSequence(duckdb_libpgque
|
|
68
70
|
|
69
71
|
info->min_value = opt_value;
|
70
72
|
if (info->increment > 0) {
|
71
|
-
|
73
|
+
default_start_value = info->min_value;
|
72
74
|
}
|
73
75
|
} else if (opt_name == "maxvalue") {
|
74
76
|
if (used.find(SequenceInfo::SEQ_MAX) != used.end()) {
|
@@ -81,7 +83,7 @@ unique_ptr<CreateStatement> Transformer::TransformCreateSequence(duckdb_libpgque
|
|
81
83
|
|
82
84
|
info->max_value = opt_value;
|
83
85
|
if (info->increment < 0) {
|
84
|
-
|
86
|
+
default_start_value = info->max_value;
|
85
87
|
}
|
86
88
|
} else if (opt_name == "start") {
|
87
89
|
if (used.find(SequenceInfo::SEQ_START) != used.end()) {
|
@@ -91,7 +93,7 @@ unique_ptr<CreateStatement> Transformer::TransformCreateSequence(duckdb_libpgque
|
|
91
93
|
if (nodef) {
|
92
94
|
continue;
|
93
95
|
}
|
94
|
-
|
96
|
+
has_start_value = true;
|
95
97
|
info->start_value = opt_value;
|
96
98
|
} else if (opt_name == "cycle") {
|
97
99
|
if (used.find(SequenceInfo::SEQ_CYCLE) != used.end()) {
|
@@ -107,6 +109,9 @@ unique_ptr<CreateStatement> Transformer::TransformCreateSequence(duckdb_libpgque
|
|
107
109
|
throw ParserException("Unrecognized option \"%s\" for CREATE SEQUENCE", opt_name);
|
108
110
|
}
|
109
111
|
}
|
112
|
+
if (!has_start_value) {
|
113
|
+
info->start_value = default_start_value;
|
114
|
+
}
|
110
115
|
}
|
111
116
|
info->temporary = !stmt.sequence->relpersistence;
|
112
117
|
info->on_conflict = TransformOnConflict(stmt.onconflict);
|
@@ -34,13 +34,11 @@ BindResult ExpressionBinder::BindExpression(BetweenExpression &expr, idx_t depth
|
|
34
34
|
input = BoundCastExpression::AddCastToType(context, std::move(input), input_type);
|
35
35
|
lower = BoundCastExpression::AddCastToType(context, std::move(lower), input_type);
|
36
36
|
upper = BoundCastExpression::AddCastToType(context, std::move(upper), input_type);
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
upper = PushCollation(context, std::move(upper), collation, false);
|
43
|
-
}
|
37
|
+
// handle collation
|
38
|
+
PushCollation(context, input, input_type, false);
|
39
|
+
PushCollation(context, lower, input_type, false);
|
40
|
+
PushCollation(context, upper, input_type, false);
|
41
|
+
|
44
42
|
if (!input->HasSideEffects() && !input->HasParameter() && !input->HasSubquery()) {
|
45
43
|
// the expression does not have side effects and can be copied: create two comparisons
|
46
44
|
// the reason we do this is that individual comparisons are easier to handle in optimizers
|
@@ -18,8 +18,10 @@ BindResult ExpressionBinder::BindExpression(CollateExpression &expr, idx_t depth
|
|
18
18
|
throw BinderException("collations are only supported for type varchar");
|
19
19
|
}
|
20
20
|
// Validate the collation, but don't use it
|
21
|
-
|
22
|
-
|
21
|
+
auto child_copy = child->Copy();
|
22
|
+
auto collation_type = LogicalType::VARCHAR_COLLATION(expr.collation);
|
23
|
+
PushCollation(context, child_copy, collation_type, false);
|
24
|
+
child->return_type = collation_type;
|
23
25
|
return BindResult(std::move(child));
|
24
26
|
}
|
25
27
|
|