1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-11 20:28:21 +03:00

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
This commit is contained in:
Peter Eisentraut
2015-04-26 10:33:14 -04:00
parent f320cbb615
commit cac7658205
101 changed files with 6034 additions and 2811 deletions

6
contrib/ltree_plpython/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
# Generated subdirectories
/expected/python3/
/log/
/results/
/sql/python3/
/tmp_check/

View File

@ -0,0 +1,31 @@
# contrib/ltree_plpython/Makefile
MODULE_big = ltree_plpython$(python_majorversion)
OBJS = ltree_plpython.o
PG_CPPFLAGS = -I$(top_srcdir)/src/pl/plpython $(python_includespec) -I$(top_srcdir)/contrib/ltree
EXTENSION = ltree_plpythonu ltree_plpython2u ltree_plpython3u
DATA = ltree_plpythonu--1.0.sql ltree_plpython2u--1.0.sql ltree_plpython3u--1.0.sql
REGRESS = ltree_plpython
REGRESS_PLPYTHON3_MANGLE := $(REGRESS)
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/ltree_plpython
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif
REGRESS_OPTS = --load-extension=ltree
ifeq ($(python_majorversion),2)
REGRESS_OPTS += --load-extension=plpythonu --load-extension=ltree_plpythonu
endif
EXTRA_INSTALL = contrib/ltree
include $(top_srcdir)/src/pl/plpython/regress-python3-mangle.mk

View File

@ -0,0 +1,45 @@
CREATE EXTENSION plpython2u;
CREATE EXTENSION ltree_plpython2u;
CREATE FUNCTION test1(val ltree) RETURNS int
LANGUAGE plpythonu
TRANSFORM FOR TYPE ltree
AS $$
plpy.info(repr(val))
return len(val)
$$;
SELECT test1('aa.bb.cc'::ltree);
INFO: ['aa', 'bb', 'cc']
CONTEXT: PL/Python function "test1"
test1
-------
3
(1 row)
CREATE FUNCTION test1n(val ltree) RETURNS int
LANGUAGE plpython2u
TRANSFORM FOR TYPE ltree
AS $$
plpy.info(repr(val))
return len(val)
$$;
SELECT test1n('aa.bb.cc'::ltree);
INFO: ['aa', 'bb', 'cc']
CONTEXT: PL/Python function "test1n"
test1n
--------
3
(1 row)
CREATE FUNCTION test2() RETURNS ltree
LANGUAGE plpythonu
TRANSFORM FOR TYPE ltree
AS $$
return ['foo', 'bar', 'baz']
$$;
-- plpython to ltree is not yet implemented, so this will fail,
-- because it will try to parse the Python list as an ltree input
-- string.
SELECT test2();
ERROR: syntax error at position 0
CONTEXT: while creating return value
PL/Python function "test2"

View File

@ -0,0 +1,32 @@
#include "postgres.h"
#include "fmgr.h"
#include "plpython.h"
#include "ltree.h"
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(ltree_to_plpython);
Datum ltree_to_plpython(PG_FUNCTION_ARGS);
Datum
ltree_to_plpython(PG_FUNCTION_ARGS)
{
ltree *in = PG_GETARG_LTREE(0);
int i;
PyObject *list;
ltree_level *curlevel;
list = PyList_New(in->numlevel);
curlevel = LTREE_FIRST(in);
for (i = 0; i < in->numlevel; i++)
{
PyList_SetItem(list, i, PyString_FromStringAndSize(curlevel->name, curlevel->len));
curlevel = LEVEL_NEXT(curlevel);
}
PG_FREE_IF_COPY(in, 0);
return PointerGetDatum(list);
}

View File

@ -0,0 +1,12 @@
-- make sure the prerequisite libraries are loaded
DO '1' LANGUAGE plpython2u;
SELECT NULL::ltree;
CREATE FUNCTION ltree_to_plpython2(val internal) RETURNS internal
LANGUAGE C STRICT IMMUTABLE
AS 'MODULE_PATHNAME', 'ltree_to_plpython';
CREATE TRANSFORM FOR ltree LANGUAGE plpython2u (
FROM SQL WITH FUNCTION ltree_to_plpython2(internal)
);

View File

@ -0,0 +1,6 @@
# ltree_plpython2u extension
comment = 'transform between ltree and plpython2u'
default_version = '1.0'
module_pathname = '$libdir/ltree_plpython2'
relocatable = true
requires = 'ltree,plpython2u'

View File

@ -0,0 +1,12 @@
-- make sure the prerequisite libraries are loaded
DO '1' LANGUAGE plpython3u;
SELECT NULL::ltree;
CREATE FUNCTION ltree_to_plpython3(val internal) RETURNS internal
LANGUAGE C STRICT IMMUTABLE
AS 'MODULE_PATHNAME', 'ltree_to_plpython';
CREATE TRANSFORM FOR ltree LANGUAGE plpython3u (
FROM SQL WITH FUNCTION ltree_to_plpython3(internal)
);

View File

@ -0,0 +1,6 @@
# ltree_plpython3u extension
comment = 'transform between ltree and plpython3u'
default_version = '1.0'
module_pathname = '$libdir/ltree_plpython3'
relocatable = true
requires = 'ltree,plpython3u'

View File

@ -0,0 +1,12 @@
-- make sure the prerequisite libraries are loaded
DO '1' LANGUAGE plpythonu;
SELECT NULL::ltree;
CREATE FUNCTION ltree_to_plpython(val internal) RETURNS internal
LANGUAGE C STRICT IMMUTABLE
AS 'MODULE_PATHNAME';
CREATE TRANSFORM FOR ltree LANGUAGE plpythonu (
FROM SQL WITH FUNCTION ltree_to_plpython(internal)
);

View File

@ -0,0 +1,6 @@
# ltree_plpythonu extension
comment = 'transform between ltree and plpythonu'
default_version = '1.0'
module_pathname = '$libdir/ltree_plpython2'
relocatable = true
requires = 'ltree,plpythonu'

View File

@ -0,0 +1,37 @@
CREATE EXTENSION plpython2u;
CREATE EXTENSION ltree_plpython2u;
CREATE FUNCTION test1(val ltree) RETURNS int
LANGUAGE plpythonu
TRANSFORM FOR TYPE ltree
AS $$
plpy.info(repr(val))
return len(val)
$$;
SELECT test1('aa.bb.cc'::ltree);
CREATE FUNCTION test1n(val ltree) RETURNS int
LANGUAGE plpython2u
TRANSFORM FOR TYPE ltree
AS $$
plpy.info(repr(val))
return len(val)
$$;
SELECT test1n('aa.bb.cc'::ltree);
CREATE FUNCTION test2() RETURNS ltree
LANGUAGE plpythonu
TRANSFORM FOR TYPE ltree
AS $$
return ['foo', 'bar', 'baz']
$$;
-- plpython to ltree is not yet implemented, so this will fail,
-- because it will try to parse the Python list as an ltree input
-- string.
SELECT test2();