duckdb 0.8.2-dev2283.0 → 0.8.2-dev2356.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 (40) hide show
  1. package/binding.gyp +1 -0
  2. package/package.json +1 -1
  3. package/src/duckdb/extension/parquet/parquet_writer.cpp +1 -0
  4. package/src/duckdb/src/common/adbc/adbc.cpp +8 -3
  5. package/src/duckdb/src/common/arrow/arrow_appender.cpp +4 -4
  6. package/src/duckdb/src/common/arrow/arrow_converter.cpp +27 -26
  7. package/src/duckdb/src/common/arrow/arrow_wrapper.cpp +37 -43
  8. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  9. package/src/duckdb/src/include/duckdb/common/arrow/appender/append_data.hpp +3 -3
  10. package/src/duckdb/src/include/duckdb/common/arrow/appender/varchar_data.hpp +1 -1
  11. package/src/duckdb/src/include/duckdb/common/arrow/arrow_appender.hpp +4 -3
  12. package/src/duckdb/src/include/duckdb/common/arrow/arrow_converter.hpp +3 -3
  13. package/src/duckdb/src/include/duckdb/common/arrow/arrow_wrapper.hpp +5 -3
  14. package/src/duckdb/src/include/duckdb/common/arrow/result_arrow_wrapper.hpp +4 -0
  15. package/src/duckdb/src/include/duckdb/common/stack_checker.hpp +34 -0
  16. package/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp +1 -2
  17. package/src/duckdb/src/include/duckdb/main/chunk_scan_state/query_result.hpp +29 -0
  18. package/src/duckdb/src/include/duckdb/main/chunk_scan_state.hpp +45 -0
  19. package/src/duckdb/src/include/duckdb/main/client_config.hpp +0 -2
  20. package/src/duckdb/src/include/duckdb/main/client_context.hpp +1 -0
  21. package/src/duckdb/src/include/duckdb/main/client_properties.hpp +25 -0
  22. package/src/duckdb/src/include/duckdb/main/config.hpp +1 -1
  23. package/src/duckdb/src/include/duckdb/main/extension_entries.hpp +3 -0
  24. package/src/duckdb/src/include/duckdb/main/query_result.hpp +2 -27
  25. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +3 -15
  26. package/src/duckdb/src/include/duckdb/planner/expression_binder.hpp +13 -1
  27. package/src/duckdb/src/include/duckdb/storage/object_cache.hpp +1 -1
  28. package/src/duckdb/src/main/capi/arrow-c.cpp +1 -7
  29. package/src/duckdb/src/main/chunk_scan_state/query_result.cpp +53 -0
  30. package/src/duckdb/src/main/chunk_scan_state.cpp +42 -0
  31. package/src/duckdb/src/main/client_context.cpp +15 -2
  32. package/src/duckdb/src/main/database.cpp +0 -9
  33. package/src/duckdb/src/main/query_result.cpp +0 -21
  34. package/src/duckdb/src/parser/transformer.cpp +2 -16
  35. package/src/duckdb/src/planner/binder/expression/bind_macro_expression.cpp +5 -3
  36. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +0 -28
  37. package/src/duckdb/src/planner/expression_binder.cpp +20 -0
  38. package/src/duckdb/ub_src_main.cpp +2 -0
  39. package/src/duckdb/ub_src_main_chunk_scan_state.cpp +2 -0
  40. package/src/duckdb/src/include/duckdb/common/arrow/arrow_options.hpp +0 -25
@@ -0,0 +1,45 @@
1
+ #pragma once
2
+
3
+ #include "duckdb/common/vector.hpp"
4
+ #include "duckdb/common/unique_ptr.hpp"
5
+ #include "duckdb/common/preserved_error.hpp"
6
+
7
+ namespace duckdb {
8
+
9
+ class DataChunk;
10
+
11
+ //! Abstract chunk fetcher
12
+ class ChunkScanState {
13
+ public:
14
+ explicit ChunkScanState() {
15
+ }
16
+ virtual ~ChunkScanState() {
17
+ }
18
+
19
+ public:
20
+ ChunkScanState(const ChunkScanState &other) = delete;
21
+ ChunkScanState(ChunkScanState &&other) = default;
22
+ ChunkScanState &operator=(const ChunkScanState &other) = delete;
23
+ ChunkScanState &operator=(ChunkScanState &&other) = default;
24
+
25
+ public:
26
+ virtual bool LoadNextChunk(PreservedError &error) = 0;
27
+ virtual bool HasError() const = 0;
28
+ virtual PreservedError &GetError() = 0;
29
+ virtual const vector<LogicalType> &Types() const = 0;
30
+ virtual const vector<string> &Names() const = 0;
31
+ idx_t CurrentOffset() const;
32
+ idx_t RemainingInChunk() const;
33
+ DataChunk &CurrentChunk();
34
+ bool ChunkIsEmpty() const;
35
+ bool Finished() const;
36
+ bool ScanStarted() const;
37
+ void IncreaseOffset(idx_t increment, bool unsafe = false);
38
+
39
+ protected:
40
+ idx_t offset = 0;
41
+ bool finished = false;
42
+ unique_ptr<DataChunk> current_chunk;
43
+ };
44
+
45
+ } // namespace duckdb
@@ -115,8 +115,6 @@ public:
115
115
  static ClientConfig &GetConfig(ClientContext &context);
116
116
  static const ClientConfig &GetConfig(const ClientContext &context);
117
117
 
118
- string ExtractTimezone() const;
119
-
120
118
  bool AnyVerification() {
121
119
  return query_verification_enabled || verify_external || verify_serializer;
122
120
  }
@@ -24,6 +24,7 @@
24
24
  #include "duckdb/main/client_config.hpp"
25
25
  #include "duckdb/main/external_dependencies.hpp"
26
26
  #include "duckdb/common/preserved_error.hpp"
27
+ #include "duckdb/main/client_properties.hpp"
27
28
 
28
29
  namespace duckdb {
29
30
  class Appender;
@@ -0,0 +1,25 @@
1
+ //===----------------------------------------------------------------------===//
2
+ // DuckDB
3
+ //
4
+ // duckdb/main/client_properties.hpp
5
+ //
6
+ //
7
+ //===----------------------------------------------------------------------===//
8
+
9
+ #pragma once
10
+
11
+ #include <string>
12
+
13
+ namespace duckdb {
14
+ enum ArrowOffsetSize { REGULAR, LARGE };
15
+
16
+ //! A set of properties from the client context that can be used to interpret the query result
17
+ struct ClientProperties {
18
+ ClientProperties(string time_zone_p, ArrowOffsetSize arrow_offset_size_p)
19
+ : time_zone(std::move(time_zone_p)), arrow_offset_size(arrow_offset_size_p) {
20
+ }
21
+ ClientProperties() {};
22
+ string time_zone = "UTC";
23
+ ArrowOffsetSize arrow_offset_size = ArrowOffsetSize::REGULAR;
24
+ };
25
+ } // namespace duckdb
@@ -28,7 +28,7 @@
28
28
  #include "duckdb/optimizer/optimizer_extension.hpp"
29
29
  #include "duckdb/parser/parser_extension.hpp"
30
30
  #include "duckdb/planner/operator_extension.hpp"
31
- #include "duckdb/common/arrow/arrow_options.hpp"
31
+ #include "duckdb/main/client_properties.hpp"
32
32
 
33
33
  namespace duckdb {
34
34
  class BufferPool;
@@ -162,6 +162,9 @@ static constexpr ExtensionEntry EXTENSION_FUNCTIONS[] = {{"->>", "json"},
162
162
  {"st_removerepeatedpoints", "spatial"},
163
163
  {"st_geomfromgeojson", "spatial"},
164
164
  {"st_readosm", "spatial"},
165
+ {"st_reduceprecision", "spatial"},
166
+ {"st_geomfromhexwkb", "spatial"},
167
+ {"st_geomfromhexewkb", "spatial"},
165
168
  {"st_numpoints", "spatial"}};
166
169
 
167
170
  static constexpr ExtensionEntry EXTENSION_SETTINGS[] = {
@@ -12,22 +12,13 @@
12
12
  #include "duckdb/common/types/data_chunk.hpp"
13
13
  #include "duckdb/common/winapi.hpp"
14
14
  #include "duckdb/common/preserved_error.hpp"
15
- #include "duckdb/common/arrow/arrow_options.hpp"
15
+ #include "duckdb/main/client_properties.hpp"
16
16
 
17
17
  namespace duckdb {
18
18
  struct BoxRendererConfig;
19
19
 
20
20
  enum class QueryResultType : uint8_t { MATERIALIZED_RESULT, STREAM_RESULT, PENDING_RESULT };
21
21
 
22
- //! A set of properties from the client context that can be used to interpret the query result
23
- struct ClientProperties {
24
- ClientProperties(string time_zone_p, ArrowOffsetSize arrow_offset_size_p)
25
- : time_zone(std::move(time_zone_p)), arrow_offset_size(arrow_offset_size_p) {
26
- }
27
- string time_zone;
28
- ArrowOffsetSize arrow_offset_size;
29
- };
30
-
31
22
  class BaseQueryResult {
32
23
  public:
33
24
  //! Creates a successful query result with the specified names and types
@@ -63,16 +54,7 @@ protected:
63
54
  //! The error (in case execution was not successful)
64
55
  PreservedError error;
65
56
  };
66
- struct CurrentChunk {
67
- //! The current data chunk
68
- unique_ptr<DataChunk> data_chunk;
69
- //! The current position in the data chunk
70
- idx_t position;
71
- //! If we have a current chunk we must scan for result production
72
- bool Valid();
73
- //! The remaining size of the current chunk
74
- idx_t RemainingSize();
75
- };
57
+
76
58
  //! The QueryResult object holds the result of a query. It can either be a MaterializedQueryResult, in which case the
77
59
  //! result contains the entire result set, or a StreamQueryResult in which case the Fetch method can be called to
78
60
  //! incrementally fetch data from the database.
@@ -89,10 +71,6 @@ public:
89
71
  ClientProperties client_properties;
90
72
  //! The next result (if any)
91
73
  unique_ptr<QueryResult> next;
92
- //! In case we are converting the result from Native DuckDB to a different library (e.g., Arrow, Polars)
93
- //! We might be producing chunks of a pre-determined size.
94
- //! To comply, we use the following variable to store the current chunk, and it's position.
95
- CurrentChunk current_chunk;
96
74
 
97
75
  public:
98
76
  template <class TARGET>
@@ -146,9 +124,6 @@ public:
146
124
  }
147
125
  }
148
126
 
149
- static ArrowOptions GetArrowOptions(QueryResult &query_result);
150
- static string GetConfigTimezone(QueryResult &query_result);
151
-
152
127
  private:
153
128
  class QueryResultIterator;
154
129
  class QueryResultRow {
@@ -11,6 +11,7 @@
11
11
  #include "duckdb/common/case_insensitive_map.hpp"
12
12
  #include "duckdb/common/constants.hpp"
13
13
  #include "duckdb/common/enums/expression_type.hpp"
14
+ #include "duckdb/common/stack_checker.hpp"
14
15
  #include "duckdb/common/types.hpp"
15
16
  #include "duckdb/common/unordered_map.hpp"
16
17
  #include "duckdb/parser/group_by_node.hpp"
@@ -26,7 +27,6 @@
26
27
  namespace duckdb {
27
28
 
28
29
  class ColumnDefinition;
29
- class StackChecker;
30
30
  struct OrderByNode;
31
31
  struct CopyInfo;
32
32
  struct CommonTableExpressionInfo;
@@ -39,7 +39,7 @@ struct PivotColumn;
39
39
  //! The transformer class is responsible for transforming the internal Postgres
40
40
  //! parser representation into the DuckDB representation
41
41
  class Transformer {
42
- friend class StackChecker;
42
+ friend class StackChecker<Transformer>;
43
43
 
44
44
  struct CreatePivotEntry {
45
45
  string enum_name;
@@ -343,7 +343,7 @@ private:
343
343
  idx_t stack_depth;
344
344
 
345
345
  void InitializeStackCheck();
346
- StackChecker StackCheck(idx_t extra_stack = 1);
346
+ StackChecker<Transformer> StackCheck(idx_t extra_stack = 1);
347
347
 
348
348
  public:
349
349
  template <class T>
@@ -356,18 +356,6 @@ public:
356
356
  }
357
357
  };
358
358
 
359
- class StackChecker {
360
- public:
361
- StackChecker(Transformer &transformer, idx_t stack_usage);
362
- ~StackChecker();
363
- StackChecker(StackChecker &&) noexcept;
364
- StackChecker(const StackChecker &) = delete;
365
-
366
- private:
367
- Transformer &transformer;
368
- idx_t stack_usage;
369
- };
370
-
371
359
  vector<string> ReadPgListToString(duckdb_libpgquery::PGList *column_list);
372
360
 
373
361
  } // namespace duckdb
@@ -9,11 +9,12 @@
9
9
  #pragma once
10
10
 
11
11
  #include "duckdb/common/exception.hpp"
12
+ #include "duckdb/common/stack_checker.hpp"
13
+ #include "duckdb/common/unordered_map.hpp"
12
14
  #include "duckdb/parser/expression/bound_expression.hpp"
13
15
  #include "duckdb/parser/parsed_expression.hpp"
14
16
  #include "duckdb/parser/tokens.hpp"
15
17
  #include "duckdb/planner/expression.hpp"
16
- #include "duckdb/common/unordered_map.hpp"
17
18
 
18
19
  namespace duckdb {
19
20
 
@@ -51,6 +52,8 @@ struct BindResult {
51
52
  };
52
53
 
53
54
  class ExpressionBinder {
55
+ friend class StackChecker<ExpressionBinder>;
56
+
54
57
  public:
55
58
  ExpressionBinder(Binder &binder, ClientContext &context, bool replace_binder = false);
56
59
  virtual ~ExpressionBinder();
@@ -110,6 +113,15 @@ public:
110
113
 
111
114
  void ReplaceMacroParametersRecursive(unique_ptr<ParsedExpression> &expr);
112
115
 
116
+ private:
117
+ //! Maximum stack depth
118
+ static constexpr const idx_t MAXIMUM_STACK_DEPTH = 128;
119
+ //! Current stack depth
120
+ idx_t stack_depth = DConstants::INVALID_INDEX;
121
+
122
+ void InitializeStackCheck();
123
+ StackChecker<ExpressionBinder> StackCheck(const ParsedExpression &expr, idx_t extra_stack = 1);
124
+
113
125
  protected:
114
126
  BindResult BindExpression(BetweenExpression &expr, idx_t depth);
115
127
  BindResult BindExpression(CaseExpression &expr, idx_t depth);
@@ -48,7 +48,7 @@ public:
48
48
  }
49
49
 
50
50
  template <class T, class... Args>
51
- shared_ptr<T> GetOrCreate(const string &key, Args &&...args) {
51
+ shared_ptr<T> GetOrCreate(const string &key, Args &&... args) {
52
52
  lock_guard<mutex> glock(lock);
53
53
 
54
54
  auto entry = cache.find(key);
@@ -95,13 +95,7 @@ duckdb_state duckdb_execute_prepared_arrow(duckdb_prepared_statement prepared_st
95
95
  return DuckDBError;
96
96
  }
97
97
  auto arrow_wrapper = new ArrowResultWrapper();
98
- if (wrapper->statement->context->config.set_variables.find("TimeZone") ==
99
- wrapper->statement->context->config.set_variables.end()) {
100
- arrow_wrapper->options.time_zone = "UTC";
101
- } else {
102
- arrow_wrapper->options.time_zone =
103
- wrapper->statement->context->config.set_variables["TimeZone"].GetValue<std::string>();
104
- }
98
+ arrow_wrapper->options = wrapper->statement->context->GetClientProperties();
105
99
 
106
100
  auto result = wrapper->statement->Execute(wrapper->values, false);
107
101
  D_ASSERT(result->type == QueryResultType::MATERIALIZED_RESULT);
@@ -0,0 +1,53 @@
1
+ #include "duckdb/main/query_result.hpp"
2
+ #include "duckdb/main/stream_query_result.hpp"
3
+ #include "duckdb/main/chunk_scan_state/query_result.hpp"
4
+
5
+ namespace duckdb {
6
+
7
+ QueryResultChunkScanState::QueryResultChunkScanState(QueryResult &result) : ChunkScanState(), result(result) {
8
+ }
9
+
10
+ QueryResultChunkScanState::~QueryResultChunkScanState() {
11
+ }
12
+
13
+ bool QueryResultChunkScanState::InternalLoad(PreservedError &error) {
14
+ D_ASSERT(!finished);
15
+ if (result.type == QueryResultType::STREAM_RESULT) {
16
+ auto &stream_result = result.Cast<StreamQueryResult>();
17
+ if (!stream_result.IsOpen()) {
18
+ return true;
19
+ }
20
+ }
21
+ return result.TryFetch(current_chunk, error);
22
+ }
23
+
24
+ bool QueryResultChunkScanState::HasError() const {
25
+ return result.HasError();
26
+ }
27
+
28
+ PreservedError &QueryResultChunkScanState::GetError() {
29
+ D_ASSERT(result.HasError());
30
+ return result.GetErrorObject();
31
+ }
32
+
33
+ const vector<LogicalType> &QueryResultChunkScanState::Types() const {
34
+ return result.types;
35
+ }
36
+
37
+ const vector<string> &QueryResultChunkScanState::Names() const {
38
+ return result.names;
39
+ }
40
+
41
+ bool QueryResultChunkScanState::LoadNextChunk(PreservedError &error) {
42
+ if (finished) {
43
+ return !finished;
44
+ }
45
+ auto load_result = InternalLoad(error);
46
+ if (!load_result) {
47
+ finished = true;
48
+ }
49
+ offset = 0;
50
+ return !finished;
51
+ }
52
+
53
+ } // namespace duckdb
@@ -0,0 +1,42 @@
1
+ #include "duckdb/common/types/data_chunk.hpp"
2
+ #include "duckdb/main/chunk_scan_state.hpp"
3
+
4
+ namespace duckdb {
5
+
6
+ idx_t ChunkScanState::CurrentOffset() const {
7
+ return offset;
8
+ }
9
+
10
+ void ChunkScanState::IncreaseOffset(idx_t increment, bool unsafe) {
11
+ D_ASSERT(unsafe || increment <= RemainingInChunk());
12
+ offset += increment;
13
+ }
14
+
15
+ bool ChunkScanState::ChunkIsEmpty() const {
16
+ return !current_chunk || current_chunk->size() == 0;
17
+ }
18
+
19
+ bool ChunkScanState::Finished() const {
20
+ return finished;
21
+ }
22
+
23
+ bool ChunkScanState::ScanStarted() const {
24
+ return !ChunkIsEmpty();
25
+ }
26
+
27
+ DataChunk &ChunkScanState::CurrentChunk() {
28
+ // Scan must already be started
29
+ D_ASSERT(current_chunk);
30
+ return *current_chunk;
31
+ }
32
+
33
+ idx_t ChunkScanState::RemainingInChunk() const {
34
+ if (ChunkIsEmpty()) {
35
+ return 0;
36
+ }
37
+ D_ASSERT(current_chunk);
38
+ D_ASSERT(offset <= current_chunk->size());
39
+ return current_chunk->size() - offset;
40
+ }
41
+
42
+ } // namespace duckdb
@@ -1155,8 +1155,21 @@ ParserOptions ClientContext::GetParserOptions() const {
1155
1155
  }
1156
1156
 
1157
1157
  ClientProperties ClientContext::GetClientProperties() const {
1158
- auto client_context = ClientConfig::GetConfig(*this);
1159
- return {client_context.ExtractTimezone(), db->config.options.arrow_offset_size};
1158
+ string timezone = "UTC";
1159
+ Value result;
1160
+ // 1) Check Set Variable
1161
+ auto &client_config = ClientConfig::GetConfig(*this);
1162
+ auto tz_config = client_config.set_variables.find("timezone");
1163
+ if (tz_config == client_config.set_variables.end()) {
1164
+ // 2) Check for Default Value
1165
+ auto default_value = db->config.extension_parameters.find("timezone");
1166
+ if (default_value != db->config.extension_parameters.end()) {
1167
+ timezone = default_value->second.default_value.GetValue<string>();
1168
+ }
1169
+ } else {
1170
+ timezone = tz_config->second.GetValue<string>();
1171
+ }
1172
+ return {timezone, db->config.options.arrow_offset_size};
1160
1173
  }
1161
1174
 
1162
1175
  bool ClientContext::ExecutionIsFinished() {
@@ -397,15 +397,6 @@ bool DatabaseInstance::TryGetCurrentSetting(const std::string &key, Value &resul
397
397
  return true;
398
398
  }
399
399
 
400
- string ClientConfig::ExtractTimezone() const {
401
- auto entry = set_variables.find("TimeZone");
402
- if (entry == set_variables.end()) {
403
- return "UTC";
404
- } else {
405
- return entry->second.GetValue<std::string>();
406
- }
407
- }
408
-
409
400
  ValidChecker &DatabaseInstance::GetValidChecker() {
410
401
  return db_validity;
411
402
  }
@@ -57,19 +57,6 @@ QueryResult::QueryResult(QueryResultType type, StatementType statement_type, Sta
57
57
  client_properties(std::move(client_properties_p)) {
58
58
  }
59
59
 
60
- bool CurrentChunk::Valid() {
61
- if (data_chunk) {
62
- if (position < data_chunk->size()) {
63
- return true;
64
- }
65
- }
66
- return false;
67
- }
68
-
69
- idx_t CurrentChunk::RemainingSize() {
70
- return data_chunk->size() - position;
71
- }
72
-
73
60
  QueryResult::QueryResult(QueryResultType type, PreservedError error)
74
61
  : BaseQueryResult(type, std::move(error)), client_properties("UTC", ArrowOffsetSize::REGULAR) {
75
62
  }
@@ -164,12 +151,4 @@ string QueryResult::HeaderToString() {
164
151
  return result;
165
152
  }
166
153
 
167
- ArrowOptions QueryResult::GetArrowOptions(QueryResult &query_result) {
168
- return {query_result.client_properties.arrow_offset_size, query_result.client_properties.time_zone};
169
- }
170
-
171
- string QueryResult::GetConfigTimezone(QueryResult &query_result) {
172
- return query_result.client_properties.time_zone;
173
- }
174
-
175
154
  } // namespace duckdb
@@ -9,20 +9,6 @@
9
9
 
10
10
  namespace duckdb {
11
11
 
12
- StackChecker::StackChecker(Transformer &transformer_p, idx_t stack_usage_p)
13
- : transformer(transformer_p), stack_usage(stack_usage_p) {
14
- transformer.stack_depth += stack_usage;
15
- }
16
-
17
- StackChecker::~StackChecker() {
18
- transformer.stack_depth -= stack_usage;
19
- }
20
-
21
- StackChecker::StackChecker(StackChecker &&other) noexcept
22
- : transformer(other.transformer), stack_usage(other.stack_usage) {
23
- other.stack_usage = 0;
24
- }
25
-
26
12
  Transformer::Transformer(ParserOptions &options)
27
13
  : parent(nullptr), options(options), stack_depth(DConstants::INVALID_INDEX) {
28
14
  }
@@ -59,7 +45,7 @@ void Transformer::InitializeStackCheck() {
59
45
  stack_depth = 0;
60
46
  }
61
47
 
62
- StackChecker Transformer::StackCheck(idx_t extra_stack) {
48
+ StackChecker<Transformer> Transformer::StackCheck(idx_t extra_stack) {
63
49
  auto &root = RootTransformer();
64
50
  D_ASSERT(root.stack_depth != DConstants::INVALID_INDEX);
65
51
  if (root.stack_depth + extra_stack >= options.max_expression_depth) {
@@ -67,7 +53,7 @@ StackChecker Transformer::StackCheck(idx_t extra_stack) {
67
53
  "increase the maximum expression depth.",
68
54
  options.max_expression_depth);
69
55
  }
70
- return StackChecker(root, extra_stack);
56
+ return StackChecker<Transformer>(root, extra_stack);
71
57
  }
72
58
 
73
59
  unique_ptr<SQLStatement> Transformer::TransformStatement(duckdb_libpgquery::PGNode &stmt) {
@@ -1,12 +1,12 @@
1
1
  #include "duckdb/catalog/catalog_entry/scalar_macro_catalog_entry.hpp"
2
+ #include "duckdb/common/reference_map.hpp"
2
3
  #include "duckdb/common/string_util.hpp"
4
+ #include "duckdb/function/scalar_macro_function.hpp"
3
5
  #include "duckdb/parser/expression/function_expression.hpp"
4
6
  #include "duckdb/parser/expression/subquery_expression.hpp"
5
7
  #include "duckdb/parser/parsed_expression_iterator.hpp"
6
8
  #include "duckdb/planner/expression_binder.hpp"
7
9
 
8
- #include "duckdb/function/scalar_macro_function.hpp"
9
-
10
10
  namespace duckdb {
11
11
 
12
12
  void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpression> &expr) {
@@ -79,8 +79,10 @@ BindResult ExpressionBinder::BindMacro(FunctionExpression &function, ScalarMacro
79
79
  new_macro_binding->arguments = &positionals;
80
80
  macro_binding = new_macro_binding.get();
81
81
 
82
- // replace current expression with stored macro expression, and replace params
82
+ // replace current expression with stored macro expression
83
83
  expr = macro_def.expression->Copy();
84
+
85
+ // now replace the parameters
84
86
  ReplaceMacroParametersRecursive(expr);
85
87
 
86
88
  // bind the unfolded macro
@@ -134,33 +134,6 @@ void Binder::BindCreateViewInfo(CreateViewInfo &base) {
134
134
  base.types = query_node.types;
135
135
  }
136
136
 
137
- static void QualifyFunctionNames(ClientContext &context, unique_ptr<ParsedExpression> &expr) {
138
- switch (expr->GetExpressionClass()) {
139
- case ExpressionClass::FUNCTION: {
140
- auto &func = expr->Cast<FunctionExpression>();
141
- auto function = Catalog::GetEntry(context, CatalogType::SCALAR_FUNCTION_ENTRY, func.catalog, func.schema,
142
- func.function_name, OnEntryNotFound::RETURN_NULL);
143
- if (function) {
144
- func.catalog = function->ParentCatalog().GetName();
145
- func.schema = function->ParentSchema().name;
146
- }
147
- break;
148
- }
149
- case ExpressionClass::SUBQUERY: {
150
- // replacing parameters within a subquery is slightly different
151
- auto &sq = (expr->Cast<SubqueryExpression>()).subquery;
152
- ParsedExpressionIterator::EnumerateQueryNodeChildren(
153
- *sq->node, [&](unique_ptr<ParsedExpression> &child) { QualifyFunctionNames(context, child); });
154
- break;
155
- }
156
- default: // fall through
157
- break;
158
- }
159
- // unfold child expressions
160
- ParsedExpressionIterator::EnumerateChildren(
161
- *expr, [&](unique_ptr<ParsedExpression> &child) { QualifyFunctionNames(context, child); });
162
- }
163
-
164
137
  SchemaCatalogEntry &Binder::BindCreateFunctionInfo(CreateInfo &info) {
165
138
  auto &base = info.Cast<CreateMacroInfo>();
166
139
  auto &scalar_function = base.function->Cast<ScalarMacroFunction>();
@@ -190,7 +163,6 @@ SchemaCatalogEntry &Binder::BindCreateFunctionInfo(CreateInfo &info) {
190
163
  auto this_macro_binding = make_uniq<DummyBinding>(dummy_types, dummy_names, base.name);
191
164
  macro_binding = this_macro_binding.get();
192
165
  ExpressionBinder::QualifyColumnNames(*this, scalar_function.expression);
193
- QualifyFunctionNames(context, scalar_function.expression);
194
166
 
195
167
  // create a copy of the expression because we do not want to alter the original
196
168
  auto expression = scalar_function.expression->Copy();
@@ -10,6 +10,7 @@ namespace duckdb {
10
10
 
11
11
  ExpressionBinder::ExpressionBinder(Binder &binder, ClientContext &context, bool replace_binder)
12
12
  : binder(binder), context(context) {
13
+ InitializeStackCheck();
13
14
  if (replace_binder) {
14
15
  stored_binder = &binder.GetActiveBinder();
15
16
  binder.SetActiveBinder(*this);
@@ -28,7 +29,26 @@ ExpressionBinder::~ExpressionBinder() {
28
29
  }
29
30
  }
30
31
 
32
+ void ExpressionBinder::InitializeStackCheck() {
33
+ if (binder.HasActiveBinder()) {
34
+ stack_depth = binder.GetActiveBinder().stack_depth;
35
+ } else {
36
+ stack_depth = 0;
37
+ }
38
+ }
39
+
40
+ StackChecker<ExpressionBinder> ExpressionBinder::StackCheck(const ParsedExpression &expr, idx_t extra_stack) {
41
+ D_ASSERT(stack_depth != DConstants::INVALID_INDEX);
42
+ if (stack_depth + extra_stack >= MAXIMUM_STACK_DEPTH) {
43
+ throw BinderException("Maximum recursion depth exceeded (Maximum: %llu) while binding \"%s\"",
44
+ MAXIMUM_STACK_DEPTH, expr.ToString());
45
+ }
46
+ return StackChecker<ExpressionBinder>(*this, extra_stack);
47
+ }
48
+
31
49
  BindResult ExpressionBinder::BindExpression(unique_ptr<ParsedExpression> &expr, idx_t depth, bool root_expression) {
50
+ auto stack_checker = StackCheck(*expr);
51
+
32
52
  auto &expr_ref = *expr;
33
53
  switch (expr_ref.expression_class) {
34
54
  case ExpressionClass::BETWEEN:
@@ -10,6 +10,8 @@
10
10
 
11
11
  #include "src/main/client_verify.cpp"
12
12
 
13
+ #include "src/main/chunk_scan_state.cpp"
14
+
13
15
  #include "src/main/config.cpp"
14
16
 
15
17
  #include "src/main/connection.cpp"
@@ -0,0 +1,2 @@
1
+ #include "src/main/chunk_scan_state/query_result.cpp"
2
+
@@ -1,25 +0,0 @@
1
- //===----------------------------------------------------------------------===//
2
- // DuckDB
3
- //
4
- // duckdb/common/arrow/arrow_options.hpp
5
- //
6
- //
7
- //===----------------------------------------------------------------------===//
8
-
9
- #pragma once
10
-
11
- namespace duckdb {
12
-
13
- enum ArrowOffsetSize { REGULAR, LARGE };
14
-
15
- struct ArrowOptions {
16
- explicit ArrowOptions(ArrowOffsetSize offset_size_p) : offset_size(offset_size_p) {
17
- }
18
- ArrowOptions(ArrowOffsetSize offset_size_p, string timezone_p) : offset_size(offset_size_p), time_zone(timezone_p) {
19
- }
20
- ArrowOptions() {
21
- }
22
- ArrowOffsetSize offset_size = ArrowOffsetSize::REGULAR;
23
- string time_zone = "UTC";
24
- };
25
- } // namespace duckdb