Skip to content

Commit 84b5719

Browse files
Actually create the namespace on table creation
Signed-off-by: Onder KALACI <[email protected]>
1 parent ccd0448 commit 84b5719

File tree

4 files changed

+32
-8
lines changed

4 files changed

+32
-8
lines changed

pg_lake_iceberg/include/pg_lake/rest_catalog/rest_catalog.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ extern PGDLLEXPORT void RegisterNamespaceToRestCatalog(const char *catalogName,
3838
bool hasRestCatalogReadOnlyOption);
3939
extern PGDLLEXPORT void ErrorIfRestNamespaceDoesNotExist(const char *catalogName, const char *namespaceName);
4040
extern PGDLLEXPORT IcebergCatalogType GetIcebergCatalogType(Oid relationId);
41+
extern PGDLLEXPORT char *GetRestCatalogName(Oid relationId);
4142
extern PGDLLEXPORT char *GetRestCatalogNamespace(Oid relationId);
4243
extern PGDLLEXPORT char *GetRestCatalogTableName(Oid relationId);
4344
extern PGDLLEXPORT bool HasRestCatalogTableOption(List *options);

pg_lake_iceberg/src/rest_catalog/rest_catalog.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ char *RestCatalogClientSecret = NULL;
4444
static void CreateNamespaceOnRestCatalog(const char *catalogName, const char *namespaceName);
4545
static char *EncodeBasicAuth(const char *clientId, const char *clientSecret);
4646
static char *JsonbGetStringByPath(const char *jsonb_text, int nkeys,...);
47-
static char *GetRestCatalogName(Oid relationId);
4847
static List *PostHeadersWithAuth(void);
4948
static List *GetHeadersWithAuth(void);
5049
static void ReportHTTPError(HttpResult httpResult, int level);
@@ -582,7 +581,7 @@ HasReadOnlyOption(List *options)
582581
* as the catalog name in the external catalog. Writable rest catalog tables
583582
* use the current database name as the catalog name.
584583
*/
585-
static char *
584+
char *
586585
GetRestCatalogName(Oid relationId)
587586
{
588587
IcebergCatalogType catalogType = GetIcebergCatalogType(relationId);

pg_lake_table/src/ddl/create_table.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,8 @@ ProcessCreateIcebergTableFromForeignTableStmt(ProcessUtilityParams * params)
659659

660660
if (hasObjectStoreCatalogOption || hasRestCatalogOption)
661661
{
662+
Oid namespaceId = RangeVarGetAndCheckCreationNamespace(createStmt->base.relation, NoLock, NULL);
663+
662664
/*
663665
* Read-only external catalog tables are a special case of Iceberg
664666
* tables. They are recognized as Iceberg tables, but are not
@@ -684,8 +686,6 @@ ProcessCreateIcebergTableFromForeignTableStmt(ProcessUtilityParams * params)
684686
*/
685687
if (catalogNamespaceProvided == NULL && hasExternalCatalogReadOnlyOption)
686688
{
687-
Oid namespaceId = RangeVarGetAndCheckCreationNamespace(createStmt->base.relation, NoLock, NULL);
688-
689689
catalogNamespace = get_namespace_name(namespaceId);
690690

691691
/* add catalog_namespace table options */
@@ -761,6 +761,30 @@ ProcessCreateIcebergTableFromForeignTableStmt(ProcessUtilityParams * params)
761761
errmsg("writable %s catalog iceberg tables do not "
762762
"allow explicit catalog options", hasObjectStoreCatalogOption ? "object store" : "REST")));
763763
}
764+
765+
if (hasRestCatalogOption)
766+
{
767+
/*
768+
* For writable rest catalog iceberg tables, we register the
769+
* namespace in the rest catalog. We do that early in the
770+
* command processing so that any errors in the registration
771+
* are caught before we create the actual table.
772+
*
773+
* Note that registering a namespace is not a transactional
774+
* operation from pg_lake's perspective. If the subsequent
775+
* table creation fails, the namespace registration will
776+
* remain. We accept that tradeoff for simplicity as
777+
* re-registering an existing namespace is a no-op. For a
778+
* writable rest catalog iceberg table, the namespace is
779+
* always the table's schema name. Similarly, the catalog name
780+
* is always the database name. We normally encode that in
781+
* GetRestCatalogName() etc., but here we need to do it early
782+
* before the table is created.
783+
*/
784+
RegisterNamespaceToRestCatalog(get_database_name(MyDatabaseId),
785+
get_namespace_name(namespaceId),
786+
hasExternalCatalogReadOnlyOption);
787+
}
764788
}
765789
else if (createStmt->base.tableElts == NIL && hasExternalCatalogReadOnlyOption)
766790
{

pg_lake_table/tests/pytests/test_polaris_catalog.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def test_create_namespace(
6262
pg_conn.commit()
6363

6464
run_command(
65-
f"""SELECT lake_iceberg.register_namespace_to_rest_catalog('{server_params.PG_DATABASE}', '{namespace}')""",
65+
f"""CREATE TABLE "{namespace}".tbl(a int) USING iceberg WITH (catalog='rest');""",
6666
pg_conn,
6767
)
6868
pg_conn.commit()
@@ -132,13 +132,13 @@ def test_create_namespace_in_tx(
132132
run_command(f'''CREATE SCHEMA "{namespace}_2"''', pg_conn)
133133

134134
run_command(
135-
f"""SELECT lake_iceberg.register_namespace_to_rest_catalog('{server_params.PG_DATABASE}', '{namespace}')""",
135+
f"""CREATE TABLE "{namespace}".tbl(a int) USING iceberg WITH (catalog='rest');""",
136136
pg_conn,
137137
)
138138
pg_conn.commit()
139139

140140
run_command(
141-
f"""SELECT lake_iceberg.register_namespace_to_rest_catalog('{server_params.PG_DATABASE}', '{namespace}_2')""",
141+
f"""CREATE TABLE "{namespace}_2".tbl(a int) USING iceberg WITH (catalog='rest');""",
142142
pg_conn,
143143
)
144144
pg_conn.commit()
@@ -176,7 +176,7 @@ def test_create_namespace_rollback(
176176
run_command(f'''CREATE SCHEMA "{namespace}"''', pg_conn)
177177

178178
run_command(
179-
f"""SELECT lake_iceberg.register_namespace_to_rest_catalog('{server_params.PG_DATABASE}', '{namespace}')""",
179+
f"""CREATE TABLE "{namespace}".tbl(a int) USING iceberg WITH (catalog='rest');""",
180180
pg_conn,
181181
)
182182

0 commit comments

Comments
 (0)