Skip to content

Commit 5113989

Browse files
authored
Fix issue with too long schema names breaking MotherDuck sync (#680)
If you have a database+schema that would result in a `ddb$` schema with more than 63 characters it would completely break the MotherDuck background syncing, due to an error-restart-loop. This changes the code to skip that schema. It also codes a bit more defensively in the place where it was also previously throwing the error continuously. If the schema cannot be found when we try to add a dependency for it, we say that we failed to create the schema and skip it instead of getting into this error loop.
1 parent 91b6bb1 commit 5113989

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

src/pgduckdb_background_worker.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,14 @@ GrantAccessToSchema(const char *postgres_schema_name) {
734734

735735
static bool
736736
CreateSchemaIfNotExists(const char *postgres_schema_name, bool is_default_db) {
737+
/* -1 is for the NULL terminator */
738+
if (strlen(postgres_schema_name) > NAMEDATALEN - 1) {
739+
ereport(WARNING,
740+
(errmsg("Skipping sync of MotherDuck schema '%s' because its name is too long", postgres_schema_name),
741+
errhint("The maximum length of a schema name is %d characters", NAMEDATALEN - 1)));
742+
return false;
743+
}
744+
737745
Oid schema_oid = get_namespace_oid(postgres_schema_name, true);
738746
if (schema_oid != InvalidOid) {
739747
/*
@@ -803,15 +811,18 @@ CreateSchemaIfNotExists(const char *postgres_schema_name, bool is_default_db) {
803811
return false;
804812
}
805813

806-
/* Success, so we commit the subtransaction */
807-
ReleaseCurrentSubTransaction();
808-
809814
if (!is_default_db) {
810815
/*
811816
* For ddb$ schemas we need to record a dependency between the schema
812817
* and the extension, so that DROP EXTENSION also drops these schemas.
813818
*/
814-
schema_oid = get_namespace_oid(postgres_schema_name, false);
819+
schema_oid = get_namespace_oid(postgres_schema_name, true);
820+
if (schema_oid == InvalidOid) {
821+
elog(WARNING, "Failed to create schema '%s' for unknown reason, skipping sync", postgres_schema_name);
822+
RollbackAndReleaseCurrentSubTransaction();
823+
return false;
824+
}
825+
815826
ObjectAddress schema_address = {
816827
.classId = NamespaceRelationId,
817828
.objectId = schema_oid,
@@ -825,6 +836,9 @@ CreateSchemaIfNotExists(const char *postgres_schema_name, bool is_default_db) {
825836
recordDependencyOn(&schema_address, &extension_address, DEPENDENCY_NORMAL);
826837
}
827838

839+
/* Success, so we commit the subtransaction */
840+
ReleaseCurrentSubTransaction();
841+
828842
/* And then we also commit the actual transaction to release any locks that
829843
* were necessary to execute it. */
830844
SPI_commit_that_works_in_bgworker();

0 commit comments

Comments
 (0)