From d2db166c7527552cc0ee6121fb32d11e14d36e97 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 4 Oct 2002 22:08:44 +0000 Subject: [PATCH] Require superuser privilege to create a binary-compatible cast, per discussion some weeks ago. Also, add a check that two types to be binary-equivalenced match as to typlen, typbyval, and typalign; if they don't then it's surely a mistake to equivalence them. --- doc/src/sgml/ref/create_cast.sgml | 9 +++++---- src/backend/commands/functioncmds.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/doc/src/sgml/ref/create_cast.sgml b/doc/src/sgml/ref/create_cast.sgml index e64d696f81..172b988a6a 100644 --- a/doc/src/sgml/ref/create_cast.sgml +++ b/doc/src/sgml/ref/create_cast.sgml @@ -1,4 +1,4 @@ - + @@ -81,10 +81,9 @@ SELECT 'The time is ' || now(); will be allowed only if the cast from type timestamp to text is marked AS IMPLICIT. Otherwise it - will be necessary to write one of + will be necessary to write the cast explicitly, for example SELECT 'The time is ' || CAST(now() AS text); -SELECT 'The time is ' || now()::text; (We generally use the term implicit cast to describe this kind of cast.) @@ -107,7 +106,9 @@ SELECT 'The time is ' || now()::text; To be able to create a cast, you must own the source or the target - data type. + data type. To create a binary-compatible cast, you must be superuser + (this restriction is made because an erroneous binary-compatible cast + conversion can easily crash the server). diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 7857eb3bb3..01217d9b12 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.22 2002/09/21 18:39:25 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.23 2002/10/04 22:08:44 tgl Exp $ * * DESCRIPTION * These routines take the parse tree and pick out the @@ -756,8 +756,35 @@ CreateCast(CreateCastStmt *stmt) } else { + int16 typ1len; + int16 typ2len; + bool typ1byval; + bool typ2byval; + char typ1align; + char typ2align; + /* indicates binary coercibility */ funcid = InvalidOid; + + /* + * Must be superuser to create binary-compatible casts, since + * erroneous casts can easily crash the backend. + */ + if (!superuser()) + elog(ERROR, "Must be superuser to create a cast WITHOUT FUNCTION"); + + /* + * Also, insist that the types match as to size, alignment, and + * pass-by-value attributes; this provides at least a crude check + * that they have similar representations. A pair of types that + * fail this test should certainly not be equated. + */ + get_typlenbyvalalign(sourcetypeid, &typ1len, &typ1byval, &typ1align); + get_typlenbyvalalign(targettypeid, &typ2len, &typ2byval, &typ2align); + if (typ1len != typ2len || + typ1byval != typ2byval || + typ1align != typ2align) + elog(ERROR, "source and target datatypes are not physically compatible"); } /* convert CoercionContext enum to char value for castcontext */