duckdb 1.1.4-dev9.0 → 1.2.1-dev4.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 (221) hide show
  1. package/LICENSE +1 -1
  2. package/binding.gyp +1 -0
  3. package/package.json +2 -2
  4. package/src/connection.cpp +42 -15
  5. package/src/duckdb/extension/core_functions/function_list.cpp +1 -0
  6. package/src/duckdb/extension/core_functions/include/core_functions/scalar/map_functions.hpp +9 -0
  7. package/src/duckdb/extension/core_functions/scalar/date/current.cpp +1 -0
  8. package/src/duckdb/extension/core_functions/scalar/generic/can_implicitly_cast.cpp +2 -2
  9. package/src/duckdb/extension/core_functions/scalar/generic/typeof.cpp +1 -1
  10. package/src/duckdb/extension/core_functions/scalar/list/flatten.cpp +91 -61
  11. package/src/duckdb/extension/core_functions/scalar/map/map_extract.cpp +89 -8
  12. package/src/duckdb/extension/icu/icu-current.cpp +63 -0
  13. package/src/duckdb/extension/icu/icu-makedate.cpp +43 -39
  14. package/src/duckdb/extension/icu/icu-timezone.cpp +63 -63
  15. package/src/duckdb/extension/icu/icu_extension.cpp +2 -0
  16. package/src/duckdb/extension/icu/include/icu-casts.hpp +39 -0
  17. package/src/duckdb/extension/icu/include/icu-current.hpp +17 -0
  18. package/src/duckdb/extension/icu/third_party/icu/stubdata/stubdata.cpp +1 -1
  19. package/src/duckdb/extension/json/json_functions/json_structure.cpp +3 -1
  20. package/src/duckdb/extension/parquet/column_writer.cpp +26 -18
  21. package/src/duckdb/extension/parquet/include/parquet_reader.hpp +0 -6
  22. package/src/duckdb/extension/parquet/include/parquet_writer.hpp +15 -1
  23. package/src/duckdb/extension/parquet/include/resizable_buffer.hpp +1 -0
  24. package/src/duckdb/extension/parquet/parquet_extension.cpp +67 -15
  25. package/src/duckdb/extension/parquet/parquet_reader.cpp +5 -3
  26. package/src/duckdb/extension/parquet/parquet_writer.cpp +5 -6
  27. package/src/duckdb/src/catalog/catalog.cpp +21 -8
  28. package/src/duckdb/src/catalog/catalog_search_path.cpp +17 -1
  29. package/src/duckdb/src/catalog/catalog_set.cpp +1 -1
  30. package/src/duckdb/src/catalog/default/default_functions.cpp +0 -3
  31. package/src/duckdb/src/catalog/dependency_list.cpp +7 -0
  32. package/src/duckdb/src/common/adbc/adbc.cpp +1 -56
  33. package/src/duckdb/src/common/arrow/arrow_converter.cpp +3 -2
  34. package/src/duckdb/src/common/arrow/arrow_type_extension.cpp +58 -28
  35. package/src/duckdb/src/common/arrow/schema_metadata.cpp +1 -1
  36. package/src/duckdb/src/common/compressed_file_system.cpp +6 -2
  37. package/src/duckdb/src/common/enum_util.cpp +26 -22
  38. package/src/duckdb/src/common/error_data.cpp +3 -2
  39. package/src/duckdb/src/common/gzip_file_system.cpp +8 -8
  40. package/src/duckdb/src/common/local_file_system.cpp +2 -2
  41. package/src/duckdb/src/common/multi_file_reader.cpp +1 -1
  42. package/src/duckdb/src/common/random_engine.cpp +4 -1
  43. package/src/duckdb/src/common/serializer/memory_stream.cpp +23 -19
  44. package/src/duckdb/src/common/serializer/serializer.cpp +1 -1
  45. package/src/duckdb/src/common/types/bit.cpp +1 -1
  46. package/src/duckdb/src/common/types/column/column_data_allocator.cpp +0 -5
  47. package/src/duckdb/src/common/types/column/column_data_collection.cpp +4 -1
  48. package/src/duckdb/src/common/types/data_chunk.cpp +2 -1
  49. package/src/duckdb/src/common/types/row/tuple_data_segment.cpp +0 -4
  50. package/src/duckdb/src/common/types.cpp +1 -1
  51. package/src/duckdb/src/execution/index/art/art.cpp +52 -42
  52. package/src/duckdb/src/execution/index/art/leaf.cpp +4 -9
  53. package/src/duckdb/src/execution/index/art/node.cpp +13 -13
  54. package/src/duckdb/src/execution/index/art/prefix.cpp +21 -16
  55. package/src/duckdb/src/execution/index/bound_index.cpp +6 -8
  56. package/src/duckdb/src/execution/index/fixed_size_allocator.cpp +39 -34
  57. package/src/duckdb/src/execution/index/fixed_size_buffer.cpp +2 -1
  58. package/src/duckdb/src/execution/index/unbound_index.cpp +10 -0
  59. package/src/duckdb/src/execution/operator/aggregate/physical_streaming_window.cpp +62 -44
  60. package/src/duckdb/src/execution/operator/csv_scanner/scanner/column_count_scanner.cpp +26 -0
  61. package/src/duckdb/src/execution/operator/csv_scanner/scanner/string_value_scanner.cpp +69 -40
  62. package/src/duckdb/src/execution/operator/csv_scanner/sniffer/dialect_detection.cpp +3 -7
  63. package/src/duckdb/src/execution/operator/csv_scanner/sniffer/header_detection.cpp +11 -5
  64. package/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_detection.cpp +4 -0
  65. package/src/duckdb/src/execution/operator/csv_scanner/state_machine/csv_state_machine_cache.cpp +8 -8
  66. package/src/duckdb/src/execution/operator/csv_scanner/util/csv_error.cpp +36 -12
  67. package/src/duckdb/src/execution/operator/csv_scanner/util/csv_reader_options.cpp +12 -9
  68. package/src/duckdb/src/execution/operator/join/physical_hash_join.cpp +0 -1
  69. package/src/duckdb/src/execution/operator/persistent/physical_copy_database.cpp +29 -1
  70. package/src/duckdb/src/execution/operator/persistent/physical_delete.cpp +58 -10
  71. package/src/duckdb/src/execution/operator/persistent/physical_insert.cpp +58 -35
  72. package/src/duckdb/src/execution/operator/schema/physical_create_art_index.cpp +2 -1
  73. package/src/duckdb/src/execution/radix_partitioned_hashtable.cpp +9 -4
  74. package/src/duckdb/src/execution/sample/reservoir_sample.cpp +7 -6
  75. package/src/duckdb/src/function/compression_config.cpp +4 -0
  76. package/src/duckdb/src/function/function_binder.cpp +1 -1
  77. package/src/duckdb/src/function/scalar/system/write_log.cpp +2 -2
  78. package/src/duckdb/src/function/table/arrow/arrow_duck_schema.cpp +15 -2
  79. package/src/duckdb/src/function/table/arrow_conversion.cpp +10 -10
  80. package/src/duckdb/src/function/table/copy_csv.cpp +8 -5
  81. package/src/duckdb/src/function/table/read_csv.cpp +21 -4
  82. package/src/duckdb/src/function/table/sniff_csv.cpp +7 -0
  83. package/src/duckdb/src/function/table/system/duckdb_extensions.cpp +4 -0
  84. package/src/duckdb/src/function/table/system/duckdb_secret_types.cpp +71 -0
  85. package/src/duckdb/src/function/table/system_functions.cpp +1 -0
  86. package/src/duckdb/src/function/table/table_scan.cpp +120 -36
  87. package/src/duckdb/src/function/table/version/pragma_version.cpp +4 -4
  88. package/src/duckdb/src/function/window/window_aggregate_function.cpp +6 -1
  89. package/src/duckdb/src/function/window/window_boundaries_state.cpp +135 -11
  90. package/src/duckdb/src/function/window/window_segment_tree.cpp +50 -22
  91. package/src/duckdb/src/function/window/window_token_tree.cpp +4 -3
  92. package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +4 -0
  93. package/src/duckdb/src/include/duckdb/catalog/catalog_search_path.hpp +2 -0
  94. package/src/duckdb/src/include/duckdb/catalog/dependency_list.hpp +1 -0
  95. package/src/duckdb/src/include/duckdb/common/arrow/arrow_type_extension.hpp +4 -2
  96. package/src/duckdb/src/include/duckdb/common/enum_util.hpp +8 -8
  97. package/src/duckdb/src/include/duckdb/common/multi_file_reader.hpp +0 -2
  98. package/src/duckdb/src/include/duckdb/common/serializer/deserializer.hpp +8 -3
  99. package/src/duckdb/src/include/duckdb/common/serializer/memory_stream.hpp +6 -1
  100. package/src/duckdb/src/include/duckdb/common/serializer/serialization_data.hpp +25 -0
  101. package/src/duckdb/src/include/duckdb/common/serializer/serializer.hpp +9 -3
  102. package/src/duckdb/src/include/duckdb/common/types/selection_vector.hpp +1 -1
  103. package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +11 -14
  104. package/src/duckdb/src/include/duckdb/execution/index/art/prefix.hpp +5 -4
  105. package/src/duckdb/src/include/duckdb/execution/index/bound_index.hpp +21 -10
  106. package/src/duckdb/src/include/duckdb/execution/index/fixed_size_allocator.hpp +6 -5
  107. package/src/duckdb/src/include/duckdb/execution/index/fixed_size_buffer.hpp +37 -32
  108. package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/base_scanner.hpp +36 -1
  109. package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/column_count_scanner.hpp +3 -0
  110. package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp +2 -0
  111. package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/state_machine_options.hpp +5 -5
  112. package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/string_value_scanner.hpp +5 -30
  113. package/src/duckdb/src/include/duckdb/execution/reservoir_sample.hpp +7 -1
  114. package/src/duckdb/src/include/duckdb/function/scalar_function.hpp +3 -3
  115. package/src/duckdb/src/include/duckdb/function/table/arrow/arrow_duck_schema.hpp +1 -0
  116. package/src/duckdb/src/include/duckdb/function/table/system_functions.hpp +4 -0
  117. package/src/duckdb/src/include/duckdb/function/window/window_boundaries_state.hpp +2 -2
  118. package/src/duckdb/src/include/duckdb/logging/logger.hpp +40 -119
  119. package/src/duckdb/src/include/duckdb/logging/logging.hpp +0 -2
  120. package/src/duckdb/src/include/duckdb/main/config.hpp +5 -0
  121. package/src/duckdb/src/include/duckdb/main/connection.hpp +0 -8
  122. package/src/duckdb/src/include/duckdb/main/connection_manager.hpp +2 -1
  123. package/src/duckdb/src/include/duckdb/main/extension.hpp +1 -0
  124. package/src/duckdb/src/include/duckdb/main/extension_entries.hpp +11 -7
  125. package/src/duckdb/src/include/duckdb/main/extension_helper.hpp +1 -0
  126. package/src/duckdb/src/include/duckdb/main/secret/secret.hpp +2 -0
  127. package/src/duckdb/src/include/duckdb/main/secret/secret_manager.hpp +3 -0
  128. package/src/duckdb/src/include/duckdb/main/settings.hpp +10 -0
  129. package/src/duckdb/src/include/duckdb/parser/constraint.hpp +9 -0
  130. package/src/duckdb/src/include/duckdb/parser/expression/window_expression.hpp +36 -9
  131. package/src/duckdb/src/include/duckdb/parser/parsed_data/create_view_info.hpp +2 -1
  132. package/src/duckdb/src/include/duckdb/parser/query_node/set_operation_node.hpp +8 -2
  133. package/src/duckdb/src/include/duckdb/planner/binder.hpp +4 -0
  134. package/src/duckdb/src/include/duckdb/planner/expression/bound_parameter_data.hpp +9 -1
  135. package/src/duckdb/src/include/duckdb/planner/filter/constant_filter.hpp +1 -0
  136. package/src/duckdb/src/include/duckdb/planner/filter/in_filter.hpp +0 -2
  137. package/src/duckdb/src/include/duckdb/planner/filter/optional_filter.hpp +4 -4
  138. package/src/duckdb/src/include/duckdb/planner/table_filter.hpp +1 -1
  139. package/src/duckdb/src/include/duckdb/storage/data_table.hpp +14 -10
  140. package/src/duckdb/src/include/duckdb/storage/index_storage_info.hpp +4 -0
  141. package/src/duckdb/src/include/duckdb/storage/single_file_block_manager.hpp +6 -1
  142. package/src/duckdb/src/include/duckdb/storage/storage_info.hpp +7 -2
  143. package/src/duckdb/src/include/duckdb/storage/storage_manager.hpp +9 -0
  144. package/src/duckdb/src/include/duckdb/storage/storage_options.hpp +2 -0
  145. package/src/duckdb/src/include/duckdb/storage/string_uncompressed.hpp +4 -3
  146. package/src/duckdb/src/include/duckdb/storage/table/column_data.hpp +2 -0
  147. package/src/duckdb/src/include/duckdb/storage/table/table_index_list.hpp +6 -4
  148. package/src/duckdb/src/include/duckdb/storage/table/table_statistics.hpp +1 -1
  149. package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +2 -0
  150. package/src/duckdb/src/include/duckdb/transaction/local_storage.hpp +2 -0
  151. package/src/duckdb/src/include/duckdb/transaction/meta_transaction.hpp +1 -1
  152. package/src/duckdb/src/logging/logger.cpp +8 -66
  153. package/src/duckdb/src/main/attached_database.cpp +3 -1
  154. package/src/duckdb/src/main/client_context.cpp +4 -2
  155. package/src/duckdb/src/main/config.cpp +20 -2
  156. package/src/duckdb/src/main/connection.cpp +2 -29
  157. package/src/duckdb/src/main/connection_manager.cpp +5 -3
  158. package/src/duckdb/src/main/database.cpp +2 -2
  159. package/src/duckdb/src/main/extension/extension_helper.cpp +4 -5
  160. package/src/duckdb/src/main/extension/extension_install.cpp +23 -10
  161. package/src/duckdb/src/main/extension/extension_load.cpp +6 -7
  162. package/src/duckdb/src/main/extension.cpp +27 -9
  163. package/src/duckdb/src/main/secret/secret_manager.cpp +11 -0
  164. package/src/duckdb/src/main/settings/custom_settings.cpp +44 -0
  165. package/src/duckdb/src/optimizer/column_lifetime_analyzer.cpp +6 -0
  166. package/src/duckdb/src/optimizer/filter_combiner.cpp +13 -3
  167. package/src/duckdb/src/optimizer/filter_pushdown.cpp +33 -6
  168. package/src/duckdb/src/optimizer/late_materialization.cpp +14 -3
  169. package/src/duckdb/src/optimizer/remove_unused_columns.cpp +0 -3
  170. package/src/duckdb/src/parser/parsed_data/attach_info.cpp +5 -1
  171. package/src/duckdb/src/parser/parsed_data/create_view_info.cpp +6 -3
  172. package/src/duckdb/src/parser/query_node/set_operation_node.cpp +49 -0
  173. package/src/duckdb/src/parser/transform/expression/transform_columnref.cpp +1 -0
  174. package/src/duckdb/src/parser/transform/expression/transform_function.cpp +50 -12
  175. package/src/duckdb/src/planner/binder/expression/bind_columnref_expression.cpp +7 -5
  176. package/src/duckdb/src/planner/binder/expression/bind_comparison_expression.cpp +1 -0
  177. package/src/duckdb/src/planner/binder/expression/bind_operator_expression.cpp +2 -2
  178. package/src/duckdb/src/planner/binder/expression/bind_star_expression.cpp +12 -2
  179. package/src/duckdb/src/planner/binder/statement/bind_copy_database.cpp +0 -1
  180. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +55 -39
  181. package/src/duckdb/src/planner/binder/statement/bind_execute.cpp +2 -1
  182. package/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp +15 -7
  183. package/src/duckdb/src/planner/binder/tableref/bind_showref.cpp +13 -8
  184. package/src/duckdb/src/planner/binder/tableref/bind_table_function.cpp +8 -3
  185. package/src/duckdb/src/planner/expression/bound_function_expression.cpp +17 -1
  186. package/src/duckdb/src/planner/expression_binder/index_binder.cpp +1 -0
  187. package/src/duckdb/src/planner/filter/conjunction_filter.cpp +1 -0
  188. package/src/duckdb/src/planner/filter/constant_filter.cpp +21 -0
  189. package/src/duckdb/src/planner/filter/in_filter.cpp +4 -7
  190. package/src/duckdb/src/planner/logical_operator.cpp +5 -3
  191. package/src/duckdb/src/planner/planner.cpp +1 -1
  192. package/src/duckdb/src/planner/subquery/flatten_dependent_join.cpp +2 -0
  193. package/src/duckdb/src/storage/checkpoint/table_data_writer.cpp +3 -4
  194. package/src/duckdb/src/storage/checkpoint_manager.cpp +3 -5
  195. package/src/duckdb/src/storage/compression/dictionary/decompression.cpp +4 -4
  196. package/src/duckdb/src/storage/compression/fsst.cpp +2 -2
  197. package/src/duckdb/src/storage/compression/roaring/common.cpp +10 -1
  198. package/src/duckdb/src/storage/compression/string_uncompressed.cpp +11 -6
  199. package/src/duckdb/src/storage/compression/validity_uncompressed.cpp +4 -0
  200. package/src/duckdb/src/storage/compression/zstd.cpp +6 -0
  201. package/src/duckdb/src/storage/data_table.cpp +104 -109
  202. package/src/duckdb/src/storage/local_storage.cpp +8 -6
  203. package/src/duckdb/src/storage/magic_bytes.cpp +1 -1
  204. package/src/duckdb/src/storage/serialization/serialize_dependency.cpp +3 -3
  205. package/src/duckdb/src/storage/serialization/serialize_nodes.cpp +3 -3
  206. package/src/duckdb/src/storage/serialization/serialize_query_node.cpp +7 -5
  207. package/src/duckdb/src/storage/single_file_block_manager.cpp +95 -28
  208. package/src/duckdb/src/storage/storage_info.cpp +38 -0
  209. package/src/duckdb/src/storage/storage_manager.cpp +11 -0
  210. package/src/duckdb/src/storage/table/column_data.cpp +4 -0
  211. package/src/duckdb/src/storage/table/column_data_checkpointer.cpp +3 -3
  212. package/src/duckdb/src/storage/table/row_group_collection.cpp +67 -68
  213. package/src/duckdb/src/storage/table/table_statistics.cpp +4 -4
  214. package/src/duckdb/src/storage/table_index_list.cpp +41 -15
  215. package/src/duckdb/src/storage/wal_replay.cpp +3 -1
  216. package/src/duckdb/src/storage/write_ahead_log.cpp +11 -4
  217. package/src/duckdb/src/transaction/meta_transaction.cpp +1 -1
  218. package/src/duckdb/src/verification/deserialized_statement_verifier.cpp +2 -1
  219. package/src/duckdb/third_party/httplib/httplib.hpp +0 -1
  220. package/src/duckdb/third_party/re2/util/logging.h +10 -10
  221. package/src/duckdb/ub_src_function_table_system.cpp +2 -0
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2018-2024 Stichting DuckDB Foundation
1
+ Copyright 2018-2025 Stichting DuckDB Foundation
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
4
 
package/binding.gyp CHANGED
@@ -306,6 +306,7 @@
306
306
  "src/duckdb/extension/icu/./icu-makedate.cpp",
307
307
  "src/duckdb/extension/icu/./icu-list-range.cpp",
308
308
  "src/duckdb/extension/icu/./icu-timebucket.cpp",
309
+ "src/duckdb/extension/icu/./icu-current.cpp",
309
310
  "src/duckdb/extension/icu/./icu-timezone.cpp",
310
311
  "src/duckdb/extension/icu/./icu-dateadd.cpp",
311
312
  "src/duckdb/extension/icu/./icu-datetrunc.cpp",
package/package.json CHANGED
@@ -2,11 +2,11 @@
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
4
  "types": "./lib/duckdb.d.ts",
5
- "version": "1.1.4-dev9.0",
5
+ "version": "1.2.1-dev4.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
9
- "@mapbox/node-pre-gyp": "^1.0.0",
9
+ "@mapbox/node-pre-gyp": "^2.0.0",
10
10
  "node-addon-api": "^7.0.0",
11
11
  "node-gyp": "^9.3.0"
12
12
  },
@@ -4,6 +4,10 @@
4
4
  #include "duckdb/parser/parser.hpp"
5
5
  #include "duckdb/parser/parsed_data/drop_info.hpp"
6
6
  #include "duckdb/parser/expression/cast_expression.hpp"
7
+ #include "duckdb/common/types/value.hpp"
8
+ #include "duckdb/main/relation/table_function_relation.hpp"
9
+
10
+
7
11
  #include <iostream>
8
12
  #include <thread>
9
13
 
@@ -451,6 +455,27 @@ Napi::Value Connection::Exec(const Napi::CallbackInfo &info) {
451
455
  return Value();
452
456
  }
453
457
 
458
+ struct CreateArrowViewTask : public Task {
459
+ CreateArrowViewTask(Connection &connection, duckdb::vector<duckdb::Value>& parameters, std::string &view_name)
460
+ : Task(connection), parameters(parameters), view_name(view_name) {
461
+ }
462
+
463
+ void DoWork() override {
464
+ auto &connection = Get<Connection>();
465
+ auto &con = *connection.connection;
466
+ // Now we create a table function relation
467
+ auto table_function_relation = duckdb::make_shared_ptr<duckdb::TableFunctionRelation>(con.context,"scan_arrow_ipc",parameters);
468
+ // Creates a relation for a temporary view that does replace
469
+ auto view_relation = table_function_relation->CreateView(view_name,true,true);
470
+
471
+ view_relation->Execute();
472
+
473
+ }
474
+
475
+ duckdb::vector<duckdb::Value> parameters;
476
+ std::string view_name;
477
+ };
478
+
454
479
  // Register Arrow IPC buffers for scanning from DuckDB
455
480
  Napi::Value Connection::RegisterBuffer(const Napi::CallbackInfo &info) {
456
481
  auto env = info.Env();
@@ -475,9 +500,10 @@ Napi::Value Connection::RegisterBuffer(const Napi::CallbackInfo &info) {
475
500
  }
476
501
 
477
502
  array_references[name] = Napi::Persistent(array);
503
+ auto &db = *connection->context->db;
478
504
 
479
- std::string arrow_scan_function = "scan_arrow_ipc([";
480
-
505
+ vector<duckdb::Value> values;
506
+
481
507
  for (uint64_t ipc_idx = 0; ipc_idx < array.Length(); ipc_idx++) {
482
508
  Napi::Value v = array[ipc_idx];
483
509
  if (!v.IsObject()) {
@@ -486,19 +512,20 @@ Napi::Value Connection::RegisterBuffer(const Napi::CallbackInfo &info) {
486
512
  Napi::Uint8Array arr = v.As<Napi::Uint8Array>();
487
513
  auto raw_ptr = reinterpret_cast<uint64_t>(arr.ArrayBuffer().Data());
488
514
  auto length = (uint64_t)arr.ElementLength();
489
-
490
- arrow_scan_function += "{'ptr': " + std::to_string(raw_ptr) + "::UBIGINT, 'size': " + std::to_string(length) + "::UBIGINT},";
491
- }
492
- arrow_scan_function += "])";
493
-
494
- std::string final_query = "CREATE OR REPLACE TEMPORARY VIEW " + name + " AS SELECT * FROM " + arrow_scan_function;
495
-
496
- Napi::Function callback;
497
- if (info.Length() > 3 && info[3].IsFunction()) {
498
- callback = info[3].As<Napi::Function>();
499
- }
500
-
501
- database_ref->Schedule(info.Env(), duckdb::make_uniq<ExecTask>(*this, final_query, callback));
515
+ duckdb::child_list_t<duckdb::Value> buffer_values;
516
+ // This is a little bit evil, but allows us to support both libraries in between 1.2 and 1.3
517
+ if (db.ExtensionIsLoaded("nanoarrow")){
518
+ buffer_values.push_back({"ptr", duckdb::Value::POINTER(raw_ptr)});
519
+ } else {
520
+ buffer_values.push_back({"ptr", duckdb::Value::UBIGINT(raw_ptr)});
521
+ }
522
+ buffer_values.push_back({"size", duckdb::Value::UBIGINT(length)});
523
+ values.push_back(duckdb::Value::STRUCT(buffer_values));
524
+ }
525
+ duckdb::vector<duckdb::Value> list_value;
526
+ list_value.push_back(duckdb::Value::LIST(values));
527
+
528
+ database_ref->Schedule(info.Env(), duckdb::make_uniq<CreateArrowViewTask>(*this, list_value, name));
502
529
 
503
530
  return Value();
504
531
  }
@@ -266,6 +266,7 @@ static const StaticFunctionDefinition core_functions[] = {
266
266
  DUCKDB_SCALAR_FUNCTION(MapConcatFun),
267
267
  DUCKDB_SCALAR_FUNCTION(MapEntriesFun),
268
268
  DUCKDB_SCALAR_FUNCTION(MapExtractFun),
269
+ DUCKDB_SCALAR_FUNCTION(MapExtractValueFun),
269
270
  DUCKDB_SCALAR_FUNCTION(MapFromEntriesFun),
270
271
  DUCKDB_SCALAR_FUNCTION(MapKeysFun),
271
272
  DUCKDB_SCALAR_FUNCTION(MapValuesFun),
@@ -57,6 +57,15 @@ struct ElementAtFun {
57
57
  static constexpr const char *Name = "element_at";
58
58
  };
59
59
 
60
+ struct MapExtractValueFun {
61
+ static constexpr const char *Name = "map_extract_value";
62
+ static constexpr const char *Parameters = "map,key";
63
+ static constexpr const char *Description = "Returns the value for a given key or NULL if the key is not contained in the map. The type of the key provided in the second parameter must match the type of the map’s keys else an error is returned";
64
+ static constexpr const char *Example = "map_extract_value(map(['key'], ['val']), 'key')";
65
+
66
+ static ScalarFunction GetFunction();
67
+ };
68
+
60
69
  struct MapFromEntriesFun {
61
70
  static constexpr const char *Name = "map_from_entries";
62
71
  static constexpr const char *Parameters = "map";
@@ -6,6 +6,7 @@
6
6
  #include "duckdb/main/client_context.hpp"
7
7
  #include "duckdb/planner/expression/bound_function_expression.hpp"
8
8
  #include "duckdb/transaction/meta_transaction.hpp"
9
+ #include "duckdb/planner/expression/bound_cast_expression.hpp"
9
10
 
10
11
  namespace duckdb {
11
12
 
@@ -18,8 +18,8 @@ static void CanCastImplicitlyFunction(DataChunk &args, ExpressionState &state, V
18
18
  }
19
19
 
20
20
  unique_ptr<Expression> BindCanCastImplicitlyExpression(FunctionBindExpressionInput &input) {
21
- auto &source_type = input.function.children[0]->return_type;
22
- auto &target_type = input.function.children[1]->return_type;
21
+ auto &source_type = input.children[0]->return_type;
22
+ auto &target_type = input.children[1]->return_type;
23
23
  if (source_type.id() == LogicalTypeId::UNKNOWN || source_type.id() == LogicalTypeId::SQLNULL ||
24
24
  target_type.id() == LogicalTypeId::UNKNOWN || target_type.id() == LogicalTypeId::SQLNULL) {
25
25
  // parameter - unknown return type
@@ -10,7 +10,7 @@ static void TypeOfFunction(DataChunk &args, ExpressionState &state, Vector &resu
10
10
  }
11
11
 
12
12
  unique_ptr<Expression> BindTypeOfFunctionExpression(FunctionBindExpressionInput &input) {
13
- auto &return_type = input.function.children[0]->return_type;
13
+ auto &return_type = input.children[0]->return_type;
14
14
  if (return_type.id() == LogicalTypeId::UNKNOWN || return_type.id() == LogicalTypeId::SQLNULL) {
15
15
  // parameter - unknown return type
16
16
  return nullptr;
@@ -7,44 +7,41 @@
7
7
 
8
8
  namespace duckdb {
9
9
 
10
- void ListFlattenFunction(DataChunk &args, ExpressionState &state, Vector &result) {
11
- D_ASSERT(args.ColumnCount() == 1);
10
+ static void ListFlattenFunction(DataChunk &args, ExpressionState &, Vector &result) {
12
11
 
13
- Vector &input = args.data[0];
14
- if (input.GetType().id() == LogicalTypeId::SQLNULL) {
15
- result.Reference(input);
12
+ const auto flat_list_data = FlatVector::GetData<list_entry_t>(result);
13
+ auto &flat_list_mask = FlatVector::Validity(result);
14
+
15
+ UnifiedVectorFormat outer_format;
16
+ UnifiedVectorFormat inner_format;
17
+ UnifiedVectorFormat items_format;
18
+
19
+ // Setup outer vec;
20
+ auto &outer_vec = args.data[0];
21
+ const auto outer_count = args.size();
22
+ outer_vec.ToUnifiedFormat(outer_count, outer_format);
23
+
24
+ // Special case: outer list is all-null
25
+ if (outer_vec.GetType().id() == LogicalTypeId::SQLNULL) {
26
+ result.Reference(outer_vec);
16
27
  return;
17
28
  }
18
29
 
19
- idx_t count = args.size();
20
-
21
- // Prepare the result vector
22
- result.SetVectorType(VectorType::FLAT_VECTOR);
23
- // This holds the new offsets and lengths
24
- auto result_entries = FlatVector::GetData<list_entry_t>(result);
25
- auto &result_validity = FlatVector::Validity(result);
26
-
27
- // The outermost list in each row
28
- UnifiedVectorFormat row_data;
29
- input.ToUnifiedFormat(count, row_data);
30
- auto row_entries = UnifiedVectorFormat::GetData<list_entry_t>(row_data);
31
-
32
- // The list elements in each row: [HERE, ...]
33
- auto &row_lists = ListVector::GetEntry(input);
34
- UnifiedVectorFormat row_lists_data;
35
- idx_t total_row_lists = ListVector::GetListSize(input);
36
- row_lists.ToUnifiedFormat(total_row_lists, row_lists_data);
37
- auto row_lists_entries = UnifiedVectorFormat::GetData<list_entry_t>(row_lists_data);
38
-
39
- if (row_lists.GetType().id() == LogicalTypeId::SQLNULL) {
40
- for (idx_t row_cnt = 0; row_cnt < count; row_cnt++) {
41
- auto row_idx = row_data.sel->get_index(row_cnt);
42
- if (!row_data.validity.RowIsValid(row_idx)) {
43
- result_validity.SetInvalid(row_cnt);
30
+ // Setup inner vec
31
+ auto &inner_vec = ListVector::GetEntry(outer_vec);
32
+ const auto inner_count = ListVector::GetListSize(outer_vec);
33
+ inner_vec.ToUnifiedFormat(inner_count, inner_format);
34
+
35
+ // Special case: inner list is all-null
36
+ if (inner_vec.GetType().id() == LogicalTypeId::SQLNULL) {
37
+ for (idx_t outer_raw_idx = 0; outer_raw_idx < outer_count; outer_raw_idx++) {
38
+ const auto outer_idx = outer_format.sel->get_index(outer_raw_idx);
39
+ if (!outer_format.validity.RowIsValid(outer_idx)) {
40
+ flat_list_mask.SetInvalid(outer_raw_idx);
44
41
  continue;
45
42
  }
46
- result_entries[row_cnt].offset = 0;
47
- result_entries[row_cnt].length = 0;
43
+ flat_list_data[outer_raw_idx].offset = 0;
44
+ flat_list_data[outer_raw_idx].length = 0;
48
45
  }
49
46
  if (args.AllConstant()) {
50
47
  result.SetVectorType(VectorType::CONSTANT_VECTOR);
@@ -52,57 +49,90 @@ void ListFlattenFunction(DataChunk &args, ExpressionState &state, Vector &result
52
49
  return;
53
50
  }
54
51
 
55
- // The actual elements inside each row list: [[HERE, ...], []]
56
- // This one becomes the child vector of the result.
57
- auto &elem_vector = ListVector::GetEntry(row_lists);
52
+ // Setup items vec
53
+ auto &items_vec = ListVector::GetEntry(inner_vec);
54
+ const auto items_count = ListVector::GetListSize(inner_vec);
55
+ items_vec.ToUnifiedFormat(items_count, items_format);
56
+
57
+ // First pass: Figure out the total amount of items.
58
+ // This can be more than items_count if the inner list reference the same item(s) multiple times.
59
+
60
+ idx_t total_items = 0;
61
+
62
+ const auto outer_data = UnifiedVectorFormat::GetData<list_entry_t>(outer_format);
63
+ const auto inner_data = UnifiedVectorFormat::GetData<list_entry_t>(inner_format);
64
+
65
+ for (idx_t outer_raw_idx = 0; outer_raw_idx < outer_count; outer_raw_idx++) {
66
+ const auto outer_idx = outer_format.sel->get_index(outer_raw_idx);
67
+
68
+ if (!outer_format.validity.RowIsValid(outer_idx)) {
69
+ continue;
70
+ }
71
+
72
+ const auto &outer_entry = outer_data[outer_idx];
73
+
74
+ for (idx_t inner_raw_idx = outer_entry.offset; inner_raw_idx < outer_entry.offset + outer_entry.length;
75
+ inner_raw_idx++) {
76
+ const auto inner_idx = inner_format.sel->get_index(inner_raw_idx);
58
77
 
59
- // We'll use this selection vector to slice the elem_vector.
60
- idx_t child_elem_cnt = ListVector::GetListSize(row_lists);
61
- SelectionVector sel(child_elem_cnt);
78
+ if (!inner_format.validity.RowIsValid(inner_idx)) {
79
+ continue;
80
+ }
81
+
82
+ const auto &inner_entry = inner_data[inner_idx];
83
+
84
+ total_items += inner_entry.length;
85
+ }
86
+ }
87
+
88
+ // Now we know the total amount of items, we can create our selection vector.
89
+ SelectionVector sel(total_items);
62
90
  idx_t sel_idx = 0;
63
91
 
64
- // HERE, [[]], ...
65
- for (idx_t row_cnt = 0; row_cnt < count; row_cnt++) {
66
- auto row_idx = row_data.sel->get_index(row_cnt);
92
+ // Second pass: Fill the selection vector (and the result list entries)
93
+
94
+ for (idx_t outer_raw_idx = 0; outer_raw_idx < outer_count; outer_raw_idx++) {
95
+ const auto outer_idx = outer_format.sel->get_index(outer_raw_idx);
67
96
 
68
- if (!row_data.validity.RowIsValid(row_idx)) {
69
- result_validity.SetInvalid(row_cnt);
97
+ if (!outer_format.validity.RowIsValid(outer_idx)) {
98
+ flat_list_mask.SetInvalid(outer_raw_idx);
70
99
  continue;
71
100
  }
72
101
 
73
- idx_t list_offset = sel_idx;
74
- idx_t list_length = 0;
102
+ const auto &outer_entry = outer_data[outer_idx];
103
+
104
+ list_entry_t list_entry = {sel_idx, 0};
75
105
 
76
- // [HERE, [...], ...]
77
- auto row_entry = row_entries[row_idx];
78
- for (idx_t row_lists_cnt = 0; row_lists_cnt < row_entry.length; row_lists_cnt++) {
79
- auto row_lists_idx = row_lists_data.sel->get_index(row_entry.offset + row_lists_cnt);
106
+ for (idx_t inner_raw_idx = outer_entry.offset; inner_raw_idx < outer_entry.offset + outer_entry.length;
107
+ inner_raw_idx++) {
108
+ const auto inner_idx = inner_format.sel->get_index(inner_raw_idx);
80
109
 
81
- // Skip invalid lists
82
- if (!row_lists_data.validity.RowIsValid(row_lists_idx)) {
110
+ if (!inner_format.validity.RowIsValid(inner_idx)) {
83
111
  continue;
84
112
  }
85
113
 
86
- // [[HERE, ...], [.., ...]]
87
- auto list_entry = row_lists_entries[row_lists_idx];
88
- list_length += list_entry.length;
114
+ const auto &inner_entry = inner_data[inner_idx];
115
+
116
+ list_entry.length += inner_entry.length;
117
+
118
+ for (idx_t elem_raw_idx = inner_entry.offset; elem_raw_idx < inner_entry.offset + inner_entry.length;
119
+ elem_raw_idx++) {
120
+ const auto elem_idx = items_format.sel->get_index(elem_raw_idx);
89
121
 
90
- for (idx_t elem_cnt = 0; elem_cnt < list_entry.length; elem_cnt++) {
91
- // offset of the element in the elem_vector.
92
- idx_t offset = list_entry.offset + elem_cnt;
93
- sel.set_index(sel_idx, offset);
122
+ sel.set_index(sel_idx, elem_idx);
94
123
  sel_idx++;
95
124
  }
96
125
  }
97
126
 
98
- result_entries[row_cnt].offset = list_offset;
99
- result_entries[row_cnt].length = list_length;
127
+ // Assign the result list entry
128
+ flat_list_data[outer_raw_idx] = list_entry;
100
129
  }
101
130
 
131
+ // Now assing the result
102
132
  ListVector::SetListSize(result, sel_idx);
103
133
 
104
134
  auto &result_child_vector = ListVector::GetEntry(result);
105
- result_child_vector.Slice(elem_vector, sel, sel_idx);
135
+ result_child_vector.Slice(items_vec, sel, sel_idx);
106
136
  result_child_vector.Flatten(sel_idx);
107
137
 
108
138
  if (args.AllConstant()) {
@@ -6,35 +6,36 @@
6
6
 
7
7
  namespace duckdb {
8
8
 
9
+ template <bool EXTRACT_VALUE>
9
10
  static unique_ptr<FunctionData> MapExtractBind(ClientContext &, ScalarFunction &bound_function,
10
11
  vector<unique_ptr<Expression>> &arguments) {
11
12
  if (arguments.size() != 2) {
12
13
  throw BinderException("MAP_EXTRACT must have exactly two arguments");
13
14
  }
14
15
 
15
- auto &map_type = arguments[0]->return_type;
16
- auto &input_type = arguments[1]->return_type;
16
+ const auto &map_type = arguments[0]->return_type;
17
+ const auto &input_type = arguments[1]->return_type;
17
18
 
18
19
  if (map_type.id() == LogicalTypeId::SQLNULL) {
19
- bound_function.return_type = LogicalTypeId::SQLNULL;
20
+ bound_function.return_type = EXTRACT_VALUE ? LogicalTypeId::SQLNULL : LogicalType::LIST(LogicalTypeId::SQLNULL);
20
21
  return make_uniq<VariableReturnBindData>(bound_function.return_type);
21
22
  }
22
23
 
23
24
  if (map_type.id() != LogicalTypeId::MAP) {
24
- throw BinderException("MAP_EXTRACT can only operate on MAPs");
25
+ throw BinderException("'%s' can only operate on MAPs", bound_function.name);
25
26
  }
26
27
  auto &value_type = MapType::ValueType(map_type);
27
28
 
28
29
  //! Here we have to construct the List Type that will be returned
29
- bound_function.return_type = value_type;
30
- auto key_type = MapType::KeyType(map_type);
30
+ bound_function.return_type = EXTRACT_VALUE ? value_type : LogicalType::LIST(value_type);
31
+ const auto &key_type = MapType::KeyType(map_type);
31
32
  if (key_type.id() != LogicalTypeId::SQLNULL && input_type.id() != LogicalTypeId::SQLNULL) {
32
33
  bound_function.arguments[1] = MapType::KeyType(map_type);
33
34
  }
34
35
  return make_uniq<VariableReturnBindData>(bound_function.return_type);
35
36
  }
36
37
 
37
- static void MapExtractFunc(DataChunk &args, ExpressionState &state, Vector &result) {
38
+ static void MapExtractValueFunc(DataChunk &args, ExpressionState &state, Vector &result) {
38
39
  const auto count = args.size();
39
40
 
40
41
  auto &map_vec = args.data[0];
@@ -94,8 +95,88 @@ static void MapExtractFunc(DataChunk &args, ExpressionState &state, Vector &resu
94
95
  result.Verify(count);
95
96
  }
96
97
 
98
+ static void MapExtractListFunc(DataChunk &args, ExpressionState &state, Vector &result) {
99
+ const auto count = args.size();
100
+
101
+ auto &map_vec = args.data[0];
102
+ auto &arg_vec = args.data[1];
103
+
104
+ const auto map_is_null = map_vec.GetType().id() == LogicalTypeId::SQLNULL;
105
+ const auto arg_is_null = arg_vec.GetType().id() == LogicalTypeId::SQLNULL;
106
+
107
+ if (map_is_null || arg_is_null) {
108
+ // Short-circuit if either the map or the arg is NULL
109
+ ListVector::SetListSize(result, 0);
110
+ result.SetVectorType(VectorType::CONSTANT_VECTOR);
111
+ ConstantVector::GetData<list_entry_t>(result)[0] = {0, 0};
112
+ result.Verify(count);
113
+ return;
114
+ }
115
+
116
+ auto &key_vec = MapVector::GetKeys(map_vec);
117
+ auto &val_vec = MapVector::GetValues(map_vec);
118
+
119
+ // Collect the matching positions
120
+ Vector pos_vec(LogicalType::INTEGER, count);
121
+ ListSearchOp<true>(map_vec, key_vec, arg_vec, pos_vec, args.size());
122
+
123
+ UnifiedVectorFormat val_format;
124
+ UnifiedVectorFormat pos_format;
125
+ UnifiedVectorFormat lst_format;
126
+
127
+ val_vec.ToUnifiedFormat(ListVector::GetListSize(map_vec), val_format);
128
+ pos_vec.ToUnifiedFormat(count, pos_format);
129
+ map_vec.ToUnifiedFormat(count, lst_format);
130
+
131
+ const auto pos_data = UnifiedVectorFormat::GetData<int32_t>(pos_format);
132
+ const auto inc_list_data = ListVector::GetData(map_vec);
133
+ const auto out_list_data = ListVector::GetData(result);
134
+
135
+ idx_t offset = 0;
136
+ for (idx_t row_idx = 0; row_idx < count; row_idx++) {
137
+ const auto lst_idx = lst_format.sel->get_index(row_idx);
138
+ if (!lst_format.validity.RowIsValid(lst_idx)) {
139
+ FlatVector::SetNull(result, row_idx, true);
140
+ continue;
141
+ }
142
+
143
+ auto &inc_list = inc_list_data[lst_idx];
144
+ auto &out_list = out_list_data[row_idx];
145
+
146
+ const auto pos_idx = pos_format.sel->get_index(row_idx);
147
+ if (!pos_format.validity.RowIsValid(pos_idx)) {
148
+ // We didnt find the key in the map, so return emptyl ist
149
+ out_list.offset = offset;
150
+ out_list.length = 0;
151
+ continue;
152
+ }
153
+
154
+ // Compute the actual position of the value in the map value vector
155
+ const auto pos = inc_list.offset + UnsafeNumericCast<idx_t>(pos_data[pos_idx] - 1);
156
+ out_list.offset = offset;
157
+ out_list.length = 1;
158
+ ListVector::Append(result, val_vec, pos + 1, pos);
159
+ offset++;
160
+ }
161
+
162
+ if (args.size() == 1) {
163
+ result.SetVectorType(VectorType::CONSTANT_VECTOR);
164
+ }
165
+
166
+ result.Verify(count);
167
+ }
168
+
169
+ ScalarFunction MapExtractValueFun::GetFunction() {
170
+ ScalarFunction fun({LogicalType::ANY, LogicalType::ANY}, LogicalType::ANY, MapExtractValueFunc,
171
+ MapExtractBind<true>);
172
+ fun.varargs = LogicalType::ANY;
173
+ fun.null_handling = FunctionNullHandling::SPECIAL_HANDLING;
174
+ return fun;
175
+ }
176
+
97
177
  ScalarFunction MapExtractFun::GetFunction() {
98
- ScalarFunction fun({LogicalType::ANY, LogicalType::ANY}, LogicalType::ANY, MapExtractFunc, MapExtractBind);
178
+ ScalarFunction fun({LogicalType::ANY, LogicalType::ANY}, LogicalType::ANY, MapExtractListFunc,
179
+ MapExtractBind<false>);
99
180
  fun.varargs = LogicalType::ANY;
100
181
  fun.null_handling = FunctionNullHandling::SPECIAL_HANDLING;
101
182
  return fun;
@@ -0,0 +1,63 @@
1
+ #include "include/icu-dateadd.hpp"
2
+
3
+ #include "duckdb/main/extension_util.hpp"
4
+ #include "duckdb/common/types/time.hpp"
5
+ #include "duckdb/common/types/timestamp.hpp"
6
+ #include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
7
+ #include "duckdb/planner/expression/bound_function_expression.hpp"
8
+ #include "duckdb/transaction/meta_transaction.hpp"
9
+ #include "include/icu-current.hpp"
10
+ #include "include/icu-casts.hpp"
11
+
12
+ namespace duckdb {
13
+
14
+ static timestamp_t GetTransactionTimestamp(ExpressionState &state) {
15
+ return MetaTransaction::Get(state.GetContext()).start_timestamp;
16
+ }
17
+
18
+ static void CurrentTimeFunction(DataChunk &input, ExpressionState &state, Vector &result) {
19
+ D_ASSERT(input.ColumnCount() == 0);
20
+ auto instant = GetTransactionTimestamp(state);
21
+ ICUDateFunc::BindData data(state.GetContext());
22
+
23
+ dtime_tz_t result_time(dtime_t(0), 0);
24
+ ICUToTimeTZ::ToTimeTZ(data.calendar.get(), instant, result_time);
25
+ auto val = Value::TIMETZ(result_time);
26
+ result.Reference(val);
27
+ }
28
+
29
+ static void CurrentDateFunction(DataChunk &input, ExpressionState &state, Vector &result) {
30
+ D_ASSERT(input.ColumnCount() == 0);
31
+ auto instant = GetTransactionTimestamp(state);
32
+
33
+ auto val = Value::DATE(ICUMakeDate::ToDate(state.GetContext(), instant));
34
+ result.Reference(val);
35
+ }
36
+
37
+ ScalarFunction GetCurrentTimeFun() {
38
+ ScalarFunction current_time({}, LogicalType::TIME_TZ, CurrentTimeFunction);
39
+ current_time.stability = FunctionStability::CONSISTENT_WITHIN_QUERY;
40
+ return current_time;
41
+ }
42
+
43
+ ScalarFunction GetCurrentDateFun() {
44
+ ScalarFunction current_date({}, LogicalType::DATE, CurrentDateFunction);
45
+ current_date.stability = FunctionStability::CONSISTENT_WITHIN_QUERY;
46
+ return current_date;
47
+ }
48
+
49
+ void RegisterICUCurrentFunctions(DatabaseInstance &db) {
50
+ // temporal + interval
51
+ ScalarFunctionSet current_time("get_current_time");
52
+ current_time.AddFunction(GetCurrentTimeFun());
53
+ ExtensionUtil::RegisterFunction(db, current_time);
54
+
55
+ ScalarFunctionSet current_date("current_date");
56
+ current_date.AddFunction(GetCurrentDateFun());
57
+ ExtensionUtil::RegisterFunction(db, current_date);
58
+
59
+ current_date.name = "today";
60
+ ExtensionUtil::RegisterFunction(db, current_date);
61
+ }
62
+
63
+ } // namespace duckdb