Skip to content

Commit 34fa0dd

Browse files
committed
Fix CREATE DATABASE so we can pg_upgrade DBs with OIDs above 2^31.
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/[email protected]
1 parent 8c71467 commit 34fa0dd

File tree

4 files changed

+37
-3
lines changed

4 files changed

+37
-3
lines changed

src/backend/commands/dbcommands.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
816816
}
817817
else if (strcmp(defel->defname, "oid") == 0)
818818
{
819-
dboid = defGetInt32(defel);
819+
dboid = defGetObjectId(defel);
820820

821821
/*
822822
* We don't normally permit new databases to be created with

src/backend/commands/define.c

+33
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,39 @@ defGetInt64(DefElem *def)
213213
return 0; /* keep compiler quiet */
214214
}
215215

216+
/*
217+
* Extract an OID value from a DefElem.
218+
*/
219+
Oid
220+
defGetObjectId(DefElem *def)
221+
{
222+
if (def->arg == NULL)
223+
ereport(ERROR,
224+
(errcode(ERRCODE_SYNTAX_ERROR),
225+
errmsg("%s requires a numeric value",
226+
def->defname)));
227+
switch (nodeTag(def->arg))
228+
{
229+
case T_Integer:
230+
return (Oid) intVal(def->arg);
231+
case T_Float:
232+
233+
/*
234+
* Values too large for int4 will be represented as Float
235+
* constants by the lexer. Accept these if they are valid OID
236+
* strings.
237+
*/
238+
return DatumGetObjectId(DirectFunctionCall1(oidin,
239+
CStringGetDatum(castNode(Float, def->arg)->fval)));
240+
default:
241+
ereport(ERROR,
242+
(errcode(ERRCODE_SYNTAX_ERROR),
243+
errmsg("%s requires a numeric value",
244+
def->defname)));
245+
}
246+
return 0; /* keep compiler quiet */
247+
}
248+
216249
/*
217250
* Extract a possibly-qualified name (as a List of Strings) from a DefElem.
218251
*/

src/backend/parser/gram.y

+2-2
Original file line numberDiff line numberDiff line change
@@ -11105,9 +11105,9 @@ createdb_opt_items:
1110511105
;
1110611106

1110711107
createdb_opt_item:
11108-
createdb_opt_name opt_equal SignedIconst
11108+
createdb_opt_name opt_equal NumericOnly
1110911109
{
11110-
$$ = makeDefElem($1, (Node *) makeInteger($3), @1);
11110+
$$ = makeDefElem($1, $3, @1);
1111111111
}
1111211112
| createdb_opt_name opt_equal opt_boolean_or_string
1111311113
{

src/include/commands/defrem.h

+1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ extern double defGetNumeric(DefElem *def);
150150
extern bool defGetBoolean(DefElem *def);
151151
extern int32 defGetInt32(DefElem *def);
152152
extern int64 defGetInt64(DefElem *def);
153+
extern Oid defGetObjectId(DefElem *def);
153154
extern List *defGetQualifiedName(DefElem *def);
154155
extern TypeName *defGetTypeName(DefElem *def);
155156
extern int defGetTypeLength(DefElem *def);

0 commit comments

Comments
 (0)