duckdb 0.3.1-dev11.0 → 0.3.1-dev210.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.cpp +17026 -14141
- package/src/duckdb.hpp +303 -183
package/src/duckdb.hpp
CHANGED
|
@@ -10,8 +10,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
10
10
|
|
|
11
11
|
#pragma once
|
|
12
12
|
#define DUCKDB_AMALGAMATION 1
|
|
13
|
-
#define DUCKDB_SOURCE_ID "
|
|
14
|
-
#define DUCKDB_VERSION "0.3.1-
|
|
13
|
+
#define DUCKDB_SOURCE_ID "f05f6f50f"
|
|
14
|
+
#define DUCKDB_VERSION "0.3.1-dev210"
|
|
15
15
|
//===----------------------------------------------------------------------===//
|
|
16
16
|
// DuckDB
|
|
17
17
|
//
|
|
@@ -567,11 +567,12 @@ using std::vector;
|
|
|
567
567
|
#endif
|
|
568
568
|
|
|
569
569
|
|
|
570
|
+
|
|
570
571
|
namespace duckdb {
|
|
571
572
|
|
|
572
573
|
class Serializer;
|
|
573
574
|
class Deserializer;
|
|
574
|
-
|
|
575
|
+
class Value;
|
|
575
576
|
//! Type used to represent dates (days since 1970-01-01)
|
|
576
577
|
struct date_t {
|
|
577
578
|
int32_t days;
|
|
@@ -861,12 +862,12 @@ enum class PhysicalType : uint8_t {
|
|
|
861
862
|
/// Like LIST, but with 64-bit offsets
|
|
862
863
|
LARGE_LIST = 33,
|
|
863
864
|
|
|
864
|
-
|
|
865
|
+
/// DuckDB Extensions
|
|
865
866
|
VARCHAR = 200, // our own string representation, different from STRING and LARGE_STRING above
|
|
866
867
|
INT128 = 204, // 128-bit integers
|
|
867
|
-
|
|
868
|
+
UNKNOWN = 205, // Unknown physical type of user defined types
|
|
868
869
|
/// Boolean as 1 bit, LSB bit-packed ordering
|
|
869
|
-
BIT =
|
|
870
|
+
BIT = 206,
|
|
870
871
|
|
|
871
872
|
INVALID = 255
|
|
872
873
|
};
|
|
@@ -879,7 +880,7 @@ enum class LogicalTypeId : uint8_t {
|
|
|
879
880
|
SQLNULL = 1, /* NULL type, used for constant NULL */
|
|
880
881
|
UNKNOWN = 2, /* unknown type, used for parameter expressions */
|
|
881
882
|
ANY = 3, /* ANY type, used for functions that accept any type as parameter */
|
|
882
|
-
|
|
883
|
+
USER = 4, /* A User Defined Type (e.g., ENUMs before the binder) */
|
|
883
884
|
BOOLEAN = 10,
|
|
884
885
|
TINYINT = 11,
|
|
885
886
|
SMALLINT = 12,
|
|
@@ -913,7 +914,8 @@ enum class LogicalTypeId : uint8_t {
|
|
|
913
914
|
STRUCT = 100,
|
|
914
915
|
LIST = 101,
|
|
915
916
|
MAP = 102,
|
|
916
|
-
TABLE = 103
|
|
917
|
+
TABLE = 103,
|
|
918
|
+
ENUM = 104
|
|
917
919
|
};
|
|
918
920
|
|
|
919
921
|
struct ExtraTypeInfo;
|
|
@@ -922,6 +924,7 @@ struct LogicalType {
|
|
|
922
924
|
DUCKDB_API LogicalType();
|
|
923
925
|
DUCKDB_API LogicalType(LogicalTypeId id); // NOLINT: Allow implicit conversion from `LogicalTypeId`
|
|
924
926
|
DUCKDB_API LogicalType(LogicalTypeId id, shared_ptr<ExtraTypeInfo> type_info);
|
|
927
|
+
|
|
925
928
|
DUCKDB_API LogicalType(const LogicalType &other) :
|
|
926
929
|
id_(other.id_), physical_type_(other.physical_type_), type_info_(other.type_info_) {}
|
|
927
930
|
|
|
@@ -1018,10 +1021,11 @@ public:
|
|
|
1018
1021
|
// explicitly allowing these functions to be capitalized to be in-line with the remaining functions
|
|
1019
1022
|
DUCKDB_API static LogicalType DECIMAL(int width, int scale); // NOLINT
|
|
1020
1023
|
DUCKDB_API static LogicalType VARCHAR_COLLATION(string collation); // NOLINT
|
|
1021
|
-
DUCKDB_API static LogicalType LIST(LogicalType child); // NOLINT
|
|
1022
|
-
DUCKDB_API static LogicalType STRUCT(child_list_t<LogicalType> children); // NOLINT
|
|
1023
|
-
DUCKDB_API static LogicalType MAP(child_list_t<LogicalType> children); // NOLINT
|
|
1024
|
-
|
|
1024
|
+
DUCKDB_API static LogicalType LIST( LogicalType child); // NOLINT
|
|
1025
|
+
DUCKDB_API static LogicalType STRUCT( child_list_t<LogicalType> children); // NOLINT
|
|
1026
|
+
DUCKDB_API static LogicalType MAP( child_list_t<LogicalType> children); // NOLINT
|
|
1027
|
+
DUCKDB_API static LogicalType ENUM(const string &enum_name, const vector<string> &ordered_data); // NOLINT
|
|
1028
|
+
DUCKDB_API static LogicalType USER(const string &user_type_name); // NOLINT
|
|
1025
1029
|
//! A list of all NUMERIC types (integral and floating point types)
|
|
1026
1030
|
DUCKDB_API static const vector<LogicalType> NUMERIC;
|
|
1027
1031
|
//! A list of all INTEGRAL types
|
|
@@ -1043,6 +1047,18 @@ struct ListType {
|
|
|
1043
1047
|
DUCKDB_API static const LogicalType &GetChildType(const LogicalType &type);
|
|
1044
1048
|
};
|
|
1045
1049
|
|
|
1050
|
+
struct UserType{
|
|
1051
|
+
DUCKDB_API static const string &GetTypeName(const LogicalType &type);
|
|
1052
|
+
};
|
|
1053
|
+
|
|
1054
|
+
struct EnumType{
|
|
1055
|
+
DUCKDB_API static const string &GetTypeName(const LogicalType &type);
|
|
1056
|
+
DUCKDB_API static int64_t GetPos(const LogicalType &type, const string& key);
|
|
1057
|
+
DUCKDB_API static const vector<string> &GetValuesInsertOrder(const LogicalType &type);
|
|
1058
|
+
DUCKDB_API static idx_t GetSize(const LogicalType &type);
|
|
1059
|
+
DUCKDB_API static const string& GetValue(const Value &val);
|
|
1060
|
+
};
|
|
1061
|
+
|
|
1046
1062
|
struct StructType {
|
|
1047
1063
|
DUCKDB_API static const child_list_t<LogicalType> &GetChildTypes(const LogicalType &type);
|
|
1048
1064
|
DUCKDB_API static const LogicalType &GetChildType(const LogicalType &type, idx_t index);
|
|
@@ -1497,7 +1513,7 @@ public:
|
|
|
1497
1513
|
//! Write a string with a length prefix
|
|
1498
1514
|
void WriteString(const string &val) {
|
|
1499
1515
|
Write<uint32_t>((uint32_t)val.size());
|
|
1500
|
-
if (val.
|
|
1516
|
+
if (!val.empty()) {
|
|
1501
1517
|
WriteData((const_data_ptr_t)val.c_str(), val.size());
|
|
1502
1518
|
}
|
|
1503
1519
|
}
|
|
@@ -2568,6 +2584,9 @@ public:
|
|
|
2568
2584
|
DUCKDB_API static Value INTERVAL(int32_t months, int32_t days, int64_t micros);
|
|
2569
2585
|
DUCKDB_API static Value INTERVAL(interval_t interval);
|
|
2570
2586
|
|
|
2587
|
+
// Create a enum Value from a specified uint value
|
|
2588
|
+
DUCKDB_API static Value ENUM(uint64_t value, const LogicalType &original_type);
|
|
2589
|
+
|
|
2571
2590
|
// Decimal values
|
|
2572
2591
|
DUCKDB_API static Value DECIMAL(int16_t value, uint8_t width, uint8_t scale);
|
|
2573
2592
|
DUCKDB_API static Value DECIMAL(int32_t value, uint8_t width, uint8_t scale);
|
|
@@ -3293,6 +3312,9 @@ public:
|
|
|
3293
3312
|
//! Without changing the type of this vector
|
|
3294
3313
|
void Reinterpret(Vector &other);
|
|
3295
3314
|
|
|
3315
|
+
//! Causes this vector to reference the data held by the other vector, changes the type if required.
|
|
3316
|
+
void ReferenceAndSetType(Vector &other);
|
|
3317
|
+
|
|
3296
3318
|
//! Resets a vector from a vector cache.
|
|
3297
3319
|
//! This turns the vector back into an empty FlatVector with STANDARD_VECTOR_SIZE entries.
|
|
3298
3320
|
//! The VectorCache is used so this can be done without requiring any allocations.
|
|
@@ -7134,6 +7156,7 @@ enum class CatalogType : uint8_t {
|
|
|
7134
7156
|
PREPARED_STATEMENT = 5,
|
|
7135
7157
|
SEQUENCE_ENTRY = 6,
|
|
7136
7158
|
COLLATION_ENTRY = 7,
|
|
7159
|
+
TYPE_ENTRY = 8,
|
|
7137
7160
|
|
|
7138
7161
|
// functions
|
|
7139
7162
|
TABLE_FUNCTION_ENTRY = 25,
|
|
@@ -7302,6 +7325,7 @@ struct CreateFunctionInfo;
|
|
|
7302
7325
|
struct CreateViewInfo;
|
|
7303
7326
|
struct CreateSequenceInfo;
|
|
7304
7327
|
struct CreateCollationInfo;
|
|
7328
|
+
struct CreateTypeInfo;
|
|
7305
7329
|
|
|
7306
7330
|
class ClientContext;
|
|
7307
7331
|
class Transaction;
|
|
@@ -7390,6 +7414,8 @@ public:
|
|
|
7390
7414
|
CatalogEntry *CreateView(ClientContext &context, CreateViewInfo *info);
|
|
7391
7415
|
//! Creates a table in the catalog.
|
|
7392
7416
|
CatalogEntry *CreateSequence(ClientContext &context, CreateSequenceInfo *info);
|
|
7417
|
+
//! Creates a Enum in the catalog.
|
|
7418
|
+
CatalogEntry *CreateType(ClientContext &context, CreateTypeInfo *info);
|
|
7393
7419
|
//! Creates a collation in the catalog
|
|
7394
7420
|
CatalogEntry *CreateCollation(ClientContext &context, CreateCollationInfo *info);
|
|
7395
7421
|
|
|
@@ -7409,6 +7435,8 @@ public:
|
|
|
7409
7435
|
CatalogEntry *CreateView(ClientContext &context, SchemaCatalogEntry *schema, CreateViewInfo *info);
|
|
7410
7436
|
//! Creates a table in the catalog.
|
|
7411
7437
|
CatalogEntry *CreateSequence(ClientContext &context, SchemaCatalogEntry *schema, CreateSequenceInfo *info);
|
|
7438
|
+
//! Creates a enum in the catalog.
|
|
7439
|
+
CatalogEntry *CreateType(ClientContext &context, SchemaCatalogEntry *schema, CreateTypeInfo *info);
|
|
7412
7440
|
//! Creates a collation in the catalog
|
|
7413
7441
|
CatalogEntry *CreateCollation(ClientContext &context, SchemaCatalogEntry *schema, CreateCollationInfo *info);
|
|
7414
7442
|
|
|
@@ -7555,6 +7583,7 @@ enum class LogicalOperatorType : uint8_t {
|
|
|
7555
7583
|
LOGICAL_DROP = 132,
|
|
7556
7584
|
LOGICAL_PRAGMA = 133,
|
|
7557
7585
|
LOGICAL_TRANSACTION = 134,
|
|
7586
|
+
LOGICAL_CREATE_TYPE = 135,
|
|
7558
7587
|
|
|
7559
7588
|
// -----------------------------
|
|
7560
7589
|
// Explain
|
|
@@ -9249,7 +9278,7 @@ public:
|
|
|
9249
9278
|
//! Delete from a table, can only be used on a TableRelation
|
|
9250
9279
|
DUCKDB_API virtual void Delete(const string &condition = string());
|
|
9251
9280
|
//! Create a relation from calling a table in/out function on the input relation
|
|
9252
|
-
DUCKDB_API shared_ptr<Relation> TableFunction(const std::string &fname, vector<Value> values);
|
|
9281
|
+
DUCKDB_API shared_ptr<Relation> TableFunction(const std::string &fname, const vector<Value> &values);
|
|
9253
9282
|
|
|
9254
9283
|
public:
|
|
9255
9284
|
//! Whether or not the relation inherits column bindings from its child or not, only relevant for binding
|
|
@@ -9504,7 +9533,7 @@ public:
|
|
|
9504
9533
|
DUCKDB_API shared_ptr<Relation> ReadCSV(const string &csv_file);
|
|
9505
9534
|
DUCKDB_API shared_ptr<Relation> ReadCSV(const string &csv_file, const vector<string> &columns);
|
|
9506
9535
|
//! Returns a relation from a query
|
|
9507
|
-
DUCKDB_API shared_ptr<Relation> RelationFromQuery(string query, string alias = "queryrelation");
|
|
9536
|
+
DUCKDB_API shared_ptr<Relation> RelationFromQuery(const string &query, const string &alias = "queryrelation");
|
|
9508
9537
|
|
|
9509
9538
|
DUCKDB_API void BeginTransaction();
|
|
9510
9539
|
DUCKDB_API void Commit();
|
|
@@ -12138,6 +12167,7 @@ struct CreateSequenceInfo;
|
|
|
12138
12167
|
struct CreateSchemaInfo;
|
|
12139
12168
|
struct CreateTableFunctionInfo;
|
|
12140
12169
|
struct CreateCopyFunctionInfo;
|
|
12170
|
+
struct CreateTypeInfo;
|
|
12141
12171
|
|
|
12142
12172
|
struct DropInfo;
|
|
12143
12173
|
|
|
@@ -12165,6 +12195,8 @@ private:
|
|
|
12165
12195
|
CatalogSet sequences;
|
|
12166
12196
|
//! The catalog set holding the collations
|
|
12167
12197
|
CatalogSet collations;
|
|
12198
|
+
//! The catalog set holding the types
|
|
12199
|
+
CatalogSet types;
|
|
12168
12200
|
|
|
12169
12201
|
public:
|
|
12170
12202
|
//! Scan the specified catalog set, invoking the callback method for every entry
|
|
@@ -12199,6 +12231,8 @@ private:
|
|
|
12199
12231
|
CatalogEntry *CreatePragmaFunction(ClientContext &context, CreatePragmaFunctionInfo *info);
|
|
12200
12232
|
//! Create a collation within the given schema
|
|
12201
12233
|
CatalogEntry *CreateCollation(ClientContext &context, CreateCollationInfo *info);
|
|
12234
|
+
//! Create a enum within the given schema
|
|
12235
|
+
CatalogEntry *CreateType(ClientContext &context, CreateTypeInfo *info);
|
|
12202
12236
|
|
|
12203
12237
|
//! Drops an entry from the schema
|
|
12204
12238
|
void DropEntry(ClientContext &context, DropInfo *info);
|
|
@@ -12307,16 +12341,6 @@ using std::thread;
|
|
|
12307
12341
|
|
|
12308
12342
|
|
|
12309
12343
|
|
|
12310
|
-
//===----------------------------------------------------------------------===//
|
|
12311
|
-
// DuckDB
|
|
12312
|
-
//
|
|
12313
|
-
// duckdb/execution/physical_sink.hpp
|
|
12314
|
-
//
|
|
12315
|
-
//
|
|
12316
|
-
//===----------------------------------------------------------------------===//
|
|
12317
|
-
|
|
12318
|
-
|
|
12319
|
-
|
|
12320
12344
|
//===----------------------------------------------------------------------===//
|
|
12321
12345
|
// DuckDB
|
|
12322
12346
|
//
|
|
@@ -12407,6 +12431,7 @@ enum class PhysicalOperatorType : uint8_t {
|
|
|
12407
12431
|
DROP,
|
|
12408
12432
|
PRAGMA,
|
|
12409
12433
|
TRANSACTION,
|
|
12434
|
+
CREATE_TYPE,
|
|
12410
12435
|
|
|
12411
12436
|
// -----------------------------
|
|
12412
12437
|
// Helpers
|
|
@@ -12442,60 +12467,110 @@ string PhysicalOperatorToString(PhysicalOperatorType type);
|
|
|
12442
12467
|
namespace duckdb {
|
|
12443
12468
|
class ClientContext;
|
|
12444
12469
|
class ThreadContext;
|
|
12445
|
-
class TaskContext;
|
|
12446
12470
|
|
|
12447
12471
|
class ExecutionContext {
|
|
12448
12472
|
public:
|
|
12449
|
-
ExecutionContext(ClientContext &client_p, ThreadContext &thread_p,
|
|
12450
|
-
: client(client_p), thread(thread_p), task(task_p) {
|
|
12473
|
+
ExecutionContext(ClientContext &client_p, ThreadContext &thread_p) : client(client_p), thread(thread_p) {
|
|
12451
12474
|
}
|
|
12452
12475
|
|
|
12453
12476
|
//! The client-global context; caution needs to be taken when used in parallel situations
|
|
12454
12477
|
ClientContext &client;
|
|
12455
12478
|
//! The thread-local context for this execution
|
|
12456
12479
|
ThreadContext &thread;
|
|
12457
|
-
//! The task context for this execution
|
|
12458
|
-
TaskContext &task;
|
|
12459
12480
|
};
|
|
12460
12481
|
|
|
12461
12482
|
} // namespace duckdb
|
|
12462
12483
|
|
|
12484
|
+
//===----------------------------------------------------------------------===//
|
|
12485
|
+
// DuckDB
|
|
12486
|
+
//
|
|
12487
|
+
// duckdb/common/enums/operator_result_type.hpp
|
|
12488
|
+
//
|
|
12489
|
+
//
|
|
12490
|
+
//===----------------------------------------------------------------------===//
|
|
12491
|
+
|
|
12492
|
+
|
|
12463
12493
|
|
|
12464
12494
|
|
|
12465
|
-
#include <functional>
|
|
12466
|
-
#include <utility>
|
|
12467
12495
|
|
|
12468
12496
|
namespace duckdb {
|
|
12469
|
-
|
|
12497
|
+
|
|
12498
|
+
//! The OperatorResultType is used to indicate how data should flow around a regular (i.e. non-sink and non-source)
|
|
12499
|
+
//! physical operator
|
|
12500
|
+
//! There are three possible results:
|
|
12501
|
+
//! NEED_MORE_INPUT means the operator is done with the current input and can consume more input if available
|
|
12502
|
+
//! If there is more input the operator will be called with more input, otherwise the operator will not be called again.
|
|
12503
|
+
//! HAVE_MORE_OUTPUT means the operator is not finished yet with the current input.
|
|
12504
|
+
//! The operator will be called again with the same input.
|
|
12505
|
+
//! FINISHED means the operator has finished the entire pipeline and no more processing is necessary.
|
|
12506
|
+
//! The operator will not be called again, and neither will any other operators in this pipeline.
|
|
12507
|
+
enum class OperatorResultType : uint8_t { NEED_MORE_INPUT, HAVE_MORE_OUTPUT, FINISHED };
|
|
12508
|
+
|
|
12509
|
+
//! The SinkResultType is used to indicate the result of data flowing into a sink
|
|
12510
|
+
//! There are two possible results:
|
|
12511
|
+
//! NEED_MORE_INPUT means the sink needs more input
|
|
12512
|
+
//! FINISHED means the sink is finished executing, and more input will not change the result any further
|
|
12513
|
+
enum class SinkResultType : uint8_t { NEED_MORE_INPUT, FINISHED };
|
|
12514
|
+
|
|
12515
|
+
//! The SinkFinalizeType is used to indicate the result of a Finalize call on a sink
|
|
12516
|
+
//! There are two possible results:
|
|
12517
|
+
//! READY means the sink is ready for further processing
|
|
12518
|
+
//! NO_OUTPUT_POSSIBLE means the sink will never provide output, and any pipelines involving the sink can be skipped
|
|
12519
|
+
enum class SinkFinalizeType : uint8_t { READY, NO_OUTPUT_POSSIBLE };
|
|
12520
|
+
|
|
12521
|
+
} // namespace duckdb
|
|
12522
|
+
|
|
12523
|
+
|
|
12524
|
+
namespace duckdb {
|
|
12525
|
+
class Event;
|
|
12470
12526
|
class PhysicalOperator;
|
|
12527
|
+
class Pipeline;
|
|
12528
|
+
|
|
12529
|
+
// LCOV_EXCL_START
|
|
12530
|
+
class OperatorState {
|
|
12531
|
+
public:
|
|
12532
|
+
virtual ~OperatorState() {
|
|
12533
|
+
}
|
|
12471
12534
|
|
|
12472
|
-
|
|
12473
|
-
|
|
12474
|
-
|
|
12475
|
-
|
|
12476
|
-
class
|
|
12535
|
+
virtual void Finalize(PhysicalOperator *op, ExecutionContext &context) {
|
|
12536
|
+
}
|
|
12537
|
+
};
|
|
12538
|
+
|
|
12539
|
+
class GlobalSinkState {
|
|
12477
12540
|
public:
|
|
12478
|
-
|
|
12479
|
-
|
|
12541
|
+
GlobalSinkState() : state(SinkFinalizeType::READY) {
|
|
12542
|
+
}
|
|
12543
|
+
virtual ~GlobalSinkState() {
|
|
12544
|
+
}
|
|
12480
12545
|
|
|
12481
|
-
|
|
12482
|
-
//! operators use this flag]
|
|
12483
|
-
bool finished;
|
|
12484
|
-
//! DataChunk that stores data from the child of this operator
|
|
12485
|
-
DataChunk child_chunk;
|
|
12486
|
-
//! State of the child of this operator
|
|
12487
|
-
unique_ptr<PhysicalOperatorState> child_state;
|
|
12546
|
+
SinkFinalizeType state;
|
|
12488
12547
|
};
|
|
12489
12548
|
|
|
12549
|
+
class LocalSinkState {
|
|
12550
|
+
public:
|
|
12551
|
+
virtual ~LocalSinkState() {
|
|
12552
|
+
}
|
|
12553
|
+
};
|
|
12554
|
+
|
|
12555
|
+
class GlobalSourceState {
|
|
12556
|
+
public:
|
|
12557
|
+
virtual ~GlobalSourceState() {
|
|
12558
|
+
}
|
|
12559
|
+
|
|
12560
|
+
virtual idx_t MaxThreads() {
|
|
12561
|
+
return 1;
|
|
12562
|
+
}
|
|
12563
|
+
};
|
|
12564
|
+
|
|
12565
|
+
class LocalSourceState {
|
|
12566
|
+
public:
|
|
12567
|
+
virtual ~LocalSourceState() {
|
|
12568
|
+
}
|
|
12569
|
+
};
|
|
12570
|
+
// LCOV_EXCL_STOP
|
|
12571
|
+
|
|
12490
12572
|
//! PhysicalOperator is the base class of the physical operators present in the
|
|
12491
12573
|
//! execution plan
|
|
12492
|
-
/*!
|
|
12493
|
-
The execution model is a pull-based execution model. GetChunk is called on
|
|
12494
|
-
the root node, which causes the root node to be executed, and presumably call
|
|
12495
|
-
GetChunk again on its child nodes. Every node in the operator chain has a
|
|
12496
|
-
state that is updated as GetChunk is called: PhysicalOperatorState (different
|
|
12497
|
-
operators subclass this state and add different properties).
|
|
12498
|
-
*/
|
|
12499
12574
|
class PhysicalOperator {
|
|
12500
12575
|
public:
|
|
12501
12576
|
PhysicalOperator(PhysicalOperatorType type, vector<LogicalType> types, idx_t estimated_cardinality)
|
|
@@ -12512,6 +12587,8 @@ public:
|
|
|
12512
12587
|
vector<LogicalType> types;
|
|
12513
12588
|
//! The extimated cardinality of this physical operator
|
|
12514
12589
|
idx_t estimated_cardinality;
|
|
12590
|
+
//! The global sink state of this operator
|
|
12591
|
+
unique_ptr<GlobalSinkState> sink_state;
|
|
12515
12592
|
|
|
12516
12593
|
public:
|
|
12517
12594
|
virtual string GetName() const;
|
|
@@ -12519,97 +12596,78 @@ public:
|
|
|
12519
12596
|
return "";
|
|
12520
12597
|
}
|
|
12521
12598
|
virtual string ToString() const;
|
|
12522
|
-
void Print();
|
|
12599
|
+
void Print() const;
|
|
12523
12600
|
|
|
12524
12601
|
//! Return a vector of the types that will be returned by this operator
|
|
12525
|
-
vector<LogicalType> &GetTypes() {
|
|
12602
|
+
const vector<LogicalType> &GetTypes() const {
|
|
12526
12603
|
return types;
|
|
12527
12604
|
}
|
|
12528
|
-
//! Initialize a given chunk to the types that will be returned by this
|
|
12529
|
-
//! operator, this will prepare chunk for a call to GetChunk. This method
|
|
12530
|
-
//! only has to be called once for any amount of calls to GetChunk.
|
|
12531
|
-
virtual void InitializeChunk(DataChunk &chunk) {
|
|
12532
|
-
auto &types = GetTypes();
|
|
12533
|
-
chunk.Initialize(types);
|
|
12534
|
-
}
|
|
12535
|
-
//! Retrieves a chunk from this operator and stores it in the chunk
|
|
12536
|
-
//! variable.
|
|
12537
|
-
virtual void GetChunkInternal(ExecutionContext &context, DataChunk &chunk, PhysicalOperatorState *state) const = 0;
|
|
12538
12605
|
|
|
12539
|
-
|
|
12540
|
-
|
|
12541
|
-
//! Create a new empty instance of the operator state
|
|
12542
|
-
virtual unique_ptr<PhysicalOperatorState> GetOperatorState() {
|
|
12543
|
-
return make_unique<PhysicalOperatorState>(*this, children.size() == 0 ? nullptr : children[0].get());
|
|
12606
|
+
virtual bool Equals(const PhysicalOperator &other) const {
|
|
12607
|
+
return false;
|
|
12544
12608
|
}
|
|
12545
12609
|
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
-
|
|
12549
|
-
|
|
12550
|
-
|
|
12610
|
+
public:
|
|
12611
|
+
// Operator interface
|
|
12612
|
+
virtual unique_ptr<OperatorState> GetOperatorState(ClientContext &context) const;
|
|
12613
|
+
virtual OperatorResultType Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk,
|
|
12614
|
+
OperatorState &state) const;
|
|
12551
12615
|
|
|
12552
|
-
virtual bool
|
|
12616
|
+
virtual bool ParallelOperator() const {
|
|
12553
12617
|
return false;
|
|
12554
12618
|
}
|
|
12555
|
-
};
|
|
12556
|
-
|
|
12557
|
-
} // namespace duckdb
|
|
12558
12619
|
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
class Pipeline;
|
|
12563
|
-
|
|
12564
|
-
class GlobalOperatorState {
|
|
12565
|
-
public:
|
|
12566
|
-
virtual ~GlobalOperatorState() {
|
|
12620
|
+
virtual bool RequiresCache() const {
|
|
12621
|
+
return false;
|
|
12567
12622
|
}
|
|
12568
|
-
};
|
|
12569
12623
|
|
|
12570
|
-
class LocalSinkState {
|
|
12571
12624
|
public:
|
|
12572
|
-
|
|
12573
|
-
|
|
12574
|
-
|
|
12625
|
+
// Source interface
|
|
12626
|
+
virtual unique_ptr<LocalSourceState> GetLocalSourceState(ExecutionContext &context,
|
|
12627
|
+
GlobalSourceState &gstate) const;
|
|
12628
|
+
virtual unique_ptr<GlobalSourceState> GetGlobalSourceState(ClientContext &context) const;
|
|
12629
|
+
virtual void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate,
|
|
12630
|
+
LocalSourceState &lstate) const;
|
|
12575
12631
|
|
|
12576
|
-
|
|
12577
|
-
|
|
12578
|
-
PhysicalSink(PhysicalOperatorType type, vector<LogicalType> types, idx_t estimated_cardinality)
|
|
12579
|
-
: PhysicalOperator(type, move(types), estimated_cardinality) {
|
|
12632
|
+
virtual bool IsSource() const {
|
|
12633
|
+
return false;
|
|
12580
12634
|
}
|
|
12581
12635
|
|
|
12582
|
-
|
|
12636
|
+
virtual bool ParallelSource() const {
|
|
12637
|
+
return false;
|
|
12638
|
+
}
|
|
12583
12639
|
|
|
12584
12640
|
public:
|
|
12641
|
+
// Sink interface
|
|
12642
|
+
|
|
12585
12643
|
//! The sink method is called constantly with new input, as long as new input is available. Note that this method
|
|
12586
|
-
//! CAN be called in parallel, proper locking is needed when accessing data inside the
|
|
12587
|
-
virtual
|
|
12588
|
-
|
|
12644
|
+
//! CAN be called in parallel, proper locking is needed when accessing data inside the GlobalSinkState.
|
|
12645
|
+
virtual SinkResultType Sink(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate,
|
|
12646
|
+
DataChunk &input) const;
|
|
12589
12647
|
// The combine is called when a single thread has completed execution of its part of the pipeline, it is the final
|
|
12590
12648
|
// time that a specific LocalSinkState is accessible. This method can be called in parallel while other Sink() or
|
|
12591
|
-
// Combine() calls are active on the same
|
|
12592
|
-
virtual void Combine(ExecutionContext &context,
|
|
12593
|
-
}
|
|
12649
|
+
// Combine() calls are active on the same GlobalSinkState.
|
|
12650
|
+
virtual void Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const;
|
|
12594
12651
|
//! The finalize is called when ALL threads are finished execution. It is called only once per pipeline, and is
|
|
12595
12652
|
//! entirely single threaded.
|
|
12596
|
-
|
|
12597
|
-
|
|
12598
|
-
|
|
12599
|
-
}
|
|
12653
|
+
//! If Finalize returns SinkResultType::FINISHED, the sink is marked as finished
|
|
12654
|
+
virtual SinkFinalizeType Finalize(Pipeline &pipeline, Event &event, ClientContext &context,
|
|
12655
|
+
GlobalSinkState &gstate) const;
|
|
12600
12656
|
|
|
12601
|
-
virtual unique_ptr<LocalSinkState> GetLocalSinkState(ExecutionContext &context)
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
virtual
|
|
12605
|
-
return
|
|
12657
|
+
virtual unique_ptr<LocalSinkState> GetLocalSinkState(ExecutionContext &context) const;
|
|
12658
|
+
virtual unique_ptr<GlobalSinkState> GetGlobalSinkState(ClientContext &context) const;
|
|
12659
|
+
|
|
12660
|
+
virtual bool IsSink() const {
|
|
12661
|
+
return false;
|
|
12606
12662
|
}
|
|
12607
12663
|
|
|
12608
|
-
bool
|
|
12609
|
-
return
|
|
12664
|
+
virtual bool ParallelSink() const {
|
|
12665
|
+
return false;
|
|
12610
12666
|
}
|
|
12611
12667
|
|
|
12612
|
-
|
|
12668
|
+
virtual bool SinkOrderMatters() const {
|
|
12669
|
+
return false;
|
|
12670
|
+
}
|
|
12613
12671
|
};
|
|
12614
12672
|
|
|
12615
12673
|
} // namespace duckdb
|
|
@@ -12668,7 +12726,9 @@ typedef void (*table_function_cleanup_t)(ClientContext &context, const FunctionD
|
|
|
12668
12726
|
FunctionOperatorData *operator_state);
|
|
12669
12727
|
typedef idx_t (*table_function_max_threads_t)(ClientContext &context, const FunctionData *bind_data);
|
|
12670
12728
|
typedef unique_ptr<ParallelState> (*table_function_init_parallel_state_t)(ClientContext &context,
|
|
12671
|
-
const FunctionData *bind_data
|
|
12729
|
+
const FunctionData *bind_data,
|
|
12730
|
+
const vector<column_t> &column_ids,
|
|
12731
|
+
TableFilterCollection *filters);
|
|
12672
12732
|
typedef unique_ptr<FunctionOperatorData> (*table_function_init_parallel_t)(ClientContext &context,
|
|
12673
12733
|
const FunctionData *bind_data,
|
|
12674
12734
|
ParallelState *state,
|
|
@@ -12820,7 +12880,10 @@ struct ParallelState {
|
|
|
12820
12880
|
|
|
12821
12881
|
|
|
12822
12882
|
namespace duckdb {
|
|
12883
|
+
class ClientContext;
|
|
12884
|
+
class Executor;
|
|
12823
12885
|
|
|
12886
|
+
//! Generic parallel task
|
|
12824
12887
|
class Task {
|
|
12825
12888
|
public:
|
|
12826
12889
|
virtual ~Task() {
|
|
@@ -12830,6 +12893,21 @@ public:
|
|
|
12830
12893
|
virtual void Execute() = 0;
|
|
12831
12894
|
};
|
|
12832
12895
|
|
|
12896
|
+
//! Execute a task within an executor, including exception handling
|
|
12897
|
+
//! This should be used within queries
|
|
12898
|
+
class ExecutorTask : public Task {
|
|
12899
|
+
public:
|
|
12900
|
+
ExecutorTask(Executor &executor);
|
|
12901
|
+
ExecutorTask(ClientContext &context);
|
|
12902
|
+
virtual ~ExecutorTask();
|
|
12903
|
+
|
|
12904
|
+
Executor &executor;
|
|
12905
|
+
|
|
12906
|
+
public:
|
|
12907
|
+
virtual void ExecuteTask() = 0;
|
|
12908
|
+
void Execute() override;
|
|
12909
|
+
};
|
|
12910
|
+
|
|
12833
12911
|
} // namespace duckdb
|
|
12834
12912
|
|
|
12835
12913
|
|
|
@@ -12894,109 +12972,87 @@ private:
|
|
|
12894
12972
|
|
|
12895
12973
|
namespace duckdb {
|
|
12896
12974
|
class Executor;
|
|
12897
|
-
class
|
|
12975
|
+
class Event;
|
|
12898
12976
|
|
|
12899
12977
|
//! The Pipeline class represents an execution pipeline
|
|
12900
12978
|
class Pipeline : public std::enable_shared_from_this<Pipeline> {
|
|
12901
12979
|
friend class Executor;
|
|
12980
|
+
friend class PipelineExecutor;
|
|
12981
|
+
friend class PipelineEvent;
|
|
12982
|
+
friend class PipelineFinishEvent;
|
|
12902
12983
|
|
|
12903
12984
|
public:
|
|
12904
|
-
Pipeline(Executor &execution_context
|
|
12985
|
+
Pipeline(Executor &execution_context);
|
|
12905
12986
|
|
|
12906
12987
|
Executor &executor;
|
|
12907
|
-
ProducerToken &token;
|
|
12908
12988
|
|
|
12909
12989
|
public:
|
|
12910
|
-
|
|
12911
|
-
void Execute(TaskContext &task);
|
|
12990
|
+
ClientContext &GetClientContext();
|
|
12912
12991
|
|
|
12913
12992
|
void AddDependency(shared_ptr<Pipeline> &pipeline);
|
|
12914
|
-
void CompleteDependency();
|
|
12915
|
-
bool HasDependencies() {
|
|
12916
|
-
return !dependencies.empty();
|
|
12917
|
-
}
|
|
12918
12993
|
|
|
12919
|
-
void
|
|
12920
|
-
void
|
|
12994
|
+
void Ready();
|
|
12995
|
+
void Reset();
|
|
12996
|
+
void ResetSource();
|
|
12997
|
+
void Schedule(shared_ptr<Event> &event);
|
|
12921
12998
|
|
|
12922
|
-
//!
|
|
12923
|
-
void
|
|
12924
|
-
//! Finish executing this pipeline
|
|
12925
|
-
void Finish();
|
|
12999
|
+
//! Finalize this pipeline
|
|
13000
|
+
void Finalize(Event &event);
|
|
12926
13001
|
|
|
12927
13002
|
string ToString() const;
|
|
12928
13003
|
void Print() const;
|
|
12929
13004
|
|
|
12930
|
-
void SetRecursiveCTE(PhysicalOperator *op) {
|
|
12931
|
-
this->recursive_cte = op;
|
|
12932
|
-
}
|
|
12933
|
-
PhysicalOperator *GetRecursiveCTE() {
|
|
12934
|
-
return recursive_cte;
|
|
12935
|
-
}
|
|
12936
|
-
void ClearParents();
|
|
12937
|
-
|
|
12938
|
-
void IncrementTasks(idx_t amount) {
|
|
12939
|
-
this->total_tasks += amount;
|
|
12940
|
-
}
|
|
12941
|
-
|
|
12942
|
-
bool IsFinished() {
|
|
12943
|
-
return finished;
|
|
12944
|
-
}
|
|
12945
13005
|
//! Returns query progress
|
|
12946
13006
|
bool GetProgress(int ¤t_percentage);
|
|
12947
13007
|
|
|
12948
|
-
|
|
12949
|
-
|
|
12950
|
-
|
|
12951
|
-
|
|
12952
|
-
|
|
13008
|
+
//! Returns a list of all operators (including source and sink) involved in this pipeline
|
|
13009
|
+
vector<PhysicalOperator *> GetOperators() const;
|
|
13010
|
+
|
|
13011
|
+
PhysicalOperator *GetSink() {
|
|
13012
|
+
return sink;
|
|
13013
|
+
}
|
|
12953
13014
|
|
|
12954
13015
|
private:
|
|
12955
|
-
//!
|
|
12956
|
-
|
|
12957
|
-
//! The
|
|
12958
|
-
|
|
13016
|
+
//! Whether or not the pipeline has been readied
|
|
13017
|
+
bool ready;
|
|
13018
|
+
//! The source of this pipeline
|
|
13019
|
+
PhysicalOperator *source;
|
|
13020
|
+
//! The chain of intermediate operators
|
|
13021
|
+
vector<PhysicalOperator *> operators;
|
|
12959
13022
|
//! The sink (i.e. destination) for data; this is e.g. a hash table to-be-built
|
|
12960
|
-
|
|
13023
|
+
PhysicalOperator *sink;
|
|
13024
|
+
|
|
13025
|
+
//! The global source state
|
|
13026
|
+
unique_ptr<GlobalSourceState> source_state;
|
|
13027
|
+
|
|
12961
13028
|
//! The parent pipelines (i.e. pipelines that are dependent on this pipeline to finish)
|
|
12962
|
-
|
|
13029
|
+
vector<weak_ptr<Pipeline>> parents;
|
|
12963
13030
|
//! The dependencies of this pipeline
|
|
12964
|
-
|
|
12965
|
-
//! The amount of completed dependencies (the pipeline can only be started after the dependencies have finished
|
|
12966
|
-
//! executing)
|
|
12967
|
-
atomic<idx_t> finished_dependencies;
|
|
12968
|
-
|
|
12969
|
-
//! The parallel operator (if any)
|
|
12970
|
-
PhysicalOperator *parallel_node;
|
|
12971
|
-
//! The parallel state (if any)
|
|
12972
|
-
unique_ptr<ParallelState> parallel_state;
|
|
12973
|
-
|
|
12974
|
-
//! Whether or not the pipeline is finished executing
|
|
12975
|
-
bool finished;
|
|
12976
|
-
//! The recursive CTE node that this pipeline belongs to, and may be executed multiple times
|
|
12977
|
-
PhysicalOperator *recursive_cte;
|
|
13031
|
+
vector<weak_ptr<Pipeline>> dependencies;
|
|
12978
13032
|
|
|
12979
13033
|
private:
|
|
12980
|
-
bool
|
|
12981
|
-
void ScheduleSequentialTask();
|
|
12982
|
-
bool LaunchScanTasks(
|
|
12983
|
-
|
|
13034
|
+
bool GetProgressInternal(ClientContext &context, PhysicalOperator *op, int ¤t_percentage);
|
|
13035
|
+
void ScheduleSequentialTask(shared_ptr<Event> &event);
|
|
13036
|
+
bool LaunchScanTasks(shared_ptr<Event> &event, idx_t max_threads);
|
|
13037
|
+
|
|
13038
|
+
bool ScheduleParallel(shared_ptr<Event> &event);
|
|
12984
13039
|
};
|
|
12985
13040
|
|
|
12986
13041
|
} // namespace duckdb
|
|
12987
13042
|
|
|
12988
13043
|
|
|
12989
13044
|
|
|
12990
|
-
#include <queue>
|
|
12991
13045
|
|
|
12992
13046
|
namespace duckdb {
|
|
12993
13047
|
class ClientContext;
|
|
12994
13048
|
class DataChunk;
|
|
12995
13049
|
class PhysicalOperator;
|
|
12996
|
-
class
|
|
13050
|
+
class PipelineExecutor;
|
|
13051
|
+
class OperatorState;
|
|
12997
13052
|
class ThreadContext;
|
|
12998
13053
|
class Task;
|
|
12999
13054
|
|
|
13055
|
+
struct PipelineEventStack;
|
|
13000
13056
|
struct ProducerToken;
|
|
13001
13057
|
|
|
13002
13058
|
class Executor {
|
|
@@ -13010,8 +13066,10 @@ public:
|
|
|
13010
13066
|
ClientContext &context;
|
|
13011
13067
|
|
|
13012
13068
|
public:
|
|
13069
|
+
static Executor &Get(ClientContext &context);
|
|
13070
|
+
|
|
13013
13071
|
void Initialize(PhysicalOperator *physical_plan);
|
|
13014
|
-
void BuildPipelines(PhysicalOperator *op, Pipeline *
|
|
13072
|
+
void BuildPipelines(PhysicalOperator *op, Pipeline *current);
|
|
13015
13073
|
|
|
13016
13074
|
void Reset();
|
|
13017
13075
|
|
|
@@ -13020,8 +13078,15 @@ public:
|
|
|
13020
13078
|
unique_ptr<DataChunk> FetchChunk();
|
|
13021
13079
|
|
|
13022
13080
|
//! Push a new error
|
|
13023
|
-
void PushError(const string &exception);
|
|
13024
|
-
|
|
13081
|
+
void PushError(ExceptionType type, const string &exception);
|
|
13082
|
+
//! True if an error has been thrown
|
|
13083
|
+
bool HasError();
|
|
13084
|
+
//! Throw the exception that was pushed using PushError.
|
|
13085
|
+
//! Should only be called if HasError returns true
|
|
13086
|
+
void ThrowException();
|
|
13087
|
+
|
|
13088
|
+
//! Work on tasks for this specific executor, until there are no tasks remaining
|
|
13089
|
+
void WorkOnTasks();
|
|
13025
13090
|
|
|
13026
13091
|
//! Flush a thread context into the client context
|
|
13027
13092
|
void Flush(ThreadContext &context);
|
|
@@ -13029,24 +13094,79 @@ public:
|
|
|
13029
13094
|
//! Returns the progress of the pipelines
|
|
13030
13095
|
bool GetPipelinesProgress(int ¤t_progress);
|
|
13031
13096
|
|
|
13097
|
+
void CompletePipeline() {
|
|
13098
|
+
completed_pipelines++;
|
|
13099
|
+
}
|
|
13100
|
+
ProducerToken &GetToken() {
|
|
13101
|
+
return *producer;
|
|
13102
|
+
}
|
|
13103
|
+
void AddEvent(shared_ptr<Event> event);
|
|
13104
|
+
|
|
13105
|
+
void ReschedulePipelines(const vector<shared_ptr<Pipeline>> &pipelines, vector<shared_ptr<Event>> &events);
|
|
13106
|
+
|
|
13107
|
+
private:
|
|
13108
|
+
void ScheduleEvents();
|
|
13109
|
+
void ScheduleEventsInternal(const vector<shared_ptr<Pipeline>> &pipelines,
|
|
13110
|
+
unordered_map<Pipeline *, vector<shared_ptr<Pipeline>>> &child_pipelines,
|
|
13111
|
+
vector<shared_ptr<Event>> &events, bool main_schedule = true);
|
|
13112
|
+
|
|
13113
|
+
void SchedulePipeline(const shared_ptr<Pipeline> &pipeline,
|
|
13114
|
+
unordered_map<Pipeline *, PipelineEventStack> &event_map, vector<shared_ptr<Event>> &events,
|
|
13115
|
+
bool complete_pipeline);
|
|
13116
|
+
void ScheduleUnionPipeline(const shared_ptr<Pipeline> &pipeline, PipelineEventStack &stack,
|
|
13117
|
+
unordered_map<Pipeline *, PipelineEventStack> &event_map,
|
|
13118
|
+
vector<shared_ptr<Event>> &events);
|
|
13119
|
+
void ScheduleChildPipeline(Pipeline *parent, const shared_ptr<Pipeline> &pipeline,
|
|
13120
|
+
unordered_map<Pipeline *, PipelineEventStack> &event_map,
|
|
13121
|
+
vector<shared_ptr<Event>> &events);
|
|
13122
|
+
void ExtractPipelines(shared_ptr<Pipeline> &pipeline, vector<shared_ptr<Pipeline>> &result);
|
|
13123
|
+
bool NextExecutor();
|
|
13124
|
+
|
|
13125
|
+
void AddChildPipeline(Pipeline *current);
|
|
13126
|
+
|
|
13127
|
+
void VerifyPipeline(Pipeline &pipeline);
|
|
13128
|
+
void VerifyPipelines();
|
|
13129
|
+
void ThrowExceptionInternal();
|
|
13130
|
+
|
|
13032
13131
|
private:
|
|
13033
13132
|
PhysicalOperator *physical_plan;
|
|
13034
|
-
unique_ptr<PhysicalOperatorState> physical_state;
|
|
13035
13133
|
|
|
13036
13134
|
mutex executor_lock;
|
|
13037
13135
|
//! The pipelines of the current query
|
|
13038
13136
|
vector<shared_ptr<Pipeline>> pipelines;
|
|
13137
|
+
//! The root pipeline of the query
|
|
13138
|
+
vector<shared_ptr<Pipeline>> root_pipelines;
|
|
13139
|
+
//! The pipeline executor for the root pipeline
|
|
13140
|
+
unique_ptr<PipelineExecutor> root_executor;
|
|
13141
|
+
//! The current root pipeline index
|
|
13142
|
+
idx_t root_pipeline_idx;
|
|
13039
13143
|
//! The producer of this query
|
|
13040
13144
|
unique_ptr<ProducerToken> producer;
|
|
13041
13145
|
//! Exceptions that occurred during the execution of the current query
|
|
13042
|
-
vector<string
|
|
13146
|
+
vector<pair<ExceptionType, string>> exceptions;
|
|
13147
|
+
//! List of events
|
|
13148
|
+
vector<shared_ptr<Event>> events;
|
|
13043
13149
|
|
|
13044
13150
|
//! The amount of completed pipelines of the query
|
|
13045
13151
|
atomic<idx_t> completed_pipelines;
|
|
13046
13152
|
//! The total amount of pipelines in the query
|
|
13047
13153
|
idx_t total_pipelines;
|
|
13048
13154
|
|
|
13155
|
+
//! The adjacent union pipelines of each pipeline
|
|
13156
|
+
//! Union pipelines have the same sink, but can be run concurrently along with this pipeline
|
|
13157
|
+
unordered_map<Pipeline *, vector<shared_ptr<Pipeline>>> union_pipelines;
|
|
13158
|
+
//! Child pipelines of this pipeline
|
|
13159
|
+
//! Like union pipelines, child pipelines share the same sink
|
|
13160
|
+
//! Unlike union pipelines, child pipelines should be run AFTER their dependencies are completed
|
|
13161
|
+
//! i.e. they should be run after the dependencies are completed, but before finalize is called on the sink
|
|
13162
|
+
unordered_map<Pipeline *, vector<shared_ptr<Pipeline>>> child_pipelines;
|
|
13163
|
+
//! Dependencies of child pipelines
|
|
13164
|
+
unordered_map<Pipeline *, vector<Pipeline *>> child_dependencies;
|
|
13165
|
+
|
|
13166
|
+
//! Duplicate eliminated join scan dependencies
|
|
13049
13167
|
unordered_map<PhysicalOperator *, Pipeline *> delim_join_dependencies;
|
|
13168
|
+
|
|
13169
|
+
//! Active recursive CTE node (if any)
|
|
13050
13170
|
PhysicalOperator *recursive_cte;
|
|
13051
13171
|
};
|
|
13052
13172
|
} // namespace duckdb
|