Add pg_get_serial_sequence() function, and cause pg_dump to use it.
This eliminates the assumption that a serial column's sequence will have the same name on reload that it was given in the original database. Christopher Kings-Lynne
This commit is contained in:
parent
ef2880263c
commit
a0e842d81b
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.210 2004/06/24 19:57:14 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.211 2004/06/25 17:20:21 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -7228,29 +7228,13 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
|
|||||||
<primary>pg_get_userbyid</primary>
|
<primary>pg_get_userbyid</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
|
<indexterm zone="functions-misc">
|
||||||
|
<primary>pg_get_serial_sequence</primary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<xref linkend="functions-misc-catalog-table"> lists functions that
|
<xref linkend="functions-misc-catalog-table"> lists functions that
|
||||||
extract information from the system catalogs.
|
extract information from the system catalogs.
|
||||||
<function>pg_get_viewdef</function>,
|
|
||||||
<function>pg_get_ruledef</function>,
|
|
||||||
<function>pg_get_indexdef</function>,
|
|
||||||
<function>pg_get_triggerdef</function>, and
|
|
||||||
<function>pg_get_constraintdef</function> respectively
|
|
||||||
reconstruct the creating command for a view, rule, index, trigger, or
|
|
||||||
constraint. (Note that this is a decompiled reconstruction, not
|
|
||||||
the original text of the command.) Most of these come in two
|
|
||||||
variants, one of which can optionally <quote>pretty-print</> the result.
|
|
||||||
The pretty-printed format is more readable, but the default format is more
|
|
||||||
likely to be
|
|
||||||
interpreted the same way by future versions of <productname>PostgreSQL</>;
|
|
||||||
avoid using pretty-printed output for dump purposes.
|
|
||||||
Passing <literal>false</> for the pretty-print parameter yields the
|
|
||||||
same result as the variant that does not have the parameter at all.
|
|
||||||
<function>pg_get_expr</function> decompiles the internal form of an
|
|
||||||
individual expression, such as the default value for a column. It
|
|
||||||
may be useful when examining the contents of system catalogs.
|
|
||||||
<function>pg_get_userbyid</function>
|
|
||||||
extracts a user's name given a user ID number.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<table id="functions-misc-catalog-table">
|
<table id="functions-misc-catalog-table">
|
||||||
@ -7335,10 +7319,49 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
|
|||||||
<entry><type>name</type></entry>
|
<entry><type>name</type></entry>
|
||||||
<entry>get user name with given ID</entry>
|
<entry>get user name with given ID</entry>
|
||||||
</row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><literal><function>pg_get_serial_sequence</function>(<parameter>table_name</parameter>, <parameter>column_name</parameter>)</literal></entry>
|
||||||
|
<entry><type>text</type></entry>
|
||||||
|
<entry>get name of the sequence that a serial or bigserial column
|
||||||
|
uses</entry>
|
||||||
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<function>pg_get_viewdef</function>,
|
||||||
|
<function>pg_get_ruledef</function>,
|
||||||
|
<function>pg_get_indexdef</function>,
|
||||||
|
<function>pg_get_triggerdef</function>, and
|
||||||
|
<function>pg_get_constraintdef</function> respectively
|
||||||
|
reconstruct the creating command for a view, rule, index, trigger, or
|
||||||
|
constraint. (Note that this is a decompiled reconstruction, not
|
||||||
|
the original text of the command.)
|
||||||
|
<function>pg_get_expr</function> decompiles the internal form of an
|
||||||
|
individual expression, such as the default value for a column. It
|
||||||
|
may be useful when examining the contents of system catalogs.
|
||||||
|
Most of these functions come in two
|
||||||
|
variants, one of which can optionally <quote>pretty-print</> the result.
|
||||||
|
The pretty-printed format is more readable, but the default format is more
|
||||||
|
likely to be
|
||||||
|
interpreted the same way by future versions of <productname>PostgreSQL</>;
|
||||||
|
avoid using pretty-printed output for dump purposes.
|
||||||
|
Passing <literal>false</> for the pretty-print parameter yields the
|
||||||
|
same result as the variant that does not have the parameter at all.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<function>pg_get_userbyid</function>
|
||||||
|
extracts a user's name given a user ID number.
|
||||||
|
<function>pg_get_serial_sequence</function>
|
||||||
|
fetches the name of the sequence associated with a serial or
|
||||||
|
bigserial column. The name is suitably formatted
|
||||||
|
for passing to the sequence functions (see <xref
|
||||||
|
linkend="functions-sequence">).
|
||||||
|
NULL is returned if the column does not have a sequence attached.
|
||||||
|
</para>
|
||||||
|
|
||||||
<indexterm zone="functions-misc">
|
<indexterm zone="functions-misc">
|
||||||
<primary>obj_description</primary>
|
<primary>obj_description</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* back to source text
|
* back to source text
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.173 2004/06/18 06:13:49 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.174 2004/06/25 17:20:24 tgl Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -42,12 +42,14 @@
|
|||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/heap.h"
|
#include "catalog/heap.h"
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_cast.h"
|
#include "catalog/pg_cast.h"
|
||||||
#include "catalog/pg_constraint.h"
|
#include "catalog/pg_constraint.h"
|
||||||
|
#include "catalog/pg_depend.h"
|
||||||
#include "catalog/pg_index.h"
|
#include "catalog/pg_index.h"
|
||||||
#include "catalog/pg_opclass.h"
|
#include "catalog/pg_opclass.h"
|
||||||
#include "catalog/pg_operator.h"
|
#include "catalog/pg_operator.h"
|
||||||
@ -1232,6 +1234,116 @@ pg_get_userbyid(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NAME(result);
|
PG_RETURN_NAME(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pg_get_serial_sequence
|
||||||
|
* Get the name of the sequence used by a serial column,
|
||||||
|
* formatted suitably for passing to setval, nextval or currval.
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
pg_get_serial_sequence(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
text *tablename = PG_GETARG_TEXT_P(0);
|
||||||
|
text *columnname = PG_GETARG_TEXT_P(1);
|
||||||
|
RangeVar *tablerv;
|
||||||
|
Oid tableOid;
|
||||||
|
char *column;
|
||||||
|
AttrNumber attnum;
|
||||||
|
Oid sequenceId = InvalidOid;
|
||||||
|
Relation depRel;
|
||||||
|
ScanKeyData key[3];
|
||||||
|
SysScanDesc scan;
|
||||||
|
HeapTuple tup;
|
||||||
|
|
||||||
|
/* Get the OID of the table */
|
||||||
|
tablerv = makeRangeVarFromNameList(textToQualifiedNameList(tablename,
|
||||||
|
"pg_get_serial_sequence"));
|
||||||
|
tableOid = RangeVarGetRelid(tablerv, false);
|
||||||
|
|
||||||
|
/* Get the number of the column */
|
||||||
|
column = DatumGetCString(DirectFunctionCall1(textout,
|
||||||
|
PointerGetDatum(columnname)));
|
||||||
|
|
||||||
|
attnum = get_attnum(tableOid, column);
|
||||||
|
if (attnum == InvalidAttrNumber)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
||||||
|
errmsg("column \"%s\" of relation \"%s\" does not exist",
|
||||||
|
column, tablerv->relname)));
|
||||||
|
|
||||||
|
/* Search the dependency table for the dependent sequence */
|
||||||
|
depRel = heap_openr(DependRelationName, AccessShareLock);
|
||||||
|
|
||||||
|
ScanKeyInit(&key[0],
|
||||||
|
Anum_pg_depend_refclassid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(RelOid_pg_class));
|
||||||
|
ScanKeyInit(&key[1],
|
||||||
|
Anum_pg_depend_refobjid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(tableOid));
|
||||||
|
ScanKeyInit(&key[2],
|
||||||
|
Anum_pg_depend_refobjsubid,
|
||||||
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
|
Int32GetDatum(attnum));
|
||||||
|
|
||||||
|
scan = systable_beginscan(depRel, DependReferenceIndex, true,
|
||||||
|
SnapshotNow, 3, key);
|
||||||
|
|
||||||
|
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
||||||
|
{
|
||||||
|
Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We assume any internal dependency of a relation on a column
|
||||||
|
* must be what we are looking for.
|
||||||
|
*/
|
||||||
|
if (deprec->classid == RelOid_pg_class &&
|
||||||
|
deprec->objsubid == 0 &&
|
||||||
|
deprec->deptype == DEPENDENCY_INTERNAL)
|
||||||
|
{
|
||||||
|
sequenceId = deprec->objid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
systable_endscan(scan);
|
||||||
|
heap_close(depRel, AccessShareLock);
|
||||||
|
|
||||||
|
if (OidIsValid(sequenceId))
|
||||||
|
{
|
||||||
|
HeapTuple classtup;
|
||||||
|
Form_pg_class classtuple;
|
||||||
|
char *nspname;
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
/* Get the sequence's pg_class entry */
|
||||||
|
classtup = SearchSysCache(RELOID,
|
||||||
|
ObjectIdGetDatum(sequenceId),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(classtup))
|
||||||
|
elog(ERROR, "cache lookup failed for relation %u", sequenceId);
|
||||||
|
classtuple = (Form_pg_class) GETSTRUCT(classtup);
|
||||||
|
|
||||||
|
/* Get the namespace */
|
||||||
|
nspname = get_namespace_name(classtuple->relnamespace);
|
||||||
|
if (!nspname)
|
||||||
|
elog(ERROR, "cache lookup failed for namespace %u",
|
||||||
|
classtuple->relnamespace);
|
||||||
|
|
||||||
|
/* And construct the result string */
|
||||||
|
result = quote_qualified_identifier(nspname,
|
||||||
|
NameStr(classtuple->relname));
|
||||||
|
|
||||||
|
ReleaseSysCache(classtup);
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(string_to_text(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* deparse_expression - General utility for deparsing expressions
|
* deparse_expression - General utility for deparsing expressions
|
||||||
*
|
*
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* by PostgreSQL
|
* by PostgreSQL
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.376 2004/06/21 13:36:41 tgl Exp $
|
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.377 2004/06/25 17:20:26 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -7319,9 +7319,27 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
|
|||||||
|
|
||||||
if (!schemaOnly)
|
if (!schemaOnly)
|
||||||
{
|
{
|
||||||
|
TableInfo *owning_tab;
|
||||||
|
|
||||||
resetPQExpBuffer(query);
|
resetPQExpBuffer(query);
|
||||||
appendPQExpBuffer(query, "SELECT pg_catalog.setval(");
|
appendPQExpBuffer(query, "SELECT pg_catalog.setval(");
|
||||||
appendStringLiteral(query, fmtId(tbinfo->dobj.name), true);
|
/*
|
||||||
|
* If this is a SERIAL sequence, then use the pg_get_serial_sequence
|
||||||
|
* function to avoid hard-coding the sequence name. Note that this
|
||||||
|
* implicitly assumes that the sequence and its owning table are in
|
||||||
|
* the same schema, because we don't schema-qualify the reference.
|
||||||
|
*/
|
||||||
|
if (OidIsValid(tbinfo->owning_tab) &&
|
||||||
|
(owning_tab = findTableByOid(tbinfo->owning_tab)) != NULL)
|
||||||
|
{
|
||||||
|
appendPQExpBuffer(query, "pg_catalog.pg_get_serial_sequence(");
|
||||||
|
appendStringLiteral(query, fmtId(owning_tab->dobj.name), true);
|
||||||
|
appendPQExpBuffer(query, ", ");
|
||||||
|
appendStringLiteral(query, owning_tab->attnames[tbinfo->owning_col-1], true);
|
||||||
|
appendPQExpBuffer(query, ")");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appendStringLiteral(query, fmtId(tbinfo->dobj.name), true);
|
||||||
appendPQExpBuffer(query, ", %s, %s);\n",
|
appendPQExpBuffer(query, ", %s, %s);\n",
|
||||||
last, (called ? "true" : "false"));
|
last, (called ? "true" : "false"));
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.239 2004/06/21 04:06:07 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.240 2004/06/25 17:20:28 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200406202
|
#define CATALOG_VERSION_NO 200406251
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.338 2004/06/16 01:26:49 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.339 2004/06/25 17:20:28 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* The script catalog/genbki.sh reads this file and generates .bki
|
* The script catalog/genbki.sh reads this file and generates .bki
|
||||||
@ -2238,6 +2238,8 @@ DATA(insert OID = 1387 ( pg_get_constraintdef PGNSP PGUID 12 f f t f s 1 25 "26
|
|||||||
DESCR("constraint description");
|
DESCR("constraint description");
|
||||||
DATA(insert OID = 1716 ( pg_get_expr PGNSP PGUID 12 f f t f s 2 25 "25 26" _null_ pg_get_expr - _null_ ));
|
DATA(insert OID = 1716 ( pg_get_expr PGNSP PGUID 12 f f t f s 2 25 "25 26" _null_ pg_get_expr - _null_ ));
|
||||||
DESCR("deparse an encoded expression");
|
DESCR("deparse an encoded expression");
|
||||||
|
DATA(insert OID = 1665 ( pg_get_serial_sequence PGNSP PGUID 12 f f t f s 2 25 "25 25" _null_ pg_get_serial_sequence - _null_ ));
|
||||||
|
DESCR("name of sequence for a serial column");
|
||||||
|
|
||||||
|
|
||||||
/* Generic referential integrity constraint triggers */
|
/* Generic referential integrity constraint triggers */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.243 2004/06/13 21:57:26 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.244 2004/06/25 17:20:29 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -472,9 +472,10 @@ extern Datum pg_get_triggerdef(PG_FUNCTION_ARGS);
|
|||||||
extern Datum pg_get_constraintdef(PG_FUNCTION_ARGS);
|
extern Datum pg_get_constraintdef(PG_FUNCTION_ARGS);
|
||||||
extern Datum pg_get_constraintdef_ext(PG_FUNCTION_ARGS);
|
extern Datum pg_get_constraintdef_ext(PG_FUNCTION_ARGS);
|
||||||
extern char *pg_get_constraintdef_string(Oid constraintId);
|
extern char *pg_get_constraintdef_string(Oid constraintId);
|
||||||
extern Datum pg_get_userbyid(PG_FUNCTION_ARGS);
|
|
||||||
extern Datum pg_get_expr(PG_FUNCTION_ARGS);
|
extern Datum pg_get_expr(PG_FUNCTION_ARGS);
|
||||||
extern Datum pg_get_expr_ext(PG_FUNCTION_ARGS);
|
extern Datum pg_get_expr_ext(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum pg_get_userbyid(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum pg_get_serial_sequence(PG_FUNCTION_ARGS);
|
||||||
extern char *deparse_expression(Node *expr, List *dpcontext,
|
extern char *deparse_expression(Node *expr, List *dpcontext,
|
||||||
bool forceprefix, bool showimplicit);
|
bool forceprefix, bool showimplicit);
|
||||||
extern List *deparse_context_for(const char *aliasname, Oid relid);
|
extern List *deparse_context_for(const char *aliasname, Oid relid);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user