Skip to content

Commit

Permalink
Fix CREATE DATABASE so we can pg_upgrade DBs with OIDs above 2^31.
Browse files Browse the repository at this point in the history
Commit aa01051 repeated one of the oldest mistakes in our book:
thinking that OID is the same as int32.  It isn't of course, and
unsurprisingly the first person who came along with a database
OID above 2 billion broke it.  Repair.

Per bug #17677 from Sergey Pankov.  Back-patch to v15.

Discussion: https://postgr.es/m/17677-a99fa067d7ed71c9@postgresql.org
  • Loading branch information
tglsfdc committed Nov 4, 2022
1 parent 8c71467 commit 34fa0dd
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/backend/commands/dbcommands.c
Expand Up @@ -816,7 +816,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
}
else if (strcmp(defel->defname, "oid") == 0)
{
dboid = defGetInt32(defel);
dboid = defGetObjectId(defel);

/*
* We don't normally permit new databases to be created with
Expand Down
33 changes: 33 additions & 0 deletions src/backend/commands/define.c
Expand Up @@ -213,6 +213,39 @@ defGetInt64(DefElem *def)
return 0; /* keep compiler quiet */
}

/*
* Extract an OID value from a DefElem.
*/
Oid
defGetObjectId(DefElem *def)
{
if (def->arg == NULL)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("%s requires a numeric value",
def->defname)));
switch (nodeTag(def->arg))
{
case T_Integer:
return (Oid) intVal(def->arg);
case T_Float:

/*
* Values too large for int4 will be represented as Float
* constants by the lexer. Accept these if they are valid OID
* strings.
*/
return DatumGetObjectId(DirectFunctionCall1(oidin,
CStringGetDatum(castNode(Float, def->arg)->fval)));
default:
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("%s requires a numeric value",
def->defname)));
}
return 0; /* keep compiler quiet */
}

/*
* Extract a possibly-qualified name (as a List of Strings) from a DefElem.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/backend/parser/gram.y
Expand Up @@ -11105,9 +11105,9 @@ createdb_opt_items:
;

createdb_opt_item:
createdb_opt_name opt_equal SignedIconst
createdb_opt_name opt_equal NumericOnly
{
$$ = makeDefElem($1, (Node *) makeInteger($3), @1);
$$ = makeDefElem($1, $3, @1);
}
| createdb_opt_name opt_equal opt_boolean_or_string
{
Expand Down
1 change: 1 addition & 0 deletions src/include/commands/defrem.h
Expand Up @@ -150,6 +150,7 @@ extern double defGetNumeric(DefElem *def);
extern bool defGetBoolean(DefElem *def);
extern int32 defGetInt32(DefElem *def);
extern int64 defGetInt64(DefElem *def);
extern Oid defGetObjectId(DefElem *def);
extern List *defGetQualifiedName(DefElem *def);
extern TypeName *defGetTypeName(DefElem *def);
extern int defGetTypeLength(DefElem *def);
Expand Down

0 comments on commit 34fa0dd

Please sign in to comment.