duckdb 0.8.2-dev4871.0 → 0.8.2-dev5080.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 (85) hide show
  1. package/package.json +1 -1
  2. package/src/duckdb/extension/icu/icu-strptime.cpp +1 -0
  3. package/src/duckdb/extension/json/json_functions/copy_json.cpp +1 -1
  4. package/src/duckdb/src/common/enum_util.cpp +5 -0
  5. package/src/duckdb/src/common/operator/cast_operators.cpp +18 -0
  6. package/src/duckdb/src/common/row_operations/row_matcher.cpp +5 -38
  7. package/src/duckdb/src/common/types/data_chunk.cpp +47 -10
  8. package/src/duckdb/src/common/types/vector.cpp +0 -1
  9. package/src/duckdb/src/common/types.cpp +10 -1
  10. package/src/duckdb/src/core_functions/scalar/date/strftime.cpp +2 -2
  11. package/src/duckdb/src/core_functions/scalar/list/array_slice.cpp +18 -8
  12. package/src/duckdb/src/core_functions/scalar/list/list_sort.cpp +10 -1
  13. package/src/duckdb/src/core_functions/scalar/map/map_concat.cpp +0 -2
  14. package/src/duckdb/src/core_functions/scalar/struct/struct_pack.cpp +12 -6
  15. package/src/duckdb/src/execution/nested_loop_join/nested_loop_join_inner.cpp +20 -27
  16. package/src/duckdb/src/execution/nested_loop_join/nested_loop_join_mark.cpp +21 -9
  17. package/src/duckdb/src/execution/operator/aggregate/physical_hash_aggregate.cpp +7 -7
  18. package/src/duckdb/src/execution/operator/csv_scanner/csv_reader_options.cpp +1 -1
  19. package/src/duckdb/src/execution/operator/csv_scanner/parallel_csv_reader.cpp +0 -2
  20. package/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_detection.cpp +14 -2
  21. package/src/duckdb/src/execution/operator/persistent/physical_export.cpp +1 -1
  22. package/src/duckdb/src/execution/physical_plan/plan_comparison_join.cpp +13 -8
  23. package/src/duckdb/src/function/cast/struct_cast.cpp +8 -0
  24. package/src/duckdb/src/function/cast/time_casts.cpp +12 -0
  25. package/src/duckdb/src/function/cast/union_casts.cpp +5 -0
  26. package/src/duckdb/src/function/function_binder.cpp +11 -2
  27. package/src/duckdb/src/function/pragma/pragma_functions.cpp +5 -0
  28. package/src/duckdb/src/function/pragma/pragma_queries.cpp +3 -0
  29. package/src/duckdb/src/function/scalar/strftime_format.cpp +29 -8
  30. package/src/duckdb/src/function/table/arrow.cpp +4 -0
  31. package/src/duckdb/src/function/table/copy_csv.cpp +2 -1
  32. package/src/duckdb/src/function/table/read_csv.cpp +4 -1
  33. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  34. package/src/duckdb/src/include/duckdb/common/multi_file_reader.hpp +5 -0
  35. package/src/duckdb/src/include/duckdb/common/operator/cast_operators.hpp +27 -0
  36. package/src/duckdb/src/include/duckdb/common/operator/comparison_operators.hpp +38 -2
  37. package/src/duckdb/src/include/duckdb/common/types.hpp +1 -0
  38. package/src/duckdb/src/include/duckdb/core_functions/scalar/bit_functions.hpp +4 -4
  39. package/src/duckdb/src/include/duckdb/core_functions/scalar/blob_functions.hpp +4 -4
  40. package/src/duckdb/src/include/duckdb/core_functions/scalar/date_functions.hpp +5 -5
  41. package/src/duckdb/src/include/duckdb/core_functions/scalar/enum_functions.hpp +7 -7
  42. package/src/duckdb/src/include/duckdb/core_functions/scalar/generic_functions.hpp +12 -12
  43. package/src/duckdb/src/include/duckdb/core_functions/scalar/list_functions.hpp +12 -12
  44. package/src/duckdb/src/include/duckdb/core_functions/scalar/map_functions.hpp +3 -3
  45. package/src/duckdb/src/include/duckdb/core_functions/scalar/math_functions.hpp +33 -33
  46. package/src/duckdb/src/include/duckdb/core_functions/scalar/operators_functions.hpp +2 -2
  47. package/src/duckdb/src/include/duckdb/core_functions/scalar/random_functions.hpp +3 -3
  48. package/src/duckdb/src/include/duckdb/core_functions/scalar/string_functions.hpp +12 -12
  49. package/src/duckdb/src/include/duckdb/core_functions/scalar/struct_functions.hpp +2 -2
  50. package/src/duckdb/src/include/duckdb/core_functions/scalar/union_functions.hpp +2 -2
  51. package/src/duckdb/src/include/duckdb/function/scalar/strftime_format.hpp +2 -1
  52. package/src/duckdb/src/include/duckdb/main/client_config.hpp +2 -0
  53. package/src/duckdb/src/include/duckdb/main/prepared_statement_data.hpp +1 -0
  54. package/src/duckdb/src/include/duckdb/planner/bound_parameter_map.hpp +28 -1
  55. package/src/duckdb/src/include/duckdb/planner/expression/bound_parameter_data.hpp +0 -18
  56. package/src/duckdb/src/include/duckdb/planner/expression/bound_parameter_expression.hpp +1 -1
  57. package/src/duckdb/src/include/duckdb/planner/expression_binder/base_select_binder.hpp +1 -0
  58. package/src/duckdb/src/include/duckdb/planner/operator/logical_create_table.hpp +1 -2
  59. package/src/duckdb/src/include/duckdb/planner/operator/logical_delete.hpp +1 -1
  60. package/src/duckdb/src/include/duckdb/planner/operator/logical_insert.hpp +1 -1
  61. package/src/duckdb/src/include/duckdb/planner/operator/logical_update.hpp +1 -1
  62. package/src/duckdb/src/include/duckdb/planner/planner.hpp +1 -1
  63. package/src/duckdb/src/include/duckdb/storage/data_table.hpp +1 -1
  64. package/src/duckdb/src/include/duckdb/storage/table/row_group_collection.hpp +1 -1
  65. package/src/duckdb/src/main/capi/prepared-c.cpp +9 -3
  66. package/src/duckdb/src/planner/binder/expression/bind_comparison_expression.cpp +1 -0
  67. package/src/duckdb/src/planner/binder/expression/bind_parameter_expression.cpp +9 -19
  68. package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +28 -6
  69. package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +3 -0
  70. package/src/duckdb/src/planner/bound_parameter_map.cpp +67 -0
  71. package/src/duckdb/src/planner/expression_binder/base_select_binder.cpp +14 -6
  72. package/src/duckdb/src/planner/operator/logical_create_table.cpp +3 -3
  73. package/src/duckdb/src/planner/operator/logical_delete.cpp +3 -2
  74. package/src/duckdb/src/planner/operator/logical_insert.cpp +3 -2
  75. package/src/duckdb/src/planner/operator/logical_update.cpp +3 -2
  76. package/src/duckdb/src/planner/planner.cpp +2 -2
  77. package/src/duckdb/src/storage/data_table.cpp +8 -8
  78. package/src/duckdb/src/storage/local_storage.cpp +2 -3
  79. package/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp +64 -80
  80. package/src/duckdb/src/storage/storage_manager.cpp +6 -2
  81. package/src/duckdb/src/storage/table/row_group.cpp +6 -0
  82. package/src/duckdb/src/storage/table/row_group_collection.cpp +4 -3
  83. package/src/duckdb/src/storage/table/struct_column_data.cpp +5 -0
  84. package/src/duckdb/src/transaction/duck_transaction.cpp +1 -0
  85. package/src/duckdb/ub_src_planner.cpp +2 -0
@@ -18,7 +18,7 @@ namespace duckdb {
18
18
  struct RandomFun {
19
19
  static constexpr const char *Name = "random";
20
20
  static constexpr const char *Parameters = "";
21
- static constexpr const char *Description = "returns a random number between 0 and 1";
21
+ static constexpr const char *Description = "Returns a random number between 0 and 1";
22
22
  static constexpr const char *Example = "random()";
23
23
 
24
24
  static ScalarFunction GetFunction();
@@ -27,7 +27,7 @@ struct RandomFun {
27
27
  struct SetseedFun {
28
28
  static constexpr const char *Name = "setseed";
29
29
  static constexpr const char *Parameters = "";
30
- static constexpr const char *Description = "sets the seed to be used for the random function";
30
+ static constexpr const char *Description = "Sets the seed to be used for the random function";
31
31
  static constexpr const char *Example = "setseed(0.42)";
32
32
 
33
33
  static ScalarFunction GetFunction();
@@ -36,7 +36,7 @@ struct SetseedFun {
36
36
  struct UUIDFun {
37
37
  static constexpr const char *Name = "uuid";
38
38
  static constexpr const char *Parameters = "";
39
- static constexpr const char *Description = "Return a random uuid similar to this: eeccb8c5-9943-b2bb-bb5e-222f4e14b687";
39
+ static constexpr const char *Description = "Returns a random UUID similar to this: eeccb8c5-9943-b2bb-bb5e-222f4e14b687";
40
40
  static constexpr const char *Example = "uuid()";
41
41
 
42
42
  static ScalarFunction GetFunction();
@@ -18,7 +18,7 @@ namespace duckdb {
18
18
  struct StartsWithOperatorFun {
19
19
  static constexpr const char *Name = "^@";
20
20
  static constexpr const char *Parameters = "string,search_string";
21
- static constexpr const char *Description = "Return true if string begins with search_string";
21
+ static constexpr const char *Description = "Returns true if string begins with search_string";
22
22
  static constexpr const char *Example = "starts_with('abc','a')";
23
23
 
24
24
  static ScalarFunction GetFunction();
@@ -33,7 +33,7 @@ struct StartsWithFun {
33
33
  struct ASCIIFun {
34
34
  static constexpr const char *Name = "ascii";
35
35
  static constexpr const char *Parameters = "string";
36
- static constexpr const char *Description = "Returns an integer that represents the Unicode code point of the first character of the string.";
36
+ static constexpr const char *Description = "Returns an integer that represents the Unicode code point of the first character of the string";
37
37
  static constexpr const char *Example = "ascii('Ω')";
38
38
 
39
39
  static ScalarFunction GetFunction();
@@ -42,7 +42,7 @@ struct ASCIIFun {
42
42
  struct BarFun {
43
43
  static constexpr const char *Name = "bar";
44
44
  static constexpr const char *Parameters = "x,min,max,width";
45
- static constexpr const char *Description = "Draw a band whose width is proportional to (x - min) and equal to width characters when x = max. width defaults to 80.";
45
+ static constexpr const char *Description = "Draws a band whose width is proportional to (x - min) and equal to width characters when x = max. width defaults to 80";
46
46
  static constexpr const char *Example = "bar(5, 0, 20, 10)";
47
47
 
48
48
  static ScalarFunctionSet GetFunctions();
@@ -66,7 +66,7 @@ struct ToBinaryFun {
66
66
  struct ChrFun {
67
67
  static constexpr const char *Name = "chr";
68
68
  static constexpr const char *Parameters = "code_point";
69
- static constexpr const char *Description = "returns a character which is corresponding the ASCII code value or Unicode code point";
69
+ static constexpr const char *Description = "Returns a character which is corresponding the ASCII code value or Unicode code point";
70
70
  static constexpr const char *Example = "chr(65)";
71
71
 
72
72
  static ScalarFunction GetFunction();
@@ -75,7 +75,7 @@ struct ChrFun {
75
75
  struct DamerauLevenshteinFun {
76
76
  static constexpr const char *Name = "damerau_levenshtein";
77
77
  static constexpr const char *Parameters = "str1,str2";
78
- static constexpr const char *Description = "Extension of Levenshtein distance to also include transposition of adjacent characters as an allowed edit operation. In other words, the minimum number of edit operations (insertions, deletions, substitutions or transpositions) required to change one string to another. Different case is considered different.";
78
+ static constexpr const char *Description = "Extension of Levenshtein distance to also include transposition of adjacent characters as an allowed edit operation. In other words, the minimum number of edit operations (insertions, deletions, substitutions or transpositions) required to change one string to another. Different case is considered different";
79
79
  static constexpr const char *Example = "damerau_levenshtein('hello', 'world')";
80
80
 
81
81
  static ScalarFunction GetFunction();
@@ -108,7 +108,7 @@ struct FormatreadabledecimalsizeFun {
108
108
  struct HammingFun {
109
109
  static constexpr const char *Name = "hamming";
110
110
  static constexpr const char *Parameters = "str1,str2";
111
- static constexpr const char *Description = "The number of positions with different characters for 2 strings of equal length. Different case is considered different.";
111
+ static constexpr const char *Description = "The number of positions with different characters for 2 strings of equal length. Different case is considered different";
112
112
  static constexpr const char *Example = "hamming('duck','luck')";
113
113
 
114
114
  static ScalarFunction GetFunction();
@@ -138,7 +138,7 @@ struct ToHexFun {
138
138
  struct InstrFun {
139
139
  static constexpr const char *Name = "instr";
140
140
  static constexpr const char *Parameters = "haystack,needle";
141
- static constexpr const char *Description = "Return location of first occurrence of needle in haystack, counting from 1. Returns 0 if no match found.";
141
+ static constexpr const char *Description = "Returns location of first occurrence of needle in haystack, counting from 1. Returns 0 if no match found";
142
142
  static constexpr const char *Example = "instr('test test','es')";
143
143
 
144
144
  static ScalarFunction GetFunction();
@@ -159,7 +159,7 @@ struct PositionFun {
159
159
  struct JaccardFun {
160
160
  static constexpr const char *Name = "jaccard";
161
161
  static constexpr const char *Parameters = "str1,str2";
162
- static constexpr const char *Description = "The Jaccard similarity between two strings. Different case is considered different. Returns a number between 0 and 1.";
162
+ static constexpr const char *Description = "The Jaccard similarity between two strings. Different case is considered different. Returns a number between 0 and 1";
163
163
  static constexpr const char *Example = "jaccard('duck','luck')";
164
164
 
165
165
  static ScalarFunction GetFunction();
@@ -168,7 +168,7 @@ struct JaccardFun {
168
168
  struct JaroSimilarityFun {
169
169
  static constexpr const char *Name = "jaro_similarity";
170
170
  static constexpr const char *Parameters = "str1,str2";
171
- static constexpr const char *Description = "The Jaro similarity between two strings. Different case is considered different. Returns a number between 0 and 1.";
171
+ static constexpr const char *Description = "The Jaro similarity between two strings. Different case is considered different. Returns a number between 0 and 1";
172
172
  static constexpr const char *Example = "jaro_similarity('duck','duckdb')";
173
173
 
174
174
  static ScalarFunction GetFunction();
@@ -177,7 +177,7 @@ struct JaroSimilarityFun {
177
177
  struct JaroWinklerSimilarityFun {
178
178
  static constexpr const char *Name = "jaro_winkler_similarity";
179
179
  static constexpr const char *Parameters = "str1,str2";
180
- static constexpr const char *Description = "The Jaro-Winkler similarity between two strings. Different case is considered different. Returns a number between 0 and 1.";
180
+ static constexpr const char *Description = "The Jaro-Winkler similarity between two strings. Different case is considered different. Returns a number between 0 and 1";
181
181
  static constexpr const char *Example = "jaro_winkler_similarity('duck','duckdb')";
182
182
 
183
183
  static ScalarFunction GetFunction();
@@ -204,7 +204,7 @@ struct LeftGraphemeFun {
204
204
  struct LevenshteinFun {
205
205
  static constexpr const char *Name = "levenshtein";
206
206
  static constexpr const char *Parameters = "str1,str2";
207
- static constexpr const char *Description = "The minimum number of single-character edits (insertions, deletions or substitutions) required to change one string to the other. Different case is considered different.";
207
+ static constexpr const char *Description = "The minimum number of single-character edits (insertions, deletions or substitutions) required to change one string to the other. Different case is considered different";
208
208
  static constexpr const char *Example = "levenshtein('duck','db')";
209
209
 
210
210
  static ScalarFunction GetFunction();
@@ -402,7 +402,7 @@ struct RegexpSplitToArrayFun {
402
402
  struct TranslateFun {
403
403
  static constexpr const char *Name = "translate";
404
404
  static constexpr const char *Parameters = "string,from,to";
405
- static constexpr const char *Description = "Replaces each character in string that matches a character in the from set with the corresponding character in the to set. If from is longer than to, occurrences of the extra characters in from are deleted.";
405
+ static constexpr const char *Description = "Replaces each character in string that matches a character in the from set with the corresponding character in the to set. If from is longer than to, occurrences of the extra characters in from are deleted";
406
406
  static constexpr const char *Example = "translate('12345', '143', 'ax')";
407
407
 
408
408
  static ScalarFunction GetFunction();
@@ -18,7 +18,7 @@ namespace duckdb {
18
18
  struct StructInsertFun {
19
19
  static constexpr const char *Name = "struct_insert";
20
20
  static constexpr const char *Parameters = "struct,any";
21
- static constexpr const char *Description = "Add field(s)/value(s) to an existing STRUCT with the argument values. The entry name(s) will be the bound variable name(s).";
21
+ static constexpr const char *Description = "Adds field(s)/value(s) to an existing STRUCT with the argument values. The entry name(s) will be the bound variable name(s)";
22
22
  static constexpr const char *Example = "struct_insert({'a': 1}, b := 2)";
23
23
 
24
24
  static ScalarFunction GetFunction();
@@ -27,7 +27,7 @@ struct StructInsertFun {
27
27
  struct StructPackFun {
28
28
  static constexpr const char *Name = "struct_pack";
29
29
  static constexpr const char *Parameters = "any";
30
- static constexpr const char *Description = "Create a STRUCT containing the argument values. The entry name will be the bound variable name";
30
+ static constexpr const char *Description = "Creates a STRUCT containing the argument values. The entry name will be the bound variable name";
31
31
  static constexpr const char *Example = "struct_pack(i := 4, s := 'string')";
32
32
 
33
33
  static ScalarFunction GetFunction();
@@ -27,7 +27,7 @@ struct UnionExtractFun {
27
27
  struct UnionTagFun {
28
28
  static constexpr const char *Name = "union_tag";
29
29
  static constexpr const char *Parameters = "union";
30
- static constexpr const char *Description = "Retrieve the currently selected tag of the union as an Enum.";
30
+ static constexpr const char *Description = "Retrieve the currently selected tag of the union as an ENUM";
31
31
  static constexpr const char *Example = "union_tag(union_value(k := 'foo'))";
32
32
 
33
33
  static ScalarFunction GetFunction();
@@ -36,7 +36,7 @@ struct UnionTagFun {
36
36
  struct UnionValueFun {
37
37
  static constexpr const char *Name = "union_value";
38
38
  static constexpr const char *Parameters = "tag";
39
- static constexpr const char *Description = "Create a single member UNION containing the argument value. The tag of the value will be the bound variable name.";
39
+ static constexpr const char *Description = "Create a single member UNION containing the argument value. The tag of the value will be the bound variable name";
40
40
  static constexpr const char *Example = "union_value(k := 'hello')";
41
41
 
42
42
  static ScalarFunction GetFunction();
@@ -52,7 +52,8 @@ enum class StrTimeSpecifier : uint8_t {
52
52
  LOCALE_APPROPRIATE_DATE_AND_TIME =
53
53
  29, // %c - Locale’s appropriate date and time representation. (Mon Sep 30 07:06:05 2013)
54
54
  LOCALE_APPROPRIATE_DATE = 30, // %x - Locale’s appropriate date representation. (09/30/13)
55
- LOCALE_APPROPRIATE_TIME = 31 // %X - Locale’s appropriate time representation. (07:06:05)
55
+ LOCALE_APPROPRIATE_TIME = 31, // %X - Locale’s appropriate time representation. (07:06:05)
56
+ NANOSECOND_PADDED = 32 // %n - Nanosecond as a decimal number, zero-padded on the left. (000000000 - 999999999)
56
57
  };
57
58
 
58
59
  struct StrTimeFormat {
@@ -67,6 +67,8 @@ struct ClientConfig {
67
67
  bool enable_caching_operators = true;
68
68
  //! Force parallelism of small tables, used for testing
69
69
  bool verify_parallelism = false;
70
+ //! Enable the optimizer to consider index joins, which are disabled on default
71
+ bool enable_index_join = false;
70
72
  //! Force index join independent of table cardinality, used for testing
71
73
  bool force_index_join = false;
72
74
  //! Force out-of-core computation for operators that support it, used for testing
@@ -14,6 +14,7 @@
14
14
  #include "duckdb/common/unordered_set.hpp"
15
15
  #include "duckdb/common/winapi.hpp"
16
16
  #include "duckdb/planner/expression/bound_parameter_data.hpp"
17
+ #include "duckdb/planner/bound_parameter_map.hpp"
17
18
 
18
19
  namespace duckdb {
19
20
  class CatalogEntry;
@@ -10,12 +10,39 @@
10
10
 
11
11
  #include "duckdb/common/types.hpp"
12
12
  #include "duckdb/common/unordered_map.hpp"
13
+ #include "duckdb/planner/expression/bound_parameter_data.hpp"
13
14
  #include "duckdb/common/case_insensitive_map.hpp"
14
15
 
15
16
  namespace duckdb {
16
17
 
17
- struct BoundParameterData;
18
+ class ParameterExpression;
19
+ class BoundParameterExpression;
18
20
 
19
21
  using bound_parameter_map_t = case_insensitive_map_t<shared_ptr<BoundParameterData>>;
20
22
 
23
+ struct BoundParameterMap {
24
+ public:
25
+ explicit BoundParameterMap(case_insensitive_map_t<BoundParameterData> &parameter_data);
26
+
27
+ public:
28
+ LogicalType GetReturnType(const string &identifier);
29
+
30
+ bound_parameter_map_t *GetParametersPtr();
31
+
32
+ const bound_parameter_map_t &GetParameters();
33
+
34
+ const case_insensitive_map_t<BoundParameterData> &GetParameterData();
35
+
36
+ unique_ptr<BoundParameterExpression> BindParameterExpression(ParameterExpression &expr);
37
+
38
+ private:
39
+ shared_ptr<BoundParameterData> CreateOrGetData(const string &identifier);
40
+ void CreateNewParameter(const string &id, const shared_ptr<BoundParameterData> &param_data);
41
+
42
+ private:
43
+ bound_parameter_map_t parameters;
44
+ // Pre-provided parameter data if populated
45
+ case_insensitive_map_t<BoundParameterData> &parameter_data;
46
+ };
47
+
21
48
  } // namespace duckdb
@@ -9,7 +9,6 @@
9
9
  #pragma once
10
10
 
11
11
  #include "duckdb/common/types/value.hpp"
12
- #include "duckdb/planner/bound_parameter_map.hpp"
13
12
  #include "duckdb/common/case_insensitive_map.hpp"
14
13
 
15
14
  namespace duckdb {
@@ -40,21 +39,4 @@ public:
40
39
  static shared_ptr<BoundParameterData> Deserialize(Deserializer &deserializer);
41
40
  };
42
41
 
43
- struct BoundParameterMap {
44
- explicit BoundParameterMap(case_insensitive_map_t<BoundParameterData> &parameter_data)
45
- : parameter_data(parameter_data) {
46
- }
47
-
48
- bound_parameter_map_t parameters;
49
- case_insensitive_map_t<BoundParameterData> &parameter_data;
50
-
51
- LogicalType GetReturnType(const string &identifier) {
52
- auto it = parameter_data.find(identifier);
53
- if (it == parameter_data.end()) {
54
- return LogicalTypeId::UNKNOWN;
55
- }
56
- return it->second.return_type;
57
- }
58
- };
59
-
60
42
  } // namespace duckdb
@@ -9,7 +9,7 @@
9
9
  #pragma once
10
10
 
11
11
  #include "duckdb/planner/expression.hpp"
12
- #include "duckdb/planner/expression/bound_parameter_data.hpp"
12
+ #include "duckdb/planner/bound_parameter_map.hpp"
13
13
 
14
14
  namespace duckdb {
15
15
 
@@ -21,6 +21,7 @@ class BoundSelectNode;
21
21
  struct BoundGroupInformation {
22
22
  parsed_expression_map_t<idx_t> map;
23
23
  case_insensitive_map_t<idx_t> alias_map;
24
+ unordered_map<idx_t, idx_t> collated_groups;
24
25
  };
25
26
 
26
27
  //! The BaseSelectBinder is the base binder of the SELECT, HAVING and QUALIFY binders. It can bind aggregates and window
@@ -35,7 +35,6 @@ protected:
35
35
  void ResolveTypes() override;
36
36
 
37
37
  private:
38
- LogicalCreateTable(ClientContext &context, const string &catalog, const string &schema,
39
- unique_ptr<CreateInfo> info);
38
+ LogicalCreateTable(ClientContext &context, unique_ptr<CreateInfo> info);
40
39
  };
41
40
  } // namespace duckdb
@@ -37,6 +37,6 @@ protected:
37
37
  void ResolveTypes() override;
38
38
 
39
39
  private:
40
- LogicalDelete(ClientContext &context, const string &catalog, const string &schema, const string &table);
40
+ LogicalDelete(ClientContext &context, const unique_ptr<CreateInfo> &table_info);
41
41
  };
42
42
  } // namespace duckdb
@@ -72,6 +72,6 @@ protected:
72
72
  string GetName() const override;
73
73
 
74
74
  private:
75
- LogicalInsert(ClientContext &context, const string &catalog, const string &schema, const string &table);
75
+ LogicalInsert(ClientContext &context, const unique_ptr<CreateInfo> table_info);
76
76
  };
77
77
  } // namespace duckdb
@@ -42,6 +42,6 @@ protected:
42
42
  void ResolveTypes() override;
43
43
 
44
44
  private:
45
- LogicalUpdate(ClientContext &context, const string &catalog, const string &schema, const string &table);
45
+ LogicalUpdate(ClientContext &context, const unique_ptr<CreateInfo> &table_info);
46
46
  };
47
47
  } // namespace duckdb
@@ -11,7 +11,7 @@
11
11
  #include "duckdb/parser/sql_statement.hpp"
12
12
  #include "duckdb/planner/binder.hpp"
13
13
  #include "duckdb/planner/logical_operator.hpp"
14
- #include "duckdb/planner/expression/bound_parameter_data.hpp"
14
+ #include "duckdb/planner/bound_parameter_map.hpp"
15
15
 
16
16
  namespace duckdb {
17
17
  class ClientContext;
@@ -144,7 +144,7 @@ public:
144
144
  //! Revert a set of appends made by the given AppendState, used to revert appends in the event of an error during
145
145
  //! commit (e.g. because of an I/O exception)
146
146
  void RevertAppend(idx_t start_row, idx_t count);
147
- void RevertAppendInternal(idx_t start_row, idx_t count);
147
+ void RevertAppendInternal(idx_t start_row);
148
148
 
149
149
  void ScanTableSegment(idx_t start_row, idx_t count, const std::function<void(DataChunk &chunk)> &function);
150
150
 
@@ -73,7 +73,7 @@ public:
73
73
  //! FinalizeAppend flushes an append with a variable number of rows.
74
74
  void FinalizeAppend(TransactionData transaction, TableAppendState &state);
75
75
  void CommitAppend(transaction_t commit_id, idx_t row_start, idx_t count);
76
- void RevertAppendInternal(idx_t start_row, idx_t count);
76
+ void RevertAppendInternal(idx_t start_row);
77
77
 
78
78
  void MergeStorage(RowGroupCollection &data);
79
79
 
@@ -124,10 +124,16 @@ duckdb_type duckdb_param_type(duckdb_prepared_statement prepared_statement, idx_
124
124
  }
125
125
  LogicalType param_type;
126
126
  auto identifier = std::to_string(param_idx);
127
- if (!wrapper->statement->data->TryGetType(identifier, param_type)) {
128
- return DUCKDB_TYPE_INVALID;
127
+ if (wrapper->statement->data->TryGetType(identifier, param_type)) {
128
+ return ConvertCPPTypeToC(param_type);
129
+ }
130
+ // The value_map is gone after executing the prepared statement
131
+ // See if this is the case and we still have a value registered for it
132
+ auto it = wrapper->values.find(identifier);
133
+ if (it != wrapper->values.end()) {
134
+ return ConvertCPPTypeToC(it->second.type());
129
135
  }
130
- return ConvertCPPTypeToC(param_type);
136
+ return DUCKDB_TYPE_INVALID;
131
137
  }
132
138
 
133
139
  duckdb_state duckdb_clear_bindings(duckdb_prepared_statement prepared_statement) {
@@ -119,6 +119,7 @@ BindResult ExpressionBinder::BindExpression(ComparisonExpression &expr, idx_t de
119
119
  if (!error.empty()) {
120
120
  return BindResult(error);
121
121
  }
122
+
122
123
  // the children have been successfully resolved
123
124
  auto &left = BoundExpression::GetExpression(*expr.left);
124
125
  auto &right = BoundExpression::GetExpression(*expr.right);
@@ -7,35 +7,25 @@
7
7
  namespace duckdb {
8
8
 
9
9
  BindResult ExpressionBinder::BindExpression(ParameterExpression &expr, idx_t depth) {
10
- auto bound_parameter = make_uniq<BoundParameterExpression>(expr.identifier);
11
- bound_parameter->alias = expr.alias;
12
10
  if (!binder.parameters) {
13
11
  throw BinderException("Unexpected prepared parameter. This type of statement can't be prepared!");
14
12
  }
15
13
  auto parameter_id = expr.identifier;
16
- // check if a parameter value has already been supplied
17
- if (binder.parameters->parameter_data.count(parameter_id)) {
14
+
15
+ D_ASSERT(binder.parameters);
16
+ // Check if a parameter value has already been supplied
17
+ auto &parameter_data = binder.parameters->GetParameterData();
18
+ auto param_data_it = parameter_data.find(parameter_id);
19
+ if (param_data_it != parameter_data.end()) {
18
20
  // it has! emit a constant directly
19
- auto &data = binder.parameters->parameter_data[parameter_id];
21
+ auto &data = param_data_it->second;
20
22
  auto constant = make_uniq<BoundConstantExpression>(data.GetValue());
21
23
  constant->alias = expr.alias;
24
+ constant->return_type = binder.parameters->GetReturnType(parameter_id);
22
25
  return BindResult(std::move(constant));
23
26
  }
24
27
 
25
- auto entry = binder.parameters->parameters.find(parameter_id);
26
- if (entry == binder.parameters->parameters.end()) {
27
- // no entry yet: create a new one
28
- auto data = make_shared<BoundParameterData>();
29
- data->return_type = binder.parameters->GetReturnType(parameter_id);
30
- bound_parameter->return_type = data->return_type;
31
- bound_parameter->parameter_data = data;
32
- binder.parameters->parameters[parameter_id] = std::move(data);
33
- } else {
34
- // a prepared statement with this parameter index was already there: use it
35
- auto &data = entry->second;
36
- bound_parameter->parameter_data = data;
37
- bound_parameter->return_type = binder.parameters->GetReturnType(parameter_id);
38
- }
28
+ auto bound_parameter = binder.parameters->BindParameterExpression(expr);
39
29
  return BindResult(std::move(bound_parameter));
40
30
  }
41
31
 
@@ -1,25 +1,29 @@
1
1
  #include "duckdb/common/limits.hpp"
2
2
  #include "duckdb/common/string_util.hpp"
3
3
  #include "duckdb/execution/expression_executor.hpp"
4
+ #include "duckdb/function/aggregate/distributive_functions.hpp"
5
+ #include "duckdb/function/function_binder.hpp"
4
6
  #include "duckdb/main/config.hpp"
5
7
  #include "duckdb/parser/expression/columnref_expression.hpp"
6
8
  #include "duckdb/parser/expression/comparison_expression.hpp"
9
+ #include "duckdb/parser/expression/conjunction_expression.hpp"
7
10
  #include "duckdb/parser/expression/constant_expression.hpp"
8
- #include "duckdb/parser/expression/subquery_expression.hpp"
9
11
  #include "duckdb/parser/expression/star_expression.hpp"
12
+ #include "duckdb/parser/expression/subquery_expression.hpp"
10
13
  #include "duckdb/parser/query_node/select_node.hpp"
11
14
  #include "duckdb/parser/tableref/joinref.hpp"
12
15
  #include "duckdb/planner/binder.hpp"
16
+ #include "duckdb/planner/expression/bound_aggregate_expression.hpp"
13
17
  #include "duckdb/planner/expression_binder/column_alias_binder.hpp"
14
18
  #include "duckdb/planner/expression_binder/constant_binder.hpp"
15
19
  #include "duckdb/planner/expression_binder/group_binder.hpp"
16
20
  #include "duckdb/planner/expression_binder/having_binder.hpp"
17
- #include "duckdb/planner/expression_binder/qualify_binder.hpp"
18
21
  #include "duckdb/planner/expression_binder/order_binder.hpp"
22
+ #include "duckdb/planner/expression_binder/qualify_binder.hpp"
19
23
  #include "duckdb/planner/expression_binder/select_binder.hpp"
20
24
  #include "duckdb/planner/expression_binder/where_binder.hpp"
25
+ #include "duckdb/planner/expression_iterator.hpp"
21
26
  #include "duckdb/planner/query_node/bound_select_node.hpp"
22
- #include "duckdb/parser/expression/conjunction_expression.hpp"
23
27
 
24
28
  namespace duckdb {
25
29
 
@@ -380,10 +384,28 @@ unique_ptr<BoundQueryNode> Binder::BindSelectNode(SelectNode &statement, unique_
380
384
  auto bound_expr = group_binder.Bind(group_expressions[i], &group_type);
381
385
  D_ASSERT(bound_expr->return_type.id() != LogicalTypeId::INVALID);
382
386
 
387
+ // find out whether the expression contains a subquery, it can't be copied if so
388
+ auto &bound_expr_ref = *bound_expr;
389
+ bool contains_subquery = bound_expr_ref.HasSubquery();
390
+
383
391
  // push a potential collation, if necessary
384
- bound_expr = ExpressionBinder::PushCollation(context, std::move(bound_expr),
385
- StringType::GetCollation(group_type), true);
386
- result->groups.group_expressions.push_back(std::move(bound_expr));
392
+ auto collated_expr = ExpressionBinder::PushCollation(context, std::move(bound_expr),
393
+ StringType::GetCollation(group_type), true);
394
+ if (!contains_subquery && !collated_expr->Equals(bound_expr_ref)) {
395
+ // if there is a collation on a group x, we should group by the collated expr,
396
+ // but also push a first(x) aggregate in case x is selected (uncollated)
397
+ info.collated_groups[i] = result->aggregates.size();
398
+
399
+ auto first_fun = FirstFun::GetFunction(LogicalType::VARCHAR);
400
+ vector<unique_ptr<Expression>> first_children;
401
+ // FIXME: would be better to just refer to this expression, but for now we copy
402
+ first_children.push_back(bound_expr_ref.Copy());
403
+
404
+ FunctionBinder function_binder(context);
405
+ auto function = function_binder.BindAggregateFunction(first_fun, std::move(first_children));
406
+ result->aggregates.push_back(std::move(function));
407
+ }
408
+ result->groups.group_expressions.push_back(std::move(collated_expr));
387
409
 
388
410
  // in the unbound expression we DO bind the table names of any ColumnRefs
389
411
  // we do this to make sure that "table.a" and "a" are treated the same
@@ -39,6 +39,9 @@ BoundStatement Binder::Bind(DropStatement &stmt) {
39
39
  if (!entry) {
40
40
  break;
41
41
  }
42
+ if (entry->internal) {
43
+ throw CatalogException("Cannot drop internal catalog entry \"%s\"!", entry->name);
44
+ }
42
45
  stmt.info->catalog = entry->ParentCatalog().GetName();
43
46
  if (!entry->temporary) {
44
47
  // we can only drop temporary tables in read-only mode
@@ -0,0 +1,67 @@
1
+ #include "duckdb/planner/bound_parameter_map.hpp"
2
+ #include "duckdb/parser/expression/parameter_expression.hpp"
3
+ #include "duckdb/planner/expression/bound_parameter_expression.hpp"
4
+
5
+ namespace duckdb {
6
+
7
+ BoundParameterMap::BoundParameterMap(case_insensitive_map_t<BoundParameterData> &parameter_data)
8
+ : parameter_data(parameter_data) {
9
+ }
10
+
11
+ LogicalType BoundParameterMap::GetReturnType(const string &identifier) {
12
+ D_ASSERT(!identifier.empty());
13
+ auto it = parameter_data.find(identifier);
14
+ if (it == parameter_data.end()) {
15
+ return LogicalTypeId::UNKNOWN;
16
+ }
17
+ return it->second.return_type;
18
+ }
19
+
20
+ bound_parameter_map_t *BoundParameterMap::GetParametersPtr() {
21
+ return &parameters;
22
+ }
23
+
24
+ const bound_parameter_map_t &BoundParameterMap::GetParameters() {
25
+ return parameters;
26
+ }
27
+
28
+ const case_insensitive_map_t<BoundParameterData> &BoundParameterMap::GetParameterData() {
29
+ return parameter_data;
30
+ }
31
+
32
+ shared_ptr<BoundParameterData> BoundParameterMap::CreateOrGetData(const string &identifier) {
33
+ auto entry = parameters.find(identifier);
34
+ if (entry == parameters.end()) {
35
+ // no entry yet: create a new one
36
+ auto data = make_shared<BoundParameterData>();
37
+ data->return_type = GetReturnType(identifier);
38
+
39
+ CreateNewParameter(identifier, data);
40
+ return data;
41
+ }
42
+ return entry->second;
43
+ }
44
+
45
+ unique_ptr<BoundParameterExpression> BoundParameterMap::BindParameterExpression(ParameterExpression &expr) {
46
+ auto &identifier = expr.identifier;
47
+ auto return_type = GetReturnType(identifier);
48
+
49
+ D_ASSERT(!parameter_data.count(identifier));
50
+
51
+ // No value has been supplied yet,
52
+ // We return a shared pointer to an object that will get populated wtih a Value later
53
+ // When the BoundParameterExpression get executed, this will be used to get the corresponding value
54
+ auto param_data = CreateOrGetData(identifier);
55
+ auto bound_expr = make_uniq<BoundParameterExpression>(identifier);
56
+ bound_expr->parameter_data = param_data;
57
+ bound_expr->return_type = return_type;
58
+ bound_expr->alias = expr.alias;
59
+ return bound_expr;
60
+ }
61
+
62
+ void BoundParameterMap::CreateNewParameter(const string &id, const shared_ptr<BoundParameterData> &param_data) {
63
+ D_ASSERT(!parameters.count(id));
64
+ parameters.emplace(std::make_pair(id, param_data));
65
+ }
66
+
67
+ } // namespace duckdb
@@ -1,15 +1,15 @@
1
1
  #include "duckdb/planner/expression_binder/base_select_binder.hpp"
2
2
 
3
+ #include "duckdb/common/string_util.hpp"
3
4
  #include "duckdb/parser/expression/columnref_expression.hpp"
5
+ #include "duckdb/parser/expression/operator_expression.hpp"
4
6
  #include "duckdb/parser/expression/window_expression.hpp"
5
7
  #include "duckdb/parser/parsed_expression_iterator.hpp"
8
+ #include "duckdb/planner/binder.hpp"
6
9
  #include "duckdb/planner/expression/bound_columnref_expression.hpp"
7
10
  #include "duckdb/planner/expression/bound_window_expression.hpp"
8
11
  #include "duckdb/planner/expression_binder/aggregate_binder.hpp"
9
12
  #include "duckdb/planner/query_node/bound_select_node.hpp"
10
- #include "duckdb/parser/expression/operator_expression.hpp"
11
- #include "duckdb/common/string_util.hpp"
12
- #include "duckdb/planner/binder.hpp"
13
13
 
14
14
  namespace duckdb {
15
15
 
@@ -138,9 +138,17 @@ BindResult BaseSelectBinder::BindGroupingFunction(OperatorExpression &op, idx_t
138
138
  }
139
139
 
140
140
  BindResult BaseSelectBinder::BindGroup(ParsedExpression &expr, idx_t depth, idx_t group_index) {
141
- auto &group = node.groups.group_expressions[group_index];
142
- return BindResult(make_uniq<BoundColumnRefExpression>(expr.GetName(), group->return_type,
143
- ColumnBinding(node.group_index, group_index), depth));
141
+ auto it = info.collated_groups.find(group_index);
142
+ if (it != info.collated_groups.end()) {
143
+ // This is an implicitly collated group, so we need to refer to the first() aggregate
144
+ const auto &aggr_index = it->second;
145
+ return BindResult(make_uniq<BoundColumnRefExpression>(expr.GetName(), node.aggregates[aggr_index]->return_type,
146
+ ColumnBinding(node.aggregate_index, aggr_index), depth));
147
+ } else {
148
+ auto &group = node.groups.group_expressions[group_index];
149
+ return BindResult(make_uniq<BoundColumnRefExpression>(expr.GetName(), group->return_type,
150
+ ColumnBinding(node.group_index, group_index), depth));
151
+ }
144
152
  }
145
153
 
146
154
  bool BaseSelectBinder::QualifyColumnAlias(const ColumnRefExpression &colref) {
@@ -6,9 +6,9 @@ LogicalCreateTable::LogicalCreateTable(SchemaCatalogEntry &schema, unique_ptr<Bo
6
6
  : LogicalOperator(LogicalOperatorType::LOGICAL_CREATE_TABLE), schema(schema), info(std::move(info)) {
7
7
  }
8
8
 
9
- LogicalCreateTable::LogicalCreateTable(ClientContext &context, const string &catalog, const string &schema,
10
- unique_ptr<CreateInfo> unbound_info)
11
- : LogicalOperator(LogicalOperatorType::LOGICAL_CREATE_TABLE), schema(Catalog::GetSchema(context, catalog, schema)) {
9
+ LogicalCreateTable::LogicalCreateTable(ClientContext &context, unique_ptr<CreateInfo> unbound_info)
10
+ : LogicalOperator(LogicalOperatorType::LOGICAL_CREATE_TABLE),
11
+ schema(Catalog::GetSchema(context, unbound_info->catalog, unbound_info->schema)) {
12
12
  D_ASSERT(unbound_info->type == CatalogType::TABLE_ENTRY);
13
13
  auto binder = Binder::CreateBinder(context);
14
14
  info = binder->BindCreateTableInfo(unique_ptr_cast<CreateInfo, CreateTableInfo>(std::move(unbound_info)));