1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/parser/column_list.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/parser/column_definition.hpp"
12#include "duckdb/common/field_writer.hpp"
13
14namespace duckdb {
15
16//! A set of column definitions
17class ColumnList {
18public:
19 class ColumnListIterator;
20
21public:
22 DUCKDB_API ColumnList(bool allow_duplicate_names = false);
23
24 DUCKDB_API void AddColumn(ColumnDefinition column);
25 void Finalize();
26
27 DUCKDB_API const ColumnDefinition &GetColumn(LogicalIndex index) const;
28 DUCKDB_API const ColumnDefinition &GetColumn(PhysicalIndex index) const;
29 DUCKDB_API const ColumnDefinition &GetColumn(const string &name) const;
30 DUCKDB_API ColumnDefinition &GetColumnMutable(LogicalIndex index);
31 DUCKDB_API ColumnDefinition &GetColumnMutable(PhysicalIndex index);
32 DUCKDB_API ColumnDefinition &GetColumnMutable(const string &name);
33 DUCKDB_API vector<string> GetColumnNames() const;
34 DUCKDB_API vector<LogicalType> GetColumnTypes() const;
35
36 DUCKDB_API bool ColumnExists(const string &name) const;
37
38 DUCKDB_API LogicalIndex GetColumnIndex(string &column_name) const;
39 DUCKDB_API PhysicalIndex LogicalToPhysical(LogicalIndex index) const;
40 DUCKDB_API LogicalIndex PhysicalToLogical(PhysicalIndex index) const;
41
42 idx_t LogicalColumnCount() const {
43 return columns.size();
44 }
45 idx_t PhysicalColumnCount() const {
46 return physical_columns.size();
47 }
48 bool empty() const {
49 return columns.empty();
50 }
51
52 ColumnList Copy() const;
53 void Serialize(FieldWriter &writer) const;
54 static ColumnList Deserialize(FieldReader &reader);
55
56 DUCKDB_API ColumnListIterator Logical() const;
57 DUCKDB_API ColumnListIterator Physical() const;
58
59 void SetAllowDuplicates(bool allow_duplicates) {
60 allow_duplicate_names = allow_duplicates;
61 }
62
63private:
64 vector<ColumnDefinition> columns;
65 //! A map of column name to column index
66 case_insensitive_map_t<column_t> name_map;
67 //! The set of physical columns
68 vector<idx_t> physical_columns;
69 //! Allow duplicate names or not
70 bool allow_duplicate_names;
71
72private:
73 void AddToNameMap(ColumnDefinition &column);
74
75public:
76 // logical iterator
77 class ColumnListIterator {
78 public:
79 ColumnListIterator(const ColumnList &list, bool physical) : list(list), physical(physical) {
80 }
81
82 private:
83 const ColumnList &list;
84 bool physical;
85
86 private:
87 class ColumnLogicalIteratorInternal {
88 public:
89 ColumnLogicalIteratorInternal(const ColumnList &list, bool physical, idx_t pos, idx_t end)
90 : list(list), physical(physical), pos(pos), end(end) {
91 }
92
93 const ColumnList &list;
94 bool physical;
95 idx_t pos;
96 idx_t end;
97
98 public:
99 ColumnLogicalIteratorInternal &operator++() {
100 pos++;
101 return *this;
102 }
103 bool operator!=(const ColumnLogicalIteratorInternal &other) const {
104 return pos != other.pos || end != other.end || &list != &other.list;
105 }
106 const ColumnDefinition &operator*() const {
107 if (physical) {
108 return list.GetColumn(index: PhysicalIndex(pos));
109 } else {
110 return list.GetColumn(index: LogicalIndex(pos));
111 }
112 }
113 };
114
115 public:
116 idx_t Size() {
117 return physical ? list.PhysicalColumnCount() : list.LogicalColumnCount();
118 }
119
120 ColumnLogicalIteratorInternal begin() {
121 return ColumnLogicalIteratorInternal(list, physical, 0, Size());
122 }
123 ColumnLogicalIteratorInternal end() {
124 return ColumnLogicalIteratorInternal(list, physical, Size(), Size());
125 }
126 };
127};
128
129} // namespace duckdb
130