On 23/12/10 14:41, Jan Urbański wrote:
> Here's a patch implementing a validator functoin mentioned in
> http://archives.postgresql.org/pgsql-hackers/2010-12/msg01991.php. It's
> an incremental patch on top of the plpython-refactor patch sent eariler.
>
> Git branch for this patch:
> https://github.com/wulczer/postgres/tree/validator.
>
> Cheers,
> Jan
Yes, here's a patch.
Jan
diff --git a/src/include/catalog/pg_pltemplate.h b/src/include/catalog/pg_pltemplate.h
index 6befcfa..2f1d8e1 100644
*** a/src/include/catalog/pg_pltemplate.h
--- b/src/include/catalog/pg_pltemplate.h
*************** DATA(insert ( "pltcl" t t "pltcl_call_h
*** 72,79 ****
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" "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 "plpython3_call_handler" "plpython3_inline_handler" _null_ "$libdir/plpython3" _null_ ));
#endif /* PG_PLTEMPLATE_H */
--- 72,79 ----
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" "plpython_inline_handler" "plpython_validator" "$libdir/plpython" _null_ ));
! DATA(insert ( "plpython2u" f f "plpython_call_handler" "plpython_inline_handler" "plpython_validator" "$libdir/plpython2" _null_ ));
! DATA(insert ( "plpython3u" f f "plpython3_call_handler" "plpython3_inline_handler" "plpython3_validator" "$libdir/plpython3" _null_ ));
#endif /* PG_PLTEMPLATE_H */
diff --git a/src/pl/plpython/expected/plpython_error.out b/src/pl/plpython/expected/plpython_error.out
index 70890a8..a9e1f15 100644
*** a/src/pl/plpython/expected/plpython_error.out
--- b/src/pl/plpython/expected/plpython_error.out
***************
*** 1,6 ****
--- 1,30 ----
-- 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 (<string>, 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 (<string>, 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 (<string>, line 2)
+ RESET check_function_bodies;
/* Flat out syntax error
*/
CREATE FUNCTION sql_syntax_error() RETURNS text
diff --git a/src/pl/plpython/expected/plpython_record.out b/src/pl/plpython/expected/plpython_record.out
index c8c4f9d..770f764 100644
*** a/src/pl/plpython/expected/plpython_record.out
--- b/src/pl/plpython/expected/plpython_record.out
*************** CREATE FUNCTION test_in_out_params_multi
*** 47,52 ****
--- 47,53 ----
second out text, third out text) AS $$
return first + '_record_in_to_out';
$$ LANGUAGE plpythonu;
+ ERROR: PL/Python functions cannot return type record
CREATE FUNCTION test_inout_params(first inout text) AS $$
return first + '_inout';
$$ LANGUAGE plpythonu;
*************** SELECT * FROM test_in_out_params('test_i
*** 299,305 ****
-- this doesn't work yet :-(
SELECT * FROM test_in_out_params_multi('test_in');
! ERROR: PL/Python functions cannot return type record
SELECT * FROM test_inout_params('test_in');
first
---------------
--- 300,309 ----
-- this doesn't work yet :-(
SELECT * FROM test_in_out_params_multi('test_in');
! ERROR: function test_in_out_params_multi(unknown) does not exist
! LINE 1: SELECT * FROM test_in_out_params_multi('test_in');
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
SELECT * FROM test_inout_params('test_in');
first
---------------
diff --git a/src/pl/plpython/expected/plpython_types.out b/src/pl/plpython/expected/plpython_types.out
index 982005b..e74a400 100644
*** a/src/pl/plpython/expected/plpython_types.out
--- b/src/pl/plpython/expected/plpython_types.out
*************** PL/Python function "test_type_conversion
*** 571,579 ****
CREATE FUNCTION test_type_conversion_array_record() RETURNS type_record[] AS $$
return [None]
$$ LANGUAGE plpythonu;
- SELECT * FROM test_type_conversion_array_record();
ERROR: PL/Python functions cannot return type type_record[]
DETAIL: PL/Python does not support conversion to arrays of row types.
CREATE FUNCTION test_type_conversion_array_string() RETURNS text[] AS $$
return 'abc'
$$ LANGUAGE plpythonu;
--- 571,583 ----
CREATE FUNCTION test_type_conversion_array_record() RETURNS type_record[] AS $$
return [None]
$$ LANGUAGE plpythonu;
ERROR: PL/Python functions cannot return type type_record[]
DETAIL: PL/Python does not support conversion to arrays of row types.
+ SELECT * FROM test_type_conversion_array_record();
+ ERROR: function test_type_conversion_array_record() does not exist
+ LINE 1: SELECT * FROM test_type_conversion_array_record();
+ ^
+ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
CREATE FUNCTION test_type_conversion_array_string() RETURNS text[] AS $$
return 'abc'
$$ LANGUAGE plpythonu;
diff --git a/src/pl/plpython/expected/plpython_types_3.out b/src/pl/plpython/expected/plpython_types_3.out
index eeb23b7..577c1ff 100644
*** a/src/pl/plpython/expected/plpython_types_3.out
--- b/src/pl/plpython/expected/plpython_types_3.out
*************** PL/Python function "test_type_conversion
*** 571,579 ****
CREATE FUNCTION test_type_conversion_array_record() RETURNS type_record[] AS $$
return [None]
$$ LANGUAGE plpython3u;
- SELECT * FROM test_type_conversion_array_record();
ERROR: PL/Python functions cannot return type type_record[]
DETAIL: PL/Python does not support conversion to arrays of row types.
CREATE FUNCTION test_type_conversion_array_string() RETURNS text[] AS $$
return 'abc'
$$ LANGUAGE plpython3u;
--- 571,583 ----
CREATE FUNCTION test_type_conversion_array_record() RETURNS type_record[] AS $$
return [None]
$$ LANGUAGE plpython3u;
ERROR: PL/Python functions cannot return type type_record[]
DETAIL: PL/Python does not support conversion to arrays of row types.
+ SELECT * FROM test_type_conversion_array_record();
+ ERROR: function test_type_conversion_array_record() does not exist
+ LINE 1: SELECT * FROM test_type_conversion_array_record();
+ ^
+ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
CREATE FUNCTION test_type_conversion_array_string() RETURNS text[] AS $$
return 'abc'
$$ LANGUAGE plpython3u;
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 67eb0f3..ba310c0 100644
*** a/src/pl/plpython/plpython.c
--- b/src/pl/plpython/plpython.c
*************** typedef struct PLyResultObject
*** 248,262 ****
--- 248,265 ----
#if PY_MAJOR_VERSION >= 3
/* Use separate names to avoid clash in pg_pltemplate */
+ #define plpython_validator plpython3_validator
#define plpython_call_handler plpython3_call_handler
#define plpython_inline_handler plpython3_inline_handler
#endif
/* exported functions */
+ Datum plpython_validator(PG_FUNCTION_ARGS);
Datum plpython_call_handler(PG_FUNCTION_ARGS);
Datum plpython_inline_handler(PG_FUNCTION_ARGS);
void _PG_init(void);
+ PG_FUNCTION_INFO_V1(plpython_validator);
PG_FUNCTION_INFO_V1(plpython_call_handler);
PG_FUNCTION_INFO_V1(plpython_inline_handler);
*************** plpython_return_error_callback(void *arg
*** 431,436 ****
--- 434,478 ----
errcontext("while creating return value");
}
+ static bool
+ PLy_procedure_is_trigger(Form_pg_proc procStruct)
+ {
+ if (get_typtype(procStruct->prorettype) != TYPTYPE_PSEUDO)
+ return false;
+
+ return (procStruct->prorettype == TRIGGEROID ||
+ (procStruct->prorettype == OPAQUEOID &&
+ procStruct->pronargs == 0));
+ }
+
+ Datum
+ plpython_validator(PG_FUNCTION_ARGS)
+ {
+ Oid funcoid = PG_GETARG_OID(0);
+ HeapTuple tuple;
+ Form_pg_proc procStruct;
+ bool is_trigger;
+
+ if (!check_function_bodies)
+ {
+ PG_RETURN_VOID();
+ }
+
+ /* Get the new function's pg_proc entry */
+ tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcoid));
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for function %u", funcoid);
+ procStruct = (Form_pg_proc) GETSTRUCT(tuple);
+
+ is_trigger = PLy_procedure_is_trigger(procStruct);
+
+ ReleaseSysCache(tuple);
+
+ PLy_procedure_get(funcoid, is_trigger);
+
+ PG_RETURN_VOID();
+ }
+
Datum
plpython_call_handler(PG_FUNCTION_ARGS)
{
diff --git a/src/pl/plpython/sql/plpython_error.sql b/src/pl/plpython/sql/plpython_error.sql
index 5ca6849..6509257 100644
*** a/src/pl/plpython/sql/plpython_error.sql
--- b/src/pl/plpython/sql/plpython_error.sql
***************
*** 2,7 ****
--- 2,30 ----
-- 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;
+
+ /* 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();
+ /* Run the function twice to check if the hashtable entry gets cleaned up */
+ SELECT python_syntax_error();
+
+ RESET check_function_bodies;
+
/* Flat out syntax error
*/
CREATE FUNCTION sql_syntax_error() RETURNS text
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers