Rename plpython to plpythonu, and update documentation to reflect its
now-untrusted status.
This commit is contained in:
parent
219e29784d
commit
6115224448
@ -1,4 +1,4 @@
|
|||||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/plpython.sgml,v 1.16 2003/04/07 01:29:25 petere Exp $ -->
|
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/plpython.sgml,v 1.17 2003/06/30 18:31:41 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="plpython">
|
<chapter id="plpython">
|
||||||
<title>PL/Python - Python Procedural Language</title>
|
<title>PL/Python - Python Procedural Language</title>
|
||||||
@ -14,9 +14,21 @@
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
To install PL/Python in a particular database, use
|
To install PL/Python in a particular database, use
|
||||||
<literal>createlang plpython <replaceable>dbname</></literal>.
|
<literal>createlang plpythonu <replaceable>dbname</></literal>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
As of <productname>PostgreSQL</productname> 7.4,
|
||||||
|
PL/Python is only available as an <quote>untrusted</> language
|
||||||
|
(meaning it does not offer any way of restricting what users
|
||||||
|
can do in it). It has therefore been renamed to <literal>plpythonu</>.
|
||||||
|
The trusted variant <literal>plpython</> may become available again in
|
||||||
|
future, if a new secure execution mechanism is developed by the Python
|
||||||
|
community.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
<tip>
|
<tip>
|
||||||
<para>
|
<para>
|
||||||
If a language is installed into <literal>template1</>, all subsequently
|
If a language is installed into <literal>template1</>, all subsequently
|
||||||
@ -41,7 +53,7 @@
|
|||||||
<programlisting>
|
<programlisting>
|
||||||
CREATE FUNCTION myfunc(text) RETURNS text
|
CREATE FUNCTION myfunc(text) RETURNS text
|
||||||
AS 'return args[0]'
|
AS 'return args[0]'
|
||||||
LANGUAGE plpython;
|
LANGUAGE plpythonu;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
gets transformed into
|
gets transformed into
|
||||||
@ -78,6 +90,8 @@ def __plpython_procedure_myfunc_23456():
|
|||||||
available to all Python functions within a session. Use with care.
|
available to all Python functions within a session. Use with care.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<!-- NOT CORRECT ANYMORE, IS IT?
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Each function gets its own restricted execution object in the
|
Each function gets its own restricted execution object in the
|
||||||
Python interpreter, so that global data and function arguments from
|
Python interpreter, so that global data and function arguments from
|
||||||
@ -85,6 +99,9 @@ def __plpython_procedure_myfunc_23456():
|
|||||||
<function>myfunc2</function>. The exception is the data in the
|
<function>myfunc2</function>. The exception is the data in the
|
||||||
<varname>GD</varname> dictionary, as mentioned above.
|
<varname>GD</varname> dictionary, as mentioned above.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="plpython-trigger">
|
<sect1 id="plpython-trigger">
|
||||||
@ -218,11 +235,13 @@ CREATE FUNCTION usesavedplan() RETURNS trigger AS '
|
|||||||
plan = plpy.prepare("SELECT 1")
|
plan = plpy.prepare("SELECT 1")
|
||||||
SD["plan"] = plan
|
SD["plan"] = plan
|
||||||
# rest of function
|
# rest of function
|
||||||
' LANGUAGE plpython;
|
' LANGUAGE plpythonu;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
<!-- NOT CURRENTLY SUPPORTED
|
||||||
|
|
||||||
<sect1 id="plpython-trusted">
|
<sect1 id="plpython-trusted">
|
||||||
<title>Restricted Environment</title>
|
<title>Restricted Environment</title>
|
||||||
|
|
||||||
@ -245,4 +264,6 @@ CREATE FUNCTION usesavedplan() RETURNS trigger AS '
|
|||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.195 2003/06/28 00:12:40 tgl Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.196 2003/06/30 18:31:41 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<appendix id="release">
|
<appendix id="release">
|
||||||
@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
|
|||||||
worries about funny characters.
|
worries about funny characters.
|
||||||
-->
|
-->
|
||||||
<literallayout><![CDATA[
|
<literallayout><![CDATA[
|
||||||
|
PL/Python is now an untrusted language, and is renamed to 'plpythonu'
|
||||||
Dollar sign ($) is no longer allowed in operator names
|
Dollar sign ($) is no longer allowed in operator names
|
||||||
Dollar sign ($) can be a non-first character in identifiers
|
Dollar sign ($) can be a non-first character in identifiers
|
||||||
Precision in FLOAT(p) is now interpreted as bits, not decimal digits
|
Precision in FLOAT(p) is now interpreted as bits, not decimal digits
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/xplang.sgml,v 1.21 2003/04/07 01:29:26 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/xplang.sgml,v 1.22 2003/06/30 18:31:42 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="xplang">
|
<chapter id="xplang">
|
||||||
@ -109,13 +109,14 @@ CREATE <optional>TRUSTED</optional> <optional>PROCEDURAL</optional> LANGUAGE <re
|
|||||||
for languages that do not allow access to database server
|
for languages that do not allow access to database server
|
||||||
internals or the file system. The languages
|
internals or the file system. The languages
|
||||||
<application>PL/pgSQL</application>,
|
<application>PL/pgSQL</application>,
|
||||||
<application>PL/Tcl</application>,
|
<application>PL/Tcl</application>, and
|
||||||
<application>PL/Perl</application>, and
|
<application>PL/Perl</application>
|
||||||
<application>PL/Python</application> are known to be trusted;
|
are considered trusted; the languages
|
||||||
the languages <application>PL/TclU</application> and
|
<application>PL/TclU</application>,
|
||||||
<application>PL/PerlU</application> are designed to provide
|
<application>PL/PerlU</application>, and
|
||||||
unlimited functionality and should <emphasis>not</emphasis> be
|
<application>PL/PythonU</application>
|
||||||
marked trusted.
|
are designed to provide unlimited functionality and should
|
||||||
|
<emphasis>not</emphasis> be marked trusted.
|
||||||
</para>
|
</para>
|
||||||
</step>
|
</step>
|
||||||
</procedure>
|
</procedure>
|
||||||
@ -158,7 +159,7 @@ CREATE TRUSTED PROCEDURAL LANGUAGE plpgsql
|
|||||||
directory. If <application>Tcl/Tk</> support is configured in, the handlers for
|
directory. If <application>Tcl/Tk</> support is configured in, the handlers for
|
||||||
<application>PL/Tcl</> and <application>PL/TclU</> are also built and installed in the same
|
<application>PL/Tcl</> and <application>PL/TclU</> are also built and installed in the same
|
||||||
location. Likewise, the <application>PL/Perl</> and <application>PL/PerlU</> handlers are built
|
location. Likewise, the <application>PL/Perl</> and <application>PL/PerlU</> handlers are built
|
||||||
and installed if Perl support is configured, and <application>PL/Python</> is
|
and installed if Perl support is configured, and <application>PL/PythonU</> is
|
||||||
installed if Python support is configured.
|
installed if Python support is configured.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/bin/scripts/createlang.c,v 1.3 2003/06/11 05:13:12 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/bin/scripts/createlang.c,v 1.4 2003/06/30 18:31:42 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -195,16 +195,16 @@ main(int argc, char *argv[])
|
|||||||
handler = "plperl_call_handler";
|
handler = "plperl_call_handler";
|
||||||
object = "plperl";
|
object = "plperl";
|
||||||
}
|
}
|
||||||
else if (strcmp(langname, "plpython")==0)
|
else if (strcmp(langname, "plpythonu")==0)
|
||||||
{
|
{
|
||||||
trusted = true;
|
trusted = false;
|
||||||
handler = "plpython_call_handler";
|
handler = "plpython_call_handler";
|
||||||
object = "plpython";
|
object = "plpython";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, _("%s: unsupported language \"%s\"\n"), progname, langname);
|
fprintf(stderr, _("%s: unsupported language \"%s\"\n"), progname, langname);
|
||||||
fprintf(stderr, _("Supported languages are plpgsql, pltcl, pltclu, plperl, plperlu, and plpython.\n"));
|
fprintf(stderr, _("Supported languages are plpgsql, pltcl, pltclu, plperl, plperlu, and plpythonu.\n"));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
PL/Python - Python Procedural Language for PostgreSQL
|
|
||||||
-----------------------------------------------------
|
|
||||||
$Id: README,v 1.2 2001/05/14 22:06:50 petere Exp $
|
|
||||||
|
|
||||||
Installation:
|
|
||||||
|
|
||||||
configure --with-python
|
|
||||||
cd src/pl/plpython
|
|
||||||
gmake
|
|
||||||
gmake install
|
|
||||||
|
|
||||||
Test:
|
|
||||||
|
|
||||||
# have postmaster running...
|
|
||||||
gmake installcheck
|
|
||||||
|
|
||||||
Enable language:
|
|
||||||
|
|
||||||
createlang plpython dbname
|
|
||||||
|
|
||||||
|
|
||||||
Note that PL/Python is currently not built automatically because the
|
|
||||||
code is new and there are some portability issues.
|
|
||||||
|
|
||||||
A default Python installation does not provide a shared libpython
|
|
||||||
library. This is not a problem on many platforms (although it makes
|
|
||||||
things less efficient), but on some platforms (especially HP-UX) the
|
|
||||||
link will fail outright.
|
|
||||||
|
|
||||||
To create a shared libpython, see this web page for hints:
|
|
||||||
|
|
||||||
http://www.python.org/cgi-bin/faqw.py?req=show&file=faq03.030.htp
|
|
||||||
|
|
||||||
Place the resulting library in the same directory as the existing
|
|
||||||
static libpythonX.Y.a and relink plpython.
|
|
||||||
|
|
||||||
|
|
||||||
Further documentation is available in the PostgreSQL Programmer's
|
|
||||||
Guide.
|
|
@ -1,5 +1,8 @@
|
|||||||
In no particular order...
|
In no particular order...
|
||||||
|
|
||||||
|
* Develop a trusted variant of PL/Python. Now that RExec has been shown
|
||||||
|
to be full of holes, this may take a while :-(
|
||||||
|
|
||||||
* Allow arrays as function arguments and return values. (almost done)
|
* Allow arrays as function arguments and return values. (almost done)
|
||||||
|
|
||||||
* Create a new restricted execution class that will allow me to pass
|
* Create a new restricted execution class that will allow me to pass
|
||||||
@ -10,7 +13,7 @@ In no particular order...
|
|||||||
so the following will make PostgreSQL unhappy:
|
so the following will make PostgreSQL unhappy:
|
||||||
|
|
||||||
create table users (first_name text, last_name text);
|
create table users (first_name text, last_name text);
|
||||||
create function user_name(user) returns text as 'mycode' language 'plpython';
|
create function user_name(user) returns text as 'mycode' language plpython;
|
||||||
select user_name(user) from users;
|
select user_name(user) from users;
|
||||||
alter table add column user_id integer;
|
alter table add column user_id integer;
|
||||||
select user_name(user) from users;
|
select user_name(user) from users;
|
||||||
|
@ -16,24 +16,15 @@ SELECT valid_type('rick');
|
|||||||
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT read_file('/etc/passwd');
|
SELECT write_file('/tmp/plpython','Only trusted users should be able to do this!');
|
||||||
ERROR: plpython: Call of function `read_file' failed.
|
write_file
|
||||||
exceptions.IOError: can't open files in restricted mode
|
------------------------------
|
||||||
SELECT write_file('/tmp/plpython','This is very bad');
|
Wrote to file: /tmp/plpython
|
||||||
ERROR: plpython: Call of function `write_file' failed.
|
(1 row)
|
||||||
exceptions.IOError: can't open files in restricted mode
|
|
||||||
SELECT getpid();
|
SELECT read_file('/tmp/plpython');
|
||||||
ERROR: plpython: Call of function `getpid' failed.
|
read_file
|
||||||
exceptions.AttributeError: 'module' object has no attribute 'getpid'
|
-----------------------------------------------
|
||||||
SELECT uname();
|
Only trusted users should be able to do this!
|
||||||
ERROR: plpython: Call of function `uname' failed.
|
|
||||||
exceptions.AttributeError: 'module' object has no attribute 'uname'
|
|
||||||
SELECT sys_exit();
|
|
||||||
ERROR: plpython: Call of function `sys_exit' failed.
|
|
||||||
exceptions.AttributeError: 'module' object has no attribute 'exit'
|
|
||||||
SELECT sys_argv();
|
|
||||||
sys_argv
|
|
||||||
----------------
|
|
||||||
['RESTRICTED']
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ SELECT global_test_two();
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT import_fail();
|
SELECT import_fail();
|
||||||
NOTICE: ('import socket failed -- untrusted dynamic module: _socket',)
|
NOTICE: ('import socket failed -- No module named foosocket',)
|
||||||
import_fail
|
import_fail
|
||||||
--------------------
|
--------------------
|
||||||
failed as expected
|
failed as expected
|
||||||
|
@ -7,5 +7,5 @@ DROP TRIGGER users_update_trig on users ;
|
|||||||
DROP FUNCTION users_update() ;
|
DROP FUNCTION users_update() ;
|
||||||
DROP TRIGGER users_delete_trig on users ;
|
DROP TRIGGER users_delete_trig on users ;
|
||||||
DROP FUNCTION users_delete() ;
|
DROP FUNCTION users_delete() ;
|
||||||
DROP PROCEDURAL LANGUAGE 'plpython' ;
|
DROP PROCEDURAL LANGUAGE plpythonu ;
|
||||||
DROP FUNCTION plpython_call_handler() ;
|
DROP FUNCTION plpython_call_handler() ;
|
||||||
|
@ -7,7 +7,7 @@ CREATE FUNCTION global_test_one() returns text
|
|||||||
if not GD.has_key("global_test"):
|
if not GD.has_key("global_test"):
|
||||||
GD["global_test"] = "set by global_test_one"
|
GD["global_test"] = "set by global_test_one"
|
||||||
return "SD: " + SD["global_test"] + ", GD: " + GD["global_test"]'
|
return "SD: " + SD["global_test"] + ", GD: " + GD["global_test"]'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
CREATE FUNCTION global_test_two() returns text
|
CREATE FUNCTION global_test_two() returns text
|
||||||
AS
|
AS
|
||||||
@ -16,7 +16,7 @@ CREATE FUNCTION global_test_two() returns text
|
|||||||
if not GD.has_key("global_test"):
|
if not GD.has_key("global_test"):
|
||||||
GD["global_test"] = "set by global_test_two"
|
GD["global_test"] = "set by global_test_two"
|
||||||
return "SD: " + SD["global_test"] + ", GD: " + GD["global_test"]'
|
return "SD: " + SD["global_test"] + ", GD: " + GD["global_test"]'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION static_test() returns int4
|
CREATE FUNCTION static_test() returns int4
|
||||||
@ -27,7 +27,7 @@ else:
|
|||||||
SD["call"] = 1
|
SD["call"] = 1
|
||||||
return SD["call"]
|
return SD["call"]
|
||||||
'
|
'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
-- import python modules
|
-- import python modules
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ except Exception, ex:
|
|||||||
plpy.notice("import socket failed -- %s" % str(ex))
|
plpy.notice("import socket failed -- %s" % str(ex))
|
||||||
return "failed as expected"
|
return "failed as expected"
|
||||||
return "succeeded, that wasn''t supposed to happen"'
|
return "succeeded, that wasn''t supposed to happen"'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION import_succeed() returns text
|
CREATE FUNCTION import_succeed() returns text
|
||||||
@ -63,14 +63,14 @@ except Exception, ex:
|
|||||||
plpy.notice("import failed -- %s" % str(ex))
|
plpy.notice("import failed -- %s" % str(ex))
|
||||||
return "failed, that wasn''t supposed to happen"
|
return "failed, that wasn''t supposed to happen"
|
||||||
return "succeeded, as expected"'
|
return "succeeded, as expected"'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
CREATE FUNCTION import_test_one(text) RETURNS text
|
CREATE FUNCTION import_test_one(text) RETURNS text
|
||||||
AS
|
AS
|
||||||
'import sha
|
'import sha
|
||||||
digest = sha.new(args[0])
|
digest = sha.new(args[0])
|
||||||
return digest.hexdigest()'
|
return digest.hexdigest()'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
CREATE FUNCTION import_test_two(users) RETURNS text
|
CREATE FUNCTION import_test_two(users) RETURNS text
|
||||||
AS
|
AS
|
||||||
@ -78,7 +78,7 @@ CREATE FUNCTION import_test_two(users) RETURNS text
|
|||||||
plain = args[0]["fname"] + args[0]["lname"]
|
plain = args[0]["fname"] + args[0]["lname"]
|
||||||
digest = sha.new(plain);
|
digest = sha.new(plain);
|
||||||
return "sha hash of " + plain + " is " + digest.hexdigest()'
|
return "sha hash of " + plain + " is " + digest.hexdigest()'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
CREATE FUNCTION argument_test_one(users, text, text) RETURNS text
|
CREATE FUNCTION argument_test_one(users, text, text) RETURNS text
|
||||||
AS
|
AS
|
||||||
@ -89,7 +89,7 @@ for key in keys:
|
|||||||
out.append("%s: %s" % (key, args[0][key]))
|
out.append("%s: %s" % (key, args[0][key]))
|
||||||
words = args[1] + " " + args[2] + " => {" + ", ".join(out) + "}"
|
words = args[1] + " " + args[2] + " => {" + ", ".join(out) + "}"
|
||||||
return words'
|
return words'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
|
||||||
-- these triggers are dedicated to HPHC of RI who
|
-- these triggers are dedicated to HPHC of RI who
|
||||||
@ -110,7 +110,7 @@ if TD["new"]["fname"] == "william":
|
|||||||
TD["new"]["fname"] = TD["args"][0]
|
TD["new"]["fname"] = TD["args"][0]
|
||||||
rv = "MODIFY"
|
rv = "MODIFY"
|
||||||
return rv'
|
return rv'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION users_update() returns trigger
|
CREATE FUNCTION users_update() returns trigger
|
||||||
@ -119,7 +119,7 @@ CREATE FUNCTION users_update() returns trigger
|
|||||||
if TD["old"]["fname"] != TD["new"]["fname"] and TD["old"]["fname"] == TD["args"][0]:
|
if TD["old"]["fname"] != TD["new"]["fname"] and TD["old"]["fname"] == TD["args"][0]:
|
||||||
return "SKIP"
|
return "SKIP"
|
||||||
return None'
|
return None'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION users_delete() RETURNS trigger
|
CREATE FUNCTION users_delete() RETURNS trigger
|
||||||
@ -127,7 +127,7 @@ CREATE FUNCTION users_delete() RETURNS trigger
|
|||||||
'if TD["old"]["fname"] == TD["args"][0]:
|
'if TD["old"]["fname"] == TD["args"][0]:
|
||||||
return "SKIP"
|
return "SKIP"
|
||||||
return None'
|
return None'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
|
||||||
CREATE TRIGGER users_insert_trig BEFORE INSERT ON users FOR EACH ROW
|
CREATE TRIGGER users_insert_trig BEFORE INSERT ON users FOR EACH ROW
|
||||||
@ -148,19 +148,19 @@ CREATE FUNCTION nested_call_one(text) RETURNS text
|
|||||||
'q = "SELECT nested_call_two(''%s'')" % args[0]
|
'q = "SELECT nested_call_two(''%s'')" % args[0]
|
||||||
r = plpy.execute(q)
|
r = plpy.execute(q)
|
||||||
return r[0]'
|
return r[0]'
|
||||||
LANGUAGE 'plpython' ;
|
LANGUAGE plpythonu ;
|
||||||
|
|
||||||
CREATE FUNCTION nested_call_two(text) RETURNS text
|
CREATE FUNCTION nested_call_two(text) RETURNS text
|
||||||
AS
|
AS
|
||||||
'q = "SELECT nested_call_three(''%s'')" % args[0]
|
'q = "SELECT nested_call_three(''%s'')" % args[0]
|
||||||
r = plpy.execute(q)
|
r = plpy.execute(q)
|
||||||
return r[0]'
|
return r[0]'
|
||||||
LANGUAGE 'plpython' ;
|
LANGUAGE plpythonu ;
|
||||||
|
|
||||||
CREATE FUNCTION nested_call_three(text) RETURNS text
|
CREATE FUNCTION nested_call_three(text) RETURNS text
|
||||||
AS
|
AS
|
||||||
'return args[0]'
|
'return args[0]'
|
||||||
LANGUAGE 'plpython' ;
|
LANGUAGE plpythonu ;
|
||||||
|
|
||||||
-- some spi stuff
|
-- some spi stuff
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ except Exception, ex:
|
|||||||
plpy.error(str(ex))
|
plpy.error(str(ex))
|
||||||
return None
|
return None
|
||||||
'
|
'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
CREATE FUNCTION spi_prepared_plan_test_nested(text) RETURNS text
|
CREATE FUNCTION spi_prepared_plan_test_nested(text) RETURNS text
|
||||||
AS
|
AS
|
||||||
@ -191,12 +191,12 @@ except Exception, ex:
|
|||||||
plpy.error(str(ex))
|
plpy.error(str(ex))
|
||||||
return None
|
return None
|
||||||
'
|
'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
|
||||||
/* really stupid function just to get the module loaded
|
/* really stupid function just to get the module loaded
|
||||||
*/
|
*/
|
||||||
CREATE FUNCTION stupid() RETURNS text AS 'return "zarkon"' LANGUAGE 'plpython';
|
CREATE FUNCTION stupid() RETURNS text AS 'return "zarkon"' LANGUAGE plpythonu;
|
||||||
|
|
||||||
/* a typo
|
/* a typo
|
||||||
*/
|
*/
|
||||||
@ -210,7 +210,7 @@ if len(rv):
|
|||||||
return rv[0]["fname"]
|
return rv[0]["fname"]
|
||||||
return None
|
return None
|
||||||
'
|
'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
/* for what it's worth catch the exception generated by
|
/* for what it's worth catch the exception generated by
|
||||||
* the typo, and return None
|
* the typo, and return None
|
||||||
@ -229,7 +229,7 @@ if len(rv):
|
|||||||
return rv[0]["fname"]
|
return rv[0]["fname"]
|
||||||
return None
|
return None
|
||||||
'
|
'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
/* for what it's worth catch the exception generated by
|
/* for what it's worth catch the exception generated by
|
||||||
* the typo, and reraise it as a plain error
|
* the typo, and reraise it as a plain error
|
||||||
@ -247,7 +247,7 @@ if len(rv):
|
|||||||
return rv[0]["fname"]
|
return rv[0]["fname"]
|
||||||
return None
|
return None
|
||||||
'
|
'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
|
||||||
/* no typo no messing about
|
/* no typo no messing about
|
||||||
@ -261,20 +261,20 @@ if len(rv):
|
|||||||
return rv[0]["fname"]
|
return rv[0]["fname"]
|
||||||
return None
|
return None
|
||||||
'
|
'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
/* Flat out syntax error
|
/* Flat out syntax error
|
||||||
*/
|
*/
|
||||||
CREATE FUNCTION sql_syntax_error() RETURNS text
|
CREATE FUNCTION sql_syntax_error() RETURNS text
|
||||||
AS
|
AS
|
||||||
'plpy.execute("syntax error")'
|
'plpy.execute("syntax error")'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
/* check the handling of uncaught python exceptions
|
/* check the handling of uncaught python exceptions
|
||||||
*/
|
*/
|
||||||
CREATE FUNCTION exception_index_invalid(text) RETURNS text
|
CREATE FUNCTION exception_index_invalid(text) RETURNS text
|
||||||
AS
|
AS
|
||||||
'return args[1]'
|
'return args[1]'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
/* check handling of nested exceptions
|
/* check handling of nested exceptions
|
||||||
*/
|
*/
|
||||||
@ -282,7 +282,7 @@ CREATE FUNCTION exception_index_invalid_nested() RETURNS text
|
|||||||
AS
|
AS
|
||||||
'rv = plpy.execute("SELECT test5(''foo'')")
|
'rv = plpy.execute("SELECT test5(''foo'')")
|
||||||
return rv[0]'
|
return rv[0]'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION join_sequences(sequences) RETURNS text
|
CREATE FUNCTION join_sequences(sequences) RETURNS text
|
||||||
@ -296,13 +296,13 @@ for r in rv:
|
|||||||
seq = seq + r["sequence"]
|
seq = seq + r["sequence"]
|
||||||
return seq
|
return seq
|
||||||
'
|
'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION read_file(text) RETURNS text AS '
|
CREATE OR REPLACE FUNCTION read_file(text) RETURNS text AS '
|
||||||
return open(args[0]).read()
|
return open(args[0]).read()
|
||||||
' LANGUAGE 'plpython';
|
' LANGUAGE plpythonu;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION write_file(text,text) RETURNS text AS '
|
CREATE OR REPLACE FUNCTION write_file(text,text) RETURNS text AS '
|
||||||
open(args[0],"w").write(args[1])
|
open(args[0],"w").write(args[1])
|
||||||
return "Wrote to file: %s" % args[0]
|
return "Wrote to file: %s" % args[0]
|
||||||
' LANGUAGE 'plpython';
|
' LANGUAGE plpythonu;
|
||||||
|
@ -8,4 +8,4 @@ CREATE FUNCTION test_setof() returns setof text
|
|||||||
else:
|
else:
|
||||||
GD["calls"] = 1
|
GD["calls"] = 1
|
||||||
return str(GD["calls"])'
|
return str(GD["calls"])'
|
||||||
LANGUAGE 'plpython';
|
LANGUAGE plpythonu;
|
||||||
|
@ -11,7 +11,7 @@ createdb $DBNAME >> test.log 2>&1
|
|||||||
echo " Done. ***"
|
echo " Done. ***"
|
||||||
|
|
||||||
echo -n "*** Create plpython."
|
echo -n "*** Create plpython."
|
||||||
createlang plpython $DBNAME >> test.log 2>&1
|
createlang plpythonu $DBNAME >> test.log 2>&1
|
||||||
echo " Done. ***"
|
echo " Done. ***"
|
||||||
|
|
||||||
echo -n "*** Create tables"
|
echo -n "*** Create tables"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user