duckdb 0.7.2-dev16.0 → 0.7.2-dev225.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 (129) hide show
  1. package/binding.gyp +2 -0
  2. package/package.json +1 -1
  3. package/src/duckdb/extension/icu/icu-extension.cpp +2 -0
  4. package/src/duckdb/extension/icu/icu-table-range.cpp +194 -0
  5. package/src/duckdb/extension/icu/include/icu-table-range.hpp +17 -0
  6. package/src/duckdb/extension/parquet/column_writer.cpp +0 -1
  7. package/src/duckdb/extension/parquet/parquet-extension.cpp +11 -2
  8. package/src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp +4 -0
  9. package/src/duckdb/src/catalog/catalog_entry/scalar_function_catalog_entry.cpp +7 -6
  10. package/src/duckdb/src/catalog/catalog_entry/table_function_catalog_entry.cpp +20 -1
  11. package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
  12. package/src/duckdb/src/common/types/bit.cpp +95 -58
  13. package/src/duckdb/src/common/types/value.cpp +149 -53
  14. package/src/duckdb/src/common/types/vector.cpp +13 -10
  15. package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +1 -1
  16. package/src/duckdb/src/function/aggregate/algebraic/avg.cpp +0 -6
  17. package/src/duckdb/src/function/aggregate/distributive/bitagg.cpp +99 -95
  18. package/src/duckdb/src/function/aggregate/distributive/bitstring_agg.cpp +261 -0
  19. package/src/duckdb/src/function/aggregate/distributive/sum.cpp +0 -3
  20. package/src/duckdb/src/function/aggregate/distributive_functions.cpp +1 -0
  21. package/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp +16 -5
  22. package/src/duckdb/src/function/cast/bit_cast.cpp +0 -2
  23. package/src/duckdb/src/function/cast/blob_cast.cpp +0 -1
  24. package/src/duckdb/src/function/scalar/bit/bitstring.cpp +99 -0
  25. package/src/duckdb/src/function/scalar/map/map_entries.cpp +61 -0
  26. package/src/duckdb/src/function/scalar/map/map_keys_values.cpp +97 -0
  27. package/src/duckdb/src/function/scalar/nested_functions.cpp +3 -0
  28. package/src/duckdb/src/function/scalar/operators/add.cpp +0 -9
  29. package/src/duckdb/src/function/scalar/operators/arithmetic.cpp +2 -14
  30. package/src/duckdb/src/function/scalar/operators/bitwise.cpp +0 -63
  31. package/src/duckdb/src/function/scalar/operators/multiply.cpp +0 -6
  32. package/src/duckdb/src/function/scalar/operators/subtract.cpp +0 -6
  33. package/src/duckdb/src/function/scalar/string_functions.cpp +1 -0
  34. package/src/duckdb/src/function/table/read_csv.cpp +9 -0
  35. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  36. package/src/duckdb/src/function/table_function.cpp +19 -0
  37. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp +6 -8
  38. package/src/duckdb/src/include/duckdb/common/constants.hpp +0 -19
  39. package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +2 -1
  40. package/src/duckdb/src/include/duckdb/common/enums/tableref_type.hpp +2 -1
  41. package/src/duckdb/src/include/duckdb/common/types/bit.hpp +5 -1
  42. package/src/duckdb/src/include/duckdb/common/types/value.hpp +2 -8
  43. package/src/duckdb/src/include/duckdb/common/types.hpp +1 -2
  44. package/src/duckdb/src/include/duckdb/function/aggregate/distributive_functions.hpp +5 -0
  45. package/src/duckdb/src/include/duckdb/function/scalar/bit_functions.hpp +4 -0
  46. package/src/duckdb/src/include/duckdb/function/scalar/nested_functions.hpp +12 -0
  47. package/src/duckdb/src/include/duckdb/function/table_function.hpp +2 -0
  48. package/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp +2 -0
  49. package/src/duckdb/src/include/duckdb/main/config.hpp +3 -0
  50. package/src/duckdb/src/include/duckdb/main/database.hpp +1 -0
  51. package/src/duckdb/src/include/duckdb/optimizer/join_order/cardinality_estimator.hpp +2 -2
  52. package/src/duckdb/src/include/duckdb/parser/common_table_expression_info.hpp +2 -0
  53. package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_info.hpp +2 -1
  54. package/src/duckdb/src/include/duckdb/parser/parsed_data/{alter_function_info.hpp → alter_scalar_function_info.hpp} +13 -13
  55. package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_table_function_info.hpp +47 -0
  56. package/src/duckdb/src/include/duckdb/parser/parsed_data/create_table_function_info.hpp +2 -1
  57. package/src/duckdb/src/include/duckdb/parser/query_node.hpp +2 -1
  58. package/src/duckdb/src/include/duckdb/parser/statement/multi_statement.hpp +28 -0
  59. package/src/duckdb/src/include/duckdb/parser/tableref/list.hpp +1 -0
  60. package/src/duckdb/src/include/duckdb/parser/tableref/pivotref.hpp +76 -0
  61. package/src/duckdb/src/include/duckdb/parser/tokens.hpp +2 -0
  62. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +28 -0
  63. package/src/duckdb/src/include/duckdb/planner/binder.hpp +8 -0
  64. package/src/duckdb/src/include/duckdb/storage/buffer/block_handle.hpp +2 -0
  65. package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +76 -44
  66. package/src/duckdb/src/include/duckdb/storage/statistics/base_statistics.hpp +2 -0
  67. package/src/duckdb/src/include/duckdb/storage/statistics/node_statistics.hpp +26 -0
  68. package/src/duckdb/src/include/duckdb/storage/table/list_column_data.hpp +1 -1
  69. package/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp +2 -0
  70. package/src/duckdb/src/include/duckdb.h +49 -1
  71. package/src/duckdb/src/include/duckdb.hpp +0 -1
  72. package/src/duckdb/src/main/capi/pending-c.cpp +16 -3
  73. package/src/duckdb/src/main/capi/result-c.cpp +27 -1
  74. package/src/duckdb/src/main/capi/stream-c.cpp +25 -0
  75. package/src/duckdb/src/main/client_context.cpp +8 -1
  76. package/src/duckdb/src/main/database.cpp +10 -2
  77. package/src/duckdb/src/optimizer/join_order/cardinality_estimator.cpp +98 -66
  78. package/src/duckdb/src/optimizer/join_order/join_order_optimizer.cpp +16 -3
  79. package/src/duckdb/src/parser/parsed_data/alter_info.cpp +7 -3
  80. package/src/duckdb/src/parser/parsed_data/alter_scalar_function_info.cpp +56 -0
  81. package/src/duckdb/src/parser/parsed_data/alter_table_function_info.cpp +51 -0
  82. package/src/duckdb/src/parser/parsed_data/create_scalar_function_info.cpp +3 -2
  83. package/src/duckdb/src/parser/parsed_data/create_table_function_info.cpp +6 -0
  84. package/src/duckdb/src/parser/parsed_expression_iterator.cpp +8 -0
  85. package/src/duckdb/src/parser/query_node.cpp +1 -1
  86. package/src/duckdb/src/parser/statement/multi_statement.cpp +18 -0
  87. package/src/duckdb/src/parser/tableref/pivotref.cpp +296 -0
  88. package/src/duckdb/src/parser/tableref.cpp +3 -0
  89. package/src/duckdb/src/parser/transform/helpers/transform_alias.cpp +12 -6
  90. package/src/duckdb/src/parser/transform/helpers/transform_cte.cpp +24 -0
  91. package/src/duckdb/src/parser/transform/statement/transform_create_function.cpp +4 -0
  92. package/src/duckdb/src/parser/transform/statement/transform_create_view.cpp +4 -0
  93. package/src/duckdb/src/parser/transform/statement/transform_pivot_stmt.cpp +150 -0
  94. package/src/duckdb/src/parser/transform/statement/transform_select.cpp +8 -0
  95. package/src/duckdb/src/parser/transform/statement/transform_select_node.cpp +1 -1
  96. package/src/duckdb/src/parser/transform/tableref/transform_pivot.cpp +105 -0
  97. package/src/duckdb/src/parser/transform/tableref/transform_tableref.cpp +2 -0
  98. package/src/duckdb/src/parser/transformer.cpp +15 -3
  99. package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +11 -3
  100. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +1 -1
  101. package/src/duckdb/src/planner/binder/statement/bind_logical_plan.cpp +17 -0
  102. package/src/duckdb/src/planner/binder/tableref/bind_pivot.cpp +365 -0
  103. package/src/duckdb/src/planner/binder.cpp +5 -0
  104. package/src/duckdb/src/planner/pragma_handler.cpp +10 -2
  105. package/src/duckdb/src/storage/buffer_manager.cpp +44 -46
  106. package/src/duckdb/src/storage/compression/bitpacking.cpp +25 -21
  107. package/src/duckdb/src/storage/compression/fixed_size_uncompressed.cpp +41 -43
  108. package/src/duckdb/src/storage/compression/rle.cpp +17 -13
  109. package/src/duckdb/src/storage/statistics/base_statistics.cpp +3 -3
  110. package/src/duckdb/src/storage/storage_info.cpp +1 -1
  111. package/src/duckdb/src/storage/table/column_data.cpp +5 -2
  112. package/src/duckdb/src/storage/table/list_column_data.cpp +32 -47
  113. package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +3 -0
  114. package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +34 -1
  115. package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +1016 -530
  116. package/src/duckdb/third_party/libpg_query/include/parser/kwlist.hpp +5 -0
  117. package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +22697 -21987
  118. package/src/duckdb/ub_src_function_aggregate_distributive.cpp +2 -0
  119. package/src/duckdb/ub_src_function_scalar_bit.cpp +2 -0
  120. package/src/duckdb/ub_src_function_scalar_map.cpp +4 -0
  121. package/src/duckdb/ub_src_main_capi.cpp +2 -0
  122. package/src/duckdb/ub_src_parser_parsed_data.cpp +4 -2
  123. package/src/duckdb/ub_src_parser_statement.cpp +2 -0
  124. package/src/duckdb/ub_src_parser_tableref.cpp +2 -0
  125. package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
  126. package/src/duckdb/ub_src_parser_transform_tableref.cpp +2 -0
  127. package/src/duckdb/ub_src_planner_binder_tableref.cpp +2 -0
  128. package/src/duckdb/src/include/duckdb/main/loadable_extension.hpp +0 -59
  129. package/src/duckdb/src/parser/parsed_data/alter_function_info.cpp +0 -55
@@ -2,7 +2,7 @@
2
2
 
3
3
  namespace duckdb {
4
4
 
5
- const uint64_t VERSION_NUMBER = 43;
5
+ const uint64_t VERSION_NUMBER = 44;
6
6
 
7
7
  struct StorageVersionInfo {
8
8
  const char *version_name;
@@ -466,8 +466,11 @@ void ColumnData::GetStorageInfo(idx_t row_group_index, vector<idx_t> col_path, T
466
466
  column_info.segment_start = segment->start;
467
467
  column_info.segment_count = segment->count;
468
468
  column_info.compression_type = CompressionTypeToString(segment->function->type);
469
- column_info.segment_stats =
470
- segment->stats.statistics ? segment->stats.statistics->ToString() : string("No Stats");
469
+ if (!segment->stats.statistics || type.id() == LogicalTypeId::LIST) {
470
+ column_info.segment_stats = string("No Stats");
471
+ } else {
472
+ column_info.segment_stats = segment->stats.statistics->ToString();
473
+ }
471
474
  column_info.has_updates = updates ? true : false;
472
475
  // persistent
473
476
  // block_id
@@ -39,15 +39,14 @@ void ListColumnData::InitializeScan(ColumnScanState &state) {
39
39
  state.child_states.push_back(std::move(child_state));
40
40
  }
41
41
 
42
- list_entry_t ListColumnData::FetchListEntry(idx_t row_idx) {
42
+ uint64_t ListColumnData::FetchListOffset(idx_t row_idx) {
43
43
  auto segment = (ColumnSegment *)data.GetSegment(row_idx);
44
44
  ColumnFetchState fetch_state;
45
45
  Vector result(type, 1);
46
46
  segment->FetchRow(fetch_state, row_idx, result, 0);
47
47
 
48
48
  // initialize the child scan with the required offset
49
- auto list_data = FlatVector::GetData<list_entry_t>(result);
50
- return list_data[0];
49
+ return FlatVector::GetData<uint64_t>(result)[0];
51
50
  }
52
51
 
53
52
  void ListColumnData::InitializeScanWithOffset(ColumnScanState &state, idx_t row_idx) {
@@ -63,8 +62,7 @@ void ListColumnData::InitializeScanWithOffset(ColumnScanState &state, idx_t row_
63
62
  state.child_states.push_back(std::move(validity_state));
64
63
 
65
64
  // we need to read the list at position row_idx to get the correct row offset of the child
66
- auto list_entry = FetchListEntry(row_idx);
67
- auto child_offset = list_entry.offset;
65
+ auto child_offset = row_idx == start ? 0 : FetchListOffset(row_idx - 1);
68
66
 
69
67
  D_ASSERT(child_offset <= child_column->GetMaxEntry());
70
68
  ColumnScanState child_state;
@@ -89,26 +87,26 @@ idx_t ListColumnData::ScanCount(ColumnScanState &state, Vector &result, idx_t co
89
87
  // updates not supported for lists
90
88
  D_ASSERT(!updates);
91
89
 
92
- idx_t scan_count = ScanVector(state, result, count);
90
+ Vector offset_vector(LogicalType::UBIGINT, count);
91
+ idx_t scan_count = ScanVector(state, offset_vector, count);
93
92
  D_ASSERT(scan_count > 0);
94
93
  validity.ScanCount(state.child_states[0], result, count);
95
94
 
96
- auto data = FlatVector::GetData<list_entry_t>(result);
97
- auto first_entry = data[0];
95
+ auto data = FlatVector::GetData<uint64_t>(offset_vector);
98
96
  auto last_entry = data[scan_count - 1];
99
97
 
100
- #ifdef DEBUG
101
- for (idx_t i = 1; i < scan_count; i++) {
102
- D_ASSERT(data[i].offset == data[i - 1].offset + data[i - 1].length);
103
- }
104
- #endif
105
98
  // shift all offsets so they are 0 at the first entry
99
+ auto result_data = FlatVector::GetData<list_entry_t>(result);
100
+ auto base_offset = state.last_offset;
101
+ idx_t current_offset = 0;
106
102
  for (idx_t i = 0; i < scan_count; i++) {
107
- data[i].offset -= first_entry.offset;
103
+ result_data[i].offset = current_offset;
104
+ result_data[i].length = data[i] - current_offset - base_offset;
105
+ current_offset += result_data[i].length;
108
106
  }
109
107
 
110
- D_ASSERT(last_entry.offset >= first_entry.offset);
111
- idx_t child_scan_count = last_entry.offset + last_entry.length - first_entry.offset;
108
+ D_ASSERT(last_entry >= base_offset);
109
+ idx_t child_scan_count = last_entry - base_offset;
112
110
  ListVector::Reserve(result, child_scan_count);
113
111
 
114
112
  if (child_scan_count > 0) {
@@ -118,6 +116,7 @@ idx_t ListColumnData::ScanCount(ColumnScanState &state, Vector &result, idx_t co
118
116
  child_column->start + child_column->GetMaxEntry());
119
117
  child_column->ScanCount(state.child_states[1], child_entry, child_scan_count);
120
118
  }
119
+ state.last_offset = last_entry;
121
120
 
122
121
  ListVector::SetListSize(result, child_scan_count);
123
122
  return scan_count;
@@ -130,19 +129,19 @@ void ListColumnData::Skip(ColumnScanState &state, idx_t count) {
130
129
  // we need to read the list entries/offsets to figure out how much to skip
131
130
  // note that we only need to read the first and last entry
132
131
  // however, let's just read all "count" entries for now
133
- auto data = unique_ptr<list_entry_t[]>(new list_entry_t[count]);
134
- Vector result(type, (data_ptr_t)data.get());
132
+ Vector result(LogicalType::UBIGINT, count);
135
133
  idx_t scan_count = ScanVector(state, result, count);
136
134
  if (scan_count == 0) {
137
135
  return;
138
136
  }
139
137
 
140
- auto &first_entry = data[0];
141
- auto &last_entry = data[scan_count - 1];
142
- idx_t child_scan_count = last_entry.offset + last_entry.length - first_entry.offset;
138
+ auto data = FlatVector::GetData<uint64_t>(result);
139
+ auto last_entry = data[scan_count - 1];
140
+ idx_t child_scan_count = last_entry - state.last_offset;
143
141
  if (child_scan_count == 0) {
144
142
  return;
145
143
  }
144
+ state.last_offset = last_entry;
146
145
 
147
146
  // skip the child state forward by the child_scan_count
148
147
  child_column->Skip(state.child_states[1], child_scan_count);
@@ -177,8 +176,8 @@ void ListColumnData::Append(BaseStatistics &stats_p, ColumnAppendState &state, V
177
176
  idx_t child_count = 0;
178
177
 
179
178
  ValidityMask append_mask(count);
180
- auto append_offsets = unique_ptr<list_entry_t[]>(new list_entry_t[count]);
181
- bool child_contiguous = false;
179
+ auto append_offsets = unique_ptr<uint64_t[]>(new uint64_t[count]);
180
+ bool child_contiguous = true;
182
181
  for (idx_t i = 0; i < count; i++) {
183
182
  auto input_idx = list_data.sel->get_index(i);
184
183
  if (list_validity.RowIsValid(input_idx)) {
@@ -186,17 +185,11 @@ void ListColumnData::Append(BaseStatistics &stats_p, ColumnAppendState &state, V
186
185
  if (input_list.offset != child_count) {
187
186
  child_contiguous = false;
188
187
  }
189
- append_offsets[i].offset = start_offset + child_count;
190
- append_offsets[i].length = input_list.length;
188
+ append_offsets[i] = start_offset + child_count + input_list.length;
191
189
  child_count += input_list.length;
192
190
  } else {
193
191
  append_mask.SetInvalid(i);
194
- if (i > 0) {
195
- append_offsets[i].offset = append_offsets[i - 1].offset + append_offsets[i - 1].length;
196
- } else {
197
- append_offsets[i].offset = start_offset;
198
- }
199
- append_offsets[i].length = 0;
192
+ append_offsets[i] = start_offset + child_count;
200
193
  }
201
194
  }
202
195
  auto &list_child = ListVector::GetEntry(vector);
@@ -218,23 +211,15 @@ void ListColumnData::Append(BaseStatistics &stats_p, ColumnAppendState &state, V
218
211
  D_ASSERT(current_count == child_count);
219
212
  child_vector.Slice(list_child, child_sel, child_count);
220
213
  }
221
- #ifdef DEBUG
222
- D_ASSERT(append_offsets[0].offset == start_offset);
223
- for (idx_t i = 1; i < count; i++) {
224
- D_ASSERT(append_offsets[i].offset == append_offsets[i - 1].offset + append_offsets[i - 1].length);
225
- }
226
- D_ASSERT(append_offsets[count - 1].offset + append_offsets[count - 1].length - append_offsets[0].offset ==
227
- child_count);
228
- #endif
229
214
 
230
215
  UnifiedVectorFormat vdata;
231
- vdata.validity = append_mask;
232
216
  vdata.sel = FlatVector::IncrementalSelectionVector();
233
217
  vdata.data = (data_ptr_t)append_offsets.get();
234
218
 
235
219
  // append the list offsets
236
220
  ColumnData::AppendData(stats, state, vdata, count);
237
221
  // append the validity data
222
+ vdata.validity = append_mask;
238
223
  validity.AppendData(*stats.validity_stats, state.child_appends[0], vdata, count);
239
224
  // append the child vector
240
225
  if (child_count > 0) {
@@ -248,8 +233,8 @@ void ListColumnData::RevertAppend(row_t start_row) {
248
233
  auto column_count = GetMaxEntry();
249
234
  if (column_count > start) {
250
235
  // revert append in the child column
251
- auto list_entry = FetchListEntry(column_count - 1);
252
- child_column->RevertAppend(list_entry.offset + list_entry.length);
236
+ auto list_offset = FetchListOffset(column_count - 1);
237
+ child_column->RevertAppend(list_offset);
253
238
  }
254
239
  }
255
240
 
@@ -281,19 +266,18 @@ void ListColumnData::FetchRow(TransactionData transaction, ColumnFetchState &sta
281
266
  auto child_state = make_unique<ColumnFetchState>();
282
267
  state.child_states.push_back(std::move(child_state));
283
268
  }
284
- // fetch the list_entry_t and the validity mask for that list
285
- auto segment = (ColumnSegment *)data.GetSegment(row_id);
286
269
 
287
270
  // now perform the fetch within the segment
288
- segment->FetchRow(state, row_id, result, result_idx);
271
+ auto start_offset = idx_t(row_id) == this->start ? 0 : FetchListOffset(row_id - 1);
272
+ auto end_offset = FetchListOffset(row_id);
289
273
  validity.FetchRow(transaction, *state.child_states[0], row_id, result, result_idx);
290
274
 
291
275
  auto &validity = FlatVector::Validity(result);
292
276
  auto list_data = FlatVector::GetData<list_entry_t>(result);
293
277
  auto &list_entry = list_data[result_idx];
294
- auto original_offset = list_entry.offset;
295
278
  // set the list entry offset to the size of the current list
296
279
  list_entry.offset = ListVector::GetListSize(result);
280
+ list_entry.length = end_offset - start_offset;
297
281
  if (!validity.RowIsValid(result_idx)) {
298
282
  // the list is NULL! no need to fetch the child
299
283
  D_ASSERT(list_entry.length == 0);
@@ -307,7 +291,7 @@ void ListColumnData::FetchRow(TransactionData transaction, ColumnFetchState &sta
307
291
  auto &child_type = ListType::GetChildType(result.GetType());
308
292
  Vector child_scan(child_type, child_scan_count);
309
293
  // seek the scan towards the specified position and read [length] entries
310
- child_column->InitializeScanWithOffset(*child_state, start + original_offset);
294
+ child_column->InitializeScanWithOffset(*child_state, start + start_offset);
311
295
  D_ASSERT(child_type.InternalType() == PhysicalType::STRUCT ||
312
296
  child_state->row_index + child_scan_count - this->start <= child_column->GetMaxEntry());
313
297
  child_column->ScanCount(*child_state, child_scan, child_scan_count);
@@ -376,6 +360,7 @@ void ListColumnData::DeserializeColumn(Deserializer &source) {
376
360
  }
377
361
 
378
362
  void ListColumnData::GetStorageInfo(idx_t row_group_index, vector<idx_t> col_path, TableStorageInfo &result) {
363
+ ColumnData::GetStorageInfo(row_group_index, col_path, result);
379
364
  col_path.push_back(0);
380
365
  validity.GetStorageInfo(row_group_index, col_path, result);
381
366
  col_path.back() = 1;
@@ -194,6 +194,9 @@ typedef enum PGNodeTag {
194
194
  T_PGOnConflictExpr,
195
195
  T_PGIntoClause,
196
196
  T_PGLambdaFunction,
197
+ T_PGPivotExpr,
198
+ T_PGPivot,
199
+ T_PGPivotStmt,
197
200
 
198
201
  /*
199
202
  * TAGS FOR EXPRESSION STATE NODES (execnodes.h)
@@ -1162,6 +1162,37 @@ typedef struct PGUpdateStmt {
1162
1162
  PGWithClause *withClause; /* WITH clause */
1163
1163
  } PGUpdateStmt;
1164
1164
 
1165
+ /* ----------------------
1166
+ * Pivot Expression
1167
+ * ----------------------
1168
+ */
1169
+ typedef struct PGPivot {
1170
+ PGNodeTag type;
1171
+ PGList *pivot_columns; /* The column names to pivot on */
1172
+ PGList *pivot_value; /* The set of pivot values */
1173
+ char *pivot_enum; /* The enum to fetch the unique values from */
1174
+ } PGPivot;
1175
+
1176
+ typedef struct PGPivotExpr {
1177
+ PGNodeTag type;
1178
+ PGNode *source; /* the source subtree */
1179
+ PGList *aggrs; /* The aggregations to pivot over (PIVOT only) */
1180
+ PGList *unpivots; /* The names to unpivot over (UNPIVOT only) */
1181
+ PGList *pivots; /* The set of pivot values */
1182
+ PGList *groups; /* The set of groups to pivot over (if any) */
1183
+ PGAlias *alias; /* table alias & optional column aliases */
1184
+ bool include_nulls; /* Whether or not to include NULL values (UNPIVOT only */
1185
+ } PGPivotExpr;
1186
+
1187
+ typedef struct PGPivotStmt {
1188
+ PGNodeTag type;
1189
+ PGNode *source; /* The source to pivot */
1190
+ PGList *aggrs; /* The aggregations to pivot over (PIVOT only) */
1191
+ PGList *unpivots; /* The names to unpivot over (UNPIVOT only) */
1192
+ PGList *columns; /* The set of columns to pivot over */
1193
+ PGList *groups; /* The set of groups to pivot over (if any) */
1194
+ } PGPivotStmt;
1195
+
1165
1196
  /* ----------------------
1166
1197
  * Select Statement
1167
1198
  *
@@ -1204,6 +1235,9 @@ typedef struct PGSelectStmt {
1204
1235
  */
1205
1236
  PGList *valuesLists; /* untransformed list of expression lists */
1206
1237
 
1238
+ /* When representing a pivot statement, all values are NULL besides the pivot field */
1239
+ PGPivotStmt *pivot; /* PIVOT statement */
1240
+
1207
1241
  /*
1208
1242
  * These fields are used in both "leaf" SelectStmts and upper-level
1209
1243
  * SelectStmts.
@@ -2107,5 +2141,4 @@ typedef struct PGUseStmt {
2107
2141
  } PGUseStmt;
2108
2142
 
2109
2143
 
2110
-
2111
2144
  }