diff options
Diffstat (limited to 'contrib/postgres_fdw/postgres_fdw.c')
-rw-r--r-- | contrib/postgres_fdw/postgres_fdw.c | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 4d1b906381e..4c2c339d1e5 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -3567,6 +3567,9 @@ create_foreign_modify(EState *estate, Assert(!attr->attisdropped); + /* Ignore generated columns; they are set to DEFAULT */ + if (attr->attgenerated) + continue; getTypeOutputInfo(attr->atttypid, &typefnoid, &isvarlena); fmgr_info(typefnoid, &fmstate->p_flinfo[fmstate->p_nums]); fmstate->p_nums++; @@ -3752,6 +3755,7 @@ convert_prep_stmt_params(PgFdwModifyState *fmstate, /* get following parameters from slot */ if (slot != NULL && fmstate->target_attrs != NIL) { + TupleDesc tupdesc = RelationGetDescr(fmstate->rel); int nestlevel; ListCell *lc; @@ -3760,9 +3764,13 @@ convert_prep_stmt_params(PgFdwModifyState *fmstate, foreach(lc, fmstate->target_attrs) { int attnum = lfirst_int(lc); + Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1); Datum value; bool isnull; + /* Ignore generated columns; they are set to DEFAULT */ + if (attr->attgenerated) + continue; value = slot_getattr(slot, attnum, &isnull); if (isnull) p_values[pindex] = NULL; @@ -4673,6 +4681,7 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) List *commands = NIL; bool import_collate = true; bool import_default = false; + bool import_generated = true; bool import_not_null = true; ForeignServer *server; UserMapping *mapping; @@ -4692,6 +4701,8 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) import_collate = defGetBoolean(def); else if (strcmp(def->defname, "import_default") == 0) import_default = defGetBoolean(def); + else if (strcmp(def->defname, "import_generated") == 0) + import_generated = defGetBoolean(def); else if (strcmp(def->defname, "import_not_null") == 0) import_not_null = defGetBoolean(def); else @@ -4753,13 +4764,24 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) * include a schema name for types/functions in other schemas, which * is what we want. */ + appendStringInfoString(&buf, + "SELECT relname, " + " attname, " + " format_type(atttypid, atttypmod), " + " attnotnull, "); + + /* Generated columns are supported since Postgres 12 */ + if (PQserverVersion(conn) >= 120000) + appendStringInfoString(&buf, + " attgenerated, " + " pg_get_expr(adbin, adrelid), "); + else + appendStringInfoString(&buf, + " NULL, " + " pg_get_expr(adbin, adrelid), "); + if (import_collate) appendStringInfoString(&buf, - "SELECT relname, " - " attname, " - " format_type(atttypid, atttypmod), " - " attnotnull, " - " pg_get_expr(adbin, adrelid), " " collname, " " collnsp.nspname " "FROM pg_class c " @@ -4776,11 +4798,6 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) " collnsp.oid = collnamespace "); else appendStringInfoString(&buf, - "SELECT relname, " - " attname, " - " format_type(atttypid, atttypmod), " - " attnotnull, " - " pg_get_expr(adbin, adrelid), " " NULL, NULL " "FROM pg_class c " " JOIN pg_namespace n ON " @@ -4856,6 +4873,7 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) char *attname; char *typename; char *attnotnull; + char *attgenerated; char *attdefault; char *collname; char *collnamespace; @@ -4867,12 +4885,14 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) attname = PQgetvalue(res, i, 1); typename = PQgetvalue(res, i, 2); attnotnull = PQgetvalue(res, i, 3); - attdefault = PQgetisnull(res, i, 4) ? (char *) NULL : + attgenerated = PQgetisnull(res, i, 4) ? (char *) NULL : PQgetvalue(res, i, 4); - collname = PQgetisnull(res, i, 5) ? (char *) NULL : + attdefault = PQgetisnull(res, i, 5) ? (char *) NULL : PQgetvalue(res, i, 5); - collnamespace = PQgetisnull(res, i, 6) ? (char *) NULL : + collname = PQgetisnull(res, i, 6) ? (char *) NULL : PQgetvalue(res, i, 6); + collnamespace = PQgetisnull(res, i, 7) ? (char *) NULL : + PQgetvalue(res, i, 7); if (first_item) first_item = false; @@ -4900,9 +4920,20 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) quote_identifier(collname)); /* Add DEFAULT if needed */ - if (import_default && attdefault != NULL) + if (import_default && attdefault != NULL && + (!attgenerated || !attgenerated[0])) appendStringInfo(&buf, " DEFAULT %s", attdefault); + /* Add GENERATED if needed */ + if (import_generated && attgenerated != NULL && + attgenerated[0] == ATTRIBUTE_GENERATED_STORED) + { + Assert(attdefault != NULL); + appendStringInfo(&buf, + " GENERATED ALWAYS AS (%s) STORED", + attdefault); + } + /* Add NOT NULL if needed */ if (import_not_null && attnotnull[0] == 't') appendStringInfoString(&buf, " NOT NULL"); |