-- suppress CONTEXT so that function OIDs aren't in output \set VERBOSITY terse -- Test composite-type arguments select tcl_composite_arg_ref1(row('tkey', 42, 'ref2')); select tcl_composite_arg_ref2(row('tkey', 42, 'ref2')); -- More tests for composite argument/result types create domain d_comp1 as T_comp1 check ((value).ref1 > 0); create function tcl_record_arg(record, fldname text) returns int as ' return $1($2) ' language pltcl; select tcl_record_arg(row('tkey', 42, 'ref2')::T_comp1, 'ref1'); select tcl_record_arg(row('tkey', 42, 'ref2')::d_comp1, 'ref1'); select tcl_record_arg(row(2,4), 'f2'); create function tcl_cdomain_arg(d_comp1) returns int as ' return $1(ref1) ' language pltcl; select tcl_cdomain_arg(row('tkey', 42, 'ref2')); select tcl_cdomain_arg(row('tkey', 42, 'ref2')::T_comp1); select tcl_cdomain_arg(row('tkey', -1, 'ref2')); -- fail -- Test argisnull primitive select tcl_argisnull('foo'); select tcl_argisnull(''); select tcl_argisnull(null); -- test some error cases create function tcl_error(out a int, out b int) as $$return {$$ language pltcl; select tcl_error(); create function bad_record(out a text, out b text) as $$return [list a]$$ language pltcl; select bad_record(); create function bad_field(out a text, out b text) as $$return [list a 1 b 2 cow 3]$$ language pltcl; select bad_field(); -- test compound return select * from tcl_test_cube_squared(5); -- test SRF select * from tcl_test_squared_rows(0,5); select * from tcl_test_sequence(0,5) as a; select 1, tcl_test_sequence(0,5); create function non_srf() returns int as $$return_next 1$$ language pltcl; select non_srf(); create function bad_record_srf(out a text, out b text) returns setof record as $$ return_next [list a] $$ language pltcl; select bad_record_srf(); create function bad_field_srf(out a text, out b text) returns setof record as $$ return_next [list a 1 b 2 cow 3] $$ language pltcl; select bad_field_srf(); -- test composite and domain-over-composite results create function tcl_composite_result(int) returns T_comp1 as $$ return [list tkey tkey1 ref1 $1 ref2 ref22] $$ language pltcl; select tcl_composite_result(1001); select * from tcl_composite_result(1002); create function tcl_dcomposite_result(int) returns d_comp1 as $$ return [list tkey tkey2 ref1 $1 ref2 ref42] $$ language pltcl; select tcl_dcomposite_result(1001); select * from tcl_dcomposite_result(1002); select * from tcl_dcomposite_result(-1); -- fail create function tcl_record_result(int) returns record as $$ return [list q1 sometext q2 $1 q3 moretext] $$ language pltcl; select tcl_record_result(42); -- fail select * from tcl_record_result(42); -- fail select * from tcl_record_result(42) as (q1 text, q2 int, q3 text); select * from tcl_record_result(42) as (q1 text, q2 int, q3 text, q4 int); select * from tcl_record_result(42) as (q1 text, q2 int, q4 int); -- fail -- test quote select tcl_eval('quote foo bar'); select tcl_eval('quote [format %c 39]'); select tcl_eval('quote [format %c 92]'); -- Test argisnull select tcl_eval('argisnull'); select tcl_eval('argisnull 14'); select tcl_eval('argisnull abc'); -- Test return_null select tcl_eval('return_null 14'); -- Test spi_exec select tcl_eval('spi_exec'); select tcl_eval('spi_exec -count'); select tcl_eval('spi_exec -array'); select tcl_eval('spi_exec -count abc'); select tcl_eval('spi_exec query loop body toomuch'); select tcl_eval('spi_exec "begin; rollback;"'); -- Test spi_execp select tcl_eval('spi_execp'); select tcl_eval('spi_execp -count'); select tcl_eval('spi_execp -array'); select tcl_eval('spi_execp -count abc'); select tcl_eval('spi_execp -nulls'); select tcl_eval('spi_execp ""'); -- test spi_prepare select tcl_eval('spi_prepare'); select tcl_eval('spi_prepare a b'); select tcl_eval('spi_prepare a "b {"'); select tcl_error_handling_test($tcl$spi_prepare "select moo" []$tcl$); -- test full error text select tcl_error_handling_test($tcl$ spi_exec "DO $$ BEGIN RAISE 'my message' USING HINT = 'my hint' , DETAIL = 'my detail' , SCHEMA = 'my schema' , TABLE = 'my table' , COLUMN = 'my column' , CONSTRAINT = 'my constraint' , DATATYPE = 'my datatype' ; END$$;" $tcl$); -- verify tcl_error_handling_test() properly reports non-postgres errors select tcl_error_handling_test('moo'); -- test elog select tcl_eval('elog'); select tcl_eval('elog foo bar'); -- test forced error select tcl_eval('error "forced error"'); -- test loop control in spi_exec[p] select tcl_spi_exec(true, 'break'); select tcl_spi_exec(true, 'continue'); select tcl_spi_exec(true, 'error'); select tcl_spi_exec(true, 'return'); select tcl_spi_exec(false, 'break'); select tcl_spi_exec(false, 'continue'); select tcl_spi_exec(false, 'error'); select tcl_spi_exec(false, 'return'); -- forcibly run the Tcl event loop for awhile, to check that we have not -- messed things up too badly by disabling the Tcl notifier subsystem select tcl_eval($$ unset -nocomplain ::tcl_vwait after 100 {set ::tcl_vwait 1} vwait ::tcl_vwait unset -nocomplain ::tcl_vwait$$);