NameListToString(analyzeName));
#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();
/*
CREATE FUNCTION casttesttype_in(cstring)
RETURNS casttesttype
AS 'textin'
- LANGUAGE internal STRICT;
+ LANGUAGE internal STRICT IMMUTABLE;
NOTICE: return type casttesttype is only a shell
CREATE FUNCTION casttesttype_out(casttesttype)
RETURNS cstring
AS 'textout'
- LANGUAGE internal STRICT;
+ LANGUAGE internal STRICT IMMUTABLE;
NOTICE: argument type casttesttype is only a shell
CREATE TYPE casttesttype (
internallength = variable,
CREATE FUNCTION int42_in(cstring)
RETURNS int42
AS 'int4in'
- LANGUAGE internal STRICT;
+ LANGUAGE internal STRICT IMMUTABLE;
NOTICE: return type int42 is only a shell
CREATE FUNCTION int42_out(int42)
RETURNS cstring
AS 'int4out'
- LANGUAGE internal STRICT;
+ LANGUAGE internal STRICT IMMUTABLE;
NOTICE: argument type int42 is only a shell
CREATE FUNCTION text_w_default_in(cstring)
RETURNS text_w_default
AS 'textin'
- LANGUAGE internal STRICT;
+ LANGUAGE internal STRICT IMMUTABLE;
NOTICE: return type text_w_default is only a shell
CREATE FUNCTION text_w_default_out(text_w_default)
RETURNS cstring
AS 'textout'
- LANGUAGE internal STRICT;
+ LANGUAGE internal STRICT IMMUTABLE;
NOTICE: argument type text_w_default is only a shell
CREATE TYPE int42 (
internallength = 4,
CREATE FUNCTION widget_in(cstring)
RETURNS widget
AS '@libdir@/regress@DLSUFFIX@'
- LANGUAGE C STRICT;
+ LANGUAGE C STRICT IMMUTABLE;
CREATE FUNCTION widget_out(widget)
RETURNS cstring
AS '@libdir@/regress@DLSUFFIX@'
- LANGUAGE C STRICT;
+ LANGUAGE C STRICT IMMUTABLE;
CREATE FUNCTION int44in(cstring)
RETURNS city_budget
AS '@libdir@/regress@DLSUFFIX@'
- LANGUAGE C STRICT;
+ LANGUAGE C STRICT IMMUTABLE;
CREATE FUNCTION int44out(city_budget)
RETURNS cstring
AS '@libdir@/regress@DLSUFFIX@'
- LANGUAGE C STRICT;
+ LANGUAGE C STRICT IMMUTABLE;
CREATE FUNCTION check_primary_key ()
RETURNS trigger
CREATE FUNCTION widget_in(cstring)
RETURNS widget
AS '@libdir@/regress@DLSUFFIX@'
- LANGUAGE C STRICT;
+ LANGUAGE C STRICT IMMUTABLE;
NOTICE: type "widget" is not yet defined
DETAIL: Creating a shell type definition.
CREATE FUNCTION widget_out(widget)
RETURNS cstring
AS '@libdir@/regress@DLSUFFIX@'
- LANGUAGE C STRICT;
+ LANGUAGE C STRICT IMMUTABLE;
NOTICE: argument type widget is only a shell
CREATE FUNCTION int44in(cstring)
RETURNS city_budget
AS '@libdir@/regress@DLSUFFIX@'
- LANGUAGE C STRICT;
+ LANGUAGE C STRICT IMMUTABLE;
NOTICE: type "city_budget" is not yet defined
DETAIL: Creating a shell type definition.
CREATE FUNCTION int44out(city_budget)
RETURNS cstring
AS '@libdir@/regress@DLSUFFIX@'
- LANGUAGE C STRICT;
+ LANGUAGE C STRICT IMMUTABLE;
NOTICE: argument type city_budget is only a shell
CREATE FUNCTION check_primary_key ()
RETURNS trigger
CREATE FUNCTION casttesttype_in(cstring)
RETURNS casttesttype
AS 'textin'
- LANGUAGE internal STRICT;
+ LANGUAGE internal STRICT IMMUTABLE;
CREATE FUNCTION casttesttype_out(casttesttype)
RETURNS cstring
AS 'textout'
- LANGUAGE internal STRICT;
+ LANGUAGE internal STRICT IMMUTABLE;
CREATE TYPE casttesttype (
internallength = variable,
CREATE FUNCTION int42_in(cstring)
RETURNS int42
AS 'int4in'
- LANGUAGE internal STRICT;
+ LANGUAGE internal STRICT IMMUTABLE;
CREATE FUNCTION int42_out(int42)
RETURNS cstring
AS 'int4out'
- LANGUAGE internal STRICT;
+ LANGUAGE internal STRICT IMMUTABLE;
CREATE FUNCTION text_w_default_in(cstring)
RETURNS text_w_default
AS 'textin'
- LANGUAGE internal STRICT;
+ LANGUAGE internal STRICT IMMUTABLE;
CREATE FUNCTION text_w_default_out(text_w_default)
RETURNS cstring
AS 'textout'
- LANGUAGE internal STRICT;
+ LANGUAGE internal STRICT IMMUTABLE;
CREATE TYPE int42 (
internallength = 4,