{"kind": "language", "major": "18", "item": {"slug": "plpgsql", "name": "plpgsql", "name_zh": "", "category": "PL/pgSQL", "summary": "PL/pgSQL procedural language", "aliases": [], "content_hash": "8388f49bcb8ba36944d1bc7305f823491e9bfae0287923008f0e9648c2cdf76b", "versions": {"10": {"facts": [{"label": "Kind", "value": "Bundled procedural-language variant"}, {"label": "Family", "value": "PL/pgSQL"}, {"label": "Trusted", "value": "t"}, {"label": "Handler", "value": "plpgsql_call_handler"}, {"label": "Inline handler", "value": "plpgsql_inline_handler"}, {"label": "Validator", "value": "plpgsql_validator"}, {"label": "Library", "value": "$libdir/plpgsql"}, {"label": "Default version", "value": "1.0"}, {"label": "Module pathname", "value": "$libdir/plpgsql"}, {"label": "Comment", "value": "PL/pgSQL procedural language"}], "tables": [], "aliases": [], "related": [{"url": "/docs/10/plpgsql-control-structures.html", "label": "plpgsql-control-structures"}, {"url": "/docs/10/plpgsql-cursors.html", "label": "plpgsql-cursors"}, {"url": "/docs/10/plpgsql-declarations.html", "label": "plpgsql-declarations"}, {"url": "/docs/10/plpgsql-development-tips.html", "label": "plpgsql-development-tips"}, {"url": "/docs/10/plpgsql-errors-and-messages.html", "label": "plpgsql-errors-and-messages"}, {"url": "/docs/10/plpgsql-expressions.html", "label": "plpgsql-expressions"}, {"url": "/docs/10/plpgsql-implementation.html", "label": "plpgsql-implementation"}, {"url": "/docs/10/plpgsql-overview.html", "label": "plpgsql-overview"}, {"url": "/docs/10/plpgsql-porting.html", "label": "plpgsql-porting"}, {"url": "/docs/10/plpgsql-statements.html", "label": "plpgsql-statements"}, {"url": "/docs/10/plpgsql-structure.html", "label": "plpgsql-structure"}, {"url": "/docs/10/plpgsql-trigger.html", "label": "plpgsql-trigger"}], "release": {"ref": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "label": "10.23", "major": "10", "channel": "historical", "revision": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9", "source_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9", "catalog_fingerprint": "691be281b476dde4374d7f805b2bacc2e75bdef40f1e9d3d42e91f97fe95cfd0"}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "label": "Matching PostgreSQL source archive", "sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}, {"url": "/docs/10/plpgsql-overview.html", "path": "plpgsql-overview.html", "label": "PostgreSQL 10 English manual", "sha256": "e4ff699e727c880b932806cb3db290bb884efb82573b94b585fdf08a6d89c00f"}], "sections": [{"code": "/* src/pl/plpgsql/src/plpgsql--1.0.sql */\n\n/*\n * Currently, all the interesting stuff is done by CREATE LANGUAGE.\n * Later we will probably \"dumb down\" that command and put more of the\n * knowledge into this script.\n */\n\nCREATE PROCEDURAL LANGUAGE plpgsql;\n\nCOMMENT ON PROCEDURAL LANGUAGE plpgsql IS 'PL/pgSQL procedural language';", "title": "Installation definition from the matching source archive", "paragraphs": ["This extension is shipped with the source. Its presence does not establish that the language or external runtime is installed."]}], "signature": "", "attributes": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "comment": "PL/pgSQL procedural language", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0", "module_pathname": "$libdir/plpgsql"}, "description": ["PL/pgSQL procedural language"], "manual_html": "<div class=\"sect1\" id=\"PLPGSQL-OVERVIEW\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h2 class=\"title\">42.1.\u00a0Overview</h2>\n</div>\n</div>\n</div>\n\n<p><span class=\"application\">PL/pgSQL</span> is a loadable procedural language for the <span class=\"productname\">PostgreSQL</span> database system. The design goals of <span class=\"application\">PL/pgSQL</span> were to create a loadable procedural language that</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>can be used to create functions and trigger procedures,</p>\n</li>\n<li class=\"listitem\">\n<p>adds control structures to the SQL language,</p>\n</li>\n<li class=\"listitem\">\n<p>can perform complex computations,</p>\n</li>\n<li class=\"listitem\">\n<p>inherits all user-defined types, functions, and operators,</p>\n</li>\n<li class=\"listitem\">\n<p>can be defined to be trusted by the server,</p>\n</li>\n<li class=\"listitem\">\n<p>is easy to use.</p>\n</li>\n</ul>\n</div>\n<p>Functions created with <span class=\"application\">PL/pgSQL</span> can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.</p>\n<p>In <span class=\"productname\">PostgreSQL</span> 9.0 and later, <span class=\"application\">PL/pgSQL</span> is installed by default. However it is still a loadable module, so especially security-conscious administrators could choose to remove it.</p>\n<div class=\"sect2\" id=\"PLPGSQL-ADVANTAGES\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">42.1.1.\u00a0Advantages of Using <span class=\"application\">PL/pgSQL</span></h3>\n</div>\n</div>\n</div>\n<p>SQL is the language <span class=\"productname\">PostgreSQL</span> and most other relational databases use as query language. It's portable and easy to learn. But every SQL statement must be executed individually by the database server.</p>\n<p>That means that your client application must send each query to the database server, wait for it to be processed, receive and process the results, do some computation, then send further queries to the server. All this incurs interprocess communication and will also incur network overhead if your client is on a different machine than the database server.</p>\n<p>With <span class=\"application\">PL/pgSQL</span> you can group a block of computation and a series of queries <span class=\"emphasis\"><em>inside</em></span> the database server, thus having the power of a procedural language and the ease of use of SQL, but with considerable savings of client/server communication overhead.</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>Extra round trips between client and server are eliminated</p>\n</li>\n<li class=\"listitem\">\n<p>Intermediate results that the client does not need do not have to be marshaled or transferred between server and client</p>\n</li>\n<li class=\"listitem\">\n<p>Multiple rounds of query parsing can be avoided</p>\n</li>\n</ul>\n</div>\n<p>This can result in a considerable performance increase as compared to an application that does not use stored functions.</p>\n<p>Also, with <span class=\"application\">PL/pgSQL</span> you can use all the data types, operators and functions of SQL.</p>\n</div>\n<div class=\"sect2\" id=\"PLPGSQL-ARGS-RESULTS\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">42.1.2.\u00a0Supported Argument and Result Data Types</h3>\n</div>\n</div>\n</div>\n<p>Functions written in <span class=\"application\">PL/pgSQL</span> can accept as arguments any scalar or array data type supported by the server, and they can return a result of any of these types. They can also accept or return any composite type (row type) specified by name. It is also possible to declare a <span class=\"application\">PL/pgSQL</span> function as returning <code class=\"type\">record</code>, which means that the result is a row type whose columns are determined by specification in the calling query, as discussed in <a class=\"xref\" href=\"/docs/10/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS\" title=\"7.2.1.4.\u00a0Table Functions\">Section\u00a07.2.1.4</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can be declared to accept a variable number of arguments by using the <code class=\"literal\">VARIADIC</code> marker. This works exactly the same way as for SQL functions, as discussed in <a class=\"xref\" href=\"/docs/10/xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS\" title=\"37.4.5.\u00a0SQL Functions with Variable Numbers of Arguments\">Section\u00a037.4.5</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to accept and return the polymorphic types <code class=\"type\">anyelement</code>, <code class=\"type\">anyarray</code>, <code class=\"type\">anynonarray</code>, <code class=\"type\">anyenum</code>, and <code class=\"type\">anyrange</code>. The actual data types handled by a polymorphic function can vary from call to call, as discussed in <a class=\"xref\" href=\"/docs/10/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"37.2.5.\u00a0Polymorphic Types\">Section\u00a037.2.5</a>. An example is shown in <a class=\"xref\" href=\"/docs/10/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"42.3.1.\u00a0Declaring Function Parameters\">Section\u00a042.3.1</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to return a <span class=\"quote\">\u201c<span class=\"quote\">set</span>\u201d</span> (or table) of any data type that can be returned as a single instance. Such a function generates its output by executing <code class=\"command\">RETURN NEXT</code> for each desired element of the result set, or by using <code class=\"command\">RETURN QUERY</code> to output the result of evaluating a query.</p>\n<p>Finally, a <span class=\"application\">PL/pgSQL</span> function can be declared to return <code class=\"type\">void</code> if it has no useful return value.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared with output parameters in place of an explicit specification of the return type. This does not add any fundamental capability to the language, but it is often convenient, especially for returning multiple values. The <code class=\"literal\">RETURNS TABLE</code> notation can also be used in place of <code class=\"literal\">RETURNS SETOF</code>.</p>\n<p>Specific examples appear in <a class=\"xref\" href=\"/docs/10/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"42.3.1.\u00a0Declaring Function Parameters\">Section\u00a042.3.1</a> and <a class=\"xref\" href=\"/docs/10/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING\" title=\"42.6.1.\u00a0Returning From a Function\">Section\u00a042.6.1</a>.</p>\n</div>\n</div>", "manual_path": "/docs/10/plpgsql-overview.html", "source_files": {"src/pl/plpgsql/src/plpgsql.control": "b48cd5aa8d87103b011dda42012b2aab62de061283272b2a454d676f041fa4c3", "src/pl/plpgsql/src/plpgsql--1.0.sql": "66f1dc2c4eaa9be9a512361d6171bd29f6ac078c9125e2d5b7014535e951a0e5"}, "comparison_data": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0"}, "comparison_hash": "e85051f39a242ce658cedd87ac97437817f0f1b2baf992d8d37c9d29df8b558b"}, "11": {"facts": [{"label": "Kind", "value": "Bundled procedural-language variant"}, {"label": "Family", "value": "PL/pgSQL"}, {"label": "Trusted", "value": "t"}, {"label": "Handler", "value": "plpgsql_call_handler"}, {"label": "Inline handler", "value": "plpgsql_inline_handler"}, {"label": "Validator", "value": "plpgsql_validator"}, {"label": "Library", "value": "$libdir/plpgsql"}, {"label": "Default version", "value": "1.0"}, {"label": "Module pathname", "value": "$libdir/plpgsql"}, {"label": "Comment", "value": "PL/pgSQL procedural language"}], "tables": [], "aliases": [], "related": [{"url": "/docs/11/plpgsql-control-structures.html", "label": "plpgsql-control-structures"}, {"url": "/docs/11/plpgsql-cursors.html", "label": "plpgsql-cursors"}, {"url": "/docs/11/plpgsql-declarations.html", "label": "plpgsql-declarations"}, {"url": "/docs/11/plpgsql-development-tips.html", "label": "plpgsql-development-tips"}, {"url": "/docs/11/plpgsql-errors-and-messages.html", "label": "plpgsql-errors-and-messages"}, {"url": "/docs/11/plpgsql-expressions.html", "label": "plpgsql-expressions"}, {"url": "/docs/11/plpgsql-implementation.html", "label": "plpgsql-implementation"}, {"url": "/docs/11/plpgsql-overview.html", "label": "plpgsql-overview"}, {"url": "/docs/11/plpgsql-porting.html", "label": "plpgsql-porting"}, {"url": "/docs/11/plpgsql-statements.html", "label": "plpgsql-statements"}, {"url": "/docs/11/plpgsql-structure.html", "label": "plpgsql-structure"}, {"url": "/docs/11/plpgsql-transactions.html", "label": "plpgsql-transactions"}, {"url": "/docs/11/plpgsql-trigger.html", "label": "plpgsql-trigger"}], "release": {"ref": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "label": "11.22", "major": "11", "channel": "historical", "revision": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0", "source_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0", "catalog_fingerprint": "8f21f4444b7f68923f4762af0eb7937fa2907026e91249483e79050de012c901"}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "label": "Matching PostgreSQL source archive", "sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}, {"url": "/docs/11/plpgsql-overview.html", "path": "plpgsql-overview.html", "label": "PostgreSQL 11 English manual", "sha256": "25b2cf2b11ea6deb32e204af2c94948b6efc1830e66cea098ed0f6755735e6dd"}], "sections": [{"code": "/* src/pl/plpgsql/src/plpgsql--1.0.sql */\n\n/*\n * Currently, all the interesting stuff is done by CREATE LANGUAGE.\n * Later we will probably \"dumb down\" that command and put more of the\n * knowledge into this script.\n */\n\nCREATE PROCEDURAL LANGUAGE plpgsql;\n\nCOMMENT ON PROCEDURAL LANGUAGE plpgsql IS 'PL/pgSQL procedural language';", "title": "Installation definition from the matching source archive", "paragraphs": ["This extension is shipped with the source. Its presence does not establish that the language or external runtime is installed."]}], "signature": "", "attributes": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "comment": "PL/pgSQL procedural language", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0", "module_pathname": "$libdir/plpgsql"}, "description": ["PL/pgSQL procedural language"], "manual_html": "<div class=\"sect1\" id=\"PLPGSQL-OVERVIEW\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h2 class=\"title\">43.1.\u00a0Overview</h2>\n</div>\n</div>\n</div>\n\n<p><span class=\"application\">PL/pgSQL</span> is a loadable procedural language for the <span class=\"productname\">PostgreSQL</span> database system. The design goals of <span class=\"application\">PL/pgSQL</span> were to create a loadable procedural language that</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>can be used to create functions, procedures, and triggers,</p>\n</li>\n<li class=\"listitem\">\n<p>adds control structures to the SQL language,</p>\n</li>\n<li class=\"listitem\">\n<p>can perform complex computations,</p>\n</li>\n<li class=\"listitem\">\n<p>inherits all user-defined types, functions, procedures, and operators,</p>\n</li>\n<li class=\"listitem\">\n<p>can be defined to be trusted by the server,</p>\n</li>\n<li class=\"listitem\">\n<p>is easy to use.</p>\n</li>\n</ul>\n</div>\n<p>Functions created with <span class=\"application\">PL/pgSQL</span> can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.</p>\n<p>In <span class=\"productname\">PostgreSQL</span> 9.0 and later, <span class=\"application\">PL/pgSQL</span> is installed by default. However it is still a loadable module, so especially security-conscious administrators could choose to remove it.</p>\n<div class=\"sect2\" id=\"PLPGSQL-ADVANTAGES\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">43.1.1.\u00a0Advantages of Using <span class=\"application\">PL/pgSQL</span></h3>\n</div>\n</div>\n</div>\n<p>SQL is the language <span class=\"productname\">PostgreSQL</span> and most other relational databases use as query language. It's portable and easy to learn. But every SQL statement must be executed individually by the database server.</p>\n<p>That means that your client application must send each query to the database server, wait for it to be processed, receive and process the results, do some computation, then send further queries to the server. All this incurs interprocess communication and will also incur network overhead if your client is on a different machine than the database server.</p>\n<p>With <span class=\"application\">PL/pgSQL</span> you can group a block of computation and a series of queries <span class=\"emphasis\"><em>inside</em></span> the database server, thus having the power of a procedural language and the ease of use of SQL, but with considerable savings of client/server communication overhead.</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>Extra round trips between client and server are eliminated</p>\n</li>\n<li class=\"listitem\">\n<p>Intermediate results that the client does not need do not have to be marshaled or transferred between server and client</p>\n</li>\n<li class=\"listitem\">\n<p>Multiple rounds of query parsing can be avoided</p>\n</li>\n</ul>\n</div>\n<p>This can result in a considerable performance increase as compared to an application that does not use stored functions.</p>\n<p>Also, with <span class=\"application\">PL/pgSQL</span> you can use all the data types, operators and functions of SQL.</p>\n</div>\n<div class=\"sect2\" id=\"PLPGSQL-ARGS-RESULTS\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">43.1.2.\u00a0Supported Argument and Result Data Types</h3>\n</div>\n</div>\n</div>\n<p>Functions written in <span class=\"application\">PL/pgSQL</span> can accept as arguments any scalar or array data type supported by the server, and they can return a result of any of these types. They can also accept or return any composite type (row type) specified by name. It is also possible to declare a <span class=\"application\">PL/pgSQL</span> function as accepting <code class=\"type\">record</code>, which means that any composite type will do as input, or as returning <code class=\"type\">record</code>, which means that the result is a row type whose columns are determined by specification in the calling query, as discussed in <a class=\"xref\" href=\"/docs/11/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS\" title=\"7.2.1.4.\u00a0Table Functions\">Section\u00a07.2.1.4</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can be declared to accept a variable number of arguments by using the <code class=\"literal\">VARIADIC</code> marker. This works exactly the same way as for SQL functions, as discussed in <a class=\"xref\" href=\"/docs/11/xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS\" title=\"38.5.5.\u00a0SQL Functions with Variable Numbers of Arguments\">Section\u00a038.5.5</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to accept and return the polymorphic types <code class=\"type\">anyelement</code>, <code class=\"type\">anyarray</code>, <code class=\"type\">anynonarray</code>, <code class=\"type\">anyenum</code>, and <code class=\"type\">anyrange</code>. The actual data types handled by a polymorphic function can vary from call to call, as discussed in <a class=\"xref\" href=\"/docs/11/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"38.2.5.\u00a0Polymorphic Types\">Section\u00a038.2.5</a>. An example is shown in <a class=\"xref\" href=\"/docs/11/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"43.3.1.\u00a0Declaring Function Parameters\">Section\u00a043.3.1</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to return a <span class=\"quote\">\u201c<span class=\"quote\">set</span>\u201d</span> (or table) of any data type that can be returned as a single instance. Such a function generates its output by executing <code class=\"command\">RETURN NEXT</code> for each desired element of the result set, or by using <code class=\"command\">RETURN QUERY</code> to output the result of evaluating a query.</p>\n<p>Finally, a <span class=\"application\">PL/pgSQL</span> function can be declared to return <code class=\"type\">void</code> if it has no useful return value. (Alternatively, it could be written as a procedure in that case.)</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared with output parameters in place of an explicit specification of the return type. This does not add any fundamental capability to the language, but it is often convenient, especially for returning multiple values. The <code class=\"literal\">RETURNS TABLE</code> notation can also be used in place of <code class=\"literal\">RETURNS SETOF</code>.</p>\n<p>Specific examples appear in <a class=\"xref\" href=\"/docs/11/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"43.3.1.\u00a0Declaring Function Parameters\">Section\u00a043.3.1</a> and <a class=\"xref\" href=\"/docs/11/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING\" title=\"43.6.1.\u00a0Returning From a Function\">Section\u00a043.6.1</a>.</p>\n</div>\n</div>", "manual_path": "/docs/11/plpgsql-overview.html", "source_files": {"src/pl/plpgsql/src/plpgsql.control": "b48cd5aa8d87103b011dda42012b2aab62de061283272b2a454d676f041fa4c3", "src/pl/plpgsql/src/plpgsql--1.0.sql": "66f1dc2c4eaa9be9a512361d6171bd29f6ac078c9125e2d5b7014535e951a0e5"}, "comparison_data": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0"}, "comparison_hash": "e85051f39a242ce658cedd87ac97437817f0f1b2baf992d8d37c9d29df8b558b"}, "12": {"facts": [{"label": "Kind", "value": "Bundled procedural-language variant"}, {"label": "Family", "value": "PL/pgSQL"}, {"label": "Trusted", "value": "t"}, {"label": "Handler", "value": "plpgsql_call_handler"}, {"label": "Inline handler", "value": "plpgsql_inline_handler"}, {"label": "Validator", "value": "plpgsql_validator"}, {"label": "Library", "value": "$libdir/plpgsql"}, {"label": "Default version", "value": "1.0"}, {"label": "Module pathname", "value": "$libdir/plpgsql"}, {"label": "Comment", "value": "PL/pgSQL procedural language"}], "tables": [], "aliases": [], "related": [{"url": "/docs/12/plpgsql-control-structures.html", "label": "plpgsql-control-structures"}, {"url": "/docs/12/plpgsql-cursors.html", "label": "plpgsql-cursors"}, {"url": "/docs/12/plpgsql-declarations.html", "label": "plpgsql-declarations"}, {"url": "/docs/12/plpgsql-development-tips.html", "label": "plpgsql-development-tips"}, {"url": "/docs/12/plpgsql-errors-and-messages.html", "label": "plpgsql-errors-and-messages"}, {"url": "/docs/12/plpgsql-expressions.html", "label": "plpgsql-expressions"}, {"url": "/docs/12/plpgsql-implementation.html", "label": "plpgsql-implementation"}, {"url": "/docs/12/plpgsql-overview.html", "label": "plpgsql-overview"}, {"url": "/docs/12/plpgsql-porting.html", "label": "plpgsql-porting"}, {"url": "/docs/12/plpgsql-statements.html", "label": "plpgsql-statements"}, {"url": "/docs/12/plpgsql-structure.html", "label": "plpgsql-structure"}, {"url": "/docs/12/plpgsql-transactions.html", "label": "plpgsql-transactions"}, {"url": "/docs/12/plpgsql-trigger.html", "label": "plpgsql-trigger"}], "release": {"ref": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "label": "12.22", "major": "12", "channel": "historical", "revision": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b", "source_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b", "catalog_fingerprint": "9f857f4ee4875f9c7de6bfc9df4b757dec8b3a0bb88eadb519c7bd267bd56149"}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "label": "Matching PostgreSQL source archive", "sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}, {"url": "/docs/12/plpgsql-overview.html", "path": "plpgsql-overview.html", "label": "PostgreSQL 12 English manual", "sha256": "51f96fb54896071d8d8601865ff2d11b3517059744801c31cbac4e4fa842b920"}], "sections": [{"code": "/* src/pl/plpgsql/src/plpgsql--1.0.sql */\n\n/*\n * Currently, all the interesting stuff is done by CREATE LANGUAGE.\n * Later we will probably \"dumb down\" that command and put more of the\n * knowledge into this script.\n */\n\nCREATE LANGUAGE plpgsql;\n\nCOMMENT ON LANGUAGE plpgsql IS 'PL/pgSQL procedural language';", "title": "Installation definition from the matching source archive", "paragraphs": ["This extension is shipped with the source. Its presence does not establish that the language or external runtime is installed."]}], "signature": "", "attributes": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "comment": "PL/pgSQL procedural language", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0", "module_pathname": "$libdir/plpgsql"}, "description": ["PL/pgSQL procedural language"], "manual_html": "<div class=\"sect1\" id=\"PLPGSQL-OVERVIEW\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h2 class=\"title\">42.1.\u00a0Overview</h2>\n</div>\n</div>\n</div>\n\n<p><span class=\"application\">PL/pgSQL</span> is a loadable procedural language for the <span class=\"productname\">PostgreSQL</span> database system. The design goals of <span class=\"application\">PL/pgSQL</span> were to create a loadable procedural language that</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>can be used to create functions, procedures, and triggers,</p>\n</li>\n<li class=\"listitem\">\n<p>adds control structures to the SQL language,</p>\n</li>\n<li class=\"listitem\">\n<p>can perform complex computations,</p>\n</li>\n<li class=\"listitem\">\n<p>inherits all user-defined types, functions, procedures, and operators,</p>\n</li>\n<li class=\"listitem\">\n<p>can be defined to be trusted by the server,</p>\n</li>\n<li class=\"listitem\">\n<p>is easy to use.</p>\n</li>\n</ul>\n</div>\n<p>Functions created with <span class=\"application\">PL/pgSQL</span> can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.</p>\n<p>In <span class=\"productname\">PostgreSQL</span> 9.0 and later, <span class=\"application\">PL/pgSQL</span> is installed by default. However it is still a loadable module, so especially security-conscious administrators could choose to remove it.</p>\n<div class=\"sect2\" id=\"PLPGSQL-ADVANTAGES\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">42.1.1.\u00a0Advantages of Using <span class=\"application\">PL/pgSQL</span></h3>\n</div>\n</div>\n</div>\n<p>SQL is the language <span class=\"productname\">PostgreSQL</span> and most other relational databases use as query language. It's portable and easy to learn. But every SQL statement must be executed individually by the database server.</p>\n<p>That means that your client application must send each query to the database server, wait for it to be processed, receive and process the results, do some computation, then send further queries to the server. All this incurs interprocess communication and will also incur network overhead if your client is on a different machine than the database server.</p>\n<p>With <span class=\"application\">PL/pgSQL</span> you can group a block of computation and a series of queries <span class=\"emphasis\"><em>inside</em></span> the database server, thus having the power of a procedural language and the ease of use of SQL, but with considerable savings of client/server communication overhead.</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>Extra round trips between client and server are eliminated</p>\n</li>\n<li class=\"listitem\">\n<p>Intermediate results that the client does not need do not have to be marshaled or transferred between server and client</p>\n</li>\n<li class=\"listitem\">\n<p>Multiple rounds of query parsing can be avoided</p>\n</li>\n</ul>\n</div>\n<p>This can result in a considerable performance increase as compared to an application that does not use stored functions.</p>\n<p>Also, with <span class=\"application\">PL/pgSQL</span> you can use all the data types, operators and functions of SQL.</p>\n</div>\n<div class=\"sect2\" id=\"PLPGSQL-ARGS-RESULTS\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">42.1.2.\u00a0Supported Argument and Result Data Types</h3>\n</div>\n</div>\n</div>\n<p>Functions written in <span class=\"application\">PL/pgSQL</span> can accept as arguments any scalar or array data type supported by the server, and they can return a result of any of these types. They can also accept or return any composite type (row type) specified by name. It is also possible to declare a <span class=\"application\">PL/pgSQL</span> function as accepting <code class=\"type\">record</code>, which means that any composite type will do as input, or as returning <code class=\"type\">record</code>, which means that the result is a row type whose columns are determined by specification in the calling query, as discussed in <a class=\"xref\" href=\"/docs/12/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS\" title=\"7.2.1.4.\u00a0Table Functions\">Section\u00a07.2.1.4</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can be declared to accept a variable number of arguments by using the <code class=\"literal\">VARIADIC</code> marker. This works exactly the same way as for SQL functions, as discussed in <a class=\"xref\" href=\"/docs/12/xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS\" title=\"37.5.5.\u00a0SQL Functions with Variable Numbers of Arguments\">Section\u00a037.5.5</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to accept and return the polymorphic types <code class=\"type\">anyelement</code>, <code class=\"type\">anyarray</code>, <code class=\"type\">anynonarray</code>, <code class=\"type\">anyenum</code>, and <code class=\"type\">anyrange</code>. The actual data types handled by a polymorphic function can vary from call to call, as discussed in <a class=\"xref\" href=\"/docs/12/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"37.2.5.\u00a0Polymorphic Types\">Section\u00a037.2.5</a>. An example is shown in <a class=\"xref\" href=\"/docs/12/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"42.3.1.\u00a0Declaring Function Parameters\">Section\u00a042.3.1</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to return a <span class=\"quote\">\u201c<span class=\"quote\">set</span>\u201d</span> (or table) of any data type that can be returned as a single instance. Such a function generates its output by executing <code class=\"command\">RETURN NEXT</code> for each desired element of the result set, or by using <code class=\"command\">RETURN QUERY</code> to output the result of evaluating a query.</p>\n<p>Finally, a <span class=\"application\">PL/pgSQL</span> function can be declared to return <code class=\"type\">void</code> if it has no useful return value. (Alternatively, it could be written as a procedure in that case.)</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared with output parameters in place of an explicit specification of the return type. This does not add any fundamental capability to the language, but it is often convenient, especially for returning multiple values. The <code class=\"literal\">RETURNS TABLE</code> notation can also be used in place of <code class=\"literal\">RETURNS SETOF</code>.</p>\n<p>Specific examples appear in <a class=\"xref\" href=\"/docs/12/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"42.3.1.\u00a0Declaring Function Parameters\">Section\u00a042.3.1</a> and <a class=\"xref\" href=\"/docs/12/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING\" title=\"42.6.1.\u00a0Returning from a Function\">Section\u00a042.6.1</a>.</p>\n</div>\n</div>", "manual_path": "/docs/12/plpgsql-overview.html", "source_files": {"src/pl/plpgsql/src/plpgsql.control": "b48cd5aa8d87103b011dda42012b2aab62de061283272b2a454d676f041fa4c3", "src/pl/plpgsql/src/plpgsql--1.0.sql": "c1fd03aa2fdd5db25d025d83cd5ee52a335a532dfbf0f72554c0df7a18188b1e"}, "comparison_data": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0"}, "comparison_hash": "e85051f39a242ce658cedd87ac97437817f0f1b2baf992d8d37c9d29df8b558b"}, "13": {"facts": [{"label": "Kind", "value": "Bundled procedural-language variant"}, {"label": "Family", "value": "PL/pgSQL"}, {"label": "Trusted", "value": "t"}, {"label": "Handler", "value": "plpgsql_call_handler"}, {"label": "Inline handler", "value": "plpgsql_inline_handler"}, {"label": "Validator", "value": "plpgsql_validator"}, {"label": "Library", "value": "$libdir/plpgsql"}, {"label": "Default version", "value": "1.0"}, {"label": "Module pathname", "value": "$libdir/plpgsql"}, {"label": "Comment", "value": "PL/pgSQL procedural language"}], "tables": [], "aliases": [], "related": [{"url": "/docs/13/plpgsql-control-structures.html", "label": "plpgsql-control-structures"}, {"url": "/docs/13/plpgsql-cursors.html", "label": "plpgsql-cursors"}, {"url": "/docs/13/plpgsql-declarations.html", "label": "plpgsql-declarations"}, {"url": "/docs/13/plpgsql-development-tips.html", "label": "plpgsql-development-tips"}, {"url": "/docs/13/plpgsql-errors-and-messages.html", "label": "plpgsql-errors-and-messages"}, {"url": "/docs/13/plpgsql-expressions.html", "label": "plpgsql-expressions"}, {"url": "/docs/13/plpgsql-implementation.html", "label": "plpgsql-implementation"}, {"url": "/docs/13/plpgsql-overview.html", "label": "plpgsql-overview"}, {"url": "/docs/13/plpgsql-porting.html", "label": "plpgsql-porting"}, {"url": "/docs/13/plpgsql-statements.html", "label": "plpgsql-statements"}, {"url": "/docs/13/plpgsql-structure.html", "label": "plpgsql-structure"}, {"url": "/docs/13/plpgsql-transactions.html", "label": "plpgsql-transactions"}, {"url": "/docs/13/plpgsql-trigger.html", "label": "plpgsql-trigger"}], "release": {"ref": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "label": "13.23", "major": "13", "channel": "historical", "revision": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6", "source_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6", "catalog_fingerprint": "c7015c845255c9d721c547c8ab9ef37825d332588c9691d982e6906b7d571002"}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "label": "Matching PostgreSQL source archive", "sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}, {"url": "/docs/13/plpgsql-overview.html", "path": "plpgsql-overview.html", "label": "PostgreSQL 13 English manual", "sha256": "93a9e509a9511632f4896600769c872d388284a91d1ae3b01b51744ed5ea2092"}], "sections": [{"code": "/* src/pl/plpgsql/src/plpgsql--1.0.sql */\n\nCREATE FUNCTION plpgsql_call_handler() RETURNS language_handler\n  LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_inline_handler(internal) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_validator(oid) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE TRUSTED LANGUAGE plpgsql\n  HANDLER plpgsql_call_handler\n  INLINE plpgsql_inline_handler\n  VALIDATOR plpgsql_validator;\n\n-- The language object, but not the functions, can be owned by a non-superuser.\nALTER LANGUAGE plpgsql OWNER TO @extowner@;\n\nCOMMENT ON LANGUAGE plpgsql IS 'PL/pgSQL procedural language';", "title": "Installation definition from the matching source archive", "paragraphs": ["This extension is shipped with the source. Its presence does not establish that the language or external runtime is installed."]}], "signature": "", "attributes": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "comment": "PL/pgSQL procedural language", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0", "module_pathname": "$libdir/plpgsql"}, "description": ["PL/pgSQL procedural language"], "manual_html": "<div class=\"sect1\" id=\"PLPGSQL-OVERVIEW\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h2 class=\"title\">42.1.\u00a0Overview</h2>\n</div>\n</div>\n</div>\n\n<p><span class=\"application\">PL/pgSQL</span> is a loadable procedural language for the <span class=\"productname\">PostgreSQL</span> database system. The design goals of <span class=\"application\">PL/pgSQL</span> were to create a loadable procedural language that</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>can be used to create functions, procedures, and triggers,</p>\n</li>\n<li class=\"listitem\">\n<p>adds control structures to the SQL language,</p>\n</li>\n<li class=\"listitem\">\n<p>can perform complex computations,</p>\n</li>\n<li class=\"listitem\">\n<p>inherits all user-defined types, functions, procedures, and operators,</p>\n</li>\n<li class=\"listitem\">\n<p>can be defined to be trusted by the server,</p>\n</li>\n<li class=\"listitem\">\n<p>is easy to use.</p>\n</li>\n</ul>\n</div>\n<p>Functions created with <span class=\"application\">PL/pgSQL</span> can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.</p>\n<p>In <span class=\"productname\">PostgreSQL</span> 9.0 and later, <span class=\"application\">PL/pgSQL</span> is installed by default. However it is still a loadable module, so especially security-conscious administrators could choose to remove it.</p>\n<div class=\"sect2\" id=\"PLPGSQL-ADVANTAGES\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">42.1.1.\u00a0Advantages of Using <span class=\"application\">PL/pgSQL</span></h3>\n</div>\n</div>\n</div>\n<p>SQL is the language <span class=\"productname\">PostgreSQL</span> and most other relational databases use as query language. It's portable and easy to learn. But every SQL statement must be executed individually by the database server.</p>\n<p>That means that your client application must send each query to the database server, wait for it to be processed, receive and process the results, do some computation, then send further queries to the server. All this incurs interprocess communication and will also incur network overhead if your client is on a different machine than the database server.</p>\n<p>With <span class=\"application\">PL/pgSQL</span> you can group a block of computation and a series of queries <span class=\"emphasis\"><em>inside</em></span> the database server, thus having the power of a procedural language and the ease of use of SQL, but with considerable savings of client/server communication overhead.</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>Extra round trips between client and server are eliminated</p>\n</li>\n<li class=\"listitem\">\n<p>Intermediate results that the client does not need do not have to be marshaled or transferred between server and client</p>\n</li>\n<li class=\"listitem\">\n<p>Multiple rounds of query parsing can be avoided</p>\n</li>\n</ul>\n</div>\n<p>This can result in a considerable performance increase as compared to an application that does not use stored functions.</p>\n<p>Also, with <span class=\"application\">PL/pgSQL</span> you can use all the data types, operators and functions of SQL.</p>\n</div>\n<div class=\"sect2\" id=\"PLPGSQL-ARGS-RESULTS\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">42.1.2.\u00a0Supported Argument and Result Data Types</h3>\n</div>\n</div>\n</div>\n<p>Functions written in <span class=\"application\">PL/pgSQL</span> can accept as arguments any scalar or array data type supported by the server, and they can return a result of any of these types. They can also accept or return any composite type (row type) specified by name. It is also possible to declare a <span class=\"application\">PL/pgSQL</span> function as accepting <code class=\"type\">record</code>, which means that any composite type will do as input, or as returning <code class=\"type\">record</code>, which means that the result is a row type whose columns are determined by specification in the calling query, as discussed in <a class=\"xref\" href=\"/docs/13/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS\" title=\"7.2.1.4.\u00a0Table Functions\">Section\u00a07.2.1.4</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can be declared to accept a variable number of arguments by using the <code class=\"literal\">VARIADIC</code> marker. This works exactly the same way as for SQL functions, as discussed in <a class=\"xref\" href=\"/docs/13/xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS\" title=\"37.5.5.\u00a0SQL Functions with Variable Numbers of Arguments\">Section\u00a037.5.5</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to accept and return the polymorphic types described in <a class=\"xref\" href=\"/docs/13/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"37.2.5.\u00a0Polymorphic Types\">Section\u00a037.2.5</a>, thus allowing the actual data types handled by the function to vary from call to call. Examples appear in <a class=\"xref\" href=\"/docs/13/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"42.3.1.\u00a0Declaring Function Parameters\">Section\u00a042.3.1</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to return a <span class=\"quote\">\u201c<span class=\"quote\">set</span>\u201d</span> (or table) of any data type that can be returned as a single instance. Such a function generates its output by executing <code class=\"command\">RETURN NEXT</code> for each desired element of the result set, or by using <code class=\"command\">RETURN QUERY</code> to output the result of evaluating a query.</p>\n<p>Finally, a <span class=\"application\">PL/pgSQL</span> function can be declared to return <code class=\"type\">void</code> if it has no useful return value. (Alternatively, it could be written as a procedure in that case.)</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared with output parameters in place of an explicit specification of the return type. This does not add any fundamental capability to the language, but it is often convenient, especially for returning multiple values. The <code class=\"literal\">RETURNS TABLE</code> notation can also be used in place of <code class=\"literal\">RETURNS SETOF</code>.</p>\n<p>Specific examples appear in <a class=\"xref\" href=\"/docs/13/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"42.3.1.\u00a0Declaring Function Parameters\">Section\u00a042.3.1</a> and <a class=\"xref\" href=\"/docs/13/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING\" title=\"42.6.1.\u00a0Returning from a Function\">Section\u00a042.6.1</a>.</p>\n</div>\n</div>", "manual_path": "/docs/13/plpgsql-overview.html", "source_files": {"src/pl/plpgsql/src/plpgsql.control": "9457c3f51d6bdfab93f13080d177795a9274c025e378fb613218342e3a3c7b45", "src/pl/plpgsql/src/plpgsql--1.0.sql": "f4e7e05438808ac0da0b3801397d16e36102969af7e2ffc982def5b7524fb557"}, "comparison_data": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0"}, "comparison_hash": "e85051f39a242ce658cedd87ac97437817f0f1b2baf992d8d37c9d29df8b558b"}, "14": {"facts": [{"label": "Kind", "value": "Bundled procedural-language variant"}, {"label": "Family", "value": "PL/pgSQL"}, {"label": "Trusted", "value": "t"}, {"label": "Handler", "value": "plpgsql_call_handler"}, {"label": "Inline handler", "value": "plpgsql_inline_handler"}, {"label": "Validator", "value": "plpgsql_validator"}, {"label": "Library", "value": "$libdir/plpgsql"}, {"label": "Default version", "value": "1.0"}, {"label": "Module pathname", "value": "$libdir/plpgsql"}, {"label": "Comment", "value": "PL/pgSQL procedural language"}], "tables": [], "aliases": [], "related": [{"url": "/docs/14/plpgsql-control-structures.html", "label": "plpgsql-control-structures"}, {"url": "/docs/14/plpgsql-cursors.html", "label": "plpgsql-cursors"}, {"url": "/docs/14/plpgsql-declarations.html", "label": "plpgsql-declarations"}, {"url": "/docs/14/plpgsql-development-tips.html", "label": "plpgsql-development-tips"}, {"url": "/docs/14/plpgsql-errors-and-messages.html", "label": "plpgsql-errors-and-messages"}, {"url": "/docs/14/plpgsql-expressions.html", "label": "plpgsql-expressions"}, {"url": "/docs/14/plpgsql-implementation.html", "label": "plpgsql-implementation"}, {"url": "/docs/14/plpgsql-overview.html", "label": "plpgsql-overview"}, {"url": "/docs/14/plpgsql-porting.html", "label": "plpgsql-porting"}, {"url": "/docs/14/plpgsql-statements.html", "label": "plpgsql-statements"}, {"url": "/docs/14/plpgsql-structure.html", "label": "plpgsql-structure"}, {"url": "/docs/14/plpgsql-transactions.html", "label": "plpgsql-transactions"}, {"url": "/docs/14/plpgsql-trigger.html", "label": "plpgsql-trigger"}], "release": {"ref": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "label": "14.24", "major": "14", "channel": "stable", "revision": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897", "source_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897", "catalog_fingerprint": "b272e6a82e4c46efda81c3a6a4cdf7de6a83dfff7f02f226a392fbe9acdd3adb"}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "label": "Matching PostgreSQL source archive", "sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}, {"url": "/docs/14/plpgsql-overview.html", "path": "plpgsql-overview.html", "label": "PostgreSQL 14 English manual", "sha256": "a2491e8906b1f45815dce416711ecf6925da80b2daa518de513f9350b9ca5062"}], "sections": [{"code": "/* src/pl/plpgsql/src/plpgsql--1.0.sql */\n\nCREATE FUNCTION plpgsql_call_handler() RETURNS language_handler\n  LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_inline_handler(internal) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_validator(oid) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE TRUSTED LANGUAGE plpgsql\n  HANDLER plpgsql_call_handler\n  INLINE plpgsql_inline_handler\n  VALIDATOR plpgsql_validator;\n\n-- The language object, but not the functions, can be owned by a non-superuser.\nALTER LANGUAGE plpgsql OWNER TO @extowner@;\n\nCOMMENT ON LANGUAGE plpgsql IS 'PL/pgSQL procedural language';", "title": "Installation definition from the matching source archive", "paragraphs": ["This extension is shipped with the source. Its presence does not establish that the language or external runtime is installed."]}], "signature": "", "attributes": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "comment": "PL/pgSQL procedural language", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0", "module_pathname": "$libdir/plpgsql"}, "description": ["PL/pgSQL procedural language"], "manual_html": "<div class=\"sect1\" id=\"PLPGSQL-OVERVIEW\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h2 class=\"title\">43.1.\u00a0Overview</h2>\n</div>\n</div>\n</div>\n\n<p><span class=\"application\">PL/pgSQL</span> is a loadable procedural language for the <span class=\"productname\">PostgreSQL</span> database system. The design goals of <span class=\"application\">PL/pgSQL</span> were to create a loadable procedural language that</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>can be used to create functions, procedures, and triggers,</p>\n</li>\n<li class=\"listitem\">\n<p>adds control structures to the SQL language,</p>\n</li>\n<li class=\"listitem\">\n<p>can perform complex computations,</p>\n</li>\n<li class=\"listitem\">\n<p>inherits all user-defined types, functions, procedures, and operators,</p>\n</li>\n<li class=\"listitem\">\n<p>can be defined to be trusted by the server,</p>\n</li>\n<li class=\"listitem\">\n<p>is easy to use.</p>\n</li>\n</ul>\n</div>\n<p>Functions created with <span class=\"application\">PL/pgSQL</span> can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.</p>\n<p>In <span class=\"productname\">PostgreSQL</span> 9.0 and later, <span class=\"application\">PL/pgSQL</span> is installed by default. However it is still a loadable module, so especially security-conscious administrators could choose to remove it.</p>\n<div class=\"sect2\" id=\"PLPGSQL-ADVANTAGES\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">43.1.1.\u00a0Advantages of Using <span class=\"application\">PL/pgSQL</span></h3>\n</div>\n</div>\n</div>\n<p>SQL is the language <span class=\"productname\">PostgreSQL</span> and most other relational databases use as query language. It's portable and easy to learn. But every SQL statement must be executed individually by the database server.</p>\n<p>That means that your client application must send each query to the database server, wait for it to be processed, receive and process the results, do some computation, then send further queries to the server. All this incurs interprocess communication and will also incur network overhead if your client is on a different machine than the database server.</p>\n<p>With <span class=\"application\">PL/pgSQL</span> you can group a block of computation and a series of queries <span class=\"emphasis\"><em>inside</em></span> the database server, thus having the power of a procedural language and the ease of use of SQL, but with considerable savings of client/server communication overhead.</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>Extra round trips between client and server are eliminated</p>\n</li>\n<li class=\"listitem\">\n<p>Intermediate results that the client does not need do not have to be marshaled or transferred between server and client</p>\n</li>\n<li class=\"listitem\">\n<p>Multiple rounds of query parsing can be avoided</p>\n</li>\n</ul>\n</div>\n<p>This can result in a considerable performance increase as compared to an application that does not use stored functions.</p>\n<p>Also, with <span class=\"application\">PL/pgSQL</span> you can use all the data types, operators and functions of SQL.</p>\n</div>\n<div class=\"sect2\" id=\"PLPGSQL-ARGS-RESULTS\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">43.1.2.\u00a0Supported Argument and Result Data Types</h3>\n</div>\n</div>\n</div>\n<p>Functions written in <span class=\"application\">PL/pgSQL</span> can accept as arguments any scalar or array data type supported by the server, and they can return a result of any of these types. They can also accept or return any composite type (row type) specified by name. It is also possible to declare a <span class=\"application\">PL/pgSQL</span> function as accepting <code class=\"type\">record</code>, which means that any composite type will do as input, or as returning <code class=\"type\">record</code>, which means that the result is a row type whose columns are determined by specification in the calling query, as discussed in <a class=\"xref\" href=\"/docs/14/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS\" title=\"7.2.1.4.\u00a0Table Functions\">Section\u00a07.2.1.4</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can be declared to accept a variable number of arguments by using the <code class=\"literal\">VARIADIC</code> marker. This works exactly the same way as for SQL functions, as discussed in <a class=\"xref\" href=\"/docs/14/xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS\" title=\"38.5.6.\u00a0SQL Functions with Variable Numbers of Arguments\">Section\u00a038.5.6</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to accept and return the polymorphic types described in <a class=\"xref\" href=\"/docs/14/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"38.2.5.\u00a0Polymorphic Types\">Section\u00a038.2.5</a>, thus allowing the actual data types handled by the function to vary from call to call. Examples appear in <a class=\"xref\" href=\"/docs/14/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"43.3.1.\u00a0Declaring Function Parameters\">Section\u00a043.3.1</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to return a <span class=\"quote\">\u201c<span class=\"quote\">set</span>\u201d</span> (or table) of any data type that can be returned as a single instance. Such a function generates its output by executing <code class=\"command\">RETURN NEXT</code> for each desired element of the result set, or by using <code class=\"command\">RETURN QUERY</code> to output the result of evaluating a query.</p>\n<p>Finally, a <span class=\"application\">PL/pgSQL</span> function can be declared to return <code class=\"type\">void</code> if it has no useful return value. (Alternatively, it could be written as a procedure in that case.)</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared with output parameters in place of an explicit specification of the return type. This does not add any fundamental capability to the language, but it is often convenient, especially for returning multiple values. The <code class=\"literal\">RETURNS TABLE</code> notation can also be used in place of <code class=\"literal\">RETURNS SETOF</code>.</p>\n<p>Specific examples appear in <a class=\"xref\" href=\"/docs/14/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"43.3.1.\u00a0Declaring Function Parameters\">Section\u00a043.3.1</a> and <a class=\"xref\" href=\"/docs/14/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING\" title=\"43.6.1.\u00a0Returning from a Function\">Section\u00a043.6.1</a>.</p>\n</div>\n</div>", "manual_path": "/docs/14/plpgsql-overview.html", "source_files": {"src/pl/plpgsql/src/plpgsql.control": "9457c3f51d6bdfab93f13080d177795a9274c025e378fb613218342e3a3c7b45", "src/pl/plpgsql/src/plpgsql--1.0.sql": "f4e7e05438808ac0da0b3801397d16e36102969af7e2ffc982def5b7524fb557"}, "comparison_data": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0"}, "comparison_hash": "e85051f39a242ce658cedd87ac97437817f0f1b2baf992d8d37c9d29df8b558b"}, "15": {"facts": [{"label": "Kind", "value": "Bundled procedural-language variant"}, {"label": "Family", "value": "PL/pgSQL"}, {"label": "Trusted", "value": "t"}, {"label": "Handler", "value": "plpgsql_call_handler"}, {"label": "Inline handler", "value": "plpgsql_inline_handler"}, {"label": "Validator", "value": "plpgsql_validator"}, {"label": "Library", "value": "$libdir/plpgsql"}, {"label": "Default version", "value": "1.0"}, {"label": "Module pathname", "value": "$libdir/plpgsql"}, {"label": "Comment", "value": "PL/pgSQL procedural language"}], "tables": [], "aliases": [], "related": [{"url": "/docs/15/plpgsql-control-structures.html", "label": "plpgsql-control-structures"}, {"url": "/docs/15/plpgsql-cursors.html", "label": "plpgsql-cursors"}, {"url": "/docs/15/plpgsql-declarations.html", "label": "plpgsql-declarations"}, {"url": "/docs/15/plpgsql-development-tips.html", "label": "plpgsql-development-tips"}, {"url": "/docs/15/plpgsql-errors-and-messages.html", "label": "plpgsql-errors-and-messages"}, {"url": "/docs/15/plpgsql-expressions.html", "label": "plpgsql-expressions"}, {"url": "/docs/15/plpgsql-implementation.html", "label": "plpgsql-implementation"}, {"url": "/docs/15/plpgsql-overview.html", "label": "plpgsql-overview"}, {"url": "/docs/15/plpgsql-porting.html", "label": "plpgsql-porting"}, {"url": "/docs/15/plpgsql-statements.html", "label": "plpgsql-statements"}, {"url": "/docs/15/plpgsql-structure.html", "label": "plpgsql-structure"}, {"url": "/docs/15/plpgsql-transactions.html", "label": "plpgsql-transactions"}, {"url": "/docs/15/plpgsql-trigger.html", "label": "plpgsql-trigger"}], "release": {"ref": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "label": "15.19", "major": "15", "channel": "stable", "revision": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89", "source_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89", "catalog_fingerprint": "fefe3c425147a86defada190c9b0663cfe02caa1724f5dede93e46457572252d"}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "label": "Matching PostgreSQL source archive", "sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}, {"url": "/docs/15/plpgsql-overview.html", "path": "plpgsql-overview.html", "label": "PostgreSQL 15 English manual", "sha256": "b3add032f57b9d2701c25fa619d069a219d4d752ab87a39e71c7e5d376eae66c"}], "sections": [{"code": "/* src/pl/plpgsql/src/plpgsql--1.0.sql */\n\nCREATE FUNCTION plpgsql_call_handler() RETURNS language_handler\n  LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_inline_handler(internal) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_validator(oid) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE TRUSTED LANGUAGE plpgsql\n  HANDLER plpgsql_call_handler\n  INLINE plpgsql_inline_handler\n  VALIDATOR plpgsql_validator;\n\n-- The language object, but not the functions, can be owned by a non-superuser.\nALTER LANGUAGE plpgsql OWNER TO @extowner@;\n\nCOMMENT ON LANGUAGE plpgsql IS 'PL/pgSQL procedural language';", "title": "Installation definition from the matching source archive", "paragraphs": ["This extension is shipped with the source. Its presence does not establish that the language or external runtime is installed."]}], "signature": "", "attributes": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "comment": "PL/pgSQL procedural language", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0", "module_pathname": "$libdir/plpgsql"}, "description": ["PL/pgSQL procedural language"], "manual_html": "<div class=\"sect1\" id=\"PLPGSQL-OVERVIEW\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h2 class=\"title\">43.1.\u00a0Overview</h2>\n</div>\n</div>\n</div>\n\n<p><span class=\"application\">PL/pgSQL</span> is a loadable procedural language for the <span class=\"productname\">PostgreSQL</span> database system. The design goals of <span class=\"application\">PL/pgSQL</span> were to create a loadable procedural language that</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>can be used to create functions, procedures, and triggers,</p>\n</li>\n<li class=\"listitem\">\n<p>adds control structures to the SQL language,</p>\n</li>\n<li class=\"listitem\">\n<p>can perform complex computations,</p>\n</li>\n<li class=\"listitem\">\n<p>inherits all user-defined types, functions, procedures, and operators,</p>\n</li>\n<li class=\"listitem\">\n<p>can be defined to be trusted by the server,</p>\n</li>\n<li class=\"listitem\">\n<p>is easy to use.</p>\n</li>\n</ul>\n</div>\n<p>Functions created with <span class=\"application\">PL/pgSQL</span> can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.</p>\n<p>In <span class=\"productname\">PostgreSQL</span> 9.0 and later, <span class=\"application\">PL/pgSQL</span> is installed by default. However it is still a loadable module, so especially security-conscious administrators could choose to remove it.</p>\n<div class=\"sect2\" id=\"PLPGSQL-ADVANTAGES\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">43.1.1.\u00a0Advantages of Using <span class=\"application\">PL/pgSQL</span></h3>\n</div>\n</div>\n</div>\n<p>SQL is the language <span class=\"productname\">PostgreSQL</span> and most other relational databases use as query language. It's portable and easy to learn. But every SQL statement must be executed individually by the database server.</p>\n<p>That means that your client application must send each query to the database server, wait for it to be processed, receive and process the results, do some computation, then send further queries to the server. All this incurs interprocess communication and will also incur network overhead if your client is on a different machine than the database server.</p>\n<p>With <span class=\"application\">PL/pgSQL</span> you can group a block of computation and a series of queries <span class=\"emphasis\"><em>inside</em></span> the database server, thus having the power of a procedural language and the ease of use of SQL, but with considerable savings of client/server communication overhead.</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>Extra round trips between client and server are eliminated</p>\n</li>\n<li class=\"listitem\">\n<p>Intermediate results that the client does not need do not have to be marshaled or transferred between server and client</p>\n</li>\n<li class=\"listitem\">\n<p>Multiple rounds of query parsing can be avoided</p>\n</li>\n</ul>\n</div>\n<p>This can result in a considerable performance increase as compared to an application that does not use stored functions.</p>\n<p>Also, with <span class=\"application\">PL/pgSQL</span> you can use all the data types, operators and functions of SQL.</p>\n</div>\n<div class=\"sect2\" id=\"PLPGSQL-ARGS-RESULTS\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">43.1.2.\u00a0Supported Argument and Result Data Types</h3>\n</div>\n</div>\n</div>\n<p>Functions written in <span class=\"application\">PL/pgSQL</span> can accept as arguments any scalar or array data type supported by the server, and they can return a result of any of these types. They can also accept or return any composite type (row type) specified by name. It is also possible to declare a <span class=\"application\">PL/pgSQL</span> function as accepting <code class=\"type\">record</code>, which means that any composite type will do as input, or as returning <code class=\"type\">record</code>, which means that the result is a row type whose columns are determined by specification in the calling query, as discussed in <a class=\"xref\" href=\"/docs/15/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS\" title=\"7.2.1.4.\u00a0Table Functions\">Section\u00a07.2.1.4</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can be declared to accept a variable number of arguments by using the <code class=\"literal\">VARIADIC</code> marker. This works exactly the same way as for SQL functions, as discussed in <a class=\"xref\" href=\"/docs/15/xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS\" title=\"38.5.6.\u00a0SQL Functions with Variable Numbers of Arguments\">Section\u00a038.5.6</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to accept and return the polymorphic types described in <a class=\"xref\" href=\"/docs/15/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"38.2.5.\u00a0Polymorphic Types\">Section\u00a038.2.5</a>, thus allowing the actual data types handled by the function to vary from call to call. Examples appear in <a class=\"xref\" href=\"/docs/15/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"43.3.1.\u00a0Declaring Function Parameters\">Section\u00a043.3.1</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to return a <span class=\"quote\">\u201c<span class=\"quote\">set</span>\u201d</span> (or table) of any data type that can be returned as a single instance. Such a function generates its output by executing <code class=\"command\">RETURN NEXT</code> for each desired element of the result set, or by using <code class=\"command\">RETURN QUERY</code> to output the result of evaluating a query.</p>\n<p>Finally, a <span class=\"application\">PL/pgSQL</span> function can be declared to return <code class=\"type\">void</code> if it has no useful return value. (Alternatively, it could be written as a procedure in that case.)</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared with output parameters in place of an explicit specification of the return type. This does not add any fundamental capability to the language, but it is often convenient, especially for returning multiple values. The <code class=\"literal\">RETURNS TABLE</code> notation can also be used in place of <code class=\"literal\">RETURNS SETOF</code>.</p>\n<p>Specific examples appear in <a class=\"xref\" href=\"/docs/15/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"43.3.1.\u00a0Declaring Function Parameters\">Section\u00a043.3.1</a> and <a class=\"xref\" href=\"/docs/15/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING\" title=\"43.6.1.\u00a0Returning from a Function\">Section\u00a043.6.1</a>.</p>\n</div>\n</div>", "manual_path": "/docs/15/plpgsql-overview.html", "source_files": {"src/pl/plpgsql/src/plpgsql.control": "9457c3f51d6bdfab93f13080d177795a9274c025e378fb613218342e3a3c7b45", "src/pl/plpgsql/src/plpgsql--1.0.sql": "f4e7e05438808ac0da0b3801397d16e36102969af7e2ffc982def5b7524fb557"}, "comparison_data": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0"}, "comparison_hash": "e85051f39a242ce658cedd87ac97437817f0f1b2baf992d8d37c9d29df8b558b"}, "16": {"facts": [{"label": "Kind", "value": "Bundled procedural-language variant"}, {"label": "Family", "value": "PL/pgSQL"}, {"label": "Trusted", "value": "t"}, {"label": "Handler", "value": "plpgsql_call_handler"}, {"label": "Inline handler", "value": "plpgsql_inline_handler"}, {"label": "Validator", "value": "plpgsql_validator"}, {"label": "Library", "value": "$libdir/plpgsql"}, {"label": "Default version", "value": "1.0"}, {"label": "Module pathname", "value": "$libdir/plpgsql"}, {"label": "Comment", "value": "PL/pgSQL procedural language"}], "tables": [], "aliases": [], "related": [{"url": "/docs/16/plpgsql-control-structures.html", "label": "plpgsql-control-structures"}, {"url": "/docs/16/plpgsql-cursors.html", "label": "plpgsql-cursors"}, {"url": "/docs/16/plpgsql-declarations.html", "label": "plpgsql-declarations"}, {"url": "/docs/16/plpgsql-development-tips.html", "label": "plpgsql-development-tips"}, {"url": "/docs/16/plpgsql-errors-and-messages.html", "label": "plpgsql-errors-and-messages"}, {"url": "/docs/16/plpgsql-expressions.html", "label": "plpgsql-expressions"}, {"url": "/docs/16/plpgsql-implementation.html", "label": "plpgsql-implementation"}, {"url": "/docs/16/plpgsql-overview.html", "label": "plpgsql-overview"}, {"url": "/docs/16/plpgsql-porting.html", "label": "plpgsql-porting"}, {"url": "/docs/16/plpgsql-statements.html", "label": "plpgsql-statements"}, {"url": "/docs/16/plpgsql-structure.html", "label": "plpgsql-structure"}, {"url": "/docs/16/plpgsql-transactions.html", "label": "plpgsql-transactions"}, {"url": "/docs/16/plpgsql-trigger.html", "label": "plpgsql-trigger"}], "release": {"ref": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "label": "16.15", "major": "16", "channel": "stable", "revision": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed", "source_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed", "catalog_fingerprint": "fa133458dc8f52e15083b4f59b7a582e2e378b608d3ac5c53054df458a374e23"}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "label": "Matching PostgreSQL source archive", "sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}, {"url": "/docs/16/plpgsql-overview.html", "path": "plpgsql-overview.html", "label": "PostgreSQL 16 English manual", "sha256": "c273d4a8ffbd67c5c7aad1d78032becad542a5b9ed22a8784c4eaa1860d86d31"}], "sections": [{"code": "/* src/pl/plpgsql/src/plpgsql--1.0.sql */\n\nCREATE FUNCTION plpgsql_call_handler() RETURNS language_handler\n  LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_inline_handler(internal) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_validator(oid) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE TRUSTED LANGUAGE plpgsql\n  HANDLER plpgsql_call_handler\n  INLINE plpgsql_inline_handler\n  VALIDATOR plpgsql_validator;\n\n-- The language object, but not the functions, can be owned by a non-superuser.\nALTER LANGUAGE plpgsql OWNER TO @extowner@;\n\nCOMMENT ON LANGUAGE plpgsql IS 'PL/pgSQL procedural language';", "title": "Installation definition from the matching source archive", "paragraphs": ["This extension is shipped with the source. Its presence does not establish that the language or external runtime is installed."]}], "signature": "", "attributes": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "comment": "PL/pgSQL procedural language", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0", "module_pathname": "$libdir/plpgsql"}, "description": ["PL/pgSQL procedural language"], "manual_html": "<div class=\"sect1\" id=\"PLPGSQL-OVERVIEW\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h2 class=\"title\">43.1.\u00a0Overview </h2>\n</div>\n</div>\n</div>\n\n<p><span class=\"application\">PL/pgSQL</span> is a loadable procedural language for the <span class=\"productname\">PostgreSQL</span> database system. The design goals of <span class=\"application\">PL/pgSQL</span> were to create a loadable procedural language that</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>can be used to create functions, procedures, and triggers,</p>\n</li>\n<li class=\"listitem\">\n<p>adds control structures to the SQL language,</p>\n</li>\n<li class=\"listitem\">\n<p>can perform complex computations,</p>\n</li>\n<li class=\"listitem\">\n<p>inherits all user-defined types, functions, procedures, and operators,</p>\n</li>\n<li class=\"listitem\">\n<p>can be defined to be trusted by the server,</p>\n</li>\n<li class=\"listitem\">\n<p>is easy to use.</p>\n</li>\n</ul>\n</div>\n<p>Functions created with <span class=\"application\">PL/pgSQL</span> can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.</p>\n<p>In <span class=\"productname\">PostgreSQL</span> 9.0 and later, <span class=\"application\">PL/pgSQL</span> is installed by default. However it is still a loadable module, so especially security-conscious administrators could choose to remove it.</p>\n<div class=\"sect2\" id=\"PLPGSQL-ADVANTAGES\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">43.1.1.\u00a0Advantages of Using <span class=\"application\">PL/pgSQL</span> </h3>\n</div>\n</div>\n</div>\n<p>SQL is the language <span class=\"productname\">PostgreSQL</span> and most other relational databases use as query language. It's portable and easy to learn. But every SQL statement must be executed individually by the database server.</p>\n<p>That means that your client application must send each query to the database server, wait for it to be processed, receive and process the results, do some computation, then send further queries to the server. All this incurs interprocess communication and will also incur network overhead if your client is on a different machine than the database server.</p>\n<p>With <span class=\"application\">PL/pgSQL</span> you can group a block of computation and a series of queries <span class=\"emphasis\"><em>inside</em></span> the database server, thus having the power of a procedural language and the ease of use of SQL, but with considerable savings of client/server communication overhead.</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>Extra round trips between client and server are eliminated</p>\n</li>\n<li class=\"listitem\">\n<p>Intermediate results that the client does not need do not have to be marshaled or transferred between server and client</p>\n</li>\n<li class=\"listitem\">\n<p>Multiple rounds of query parsing can be avoided</p>\n</li>\n</ul>\n</div>\n<p>This can result in a considerable performance increase as compared to an application that does not use stored functions.</p>\n<p>Also, with <span class=\"application\">PL/pgSQL</span> you can use all the data types, operators and functions of SQL.</p>\n</div>\n<div class=\"sect2\" id=\"PLPGSQL-ARGS-RESULTS\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">43.1.2.\u00a0Supported Argument and Result Data Types </h3>\n</div>\n</div>\n</div>\n<p>Functions written in <span class=\"application\">PL/pgSQL</span> can accept as arguments any scalar or array data type supported by the server, and they can return a result of any of these types. They can also accept or return any composite type (row type) specified by name. It is also possible to declare a <span class=\"application\">PL/pgSQL</span> function as accepting <code class=\"type\">record</code>, which means that any composite type will do as input, or as returning <code class=\"type\">record</code>, which means that the result is a row type whose columns are determined by specification in the calling query, as discussed in <a class=\"xref\" href=\"/docs/16/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS\" title=\"7.2.1.4.\u00a0Table Functions\">Section\u00a07.2.1.4</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can be declared to accept a variable number of arguments by using the <code class=\"literal\">VARIADIC</code> marker. This works exactly the same way as for SQL functions, as discussed in <a class=\"xref\" href=\"/docs/16/xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS\" title=\"38.5.6.\u00a0SQL Functions with Variable Numbers of Arguments\">Section\u00a038.5.6</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to accept and return the polymorphic types described in <a class=\"xref\" href=\"/docs/16/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"38.2.5.\u00a0Polymorphic Types\">Section\u00a038.2.5</a>, thus allowing the actual data types handled by the function to vary from call to call. Examples appear in <a class=\"xref\" href=\"/docs/16/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"43.3.1.\u00a0Declaring Function Parameters\">Section\u00a043.3.1</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to return a <span class=\"quote\">\u201c<span class=\"quote\">set</span>\u201d</span> (or table) of any data type that can be returned as a single instance. Such a function generates its output by executing <code class=\"command\">RETURN NEXT</code> for each desired element of the result set, or by using <code class=\"command\">RETURN QUERY</code> to output the result of evaluating a query.</p>\n<p>Finally, a <span class=\"application\">PL/pgSQL</span> function can be declared to return <code class=\"type\">void</code> if it has no useful return value. (Alternatively, it could be written as a procedure in that case.)</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared with output parameters in place of an explicit specification of the return type. This does not add any fundamental capability to the language, but it is often convenient, especially for returning multiple values. The <code class=\"literal\">RETURNS TABLE</code> notation can also be used in place of <code class=\"literal\">RETURNS SETOF</code>.</p>\n<p>Specific examples appear in <a class=\"xref\" href=\"/docs/16/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"43.3.1.\u00a0Declaring Function Parameters\">Section\u00a043.3.1</a> and <a class=\"xref\" href=\"/docs/16/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING\" title=\"43.6.1.\u00a0Returning from a Function\">Section\u00a043.6.1</a>.</p>\n</div>\n</div>", "manual_path": "/docs/16/plpgsql-overview.html", "source_files": {"src/pl/plpgsql/src/plpgsql.control": "9457c3f51d6bdfab93f13080d177795a9274c025e378fb613218342e3a3c7b45", "src/pl/plpgsql/src/plpgsql--1.0.sql": "f4e7e05438808ac0da0b3801397d16e36102969af7e2ffc982def5b7524fb557"}, "comparison_data": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0"}, "comparison_hash": "e85051f39a242ce658cedd87ac97437817f0f1b2baf992d8d37c9d29df8b558b"}, "17": {"facts": [{"label": "Kind", "value": "Bundled procedural-language variant"}, {"label": "Family", "value": "PL/pgSQL"}, {"label": "Trusted", "value": "t"}, {"label": "Handler", "value": "plpgsql_call_handler"}, {"label": "Inline handler", "value": "plpgsql_inline_handler"}, {"label": "Validator", "value": "plpgsql_validator"}, {"label": "Library", "value": "$libdir/plpgsql"}, {"label": "Default version", "value": "1.0"}, {"label": "Module pathname", "value": "$libdir/plpgsql"}, {"label": "Comment", "value": "PL/pgSQL procedural language"}], "tables": [], "aliases": [], "related": [{"url": "/docs/17/plpgsql-control-structures.html", "label": "plpgsql-control-structures"}, {"url": "/docs/17/plpgsql-cursors.html", "label": "plpgsql-cursors"}, {"url": "/docs/17/plpgsql-declarations.html", "label": "plpgsql-declarations"}, {"url": "/docs/17/plpgsql-development-tips.html", "label": "plpgsql-development-tips"}, {"url": "/docs/17/plpgsql-errors-and-messages.html", "label": "plpgsql-errors-and-messages"}, {"url": "/docs/17/plpgsql-expressions.html", "label": "plpgsql-expressions"}, {"url": "/docs/17/plpgsql-implementation.html", "label": "plpgsql-implementation"}, {"url": "/docs/17/plpgsql-overview.html", "label": "plpgsql-overview"}, {"url": "/docs/17/plpgsql-porting.html", "label": "plpgsql-porting"}, {"url": "/docs/17/plpgsql-statements.html", "label": "plpgsql-statements"}, {"url": "/docs/17/plpgsql-structure.html", "label": "plpgsql-structure"}, {"url": "/docs/17/plpgsql-transactions.html", "label": "plpgsql-transactions"}, {"url": "/docs/17/plpgsql-trigger.html", "label": "plpgsql-trigger"}], "release": {"ref": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "label": "17.11", "major": "17", "channel": "stable", "revision": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979", "source_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979", "catalog_fingerprint": "4bbe3ac77becd618478f66aec420a533e9017be356c5c1d51a4b17f0fd497c07"}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "label": "Matching PostgreSQL source archive", "sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}, {"url": "/docs/17/plpgsql-overview.html", "path": "plpgsql-overview.html", "label": "PostgreSQL 17 English manual", "sha256": "12a593e4e51bdb0535cfc433f8ec2dc29d3b5ef75095a4f7f90be53b42be0240"}], "sections": [{"code": "/* src/pl/plpgsql/src/plpgsql--1.0.sql */\n\nCREATE FUNCTION plpgsql_call_handler() RETURNS language_handler\n  LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_inline_handler(internal) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_validator(oid) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE TRUSTED LANGUAGE plpgsql\n  HANDLER plpgsql_call_handler\n  INLINE plpgsql_inline_handler\n  VALIDATOR plpgsql_validator;\n\n-- The language object, but not the functions, can be owned by a non-superuser.\nALTER LANGUAGE plpgsql OWNER TO @extowner@;\n\nCOMMENT ON LANGUAGE plpgsql IS 'PL/pgSQL procedural language';", "title": "Installation definition from the matching source archive", "paragraphs": ["This extension is shipped with the source. Its presence does not establish that the language or external runtime is installed."]}], "signature": "", "attributes": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "comment": "PL/pgSQL procedural language", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0", "module_pathname": "$libdir/plpgsql"}, "description": ["PL/pgSQL procedural language"], "manual_html": "<div class=\"sect1\" id=\"PLPGSQL-OVERVIEW\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h2 class=\"title\">41.1.\u00a0Overview </h2>\n</div>\n</div>\n</div>\n\n<p><span class=\"application\">PL/pgSQL</span> is a loadable procedural language for the <span class=\"productname\">PostgreSQL</span> database system. The design goals of <span class=\"application\">PL/pgSQL</span> were to create a loadable procedural language that</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>can be used to create functions, procedures, and triggers,</p>\n</li>\n<li class=\"listitem\">\n<p>adds control structures to the SQL language,</p>\n</li>\n<li class=\"listitem\">\n<p>can perform complex computations,</p>\n</li>\n<li class=\"listitem\">\n<p>inherits all user-defined types, functions, procedures, and operators,</p>\n</li>\n<li class=\"listitem\">\n<p>can be defined to be trusted by the server,</p>\n</li>\n<li class=\"listitem\">\n<p>is easy to use.</p>\n</li>\n</ul>\n</div>\n<p>Functions created with <span class=\"application\">PL/pgSQL</span> can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.</p>\n<p>In <span class=\"productname\">PostgreSQL</span> 9.0 and later, <span class=\"application\">PL/pgSQL</span> is installed by default. However it is still a loadable module, so especially security-conscious administrators could choose to remove it.</p>\n<div class=\"sect2\" id=\"PLPGSQL-ADVANTAGES\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">41.1.1.\u00a0Advantages of Using <span class=\"application\">PL/pgSQL</span> </h3>\n</div>\n</div>\n</div>\n<p>SQL is the language <span class=\"productname\">PostgreSQL</span> and most other relational databases use as query language. It's portable and easy to learn. But every SQL statement must be executed individually by the database server.</p>\n<p>That means that your client application must send each query to the database server, wait for it to be processed, receive and process the results, do some computation, then send further queries to the server. All this incurs interprocess communication and will also incur network overhead if your client is on a different machine than the database server.</p>\n<p>With <span class=\"application\">PL/pgSQL</span> you can group a block of computation and a series of queries <span class=\"emphasis\"><em>inside</em></span> the database server, thus having the power of a procedural language and the ease of use of SQL, but with considerable savings of client/server communication overhead.</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>Extra round trips between client and server are eliminated</p>\n</li>\n<li class=\"listitem\">\n<p>Intermediate results that the client does not need do not have to be marshaled or transferred between server and client</p>\n</li>\n<li class=\"listitem\">\n<p>Multiple rounds of query parsing can be avoided</p>\n</li>\n</ul>\n</div>\n<p>This can result in a considerable performance increase as compared to an application that does not use stored functions.</p>\n<p>Also, with <span class=\"application\">PL/pgSQL</span> you can use all the data types, operators and functions of SQL.</p>\n</div>\n<div class=\"sect2\" id=\"PLPGSQL-ARGS-RESULTS\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">41.1.2.\u00a0Supported Argument and Result Data Types </h3>\n</div>\n</div>\n</div>\n<p>Functions written in <span class=\"application\">PL/pgSQL</span> can accept as arguments any scalar or array data type supported by the server, and they can return a result of any of these types. They can also accept or return any composite type (row type) specified by name. It is also possible to declare a <span class=\"application\">PL/pgSQL</span> function as accepting <code class=\"type\">record</code>, which means that any composite type will do as input, or as returning <code class=\"type\">record</code>, which means that the result is a row type whose columns are determined by specification in the calling query, as discussed in <a class=\"xref\" href=\"/docs/17/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS\" title=\"7.2.1.4.\u00a0Table Functions\">Section\u00a07.2.1.4</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can be declared to accept a variable number of arguments by using the <code class=\"literal\">VARIADIC</code> marker. This works exactly the same way as for SQL functions, as discussed in <a class=\"xref\" href=\"/docs/17/xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS\" title=\"36.5.6.\u00a0SQL Functions with Variable Numbers of Arguments\">Section\u00a036.5.6</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to accept and return the polymorphic types described in <a class=\"xref\" href=\"/docs/17/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"36.2.5.\u00a0Polymorphic Types\">Section\u00a036.2.5</a>, thus allowing the actual data types handled by the function to vary from call to call. Examples appear in <a class=\"xref\" href=\"/docs/17/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"41.3.1.\u00a0Declaring Function Parameters\">Section\u00a041.3.1</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to return a <span class=\"quote\">\u201c<span class=\"quote\">set</span>\u201d</span> (or table) of any data type that can be returned as a single instance. Such a function generates its output by executing <code class=\"command\">RETURN NEXT</code> for each desired element of the result set, or by using <code class=\"command\">RETURN QUERY</code> to output the result of evaluating a query.</p>\n<p>Finally, a <span class=\"application\">PL/pgSQL</span> function can be declared to return <code class=\"type\">void</code> if it has no useful return value. (Alternatively, it could be written as a procedure in that case.)</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared with output parameters in place of an explicit specification of the return type. This does not add any fundamental capability to the language, but it is often convenient, especially for returning multiple values. The <code class=\"literal\">RETURNS TABLE</code> notation can also be used in place of <code class=\"literal\">RETURNS SETOF</code>.</p>\n<p>Specific examples appear in <a class=\"xref\" href=\"/docs/17/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"41.3.1.\u00a0Declaring Function Parameters\">Section\u00a041.3.1</a> and <a class=\"xref\" href=\"/docs/17/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING\" title=\"41.6.1.\u00a0Returning from a Function\">Section\u00a041.6.1</a>.</p>\n</div>\n</div>", "manual_path": "/docs/17/plpgsql-overview.html", "source_files": {"src/pl/plpgsql/src/plpgsql.control": "9457c3f51d6bdfab93f13080d177795a9274c025e378fb613218342e3a3c7b45", "src/pl/plpgsql/src/plpgsql--1.0.sql": "f4e7e05438808ac0da0b3801397d16e36102969af7e2ffc982def5b7524fb557"}, "comparison_data": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0"}, "comparison_hash": "e85051f39a242ce658cedd87ac97437817f0f1b2baf992d8d37c9d29df8b558b"}, "18": {"facts": [{"label": "Kind", "value": "Bundled procedural-language variant"}, {"label": "Family", "value": "PL/pgSQL"}, {"label": "Trusted", "value": "t"}, {"label": "Handler", "value": "plpgsql_call_handler"}, {"label": "Inline handler", "value": "plpgsql_inline_handler"}, {"label": "Validator", "value": "plpgsql_validator"}, {"label": "Library", "value": "$libdir/plpgsql"}, {"label": "Default version", "value": "1.0"}, {"label": "Module pathname", "value": "$libdir/plpgsql"}, {"label": "Comment", "value": "PL/pgSQL procedural language"}], "tables": [], "aliases": [], "related": [{"url": "/docs/18/plpgsql-control-structures.html", "label": "plpgsql-control-structures"}, {"url": "/docs/18/plpgsql-cursors.html", "label": "plpgsql-cursors"}, {"url": "/docs/18/plpgsql-declarations.html", "label": "plpgsql-declarations"}, {"url": "/docs/18/plpgsql-development-tips.html", "label": "plpgsql-development-tips"}, {"url": "/docs/18/plpgsql-errors-and-messages.html", "label": "plpgsql-errors-and-messages"}, {"url": "/docs/18/plpgsql-expressions.html", "label": "plpgsql-expressions"}, {"url": "/docs/18/plpgsql-implementation.html", "label": "plpgsql-implementation"}, {"url": "/docs/18/plpgsql-overview.html", "label": "plpgsql-overview"}, {"url": "/docs/18/plpgsql-porting.html", "label": "plpgsql-porting"}, {"url": "/docs/18/plpgsql-statements.html", "label": "plpgsql-statements"}, {"url": "/docs/18/plpgsql-structure.html", "label": "plpgsql-structure"}, {"url": "/docs/18/plpgsql-transactions.html", "label": "plpgsql-transactions"}, {"url": "/docs/18/plpgsql-trigger.html", "label": "plpgsql-trigger"}], "release": {"ref": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "label": "18.6", "major": "18", "channel": "stable", "revision": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f", "source_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f", "catalog_fingerprint": "65c93d6048ef30e61023a84f9680fa6a92b1c383b7eb226741170077eb078502"}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "label": "Matching PostgreSQL source archive", "sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "/docs/18/plpgsql-overview.html", "path": "plpgsql-overview.html", "label": "PostgreSQL 18 English manual", "sha256": "7f93dfdf27c74b24d0bd355e845c7a6ff142aa9479bdcd0f203e8d37f36a3dfc"}], "sections": [{"code": "/* src/pl/plpgsql/src/plpgsql--1.0.sql */\n\nCREATE FUNCTION plpgsql_call_handler() RETURNS language_handler\n  LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_inline_handler(internal) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_validator(oid) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE TRUSTED LANGUAGE plpgsql\n  HANDLER plpgsql_call_handler\n  INLINE plpgsql_inline_handler\n  VALIDATOR plpgsql_validator;\n\n-- The language object, but not the functions, can be owned by a non-superuser.\nALTER LANGUAGE plpgsql OWNER TO @extowner@;\n\nCOMMENT ON LANGUAGE plpgsql IS 'PL/pgSQL procedural language';", "title": "Installation definition from the matching source archive", "paragraphs": ["This extension is shipped with the source. Its presence does not establish that the language or external runtime is installed."]}], "signature": "", "attributes": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "comment": "PL/pgSQL procedural language", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0", "module_pathname": "$libdir/plpgsql"}, "description": ["PL/pgSQL procedural language"], "manual_html": "<div class=\"sect1\" id=\"PLPGSQL-OVERVIEW\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h2 class=\"title\">41.1.\u00a0Overview </h2>\n</div>\n</div>\n</div>\n\n<p><span class=\"application\">PL/pgSQL</span> is a loadable procedural language for the <span class=\"productname\">PostgreSQL</span> database system. The design goals of <span class=\"application\">PL/pgSQL</span> were to create a loadable procedural language that</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>can be used to create functions, procedures, and triggers,</p>\n</li>\n<li class=\"listitem\">\n<p>adds control structures to the SQL language,</p>\n</li>\n<li class=\"listitem\">\n<p>can perform complex computations,</p>\n</li>\n<li class=\"listitem\">\n<p>inherits all user-defined types, functions, procedures, and operators,</p>\n</li>\n<li class=\"listitem\">\n<p>can be defined to be trusted by the server,</p>\n</li>\n<li class=\"listitem\">\n<p>is easy to use.</p>\n</li>\n</ul>\n</div>\n<p>Functions created with <span class=\"application\">PL/pgSQL</span> can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.</p>\n<p>In <span class=\"productname\">PostgreSQL</span> 9.0 and later, <span class=\"application\">PL/pgSQL</span> is installed by default. However it is still a loadable module, so especially security-conscious administrators could choose to remove it.</p>\n<div class=\"sect2\" id=\"PLPGSQL-ADVANTAGES\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">41.1.1.\u00a0Advantages of Using <span class=\"application\">PL/pgSQL</span> </h3>\n</div>\n</div>\n</div>\n<p>SQL is the language <span class=\"productname\">PostgreSQL</span> and most other relational databases use as query language. It's portable and easy to learn. But every SQL statement must be executed individually by the database server.</p>\n<p>That means that your client application must send each query to the database server, wait for it to be processed, receive and process the results, do some computation, then send further queries to the server. All this incurs interprocess communication and will also incur network overhead if your client is on a different machine than the database server.</p>\n<p>With <span class=\"application\">PL/pgSQL</span> you can group a block of computation and a series of queries <span class=\"emphasis\"><em>inside</em></span> the database server, thus having the power of a procedural language and the ease of use of SQL, but with considerable savings of client/server communication overhead.</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>Extra round trips between client and server are eliminated</p>\n</li>\n<li class=\"listitem\">\n<p>Intermediate results that the client does not need do not have to be marshaled or transferred between server and client</p>\n</li>\n<li class=\"listitem\">\n<p>Multiple rounds of query parsing can be avoided</p>\n</li>\n</ul>\n</div>\n<p>This can result in a considerable performance increase as compared to an application that does not use stored functions.</p>\n<p>Also, with <span class=\"application\">PL/pgSQL</span> you can use all the data types, operators and functions of SQL.</p>\n</div>\n<div class=\"sect2\" id=\"PLPGSQL-ARGS-RESULTS\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">41.1.2.\u00a0Supported Argument and Result Data Types </h3>\n</div>\n</div>\n</div>\n<p>Functions written in <span class=\"application\">PL/pgSQL</span> can accept as arguments any scalar or array data type supported by the server, and they can return a result of any of these types. They can also accept or return any composite type (row type) specified by name. It is also possible to declare a <span class=\"application\">PL/pgSQL</span> function as accepting <code class=\"type\">record</code>, which means that any composite type will do as input, or as returning <code class=\"type\">record</code>, which means that the result is a row type whose columns are determined by specification in the calling query, as discussed in <a class=\"xref\" href=\"/docs/18/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS\" title=\"7.2.1.4.\u00a0Table Functions\">Section\u00a07.2.1.4</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can be declared to accept a variable number of arguments by using the <code class=\"literal\">VARIADIC</code> marker. This works exactly the same way as for SQL functions, as discussed in <a class=\"xref\" href=\"/docs/18/xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS\" title=\"36.5.6.\u00a0SQL Functions with Variable Numbers of Arguments\">Section\u00a036.5.6</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to accept and return the polymorphic types described in <a class=\"xref\" href=\"/docs/18/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"36.2.5.\u00a0Polymorphic Types\">Section\u00a036.2.5</a>, thus allowing the actual data types handled by the function to vary from call to call. Examples appear in <a class=\"xref\" href=\"/docs/18/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"41.3.1.\u00a0Declaring Function Parameters\">Section\u00a041.3.1</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to return a <span class=\"quote\">\u201c<span class=\"quote\">set</span>\u201d</span> (or table) of any data type that can be returned as a single instance. Such a function generates its output by executing <code class=\"command\">RETURN NEXT</code> for each desired element of the result set, or by using <code class=\"command\">RETURN QUERY</code> to output the result of evaluating a query.</p>\n<p>Finally, a <span class=\"application\">PL/pgSQL</span> function can be declared to return <code class=\"type\">void</code> if it has no useful return value. (Alternatively, it could be written as a procedure in that case.)</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared with output parameters in place of an explicit specification of the return type. This does not add any fundamental capability to the language, but it is often convenient, especially for returning multiple values. The <code class=\"literal\">RETURNS TABLE</code> notation can also be used in place of <code class=\"literal\">RETURNS SETOF</code>.</p>\n<p>Specific examples appear in <a class=\"xref\" href=\"/docs/18/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"41.3.1.\u00a0Declaring Function Parameters\">Section\u00a041.3.1</a> and <a class=\"xref\" href=\"/docs/18/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING\" title=\"41.6.1.\u00a0Returning from a Function\">Section\u00a041.6.1</a>.</p>\n</div>\n</div>", "manual_path": "/docs/18/plpgsql-overview.html", "source_files": {"src/pl/plpgsql/src/plpgsql.control": "9457c3f51d6bdfab93f13080d177795a9274c025e378fb613218342e3a3c7b45", "src/pl/plpgsql/src/plpgsql--1.0.sql": "f4e7e05438808ac0da0b3801397d16e36102969af7e2ffc982def5b7524fb557"}, "comparison_data": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0"}, "comparison_hash": "e85051f39a242ce658cedd87ac97437817f0f1b2baf992d8d37c9d29df8b558b"}, "19": {"facts": [{"label": "Kind", "value": "Bundled procedural-language variant"}, {"label": "Family", "value": "PL/pgSQL"}, {"label": "Trusted", "value": "t"}, {"label": "Handler", "value": "plpgsql_call_handler"}, {"label": "Inline handler", "value": "plpgsql_inline_handler"}, {"label": "Validator", "value": "plpgsql_validator"}, {"label": "Library", "value": "$libdir/plpgsql"}, {"label": "Default version", "value": "1.0"}, {"label": "Module pathname", "value": "$libdir/plpgsql"}, {"label": "Comment", "value": "PL/pgSQL procedural language"}], "tables": [], "aliases": [], "related": [{"url": "/docs/19/plpgsql-control-structures.html", "label": "plpgsql-control-structures"}, {"url": "/docs/19/plpgsql-cursors.html", "label": "plpgsql-cursors"}, {"url": "/docs/19/plpgsql-declarations.html", "label": "plpgsql-declarations"}, {"url": "/docs/19/plpgsql-development-tips.html", "label": "plpgsql-development-tips"}, {"url": "/docs/19/plpgsql-errors-and-messages.html", "label": "plpgsql-errors-and-messages"}, {"url": "/docs/19/plpgsql-expressions.html", "label": "plpgsql-expressions"}, {"url": "/docs/19/plpgsql-implementation.html", "label": "plpgsql-implementation"}, {"url": "/docs/19/plpgsql-overview.html", "label": "plpgsql-overview"}, {"url": "/docs/19/plpgsql-porting.html", "label": "plpgsql-porting"}, {"url": "/docs/19/plpgsql-statements.html", "label": "plpgsql-statements"}, {"url": "/docs/19/plpgsql-structure.html", "label": "plpgsql-structure"}, {"url": "/docs/19/plpgsql-transactions.html", "label": "plpgsql-transactions"}, {"url": "/docs/19/plpgsql-trigger.html", "label": "plpgsql-trigger"}], "release": {"ref": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "label": "19beta4", "major": "19", "channel": "preview", "revision": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86", "source_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86", "catalog_fingerprint": "62fbf1a3689dbe8bf7e6b3372cfe6fbf867581427b3858a94c8419b77a4d2d1d"}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "label": "Matching PostgreSQL source archive", "sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}, {"url": "/docs/19/plpgsql-overview.html", "path": "plpgsql-overview.html", "label": "PostgreSQL 19 English manual", "sha256": "0c9878b8af229dae348c65bf221f83b15f8dc940395f99e3c4749cf4c41e081b"}], "sections": [{"code": "/* src/pl/plpgsql/src/plpgsql--1.0.sql */\n\nCREATE FUNCTION plpgsql_call_handler() RETURNS language_handler\n  LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_inline_handler(internal) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_validator(oid) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE TRUSTED LANGUAGE plpgsql\n  HANDLER plpgsql_call_handler\n  INLINE plpgsql_inline_handler\n  VALIDATOR plpgsql_validator;\n\n-- The language object, but not the functions, can be owned by a non-superuser.\nALTER LANGUAGE plpgsql OWNER TO @extowner@;\n\nCOMMENT ON LANGUAGE plpgsql IS 'PL/pgSQL procedural language';", "title": "Installation definition from the matching source archive", "paragraphs": ["This extension is shipped with the source. Its presence does not establish that the language or external runtime is installed."]}], "signature": "", "attributes": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "comment": "PL/pgSQL procedural language", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0", "module_pathname": "$libdir/plpgsql"}, "description": ["PL/pgSQL procedural language"], "manual_html": "<div class=\"sect1\" id=\"PLPGSQL-OVERVIEW\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h2 class=\"title\">41.1.\u00a0Overview </h2>\n</div>\n</div>\n</div>\n\n<p><span class=\"application\">PL/pgSQL</span> is a loadable procedural language for the <span class=\"productname\">PostgreSQL</span> database system. The design goals of <span class=\"application\">PL/pgSQL</span> were to create a loadable procedural language that</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>can be used to create functions, procedures, and triggers,</p>\n</li>\n<li class=\"listitem\">\n<p>adds control structures to the SQL language,</p>\n</li>\n<li class=\"listitem\">\n<p>can perform complex computations,</p>\n</li>\n<li class=\"listitem\">\n<p>inherits all user-defined types, functions, procedures, and operators,</p>\n</li>\n<li class=\"listitem\">\n<p>can be defined to be trusted by the server,</p>\n</li>\n<li class=\"listitem\">\n<p>is easy to use.</p>\n</li>\n</ul>\n</div>\n<p>Functions created with <span class=\"application\">PL/pgSQL</span> can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.</p>\n<p>In <span class=\"productname\">PostgreSQL</span> 9.0 and later, <span class=\"application\">PL/pgSQL</span> is installed by default. However it is still a loadable module, so especially security-conscious administrators could choose to remove it.</p>\n<div class=\"sect2\" id=\"PLPGSQL-ADVANTAGES\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">41.1.1.\u00a0Advantages of Using <span class=\"application\">PL/pgSQL</span> </h3>\n</div>\n</div>\n</div>\n<p>SQL is the language <span class=\"productname\">PostgreSQL</span> and most other relational databases use as query language. It's portable and easy to learn. But every SQL statement must be executed individually by the database server.</p>\n<p>That means that your client application must send each query to the database server, wait for it to be processed, receive and process the results, do some computation, then send further queries to the server. All this incurs interprocess communication and will also incur network overhead if your client is on a different machine than the database server.</p>\n<p>With <span class=\"application\">PL/pgSQL</span> you can group a block of computation and a series of queries <span class=\"emphasis\"><em>inside</em></span> the database server, thus having the power of a procedural language and the ease of use of SQL, but with considerable savings of client/server communication overhead.</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>Extra round trips between client and server are eliminated</p>\n</li>\n<li class=\"listitem\">\n<p>Intermediate results that the client does not need do not have to be marshaled or transferred between server and client</p>\n</li>\n<li class=\"listitem\">\n<p>Multiple rounds of query parsing can be avoided</p>\n</li>\n</ul>\n</div>\n<p>This can result in a considerable performance increase as compared to an application that does not use stored functions.</p>\n<p>Also, with <span class=\"application\">PL/pgSQL</span> you can use all the data types, operators and functions of SQL.</p>\n</div>\n<div class=\"sect2\" id=\"PLPGSQL-ARGS-RESULTS\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">41.1.2.\u00a0Supported Argument and Result Data Types </h3>\n</div>\n</div>\n</div>\n<p>Functions written in <span class=\"application\">PL/pgSQL</span> can accept as arguments any scalar or array data type supported by the server, and they can return a result of any of these types. They can also accept or return any composite type (row type) specified by name. It is also possible to declare a <span class=\"application\">PL/pgSQL</span> function as accepting <code class=\"type\">record</code>, which means that any composite type will do as input, or as returning <code class=\"type\">record</code>, which means that the result is a row type whose columns are determined by specification in the calling query, as discussed in <a class=\"xref\" href=\"/docs/19/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS\" title=\"7.2.1.4.\u00a0Table Functions\">Section\u00a07.2.1.4</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can be declared to accept a variable number of arguments by using the <code class=\"literal\">VARIADIC</code> marker. This works exactly the same way as for SQL functions, as discussed in <a class=\"xref\" href=\"/docs/19/xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS\" title=\"36.5.6.\u00a0SQL Functions with Variable Numbers of Arguments\">Section\u00a036.5.6</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to accept and return the polymorphic types described in <a class=\"xref\" href=\"/docs/19/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"36.2.5.\u00a0Polymorphic Types\">Section\u00a036.2.5</a>, thus allowing the actual data types handled by the function to vary from call to call. Examples appear in <a class=\"xref\" href=\"/docs/19/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"41.3.1.\u00a0Declaring Function Parameters\">Section\u00a041.3.1</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to return a <span class=\"quote\">\u201c<span class=\"quote\">set</span>\u201d</span> (or table) of any data type that can be returned as a single instance. Such a function generates its output by executing <code class=\"command\">RETURN NEXT</code> for each desired element of the result set, or by using <code class=\"command\">RETURN QUERY</code> to output the result of evaluating a query.</p>\n<p>Finally, a <span class=\"application\">PL/pgSQL</span> function can be declared to return <code class=\"type\">void</code> if it has no useful return value. (Alternatively, it could be written as a procedure in that case.)</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared with output parameters in place of an explicit specification of the return type. This does not add any fundamental capability to the language, but it is often convenient, especially for returning multiple values. The <code class=\"literal\">RETURNS TABLE</code> notation can also be used in place of <code class=\"literal\">RETURNS SETOF</code>.</p>\n<p>Specific examples appear in <a class=\"xref\" href=\"/docs/19/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"41.3.1.\u00a0Declaring Function Parameters\">Section\u00a041.3.1</a> and <a class=\"xref\" href=\"/docs/19/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING\" title=\"41.6.1.\u00a0Returning from a Function\">Section\u00a041.6.1</a>.</p>\n</div>\n</div>", "manual_path": "/docs/19/plpgsql-overview.html", "source_files": {"src/pl/plpgsql/src/plpgsql.control": "9457c3f51d6bdfab93f13080d177795a9274c025e378fb613218342e3a3c7b45", "src/pl/plpgsql/src/plpgsql--1.0.sql": "f4e7e05438808ac0da0b3801397d16e36102969af7e2ffc982def5b7524fb557"}, "comparison_data": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0"}, "comparison_hash": "e85051f39a242ce658cedd87ac97437817f0f1b2baf992d8d37c9d29df8b558b"}, "20": {"facts": [{"label": "Kind", "value": "Bundled procedural-language variant"}, {"label": "Family", "value": "PL/pgSQL"}, {"label": "Trusted", "value": "t"}, {"label": "Handler", "value": "plpgsql_call_handler"}, {"label": "Inline handler", "value": "plpgsql_inline_handler"}, {"label": "Validator", "value": "plpgsql_validator"}, {"label": "Library", "value": "$libdir/plpgsql"}, {"label": "Default version", "value": "1.0"}, {"label": "Module pathname", "value": "$libdir/plpgsql"}, {"label": "Comment", "value": "PL/pgSQL procedural language"}], "tables": [], "aliases": [], "related": [{"url": "/docs/devel/plpgsql-control-structures.html", "label": "plpgsql-control-structures"}, {"url": "/docs/devel/plpgsql-cursors.html", "label": "plpgsql-cursors"}, {"url": "/docs/devel/plpgsql-declarations.html", "label": "plpgsql-declarations"}, {"url": "/docs/devel/plpgsql-development-tips.html", "label": "plpgsql-development-tips"}, {"url": "/docs/devel/plpgsql-errors-and-messages.html", "label": "plpgsql-errors-and-messages"}, {"url": "/docs/devel/plpgsql-expressions.html", "label": "plpgsql-expressions"}, {"url": "/docs/devel/plpgsql-implementation.html", "label": "plpgsql-implementation"}, {"url": "/docs/devel/plpgsql-overview.html", "label": "plpgsql-overview"}, {"url": "/docs/devel/plpgsql-porting.html", "label": "plpgsql-porting"}, {"url": "/docs/devel/plpgsql-statements.html", "label": "plpgsql-statements"}, {"url": "/docs/devel/plpgsql-structure.html", "label": "plpgsql-structure"}, {"url": "/docs/devel/plpgsql-transactions.html", "label": "plpgsql-transactions"}, {"url": "/docs/devel/plpgsql-trigger.html", "label": "plpgsql-trigger"}], "release": {"ref": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "label": "20devel", "major": "20", "channel": "devel", "revision": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41", "source_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41", "catalog_fingerprint": "398fbb9f262264053c02fbf79f88be0a6770c1473faa6ecd5931d6ec41b8258b", "source_snapshot_utc": "26-Sep-2026 20:22"}, "sources": [{"url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "label": "Matching PostgreSQL source archive", "sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}, {"url": "/docs/devel/plpgsql-overview.html", "path": "plpgsql-overview.html", "label": "PostgreSQL 20 English manual", "sha256": "7202bce9e8548da61529e98ad2a35c20b028f8e1f4a3dc30e1be504c0719da67"}], "sections": [{"code": "/* src/pl/plpgsql/src/plpgsql--1.0.sql */\n\nCREATE FUNCTION plpgsql_call_handler() RETURNS language_handler\n  LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_inline_handler(internal) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_validator(oid) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE TRUSTED LANGUAGE plpgsql\n  HANDLER plpgsql_call_handler\n  INLINE plpgsql_inline_handler\n  VALIDATOR plpgsql_validator;\n\n-- The language object, but not the functions, can be owned by a non-superuser.\nALTER LANGUAGE plpgsql OWNER TO @extowner@;\n\nCOMMENT ON LANGUAGE plpgsql IS 'PL/pgSQL procedural language';", "title": "Installation definition from the matching source archive", "paragraphs": ["This extension is shipped with the source. Its presence does not establish that the language or external runtime is installed."]}], "signature": "", "attributes": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "comment": "PL/pgSQL procedural language", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0", "module_pathname": "$libdir/plpgsql"}, "description": ["PL/pgSQL procedural language"], "manual_html": "<div class=\"sect1\" id=\"PLPGSQL-OVERVIEW\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h2 class=\"title\">41.1.\u00a0Overview </h2>\n</div>\n</div>\n</div>\n\n<p><span class=\"application\">PL/pgSQL</span> is a loadable procedural language for the <span class=\"productname\">PostgreSQL</span> database system. The design goals of <span class=\"application\">PL/pgSQL</span> were to create a loadable procedural language that</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>can be used to create functions, procedures, and triggers,</p>\n</li>\n<li class=\"listitem\">\n<p>adds control structures to the SQL language,</p>\n</li>\n<li class=\"listitem\">\n<p>can perform complex computations,</p>\n</li>\n<li class=\"listitem\">\n<p>inherits all user-defined types, functions, procedures, and operators,</p>\n</li>\n<li class=\"listitem\">\n<p>can be defined to be trusted by the server,</p>\n</li>\n<li class=\"listitem\">\n<p>is easy to use.</p>\n</li>\n</ul>\n</div>\n<p>Functions created with <span class=\"application\">PL/pgSQL</span> can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.</p>\n<p>In <span class=\"productname\">PostgreSQL</span> 9.0 and later, <span class=\"application\">PL/pgSQL</span> is installed by default. However it is still a loadable module, so especially security-conscious administrators could choose to remove it.</p>\n<div class=\"sect2\" id=\"PLPGSQL-ADVANTAGES\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">41.1.1.\u00a0Advantages of Using <span class=\"application\">PL/pgSQL</span> </h3>\n</div>\n</div>\n</div>\n<p>SQL is the language <span class=\"productname\">PostgreSQL</span> and most other relational databases use as query language. It's portable and easy to learn. But every SQL statement must be executed individually by the database server.</p>\n<p>That means that your client application must send each query to the database server, wait for it to be processed, receive and process the results, do some computation, then send further queries to the server. All this incurs interprocess communication and will also incur network overhead if your client is on a different machine than the database server.</p>\n<p>With <span class=\"application\">PL/pgSQL</span> you can group a block of computation and a series of queries <span class=\"emphasis\"><em>inside</em></span> the database server, thus having the power of a procedural language and the ease of use of SQL, but with considerable savings of client/server communication overhead.</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>Extra round trips between client and server are eliminated</p>\n</li>\n<li class=\"listitem\">\n<p>Intermediate results that the client does not need do not have to be marshaled or transferred between server and client</p>\n</li>\n<li class=\"listitem\">\n<p>Multiple rounds of query parsing can be avoided</p>\n</li>\n</ul>\n</div>\n<p>This can result in a considerable performance increase as compared to an application that does not use stored functions.</p>\n<p>Also, with <span class=\"application\">PL/pgSQL</span> you can use all the data types, operators and functions of SQL.</p>\n</div>\n<div class=\"sect2\" id=\"PLPGSQL-ARGS-RESULTS\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">41.1.2.\u00a0Supported Argument and Result Data Types </h3>\n</div>\n</div>\n</div>\n<p>Functions written in <span class=\"application\">PL/pgSQL</span> can accept as arguments any scalar or array data type supported by the server, and they can return a result of any of these types. They can also accept or return any composite type (row type) specified by name. It is also possible to declare a <span class=\"application\">PL/pgSQL</span> function as accepting <code class=\"type\">record</code>, which means that any composite type will do as input, or as returning <code class=\"type\">record</code>, which means that the result is a row type whose columns are determined by specification in the calling query, as discussed in <a class=\"xref\" href=\"/docs/devel/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS\" title=\"7.2.1.4.\u00a0Table Functions\">Section\u00a07.2.1.4</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can be declared to accept a variable number of arguments by using the <code class=\"literal\">VARIADIC</code> marker. This works exactly the same way as for SQL functions, as discussed in <a class=\"xref\" href=\"/docs/devel/xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS\" title=\"36.5.6.\u00a0SQL Functions with Variable Numbers of Arguments\">Section\u00a036.5.6</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to accept and return the polymorphic types described in <a class=\"xref\" href=\"/docs/devel/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"36.2.5.\u00a0Polymorphic Types\">Section\u00a036.2.5</a>, thus allowing the actual data types handled by the function to vary from call to call. Examples appear in <a class=\"xref\" href=\"/docs/devel/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"41.3.1.\u00a0Declaring Function Parameters\">Section\u00a041.3.1</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to return a <span class=\"quote\">\u201c<span class=\"quote\">set</span>\u201d</span> (or table) of any data type that can be returned as a single instance. Such a function generates its output by executing <code class=\"command\">RETURN NEXT</code> for each desired element of the result set, or by using <code class=\"command\">RETURN QUERY</code> to output the result of evaluating a query.</p>\n<p>Finally, a <span class=\"application\">PL/pgSQL</span> function can be declared to return <code class=\"type\">void</code> if it has no useful return value. (Alternatively, it could be written as a procedure in that case.)</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared with output parameters in place of an explicit specification of the return type. This does not add any fundamental capability to the language, but it is often convenient, especially for returning multiple values. The <code class=\"literal\">RETURNS TABLE</code> notation can also be used in place of <code class=\"literal\">RETURNS SETOF</code>.</p>\n<p>Specific examples appear in <a class=\"xref\" href=\"/docs/devel/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"41.3.1.\u00a0Declaring Function Parameters\">Section\u00a041.3.1</a> and <a class=\"xref\" href=\"/docs/devel/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING\" title=\"41.6.1.\u00a0Returning from a Function\">Section\u00a041.6.1</a>.</p>\n</div>\n</div>", "manual_path": "/docs/devel/plpgsql-overview.html", "source_files": {"src/pl/plpgsql/src/plpgsql.control": "9457c3f51d6bdfab93f13080d177795a9274c025e378fb613218342e3a3c7b45", "src/pl/plpgsql/src/plpgsql--1.0.sql": "f4e7e05438808ac0da0b3801397d16e36102969af7e2ffc982def5b7524fb557"}, "comparison_data": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0"}, "comparison_hash": "e85051f39a242ce658cedd87ac97437817f0f1b2baf992d8d37c9d29df8b558b"}}}, "snapshot": {"facts": [{"label": "Kind", "value": "Bundled procedural-language variant"}, {"label": "Family", "value": "PL/pgSQL"}, {"label": "Trusted", "value": "t"}, {"label": "Handler", "value": "plpgsql_call_handler"}, {"label": "Inline handler", "value": "plpgsql_inline_handler"}, {"label": "Validator", "value": "plpgsql_validator"}, {"label": "Library", "value": "$libdir/plpgsql"}, {"label": "Default version", "value": "1.0"}, {"label": "Module pathname", "value": "$libdir/plpgsql"}, {"label": "Comment", "value": "PL/pgSQL procedural language"}], "tables": [], "aliases": [], "related": [{"url": "/docs/18/plpgsql-control-structures.html", "label": "plpgsql-control-structures"}, {"url": "/docs/18/plpgsql-cursors.html", "label": "plpgsql-cursors"}, {"url": "/docs/18/plpgsql-declarations.html", "label": "plpgsql-declarations"}, {"url": "/docs/18/plpgsql-development-tips.html", "label": "plpgsql-development-tips"}, {"url": "/docs/18/plpgsql-errors-and-messages.html", "label": "plpgsql-errors-and-messages"}, {"url": "/docs/18/plpgsql-expressions.html", "label": "plpgsql-expressions"}, {"url": "/docs/18/plpgsql-implementation.html", "label": "plpgsql-implementation"}, {"url": "/docs/18/plpgsql-overview.html", "label": "plpgsql-overview"}, {"url": "/docs/18/plpgsql-porting.html", "label": "plpgsql-porting"}, {"url": "/docs/18/plpgsql-statements.html", "label": "plpgsql-statements"}, {"url": "/docs/18/plpgsql-structure.html", "label": "plpgsql-structure"}, {"url": "/docs/18/plpgsql-transactions.html", "label": "plpgsql-transactions"}, {"url": "/docs/18/plpgsql-trigger.html", "label": "plpgsql-trigger"}], "release": {"ref": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "label": "18.6", "major": "18", "channel": "stable", "revision": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f", "source_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f", "catalog_fingerprint": "65c93d6048ef30e61023a84f9680fa6a92b1c383b7eb226741170077eb078502"}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "label": "Matching PostgreSQL source archive", "sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "/docs/18/plpgsql-overview.html", "path": "plpgsql-overview.html", "label": "PostgreSQL 18 English manual", "sha256": "7f93dfdf27c74b24d0bd355e845c7a6ff142aa9479bdcd0f203e8d37f36a3dfc"}], "sections": [{"code": "/* src/pl/plpgsql/src/plpgsql--1.0.sql */\n\nCREATE FUNCTION plpgsql_call_handler() RETURNS language_handler\n  LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_inline_handler(internal) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE FUNCTION plpgsql_validator(oid) RETURNS void\n  STRICT LANGUAGE c AS 'MODULE_PATHNAME';\n\nCREATE TRUSTED LANGUAGE plpgsql\n  HANDLER plpgsql_call_handler\n  INLINE plpgsql_inline_handler\n  VALIDATOR plpgsql_validator;\n\n-- The language object, but not the functions, can be owned by a non-superuser.\nALTER LANGUAGE plpgsql OWNER TO @extowner@;\n\nCOMMENT ON LANGUAGE plpgsql IS 'PL/pgSQL procedural language';", "title": "Installation definition from the matching source archive", "paragraphs": ["This extension is shipped with the source. Its presence does not establish that the language or external runtime is installed."]}], "signature": "", "attributes": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "comment": "PL/pgSQL procedural language", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0", "module_pathname": "$libdir/plpgsql"}, "description": ["PL/pgSQL procedural language"], "manual_html": "<div class=\"sect1\" id=\"PLPGSQL-OVERVIEW\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h2 class=\"title\">41.1.\u00a0Overview </h2>\n</div>\n</div>\n</div>\n\n<p><span class=\"application\">PL/pgSQL</span> is a loadable procedural language for the <span class=\"productname\">PostgreSQL</span> database system. The design goals of <span class=\"application\">PL/pgSQL</span> were to create a loadable procedural language that</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>can be used to create functions, procedures, and triggers,</p>\n</li>\n<li class=\"listitem\">\n<p>adds control structures to the SQL language,</p>\n</li>\n<li class=\"listitem\">\n<p>can perform complex computations,</p>\n</li>\n<li class=\"listitem\">\n<p>inherits all user-defined types, functions, procedures, and operators,</p>\n</li>\n<li class=\"listitem\">\n<p>can be defined to be trusted by the server,</p>\n</li>\n<li class=\"listitem\">\n<p>is easy to use.</p>\n</li>\n</ul>\n</div>\n<p>Functions created with <span class=\"application\">PL/pgSQL</span> can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.</p>\n<p>In <span class=\"productname\">PostgreSQL</span> 9.0 and later, <span class=\"application\">PL/pgSQL</span> is installed by default. However it is still a loadable module, so especially security-conscious administrators could choose to remove it.</p>\n<div class=\"sect2\" id=\"PLPGSQL-ADVANTAGES\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">41.1.1.\u00a0Advantages of Using <span class=\"application\">PL/pgSQL</span> </h3>\n</div>\n</div>\n</div>\n<p>SQL is the language <span class=\"productname\">PostgreSQL</span> and most other relational databases use as query language. It's portable and easy to learn. But every SQL statement must be executed individually by the database server.</p>\n<p>That means that your client application must send each query to the database server, wait for it to be processed, receive and process the results, do some computation, then send further queries to the server. All this incurs interprocess communication and will also incur network overhead if your client is on a different machine than the database server.</p>\n<p>With <span class=\"application\">PL/pgSQL</span> you can group a block of computation and a series of queries <span class=\"emphasis\"><em>inside</em></span> the database server, thus having the power of a procedural language and the ease of use of SQL, but with considerable savings of client/server communication overhead.</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist\">\n<li class=\"listitem\">\n<p>Extra round trips between client and server are eliminated</p>\n</li>\n<li class=\"listitem\">\n<p>Intermediate results that the client does not need do not have to be marshaled or transferred between server and client</p>\n</li>\n<li class=\"listitem\">\n<p>Multiple rounds of query parsing can be avoided</p>\n</li>\n</ul>\n</div>\n<p>This can result in a considerable performance increase as compared to an application that does not use stored functions.</p>\n<p>Also, with <span class=\"application\">PL/pgSQL</span> you can use all the data types, operators and functions of SQL.</p>\n</div>\n<div class=\"sect2\" id=\"PLPGSQL-ARGS-RESULTS\">\n<div class=\"titlepage\">\n<div>\n<div>\n<h3 class=\"title\">41.1.2.\u00a0Supported Argument and Result Data Types </h3>\n</div>\n</div>\n</div>\n<p>Functions written in <span class=\"application\">PL/pgSQL</span> can accept as arguments any scalar or array data type supported by the server, and they can return a result of any of these types. They can also accept or return any composite type (row type) specified by name. It is also possible to declare a <span class=\"application\">PL/pgSQL</span> function as accepting <code class=\"type\">record</code>, which means that any composite type will do as input, or as returning <code class=\"type\">record</code>, which means that the result is a row type whose columns are determined by specification in the calling query, as discussed in <a class=\"xref\" href=\"/docs/18/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS\" title=\"7.2.1.4.\u00a0Table Functions\">Section\u00a07.2.1.4</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can be declared to accept a variable number of arguments by using the <code class=\"literal\">VARIADIC</code> marker. This works exactly the same way as for SQL functions, as discussed in <a class=\"xref\" href=\"/docs/18/xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS\" title=\"36.5.6.\u00a0SQL Functions with Variable Numbers of Arguments\">Section\u00a036.5.6</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to accept and return the polymorphic types described in <a class=\"xref\" href=\"/docs/18/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"36.2.5.\u00a0Polymorphic Types\">Section\u00a036.2.5</a>, thus allowing the actual data types handled by the function to vary from call to call. Examples appear in <a class=\"xref\" href=\"/docs/18/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"41.3.1.\u00a0Declaring Function Parameters\">Section\u00a041.3.1</a>.</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared to return a <span class=\"quote\">\u201c<span class=\"quote\">set</span>\u201d</span> (or table) of any data type that can be returned as a single instance. Such a function generates its output by executing <code class=\"command\">RETURN NEXT</code> for each desired element of the result set, or by using <code class=\"command\">RETURN QUERY</code> to output the result of evaluating a query.</p>\n<p>Finally, a <span class=\"application\">PL/pgSQL</span> function can be declared to return <code class=\"type\">void</code> if it has no useful return value. (Alternatively, it could be written as a procedure in that case.)</p>\n<p><span class=\"application\">PL/pgSQL</span> functions can also be declared with output parameters in place of an explicit specification of the return type. This does not add any fundamental capability to the language, but it is often convenient, especially for returning multiple values. The <code class=\"literal\">RETURNS TABLE</code> notation can also be used in place of <code class=\"literal\">RETURNS SETOF</code>.</p>\n<p>Specific examples appear in <a class=\"xref\" href=\"/docs/18/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS\" title=\"41.3.1.\u00a0Declaring Function Parameters\">Section\u00a041.3.1</a> and <a class=\"xref\" href=\"/docs/18/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING\" title=\"41.6.1.\u00a0Returning from a Function\">Section\u00a041.6.1</a>.</p>\n</div>\n</div>", "manual_path": "/docs/18/plpgsql-overview.html", "source_files": {"src/pl/plpgsql/src/plpgsql.control": "9457c3f51d6bdfab93f13080d177795a9274c025e378fb613218342e3a3c7b45", "src/pl/plpgsql/src/plpgsql--1.0.sql": "f4e7e05438808ac0da0b3801397d16e36102969af7e2ffc982def5b7524fb557"}, "comparison_data": {"kind": "Bundled procedural-language variant", "family": "PL/pgSQL", "handler": "plpgsql_call_handler", "library": "$libdir/plpgsql", "trusted": "t", "validator": "plpgsql_validator", "inline_handler": "plpgsql_inline_handler", "default_version": "1.0"}, "comparison_hash": "e85051f39a242ce658cedd87ac97437817f0f1b2baf992d8d37c9d29df8b558b"}, "comparison": {"left": "17", "right": "18", "status": "unchanged", "diff": ""}}