Remove support for Python older than 2.6
authorPeter Eisentraut <peter@eisentraut.org>
Wed, 8 Jan 2020 20:48:44 +0000 (21:48 +0100)
committerPeter Eisentraut <peter@eisentraut.org>
Wed, 8 Jan 2020 21:47:22 +0000 (22:47 +0100)
Supporting very old Python versions is a maintenance burden,
especially with the several variant test files to maintain for Python
<2.6.

Since we have dropped support for older OpenSSL versions in
7b283d0e1d1d79bf1c962d790c94d2a53f3bb38a, RHEL 5 is now effectively
desupported, and that was also the only mainstream operating system
still using Python versions before 2.6, so it's a good time to drop
those as well.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://www.postgresql.org/message-id/flat/98b69261-298c-13d2-f34d-836fd9c29b21%402ndquadrant.com

12 files changed:
config/python.m4
configure
doc/src/sgml/installation.sgml
doc/src/sgml/plpython.sgml
src/pl/plpython/expected/README
src/pl/plpython/expected/plpython_error_0.out [deleted file]
src/pl/plpython/expected/plpython_subtransaction.out
src/pl/plpython/expected/plpython_subtransaction_0.out [deleted file]
src/pl/plpython/expected/plpython_subtransaction_5.out [deleted file]
src/pl/plpython/plpy_elog.c
src/pl/plpython/plpython.h
src/pl/plpython/sql/plpython_subtransaction.sql

index c51aa4e332e0d746524d32866ccab1e1e31b6bc4..d41aeb2876a4842fa48eb8cc88d57750178e3ee1 100644 (file)
@@ -37,8 +37,8 @@ python_majorversion=`echo "$python_fullversion" | sed '[s/^\([0-9]*\).*/\1/]'`
 python_minorversion=`echo "$python_fullversion" | sed '[s/^[0-9]*\.\([0-9]*\).*/\1/]'`
 python_version=`echo "$python_fullversion" | sed '[s/^\([0-9]*\.[0-9]*\).*/\1/]'`
 # Reject unsupported Python versions as soon as practical.
-if test "$python_majorversion" -lt 3 -a "$python_minorversion" -lt 4; then
-  AC_MSG_ERROR([Python version $python_version is too old (version 2.4 or later is required)])
+if test "$python_majorversion" -lt 3 -a "$python_minorversion" -lt 6; then
+  AC_MSG_ERROR([Python version $python_version is too old (version 2.6 or later is required)])
 fi
 
 AC_MSG_CHECKING([for Python distutils module])
index d2d63f2e55582e10d8ed3efa805fe57d23f3bc02..25cfbcb2cd02c013aec18c05f191f58ce967db16 100755 (executable)
--- a/configure
+++ b/configure
@@ -9616,8 +9616,8 @@ python_majorversion=`echo "$python_fullversion" | sed 's/^\([0-9]*\).*/\1/'`
 python_minorversion=`echo "$python_fullversion" | sed 's/^[0-9]*\.\([0-9]*\).*/\1/'`
 python_version=`echo "$python_fullversion" | sed 's/^\([0-9]*\.[0-9]*\).*/\1/'`
 # Reject unsupported Python versions as soon as practical.
-if test "$python_majorversion" -lt 3 -a "$python_minorversion" -lt 4; then
-  as_fn_error $? "Python version $python_version is too old (version 2.4 or later is required)" "$LINENO" 5
+if test "$python_majorversion" -lt 3 -a "$python_minorversion" -lt 6; then
+  as_fn_error $? "Python version $python_version is too old (version 2.6 or later is required)" "$LINENO" 5
 fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python distutils module" >&5
index d4904bf5a06fd66705cbf39e308cf5008c4344ee..f1adcc3c559e21455e08fb080854d6dd9bda5396 100644 (file)
@@ -196,7 +196,7 @@ su - postgres
       language, you need a <productname>Python</productname>
       installation with the header files and
       the <application>distutils</application> module.  The minimum
-      required version is <productname>Python</productname> 2.4.
+      required version is <productname>Python</productname> 2.6.
       <productname>Python 3</productname> is supported if it's
       version 3.1 or later; but see
       <xref linkend="plpython-python23"/>
index c42109257180962d3a95ae077fce9abf8a491f64..7bdaf76bbad84b4d963f253e084ed80ad1a1f920 100644 (file)
@@ -1335,9 +1335,8 @@ $$ LANGUAGE plpythonu;
 
    <para>
     Context managers syntax using the <literal>with</literal> keyword
-    is available by default in Python 2.6.  If using PL/Python with an
-    older Python version, it is still possible to use explicit
-    subtransactions, although not as transparently.  You can call the
+    is available by default in Python 2.6.  For compatibility with
+    older Python versions, you can call the
     subtransaction manager's <literal>__enter__</literal> and
     <literal>__exit__</literal> functions using the
     <literal>enter</literal> and <literal>exit</literal> convenience
@@ -1367,17 +1366,6 @@ plpy.execute(plan, [result])
 $$ LANGUAGE plpythonu;
 </programlisting>
    </para>
-
-   <note>
-    <para>
-     Although context managers were implemented in Python 2.5, to use
-     the <literal>with</literal> syntax in that version you need to
-     use a <ulink
-     url="https://docs.python.org/release/2.5/ref/future.html">future
-     statement</ulink>.  Because of implementation details, however,
-     you cannot use future statements in PL/Python functions.
-    </para>
-   </note>
   </sect2>
  </sect1>
 
index b8905633770ed400b81958151a917f8136b2a82b..d735ae989bc0ab48de4eec688b1a250200094723 100644 (file)
@@ -1,12 +1,8 @@
 Guide to alternative expected files:
 
-plpython_error_0.out           Python 2.4 and older
 plpython_error_5.out           Python 3.5 and newer
 
 plpython_unicode.out           server encoding != SQL_ASCII
 plpython_unicode_3.out         server encoding == SQL_ASCII
 
-plpython_subtransaction_0.out  Python 2.4 and older (without with statement)
-plpython_subtransaction_5.out  Python 2.5 (without with statement)
-
 plpython_types_3.out           Python 3.x
diff --git a/src/pl/plpython/expected/plpython_error_0.out b/src/pl/plpython/expected/plpython_error_0.out
deleted file mode 100644 (file)
index 290902b..0000000
+++ /dev/null
@@ -1,447 +0,0 @@
--- test error handling, i forgot to restore Warn_restart in
--- the trigger handler once. the errors and subsequent core dump were
--- interesting.
-/* Flat out Python syntax error
- */
-CREATE FUNCTION python_syntax_error() RETURNS text
-        AS
-'.syntaxerror'
-        LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "python_syntax_error"
-DETAIL:  SyntaxError: invalid syntax (line 2)
-/* With check_function_bodies = false the function should get defined
- * and the error reported when called
- */
-SET check_function_bodies = false;
-CREATE FUNCTION python_syntax_error() RETURNS text
-        AS
-'.syntaxerror'
-        LANGUAGE plpythonu;
-SELECT python_syntax_error();
-ERROR:  could not compile PL/Python function "python_syntax_error"
-DETAIL:  SyntaxError: invalid syntax (line 2)
-/* Run the function twice to check if the hashtable entry gets cleaned up */
-SELECT python_syntax_error();
-ERROR:  could not compile PL/Python function "python_syntax_error"
-DETAIL:  SyntaxError: invalid syntax (line 2)
-RESET check_function_bodies;
-/* Flat out syntax error
- */
-CREATE FUNCTION sql_syntax_error() RETURNS text
-        AS
-'plpy.execute("syntax error")'
-        LANGUAGE plpythonu;
-SELECT sql_syntax_error();
-ERROR:  spiexceptions.SyntaxError: syntax error at or near "syntax"
-LINE 1: syntax error
-        ^
-QUERY:  syntax error
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "sql_syntax_error", line 1, in <module>
-    plpy.execute("syntax error")
-PL/Python function "sql_syntax_error"
-/* check the handling of uncaught python exceptions
- */
-CREATE FUNCTION exception_index_invalid(text) RETURNS text
-   AS
-'return args[1]'
-   LANGUAGE plpythonu;
-SELECT exception_index_invalid('test');
-ERROR:  IndexError: list index out of range
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "exception_index_invalid", line 1, in <module>
-    return args[1]
-PL/Python function "exception_index_invalid"
-/* check handling of nested exceptions
- */
-CREATE FUNCTION exception_index_invalid_nested() RETURNS text
-   AS
-'rv = plpy.execute("SELECT test5(''foo'')")
-return rv[0]'
-   LANGUAGE plpythonu;
-SELECT exception_index_invalid_nested();
-ERROR:  spiexceptions.UndefinedFunction: function test5(unknown) does not exist
-LINE 1: SELECT test5('foo')
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-QUERY:  SELECT test5('foo')
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "exception_index_invalid_nested", line 1, in <module>
-    rv = plpy.execute("SELECT test5('foo')")
-PL/Python function "exception_index_invalid_nested"
-/* a typo
- */
-CREATE FUNCTION invalid_type_uncaught(a text) RETURNS text
-   AS
-'if "plan" not in SD:
-   q = "SELECT fname FROM users WHERE lname = $1"
-   SD["plan"] = plpy.prepare(q, [ "test" ])
-rv = plpy.execute(SD["plan"], [ a ])
-if len(rv):
-   return rv[0]["fname"]
-return None
-'
-   LANGUAGE plpythonu;
-SELECT invalid_type_uncaught('rick');
-ERROR:  spiexceptions.UndefinedObject: type "test" does not exist
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "invalid_type_uncaught", line 3, in <module>
-    SD["plan"] = plpy.prepare(q, [ "test" ])
-PL/Python function "invalid_type_uncaught"
-/* for what it's worth catch the exception generated by
- * the typo, and return None
- */
-CREATE FUNCTION invalid_type_caught(a text) RETURNS text
-   AS
-'if "plan" not in SD:
-   q = "SELECT fname FROM users WHERE lname = $1"
-   try:
-       SD["plan"] = plpy.prepare(q, [ "test" ])
-   except plpy.SPIError, ex:
-       plpy.notice(str(ex))
-       return None
-rv = plpy.execute(SD["plan"], [ a ])
-if len(rv):
-   return rv[0]["fname"]
-return None
-'
-   LANGUAGE plpythonu;
-SELECT invalid_type_caught('rick');
-NOTICE:  type "test" does not exist
- invalid_type_caught 
----------------------
-(1 row)
-
-/* for what it's worth catch the exception generated by
- * the typo, and reraise it as a plain error
- */
-CREATE FUNCTION invalid_type_reraised(a text) RETURNS text
-   AS
-'if "plan" not in SD:
-   q = "SELECT fname FROM users WHERE lname = $1"
-   try:
-       SD["plan"] = plpy.prepare(q, [ "test" ])
-   except plpy.SPIError, ex:
-       plpy.error(str(ex))
-rv = plpy.execute(SD["plan"], [ a ])
-if len(rv):
-   return rv[0]["fname"]
-return None
-'
-   LANGUAGE plpythonu;
-SELECT invalid_type_reraised('rick');
-ERROR:  plpy.Error: type "test" does not exist
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "invalid_type_reraised", line 6, in <module>
-    plpy.error(str(ex))
-PL/Python function "invalid_type_reraised"
-/* no typo no messing about
- */
-CREATE FUNCTION valid_type(a text) RETURNS text
-   AS
-'if "plan" not in SD:
-   SD["plan"] = plpy.prepare("SELECT fname FROM users WHERE lname = $1", [ "text" ])
-rv = plpy.execute(SD["plan"], [ a ])
-if len(rv):
-   return rv[0]["fname"]
-return None
-'
-   LANGUAGE plpythonu;
-SELECT valid_type('rick');
- valid_type 
-------------
-(1 row)
-
-/* error in nested functions to get a traceback
-*/
-CREATE FUNCTION nested_error() RETURNS text
-   AS
-'def fun1():
-   plpy.error("boom")
-
-def fun2():
-   fun1()
-
-def fun3():
-   fun2()
-
-fun3()
-return "not reached"
-'
-   LANGUAGE plpythonu;
-SELECT nested_error();
-ERROR:  plpy.Error: boom
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "nested_error", line 10, in <module>
-    fun3()
-  PL/Python function "nested_error", line 8, in fun3
-    fun2()
-  PL/Python function "nested_error", line 5, in fun2
-    fun1()
-  PL/Python function "nested_error", line 2, in fun1
-    plpy.error("boom")
-PL/Python function "nested_error"
-/* raising plpy.Error is just like calling plpy.error
-*/
-CREATE FUNCTION nested_error_raise() RETURNS text
-   AS
-'def fun1():
-   raise plpy.Error("boom")
-
-def fun2():
-   fun1()
-
-def fun3():
-   fun2()
-
-fun3()
-return "not reached"
-'
-   LANGUAGE plpythonu;
-SELECT nested_error_raise();
-ERROR:  plpy.Error: boom
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "nested_error_raise", line 10, in <module>
-    fun3()
-  PL/Python function "nested_error_raise", line 8, in fun3
-    fun2()
-  PL/Python function "nested_error_raise", line 5, in fun2
-    fun1()
-  PL/Python function "nested_error_raise", line 2, in fun1
-    raise plpy.Error("boom")
-PL/Python function "nested_error_raise"
-/* using plpy.warning should not produce a traceback
-*/
-CREATE FUNCTION nested_warning() RETURNS text
-   AS
-'def fun1():
-   plpy.warning("boom")
-
-def fun2():
-   fun1()
-
-def fun3():
-   fun2()
-
-fun3()
-return "you''ve been warned"
-'
-   LANGUAGE plpythonu;
-SELECT nested_warning();
-WARNING:  boom
-   nested_warning   
---------------------
- you've been warned
-(1 row)
-
-/* AttributeError at toplevel used to give segfaults with the traceback
-*/
-CREATE FUNCTION toplevel_attribute_error() RETURNS void AS
-$$
-plpy.nonexistent
-$$ LANGUAGE plpythonu;
-SELECT toplevel_attribute_error();
-ERROR:  AttributeError: 'module' object has no attribute 'nonexistent'
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "toplevel_attribute_error", line 2, in <module>
-    plpy.nonexistent
-PL/Python function "toplevel_attribute_error"
-/* Calling PL/Python functions from SQL and vice versa should not lose context.
- */
-CREATE OR REPLACE FUNCTION python_traceback() RETURNS void AS $$
-def first():
-  second()
-
-def second():
-  third()
-
-def third():
-  plpy.execute("select sql_error()")
-
-first()
-$$ LANGUAGE plpythonu;
-CREATE OR REPLACE FUNCTION sql_error() RETURNS void AS $$
-begin
-  select 1/0;
-end
-$$ LANGUAGE plpgsql;
-CREATE OR REPLACE FUNCTION python_from_sql_error() RETURNS void AS $$
-begin
-  select python_traceback();
-end
-$$ LANGUAGE plpgsql;
-CREATE OR REPLACE FUNCTION sql_from_python_error() RETURNS void AS $$
-plpy.execute("select sql_error()")
-$$ LANGUAGE plpythonu;
-SELECT python_traceback();
-ERROR:  spiexceptions.DivisionByZero: division by zero
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "python_traceback", line 11, in <module>
-    first()
-  PL/Python function "python_traceback", line 3, in first
-    second()
-  PL/Python function "python_traceback", line 6, in second
-    third()
-  PL/Python function "python_traceback", line 9, in third
-    plpy.execute("select sql_error()")
-PL/Python function "python_traceback"
-SELECT sql_error();
-ERROR:  division by zero
-CONTEXT:  SQL statement "select 1/0"
-PL/pgSQL function sql_error() line 3 at SQL statement
-SELECT python_from_sql_error();
-ERROR:  spiexceptions.DivisionByZero: division by zero
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "python_traceback", line 11, in <module>
-    first()
-  PL/Python function "python_traceback", line 3, in first
-    second()
-  PL/Python function "python_traceback", line 6, in second
-    third()
-  PL/Python function "python_traceback", line 9, in third
-    plpy.execute("select sql_error()")
-PL/Python function "python_traceback"
-SQL statement "select python_traceback()"
-PL/pgSQL function python_from_sql_error() line 3 at SQL statement
-SELECT sql_from_python_error();
-ERROR:  spiexceptions.DivisionByZero: division by zero
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "sql_from_python_error", line 2, in <module>
-    plpy.execute("select sql_error()")
-PL/Python function "sql_from_python_error"
-/* check catching specific types of exceptions
- */
-CREATE TABLE specific (
-    i integer PRIMARY KEY
-);
-CREATE FUNCTION specific_exception(i integer) RETURNS void AS
-$$
-from plpy import spiexceptions
-try:
-    plpy.execute("insert into specific values (%s)" % (i or "NULL"));
-except spiexceptions.NotNullViolation, e:
-    plpy.notice("Violated the NOT NULL constraint, sqlstate %s" % e.sqlstate)
-except spiexceptions.UniqueViolation, e:
-    plpy.notice("Violated the UNIQUE constraint, sqlstate %s" % e.sqlstate)
-$$ LANGUAGE plpythonu;
-SELECT specific_exception(2);
- specific_exception 
---------------------
-(1 row)
-
-SELECT specific_exception(NULL);
-NOTICE:  Violated the NOT NULL constraint, sqlstate 23502
- specific_exception 
---------------------
-(1 row)
-
-SELECT specific_exception(2);
-NOTICE:  Violated the UNIQUE constraint, sqlstate 23505
- specific_exception 
---------------------
-(1 row)
-
-/* SPI errors in PL/Python functions should preserve the SQLSTATE value
- */
-CREATE FUNCTION python_unique_violation() RETURNS void AS $$
-plpy.execute("insert into specific values (1)")
-plpy.execute("insert into specific values (1)")
-$$ LANGUAGE plpythonu;
-CREATE FUNCTION catch_python_unique_violation() RETURNS text AS $$
-begin
-    begin
-        perform python_unique_violation();
-    exception when unique_violation then
-        return 'ok';
-    end;
-    return 'not reached';
-end;
-$$ language plpgsql;
-SELECT catch_python_unique_violation();
- catch_python_unique_violation 
--------------------------------
- ok
-(1 row)
-
-/* manually starting subtransactions - a bad idea
- */
-CREATE FUNCTION manual_subxact() RETURNS void AS $$
-plpy.execute("savepoint save")
-plpy.execute("create table foo(x integer)")
-plpy.execute("rollback to save")
-$$ LANGUAGE plpythonu;
-SELECT manual_subxact();
-ERROR:  plpy.SPIError: SPI_execute failed: SPI_ERROR_TRANSACTION
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "manual_subxact", line 2, in <module>
-    plpy.execute("savepoint save")
-PL/Python function "manual_subxact"
-/* same for prepared plans
- */
-CREATE FUNCTION manual_subxact_prepared() RETURNS void AS $$
-save = plpy.prepare("savepoint save")
-rollback = plpy.prepare("rollback to save")
-plpy.execute(save)
-plpy.execute("create table foo(x integer)")
-plpy.execute(rollback)
-$$ LANGUAGE plpythonu;
-SELECT manual_subxact_prepared();
-ERROR:  plpy.SPIError: SPI_execute_plan failed: SPI_ERROR_TRANSACTION
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "manual_subxact_prepared", line 4, in <module>
-    plpy.execute(save)
-PL/Python function "manual_subxact_prepared"
-/* raising plpy.spiexception.* from python code should preserve sqlstate
- */
-CREATE FUNCTION plpy_raise_spiexception() RETURNS void AS $$
-raise plpy.spiexceptions.DivisionByZero()
-$$ LANGUAGE plpythonu;
-DO $$
-BEGIN
-   SELECT plpy_raise_spiexception();
-EXCEPTION WHEN division_by_zero THEN
-   -- NOOP
-END
-$$ LANGUAGE plpgsql;
-/* setting a custom sqlstate should be handled
- */
-CREATE FUNCTION plpy_raise_spiexception_override() RETURNS void AS $$
-exc = plpy.spiexceptions.DivisionByZero()
-exc.sqlstate = 'SILLY'
-raise exc
-$$ LANGUAGE plpythonu;
-DO $$
-BEGIN
-   SELECT plpy_raise_spiexception_override();
-EXCEPTION WHEN SQLSTATE 'SILLY' THEN
-   -- NOOP
-END
-$$ LANGUAGE plpgsql;
-/* test the context stack trace for nested execution levels
- */
-CREATE FUNCTION notice_innerfunc() RETURNS int AS $$
-plpy.execute("DO LANGUAGE plpythonu $x$ plpy.notice('inside DO') $x$")
-return 1
-$$ LANGUAGE plpythonu;
-CREATE FUNCTION notice_outerfunc() RETURNS int AS $$
-plpy.execute("SELECT notice_innerfunc()")
-return 1
-$$ LANGUAGE plpythonu;
-\set SHOW_CONTEXT always
-SELECT notice_outerfunc();
-NOTICE:  inside DO
-CONTEXT:  PL/Python anonymous code block
-SQL statement "DO LANGUAGE plpythonu $x$ plpy.notice('inside DO') $x$"
-PL/Python function "notice_innerfunc"
-SQL statement "SELECT notice_innerfunc()"
-PL/Python function "notice_outerfunc"
- notice_outerfunc 
-------------------
-                1
-(1 row)
-
index 069f0992abdaf8835d2e96b0bb793385c6676c03..8df64e7619cc39655d04684961f40bc06c43b9a1 100644 (file)
@@ -5,71 +5,6 @@
 CREATE TABLE subtransaction_tbl (
     i integer
 );
--- Explicit case for Python <2.6
-CREATE FUNCTION subtransaction_test(what_error text = NULL) RETURNS text
-AS $$
-import sys
-subxact = plpy.subtransaction()
-subxact.__enter__()
-exc = True
-try:
-    try:
-        plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-        plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
-        if what_error == "SPI":
-            plpy.execute("INSERT INTO subtransaction_tbl VALUES ('oops')")
-        elif what_error == "Python":
-            raise Exception("Python exception")
-    except:
-        exc = False
-        subxact.__exit__(*sys.exc_info())
-        raise
-finally:
-    if exc:
-        subxact.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
-SELECT subtransaction_test();
- subtransaction_test 
----------------------
-(1 row)
-
-SELECT * FROM subtransaction_tbl;
- i 
----
- 1
- 2
-(2 rows)
-
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_test('SPI');
-ERROR:  spiexceptions.InvalidTextRepresentation: invalid input syntax for type integer: "oops"
-LINE 1: INSERT INTO subtransaction_tbl VALUES ('oops')
-                                               ^
-QUERY:  INSERT INTO subtransaction_tbl VALUES ('oops')
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_test", line 11, in <module>
-    plpy.execute("INSERT INTO subtransaction_tbl VALUES ('oops')")
-PL/Python function "subtransaction_test"
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_test('Python');
-ERROR:  Exception: Python exception
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_test", line 13, in <module>
-    raise Exception("Python exception")
-PL/Python function "subtransaction_test"
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
--- Context manager case for Python >=2.6
 CREATE FUNCTION subtransaction_ctx_test(what_error text = NULL) RETURNS text
 AS $$
 with plpy.subtransaction():
diff --git a/src/pl/plpython/expected/plpython_subtransaction_0.out b/src/pl/plpython/expected/plpython_subtransaction_0.out
deleted file mode 100644 (file)
index 97ee42b..0000000
+++ /dev/null
@@ -1,448 +0,0 @@
---
--- Test explicit subtransactions
---
--- Test table to see if transactions get properly rolled back
-CREATE TABLE subtransaction_tbl (
-    i integer
-);
--- Explicit case for Python <2.6
-CREATE FUNCTION subtransaction_test(what_error text = NULL) RETURNS text
-AS $$
-import sys
-subxact = plpy.subtransaction()
-subxact.__enter__()
-exc = True
-try:
-    try:
-        plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-        plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
-        if what_error == "SPI":
-            plpy.execute("INSERT INTO subtransaction_tbl VALUES ('oops')")
-        elif what_error == "Python":
-            raise Exception("Python exception")
-    except:
-        exc = False
-        subxact.__exit__(*sys.exc_info())
-        raise
-finally:
-    if exc:
-        subxact.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
-SELECT subtransaction_test();
- subtransaction_test 
----------------------
-(1 row)
-
-SELECT * FROM subtransaction_tbl;
- i 
----
- 1
- 2
-(2 rows)
-
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_test('SPI');
-ERROR:  spiexceptions.InvalidTextRepresentation: invalid input syntax for type integer: "oops"
-LINE 1: INSERT INTO subtransaction_tbl VALUES ('oops')
-                                               ^
-QUERY:  INSERT INTO subtransaction_tbl VALUES ('oops')
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_test", line 11, in <module>
-    plpy.execute("INSERT INTO subtransaction_tbl VALUES ('oops')")
-PL/Python function "subtransaction_test"
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_test('Python');
-ERROR:  Exception: Python exception
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_test", line 13, in <module>
-    raise Exception("Python exception")
-PL/Python function "subtransaction_test"
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
--- Context manager case for Python >=2.6
-CREATE FUNCTION subtransaction_ctx_test(what_error text = NULL) RETURNS text
-AS $$
-with plpy.subtransaction():
-    plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-    plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
-    if what_error == "SPI":
-        plpy.execute("INSERT INTO subtransaction_tbl VALUES ('oops')")
-    elif what_error == "Python":
-        raise Exception("Python exception")
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "subtransaction_ctx_test"
-DETAIL:  SyntaxError: invalid syntax (line 3)
-SELECT subtransaction_ctx_test();
-ERROR:  function subtransaction_ctx_test() does not exist
-LINE 1: SELECT subtransaction_ctx_test();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_ctx_test('SPI');
-ERROR:  function subtransaction_ctx_test(unknown) does not exist
-LINE 1: SELECT subtransaction_ctx_test('SPI');
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_ctx_test('Python');
-ERROR:  function subtransaction_ctx_test(unknown) does not exist
-LINE 1: SELECT subtransaction_ctx_test('Python');
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
--- Nested subtransactions
-CREATE FUNCTION subtransaction_nested_test(swallow boolean = 'f') RETURNS text
-AS $$
-plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-with plpy.subtransaction():
-    plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
-    try:
-        with plpy.subtransaction():
-            plpy.execute("INSERT INTO subtransaction_tbl VALUES (3)")
-            plpy.execute("error")
-    except plpy.SPIError, e:
-        if not swallow:
-            raise
-        plpy.notice("Swallowed %s(%r)" % (e.__class__.__name__, e.args[0]))
-return "ok"
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "subtransaction_nested_test"
-DETAIL:  SyntaxError: invalid syntax (line 4)
-SELECT subtransaction_nested_test();
-ERROR:  function subtransaction_nested_test() does not exist
-LINE 1: SELECT subtransaction_nested_test();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_nested_test('t');
-ERROR:  function subtransaction_nested_test(unknown) does not exist
-LINE 1: SELECT subtransaction_nested_test('t');
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
--- Nested subtransactions that recursively call code dealing with
--- subtransactions
-CREATE FUNCTION subtransaction_deeply_nested_test() RETURNS text
-AS $$
-plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-with plpy.subtransaction():
-    plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
-    plpy.execute("SELECT subtransaction_nested_test('t')")
-return "ok"
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "subtransaction_deeply_nested_test"
-DETAIL:  SyntaxError: invalid syntax (line 4)
-SELECT subtransaction_deeply_nested_test();
-ERROR:  function subtransaction_deeply_nested_test() does not exist
-LINE 1: SELECT subtransaction_deeply_nested_test();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
--- Error conditions from not opening/closing subtransactions
-CREATE FUNCTION subtransaction_exit_without_enter() RETURNS void
-AS $$
-plpy.subtransaction().__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
-CREATE FUNCTION subtransaction_enter_without_exit() RETURNS void
-AS $$
-plpy.subtransaction().__enter__()
-$$ LANGUAGE plpythonu;
-CREATE FUNCTION subtransaction_exit_twice() RETURNS void
-AS $$
-plpy.subtransaction().__enter__()
-plpy.subtransaction().__exit__(None, None, None)
-plpy.subtransaction().__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
-CREATE FUNCTION subtransaction_enter_twice() RETURNS void
-AS $$
-plpy.subtransaction().__enter__()
-plpy.subtransaction().__enter__()
-$$ LANGUAGE plpythonu;
-CREATE FUNCTION subtransaction_exit_same_subtransaction_twice() RETURNS void
-AS $$
-s = plpy.subtransaction()
-s.__enter__()
-s.__exit__(None, None, None)
-s.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
-CREATE FUNCTION subtransaction_enter_same_subtransaction_twice() RETURNS void
-AS $$
-s = plpy.subtransaction()
-s.__enter__()
-s.__enter__()
-s.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
--- No warnings here, as the subtransaction gets indeed closed
-CREATE FUNCTION subtransaction_enter_subtransaction_in_with() RETURNS void
-AS $$
-with plpy.subtransaction() as s:
-    s.__enter__()
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "subtransaction_enter_subtransaction_in_with"
-DETAIL:  SyntaxError: invalid syntax (line 3)
-CREATE FUNCTION subtransaction_exit_subtransaction_in_with() RETURNS void
-AS $$
-with plpy.subtransaction() as s:
-    s.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "subtransaction_exit_subtransaction_in_with"
-DETAIL:  SyntaxError: invalid syntax (line 3)
-SELECT subtransaction_exit_without_enter();
-ERROR:  ValueError: this subtransaction has not been entered
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_exit_without_enter", line 2, in <module>
-    plpy.subtransaction().__exit__(None, None, None)
-PL/Python function "subtransaction_exit_without_enter"
-SELECT subtransaction_enter_without_exit();
-WARNING:  forcibly aborting a subtransaction that has not been exited
- subtransaction_enter_without_exit 
------------------------------------
-(1 row)
-
-SELECT subtransaction_exit_twice();
-WARNING:  forcibly aborting a subtransaction that has not been exited
-ERROR:  ValueError: this subtransaction has not been entered
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_exit_twice", line 3, in <module>
-    plpy.subtransaction().__exit__(None, None, None)
-PL/Python function "subtransaction_exit_twice"
-SELECT subtransaction_enter_twice();
-WARNING:  forcibly aborting a subtransaction that has not been exited
-WARNING:  forcibly aborting a subtransaction that has not been exited
- subtransaction_enter_twice 
-----------------------------
-(1 row)
-
-SELECT subtransaction_exit_same_subtransaction_twice();
-ERROR:  ValueError: this subtransaction has already been exited
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_exit_same_subtransaction_twice", line 5, in <module>
-    s.__exit__(None, None, None)
-PL/Python function "subtransaction_exit_same_subtransaction_twice"
-SELECT subtransaction_enter_same_subtransaction_twice();
-WARNING:  forcibly aborting a subtransaction that has not been exited
-ERROR:  ValueError: this subtransaction has already been entered
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_enter_same_subtransaction_twice", line 4, in <module>
-    s.__enter__()
-PL/Python function "subtransaction_enter_same_subtransaction_twice"
-SELECT subtransaction_enter_subtransaction_in_with();
-ERROR:  function subtransaction_enter_subtransaction_in_with() does not exist
-LINE 1: SELECT subtransaction_enter_subtransaction_in_with();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT subtransaction_exit_subtransaction_in_with();
-ERROR:  function subtransaction_exit_subtransaction_in_with() does not exist
-LINE 1: SELECT subtransaction_exit_subtransaction_in_with();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
--- Make sure we don't get a "current transaction is aborted" error
-SELECT 1 as test;
- test 
-------
-    1
-(1 row)
-
--- Mix explicit subtransactions and normal SPI calls
-CREATE FUNCTION subtransaction_mix_explicit_and_implicit() RETURNS void
-AS $$
-p = plpy.prepare("INSERT INTO subtransaction_tbl VALUES ($1)", ["integer"])
-try:
-    with plpy.subtransaction():
-        plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-        plpy.execute(p, [2])
-        plpy.execute(p, ["wrong"])
-except plpy.SPIError:
-    plpy.warning("Caught a SPI error from an explicit subtransaction")
-
-try:
-    plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-    plpy.execute(p, [2])
-    plpy.execute(p, ["wrong"])
-except plpy.SPIError:
-    plpy.warning("Caught a SPI error")
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "subtransaction_mix_explicit_and_implicit"
-DETAIL:  SyntaxError: invalid syntax (line 5)
-SELECT subtransaction_mix_explicit_and_implicit();
-ERROR:  function subtransaction_mix_explicit_and_implicit() does not exist
-LINE 1: SELECT subtransaction_mix_explicit_and_implicit();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
--- Alternative method names for Python <2.6
-CREATE FUNCTION subtransaction_alternative_names() RETURNS void
-AS $$
-s = plpy.subtransaction()
-s.enter()
-s.exit(None, None, None)
-$$ LANGUAGE plpythonu;
-SELECT subtransaction_alternative_names();
- subtransaction_alternative_names 
-----------------------------------
-(1 row)
-
--- try/catch inside a subtransaction block
-CREATE FUNCTION try_catch_inside_subtransaction() RETURNS void
-AS $$
-with plpy.subtransaction():
-     plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-     try:
-         plpy.execute("INSERT INTO subtransaction_tbl VALUES ('a')")
-     except plpy.SPIError:
-         plpy.notice("caught")
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "try_catch_inside_subtransaction"
-DETAIL:  SyntaxError: invalid syntax (line 3)
-SELECT try_catch_inside_subtransaction();
-ERROR:  function try_catch_inside_subtransaction() does not exist
-LINE 1: SELECT try_catch_inside_subtransaction();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
-ALTER TABLE subtransaction_tbl ADD PRIMARY KEY (i);
-CREATE FUNCTION pk_violation_inside_subtransaction() RETURNS void
-AS $$
-with plpy.subtransaction():
-     plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-     try:
-         plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-     except plpy.SPIError:
-         plpy.notice("caught")
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "pk_violation_inside_subtransaction"
-DETAIL:  SyntaxError: invalid syntax (line 3)
-SELECT pk_violation_inside_subtransaction();
-ERROR:  function pk_violation_inside_subtransaction() does not exist
-LINE 1: SELECT pk_violation_inside_subtransaction();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-DROP TABLE subtransaction_tbl;
--- cursor/subtransactions interactions
-CREATE FUNCTION cursor_in_subxact() RETURNS int AS $$
-with plpy.subtransaction():
-    cur = plpy.cursor("select * from generate_series(1, 20) as gen(i)")
-    cur.fetch(10)
-fetched = cur.fetch(10);
-return int(fetched[5]["i"])
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "cursor_in_subxact"
-DETAIL:  SyntaxError: invalid syntax (line 3)
-CREATE FUNCTION cursor_aborted_subxact() RETURNS int AS $$
-try:
-    with plpy.subtransaction():
-        cur = plpy.cursor("select * from generate_series(1, 20) as gen(i)")
-        cur.fetch(10);
-        plpy.execute("select no_such_function()")
-except plpy.SPIError:
-    fetched = cur.fetch(10)
-    return int(fetched[5]["i"])
-return 0 # not reached
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "cursor_aborted_subxact"
-DETAIL:  SyntaxError: invalid syntax (line 4)
-CREATE FUNCTION cursor_plan_aborted_subxact() RETURNS int AS $$
-try:
-    with plpy.subtransaction():
-        plpy.execute('create temporary table tmp(i) '
-                     'as select generate_series(1, 10)')
-        plan = plpy.prepare("select i from tmp")
-        cur = plpy.cursor(plan)
-        plpy.execute("select no_such_function()")
-except plpy.SPIError:
-    fetched = cur.fetch(5)
-    return fetched[2]["i"]
-return 0 # not reached
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "cursor_plan_aborted_subxact"
-DETAIL:  SyntaxError: invalid syntax (line 4)
-CREATE FUNCTION cursor_close_aborted_subxact() RETURNS boolean AS $$
-try:
-    with plpy.subtransaction():
-        cur = plpy.cursor('select 1')
-        plpy.execute("select no_such_function()")
-except plpy.SPIError:
-    cur.close()
-    return True
-return False # not reached
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "cursor_close_aborted_subxact"
-DETAIL:  SyntaxError: invalid syntax (line 4)
-SELECT cursor_in_subxact();
-ERROR:  function cursor_in_subxact() does not exist
-LINE 1: SELECT cursor_in_subxact();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT cursor_aborted_subxact();
-ERROR:  function cursor_aborted_subxact() does not exist
-LINE 1: SELECT cursor_aborted_subxact();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT cursor_plan_aborted_subxact();
-ERROR:  function cursor_plan_aborted_subxact() does not exist
-LINE 1: SELECT cursor_plan_aborted_subxact();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT cursor_close_aborted_subxact();
-ERROR:  function cursor_close_aborted_subxact() does not exist
-LINE 1: SELECT cursor_close_aborted_subxact();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
diff --git a/src/pl/plpython/expected/plpython_subtransaction_5.out b/src/pl/plpython/expected/plpython_subtransaction_5.out
deleted file mode 100644 (file)
index e172e98..0000000
+++ /dev/null
@@ -1,448 +0,0 @@
---
--- Test explicit subtransactions
---
--- Test table to see if transactions get properly rolled back
-CREATE TABLE subtransaction_tbl (
-    i integer
-);
--- Explicit case for Python <2.6
-CREATE FUNCTION subtransaction_test(what_error text = NULL) RETURNS text
-AS $$
-import sys
-subxact = plpy.subtransaction()
-subxact.__enter__()
-exc = True
-try:
-    try:
-        plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-        plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
-        if what_error == "SPI":
-            plpy.execute("INSERT INTO subtransaction_tbl VALUES ('oops')")
-        elif what_error == "Python":
-            raise Exception("Python exception")
-    except:
-        exc = False
-        subxact.__exit__(*sys.exc_info())
-        raise
-finally:
-    if exc:
-        subxact.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
-SELECT subtransaction_test();
- subtransaction_test 
----------------------
-(1 row)
-
-SELECT * FROM subtransaction_tbl;
- i 
----
- 1
- 2
-(2 rows)
-
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_test('SPI');
-ERROR:  spiexceptions.InvalidTextRepresentation: invalid input syntax for type integer: "oops"
-LINE 1: INSERT INTO subtransaction_tbl VALUES ('oops')
-                                               ^
-QUERY:  INSERT INTO subtransaction_tbl VALUES ('oops')
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_test", line 11, in <module>
-    plpy.execute("INSERT INTO subtransaction_tbl VALUES ('oops')")
-PL/Python function "subtransaction_test"
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_test('Python');
-ERROR:  Exception: Python exception
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_test", line 13, in <module>
-    raise Exception("Python exception")
-PL/Python function "subtransaction_test"
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
--- Context manager case for Python >=2.6
-CREATE FUNCTION subtransaction_ctx_test(what_error text = NULL) RETURNS text
-AS $$
-with plpy.subtransaction():
-    plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-    plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
-    if what_error == "SPI":
-        plpy.execute("INSERT INTO subtransaction_tbl VALUES ('oops')")
-    elif what_error == "Python":
-        raise Exception("Python exception")
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "subtransaction_ctx_test"
-DETAIL:  SyntaxError: invalid syntax (<string>, line 3)
-SELECT subtransaction_ctx_test();
-ERROR:  function subtransaction_ctx_test() does not exist
-LINE 1: SELECT subtransaction_ctx_test();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_ctx_test('SPI');
-ERROR:  function subtransaction_ctx_test(unknown) does not exist
-LINE 1: SELECT subtransaction_ctx_test('SPI');
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_ctx_test('Python');
-ERROR:  function subtransaction_ctx_test(unknown) does not exist
-LINE 1: SELECT subtransaction_ctx_test('Python');
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
--- Nested subtransactions
-CREATE FUNCTION subtransaction_nested_test(swallow boolean = 'f') RETURNS text
-AS $$
-plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-with plpy.subtransaction():
-    plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
-    try:
-        with plpy.subtransaction():
-            plpy.execute("INSERT INTO subtransaction_tbl VALUES (3)")
-            plpy.execute("error")
-    except plpy.SPIError, e:
-        if not swallow:
-            raise
-        plpy.notice("Swallowed %s(%r)" % (e.__class__.__name__, e.args[0]))
-return "ok"
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "subtransaction_nested_test"
-DETAIL:  SyntaxError: invalid syntax (<string>, line 4)
-SELECT subtransaction_nested_test();
-ERROR:  function subtransaction_nested_test() does not exist
-LINE 1: SELECT subtransaction_nested_test();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_nested_test('t');
-ERROR:  function subtransaction_nested_test(unknown) does not exist
-LINE 1: SELECT subtransaction_nested_test('t');
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
--- Nested subtransactions that recursively call code dealing with
--- subtransactions
-CREATE FUNCTION subtransaction_deeply_nested_test() RETURNS text
-AS $$
-plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-with plpy.subtransaction():
-    plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
-    plpy.execute("SELECT subtransaction_nested_test('t')")
-return "ok"
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "subtransaction_deeply_nested_test"
-DETAIL:  SyntaxError: invalid syntax (<string>, line 4)
-SELECT subtransaction_deeply_nested_test();
-ERROR:  function subtransaction_deeply_nested_test() does not exist
-LINE 1: SELECT subtransaction_deeply_nested_test();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
--- Error conditions from not opening/closing subtransactions
-CREATE FUNCTION subtransaction_exit_without_enter() RETURNS void
-AS $$
-plpy.subtransaction().__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
-CREATE FUNCTION subtransaction_enter_without_exit() RETURNS void
-AS $$
-plpy.subtransaction().__enter__()
-$$ LANGUAGE plpythonu;
-CREATE FUNCTION subtransaction_exit_twice() RETURNS void
-AS $$
-plpy.subtransaction().__enter__()
-plpy.subtransaction().__exit__(None, None, None)
-plpy.subtransaction().__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
-CREATE FUNCTION subtransaction_enter_twice() RETURNS void
-AS $$
-plpy.subtransaction().__enter__()
-plpy.subtransaction().__enter__()
-$$ LANGUAGE plpythonu;
-CREATE FUNCTION subtransaction_exit_same_subtransaction_twice() RETURNS void
-AS $$
-s = plpy.subtransaction()
-s.__enter__()
-s.__exit__(None, None, None)
-s.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
-CREATE FUNCTION subtransaction_enter_same_subtransaction_twice() RETURNS void
-AS $$
-s = plpy.subtransaction()
-s.__enter__()
-s.__enter__()
-s.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
--- No warnings here, as the subtransaction gets indeed closed
-CREATE FUNCTION subtransaction_enter_subtransaction_in_with() RETURNS void
-AS $$
-with plpy.subtransaction() as s:
-    s.__enter__()
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "subtransaction_enter_subtransaction_in_with"
-DETAIL:  SyntaxError: invalid syntax (<string>, line 3)
-CREATE FUNCTION subtransaction_exit_subtransaction_in_with() RETURNS void
-AS $$
-with plpy.subtransaction() as s:
-    s.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "subtransaction_exit_subtransaction_in_with"
-DETAIL:  SyntaxError: invalid syntax (<string>, line 3)
-SELECT subtransaction_exit_without_enter();
-ERROR:  ValueError: this subtransaction has not been entered
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_exit_without_enter", line 2, in <module>
-    plpy.subtransaction().__exit__(None, None, None)
-PL/Python function "subtransaction_exit_without_enter"
-SELECT subtransaction_enter_without_exit();
-WARNING:  forcibly aborting a subtransaction that has not been exited
- subtransaction_enter_without_exit 
------------------------------------
-(1 row)
-
-SELECT subtransaction_exit_twice();
-WARNING:  forcibly aborting a subtransaction that has not been exited
-ERROR:  ValueError: this subtransaction has not been entered
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_exit_twice", line 3, in <module>
-    plpy.subtransaction().__exit__(None, None, None)
-PL/Python function "subtransaction_exit_twice"
-SELECT subtransaction_enter_twice();
-WARNING:  forcibly aborting a subtransaction that has not been exited
-WARNING:  forcibly aborting a subtransaction that has not been exited
- subtransaction_enter_twice 
-----------------------------
-(1 row)
-
-SELECT subtransaction_exit_same_subtransaction_twice();
-ERROR:  ValueError: this subtransaction has already been exited
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_exit_same_subtransaction_twice", line 5, in <module>
-    s.__exit__(None, None, None)
-PL/Python function "subtransaction_exit_same_subtransaction_twice"
-SELECT subtransaction_enter_same_subtransaction_twice();
-WARNING:  forcibly aborting a subtransaction that has not been exited
-ERROR:  ValueError: this subtransaction has already been entered
-CONTEXT:  Traceback (most recent call last):
-  PL/Python function "subtransaction_enter_same_subtransaction_twice", line 4, in <module>
-    s.__enter__()
-PL/Python function "subtransaction_enter_same_subtransaction_twice"
-SELECT subtransaction_enter_subtransaction_in_with();
-ERROR:  function subtransaction_enter_subtransaction_in_with() does not exist
-LINE 1: SELECT subtransaction_enter_subtransaction_in_with();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT subtransaction_exit_subtransaction_in_with();
-ERROR:  function subtransaction_exit_subtransaction_in_with() does not exist
-LINE 1: SELECT subtransaction_exit_subtransaction_in_with();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
--- Make sure we don't get a "current transaction is aborted" error
-SELECT 1 as test;
- test 
-------
-    1
-(1 row)
-
--- Mix explicit subtransactions and normal SPI calls
-CREATE FUNCTION subtransaction_mix_explicit_and_implicit() RETURNS void
-AS $$
-p = plpy.prepare("INSERT INTO subtransaction_tbl VALUES ($1)", ["integer"])
-try:
-    with plpy.subtransaction():
-        plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-        plpy.execute(p, [2])
-        plpy.execute(p, ["wrong"])
-except plpy.SPIError:
-    plpy.warning("Caught a SPI error from an explicit subtransaction")
-
-try:
-    plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-    plpy.execute(p, [2])
-    plpy.execute(p, ["wrong"])
-except plpy.SPIError:
-    plpy.warning("Caught a SPI error")
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "subtransaction_mix_explicit_and_implicit"
-DETAIL:  SyntaxError: invalid syntax (<string>, line 5)
-SELECT subtransaction_mix_explicit_and_implicit();
-ERROR:  function subtransaction_mix_explicit_and_implicit() does not exist
-LINE 1: SELECT subtransaction_mix_explicit_and_implicit();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
--- Alternative method names for Python <2.6
-CREATE FUNCTION subtransaction_alternative_names() RETURNS void
-AS $$
-s = plpy.subtransaction()
-s.enter()
-s.exit(None, None, None)
-$$ LANGUAGE plpythonu;
-SELECT subtransaction_alternative_names();
- subtransaction_alternative_names 
-----------------------------------
-(1 row)
-
--- try/catch inside a subtransaction block
-CREATE FUNCTION try_catch_inside_subtransaction() RETURNS void
-AS $$
-with plpy.subtransaction():
-     plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-     try:
-         plpy.execute("INSERT INTO subtransaction_tbl VALUES ('a')")
-     except plpy.SPIError:
-         plpy.notice("caught")
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "try_catch_inside_subtransaction"
-DETAIL:  SyntaxError: invalid syntax (<string>, line 3)
-SELECT try_catch_inside_subtransaction();
-ERROR:  function try_catch_inside_subtransaction() does not exist
-LINE 1: SELECT try_catch_inside_subtransaction();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-TRUNCATE subtransaction_tbl;
-ALTER TABLE subtransaction_tbl ADD PRIMARY KEY (i);
-CREATE FUNCTION pk_violation_inside_subtransaction() RETURNS void
-AS $$
-with plpy.subtransaction():
-     plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-     try:
-         plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-     except plpy.SPIError:
-         plpy.notice("caught")
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "pk_violation_inside_subtransaction"
-DETAIL:  SyntaxError: invalid syntax (<string>, line 3)
-SELECT pk_violation_inside_subtransaction();
-ERROR:  function pk_violation_inside_subtransaction() does not exist
-LINE 1: SELECT pk_violation_inside_subtransaction();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT * FROM subtransaction_tbl;
- i 
----
-(0 rows)
-
-DROP TABLE subtransaction_tbl;
--- cursor/subtransactions interactions
-CREATE FUNCTION cursor_in_subxact() RETURNS int AS $$
-with plpy.subtransaction():
-    cur = plpy.cursor("select * from generate_series(1, 20) as gen(i)")
-    cur.fetch(10)
-fetched = cur.fetch(10);
-return int(fetched[5]["i"])
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "cursor_in_subxact"
-DETAIL:  SyntaxError: invalid syntax (<string>, line 3)
-CREATE FUNCTION cursor_aborted_subxact() RETURNS int AS $$
-try:
-    with plpy.subtransaction():
-        cur = plpy.cursor("select * from generate_series(1, 20) as gen(i)")
-        cur.fetch(10);
-        plpy.execute("select no_such_function()")
-except plpy.SPIError:
-    fetched = cur.fetch(10)
-    return int(fetched[5]["i"])
-return 0 # not reached
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "cursor_aborted_subxact"
-DETAIL:  SyntaxError: invalid syntax (<string>, line 4)
-CREATE FUNCTION cursor_plan_aborted_subxact() RETURNS int AS $$
-try:
-    with plpy.subtransaction():
-        plpy.execute('create temporary table tmp(i) '
-                     'as select generate_series(1, 10)')
-        plan = plpy.prepare("select i from tmp")
-        cur = plpy.cursor(plan)
-        plpy.execute("select no_such_function()")
-except plpy.SPIError:
-    fetched = cur.fetch(5)
-    return fetched[2]["i"]
-return 0 # not reached
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "cursor_plan_aborted_subxact"
-DETAIL:  SyntaxError: invalid syntax (<string>, line 4)
-CREATE FUNCTION cursor_close_aborted_subxact() RETURNS boolean AS $$
-try:
-    with plpy.subtransaction():
-        cur = plpy.cursor('select 1')
-        plpy.execute("select no_such_function()")
-except plpy.SPIError:
-    cur.close()
-    return True
-return False # not reached
-$$ LANGUAGE plpythonu;
-ERROR:  could not compile PL/Python function "cursor_close_aborted_subxact"
-DETAIL:  SyntaxError: invalid syntax (<string>, line 4)
-SELECT cursor_in_subxact();
-ERROR:  function cursor_in_subxact() does not exist
-LINE 1: SELECT cursor_in_subxact();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT cursor_aborted_subxact();
-ERROR:  function cursor_aborted_subxact() does not exist
-LINE 1: SELECT cursor_aborted_subxact();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT cursor_plan_aborted_subxact();
-ERROR:  function cursor_plan_aborted_subxact() does not exist
-LINE 1: SELECT cursor_plan_aborted_subxact();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-SELECT cursor_close_aborted_subxact();
-ERROR:  function cursor_close_aborted_subxact() does not exist
-LINE 1: SELECT cursor_close_aborted_subxact();
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
index eb562821a27bb1cb57f22298deacf90f9975969b..71b433ef2672a4401fd8177a834271cdc6eaedad 100644 (file)
@@ -242,12 +242,6 @@ PLy_traceback(PyObject *e, PyObject *v, PyObject *tb,
 
        PG_TRY();
        {
-           /*
-            * Ancient versions of Python (circa 2.3) contain a bug whereby
-            * the fetches below can fail if the error indicator is set.
-            */
-           PyErr_Clear();
-
            lineno = PyObject_GetAttrString(tb, "tb_lineno");
            if (lineno == NULL)
                elog(ERROR, "could not get line number from Python traceback");
index 4a1df3ee7ea6f63a30ad5bd25e4921eadf8b2d37..6d981a0a06dee9b151ddbe016541f904935bdb93 100644 (file)
 #include <Python.h>
 #endif
 
-/*
- * Py_ssize_t compat for Python <= 2.4
- */
-#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
-typedef int Py_ssize_t;
-
-#define PY_SSIZE_T_MAX INT_MAX
-#define PY_SSIZE_T_MIN INT_MIN
-#endif
-
 /*
  * Python 2/3 strings/unicode/bytes handling.  Python 2 has strings
  * and unicode, Python 3 has strings, which are unicode on the C
@@ -80,15 +70,6 @@ typedef int Py_ssize_t;
  * string to a Python string it converts the C string from the
  * PostgreSQL server encoding to a Python Unicode object.
  */
-
-#if PY_VERSION_HEX < 0x02060000
-/* This is exactly the compatibility layer that Python 2.6 uses. */
-#define PyBytes_AsString PyString_AsString
-#define PyBytes_FromStringAndSize PyString_FromStringAndSize
-#define PyBytes_Size PyString_Size
-#define PyObject_Bytes PyObject_Str
-#endif
-
 #if PY_MAJOR_VERSION >= 3
 #define PyString_Check(x) 0
 #define PyString_AsString(x) PLyUnicode_AsString(x)
@@ -104,16 +85,6 @@ typedef int Py_ssize_t;
 #define PyInt_AsLong(x) PyLong_AsLong(x)
 #endif
 
-/*
- * PyVarObject_HEAD_INIT was added in Python 2.6.  Its use is
- * necessary to handle both Python 2 and 3.  This replacement
- * definition is for Python <=2.5
- */
-#ifndef PyVarObject_HEAD_INIT
-#define PyVarObject_HEAD_INIT(type, size)      \
-       PyObject_HEAD_INIT(type) size,
-#endif
-
 /* Python 3 removed the Py_TPFLAGS_HAVE_ITER flag */
 #if PY_MAJOR_VERSION >= 3
 #define Py_TPFLAGS_HAVE_ITER 0
index 398c65720ced41349550356f6e1fb115d104d998..38c861782856921a49c76d2a507855488daa691b 100644 (file)
@@ -8,43 +8,6 @@ CREATE TABLE subtransaction_tbl (
     i integer
 );
 
--- Explicit case for Python <2.6
-
-CREATE FUNCTION subtransaction_test(what_error text = NULL) RETURNS text
-AS $$
-import sys
-subxact = plpy.subtransaction()
-subxact.__enter__()
-exc = True
-try:
-    try:
-        plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
-        plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
-        if what_error == "SPI":
-            plpy.execute("INSERT INTO subtransaction_tbl VALUES ('oops')")
-        elif what_error == "Python":
-            raise Exception("Python exception")
-    except:
-        exc = False
-        subxact.__exit__(*sys.exc_info())
-        raise
-finally:
-    if exc:
-        subxact.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
-
-SELECT subtransaction_test();
-SELECT * FROM subtransaction_tbl;
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_test('SPI');
-SELECT * FROM subtransaction_tbl;
-TRUNCATE subtransaction_tbl;
-SELECT subtransaction_test('Python');
-SELECT * FROM subtransaction_tbl;
-TRUNCATE subtransaction_tbl;
-
--- Context manager case for Python >=2.6
-
 CREATE FUNCTION subtransaction_ctx_test(what_error text = NULL) RETURNS text
 AS $$
 with plpy.subtransaction():