Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 2c6d436

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/17677-a99fa067d7ed71c9@postgresql.org
1 parent 8117326 commit 2c6d436

File tree

4 files changed

+37
-3
lines changed

4 files changed

+37
-3
lines changed

src/backend/commands/dbcommands.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
815815
}
816816
else if (strcmp(defel->defname, "oid") == 0)
817817
{
818-
dboid = defGetInt32(defel);
818+
dboid = defGetObjectId(defel);
819819

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

src/backend/commands/define.c

Lines changed: 33 additions & 0 deletions
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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11067,9 +11067,9 @@ createdb_opt_items:
1106711067
;
1106811068

1106911069
createdb_opt_item:
11070-
createdb_opt_name opt_equal SignedIconst
11070+
createdb_opt_name opt_equal NumericOnly
1107111071
{
11072-
$$ = makeDefElem($1, (Node *) makeInteger($3), @1);
11072+
$$ = makeDefElem($1, $3, @1);
1107311073
}
1107411074
| createdb_opt_name opt_equal opt_boolean_or_string
1107511075
{

src/include/commands/defrem.h

Lines changed: 1 addition & 0 deletions
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)