1
+ // ===----------------------------------------------------------------------===//
2
+ //
3
+ // Peloton
4
+ //
5
+ // layout_catalog.cpp
6
+ //
7
+ // Identification: src/catalog/layout_catalog.cpp
8
+ //
9
+ // Copyright (c) 2015-2018, Carnegie Mellon University Database Group
10
+ //
11
+ // ===----------------------------------------------------------------------===//
12
+
13
+ #include " catalog/layout_catalog.h"
14
+
15
+ #include " catalog/catalog.h"
16
+ #include " catalog/system_catalogs.h"
17
+ #include " concurrency/transaction_context.h"
18
+ #include " executor/logical_tile.h"
19
+ #include " storage/data_table.h"
20
+ #include " storage/layout.h"
21
+
22
+ namespace peloton {
23
+ namespace catalog {
24
+
25
+ /* * @brief Constructor invoked by the SystemsCatalog constructor.
26
+ * @param pg_catalog The database to which this pg_layout belongs.
27
+ */
28
+ LayoutCatalog::LayoutCatalog (
29
+ storage::Database *pg_catalog, UNUSED_ATTRIBUTE type::AbstractPool *pool,
30
+ UNUSED_ATTRIBUTE concurrency::TransactionContext *txn)
31
+ : AbstractCatalog(LAYOUT_CATALOG_OID, LAYOUT_CATALOG_NAME,
32
+ InitializeSchema ().release(), pg_catalog) {
33
+ // Add indexes for pg_attribute
34
+ AddIndex ({ColumnId::TABLE_OID, ColumnId::LAYOUT_OID}, LAYOUT_CATALOG_PKEY_OID,
35
+ LAYOUT_CATALOG_NAME " _pkey" , IndexConstraintType::PRIMARY_KEY);
36
+ AddIndex ({ColumnId::TABLE_OID}, LAYOUT_CATALOG_SKEY0_OID,
37
+ LAYOUT_CATALOG_NAME " _skey0" , IndexConstraintType::DEFAULT);
38
+ }
39
+ /* * @brief Destructor. Do nothing. Layouts will be dropped by DropTable. */
40
+ LayoutCatalog::~LayoutCatalog () {}
41
+
42
+ /* * @brief Initilailizes the schema for the pg_layout table.
43
+ * @return unique_ptr of the schema for pg_layout.
44
+ */
45
+ std::unique_ptr<catalog::Schema> LayoutCatalog::InitializeSchema () {
46
+ const std::string primary_key_constraint_name = " primary_key" ;
47
+ const std::string not_null_constraint_name = " not_null" ;
48
+
49
+ auto table_id_column = catalog::Column (
50
+ type::TypeId::INTEGER, type::Type::GetTypeSize (type::TypeId::INTEGER),
51
+ " table_oid" , true );
52
+ table_id_column.AddConstraint (catalog::Constraint (
53
+ ConstraintType::PRIMARY, primary_key_constraint_name));
54
+ table_id_column.AddConstraint (
55
+ catalog::Constraint (ConstraintType::NOTNULL, not_null_constraint_name));
56
+
57
+ auto layout_oid_column = catalog::Column (
58
+ type::TypeId::INTEGER, type::Type::GetTypeSize (type::TypeId::INTEGER),
59
+ " layout_oid" , true );
60
+ layout_oid_column.AddConstraint (catalog::Constraint (
61
+ ConstraintType::PRIMARY, primary_key_constraint_name));
62
+ layout_oid_column.AddConstraint (
63
+ catalog::Constraint (ConstraintType::NOTNULL, not_null_constraint_name));
64
+
65
+ auto num_columns_column = catalog::Column (
66
+ type::TypeId::INTEGER, type::Type::GetTypeSize (type::TypeId::INTEGER),
67
+ " num_columns" , true );
68
+ num_columns_column.AddConstraint (
69
+ catalog::Constraint (ConstraintType::NOTNULL, not_null_constraint_name));
70
+
71
+ auto column_map_column = catalog::Column (
72
+ type::TypeId::VARCHAR, type::Type::GetTypeSize (type::TypeId::VARCHAR),
73
+ " column_map" , false );
74
+ column_map_column.AddConstraint (
75
+ catalog::Constraint (ConstraintType::NOTNULL, not_null_constraint_name));
76
+
77
+ std::unique_ptr<catalog::Schema> column_catalog_schema (
78
+ new catalog::Schema ({table_id_column, layout_oid_column,
79
+ num_columns_column, column_map_column}));
80
+
81
+ return column_catalog_schema;
82
+ }
83
+
84
+ /* * @brief Insert a layout into the pg_layout table.
85
+ * @param table_oid oid of the table to which the new layout belongs.
86
+ * @param layout layout to be added to the pg_layout table.
87
+ * @param pool to allocate memory for the column_map column.
88
+ * @param txn TransactionContext for adding the layout.
89
+ * @return true on success.
90
+ */
91
+ bool LayoutCatalog::InsertLayout (oid_t table_oid,
92
+ std::shared_ptr<const storage::Layout> layout,
93
+ type::AbstractPool *pool,
94
+ concurrency::TransactionContext *txn) {
95
+ // Create the tuple first
96
+ std::unique_ptr<storage::Tuple> tuple (
97
+ new storage::Tuple (catalog_table_->GetSchema (), true ));
98
+
99
+ auto val0 = type::ValueFactory::GetIntegerValue (table_oid);
100
+ auto val1 = type::ValueFactory::GetIntegerValue (layout->GetOid ());
101
+ auto val2 = type::ValueFactory::GetIntegerValue (layout->GetColumnCount ());
102
+ auto val3 = type::ValueFactory::GetVarcharValue (layout->SerializeColumnMap (),
103
+ nullptr );
104
+
105
+ tuple->SetValue (LayoutCatalog::ColumnId::TABLE_OID, val0, pool);
106
+ tuple->SetValue (LayoutCatalog::ColumnId::LAYOUT_OID, val1, pool);
107
+ tuple->SetValue (LayoutCatalog::ColumnId::NUM_COLUMNS, val2, pool);
108
+ tuple->SetValue (LayoutCatalog::ColumnId::COLUMN_MAP, val3, pool);
109
+
110
+ // Insert the tuple
111
+ return InsertTuple (std::move (tuple), txn);
112
+ }
113
+
114
+ /* * @brief Delete a layout from the pg_layout table.
115
+ * @param table_oid oid of the table to which the old layout belongs.
116
+ * @param layout_oid oid of the layout to be deleted.
117
+ * @param txn TransactionContext for deleting the layout.
118
+ * @return true on success.
119
+ */
120
+ bool LayoutCatalog::DeleteLayout (oid_t table_oid, oid_t layout_oid,
121
+ concurrency::TransactionContext *txn) {
122
+ oid_t index_offset = IndexId::PRIMARY_KEY; // Index of table_oid & layout_oid
123
+
124
+ std::vector<type::Value> values;
125
+ values.push_back (type::ValueFactory::GetIntegerValue (table_oid).Copy ());
126
+ values.push_back (type::ValueFactory::GetIntegerValue (layout_oid).Copy ());
127
+
128
+ auto pg_table = Catalog::GetInstance ()
129
+ ->GetSystemCatalogs (database_oid)
130
+ ->GetTableCatalog ();
131
+
132
+ // delete column from cache
133
+ auto table_object = pg_table->GetTableObject (table_oid, txn);
134
+ table_object->EvictLayout (layout_oid);
135
+
136
+ return DeleteWithIndexScan (index_offset, values, txn);
137
+ }
138
+
139
+ /* * @brief Delete all layouts correponding to a table from the pg_layout.
140
+ * @param table_oid oid of the table to delete all layouts.
141
+ * @param txn TransactionContext for deleting the layouts.
142
+ * @return true on success.
143
+ */
144
+ bool LayoutCatalog::DeleteLayouts (oid_t table_oid,
145
+ concurrency::TransactionContext *txn) {
146
+ oid_t index_offset = IndexId::SKEY_TABLE_OID; // Index of table_oid
147
+ std::vector<type::Value> values;
148
+ values.push_back (type::ValueFactory::GetIntegerValue (table_oid).Copy ());
149
+
150
+ // delete layouts from cache
151
+ auto pg_table = Catalog::GetInstance ()
152
+ ->GetSystemCatalogs (database_oid)
153
+ ->GetTableCatalog ();
154
+ auto table_object = pg_table->GetTableObject (table_oid, txn);
155
+ table_object->EvictAllLayouts ();
156
+
157
+ return DeleteWithIndexScan (index_offset, values, txn);
158
+ }
159
+
160
+ /* * @brief Get all layouts correponding to a table from the pg_layout.
161
+ * @param table_oid oid of the table to fetch all layouts.
162
+ * @param txn TransactionContext for getting the layouts.
163
+ * @return unordered_map containing a layout_oid -> layout mapping.
164
+ */
165
+ const std::unordered_map<oid_t , std::shared_ptr<const storage::Layout>>
166
+ LayoutCatalog::GetLayouts (oid_t table_oid,
167
+ concurrency::TransactionContext *txn) {
168
+ // Try to find the layouts in the cache
169
+ auto pg_table = Catalog::GetInstance ()
170
+ ->GetSystemCatalogs (database_oid)
171
+ ->GetTableCatalog ();
172
+ auto table_object = pg_table->GetTableObject (table_oid, txn);
173
+ PELOTON_ASSERT (table_object && table_object->GetTableOid () == table_oid);
174
+ auto layout_objects = table_object->GetLayouts (true );
175
+ if (layout_objects.size () != 0 ) {
176
+ return layout_objects;
177
+ }
178
+
179
+ // Cache miss, get from pg_catalog
180
+ std::vector<oid_t > column_ids (all_column_ids);
181
+ oid_t index_offset = IndexId::SKEY_TABLE_OID; // Index of table_oid
182
+ std::vector<type::Value> values;
183
+ values.push_back (type::ValueFactory::GetIntegerValue (table_oid).Copy ());
184
+
185
+ auto result_tiles =
186
+ GetResultWithIndexScan (column_ids, index_offset, values, txn);
187
+
188
+ for (auto &tile : (*result_tiles)) { // Iterate through the result_tiles
189
+ for (auto tuple_id : *tile) {
190
+ oid_t layout_oid =
191
+ tile->GetValue (tuple_id, LayoutCatalog::ColumnId::LAYOUT_OID)
192
+ .GetAs <oid_t >();
193
+ oid_t num_columns =
194
+ tile->GetValue (tuple_id, LayoutCatalog::ColumnId::NUM_COLUMNS)
195
+ .GetAs <oid_t >();
196
+ std::string column_map_str =
197
+ tile->GetValue (tuple_id, LayoutCatalog::ColumnId::COLUMN_MAP)
198
+ .ToString ();
199
+ auto column_map =
200
+ storage::Layout::DeserializeColumnMap (num_columns, column_map_str);
201
+ auto layout_object =
202
+ std::make_shared<const storage::Layout>(column_map, layout_oid);
203
+ table_object->InsertLayout (layout_object);
204
+ }
205
+ }
206
+
207
+ return table_object->GetLayouts ();
208
+ }
209
+
210
+ /* * @brief Get the layout by layout_oid from the pg_layout.
211
+ * @param table_oid oid of the table to fetch the layout.
212
+ * @param layout_oid oid of the layout being queried.
213
+ * @param txn TransactionContext for getting the layout.
214
+ * @return shared_ptr corresponding to the layout_oid if found.
215
+ * nullptr otherwise.
216
+ */
217
+ std::shared_ptr<const storage::Layout> LayoutCatalog::GetLayoutWithOid (
218
+ oid_t table_oid, oid_t layout_oid, concurrency::TransactionContext *txn) {
219
+ auto table_layouts = GetLayouts (table_oid, txn);
220
+ for (const auto &layout_entry : table_layouts) {
221
+ if (layout_entry.second ->GetOid () == layout_oid) {
222
+ return layout_entry.second ;
223
+ }
224
+ }
225
+ return nullptr ;
226
+ }
227
+
228
+ } // namespace catalog
229
+ } // namespace peloton
0 commit comments