| 202 | } |
| 203 | |
| 204 | void table_storage::save_table_metadata(const pg::table_data& table_data) |
| 205 | { |
| 206 | const std::string& table_name = table_data.get_table_name(); |
| 207 | const std::string ds_path = table_data.get_dataset_path().url(); |
| 208 | pg::utils::memory_context_switcher context_switcher; |
| 209 | pg::utils::pg_try([&]() { |
| 210 | StringInfoData buf; |
| 211 | initStringInfo(&buf); |
| 212 | |
| 213 | appendStringInfo(&buf, |
| 214 | "INSERT INTO public.pg_deeplake_tables (table_oid, table_name, ds_path) " |
| 215 | "VALUES (%u, %s, %s) " |
| 216 | "ON CONFLICT DO NOTHING", |
| 217 | table_data.get_table_oid(), |
| 218 | quote_literal_cstr(table_name.c_str()), |
| 219 | quote_literal_cstr(ds_path.c_str())); |
| 220 | |
| 221 | pg::utils::spi_connector connector; |
| 222 | if (SPI_execute(buf.data, false, 0) != SPI_OK_INSERT) { |
| 223 | throw pg::exception("Failed to save table metadata"); |
| 224 | } |
| 225 | return true; |
| 226 | }); |
| 227 | |
| 228 | // Also write into Deep Lake catalog for stateless multi-instance support. |
| 229 | // Skip when in catalog-only mode — the data was synced FROM the S3 catalog, |
| 230 | // so writing back would be redundant and add unnecessary S3 latency. |
| 231 | if (pg::stateless_enabled && !is_catalog_only_create()) { |
| 232 | const auto root_dir = []() { |
| 233 | auto root = session_credentials::get_root_path(); |
| 234 | if (root.empty()) { |
| 235 | root = pg::utils::get_deeplake_root_directory(); |
| 236 | } |
| 237 | return root; |
| 238 | }(); |
| 239 | auto creds = session_credentials::get_credentials(); |
| 240 | pg::dl_catalog::ensure_catalog(root_dir, creds); |
| 241 | |
| 242 | auto [schema_name, simple_table_name] = split_table_name(table_name); |
| 243 | const std::string table_id = schema_name + "." + simple_table_name; |
| 244 | |
| 245 | pg::dl_catalog::table_meta meta; |
| 246 | meta.table_id = table_id; |
| 247 | meta.schema_name = schema_name; |
| 248 | meta.table_name = simple_table_name; |
| 249 | meta.dataset_path = ds_path; |
| 250 | meta.state = "ready"; |
| 251 | pg::dl_catalog::upsert_table(root_dir, creds, meta); |
| 252 | |
| 253 | // Save column metadata to catalog |
| 254 | TupleDesc tupdesc = table_data.get_tuple_descriptor(); |
| 255 | std::vector<pg::dl_catalog::column_meta> columns; |
| 256 | for (int i = 0; i < tupdesc->natts; i++) { |
| 257 | Form_pg_attribute attr = TupleDescAttr(tupdesc, i); |
| 258 | if (attr->attisdropped) { |
| 259 | continue; |
| 260 | } |
| 261 | pg::dl_catalog::column_meta col; |
nothing calls this directly
no test coverage detected