mirror of
https://github.com/postgres/postgres.git
synced 2025-10-13 18:28:01 +03:00
Commit 16828d5c02
neglected to do this, so upgraded databases would
silently get null instead of the specified default in rows without the
attribute defined.
A new binary upgrade function is provided to perform this and pg_dump is
adjusted to output a call to the function if required in binary upgrade
mode.
Also included is code to drop missing attribute values for dropped
columns. That way if the type is later dropped the missing value won't
have a dangling reference to the type.
Finally the regression tests are adjusted to ensure that there is a row
with a missing value so that this code is exercised in upgrade testing.
Catalog version unfortunately bumped.
Regression test changes from Tom Lane.
Remainder from me, reviewed by Tom Lane, Andres Freund, Alvaro Herrera
Discussion: https://postgr.es/m/19987.1529420110@sss.pgh.pa.us
211 lines
4.5 KiB
C
211 lines
4.5 KiB
C
/*
|
|
* pg_upgrade_support.c
|
|
*
|
|
* server-side functions to set backend global variables
|
|
* to control oid and relfilenode assignment, and do other special
|
|
* hacks needed for pg_upgrade.
|
|
*
|
|
* Copyright (c) 2010-2018, PostgreSQL Global Development Group
|
|
* src/backend/utils/adt/pg_upgrade_support.c
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
#include "catalog/binary_upgrade.h"
|
|
#include "catalog/heap.h"
|
|
#include "catalog/namespace.h"
|
|
#include "catalog/pg_type.h"
|
|
#include "commands/extension.h"
|
|
#include "miscadmin.h"
|
|
#include "utils/array.h"
|
|
#include "utils/builtins.h"
|
|
|
|
|
|
#define CHECK_IS_BINARY_UPGRADE \
|
|
do { \
|
|
if (!IsBinaryUpgrade) \
|
|
ereport(ERROR, \
|
|
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM), \
|
|
(errmsg("function can only be called when server is in binary upgrade mode")))); \
|
|
} while (0)
|
|
|
|
Datum
|
|
binary_upgrade_set_next_pg_type_oid(PG_FUNCTION_ARGS)
|
|
{
|
|
Oid typoid = PG_GETARG_OID(0);
|
|
|
|
CHECK_IS_BINARY_UPGRADE;
|
|
binary_upgrade_next_pg_type_oid = typoid;
|
|
|
|
PG_RETURN_VOID();
|
|
}
|
|
|
|
Datum
|
|
binary_upgrade_set_next_array_pg_type_oid(PG_FUNCTION_ARGS)
|
|
{
|
|
Oid typoid = PG_GETARG_OID(0);
|
|
|
|
CHECK_IS_BINARY_UPGRADE;
|
|
binary_upgrade_next_array_pg_type_oid = typoid;
|
|
|
|
PG_RETURN_VOID();
|
|
}
|
|
|
|
Datum
|
|
binary_upgrade_set_next_toast_pg_type_oid(PG_FUNCTION_ARGS)
|
|
{
|
|
Oid typoid = PG_GETARG_OID(0);
|
|
|
|
CHECK_IS_BINARY_UPGRADE;
|
|
binary_upgrade_next_toast_pg_type_oid = typoid;
|
|
|
|
PG_RETURN_VOID();
|
|
}
|
|
|
|
Datum
|
|
binary_upgrade_set_next_heap_pg_class_oid(PG_FUNCTION_ARGS)
|
|
{
|
|
Oid reloid = PG_GETARG_OID(0);
|
|
|
|
CHECK_IS_BINARY_UPGRADE;
|
|
binary_upgrade_next_heap_pg_class_oid = reloid;
|
|
|
|
PG_RETURN_VOID();
|
|
}
|
|
|
|
Datum
|
|
binary_upgrade_set_next_index_pg_class_oid(PG_FUNCTION_ARGS)
|
|
{
|
|
Oid reloid = PG_GETARG_OID(0);
|
|
|
|
CHECK_IS_BINARY_UPGRADE;
|
|
binary_upgrade_next_index_pg_class_oid = reloid;
|
|
|
|
PG_RETURN_VOID();
|
|
}
|
|
|
|
Datum
|
|
binary_upgrade_set_next_toast_pg_class_oid(PG_FUNCTION_ARGS)
|
|
{
|
|
Oid reloid = PG_GETARG_OID(0);
|
|
|
|
CHECK_IS_BINARY_UPGRADE;
|
|
binary_upgrade_next_toast_pg_class_oid = reloid;
|
|
|
|
PG_RETURN_VOID();
|
|
}
|
|
|
|
Datum
|
|
binary_upgrade_set_next_pg_enum_oid(PG_FUNCTION_ARGS)
|
|
{
|
|
Oid enumoid = PG_GETARG_OID(0);
|
|
|
|
CHECK_IS_BINARY_UPGRADE;
|
|
binary_upgrade_next_pg_enum_oid = enumoid;
|
|
|
|
PG_RETURN_VOID();
|
|
}
|
|
|
|
Datum
|
|
binary_upgrade_set_next_pg_authid_oid(PG_FUNCTION_ARGS)
|
|
{
|
|
Oid authoid = PG_GETARG_OID(0);
|
|
|
|
CHECK_IS_BINARY_UPGRADE;
|
|
binary_upgrade_next_pg_authid_oid = authoid;
|
|
PG_RETURN_VOID();
|
|
}
|
|
|
|
Datum
|
|
binary_upgrade_create_empty_extension(PG_FUNCTION_ARGS)
|
|
{
|
|
text *extName;
|
|
text *schemaName;
|
|
bool relocatable;
|
|
text *extVersion;
|
|
Datum extConfig;
|
|
Datum extCondition;
|
|
List *requiredExtensions;
|
|
|
|
CHECK_IS_BINARY_UPGRADE;
|
|
|
|
/* We must check these things before dereferencing the arguments */
|
|
if (PG_ARGISNULL(0) ||
|
|
PG_ARGISNULL(1) ||
|
|
PG_ARGISNULL(2) ||
|
|
PG_ARGISNULL(3))
|
|
elog(ERROR, "null argument to binary_upgrade_create_empty_extension is not allowed");
|
|
|
|
extName = PG_GETARG_TEXT_PP(0);
|
|
schemaName = PG_GETARG_TEXT_PP(1);
|
|
relocatable = PG_GETARG_BOOL(2);
|
|
extVersion = PG_GETARG_TEXT_PP(3);
|
|
|
|
if (PG_ARGISNULL(4))
|
|
extConfig = PointerGetDatum(NULL);
|
|
else
|
|
extConfig = PG_GETARG_DATUM(4);
|
|
|
|
if (PG_ARGISNULL(5))
|
|
extCondition = PointerGetDatum(NULL);
|
|
else
|
|
extCondition = PG_GETARG_DATUM(5);
|
|
|
|
requiredExtensions = NIL;
|
|
if (!PG_ARGISNULL(6))
|
|
{
|
|
ArrayType *textArray = PG_GETARG_ARRAYTYPE_P(6);
|
|
Datum *textDatums;
|
|
int ndatums;
|
|
int i;
|
|
|
|
deconstruct_array(textArray,
|
|
TEXTOID, -1, false, 'i',
|
|
&textDatums, NULL, &ndatums);
|
|
for (i = 0; i < ndatums; i++)
|
|
{
|
|
char *extName = TextDatumGetCString(textDatums[i]);
|
|
Oid extOid = get_extension_oid(extName, false);
|
|
|
|
requiredExtensions = lappend_oid(requiredExtensions, extOid);
|
|
}
|
|
}
|
|
|
|
InsertExtensionTuple(text_to_cstring(extName),
|
|
GetUserId(),
|
|
get_namespace_oid(text_to_cstring(schemaName), false),
|
|
relocatable,
|
|
text_to_cstring(extVersion),
|
|
extConfig,
|
|
extCondition,
|
|
requiredExtensions);
|
|
|
|
PG_RETURN_VOID();
|
|
}
|
|
|
|
Datum
|
|
binary_upgrade_set_record_init_privs(PG_FUNCTION_ARGS)
|
|
{
|
|
bool record_init_privs = PG_GETARG_BOOL(0);
|
|
|
|
CHECK_IS_BINARY_UPGRADE;
|
|
binary_upgrade_record_init_privs = record_init_privs;
|
|
|
|
PG_RETURN_VOID();
|
|
}
|
|
|
|
Datum
|
|
binary_upgrade_set_missing_value(PG_FUNCTION_ARGS)
|
|
{
|
|
Oid table_id = PG_GETARG_OID(0);
|
|
text *attname = PG_GETARG_TEXT_P(1);
|
|
text *value = PG_GETARG_TEXT_P(2);
|
|
char *cattname = text_to_cstring(attname);
|
|
char *cvalue = text_to_cstring(value);
|
|
|
|
CHECK_IS_BINARY_UPGRADE;
|
|
SetAttrMissing(table_id, cattname, cvalue);
|
|
|
|
PG_RETURN_VOID();
|
|
}
|