Skip to content

Commit 961bed0

Browse files
committed
Expand the regression tests for PL/Tcl.
This raises the test coverage (by line count) in pltcl.c from about 70% to 86%. Karl Lehenbauer and Jim Nasby Discussion: https://postgr.es/m/[email protected]
1 parent 534b6f3 commit 961bed0

File tree

4 files changed

+654
-89
lines changed

4 files changed

+654
-89
lines changed

src/pl/tcl/expected/pltcl_queries.out

+316-20
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,23 @@ select * from T_pkey2 order by key1 using @<, key2 collate "C";
185185

186186
-- show dump of trigger data
187187
insert into trigger_test values(1,'insert');
188-
NOTICE: NEW: {i: 1, v: insert}
188+
NOTICE: NEW: {}
189+
NOTICE: OLD: {}
190+
NOTICE: TG_level: STATEMENT
191+
NOTICE: TG_name: statement_trigger
192+
NOTICE: TG_op: INSERT
193+
NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull}
194+
NOTICE: TG_relid: bogus:12345
195+
NOTICE: TG_table_name: trigger_test
196+
NOTICE: TG_table_schema: public
197+
NOTICE: TG_when: BEFORE
198+
NOTICE: args: {42 {statement trigger}}
199+
NOTICE: NEW: {i: 1, test_argisnull: f, test_return_null: f, test_skip: f, v: insert}
189200
NOTICE: OLD: {}
190201
NOTICE: TG_level: ROW
191202
NOTICE: TG_name: show_trigger_data_trig
192203
NOTICE: TG_op: INSERT
193-
NOTICE: TG_relatts: {{} i v}
204+
NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull}
194205
NOTICE: TG_relid: bogus:12345
195206
NOTICE: TG_table_name: trigger_test
196207
NOTICE: TG_table_schema: public
@@ -232,30 +243,77 @@ NOTICE: TG_table_name: trigger_test_view
232243
NOTICE: TG_table_schema: public
233244
NOTICE: TG_when: {INSTEAD OF}
234245
NOTICE: args: {24 {skidoo view}}
246+
update trigger_test set v = 'update', test_skip=true where i = 1;
247+
NOTICE: NEW: {}
248+
NOTICE: OLD: {}
249+
NOTICE: TG_level: STATEMENT
250+
NOTICE: TG_name: statement_trigger
251+
NOTICE: TG_op: UPDATE
252+
NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull}
253+
NOTICE: TG_relid: bogus:12345
254+
NOTICE: TG_table_name: trigger_test
255+
NOTICE: TG_table_schema: public
256+
NOTICE: TG_when: BEFORE
257+
NOTICE: args: {42 {statement trigger}}
258+
NOTICE: SKIPPING OPERATION UPDATE
235259
update trigger_test set v = 'update' where i = 1;
236-
NOTICE: NEW: {i: 1, v: update}
237-
NOTICE: OLD: {i: 1, v: insert}
260+
NOTICE: NEW: {}
261+
NOTICE: OLD: {}
262+
NOTICE: TG_level: STATEMENT
263+
NOTICE: TG_name: statement_trigger
264+
NOTICE: TG_op: UPDATE
265+
NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull}
266+
NOTICE: TG_relid: bogus:12345
267+
NOTICE: TG_table_name: trigger_test
268+
NOTICE: TG_table_schema: public
269+
NOTICE: TG_when: BEFORE
270+
NOTICE: args: {42 {statement trigger}}
271+
NOTICE: NEW: {i: 1, test_argisnull: f, test_return_null: f, test_skip: f, v: update}
272+
NOTICE: OLD: {i: 1, test_argisnull: f, test_return_null: f, test_skip: f, v: insert}
238273
NOTICE: TG_level: ROW
239274
NOTICE: TG_name: show_trigger_data_trig
240275
NOTICE: TG_op: UPDATE
241-
NOTICE: TG_relatts: {{} i v}
276+
NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull}
242277
NOTICE: TG_relid: bogus:12345
243278
NOTICE: TG_table_name: trigger_test
244279
NOTICE: TG_table_schema: public
245280
NOTICE: TG_when: BEFORE
246281
NOTICE: args: {23 skidoo}
247282
delete from trigger_test;
248283
NOTICE: NEW: {}
249-
NOTICE: OLD: {i: 1, v: update}
284+
NOTICE: OLD: {}
285+
NOTICE: TG_level: STATEMENT
286+
NOTICE: TG_name: statement_trigger
287+
NOTICE: TG_op: DELETE
288+
NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull}
289+
NOTICE: TG_relid: bogus:12345
290+
NOTICE: TG_table_name: trigger_test
291+
NOTICE: TG_table_schema: public
292+
NOTICE: TG_when: BEFORE
293+
NOTICE: args: {42 {statement trigger}}
294+
NOTICE: NEW: {}
295+
NOTICE: OLD: {i: 1, test_argisnull: f, test_return_null: f, test_skip: f, v: update}
250296
NOTICE: TG_level: ROW
251297
NOTICE: TG_name: show_trigger_data_trig
252298
NOTICE: TG_op: DELETE
253-
NOTICE: TG_relatts: {{} i v}
299+
NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull}
254300
NOTICE: TG_relid: bogus:12345
255301
NOTICE: TG_table_name: trigger_test
256302
NOTICE: TG_table_schema: public
257303
NOTICE: TG_when: BEFORE
258304
NOTICE: args: {23 skidoo}
305+
truncate trigger_test;
306+
NOTICE: NEW: {}
307+
NOTICE: OLD: {}
308+
NOTICE: TG_level: STATEMENT
309+
NOTICE: TG_name: statement_trigger
310+
NOTICE: TG_op: TRUNCATE
311+
NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull}
312+
NOTICE: TG_relid: bogus:12345
313+
NOTICE: TG_table_name: trigger_test
314+
NOTICE: TG_table_schema: public
315+
NOTICE: TG_when: BEFORE
316+
NOTICE: args: {42 {statement trigger}}
259317
-- Test composite-type arguments
260318
select tcl_composite_arg_ref1(row('tkey', 42, 'ref2'));
261319
tcl_composite_arg_ref1
@@ -288,6 +346,22 @@ select tcl_argisnull(null);
288346
t
289347
(1 row)
290348

349+
-- should error
350+
insert into trigger_test(test_argisnull) values(true);
351+
NOTICE: NEW: {}
352+
NOTICE: OLD: {}
353+
NOTICE: TG_level: STATEMENT
354+
NOTICE: TG_name: statement_trigger
355+
NOTICE: TG_op: INSERT
356+
NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull}
357+
NOTICE: TG_relid: bogus:12345
358+
NOTICE: TG_table_name: trigger_test
359+
NOTICE: TG_table_schema: public
360+
NOTICE: TG_when: BEFORE
361+
NOTICE: args: {42 {statement trigger}}
362+
ERROR: argisnull cannot be used in triggers
363+
select trigger_data();
364+
ERROR: trigger functions can only be called as triggers
291365
-- Test spi_lastoid primitive
292366
create temp table t1 (f1 int);
293367
select tcl_lastoid('t1');
@@ -304,14 +378,14 @@ select tcl_lastoid('t2') > 0;
304378
(1 row)
305379

306380
-- test some error cases
307-
CREATE FUNCTION tcl_error(OUT a int, OUT b int) AS $$return {$$ LANGUAGE pltcl;
308-
SELECT tcl_error();
381+
create function tcl_error(out a int, out b int) as $$return {$$ language pltcl;
382+
select tcl_error();
309383
ERROR: missing close-brace
310-
CREATE FUNCTION bad_record(OUT a text, OUT b text) AS $$return [list a]$$ LANGUAGE pltcl;
311-
SELECT bad_record();
384+
create function bad_record(out a text, out b text) as $$return [list a]$$ language pltcl;
385+
select bad_record();
312386
ERROR: column name/value list must have even number of elements
313-
CREATE FUNCTION bad_field(OUT a text, OUT b text) AS $$return [list a 1 b 2 cow 3]$$ LANGUAGE pltcl;
314-
SELECT bad_field();
387+
create function bad_field(out a text, out b text) as $$return [list a 1 b 2 cow 3]$$ language pltcl;
388+
select bad_field();
315389
ERROR: column name/value list contains nonexistent column name "cow"
316390
-- test compound return
317391
select * from tcl_test_cube_squared(5);
@@ -351,16 +425,238 @@ select 1, tcl_test_sequence(0,5);
351425
1 | 4
352426
(5 rows)
353427

354-
CREATE FUNCTION non_srf() RETURNS int AS $$return_next 1$$ LANGUAGE pltcl;
428+
create function non_srf() returns int as $$return_next 1$$ language pltcl;
355429
select non_srf();
356430
ERROR: return_next cannot be used in non-set-returning functions
357-
CREATE FUNCTION bad_record_srf(OUT a text, OUT b text) RETURNS SETOF record AS $$
431+
create function bad_record_srf(out a text, out b text) returns setof record as $$
358432
return_next [list a]
359-
$$ LANGUAGE pltcl;
360-
SELECT bad_record_srf();
433+
$$ language pltcl;
434+
select bad_record_srf();
361435
ERROR: column name/value list must have even number of elements
362-
CREATE FUNCTION bad_field_srf(OUT a text, OUT b text) RETURNS SETOF record AS $$
436+
create function bad_field_srf(out a text, out b text) returns setof record as $$
363437
return_next [list a 1 b 2 cow 3]
364-
$$ LANGUAGE pltcl;
365-
SELECT bad_field_srf();
438+
$$ language pltcl;
439+
select bad_field_srf();
366440
ERROR: column name/value list contains nonexistent column name "cow"
441+
-- test quote
442+
select tcl_eval('quote foo bar');
443+
ERROR: wrong # args: should be "quote string"
444+
select tcl_eval('quote [format %c 39]');
445+
tcl_eval
446+
----------
447+
''
448+
(1 row)
449+
450+
select tcl_eval('quote [format %c 92]');
451+
tcl_eval
452+
----------
453+
\\
454+
(1 row)
455+
456+
-- Test argisnull
457+
select tcl_eval('argisnull');
458+
ERROR: wrong # args: should be "argisnull argno"
459+
select tcl_eval('argisnull 14');
460+
ERROR: argno out of range
461+
select tcl_eval('argisnull abc');
462+
ERROR: expected integer but got "abc"
463+
-- Test return_null
464+
select tcl_eval('return_null 14');
465+
ERROR: wrong # args: should be "return_null "
466+
-- should error
467+
insert into trigger_test(test_return_null) values(true);
468+
NOTICE: NEW: {}
469+
NOTICE: OLD: {}
470+
NOTICE: TG_level: STATEMENT
471+
NOTICE: TG_name: statement_trigger
472+
NOTICE: TG_op: INSERT
473+
NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull}
474+
NOTICE: TG_relid: bogus:12345
475+
NOTICE: TG_table_name: trigger_test
476+
NOTICE: TG_table_schema: public
477+
NOTICE: TG_when: BEFORE
478+
NOTICE: args: {42 {statement trigger}}
479+
ERROR: return_null cannot be used in triggers
480+
-- Test spi_exec
481+
select tcl_eval('spi_exec');
482+
ERROR: wrong # args: should be "spi_exec ?-count n? ?-array name? query ?loop body?"
483+
select tcl_eval('spi_exec -count');
484+
ERROR: missing argument to -count or -array
485+
select tcl_eval('spi_exec -array');
486+
ERROR: missing argument to -count or -array
487+
select tcl_eval('spi_exec -count abc');
488+
ERROR: expected integer but got "abc"
489+
select tcl_eval('spi_exec query loop body toomuch');
490+
ERROR: wrong # args: should be "query ?loop body?"
491+
select tcl_eval('spi_exec "begin; rollback;"');
492+
ERROR: pltcl: SPI_execute failed: SPI_ERROR_TRANSACTION
493+
-- Test spi_execp
494+
select tcl_eval('spi_execp');
495+
ERROR: missing argument to -count or -array
496+
select tcl_eval('spi_execp -count');
497+
ERROR: missing argument to -array, -count or -nulls
498+
select tcl_eval('spi_execp -array');
499+
ERROR: missing argument to -array, -count or -nulls
500+
select tcl_eval('spi_execp -count abc');
501+
ERROR: expected integer but got "abc"
502+
select tcl_eval('spi_execp -nulls');
503+
ERROR: missing argument to -array, -count or -nulls
504+
select tcl_eval('spi_execp ""');
505+
ERROR: invalid queryid ''
506+
-- test spi_prepare
507+
select tcl_eval('spi_prepare');
508+
ERROR: wrong # args: should be "spi_prepare query argtypes"
509+
select tcl_eval('spi_prepare a b');
510+
ERROR: type "b" does not exist
511+
select tcl_eval('spi_prepare a "b {"');
512+
ERROR: unmatched open brace in list
513+
select tcl_error_handling_test($tcl$spi_prepare "select moo" []$tcl$);
514+
tcl_error_handling_test
515+
--------------------------------------
516+
SQLSTATE: 42703 +
517+
condition: undefined_column +
518+
cursor_position: 8 +
519+
message: column "moo" does not exist+
520+
statement: select moo
521+
(1 row)
522+
523+
-- test full error text
524+
select tcl_error_handling_test($tcl$
525+
spi_exec "DO $$
526+
BEGIN
527+
RAISE 'my message'
528+
USING HINT = 'my hint'
529+
, DETAIL = 'my detail'
530+
, SCHEMA = 'my schema'
531+
, TABLE = 'my table'
532+
, COLUMN = 'my column'
533+
, CONSTRAINT = 'my constraint'
534+
, DATATYPE = 'my datatype'
535+
;
536+
END$$;"
537+
$tcl$);
538+
tcl_error_handling_test
539+
--------------------------------------------------------------
540+
SQLSTATE: P0001 +
541+
column: my column +
542+
condition: raise_exception +
543+
constraint: my constraint +
544+
context: PL/pgSQL function inline_code_block line 3 at RAISE+
545+
SQL statement "DO $$ +
546+
BEGIN +
547+
RAISE 'my message' +
548+
USING HINT = 'my hint' +
549+
, DETAIL = 'my detail' +
550+
, SCHEMA = 'my schema' +
551+
, TABLE = 'my table' +
552+
, COLUMN = 'my column' +
553+
, CONSTRAINT = 'my constraint' +
554+
, DATATYPE = 'my datatype' +
555+
; +
556+
END$$;" +
557+
datatype: my datatype +
558+
detail: my detail +
559+
hint: my hint +
560+
message: my message +
561+
schema: my schema +
562+
table: my table
563+
(1 row)
564+
565+
-- verify tcl_error_handling_test() properly reports non-postgres errors
566+
select tcl_error_handling_test('moo');
567+
tcl_error_handling_test
568+
----------------------------
569+
invalid command name "moo"
570+
(1 row)
571+
572+
-- test elog
573+
select tcl_eval('elog');
574+
ERROR: wrong # args: should be "elog level msg"
575+
select tcl_eval('elog foo bar');
576+
ERROR: bad priority "foo": must be DEBUG, LOG, INFO, NOTICE, WARNING, ERROR, or FATAL
577+
-- test forced error
578+
select tcl_eval('error "forced error"');
579+
ERROR: forced error
580+
-- test loop control in spi_exec[p]
581+
select tcl_spi_exec(true, 'break');
582+
NOTICE: col1 1, col2 foo
583+
NOTICE: col1 2, col2 bar
584+
NOTICE: action: break
585+
NOTICE: end of function
586+
tcl_spi_exec
587+
--------------
588+
589+
(1 row)
590+
591+
select tcl_spi_exec(true, 'continue');
592+
NOTICE: col1 1, col2 foo
593+
NOTICE: col1 2, col2 bar
594+
NOTICE: action: continue
595+
NOTICE: col1 3, col2 baz
596+
NOTICE: end of function
597+
tcl_spi_exec
598+
--------------
599+
600+
(1 row)
601+
602+
select tcl_spi_exec(true, 'error');
603+
NOTICE: col1 1, col2 foo
604+
NOTICE: col1 2, col2 bar
605+
NOTICE: action: error
606+
ERROR: error message
607+
select tcl_spi_exec(true, 'return');
608+
NOTICE: col1 1, col2 foo
609+
NOTICE: col1 2, col2 bar
610+
NOTICE: action: return
611+
tcl_spi_exec
612+
--------------
613+
614+
(1 row)
615+
616+
select tcl_spi_exec(false, 'break');
617+
NOTICE: col1 1, col2 foo
618+
NOTICE: col1 2, col2 bar
619+
NOTICE: action: break
620+
NOTICE: end of function
621+
tcl_spi_exec
622+
--------------
623+
624+
(1 row)
625+
626+
select tcl_spi_exec(false, 'continue');
627+
NOTICE: col1 1, col2 foo
628+
NOTICE: col1 2, col2 bar
629+
NOTICE: action: continue
630+
NOTICE: col1 3, col2 baz
631+
NOTICE: end of function
632+
tcl_spi_exec
633+
--------------
634+
635+
(1 row)
636+
637+
select tcl_spi_exec(false, 'error');
638+
NOTICE: col1 1, col2 foo
639+
NOTICE: col1 2, col2 bar
640+
NOTICE: action: error
641+
ERROR: error message
642+
select tcl_spi_exec(false, 'return');
643+
NOTICE: col1 1, col2 foo
644+
NOTICE: col1 2, col2 bar
645+
NOTICE: action: return
646+
tcl_spi_exec
647+
--------------
648+
649+
(1 row)
650+
651+
-- forcibly run the Tcl event loop for awhile, to check that we have not
652+
-- messed things up too badly by disabling the Tcl notifier subsystem
653+
select tcl_eval($$
654+
unset -nocomplain ::tcl_vwait
655+
after 100 {set ::tcl_vwait 1}
656+
vwait ::tcl_vwait
657+
unset -nocomplain ::tcl_vwait$$);
658+
tcl_eval
659+
----------
660+
661+
(1 row)
662+

0 commit comments

Comments
 (0)