1-- suppress CONTEXT so that function OIDs aren't in output 2\set VERBOSITY terse 3 4-- Test composite-type arguments 5select tcl_composite_arg_ref1(row('tkey', 42, 'ref2')); 6select tcl_composite_arg_ref2(row('tkey', 42, 'ref2')); 7 8-- More tests for composite argument/result types 9 10create domain d_comp1 as T_comp1 check ((value).ref1 > 0); 11 12create function tcl_record_arg(record, fldname text) returns int as ' 13 return $1($2) 14' language pltcl; 15 16select tcl_record_arg(row('tkey', 42, 'ref2')::T_comp1, 'ref1'); 17select tcl_record_arg(row('tkey', 42, 'ref2')::d_comp1, 'ref1'); 18select tcl_record_arg(row(2,4), 'f2'); 19 20create function tcl_cdomain_arg(d_comp1) returns int as ' 21 return $1(ref1) 22' language pltcl; 23 24select tcl_cdomain_arg(row('tkey', 42, 'ref2')); 25select tcl_cdomain_arg(row('tkey', 42, 'ref2')::T_comp1); 26select tcl_cdomain_arg(row('tkey', -1, 'ref2')); -- fail 27 28-- Test argisnull primitive 29select tcl_argisnull('foo'); 30select tcl_argisnull(''); 31select tcl_argisnull(null); 32 33-- test some error cases 34create function tcl_error(out a int, out b int) as $$return {$$ language pltcl; 35select tcl_error(); 36 37create function bad_record(out a text, out b text) as $$return [list a]$$ language pltcl; 38select bad_record(); 39 40create function bad_field(out a text, out b text) as $$return [list a 1 b 2 cow 3]$$ language pltcl; 41select bad_field(); 42 43-- test compound return 44select * from tcl_test_cube_squared(5); 45 46-- test SRF 47select * from tcl_test_squared_rows(0,5); 48 49select * from tcl_test_sequence(0,5) as a; 50 51select 1, tcl_test_sequence(0,5); 52 53create function non_srf() returns int as $$return_next 1$$ language pltcl; 54select non_srf(); 55 56create function bad_record_srf(out a text, out b text) returns setof record as $$ 57return_next [list a] 58$$ language pltcl; 59select bad_record_srf(); 60 61create function bad_field_srf(out a text, out b text) returns setof record as $$ 62return_next [list a 1 b 2 cow 3] 63$$ language pltcl; 64select bad_field_srf(); 65 66-- test composite and domain-over-composite results 67create function tcl_composite_result(int) returns T_comp1 as $$ 68return [list tkey tkey1 ref1 $1 ref2 ref22] 69$$ language pltcl; 70select tcl_composite_result(1001); 71select * from tcl_composite_result(1002); 72 73create function tcl_dcomposite_result(int) returns d_comp1 as $$ 74return [list tkey tkey2 ref1 $1 ref2 ref42] 75$$ language pltcl; 76select tcl_dcomposite_result(1001); 77select * from tcl_dcomposite_result(1002); 78select * from tcl_dcomposite_result(-1); -- fail 79 80create function tcl_record_result(int) returns record as $$ 81return [list q1 sometext q2 $1 q3 moretext] 82$$ language pltcl; 83select tcl_record_result(42); -- fail 84select * from tcl_record_result(42); -- fail 85select * from tcl_record_result(42) as (q1 text, q2 int, q3 text); 86select * from tcl_record_result(42) as (q1 text, q2 int, q3 text, q4 int); 87select * from tcl_record_result(42) as (q1 text, q2 int, q4 int); -- fail 88 89-- test quote 90select tcl_eval('quote foo bar'); 91select tcl_eval('quote [format %c 39]'); 92select tcl_eval('quote [format %c 92]'); 93 94-- Test argisnull 95select tcl_eval('argisnull'); 96select tcl_eval('argisnull 14'); 97select tcl_eval('argisnull abc'); 98 99-- Test return_null 100select tcl_eval('return_null 14'); 101 102-- Test spi_exec 103select tcl_eval('spi_exec'); 104select tcl_eval('spi_exec -count'); 105select tcl_eval('spi_exec -array'); 106select tcl_eval('spi_exec -count abc'); 107select tcl_eval('spi_exec query loop body toomuch'); 108select tcl_eval('spi_exec "begin; rollback;"'); 109 110-- Test spi_execp 111select tcl_eval('spi_execp'); 112select tcl_eval('spi_execp -count'); 113select tcl_eval('spi_execp -array'); 114select tcl_eval('spi_execp -count abc'); 115select tcl_eval('spi_execp -nulls'); 116select tcl_eval('spi_execp ""'); 117 118-- test spi_prepare 119select tcl_eval('spi_prepare'); 120select tcl_eval('spi_prepare a b'); 121select tcl_eval('spi_prepare a "b {"'); 122select tcl_error_handling_test($tcl$spi_prepare "select moo" []$tcl$); 123 124-- test full error text 125select tcl_error_handling_test($tcl$ 126spi_exec "DO $$ 127BEGIN 128RAISE 'my message' 129 USING HINT = 'my hint' 130 , DETAIL = 'my detail' 131 , SCHEMA = 'my schema' 132 , TABLE = 'my table' 133 , COLUMN = 'my column' 134 , CONSTRAINT = 'my constraint' 135 , DATATYPE = 'my datatype' 136; 137END$$;" 138$tcl$); 139 140-- verify tcl_error_handling_test() properly reports non-postgres errors 141select tcl_error_handling_test('moo'); 142 143-- test elog 144select tcl_eval('elog'); 145select tcl_eval('elog foo bar'); 146 147-- test forced error 148select tcl_eval('error "forced error"'); 149 150-- test loop control in spi_exec[p] 151select tcl_spi_exec(true, 'break'); 152select tcl_spi_exec(true, 'continue'); 153select tcl_spi_exec(true, 'error'); 154select tcl_spi_exec(true, 'return'); 155select tcl_spi_exec(false, 'break'); 156select tcl_spi_exec(false, 'continue'); 157select tcl_spi_exec(false, 'error'); 158select tcl_spi_exec(false, 'return'); 159 160-- forcibly run the Tcl event loop for awhile, to check that we have not 161-- messed things up too badly by disabling the Tcl notifier subsystem 162select tcl_eval($$ 163 unset -nocomplain ::tcl_vwait 164 after 100 {set ::tcl_vwait 1} 165 vwait ::tcl_vwait 166 unset -nocomplain ::tcl_vwait$$); 167