From cac76582053ef8ea07df65fed0757f352da23705 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut
Date: Sun, 26 Apr 2015 10:33:14 -0400
Subject: Add transforms feature
This provides a mechanism for specifying conversions between SQL data
types and procedural languages. As examples, there are transforms
for hstore and ltree for PL/Perl and PL/Python.
reviews by Pavel Stěhule and Andres Freund
---
doc/src/sgml/catalogs.sgml | 82 +++++++++++++
doc/src/sgml/hstore.sgml | 19 +++
doc/src/sgml/information_schema.sgml | 85 ++++++++++++++
doc/src/sgml/ltree.sgml | 15 +++
doc/src/sgml/ref/allfiles.sgml | 2 +
doc/src/sgml/ref/alter_extension.sgml | 21 ++++
doc/src/sgml/ref/comment.sgml | 22 ++++
doc/src/sgml/ref/create_function.sgml | 18 +++
doc/src/sgml/ref/create_transform.sgml | 207 +++++++++++++++++++++++++++++++++
doc/src/sgml/ref/drop_transform.sgml | 123 ++++++++++++++++++++
doc/src/sgml/reference.sgml | 2 +
11 files changed, 596 insertions(+)
create mode 100644 doc/src/sgml/ref/create_transform.sgml
create mode 100644 doc/src/sgml/ref/drop_transform.sgml
(limited to 'doc/src')
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 4e6fd0e06fb..898865eea19 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -273,6 +273,11 @@
tablespaces within this database cluster
+
+ pg_transform
+ transforms (data type to procedural language conversions)
+
+
pg_triggertriggers
@@ -5071,6 +5076,15 @@
+
+ protrftypes
+ oid[]
+
+
+ Data type OIDs for which to apply transforms.
+
+
+
prosrctext
@@ -6071,6 +6085,74 @@
+
+ pg_transform
+
+
+ pg_transform
+
+
+
+ The catalog pg_transform stores information about
+ transforms, which are a mechanism to adapt data types to procedural
+ languages. See for more information.
+
+
+
+ pg_transform> Columns
+
+
+
+
+ Name
+ Type
+ References
+ Description
+
+
+
+
+
+ trftype
+ oid
+ pg_type.oid
+ OID of the data type this transform is for
+
+
+
+ trflang
+ oid
+ pg_language.oid
+ OID of the language this transform is for
+
+
+
+ trffromsql
+ regproc
+ pg_proc.oid
+
+ The OID of the function to use when converting the data type for input
+ to the procedural language (e.g., function parameters). Zero is stored
+ if this operation is not supported.
+
+
+
+
+ trftosql
+ regproc
+ pg_proc.oid
+
+ The OID of the function to use when converting output from the
+ procedural language (e.g., return values) to the data type. Zero is
+ stored if this operation is not supported.
+
+
+
+
+
+
+
+
pg_trigger
diff --git a/doc/src/sgml/hstore.sgml b/doc/src/sgml/hstore.sgml
index fbe9543dfea..94f01f8dfe7 100644
--- a/doc/src/sgml/hstore.sgml
+++ b/doc/src/sgml/hstore.sgml
@@ -596,6 +596,25 @@ ALTER TABLE tablename ALTER hstorecol TYPE hstore USING hstorecol || '';
+
+ Transforms
+
+
+ Additional extensions are available that implement transforms for
+ the hstore type for the languages PL/Perl and PL/Python. The
+ extensions for PL/Perl are called hstore_plperl
+ and hstore_plperlu, for trusted and untrusted PL/Perl.
+ If you install these transforms and specify them when creating a
+ function, hstore values are mapped to Perl hashes. The
+ extensions for PL/Python are
+ called hstore_plpythonu, hstore_plpython2u,
+ and hstore_plpython3u
+ (see for the PL/Python naming
+ convention). If you use them, hstore values are mapped to
+ Python dictionaries.
+
+
+
Authors
diff --git a/doc/src/sgml/information_schema.sgml b/doc/src/sgml/information_schema.sgml
index 22f43c8a5bf..ca1f20b3385 100644
--- a/doc/src/sgml/information_schema.sgml
+++ b/doc/src/sgml/information_schema.sgml
@@ -5519,6 +5519,91 @@ ORDER BY c.ordinal_position;
+
+ transforms
+
+
+ The view transforms contains information about the
+ transforms defined in the current database. More precisely, it contains a
+ row for each function contained in a transform (the from SQL
+ or to SQL function).
+
+
+
+ transforms Columns
+
+
+
+
+ Name
+ Data Type
+ Description
+
+
+
+
+
+ udt_catalog
+ sql_identifier
+ Name of the database that contains the type the transform is for (always the current database)
+
+
+
+ udt_schema
+ sql_identifier
+ Name of the schema that contains the type the transform is for
+
+
+
+ udt_name
+ sql_identifier
+ Name of the type the transform is for
+
+
+
+ specific_catalog
+ sql_identifier
+ Name of the database containing the function (always the current database)
+
+
+
+ specific_schema
+ sql_identifier
+ Name of the schema containing the function
+
+
+
+ specific_name
+ sql_identifier
+
+ The specific name of the function. See for more information.
+
+
+
+
+ group_name
+ sql_identifier
+
+ The SQL standard allows defining transforms in groups,
+ and selecting a group at run time. PostgreSQL does not support this.
+ Instead, transforms are specific to a language. As a compromise, this
+ field contains the language the transform is for.
+
+
+
+
+ transform_type
+ character_data
+
+ FROM SQL or TO SQL
+
+
+
+
+
+
+
triggered_update_columns
diff --git a/doc/src/sgml/ltree.sgml b/doc/src/sgml/ltree.sgml
index cd8a061c943..3f87319bf96 100644
--- a/doc/src/sgml/ltree.sgml
+++ b/doc/src/sgml/ltree.sgml
@@ -664,6 +664,21 @@ ltreetest=> SELECT ins_label(path,2,'Space') FROM test WHERE path <@ 'Top.
+
+ Transforms
+
+
+ Additional extensions are available that implement transforms for
+ the ltree type for PL/Python. The extensions are
+ called ltree_plpythonu, ltree_plpython2u,
+ and ltree_plpython3u
+ (see for the PL/Python naming
+ convention). If you install these transforms and specify them when
+ creating a function, ltree values are mapped to Python lists.
+ (The reverse is currently not supported, however.)
+
+
+
Authors
diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml
index f09fc250f08..bf95453b6c6 100644
--- a/doc/src/sgml/ref/allfiles.sgml
+++ b/doc/src/sgml/ref/allfiles.sgml
@@ -79,6 +79,7 @@ Complete list of usable sgml source files in this directory.
+
@@ -120,6 +121,7 @@ Complete list of usable sgml source files in this directory.
+
diff --git a/doc/src/sgml/ref/alter_extension.sgml b/doc/src/sgml/ref/alter_extension.sgml
index 0d479c8ca2d..7141ee352eb 100644
--- a/doc/src/sgml/ref/alter_extension.sgml
+++ b/doc/src/sgml/ref/alter_extension.sgml
@@ -52,6 +52,7 @@ ALTER EXTENSION name DROP object_name |
TEXT SEARCH PARSER object_name |
TEXT SEARCH TEMPLATE object_name |
+ TRANSFORM FOR type_name LANGUAGE lang_name |
TYPE object_name |
VIEW object_name
@@ -259,6 +260,26 @@ ALTER EXTENSION name DROP
+
+
+ type_name
+
+
+
+ The name of the data type of the transform.
+
+
+
+
+
+ lang_name
+
+
+
+ The name of the language of the transform.
+
+
+
diff --git a/doc/src/sgml/ref/comment.sgml b/doc/src/sgml/ref/comment.sgml
index 62e1968c08d..656f5aae5ba 100644
--- a/doc/src/sgml/ref/comment.sgml
+++ b/doc/src/sgml/ref/comment.sgml
@@ -55,6 +55,7 @@ COMMENT ON
TEXT SEARCH DICTIONARY object_name |
TEXT SEARCH PARSER object_name |
TEXT SEARCH TEMPLATE object_name |
+ TRANSFORM FOR type_name LANGUAGE lang_name |
TRIGGER trigger_name ON table_name |
TYPE object_name |
VIEW object_name
@@ -225,6 +226,26 @@ COMMENT ON
+
+ type_name
+
+
+
+ The name of the data type of the transform.
+
+
+
+
+
+ lang_name
+
+
+
+ The name of the language of the transform.
+
+
+
+
text
@@ -305,6 +326,7 @@ COMMENT ON TEXT SEARCH CONFIGURATION my_config IS 'Special word filtering';
COMMENT ON TEXT SEARCH DICTIONARY swedish IS 'Snowball stemmer for Swedish language';
COMMENT ON TEXT SEARCH PARSER my_parser IS 'Splits text into words';
COMMENT ON TEXT SEARCH TEMPLATE snowball IS 'Snowball stemmer';
+COMMENT ON TRANSFORM FOR hstore LANGUAGE plpythonu IS 'Transform between hstore and Python dict';
COMMENT ON TRIGGER my_trigger ON my_table IS 'Used for RI';
COMMENT ON TYPE complex IS 'Complex number data type';
COMMENT ON VIEW my_view IS 'View of departmental costs';
diff --git a/doc/src/sgml/ref/create_function.sgml b/doc/src/sgml/ref/create_function.sgml
index 20019215351..c5beb166cfa 100644
--- a/doc/src/sgml/ref/create_function.sgml
+++ b/doc/src/sgml/ref/create_function.sgml
@@ -25,6 +25,7 @@ CREATE [ OR REPLACE ] FUNCTION
[ RETURNS rettype
| RETURNS TABLE ( column_namecolumn_type [, ...] ) ]
{ LANGUAGE lang_name
+ | TRANSFORM { FOR TYPE type_name } [, ... ]
| WINDOW
| IMMUTABLE | STABLE | VOLATILE | [ NOT ] LEAKPROOF
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
@@ -260,6 +261,23 @@ CREATE [ OR REPLACE ] FUNCTION
+
+ TRANSFORM { FOR TYPE type_name } [, ... ] }
+
+
+
+ Lists which transforms a call to the function should apply. Transforms
+ convert between SQL types and language-specific data types;
+ see . Procedural language
+ implementations usually have hardcoded knowledge of the built-in types,
+ so those don't need to be listed here. If a procedural language
+ implementation does not know how to handle a type and no transform is
+ supplied, it will fall back to a default behavior for converting data
+ types, but this depends on the implementation.
+
+
+
+
WINDOW
diff --git a/doc/src/sgml/ref/create_transform.sgml b/doc/src/sgml/ref/create_transform.sgml
new file mode 100644
index 00000000000..d321dad7a56
--- /dev/null
+++ b/doc/src/sgml/ref/create_transform.sgml
@@ -0,0 +1,207 @@
+
+
+
+
+ CREATE TRANSFORM
+
+
+
+ CREATE TRANSFORM
+ 7
+ SQL - Language Statements
+
+
+
+ CREATE TRANSFORM
+ define a new transform
+
+
+
+
+CREATE [ OR REPLACE ] TRANSFORM FOR type_name LANGUAGE lang_name (
+ FROM SQL WITH FUNCTION from_sql_function_name (argument_type [, ...]),
+ TO SQL WITH FUNCTION to_sql_function_name (argument_type [, ...])
+);
+
+
+
+
+ Description
+
+
+ CREATE TRANSFORM defines a new transform.
+ CREATE OR REPLACE TRANSFORM will either create a new
+ transform, or replace an existing definition.
+
+
+
+ A transform specifies how to adapt a data type to a procedural language.
+ For example, when writing a function in PL/Python using
+ the hstore type, PL/Python has no prior knowledge how to
+ present hstore values in the Python environment. Language
+ implementations usually default to using the text representation, but that
+ is inconvenient when, for example, an associative array or a list would be
+ more appropriate.
+
+
+
+ A transform specifies two functions:
+
+
+
+ A from SQL function that converts the type from the SQL
+ environment to the language. This function will be invoked on the
+ arguments of a function written in the language.
+
+
+
+
+
+ A to SQL function that converts the type from the
+ language to the SQL environment. This function will be invoked on the
+ return value of a function written in the language.
+
+
+
+ It is not necessary to provide both of these functions. If one is not
+ specified, the language-specific default behavior will be used if
+ necessary. (To prevent a transformation in a certain direction from
+ happening at all, you could also write a transform function that always
+ errors out.)
+
+
+
+ To be able to create a transform, you must own and
+ have USAGE privilege on the type, have
+ USAGE privilege on the language, and own and
+ have EXECUTE privilege on the from-SQL and to-SQL
+ functions, if specified.
+
+
+
+
+ Parameters
+
+
+
+ type_name
+
+
+
+ The name of the data type of the transform.
+
+
+
+
+
+ lang_name
+
+
+
+ The name of the language of the transform.
+
+
+
+
+
+ from_sql_function_name(argument_type [, ...])
+
+
+
+ The name of the function for converting the type from the SQL
+ environment to the language. It must take one argument of
+ type internal and return type internal. The
+ actual argument will be of the type for the transform, and the function
+ should be coded as if it were. (But it is not allowed to declare an
+ SQL-level function function returning internal without at
+ least one argument of type internal.) The actual return
+ value will be something specific to the language implementation.
+
+
+
+
+
+ to_sql_function_name(argument_type [, ...])
+
+
+
+ The name of the function for converting the type from the language to
+ the SQL environment. It must take one argument of type
+ internal and return the type that is the type for the
+ transform. The actual argument value will be something specific to the
+ language implementation.
+
+
+
+
+
+
+
+ Notes
+
+
+ Use to remove transforms.
+
+
+
+
+ Examples
+
+
+ To create a transform for type hstore and language
+ plpythonu, first set up the type and the language:
+
+CREATE TYPE hstore ...;
+
+CREATE LANGUAGE plpythonu ...;
+
+ Then create the necessary functions:
+
+CREATE FUNCTION hstore_to_plpython(val internal) RETURNS internal
+LANGUAGE C STRICT IMMUTABLE
+AS ...;
+
+CREATE FUNCTION plpython_to_hstore(val internal) RETURNS hstore
+LANGUAGE C STRICT IMMUTABLE
+AS ...;
+
+ And finally create the transform to connect them all together:
+
+CREATE TRANSFORM FOR hstore LANGUAGE plpythonu (
+ FROM SQL WITH FUNCTION hstore_to_plpython(internal),
+ TO SQL WITH FUNCTION plpython_to_hstore(internal)
+);
+
+ In practice, these commands would be wrapped up in extensions.
+
+
+
+ The contrib section contains a number of extensions
+ that provide transforms, which can serve as real-world examples.
+
+
+
+
+ Compatibility
+
+
+ This form of CREATE TRANSFORM is a
+ PostgreSQL extension. There is a CREATE
+ TRANSFORM command in the SQL standard, but it
+ is for adapting data types to client languages. That usage is not supported
+ by PostgreSQL.
+
+
+
+
+ See Also
+
+
+ ,
+ ,
+ ,
+
+
+
+
+
diff --git a/doc/src/sgml/ref/drop_transform.sgml b/doc/src/sgml/ref/drop_transform.sgml
new file mode 100644
index 00000000000..59ff87cfe48
--- /dev/null
+++ b/doc/src/sgml/ref/drop_transform.sgml
@@ -0,0 +1,123 @@
+
+
+
+
+ DROP TRANSFORM
+
+
+
+ DROP TRANSFORM
+ 7
+ SQL - Language Statements
+
+
+
+ DROP TRANSFORM
+ remove a transform
+
+
+
+
+DROP TRANSFORM [ IF EXISTS ] FOR type_name LANGUAGE lang_name
+
+
+
+
+ Description
+
+
+ DROP TRANSFORM removes a previously defined transform.
+
+
+
+ To be able to drop a transform, you must own the type and the language.
+ These are the same privileges that are required to create a transform.
+
+
+
+
+ Parameters
+
+
+
+
+ IF EXISTS
+
+
+ Do not throw an error if the transform does not exist. A notice is issued
+ in this case.
+
+
+
+
+
+ type_name
+
+
+
+ The name of the data type of the transform.
+
+
+
+
+
+ lang_name
+
+
+
+ The name of the language of the transform.
+
+
+
+
+
+ CASCADE
+
+
+ Automatically drop objects that depend on the transform.
+
+
+
+
+
+ RESTRICT
+
+
+ Refuse to drop the transform if any objects depend on it. This is the
+ default.
+
+
+
+
+
+
+
+ Examples
+
+
+ To drop the transform for type hstore and language
+ plpythonu:
+
+DROP TRANSFORM FOR hstore LANGUAGE plpythonu;
+
+
+
+
+ Compatibility
+
+
+ This form of DROP TRANSFORM is a
+ PostgreSQL extension. See for details.
+
+
+
+
+ See Also
+
+
+
+
+
+
+
diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml
index c52eb28c8c4..03020dfec42 100644
--- a/doc/src/sgml/reference.sgml
+++ b/doc/src/sgml/reference.sgml
@@ -111,6 +111,7 @@
&createTSDictionary;
&createTSParser;
&createTSTemplate;
+ &createTransform;
&createTrigger;
&createType;
&createUser;
@@ -152,6 +153,7 @@
&dropTSDictionary;
&dropTSParser;
&dropTSTemplate;
+ &dropTransform;
&dropTrigger;
&dropType;
&dropUser;
--
cgit v1.2.3