duckdb 0.8.2-dev1559.0 → 0.8.2-dev1573.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 CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
4
  "types": "./lib/duckdb.d.ts",
5
- "version": "0.8.2-dev1559.0",
5
+ "version": "0.8.2-dev1573.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
@@ -20,7 +20,8 @@ namespace duckdb {
20
20
  PhysicalAsOfJoin::PhysicalAsOfJoin(LogicalComparisonJoin &op, unique_ptr<PhysicalOperator> left,
21
21
  unique_ptr<PhysicalOperator> right)
22
22
  : PhysicalComparisonJoin(op, PhysicalOperatorType::ASOF_JOIN, std::move(op.conditions), op.join_type,
23
- op.estimated_cardinality) {
23
+ op.estimated_cardinality),
24
+ comparison_type(ExpressionType::INVALID) {
24
25
 
25
26
  // Convert the conditions partitions and sorts
26
27
  for (auto &cond : conditions) {
@@ -31,9 +32,19 @@ PhysicalAsOfJoin::PhysicalAsOfJoin(LogicalComparisonJoin &op, unique_ptr<Physica
31
32
  auto right = cond.right->Copy();
32
33
  switch (cond.comparison) {
33
34
  case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
35
+ case ExpressionType::COMPARE_GREATERTHAN:
34
36
  null_sensitive.emplace_back(lhs_orders.size());
35
37
  lhs_orders.emplace_back(OrderType::ASCENDING, OrderByNullType::NULLS_LAST, std::move(left));
36
38
  rhs_orders.emplace_back(OrderType::ASCENDING, OrderByNullType::NULLS_LAST, std::move(right));
39
+ comparison_type = cond.comparison;
40
+ break;
41
+ case ExpressionType::COMPARE_LESSTHANOREQUALTO:
42
+ case ExpressionType::COMPARE_LESSTHAN:
43
+ // Always put NULLS LAST so they can be ignored.
44
+ null_sensitive.emplace_back(lhs_orders.size());
45
+ lhs_orders.emplace_back(OrderType::DESCENDING, OrderByNullType::NULLS_LAST, std::move(left));
46
+ rhs_orders.emplace_back(OrderType::DESCENDING, OrderByNullType::NULLS_LAST, std::move(right));
47
+ comparison_type = cond.comparison;
37
48
  break;
38
49
  case ExpressionType::COMPARE_EQUAL:
39
50
  null_sensitive.emplace_back(lhs_orders.size());
@@ -401,10 +412,28 @@ void AsOfProbeBuffer::BeginLeftScan(hash_t scan_bin) {
401
412
  return;
402
413
  }
403
414
 
415
+ auto iterator_comp = ExpressionType::INVALID;
416
+ switch (op.comparison_type) {
417
+ case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
418
+ iterator_comp = ExpressionType::COMPARE_LESSTHANOREQUALTO;
419
+ break;
420
+ case ExpressionType::COMPARE_GREATERTHAN:
421
+ iterator_comp = ExpressionType::COMPARE_LESSTHAN;
422
+ break;
423
+ case ExpressionType::COMPARE_LESSTHANOREQUALTO:
424
+ iterator_comp = ExpressionType::COMPARE_GREATERTHANOREQUALTO;
425
+ break;
426
+ case ExpressionType::COMPARE_LESSTHAN:
427
+ iterator_comp = ExpressionType::COMPARE_GREATERTHAN;
428
+ break;
429
+ default:
430
+ throw NotImplementedException("Unsupported comparison type for ASOF join");
431
+ }
432
+
404
433
  left_hash = lhs_sink.hash_groups[left_group].get();
405
434
  auto &left_sort = *(left_hash->global_sort);
406
435
  lhs_scanner = make_uniq<PayloadScanner>(left_sort, false);
407
- left_itr = make_uniq<SBIterator>(left_sort, ExpressionType::COMPARE_LESSTHANOREQUALTO);
436
+ left_itr = make_uniq<SBIterator>(left_sort, iterator_comp);
408
437
 
409
438
  // We are only probing the corresponding right side bin, which may be empty
410
439
  // If they are empty, we leave the iterator as null so we can emit left matches
@@ -414,7 +443,7 @@ void AsOfProbeBuffer::BeginLeftScan(hash_t scan_bin) {
414
443
  right_hash = rhs_sink.hash_groups[right_group].get();
415
444
  right_outer = gsink.right_outers.data() + right_group;
416
445
  auto &right_sort = *(right_hash->global_sort);
417
- right_itr = make_uniq<SBIterator>(right_sort, ExpressionType::COMPARE_LESSTHANOREQUALTO);
446
+ right_itr = make_uniq<SBIterator>(right_sort, iterator_comp);
418
447
  rhs_scanner = make_uniq<PayloadScanner>(right_sort, false);
419
448
  }
420
449
  }
@@ -31,6 +31,9 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalAsOfJoin &
31
31
  equi_indexes.emplace_back(c);
32
32
  break;
33
33
  case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
34
+ case ExpressionType::COMPARE_GREATERTHAN:
35
+ case ExpressionType::COMPARE_LESSTHANOREQUALTO:
36
+ case ExpressionType::COMPARE_LESSTHAN:
34
37
  D_ASSERT(asof_idx == op.conditions.size());
35
38
  asof_idx = c;
36
39
  break;
@@ -55,24 +58,37 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalAsOfJoin &
55
58
  }
56
59
 
57
60
  // Debug implementation: IEJoin of Window
58
- // LEAD(asof_column, 1, infinity) OVER (PARTITION BY equi_column... ORDER BY asof_column) AS asof_temp
61
+ // LEAD(asof_column, 1, infinity) OVER (PARTITION BY equi_column... ORDER BY asof_column) AS asof_end
59
62
  auto &asof_comp = op.conditions[asof_idx];
60
63
  auto &asof_column = asof_comp.right;
61
64
  auto asof_type = asof_column->return_type;
62
- auto asof_temp = make_uniq<BoundWindowExpression>(ExpressionType::WINDOW_LEAD, asof_type, nullptr, nullptr);
63
- asof_temp->children.emplace_back(asof_column->Copy());
64
- asof_temp->offset_expr = make_uniq<BoundConstantExpression>(Value::BIGINT(1));
65
+ auto asof_end = make_uniq<BoundWindowExpression>(ExpressionType::WINDOW_LEAD, asof_type, nullptr, nullptr);
66
+ asof_end->children.emplace_back(asof_column->Copy());
65
67
  // TODO: If infinities are not supported for a type, fake them by looking at LHS statistics?
66
- asof_temp->default_expr = make_uniq<BoundConstantExpression>(Value::Infinity(asof_type));
68
+ asof_end->offset_expr = make_uniq<BoundConstantExpression>(Value::BIGINT(1));
67
69
  for (auto equi_idx : equi_indexes) {
68
- asof_temp->partitions.emplace_back(op.conditions[equi_idx].right->Copy());
70
+ asof_end->partitions.emplace_back(op.conditions[equi_idx].right->Copy());
69
71
  }
70
- asof_temp->orders.emplace_back(OrderType::ASCENDING, OrderByNullType::NULLS_FIRST, asof_column->Copy());
71
- asof_temp->start = WindowBoundary::UNBOUNDED_PRECEDING;
72
- asof_temp->end = WindowBoundary::CURRENT_ROW_ROWS;
72
+ switch (asof_comp.comparison) {
73
+ case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
74
+ case ExpressionType::COMPARE_GREATERTHAN:
75
+ asof_end->orders.emplace_back(OrderType::ASCENDING, OrderByNullType::NULLS_FIRST, asof_column->Copy());
76
+ asof_end->default_expr = make_uniq<BoundConstantExpression>(Value::Infinity(asof_type));
77
+ break;
78
+ case ExpressionType::COMPARE_LESSTHANOREQUALTO:
79
+ case ExpressionType::COMPARE_LESSTHAN:
80
+ asof_end->orders.emplace_back(OrderType::DESCENDING, OrderByNullType::NULLS_FIRST, asof_column->Copy());
81
+ asof_end->default_expr = make_uniq<BoundConstantExpression>(Value::NegativeInfinity(asof_type));
82
+ break;
83
+ default:
84
+ throw InternalException("Invalid ASOF JOIN ordering for WINDOW");
85
+ }
86
+
87
+ asof_end->start = WindowBoundary::UNBOUNDED_PRECEDING;
88
+ asof_end->end = WindowBoundary::CURRENT_ROW_ROWS;
73
89
 
74
90
  vector<unique_ptr<Expression>> window_select;
75
- window_select.emplace_back(std::move(asof_temp));
91
+ window_select.emplace_back(std::move(asof_end));
76
92
 
77
93
  auto &window_types = op.children[1]->types;
78
94
  window_types.emplace_back(asof_type);
@@ -80,11 +96,27 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalAsOfJoin &
80
96
  auto window = make_uniq<PhysicalWindow>(window_types, std::move(window_select), rhs_cardinality);
81
97
  window->children.emplace_back(std::move(right));
82
98
 
83
- // IEJoin(left, window, conditions || asof_column < asof_temp)
99
+ // IEJoin(left, window, conditions || asof_comp ~op asof_end)
84
100
  JoinCondition asof_upper;
85
101
  asof_upper.left = asof_comp.left->Copy();
86
102
  asof_upper.right = make_uniq<BoundReferenceExpression>(asof_type, window_types.size() - 1);
87
- asof_upper.comparison = ExpressionType::COMPARE_LESSTHAN;
103
+ switch (asof_comp.comparison) {
104
+ case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
105
+ asof_upper.comparison = ExpressionType::COMPARE_LESSTHAN;
106
+ break;
107
+ case ExpressionType::COMPARE_GREATERTHAN:
108
+ asof_upper.comparison = ExpressionType::COMPARE_LESSTHANOREQUALTO;
109
+ break;
110
+ case ExpressionType::COMPARE_LESSTHANOREQUALTO:
111
+ asof_upper.comparison = ExpressionType::COMPARE_GREATERTHAN;
112
+ break;
113
+ case ExpressionType::COMPARE_LESSTHAN:
114
+ asof_upper.comparison = ExpressionType::COMPARE_GREATERTHANOREQUALTO;
115
+ break;
116
+ default:
117
+ throw InternalException("Invalid ASOF JOIN comparison for IEJoin");
118
+ }
119
+
88
120
  op.conditions.emplace_back(std::move(asof_upper));
89
121
 
90
122
  return make_uniq<PhysicalIEJoin>(op, std::move(left), std::move(window), std::move(op.conditions), op.join_type,
@@ -136,6 +136,10 @@ string PragmaVersion(ClientContext &context, const FunctionParameters &parameter
136
136
  return "SELECT * FROM pragma_version();";
137
137
  }
138
138
 
139
+ string PragmaPlatform(ClientContext &context, const FunctionParameters &parameters) {
140
+ return "SELECT * FROM pragma_platform();";
141
+ }
142
+
139
143
  string PragmaImportDatabase(ClientContext &context, const FunctionParameters &parameters) {
140
144
  auto &config = DBConfig::GetConfig(context);
141
145
  if (!config.options.enable_external_access) {
@@ -192,6 +196,7 @@ void PragmaQueries::RegisterFunction(BuiltinFunctions &set) {
192
196
  set.AddFunction(PragmaFunction::PragmaStatement("collations", PragmaCollations));
193
197
  set.AddFunction(PragmaFunction::PragmaCall("show", PragmaShow, {LogicalType::VARCHAR}));
194
198
  set.AddFunction(PragmaFunction::PragmaStatement("version", PragmaVersion));
199
+ set.AddFunction(PragmaFunction::PragmaStatement("platform", PragmaPlatform));
195
200
  set.AddFunction(PragmaFunction::PragmaStatement("database_size", PragmaDatabaseSize));
196
201
  set.AddFunction(PragmaFunction::PragmaStatement("functions", PragmaFunctionsQuery));
197
202
  set.AddFunction(PragmaFunction::PragmaCall("import_database", PragmaImportDatabase, {LogicalType::VARCHAR}));
@@ -10,6 +10,7 @@ namespace duckdb {
10
10
 
11
11
  void BuiltinFunctions::RegisterSQLiteFunctions() {
12
12
  PragmaVersion::RegisterFunction(*this);
13
+ PragmaPlatform::RegisterFunction(*this);
13
14
  PragmaCollations::RegisterFunction(*this);
14
15
  PragmaTableInfo::RegisterFunction(*this);
15
16
  PragmaStorageInfo::RegisterFunction(*this);
@@ -1,11 +1,12 @@
1
1
  #ifndef DUCKDB_VERSION
2
- #define DUCKDB_VERSION "0.8.2-dev1559"
2
+ #define DUCKDB_VERSION "0.8.2-dev1573"
3
3
  #endif
4
4
  #ifndef DUCKDB_SOURCE_ID
5
- #define DUCKDB_SOURCE_ID "fa204ca892"
5
+ #define DUCKDB_SOURCE_ID "c277db819b"
6
6
  #endif
7
7
  #include "duckdb/function/table/system_functions.hpp"
8
8
  #include "duckdb/main/database.hpp"
9
+ #include "duckdb/common/string_util.hpp"
9
10
 
10
11
  #include <cstdint>
11
12
 
@@ -63,6 +64,13 @@ const char *DuckDB::LibraryVersion() {
63
64
  }
64
65
 
65
66
  string DuckDB::Platform() {
67
+ #if defined(DUCKDB_CUSTOM_PLATFORM)
68
+ return DUCKDB_QUOTE_DEFINE(DUCKDB_CUSTOM_PLATFORM);
69
+ #endif
70
+ #if defined(DUCKDB_WASM_VERSION)
71
+ // DuckDB-Wasm requires CUSTOM_PLATFORM to be defined
72
+ static_assert(0, "DUCKDB_WASM_VERSION should rely on CUSTOM_PLATFORM being provided");
73
+ #endif
66
74
  string os = "linux";
67
75
  #if INTPTR_MAX == INT64_MAX
68
76
  string arch = "amd64";
@@ -97,4 +105,40 @@ string DuckDB::Platform() {
97
105
  return os + "_" + arch + postfix;
98
106
  }
99
107
 
108
+ struct PragmaPlatformData : public GlobalTableFunctionState {
109
+ PragmaPlatformData() : finished(false) {
110
+ }
111
+
112
+ bool finished;
113
+ };
114
+
115
+ static unique_ptr<FunctionData> PragmaPlatformBind(ClientContext &context, TableFunctionBindInput &input,
116
+ vector<LogicalType> &return_types, vector<string> &names) {
117
+ names.emplace_back("platform");
118
+ return_types.emplace_back(LogicalType::VARCHAR);
119
+ return nullptr;
120
+ }
121
+
122
+ static unique_ptr<GlobalTableFunctionState> PragmaPlatformInit(ClientContext &context, TableFunctionInitInput &input) {
123
+ return make_uniq<PragmaPlatformData>();
124
+ }
125
+
126
+ static void PragmaPlatformFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) {
127
+ auto &data = data_p.global_state->Cast<PragmaPlatformData>();
128
+ if (data.finished) {
129
+ // finished returning values
130
+ return;
131
+ }
132
+ output.SetCardinality(1);
133
+ output.SetValue(0, 0, DuckDB::Platform());
134
+ data.finished = true;
135
+ }
136
+
137
+ void PragmaPlatform::RegisterFunction(BuiltinFunctions &set) {
138
+ TableFunction pragma_platform("pragma_platform", {}, PragmaPlatformFunction);
139
+ pragma_platform.bind = PragmaPlatformBind;
140
+ pragma_platform.init_global = PragmaPlatformInit;
141
+ set.AddFunction(pragma_platform);
142
+ }
143
+
100
144
  } // namespace duckdb
@@ -16,6 +16,17 @@
16
16
 
17
17
  namespace duckdb {
18
18
 
19
+ #ifndef DUCKDB_QUOTE_DEFINE
20
+ // Preprocessor trick to allow text to be converted to C-string / string
21
+ // Expecte use is:
22
+ // #ifdef SOME_DEFINE
23
+ // string str = DUCKDB_QUOTE_DEFINE(SOME_DEFINE)
24
+ // ...do something with str
25
+ // #endif SOME_DEFINE
26
+ #define DUCKDB_QUOTE_DEFINE_IMPL(x) #x
27
+ #define DUCKDB_QUOTE_DEFINE(x) DUCKDB_QUOTE_DEFINE_IMPL(x)
28
+ #endif
29
+
19
30
  /**
20
31
  * String Utility Functions
21
32
  * Note that these are not the most efficient implementations (i.e., they copy
@@ -23,6 +23,7 @@ public:
23
23
 
24
24
  vector<LogicalType> join_key_types;
25
25
  vector<column_t> null_sensitive;
26
+ ExpressionType comparison_type;
26
27
 
27
28
  // Equalities
28
29
  vector<unique_ptr<Expression>> lhs_partitions;
@@ -37,6 +37,10 @@ struct PragmaVersion {
37
37
  static void RegisterFunction(BuiltinFunctions &set);
38
38
  };
39
39
 
40
+ struct PragmaPlatform {
41
+ static void RegisterFunction(BuiltinFunctions &set);
42
+ };
43
+
40
44
  struct PragmaDatabaseSize {
41
45
  static void RegisterFunction(BuiltinFunctions &set);
42
46
  };
@@ -29,6 +29,9 @@ bool ExtensionHelper::IsRelease(const string &version_tag) {
29
29
  }
30
30
 
31
31
  const string ExtensionHelper::GetVersionDirectoryName() {
32
+ #ifdef DUCKDB_WASM_VERSION
33
+ return DUCKDB_QUOTE_DEFINE(DUCKDB_WASM_VERSION);
34
+ #endif
32
35
  if (IsRelease(DuckDB::LibraryVersion())) {
33
36
  return NormalizeVersionTag(DuckDB::LibraryVersion());
34
37
  } else {
@@ -137,6 +137,9 @@ unique_ptr<LogicalOperator> LogicalComparisonJoin::CreateJoin(ClientContext &con
137
137
  case ExpressionType::COMPARE_NOT_DISTINCT_FROM:
138
138
  break;
139
139
  case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
140
+ case ExpressionType::COMPARE_GREATERTHAN:
141
+ case ExpressionType::COMPARE_LESSTHANOREQUALTO:
142
+ case ExpressionType::COMPARE_LESSTHAN:
140
143
  if (asof_idx < conditions.size()) {
141
144
  throw BinderException("Multiple ASOF JOIN inequalities");
142
145
  }