Commit 465d7e18 authored by Tom Lane's avatar Tom Lane

Make CREATE TYPE print warnings if a datatype's I/O functions are volatile.

This is a followup to commit 43ac12c6,
which added regression tests checking that I/O functions of built-in
types are not marked volatile.  Complaining in CREATE TYPE should push
developers of add-on types to fix any misdeclared functions in their
types.  It's just a warning not an error, to avoid creating upgrade
problems for what might be just cosmetic mis-markings.

Aside from adding the warning code, fix a number of types that were
sloppily created in the regression tests.
parent 66c029c8
...@@ -547,6 +547,52 @@ DefineType(List *names, List *parameters) ...@@ -547,6 +547,52 @@ DefineType(List *names, List *parameters)
NameListToString(analyzeName)); NameListToString(analyzeName));
#endif #endif
/*
* Print warnings if any of the type's I/O functions are marked volatile.
* There is a general assumption that I/O functions are stable or
* immutable; this allows us for example to mark record_in/record_out
* stable rather than volatile. Ideally we would throw errors not just
* warnings here; but since this check is new as of 9.5, and since the
* volatility marking might be just an error-of-omission and not a true
* indication of how the function behaves, we'll let it pass as a warning
* for now.
*/
if (inputOid && func_volatile(inputOid) == PROVOLATILE_VOLATILE)
ereport(WARNING,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("type input function %s should not be volatile",
NameListToString(inputName))));
if (outputOid && func_volatile(outputOid) == PROVOLATILE_VOLATILE)
ereport(WARNING,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("type output function %s should not be volatile",
NameListToString(outputName))));
if (receiveOid && func_volatile(receiveOid) == PROVOLATILE_VOLATILE)
ereport(WARNING,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("type receive function %s should not be volatile",
NameListToString(receiveName))));
if (sendOid && func_volatile(sendOid) == PROVOLATILE_VOLATILE)
ereport(WARNING,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("type send function %s should not be volatile",
NameListToString(sendName))));
if (typmodinOid && func_volatile(typmodinOid) == PROVOLATILE_VOLATILE)
ereport(WARNING,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("type modifier input function %s should not be volatile",
NameListToString(typmodinName))));
if (typmodoutOid && func_volatile(typmodoutOid) == PROVOLATILE_VOLATILE)
ereport(WARNING,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("type modifier output function %s should not be volatile",
NameListToString(typmodoutName))));
/*
* OK, we're done checking, time to make the type. We must assign the
* array type OID ahead of calling TypeCreate, since the base type and
* array type each refer to the other.
*/
array_oid = AssignTypeArrayOid(); array_oid = AssignTypeArrayOid();
/* /*
......
...@@ -6,12 +6,12 @@ CREATE TYPE casttesttype; ...@@ -6,12 +6,12 @@ CREATE TYPE casttesttype;
CREATE FUNCTION casttesttype_in(cstring) CREATE FUNCTION casttesttype_in(cstring)
RETURNS casttesttype RETURNS casttesttype
AS 'textin' AS 'textin'
LANGUAGE internal STRICT; LANGUAGE internal STRICT IMMUTABLE;
NOTICE: return type casttesttype is only a shell NOTICE: return type casttesttype is only a shell
CREATE FUNCTION casttesttype_out(casttesttype) CREATE FUNCTION casttesttype_out(casttesttype)
RETURNS cstring RETURNS cstring
AS 'textout' AS 'textout'
LANGUAGE internal STRICT; LANGUAGE internal STRICT IMMUTABLE;
NOTICE: argument type casttesttype is only a shell NOTICE: argument type casttesttype is only a shell
CREATE TYPE casttesttype ( CREATE TYPE casttesttype (
internallength = variable, internallength = variable,
......
...@@ -41,22 +41,22 @@ CREATE TYPE text_w_default; ...@@ -41,22 +41,22 @@ CREATE TYPE text_w_default;
CREATE FUNCTION int42_in(cstring) CREATE FUNCTION int42_in(cstring)
RETURNS int42 RETURNS int42
AS 'int4in' AS 'int4in'
LANGUAGE internal STRICT; LANGUAGE internal STRICT IMMUTABLE;
NOTICE: return type int42 is only a shell NOTICE: return type int42 is only a shell
CREATE FUNCTION int42_out(int42) CREATE FUNCTION int42_out(int42)
RETURNS cstring RETURNS cstring
AS 'int4out' AS 'int4out'
LANGUAGE internal STRICT; LANGUAGE internal STRICT IMMUTABLE;
NOTICE: argument type int42 is only a shell NOTICE: argument type int42 is only a shell
CREATE FUNCTION text_w_default_in(cstring) CREATE FUNCTION text_w_default_in(cstring)
RETURNS text_w_default RETURNS text_w_default
AS 'textin' AS 'textin'
LANGUAGE internal STRICT; LANGUAGE internal STRICT IMMUTABLE;
NOTICE: return type text_w_default is only a shell NOTICE: return type text_w_default is only a shell
CREATE FUNCTION text_w_default_out(text_w_default) CREATE FUNCTION text_w_default_out(text_w_default)
RETURNS cstring RETURNS cstring
AS 'textout' AS 'textout'
LANGUAGE internal STRICT; LANGUAGE internal STRICT IMMUTABLE;
NOTICE: argument type text_w_default is only a shell NOTICE: argument type text_w_default is only a shell
CREATE TYPE int42 ( CREATE TYPE int42 (
internallength = 4, internallength = 4,
......
...@@ -5,22 +5,22 @@ ...@@ -5,22 +5,22 @@
CREATE FUNCTION widget_in(cstring) CREATE FUNCTION widget_in(cstring)
RETURNS widget RETURNS widget
AS '@libdir@/regress@DLSUFFIX@' AS '@libdir@/regress@DLSUFFIX@'
LANGUAGE C STRICT; LANGUAGE C STRICT IMMUTABLE;
CREATE FUNCTION widget_out(widget) CREATE FUNCTION widget_out(widget)
RETURNS cstring RETURNS cstring
AS '@libdir@/regress@DLSUFFIX@' AS '@libdir@/regress@DLSUFFIX@'
LANGUAGE C STRICT; LANGUAGE C STRICT IMMUTABLE;
CREATE FUNCTION int44in(cstring) CREATE FUNCTION int44in(cstring)
RETURNS city_budget RETURNS city_budget
AS '@libdir@/regress@DLSUFFIX@' AS '@libdir@/regress@DLSUFFIX@'
LANGUAGE C STRICT; LANGUAGE C STRICT IMMUTABLE;
CREATE FUNCTION int44out(city_budget) CREATE FUNCTION int44out(city_budget)
RETURNS cstring RETURNS cstring
AS '@libdir@/regress@DLSUFFIX@' AS '@libdir@/regress@DLSUFFIX@'
LANGUAGE C STRICT; LANGUAGE C STRICT IMMUTABLE;
CREATE FUNCTION check_primary_key () CREATE FUNCTION check_primary_key ()
RETURNS trigger RETURNS trigger
......
...@@ -4,24 +4,24 @@ ...@@ -4,24 +4,24 @@
CREATE FUNCTION widget_in(cstring) CREATE FUNCTION widget_in(cstring)
RETURNS widget RETURNS widget
AS '@libdir@/regress@DLSUFFIX@' AS '@libdir@/regress@DLSUFFIX@'
LANGUAGE C STRICT; LANGUAGE C STRICT IMMUTABLE;
NOTICE: type "widget" is not yet defined NOTICE: type "widget" is not yet defined
DETAIL: Creating a shell type definition. DETAIL: Creating a shell type definition.
CREATE FUNCTION widget_out(widget) CREATE FUNCTION widget_out(widget)
RETURNS cstring RETURNS cstring
AS '@libdir@/regress@DLSUFFIX@' AS '@libdir@/regress@DLSUFFIX@'
LANGUAGE C STRICT; LANGUAGE C STRICT IMMUTABLE;
NOTICE: argument type widget is only a shell NOTICE: argument type widget is only a shell
CREATE FUNCTION int44in(cstring) CREATE FUNCTION int44in(cstring)
RETURNS city_budget RETURNS city_budget
AS '@libdir@/regress@DLSUFFIX@' AS '@libdir@/regress@DLSUFFIX@'
LANGUAGE C STRICT; LANGUAGE C STRICT IMMUTABLE;
NOTICE: type "city_budget" is not yet defined NOTICE: type "city_budget" is not yet defined
DETAIL: Creating a shell type definition. DETAIL: Creating a shell type definition.
CREATE FUNCTION int44out(city_budget) CREATE FUNCTION int44out(city_budget)
RETURNS cstring RETURNS cstring
AS '@libdir@/regress@DLSUFFIX@' AS '@libdir@/regress@DLSUFFIX@'
LANGUAGE C STRICT; LANGUAGE C STRICT IMMUTABLE;
NOTICE: argument type city_budget is only a shell NOTICE: argument type city_budget is only a shell
CREATE FUNCTION check_primary_key () CREATE FUNCTION check_primary_key ()
RETURNS trigger RETURNS trigger
......
...@@ -8,11 +8,11 @@ CREATE TYPE casttesttype; ...@@ -8,11 +8,11 @@ CREATE TYPE casttesttype;
CREATE FUNCTION casttesttype_in(cstring) CREATE FUNCTION casttesttype_in(cstring)
RETURNS casttesttype RETURNS casttesttype
AS 'textin' AS 'textin'
LANGUAGE internal STRICT; LANGUAGE internal STRICT IMMUTABLE;
CREATE FUNCTION casttesttype_out(casttesttype) CREATE FUNCTION casttesttype_out(casttesttype)
RETURNS cstring RETURNS cstring
AS 'textout' AS 'textout'
LANGUAGE internal STRICT; LANGUAGE internal STRICT IMMUTABLE;
CREATE TYPE casttesttype ( CREATE TYPE casttesttype (
internallength = variable, internallength = variable,
......
...@@ -44,19 +44,19 @@ CREATE TYPE text_w_default; ...@@ -44,19 +44,19 @@ CREATE TYPE text_w_default;
CREATE FUNCTION int42_in(cstring) CREATE FUNCTION int42_in(cstring)
RETURNS int42 RETURNS int42
AS 'int4in' AS 'int4in'
LANGUAGE internal STRICT; LANGUAGE internal STRICT IMMUTABLE;
CREATE FUNCTION int42_out(int42) CREATE FUNCTION int42_out(int42)
RETURNS cstring RETURNS cstring
AS 'int4out' AS 'int4out'
LANGUAGE internal STRICT; LANGUAGE internal STRICT IMMUTABLE;
CREATE FUNCTION text_w_default_in(cstring) CREATE FUNCTION text_w_default_in(cstring)
RETURNS text_w_default RETURNS text_w_default
AS 'textin' AS 'textin'
LANGUAGE internal STRICT; LANGUAGE internal STRICT IMMUTABLE;
CREATE FUNCTION text_w_default_out(text_w_default) CREATE FUNCTION text_w_default_out(text_w_default)
RETURNS cstring RETURNS cstring
AS 'textout' AS 'textout'
LANGUAGE internal STRICT; LANGUAGE internal STRICT IMMUTABLE;
CREATE TYPE int42 ( CREATE TYPE int42 (
internallength = 4, internallength = 4,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment