Skip to content
plpgsql_check

plpgsql_check

plpgsql_check : extended check for plpgsql functions

Overview

IDExtensionPackageVersionCategoryLicenseLanguage
3060
plpgsql_check
plpgsql_check
2.8.11
LANG
MIT
C
AttributeHas BinaryHas LibraryNeed LoadHas DDLRelocatableTrusted
--sLd--
No
Yes
Yes
Yes
no
no
Relationships
Requires
plpgsql
See Also
pldbgapi
plprofiler
pg_hint_plan
pgtap
auto_explain
plv8
plperl
plpython3u

Packages

TypeRepoVersionPG Major CompatibilityPackage PatternDependencies
EXT
PGDG
2.8.11
18
17
16
15
14
plpgsql_checkplpgsql
RPM
PGDG
2.8.10
18
17
16
15
14
plpgsql_check_$v-
DEB
PGDG
2.8.11
18
17
16
15
14
postgresql-$v-plpgsql-check-
Linux / PGPG18PG17PG16PG15PG14
el8.x86_64
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
el8.aarch64
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
el9.x86_64
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
el9.aarch64
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
el10.x86_64
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
el10.aarch64
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
PGDG 2.8.10
d12.x86_64
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
d12.aarch64
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
d13.x86_64
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
d13.aarch64
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
u22.x86_64
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
u22.aarch64
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
u24.x86_64
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
u24.aarch64
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
u26.x86_64
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
u26.aarch64
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PGDG 2.8.11
PackageVersionOSORGSIZEFile URL
plpgsql_check_182.8.10el8.x86_64pgdg116.7 KiBplpgsql_check_18-2.8.10-1PGDG.rhel8.10.x86_64.rpm
plpgsql_check_182.8.8el8.x86_64pgdg116.5 KiBplpgsql_check_18-2.8.8-1PGDG.rhel8.10.x86_64.rpm
plpgsql_check_182.8.5el8.x86_64pgdg114.2 KiBplpgsql_check_18-2.8.5-1PGDG.rhel8.10.x86_64.rpm
plpgsql_check_182.8.4el8.x86_64pgdg113.9 KiBplpgsql_check_18-2.8.4-1PGDG.rhel8.10.x86_64.rpm
plpgsql_check_182.8.3el8.x86_64pgdg113.8 KiBplpgsql_check_18-2.8.3-1PGDG.rhel8.x86_64.rpm
plpgsql_check_182.8.2el8.x86_64pgdg113.0 KiBplpgsql_check_18-2.8.2-1PGDG.rhel8.x86_64.rpm
plpgsql_check_182.8.10el8.aarch64pgdg108.2 KiBplpgsql_check_18-2.8.10-1PGDG.rhel8.10.aarch64.rpm
plpgsql_check_182.8.8el8.aarch64pgdg107.9 KiBplpgsql_check_18-2.8.8-1PGDG.rhel8.10.aarch64.rpm
plpgsql_check_182.8.5el8.aarch64pgdg105.5 KiBplpgsql_check_18-2.8.5-1PGDG.rhel8.10.aarch64.rpm
plpgsql_check_182.8.4el8.aarch64pgdg105.4 KiBplpgsql_check_18-2.8.4-1PGDG.rhel8.10.aarch64.rpm
plpgsql_check_182.8.3el8.aarch64pgdg105.2 KiBplpgsql_check_18-2.8.3-1PGDG.rhel8.aarch64.rpm
plpgsql_check_182.8.2el8.aarch64pgdg104.4 KiBplpgsql_check_18-2.8.2-1PGDG.rhel8.aarch64.rpm
plpgsql_check_182.8.10el9.x86_64pgdg112.4 KiBplpgsql_check_18-2.8.10-1PGDG.rhel9.7.x86_64.rpm
plpgsql_check_182.8.8el9.x86_64pgdg112.0 KiBplpgsql_check_18-2.8.8-1PGDG.rhel9.7.x86_64.rpm
plpgsql_check_182.8.5el9.x86_64pgdg108.8 KiBplpgsql_check_18-2.8.5-1PGDG.rhel9.7.x86_64.rpm
plpgsql_check_182.8.4el9.x86_64pgdg108.7 KiBplpgsql_check_18-2.8.4-1PGDG.rhel9.7.x86_64.rpm
plpgsql_check_182.8.3el9.x86_64pgdg109.0 KiBplpgsql_check_18-2.8.3-1PGDG.rhel9.x86_64.rpm
plpgsql_check_182.8.2el9.x86_64pgdg108.6 KiBplpgsql_check_18-2.8.2-1PGDG.rhel9.x86_64.rpm
plpgsql_check_182.8.10el9.aarch64pgdg107.9 KiBplpgsql_check_18-2.8.10-1PGDG.rhel9.7.aarch64.rpm
plpgsql_check_182.8.8el9.aarch64pgdg107.6 KiBplpgsql_check_18-2.8.8-1PGDG.rhel9.7.aarch64.rpm
plpgsql_check_182.8.5el9.aarch64pgdg103.6 KiBplpgsql_check_18-2.8.5-1PGDG.rhel9.7.aarch64.rpm
plpgsql_check_182.8.4el9.aarch64pgdg103.7 KiBplpgsql_check_18-2.8.4-1PGDG.rhel9.7.aarch64.rpm
plpgsql_check_182.8.3el9.aarch64pgdg103.7 KiBplpgsql_check_18-2.8.3-1PGDG.rhel9.aarch64.rpm
plpgsql_check_182.8.2el9.aarch64pgdg103.5 KiBplpgsql_check_18-2.8.2-1PGDG.rhel9.aarch64.rpm
plpgsql_check_182.8.10el10.x86_64pgdg114.6 KiBplpgsql_check_18-2.8.10-1PGDG.rhel10.1.x86_64.rpm
plpgsql_check_182.8.8el10.x86_64pgdg114.7 KiBplpgsql_check_18-2.8.8-1PGDG.rhel10.1.x86_64.rpm
plpgsql_check_182.8.5el10.x86_64pgdg111.1 KiBplpgsql_check_18-2.8.5-1PGDGrhel10.1.x86_64.rpm
plpgsql_check_182.8.4el10.x86_64pgdg111.2 KiBplpgsql_check_18-2.8.4-1PGDGrhel10.1.x86_64.rpm
plpgsql_check_182.8.3el10.x86_64pgdg111.5 KiBplpgsql_check_18-2.8.3-1PGDG.rhel10.x86_64.rpm
plpgsql_check_182.8.2el10.x86_64pgdg111.2 KiBplpgsql_check_18-2.8.2-1PGDG.rhel10.x86_64.rpm
plpgsql_check_182.8.10el10.aarch64pgdg109.0 KiBplpgsql_check_18-2.8.10-1PGDG.rhel10.1.aarch64.rpm
plpgsql_check_182.8.8el10.aarch64pgdg108.7 KiBplpgsql_check_18-2.8.8-1PGDG.rhel10.1.aarch64.rpm
plpgsql_check_182.8.5el10.aarch64pgdg105.2 KiBplpgsql_check_18-2.8.5-1PGDGrhel10.1.aarch64.rpm
plpgsql_check_182.8.4el10.aarch64pgdg105.2 KiBplpgsql_check_18-2.8.4-1PGDGrhel10.1.aarch64.rpm
plpgsql_check_182.8.3el10.aarch64pgdg105.7 KiBplpgsql_check_18-2.8.3-1PGDG.rhel10.aarch64.rpm
plpgsql_check_182.8.2el10.aarch64pgdg105.1 KiBplpgsql_check_18-2.8.2-1PGDG.rhel10.aarch64.rpm
postgresql-18-plpgsql-check2.8.11d12.x86_64pgdg292.6 KiBpostgresql-18-plpgsql-check_2.8.11-1.pgdg12+1_amd64.deb
postgresql-18-plpgsql-check2.8.11d12.aarch64pgdg281.5 KiBpostgresql-18-plpgsql-check_2.8.11-1.pgdg12+1_arm64.deb
postgresql-18-plpgsql-check2.8.11d13.x86_64pgdg293.1 KiBpostgresql-18-plpgsql-check_2.8.11-1.pgdg13+1_amd64.deb
postgresql-18-plpgsql-check2.8.11d13.aarch64pgdg282.5 KiBpostgresql-18-plpgsql-check_2.8.11-1.pgdg13+1_arm64.deb
postgresql-18-plpgsql-check2.8.11u22.x86_64pgdg301.7 KiBpostgresql-18-plpgsql-check_2.8.11-1.pgdg22.04+1_amd64.deb
postgresql-18-plpgsql-check2.8.11u22.aarch64pgdg291.1 KiBpostgresql-18-plpgsql-check_2.8.11-1.pgdg22.04+1_arm64.deb
postgresql-18-plpgsql-check2.8.11u24.x86_64pgdg291.9 KiBpostgresql-18-plpgsql-check_2.8.11-1.pgdg24.04+1_amd64.deb
postgresql-18-plpgsql-check2.8.11u24.aarch64pgdg280.7 KiBpostgresql-18-plpgsql-check_2.8.11-1.pgdg24.04+1_arm64.deb
postgresql-18-plpgsql-check2.8.11u26.x86_64pgdg290.6 KiBpostgresql-18-plpgsql-check_2.8.11-1.pgdg26.04+1_amd64.deb
postgresql-18-plpgsql-check2.8.11u26.aarch64pgdg278.6 KiBpostgresql-18-plpgsql-check_2.8.11-1.pgdg26.04+1_arm64.deb

Source

Install

Make sure PGDG repo available:

pig repo add pgdg -u    # add pgdg repo and update cache

Install this extension with pig:

pig install plpgsql_check;		# install via package name, for the active PG version

pig install plpgsql_check -v 18;   # install for PG 18
pig install plpgsql_check -v 17;   # install for PG 17
pig install plpgsql_check -v 16;   # install for PG 16
pig install plpgsql_check -v 15;   # install for PG 15
pig install plpgsql_check -v 14;   # install for PG 14

Config this extension to shared_preload_libraries:

shared_preload_libraries = 'plpgsql_check';

Create this extension with:

CREATE EXTENSION plpgsql_check CASCADE; -- requires plpgsql

Usage

plpgsql_check: extended check for plpgsql functions

plpgsql_check is a linter and checker for PL/pgSQL functions that detects errors at development time rather than runtime.

CREATE EXTENSION plpgsql_check;

Check a Function

SELECT * FROM plpgsql_check_function('my_function()');
SELECT * FROM plpgsql_check_function('my_function(int, text)');
SELECT * FROM plpgsql_check_function('my_function()', fatal_errors := false);

Output Formats

SELECT * FROM plpgsql_check_function('fx()', format := 'text');
SELECT * FROM plpgsql_check_function('fx()', format := 'json');
SELECT * FROM plpgsql_check_function('fx()', format := 'xml');

Check Trigger Functions

-- Trigger functions need the associated table
SELECT * FROM plpgsql_check_function('my_trigger_func()', 'my_table');

-- With transition tables
SELECT * FROM plpgsql_check_function(
  'my_trigger_func()', 'my_table',
  newtable := 'newtab', oldtable := 'oldtab'
);

Warning Categories

SELECT * FROM plpgsql_check_function('fx()',
  extra_warnings := true,         -- dead code, unused parameters
  performance_warnings := true,   -- index and casting issues
  security_warnings := true,      -- SQL injection checks
  compatibility_warnings := true  -- obsolete patterns
);

Batch Check All Functions

SELECT p.oid, p.proname, plpgsql_check_function(p.oid)
FROM pg_catalog.pg_namespace n
JOIN pg_catalog.pg_proc p ON pronamespace = n.oid
JOIN pg_catalog.pg_language l ON p.prolang = l.oid
WHERE l.lanname = 'plpgsql' AND p.prorettype <> 2279;

Passive Mode (Check on Execution)

LOAD 'plpgsql_check';
SET plpgsql_check.mode = 'every_start';  -- check before each execution

Or in postgresql.conf:

shared_preload_libraries = 'plpgsql,plpgsql_check'
plpgsql_check.mode = 'every_start'

Profiler

-- Enable profiling
SELECT plpgsql_check_profiler(true);

-- Execute functions to collect data
SELECT my_function();

-- View per-line execution times
SELECT lineno, avg_time, source
FROM plpgsql_profiler_function_tb('my_function()');

-- Per-statement profile
SELECT stmtid, parent_stmtid, lineno, exec_stmts, stmtname
FROM plpgsql_profiler_function_statements_tb('my_function()');

-- All function statistics
SELECT * FROM plpgsql_profiler_functions_all();

-- Reset profiling data
SELECT plpgsql_profiler_reset_all();

Dependency Tracking

SELECT * FROM plpgsql_show_dependency_tb('my_function(int)');

Coverage Metrics

SELECT * FROM plpgsql_coverage_statements('my_function()');
SELECT * FROM plpgsql_coverage_branches('my_function()');

Pragma Directives

Embed checking options in function comments:

CREATE OR REPLACE FUNCTION fx(anyelement) RETURNS text AS $$
BEGIN
  /* @plpgsql_check_options: anyelementtype = text */
  RETURN $1;
END;
$$ LANGUAGE plpgsql;
Last updated on