aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2010-01-22 15:45:15 +0000
committerPeter Eisentraut <peter_e@gmx.net>2010-01-22 15:45:15 +0000
commitadb77640304a375883eaaec9eb9b21036c2be0bd (patch)
tree3f143de99489c23d970af045ee73596f3d17e4bf /src
parent306a4287c3503bdd3c3e490d80508e00e1708c02 (diff)
downloadpostgresql-adb77640304a375883eaaec9eb9b21036c2be0bd.tar.gz
postgresql-adb77640304a375883eaaec9eb9b21036c2be0bd.zip
PL/Python DO handler
Also cleaned up some redundancies between the primary error messages and the error context in PL/Python. Hannu Valtonen
Diffstat (limited to 'src')
-rw-r--r--src/include/catalog/catversion.h4
-rw-r--r--src/include/catalog/pg_pltemplate.h8
-rw-r--r--src/pl/plpython/Makefile3
-rw-r--r--src/pl/plpython/expected/plpython_do.out6
-rw-r--r--src/pl/plpython/expected/plpython_error.out3
-rw-r--r--src/pl/plpython/plpython.c71
-rw-r--r--src/pl/plpython/sql/plpython_do.sql3
7 files changed, 83 insertions, 15 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index f37b9077a9b..29e04bea010 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.576 2010/01/19 14:11:32 mha Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.577 2010/01/22 15:45:15 petere Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201001191
+#define CATALOG_VERSION_NO 201001221
#endif
diff --git a/src/include/catalog/pg_pltemplate.h b/src/include/catalog/pg_pltemplate.h
index f7b77081cbc..59c890100b6 100644
--- a/src/include/catalog/pg_pltemplate.h
+++ b/src/include/catalog/pg_pltemplate.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_pltemplate.h,v 1.12 2010/01/05 01:06:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_pltemplate.h,v 1.13 2010/01/22 15:45:15 petere Exp $
*
* NOTES
* the genbki.pl script reads this file and generates .bki
@@ -72,8 +72,8 @@ DATA(insert ( "pltcl" t t "pltcl_call_handler" _null_ _null_ "$libdir/pltcl" _n
DATA(insert ( "pltclu" f f "pltclu_call_handler" _null_ _null_ "$libdir/pltcl" _null_ ));
DATA(insert ( "plperl" t t "plperl_call_handler" "plperl_inline_handler" "plperl_validator" "$libdir/plperl" _null_ ));
DATA(insert ( "plperlu" f f "plperl_call_handler" "plperl_inline_handler" "plperl_validator" "$libdir/plperl" _null_ ));
-DATA(insert ( "plpythonu" f f "plpython_call_handler" _null_ _null_ "$libdir/plpython" _null_ ));
-DATA(insert ( "plpython2u" f f "plpython_call_handler" _null_ _null_ "$libdir/plpython2" _null_ ));
-DATA(insert ( "plpython3u" f f "plpython_call_handler" _null_ _null_ "$libdir/plpython3" _null_ ));
+DATA(insert ( "plpythonu" f f "plpython_call_handler" "plpython_inline_handler" _null_ "$libdir/plpython" _null_ ));
+DATA(insert ( "plpython2u" f f "plpython_call_handler" "plpython_inline_handler" _null_ "$libdir/plpython2" _null_ ));
+DATA(insert ( "plpython3u" f f "plpython_call_handler" "plpython_inline_handler" _null_ "$libdir/plpython3" _null_ ));
#endif /* PG_PLTEMPLATE_H */
diff --git a/src/pl/plpython/Makefile b/src/pl/plpython/Makefile
index 5db880b08e1..4b18076a0f4 100644
--- a/src/pl/plpython/Makefile
+++ b/src/pl/plpython/Makefile
@@ -1,4 +1,4 @@
-# $PostgreSQL: pgsql/src/pl/plpython/Makefile,v 1.35 2009/12/15 22:59:54 petere Exp $
+# $PostgreSQL: pgsql/src/pl/plpython/Makefile,v 1.36 2010/01/22 15:45:15 petere Exp $
subdir = src/pl/plpython
top_builddir = ../../..
@@ -66,6 +66,7 @@ REGRESS = \
plpython_schema \
plpython_populate \
plpython_test \
+ plpython_do \
plpython_global \
plpython_import \
plpython_spi \
diff --git a/src/pl/plpython/expected/plpython_do.out b/src/pl/plpython/expected/plpython_do.out
new file mode 100644
index 00000000000..9de261ae450
--- /dev/null
+++ b/src/pl/plpython/expected/plpython_do.out
@@ -0,0 +1,6 @@
+DO $$ plpy.notice("This is plpythonu.") $$ LANGUAGE plpythonu;
+NOTICE: This is plpythonu.
+CONTEXT: PL/Python anonymous code block
+DO $$ nonsense $$ LANGUAGE plpythonu;
+ERROR: PL/Python: NameError: global name 'nonsense' is not defined
+CONTEXT: PL/Python anonymous code block
diff --git a/src/pl/plpython/expected/plpython_error.out b/src/pl/plpython/expected/plpython_error.out
index 36ffa8b5bd4..1f24c13892d 100644
--- a/src/pl/plpython/expected/plpython_error.out
+++ b/src/pl/plpython/expected/plpython_error.out
@@ -22,8 +22,7 @@ CREATE FUNCTION exception_index_invalid(text) RETURNS text
'return args[1]'
LANGUAGE plpythonu;
SELECT exception_index_invalid('test');
-ERROR: PL/Python: PL/Python function "exception_index_invalid" failed
-DETAIL: IndexError: list index out of range
+ERROR: PL/Python: IndexError: list index out of range
CONTEXT: PL/Python function "exception_index_invalid"
/* check handling of nested exceptions
*/
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 8ddb08c2029..c6accdac9a8 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -1,7 +1,7 @@
/**********************************************************************
* plpython.c - python as a procedural language for PostgreSQL
*
- * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.135 2010/01/16 11:03:51 petere Exp $
+ * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.136 2010/01/22 15:45:15 petere Exp $
*
*********************************************************************
*/
@@ -243,14 +243,13 @@ typedef struct PLyResultObject
/* function declarations */
-/* Two exported functions: first is the magic telling Postgresql
- * what function call interface it implements. Second is for
- * initialization of the interpreter during library load.
- */
+/* exported functions */
Datum plpython_call_handler(PG_FUNCTION_ARGS);
+Datum plpython_inline_handler(PG_FUNCTION_ARGS);
void _PG_init(void);
PG_FUNCTION_INFO_V1(plpython_call_handler);
+PG_FUNCTION_INFO_V1(plpython_inline_handler);
/* most of the remaining of the declarations, all static */
@@ -419,6 +418,12 @@ plpython_error_callback(void *arg)
}
static void
+plpython_inline_error_callback(void *arg)
+{
+ errcontext("PL/Python anonymous code block");
+}
+
+static void
plpython_trigger_error_callback(void *arg)
{
if (PLy_curr_procedure)
@@ -495,6 +500,60 @@ plpython_call_handler(PG_FUNCTION_ARGS)
return retval;
}
+Datum
+plpython_inline_handler(PG_FUNCTION_ARGS)
+{
+ InlineCodeBlock *codeblock = (InlineCodeBlock *) DatumGetPointer(PG_GETARG_DATUM(0));
+ FunctionCallInfoData fake_fcinfo;
+ FmgrInfo flinfo;
+ PLyProcedure *save_curr_proc;
+ PLyProcedure *volatile proc = NULL;
+ ErrorContextCallback plerrcontext;
+
+ if (SPI_connect() != SPI_OK_CONNECT)
+ elog(ERROR, "SPI_connect failed");
+
+ save_curr_proc = PLy_curr_procedure;
+
+ /*
+ * Setup error traceback support for ereport()
+ */
+ plerrcontext.callback = plpython_inline_error_callback;
+ plerrcontext.previous = error_context_stack;
+ error_context_stack = &plerrcontext;
+
+ MemSet(&fake_fcinfo, 0, sizeof(fake_fcinfo));
+ MemSet(&flinfo, 0, sizeof(flinfo));
+ fake_fcinfo.flinfo = &flinfo;
+ flinfo.fn_oid = InvalidOid;
+ flinfo.fn_mcxt = CurrentMemoryContext;
+
+ proc = PLy_malloc0(sizeof(PLyProcedure));
+ proc->pyname = PLy_strdup("__plpython_inline_block");
+ proc->result.out.d.typoid = VOIDOID;
+
+ PG_TRY();
+ {
+ PLy_procedure_compile(proc, codeblock->source_text);
+ PLy_curr_procedure = proc;
+ PLy_function_handler(&fake_fcinfo, proc);
+ }
+ PG_CATCH();
+ {
+ PLy_curr_procedure = save_curr_proc;
+ PyErr_Clear();
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
+
+ /* Pop the error context stack */
+ error_context_stack = plerrcontext.previous;
+
+ PLy_curr_procedure = save_curr_proc;
+
+ PG_RETURN_VOID();
+}
+
/* trigger and function sub handlers
*
* the python function is expected to return Py_None if the tuple is
@@ -1107,7 +1166,7 @@ PLy_procedure_call(PLyProcedure *proc, char *kargs, PyObject *vargs)
if (rv == NULL || PyErr_Occurred())
{
Py_XDECREF(rv);
- PLy_elog(ERROR, "PL/Python function \"%s\" failed", proc->proname);
+ PLy_elog(ERROR, NULL);
}
return rv;
diff --git a/src/pl/plpython/sql/plpython_do.sql b/src/pl/plpython/sql/plpython_do.sql
new file mode 100644
index 00000000000..8596c39d37a
--- /dev/null
+++ b/src/pl/plpython/sql/plpython_do.sql
@@ -0,0 +1,3 @@
+DO $$ plpy.notice("This is plpythonu.") $$ LANGUAGE plpythonu;
+
+DO $$ nonsense $$ LANGUAGE plpythonu;