<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Shinya Kato</title>
    <description>The latest articles on DEV Community by Shinya Kato (@shinyakato_).</description>
    <link>https://dev.to/shinyakato_</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2629632%2F89894444-31f0-4783-86e2-7d722f7c8286.png</url>
      <title>DEV Community: Shinya Kato</title>
      <link>https://dev.to/shinyakato_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shinyakato_"/>
    <language>en</language>
    <item>
      <title>Reducing row count estimation errors in PostgreSQL</title>
      <dc:creator>Shinya Kato</dc:creator>
      <pubDate>Fri, 06 Feb 2026 05:41:10 +0000</pubDate>
      <link>https://dev.to/shinyakato_/reducing-row-count-estimation-errors-in-postgresql-54ok</link>
      <guid>https://dev.to/shinyakato_/reducing-row-count-estimation-errors-in-postgresql-54ok</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;PostgreSQL's query planner relies on table statistics to estimate the number of rows (estimated rows) each operation will process, and then selects an optimal execution plan based on these estimates. When the estimated rows diverge significantly from the actual rows, the planner can choose a suboptimal plan, leading to severe query performance degradation.&lt;/p&gt;

&lt;p&gt;This article walks through four approaches I used to reduce row count estimation errors, ordered from least to most invasive. Due to confidentiality constraints, I cannot share actual SQL or execution plans, so the focus is on the diagnostic thought process and the techniques applied.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The approaches in this article are applicable to any modern PostgreSQL version, as the underlying mechanisms (autovacuum, &lt;code&gt;pg_statistic&lt;/code&gt;, extended statistics) have been stable across versions&lt;/li&gt;
&lt;li&gt;The target table had a high update frequency&lt;/li&gt;
&lt;li&gt;Actual SQL and execution plans cannot be shared; this article focuses on methodology&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Approach 1: Tuning autovacuum auto-ANALYZE frequency per table
&lt;/h2&gt;

&lt;p&gt;The target table was known to have a very high update rate, so the first hypothesis was that the statistics were simply stale.&lt;/p&gt;

&lt;p&gt;In PostgreSQL, the autovacuum daemon automatically runs &lt;code&gt;ANALYZE&lt;/code&gt; to update statistics stored in &lt;code&gt;pg_statistic&lt;/code&gt;. However, for tables with heavy write activity, auto-&lt;code&gt;ANALYZE&lt;/code&gt; may not keep up with the rate of change, causing the statistics to drift from reality.&lt;/p&gt;

&lt;p&gt;To address this, I adjusted the auto-&lt;code&gt;ANALYZE&lt;/code&gt; frequency for the specific table rather than changing the server-wide settings in &lt;code&gt;postgresql.conf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The two key parameters are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;autovacuum_analyze_threshold&lt;/code&gt;: The minimum number of tuple modifications before auto-&lt;code&gt;ANALYZE&lt;/code&gt; is triggered (default: 50)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;autovacuum_analyze_scale_factor&lt;/code&gt;: The fraction of the table size added to the threshold (default: 0.1, i.e., 10%)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;autovacuum_analyze_threshold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;autovacuum_analyze_scale_factor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;autovacuum_analyze_threshold&lt;/code&gt; is set to 0 (default: 50) and &lt;code&gt;autovacuum_analyze_scale_factor&lt;/code&gt; is reduced from 0.1 to 0.01, so that auto-&lt;code&gt;ANALYZE&lt;/code&gt; triggers after just 1% of the table has been modified.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can verify whether auto-&lt;code&gt;ANALYZE&lt;/code&gt; is keeping up by querying the &lt;code&gt;pg_stat_user_tables&lt;/code&gt; view. Check the &lt;code&gt;last_autoanalyze&lt;/code&gt; column for the timestamp of the last auto-&lt;code&gt;ANALYZE&lt;/code&gt;, and &lt;code&gt;n_mod_since_analyze&lt;/code&gt; for the number of row modifications since the last &lt;code&gt;ANALYZE&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For the full list of per-table storage parameters, see the &lt;a href="https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS" rel="noopener noreferrer"&gt;PostgreSQL documentation on storage parameters&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approach 2: Increasing the statistics sampling target per column
&lt;/h2&gt;

&lt;p&gt;After adjusting autovacuum frequency, the next hypothesis was that &lt;code&gt;ANALYZE&lt;/code&gt; was running often enough but the sample size was too small to produce accurate statistics.&lt;/p&gt;

&lt;p&gt;PostgreSQL's &lt;code&gt;ANALYZE&lt;/code&gt; collects samples from each column and stores most-common values (MCVs) and histograms in &lt;code&gt;pg_statistic&lt;/code&gt;. The precision of this information is governed by &lt;code&gt;default_statistics_target&lt;/code&gt; (default: 100), which controls the number of histogram buckets and MCV entries.&lt;/p&gt;

&lt;p&gt;Rather than changing the server-wide setting, I increased the statistics target on a per-column basis for the affected table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt; &lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="k"&gt;column_name&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="k"&gt;STATISTICS&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a general guideline, setting the target to 500-1000 for columns frequently used in &lt;code&gt;WHERE&lt;/code&gt; clauses is a common tuning step. However, higher values increase &lt;code&gt;ANALYZE&lt;/code&gt; execution time and the size of &lt;code&gt;pg_statistic&lt;/code&gt;, so there is a trade-off to consider.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; After changing the statistics target with &lt;code&gt;SET STATISTICS&lt;/code&gt;, you must run &lt;code&gt;ANALYZE&lt;/code&gt; (or wait for the next auto-&lt;code&gt;ANALYZE&lt;/code&gt;) for the new setting to take effect.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Approach 3: Using extended statistics
&lt;/h2&gt;

&lt;p&gt;Even after improving the freshness and precision of the base statistics, row count estimation errors can persist. This happens when the planner's estimation model itself has structural limitations.&lt;/p&gt;

&lt;p&gt;By default, PostgreSQL's planner assumes that conditions on different columns are independent. When this assumption is violated, the planner multiplies selectivities independently, often resulting in a dramatic underestimation of the actual row count.&lt;/p&gt;

&lt;p&gt;This occurs when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A table has two columns &lt;code&gt;a1&lt;/code&gt; and &lt;code&gt;a2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;There is a functional dependency between them (e.g., &lt;code&gt;a1&lt;/code&gt; determines &lt;code&gt;a2&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;WHERE&lt;/code&gt; clause includes conditions on both columns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A concrete example would be columns like &lt;code&gt;country&lt;/code&gt; and &lt;code&gt;city&lt;/code&gt; -- knowing the country largely determines the set of possible cities. The planner treats the selectivities of each condition as independent, producing an estimate far lower than the actual row count.&lt;/p&gt;

&lt;p&gt;To address this, I created extended statistics on the correlated columns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;STATISTICS&lt;/span&gt; &lt;span class="n"&gt;stat_name&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;a1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a2&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;CREATE STATISTICS&lt;/code&gt; supports three kinds of statistics: &lt;code&gt;ndistinct&lt;/code&gt; (multi-column distinct counts), &lt;code&gt;dependencies&lt;/code&gt; (functional dependencies), and &lt;code&gt;mcv&lt;/code&gt; (multi-column most-common values). If you omit the kind specification, all three are collected, which is what I did as a starting point.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;CREATE STATISTICS&lt;/code&gt; only defines the statistics object. The actual statistics are not populated until &lt;code&gt;ANALYZE&lt;/code&gt; runs on the table.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For more details, see the &lt;a href="https://www.postgresql.org/docs/current/sql-createstatistics.html" rel="noopener noreferrer"&gt;PostgreSQL documentation on CREATE STATISTICS&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approach 4: Using pg_hint_plan as a last resort
&lt;/h2&gt;

&lt;p&gt;When statistics-based approaches are not sufficient, &lt;a href="https://github.com/ossc-db/pg_hint_plan" rel="noopener noreferrer"&gt;pg_hint_plan&lt;/a&gt; provides a way to directly control the planner's behavior through SQL comment-based hints.&lt;/p&gt;

&lt;p&gt;For row count estimation issues specifically, the &lt;code&gt;Rows&lt;/code&gt; hint allows you to override the planner's row estimate for a given table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*+ Rows(table_name #1000) */&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, the estimated row count for &lt;code&gt;table_name&lt;/code&gt; is fixed at 1000. You can also use &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, or &lt;code&gt;*&lt;/code&gt; instead of &lt;code&gt;#&lt;/code&gt; to add, subtract, or multiply the planner's original estimate.&lt;/p&gt;

&lt;p&gt;However, hint-based approaches come with significant drawbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fragile to data changes&lt;/strong&gt;: Fixed row counts become inaccurate as data volumes change&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced maintainability&lt;/strong&gt;: Team members unfamiliar with the hints may be confused by them&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Masks root causes&lt;/strong&gt;: Hints can hide underlying statistics or schema issues that should be properly addressed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For these reasons, I recommend using hints only when statistics-based approaches have been exhausted, or as a temporary measure while investigating the root cause.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This article covered four approaches to reducing row count estimation errors in PostgreSQL, ordered by increasing invasiveness:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tune autovacuum frequency&lt;/strong&gt;: Are the statistics stale?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Increase the statistics target&lt;/strong&gt;: Is the sample size sufficient?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create extended statistics&lt;/strong&gt;: Can the planner account for cross-column correlations?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apply hint clauses&lt;/strong&gt;: A last resort when statistics alone cannot solve the problem&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When facing row estimation errors, a systematic approach works best: start with &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt; to compare estimated vs. actual row counts, then work through the possible causes in order -- &lt;strong&gt;statistics freshness, then precision, then structural limitations of the estimation model&lt;/strong&gt;. I hope this article serves as a useful reference in your troubleshooting process.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS" rel="noopener noreferrer"&gt;PostgreSQL documentation: table storage parameters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.postgresql.org/docs/current/sql-createstatistics.html" rel="noopener noreferrer"&gt;PostgreSQL documentation: CREATE STATISTICS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ossc-db/pg_hint_plan" rel="noopener noreferrer"&gt;pg_hint_plan (GitHub)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>postgres</category>
    </item>
    <item>
      <title>4 causes of table bloat in PostgreSQL and how to address them</title>
      <dc:creator>Shinya Kato</dc:creator>
      <pubDate>Tue, 20 Jan 2026 08:55:13 +0000</pubDate>
      <link>https://dev.to/shinyakato_/4-causes-of-table-bloat-in-postgresql-and-how-to-address-them-3ec9</link>
      <guid>https://dev.to/shinyakato_/4-causes-of-table-bloat-in-postgresql-and-how-to-address-them-3ec9</guid>
      <description>&lt;h2&gt;
  
  
  What Is Table Bloat?
&lt;/h2&gt;

&lt;p&gt;Table bloat in PostgreSQL refers to the phenomenon where "dead tuples" generated by UPDATE or DELETE operations remain uncollected by VACUUM, causing data files to grow unnecessarily large.&lt;/p&gt;

&lt;p&gt;For VACUUM to reclaim dead tuples, it must be guaranteed that those tuples "cannot possibly be referenced by any currently running transaction." If old transactions persist for any reason, VACUUM's garbage collection stops at that point.&lt;/p&gt;

&lt;p&gt;This article explains the following four causes of table bloat: how each manifests, how to identify the root cause, and how to resolve it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Long-running transactions&lt;/li&gt;
&lt;li&gt;Uncommitted prepared transactions&lt;/li&gt;
&lt;li&gt;Queries on standby servers with &lt;code&gt;hot_standby_feedback&lt;/code&gt; enabled&lt;/li&gt;
&lt;li&gt;Logical replication lag&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Test Environment
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL 19dev (&lt;code&gt;34740b90bc123d645a3a71231b765b778bdcf049&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Long-Running Transactions
&lt;/h2&gt;

&lt;p&gt;This is probably the most familiar cause. Whether active or idle, a long-running transaction prevents VACUUM from reclaiming dead tuples generated by UPDATE or DELETE operations that occurred after the transaction started. This is because the long-running transaction might need to read the pre-update versions of those tuples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;In Terminal 1, start a transaction and obtain a transaction ID.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Terminal 1:
=# BEGIN;
BEGIN
=*# SELECT txid_current();
 txid_current
--------------
          782
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a separate Terminal 2, delete data and run VACUUM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Terminal 2:
=# DELETE FROM t;
DELETE 100
=# VACUUM (VERBOSE) t;
INFO:  00000: vacuuming "postgres.public.t"
LOCATION:  heap_vacuum_rel, vacuumlazy.c:848
INFO:  00000: finished vacuuming "postgres.public.t": index scans: 0
pages: 0 removed, 1 remain, 1 scanned (100.00% of total), 0 eagerly scanned
tuples: 0 removed, 100 remain, 100 are dead but not yet removable
removable cutoff: 782, which was 2 XIDs old when operation ended
frozen: 0 pages from table (0.00% of total) had 0 tuples frozen
visibility map: 0 pages set all-visible, 0 pages set all-frozen (0 were all-visible)
index scan not needed: 0 pages from table (0.00% of total) had 0 dead item identifiers removed
avg read rate: 0.000 MB/s, avg write rate: 0.000 MB/s
buffer usage: 15 hits, 0 reads, 0 dirtied
WAL usage: 0 records, 0 full page images, 0 bytes, 0 full page image bytes, 0 buffers full
memory usage: dead item storage 0.02 MB accumulated across 0 resets (limit 64.00 MB each)
system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
LOCATION:  heap_vacuum_rel, vacuumlazy.c:1199
VACUUM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The message &lt;code&gt;tuples: 0 removed, 100 remain, 100 are dead but not yet removable&lt;/code&gt; indicates that dead tuples were not reclaimed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identifying the cause
&lt;/h3&gt;

&lt;p&gt;The message &lt;code&gt;removable cutoff: 782, which was 2 XIDs old when operation ended&lt;/code&gt; suggests that transaction ID 782 is the culprit. Check the &lt;code&gt;pg_stat_activity&lt;/code&gt; view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Terminal 2:
=# SELECT * FROM pg_stat_activity WHERE backend_xid = 782;
-[ RECORD 1 ]----+------------------------------
datid            | 5
datname          | postgres
pid              | 94076
leader_pid       | [NULL]
usesysid         | 10
usename          | shinya
application_name | psql
client_addr      | [NULL]
client_hostname  | [NULL]
client_port      | -1
backend_start    | 2026-01-19 13:41:30.049678+09
xact_start       | 2026-01-19 13:54:38.856466+09
query_start      | 2026-01-19 13:54:43.501664+09
state_change     | 2026-01-19 13:54:43.50271+09
wait_event_type  | Client
wait_event       | ClientRead
state            | idle in transaction
backend_xid      | 782
backend_xmin     | [NULL]
query_id         | [NULL]
query            | SELECT txid_current();
backend_type     | client backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend process with PID 94076 is in an "idle in transaction" state, which prevented VACUUM from reclaiming the dead tuples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolution
&lt;/h3&gt;

&lt;p&gt;Terminate the backend process with PID 94076.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Terminal 2:
=# SELECT pg_terminate_backend(94076);
 pg_terminate_backend
----------------------
 t
(1 row)

=# VACUUM (VERBOSE) t;
INFO:  00000: vacuuming "postgres.public.t"
LOCATION:  heap_vacuum_rel, vacuumlazy.c:848
INFO:  00000: table "t": truncated 1 to 0 pages
LOCATION:  lazy_truncate_heap, vacuumlazy.c:3401
INFO:  00000: finished vacuuming "postgres.public.t": index scans: 0
pages: 1 removed, 0 remain, 1 scanned (100.00% of total), 0 eagerly scanned
tuples: 100 removed, 0 remain, 0 are dead but not yet removable
removable cutoff: 792, which was 1 XIDs old when operation ended
new relfrozenxid: 792, which is 3 XIDs ahead of previous value
frozen: 0 pages from table (0.00% of total) had 0 tuples frozen
visibility map: 1 pages set all-visible, 1 pages set all-frozen (0 were all-visible)
index scan not needed: 0 pages from table (0.00% of total) had 0 dead item identifiers removed
avg read rate: 0.000 MB/s, avg write rate: 7.796 MB/s
buffer usage: 20 hits, 0 reads, 6 dirtied
WAL usage: 8 records, 6 full page images, 34103 bytes, 33628 full page image bytes, 0 buffers full
memory usage: dead item storage 0.02 MB accumulated across 0 resets (limit 64.00 MB each)
system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
LOCATION:  heap_vacuum_rel, vacuumlazy.c:1199
VACUUM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The message &lt;code&gt;tuples: 100 removed, 0 remain, 0 are dead but not yet removable&lt;/code&gt; confirms that all dead tuples have been reclaimed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Always verify that it is safe to terminate the backend process before doing so.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Uncommitted Prepared Transactions
&lt;/h2&gt;

&lt;p&gt;This can occur when applications or distributed database middleware use two-phase commit (2PC). Uncommitted prepared transactions persist in the database even after the session is disconnected, preventing VACUUM from reclaiming dead tuples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;To use prepared transactions, set &lt;code&gt;max_prepared_transactions&lt;/code&gt; to 1 or higher and restart PostgreSQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgresql.conf:
max_prepared_transactions = 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start a transaction and prepare it for 2PC.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# BEGIN;
BEGIN
=*# PREPARE TRANSACTION 'foobar';
PREPARE TRANSACTION
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete data and run VACUUM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# DELETE FROM t;
DELETE 100
=# VACUUM (VERBOSE) t;
INFO:  00000: vacuuming "postgres.public.t"
LOCATION:  heap_vacuum_rel, vacuumlazy.c:848
INFO:  00000: finished vacuuming "postgres.public.t": index scans: 0
pages: 0 removed, 1 remain, 1 scanned (100.00% of total), 0 eagerly scanned
tuples: 0 removed, 100 remain, 100 are dead but not yet removable
removable cutoff: 796, which was 2 XIDs old when operation ended
new relfrozenxid: 793, which is 1 XIDs ahead of previous value
frozen: 0 pages from table (0.00% of total) had 0 tuples frozen
visibility map: 0 pages set all-visible, 0 pages set all-frozen (0 were all-visible)
index scan not needed: 0 pages from table (0.00% of total) had 0 dead item identifiers removed
avg read rate: 14.974 MB/s, avg write rate: 14.974 MB/s
buffer usage: 13 hits, 4 reads, 4 dirtied
WAL usage: 4 records, 4 full page images, 25678 bytes, 25412 full page image bytes, 0 buffers full
memory usage: dead item storage 0.02 MB accumulated across 0 resets (limit 64.00 MB each)
system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
LOCATION:  heap_vacuum_rel, vacuumlazy.c:1199
VACUUM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The message &lt;code&gt;tuples: 0 removed, 100 remain, 100 are dead but not yet removable&lt;/code&gt; indicates that dead tuples were not reclaimed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identifying the cause
&lt;/h3&gt;

&lt;p&gt;The message &lt;code&gt;removable cutoff: 796, which was 2 XIDs old when operation ended&lt;/code&gt; suggests that transaction ID 796 is the culprit. Check the &lt;code&gt;pg_prepared_xacts&lt;/code&gt; view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# SELECT * FROM pg_prepared_xacts;
 transaction |  gid   |           prepared            | owner  | database
-------------+--------+-------------------------------+--------+----------
         796 | foobar | 2026-01-19 14:49:30.089288+09 | shinya | postgres
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The prepared transaction with global transaction ID "foobar" prevented VACUUM from reclaiming the dead tuples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolution
&lt;/h3&gt;

&lt;p&gt;Either commit or roll back the prepared transaction with global transaction ID "foobar" using &lt;code&gt;COMMIT PREPARED&lt;/code&gt; or &lt;code&gt;ROLLBACK PREPARED&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# COMMIT PREPARED 'foobar';
COMMIT PREPARED
=# VACUUM (VERBOSE) t;
INFO:  00000: vacuuming "postgres.public.t"
LOCATION:  heap_vacuum_rel, vacuumlazy.c:848
INFO:  00000: table "t": truncated 1 to 0 pages
LOCATION:  lazy_truncate_heap, vacuumlazy.c:3401
INFO:  00000: finished vacuuming "postgres.public.t": index scans: 0
pages: 1 removed, 0 remain, 1 scanned (100.00% of total), 0 eagerly scanned
tuples: 100 removed, 0 remain, 0 are dead but not yet removable
removable cutoff: 798, which was 1 XIDs old when operation ended
new relfrozenxid: 798, which is 5 XIDs ahead of previous value
frozen: 0 pages from table (0.00% of total) had 0 tuples frozen
visibility map: 1 pages set all-visible, 1 pages set all-frozen (0 were all-visible)
index scan not needed: 0 pages from table (0.00% of total) had 0 dead item identifiers removed
avg read rate: 0.000 MB/s, avg write rate: 9.778 MB/s
buffer usage: 20 hits, 0 reads, 6 dirtied
WAL usage: 8 records, 6 full page images, 34103 bytes, 33628 full page image bytes, 0 buffers full
memory usage: dead item storage 0.02 MB accumulated across 0 resets (limit 64.00 MB each)
system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
LOCATION:  heap_vacuum_rel, vacuumlazy.c:1199
VACUUM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The message &lt;code&gt;tuples: 100 removed, 0 remain, 0 are dead but not yet removable&lt;/code&gt; confirms that all dead tuples have been reclaimed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Queries on Standby with &lt;code&gt;hot_standby_feedback&lt;/code&gt; Enabled
&lt;/h2&gt;

&lt;p&gt;In a streaming replication setup with &lt;code&gt;hot_standby_feedback&lt;/code&gt; enabled, queries on the standby server can prevent VACUUM from reclaiming dead tuples on the primary. This is by design: &lt;code&gt;hot_standby_feedback&lt;/code&gt; exists specifically to prevent dead tuple removal by VACUUM and avoid query conflicts on the standby.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;Set up a streaming replication environment, enable &lt;code&gt;hot_standby_feedback&lt;/code&gt; on the standby, and reduce &lt;code&gt;wal_receiver_status_interval&lt;/code&gt; to increase the frequency of feedback from the standby to the primary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgresql.conf:
hot_standby_feedback = on
wal_receiver_status_interval = 1s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the standby, start a transaction and execute a query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Standby:
=# BEGIN;
BEGIN
=*# SELECT pg_sleep(300);
 pg_sleep
----------

(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; We use &lt;code&gt;pg_sleep()&lt;/code&gt; to prevent the snapshot from being released immediately when the query completes. You could also set the transaction isolation level to &lt;code&gt;REPEATABLE READ&lt;/code&gt; to maintain the snapshot within the transaction.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On the primary, delete data and run VACUUM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Primary:
=# DELETE FROM t;
DELETE 100
=# VACUUM (VERBOSE) t;
INFO:  00000: vacuuming "postgres.public.t"
LOCATION:  heap_vacuum_rel, vacuumlazy.c:848
INFO:  00000: finished vacuuming "postgres.public.t": index scans: 0
pages: 0 removed, 1 remain, 1 scanned (100.00% of total), 0 eagerly scanned
tuples: 0 removed, 100 remain, 100 are dead but not yet removable
removable cutoff: 831, which was 1 XIDs old when operation ended
frozen: 0 pages from table (0.00% of total) had 0 tuples frozen
visibility map: 0 pages set all-visible, 0 pages set all-frozen (0 were all-visible)
index scan not needed: 0 pages from table (0.00% of total) had 0 dead item identifiers removed
avg read rate: 0.000 MB/s, avg write rate: 0.000 MB/s
buffer usage: 12 hits, 0 reads, 0 dirtied
WAL usage: 0 records, 0 full page images, 0 bytes, 0 full page image bytes, 0 buffers full
memory usage: dead item storage 0.02 MB accumulated across 0 resets (limit 64.00 MB each)
system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
LOCATION:  heap_vacuum_rel, vacuumlazy.c:1199
VACUUM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The message &lt;code&gt;tuples: 0 removed, 100 remain, 100 are dead but not yet removable&lt;/code&gt; indicates that dead tuples were not reclaimed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identifying the cause
&lt;/h3&gt;

&lt;p&gt;The message &lt;code&gt;removable cutoff: 831, which was 1 XIDs old when operation ended&lt;/code&gt; suggests that transaction ID 831 is the culprit. Check the &lt;code&gt;pg_stat_replication&lt;/code&gt; view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Primary:
=# SELECT * FROM pg_stat_replication WHERE backend_xmin = 831;
-[ RECORD 1 ]----+------------------------------
pid              | 171632
usesysid         | 10
usename          | shinya
application_name | walreceiver
client_addr      | [NULL]
client_hostname  | [NULL]
client_port      | -1
backend_start    | 2026-01-19 16:32:24.33927+09
backend_xmin     | 831
state            | streaming
sent_lsn         | 0/03081178
write_lsn        | 0/03081178
flush_lsn        | 0/03081178
replay_lsn       | 0/03081178
write_lag        | [NULL]
flush_lag        | [NULL]
replay_lag       | [NULL]
sync_priority    | 0
sync_state       | async
reply_time       | 2026-01-19 17:29:08.063083+09
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Transaction ID 831 is being reported via &lt;code&gt;hot_standby_feedback&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, check the &lt;code&gt;pg_stat_activity&lt;/code&gt; view on the standby.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Standby:
=# SELECT * FROM pg_stat_activity WHERE backend_xmin = 831;
-[ RECORD 1 ]----+------------------------------
datid            | 5
datname          | postgres
pid              | 197146
leader_pid       | [NULL]
usesysid         | 10
usename          | shinya
application_name | psql
client_addr      | [NULL]
client_hostname  | [NULL]
client_port      | -1
backend_start    | 2026-01-19 17:25:19.931946+09
xact_start       | 2026-01-19 17:28:33.640921+09
query_start      | 2026-01-19 17:28:36.617061+09
state_change     | 2026-01-19 17:28:36.617067+09
wait_event_type  | Timeout
wait_event       | PgSleep
state            | active
backend_xid      | [NULL]
backend_xmin     | 831
query_id         | [NULL]
query            | SELECT pg_sleep(300);
backend_type     | client backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The query &lt;code&gt;SELECT pg_sleep(300)&lt;/code&gt; running on the standby backend process with PID 197146 is the cause.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolution
&lt;/h3&gt;

&lt;p&gt;Cancel the query running on the standby backend process (PID 197146).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Standby:
=# SELECT pg_cancel_backend(197146);
 pg_cancel_backend
-------------------
 t
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Primary:
=# VACUUM (VERBOSE) t;
INFO:  00000: vacuuming "postgres.public.t"
LOCATION:  heap_vacuum_rel, vacuumlazy.c:848
INFO:  00000: table "t": truncated 1 to 0 pages
LOCATION:  lazy_truncate_heap, vacuumlazy.c:3401
INFO:  00000: finished vacuuming "postgres.public.t": index scans: 0
pages: 1 removed, 0 remain, 1 scanned (100.00% of total), 0 eagerly scanned
tuples: 100 removed, 0 remain, 0 are dead but not yet removable
removable cutoff: 792, which was 1 XIDs old when operation ended
new relfrozenxid: 792, which is 3 XIDs ahead of previous value
frozen: 0 pages from table (0.00% of total) had 0 tuples frozen
visibility map: 1 pages set all-visible, 1 pages set all-frozen (0 were all-visible)
index scan not needed: 0 pages from table (0.00% of total) had 0 dead item identifiers removed
avg read rate: 0.000 MB/s, avg write rate: 7.796 MB/s
buffer usage: 20 hits, 0 reads, 6 dirtied
WAL usage: 8 records, 6 full page images, 34103 bytes, 33628 full page image bytes, 0 buffers full
memory usage: dead item storage 0.02 MB accumulated across 0 resets (limit 64.00 MB each)
system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
LOCATION:  heap_vacuum_rel, vacuumlazy.c:1199
VACUUM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The message &lt;code&gt;tuples: 100 removed, 0 remain, 0 are dead but not yet removable&lt;/code&gt; confirms that all dead tuples have been reclaimed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logical Replication Lag
&lt;/h2&gt;

&lt;p&gt;Logical replication reads WAL records, decodes them, and sends them to subscribers. A key point is that the decoding process requires the system catalog state as it existed at the "past point in time" when the WAL record was generated.&lt;/p&gt;

&lt;p&gt;For example, when decoding WAL for a table that had a column dropped in the past, the decoder must reference the table definition from "before the column was dropped" rather than the current definition to decode correctly. Therefore, the system catalog dead tuples required for that point in time must be retained until the logical replication slot finishes processing that WAL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;Create a logical replication slot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# SELECT pg_create_logical_replication_slot('test_slot', 'test_decoding');
 pg_create_logical_replication_slot
------------------------------------
 (test_slot,0/017BBC00)
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop an existing table and run VACUUM on the &lt;code&gt;pg_class&lt;/code&gt; catalog.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# DROP TABLE t;
DROP TABLE
=# VACUUM (VERBOSE) pg_class;
INFO:  00000: vacuuming "postgres.pg_catalog.pg_class"
LOCATION:  heap_vacuum_rel, vacuumlazy.c:848
INFO:  00000: finished vacuuming "postgres.pg_catalog.pg_class": index scans: 0
pages: 0 removed, 14 remain, 14 scanned (100.00% of total), 0 eagerly scanned
tuples: 0 removed, 418 remain, 1 are dead but not yet removable
removable cutoff: 780, which was 1 XIDs old when operation ended
new relfrozenxid: 779, which is 19 XIDs ahead of previous value
frozen: 0 pages from table (0.00% of total) had 0 tuples frozen
visibility map: 0 pages set all-visible, 0 pages set all-frozen (0 were all-visible)
index scan not needed: 0 pages from table (0.00% of total) had 0 dead item identifiers removed
avg read rate: 0.000 MB/s, avg write rate: 16.421 MB/s
buffer usage: 45 hits, 0 reads, 4 dirtied
WAL usage: 4 records, 4 full page images, 32658 bytes, 32392 full page image bytes, 0 buffers full
memory usage: dead item storage 0.02 MB accumulated across 0 resets (limit 64.00 MB each)
system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
LOCATION:  heap_vacuum_rel, vacuumlazy.c:1199
VACUUM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The message &lt;code&gt;tuples: 0 removed, 418 remain, 1 are dead but not yet removable&lt;/code&gt; indicates that a dead tuple was not reclaimed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identifying the cause
&lt;/h3&gt;

&lt;p&gt;The message &lt;code&gt;removable cutoff: 780, which was 1 XIDs old when operation ended&lt;/code&gt; suggests that transaction ID 780 is the culprit. Check the &lt;code&gt;pg_replication_slots&lt;/code&gt; view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# SELECT * FROM pg_replication_slots WHERE catalog_xmin = 780;
-[ RECORD 1 ]--------+------------------------------
slot_name            | test_slot
plugin               | test_decoding
slot_type            | logical
datoid               | 5
database             | postgres
temporary            | f
active               | f
active_pid           | [NULL]
xmin                 | [NULL]
catalog_xmin         | 780
restart_lsn          | 0/017BBBC8
confirmed_flush_lsn  | 0/017BBC00
wal_status           | reserved
safe_wal_size        | [NULL]
two_phase            | f
two_phase_at         | [NULL]
inactive_since       | 2026-01-19 20:09:07.152103+09
conflicting          | f
invalidation_reason  | [NULL]
failover             | f
synced               | f
slotsync_skip_reason | [NULL]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This logical replication slot requires transaction ID 780 as its oldest transaction affecting the system catalogs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolution
&lt;/h3&gt;

&lt;p&gt;Since this logical replication slot is not in use, drop it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# SELECT pg_drop_replication_slot('test_slot');
 pg_drop_replication_slot
--------------------------

(1 row)

=# VACUUM (VERBOSE) pg_class;
INFO:  00000: vacuuming "postgres.pg_catalog.pg_class"
LOCATION:  heap_vacuum_rel, vacuumlazy.c:848
INFO:  00000: finished vacuuming "postgres.pg_catalog.pg_class": index scans: 1
pages: 0 removed, 14 remain, 14 scanned (100.00% of total), 0 eagerly scanned
tuples: 1 removed, 417 remain, 0 are dead but not yet removable
removable cutoff: 781, which was 0 XIDs old when operation ended
new relfrozenxid: 781, which is 2 XIDs ahead of previous value
frozen: 0 pages from table (0.00% of total) had 0 tuples frozen
visibility map: 1 pages set all-visible, 1 pages set all-frozen (0 were all-visible)
index scan needed: 1 pages from table (7.14% of total) had 1 dead item identifiers removed
index "pg_class_oid_index": pages: 4 in total, 0 newly deleted, 0 currently deleted, 0 reusable
index "pg_class_relname_nsp_index": pages: 6 in total, 0 newly deleted, 0 currently deleted, 0 reusable
index "pg_class_tblspc_relfilenode_index": pages: 2 in total, 0 newly deleted, 0 currently deleted, 0 reusable
avg read rate: 7.032 MB/s, avg write rate: 63.288 MB/s
buffer usage: 62 hits, 1 reads, 9 dirtied
WAL usage: 9 records, 9 full page images, 55417 bytes, 54864 full page image bytes, 0 buffers full
memory usage: dead item storage 0.03 MB accumulated across 1 reset (limit 64.00 MB each)
system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
LOCATION:  heap_vacuum_rel, vacuumlazy.c:1199
VACUUM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The message &lt;code&gt;tuples: 1 removed, 417 remain, 0 are dead but not yet removable&lt;/code&gt; confirms that all dead tuples have been reclaimed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ongoing Community Discussions
&lt;/h2&gt;

&lt;p&gt;This article has explained the causes and solutions for table bloat.&lt;/p&gt;

&lt;p&gt;Since we intentionally created these situations to demonstrate the solutions, they may not have seemed particularly difficult to handle. However, resolving these issues in practice requires significant PostgreSQL operational knowledge and involves checking multiple system views, which can be quite challenging.&lt;/p&gt;

&lt;p&gt;Furthermore, when table bloat is accompanied by an impending transaction ID wraparound crisis, executing these procedures calmly while avoiding operational errors is stressful, and ideally, we would want to avoid such situations.&lt;/p&gt;

&lt;p&gt;Currently, I am proposing a feature to the PostgreSQL community that would output the reason why dead tuples could not be reclaimed in the VACUUM log. It does not seem close to being committed yet, but once it is, I plan to update this blog post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.postgresql.org/message-id/CAOzEurSgy-gDtwFmEbj5%2BR9PL0_G3qYB6nnzJtNStyuf87VSVg%40mail.gmail.com" rel="noopener noreferrer"&gt;Report oldest xmin source when autovacuum cannot remove tuples&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There have also been past discussions about displaying the reason why dead tuples could not be reclaimed in a system view, but this has not been implemented yet either. I would like to work on this as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.postgresql.org/message-id/CAAaqYe9Dy9sicKg3xzCQUMK3VLdEP39g9nMGZheqtFYfNiO5Bg%40mail.gmail.com" rel="noopener noreferrer"&gt;Proposal: Expose oldest xmin as SQL function for monitoring&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This article explained the causes of table bloat in PostgreSQL and how to address them. I hope you found it helpful.&lt;/p&gt;

</description>
      <category>postgres</category>
    </item>
    <item>
      <title>New PostgreSQL features I developed in 2025</title>
      <dc:creator>Shinya Kato</dc:creator>
      <pubDate>Thu, 25 Dec 2025 23:00:00 +0000</pubDate>
      <link>https://dev.to/shinyakato_/new-postgresql-features-i-developed-in-2025-3lca</link>
      <guid>https://dev.to/shinyakato_/new-postgresql-features-i-developed-in-2025-3lca</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I started contributing to PostgreSQL around 2020. This year I wanted to work harder, so I will explain the PostgreSQL features I developed and committed in 2025.&lt;/p&gt;

&lt;p&gt;I also committed some other patches, but they were bug fixes or small document changes. Here I explain the ones that seem most useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;These are mainly features in PostgreSQL 19, now in development. They may be reverted before the final release.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Added a document that recommends default psql settings when restoring pg_dump backups
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Title: Doc: recommend "psql -X" for restoring pg_dump scripts.&lt;/li&gt;
&lt;li&gt;Committer: Tom Lane&lt;/li&gt;
&lt;li&gt;Date: Sat, 25 Jan 2025&lt;/li&gt;
&lt;li&gt;Link: &lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=d83a108c10a3ec886a24c620a915aa2c5bc023aa" rel="noopener noreferrer"&gt;https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=d83a108c10a3ec886a24c620a915aa2c5bc023aa&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you restore a dump file made by pg_dump with psql, you may get errors if psql is using non-default settings (I saw it with AUTOCOMMIT=off). The change is only in the docs. It recommends using the psql option &lt;code&gt;-X&lt;/code&gt; (&lt;code&gt;--no-psqlrc&lt;/code&gt;) to avoid reading the psql config file.&lt;/p&gt;

&lt;p&gt;For psql config file &lt;code&gt;psqlrc&lt;/code&gt;, see my past blog:&lt;br&gt;
&lt;a href="https://zenn.dev/shinyakato/articles/543dae5d2825ee" rel="noopener noreferrer"&gt;https://zenn.dev/shinyakato/articles/543dae5d2825ee&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a test with &lt;code&gt;\set AUTOCOMMIT off&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--&lt;/span&gt; create a &lt;span class="nb"&gt;test &lt;/span&gt;database
&lt;span class="nv"&gt;$ &lt;/span&gt;createdb test1

&lt;span class="nt"&gt;--&lt;/span&gt; dump all databases to an SQL script file
&lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; issues DROP &lt;span class="k"&gt;for &lt;/span&gt;databases, roles, and tablespaces before recreating them
&lt;span class="nv"&gt;$ &lt;/span&gt;pg_dumpall &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; test1.sql

&lt;span class="nt"&gt;--&lt;/span&gt; restore with psql
&lt;span class="nv"&gt;$ &lt;/span&gt;psql &lt;span class="nt"&gt;-f&lt;/span&gt; test1.sql
~snip~
psql:test1.sql:14: ERROR:  DROP DATABASE cannot run inside a transaction block
psql:test1.sql:23: ERROR:  current transaction is aborted, commands ignored &lt;span class="k"&gt;until &lt;/span&gt;end of transaction block
psql:test1.sql:30: ERROR:  current transaction is aborted, commands ignored &lt;span class="k"&gt;until &lt;/span&gt;end of transaction block
psql:test1.sql:31: ERROR:  current transaction is aborted, commands ignored &lt;span class="k"&gt;until &lt;/span&gt;end of transaction block
~snip~
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;DROP DATABASE&lt;/code&gt; from &lt;code&gt;-c&lt;/code&gt; cannot run inside a transaction block, so you get these errors. Also, by default, when a statement fails inside a transaction block, the whole transaction aborts, so later statements also fail.&lt;/p&gt;

&lt;p&gt;Other statements also cannot run inside a transaction block, so you will see similar errors when restoring them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Added backup_type column to pg_stat_progress_basebackup view
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Title: Add backup_type column to pg_stat_progress_basebackup.&lt;/li&gt;
&lt;li&gt;Committer: Masahiko Sawada&lt;/li&gt;
&lt;li&gt;Date: Tue, 5 Aug 2025&lt;/li&gt;
&lt;li&gt;Link: &lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=deb674454c5cb7ecabecee2e04ca929eee570df4" rel="noopener noreferrer"&gt;https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=deb674454c5cb7ecabecee2e04ca929eee570df4&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PostgreSQL 17 added incremental backup to pg_basebackup. But the pg_stat_progress_basebackup view had no column to tell full or incremental.&lt;/p&gt;

&lt;p&gt;So I added &lt;code&gt;backup_type&lt;/code&gt;, which shows &lt;code&gt;full&lt;/code&gt; or &lt;code&gt;incremental&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Run pg_basebackup and check pg_stat_progress_basebackup from another terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pg_basebackup &lt;span class="nt"&gt;-D&lt;/span&gt; full
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;backup_type&lt;/code&gt; shows &lt;code&gt;full&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# TABLE pg_stat_progress_basebackup;
-[ RECORD 1 ]--------+-------------------------
pid                  | 853626
phase                | streaming database files
backup_total         | 1592460800
backup_streamed      | 622124544
tablespaces_total    | 1
tablespaces_streamed | 0
backup_type          | full                     &amp;lt;- new!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now take an incremental backup with pg_basebackup -i.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pg_basebackup &lt;span class="nt"&gt;-i&lt;/span&gt; full/backup_manifest &lt;span class="nt"&gt;-D&lt;/span&gt; incl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;backup_type&lt;/code&gt; shows &lt;code&gt;incremental&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# TABLE pg_stat_progress_basebackup;
-[ RECORD 1 ]--------+-------------------------
pid                  | 854435
phase                | streaming database files
backup_total         | 1613615104
backup_streamed      | 726617088
tablespaces_total    | 1
tablespaces_streamed | 0
backup_type          | incremental              &amp;lt;- new!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  COPY FROM now supports files with multi-line headers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Title: Support multi-line headers in COPY FROM command.&lt;/li&gt;
&lt;li&gt;Committer: Fujii Masao&lt;/li&gt;
&lt;li&gt;Date: Thu, 3 Jul 2025&lt;/li&gt;
&lt;li&gt;Link: &lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=bc2f348e87c02de63647dbe290d64ff088880dbe" rel="noopener noreferrer"&gt;https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=bc2f348e87c02de63647dbe290d64ff088880dbe&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The COPY command has a &lt;code&gt;HEADER&lt;/code&gt; option. For COPY FROM it controls skipping header rows. For COPY TO it controls outputting column names. Before, COPY FROM could not skip multi-line headers. It only accepted a boolean.&lt;/p&gt;

&lt;p&gt;Now it accepts an integer, so it skips the given number of header lines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# \! cat /tmp/copy.csv
first header
second header
1,one
2,two
3,three

=# COPY t FROM '/tmp/copy.csv' WITH (HEADER 2, FORMAT csv);
COPY 3

=# TABLE t;
 id | data  
----+-------
  1 | one
  2 | two
  3 | three
(3 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the way, MySQL, SQL Server, and Oracle SQL*Loader already had similar functions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MySQL: &lt;code&gt;LOAD DATA ... IGNORE N LINES&lt;/code&gt; &lt;sup id="fnref1"&gt;1&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;SQL Server: &lt;code&gt;BULK INSERT … WITH (FIRST ROW=N)&lt;/code&gt; &lt;sup id="fnref2"&gt;2&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;Oracle SQL*Loader: &lt;code&gt;sqlldr … SKIP=N&lt;/code&gt; &lt;sup id="fnref3"&gt;3&lt;/sup&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Split the autovacuum log settings for VACUUM and ANALYZE
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Title: Add log_autoanalyze_min_duration&lt;/li&gt;
&lt;li&gt;Committer: Peter Eisentraut&lt;/li&gt;
&lt;li&gt;Date: Wed, 15 Oct 2025&lt;/li&gt;
&lt;li&gt;Link: &lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=dd3ae378301f7e84c18f7a90f183c3cd4165c0da" rel="noopener noreferrer"&gt;https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=dd3ae378301f7e84c18f7a90f183c3cd4165c0da&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We already had &lt;code&gt;log_autovacuum_min_duration&lt;/code&gt;. It logged VACUUM and ANALYZE by autovacuum when they took more time than the setting (default unit: ms). But ANALYZE mostly reads sampled rows, while VACUUM reads and writes table and index pages, so VACUUM often takes longer (it depends on table design, data size, stats target, workload, extended stats, etc.). We could not set them separately.&lt;/p&gt;

&lt;p&gt;Now &lt;code&gt;log_autovacuum_min_duration&lt;/code&gt; is VACUUM-only, and new &lt;code&gt;log_autoanalyze_min_duration&lt;/code&gt; is ANALYZE-only. At first we proposed &lt;code&gt;log_autovacuum_vacuum_min_duration&lt;/code&gt; and &lt;code&gt;log_autovacuum_analyze_min_duration&lt;/code&gt; for consistency, but changing the existing name would break backward compatibility and affect pg_dump/pg_upgrade, so we stopped.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# CREATE TABLE t (i int, d text) WITH (
  -- autoanalyze settings
  autovacuum_analyze_threshold = 1,
  autovacuum_analyze_scale_factor = 0,
  log_autoanalyze_min_duration = 0,
  -- autovacuum settings
  autovacuum_vacuum_threshold = 1,
  autovacuum_vacuum_scale_factor = 0,
  log_autovacuum_min_duration = 100_000_000
);
=# INSERT INTO t VALUES (1, 'a');
=# DELETE FROM t WHERE i = 1;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2025-12-03 15:15:39.608 JST [401368] LOG:  automatic analyze of table "postgres.public.t"
avg read rate: 18.229 MB/s, avg write rate: 0.000 MB/s
buffer usage: 155 hits, 7 reads, 0 dirtied
WAL usage: 1 records, 0 full page images, 530 bytes, 0 buffers full
system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Show compressed full-page image size in pg_stat_wal
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Title: Add wal_fpi_bytes to pg_stat_wal and pg_stat_get_backend_wal()&lt;/li&gt;
&lt;li&gt;Committer: Michael Paquier&lt;/li&gt;
&lt;li&gt;Date: Tue, 28 Oct 2025&lt;/li&gt;
&lt;li&gt;Link: &lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=f9a09aa2952039a9956b44d929b9df74d62a4cd4" rel="noopener noreferrer"&gt;https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=f9a09aa2952039a9956b44d929b9df74d62a4cd4&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When &lt;code&gt;wal_compression&lt;/code&gt; is on, full-page images (FPI) in WAL are compressed. Before, to measure the effect you had to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the same benchmark with compression on/off and compare &lt;code&gt;wal_bytes&lt;/code&gt; in pg_stat_wal. But this is for all WAL, not only FPI, so it is not the exact compression ratio.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;pg_waldump --fullpage&lt;/code&gt; on the server to see compressed WAL sizes and calculate the ratio. This needs WAL files and server access, so it was not usable in clouds where you cannot log in. (If you can use pg_wal_inspect, maybe you can calculate in the cloud, but I have not checked.)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So I added &lt;code&gt;wal_fpi_bytes&lt;/code&gt; to pg_stat_wal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# TABLE pg_stat_wal;
-[ RECORD 1 ]----+-----------------------------
wal_records      | 2031667
wal_fpi          | 288581
wal_bytes        | 6346674376
wal_fpi_bytes    | 1932610356                   &amp;lt;- new!
wal_buffers_full | 424447
stats_reset      | 2025-12-02 19:31:44.16184+09
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are also patches to add this info to EXPLAIN (WAL) and VACUUM logs. &lt;sup id="fnref4"&gt;4&lt;/sup&gt;&lt;sup id="fnref5"&gt;5&lt;/sup&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Added mode and started_by columns to pg_stat_progress_vacuum view
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Title: Add mode and started_by columns to pg_stat_progress_vacuum view.&lt;/li&gt;
&lt;li&gt;Committer: Masahiko Sawada&lt;/li&gt;
&lt;li&gt;Date: Tue, 9 Dec 2025&lt;/li&gt;
&lt;li&gt;Link: &lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=f9a09aa2952039a9956b44d929b9df74d62a4cd4" rel="noopener noreferrer"&gt;https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=f9a09aa2952039a9956b44d929b9df74d62a4cd4&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;VACUUM has several reasons to start (auto, manual, wraparound) and several modes (normal, aggressive, fail-safe). The pg_stat_progress_vacuum view for progress did not show these.&lt;/p&gt;

&lt;p&gt;So I added &lt;code&gt;mode&lt;/code&gt; (&lt;code&gt;normal&lt;/code&gt;, &lt;code&gt;aggressive&lt;/code&gt;, &lt;code&gt;failsafe&lt;/code&gt;) and &lt;code&gt;started_by&lt;/code&gt; (&lt;code&gt;manual&lt;/code&gt;, &lt;code&gt;autovacuum&lt;/code&gt;, &lt;code&gt;autovacuum_wraparound&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Here is pg_stat_progress_vacuum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=# TABLE pg_stat_progress_vacuum;
-[ RECORD 1 ]--------+--------------
pid                  | 362895
datid                | 5
datname              | postgres
relid                | 24602
phase                | scanning heap
heap_blks_total      | 8850
heap_blks_scanned    | 5327
heap_blks_vacuumed   | 0
index_vacuum_count   | 0
max_dead_tuple_bytes | 67108864
dead_tuple_bytes     | 0
num_dead_item_ids    | 0
indexes_total        | 0
indexes_processed    | 0
delay_time           | 0
mode                 | normal       &amp;lt;- new!
started_by           | autovacuum   &amp;lt;- new!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A similar patch adds &lt;code&gt;started_by&lt;/code&gt; (&lt;code&gt;manual&lt;/code&gt;, &lt;code&gt;autovacuum&lt;/code&gt;) to pg_stat_progress_analyze. &lt;sup id="fnref6"&gt;6&lt;/sup&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I introduced the PostgreSQL features I developed in 2025. I also proposed some other patches, but they are still under discussion. I hope to share them in next year.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="https://dev.mysql.com/doc/refman/8.4/en/load-data.html#load-data-field-line-handling" rel="noopener noreferrer"&gt;https://dev.mysql.com/doc/refman/8.4/en/load-data.html#load-data-field-line-handling&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/sql/t-sql/statements/bulk-insert-transact-sql?view=sql-server-ver17#firstrow--first_row" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/sql/t-sql/statements/bulk-insert-transact-sql?view=sql-server-ver17#firstrow--first_row&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;&lt;a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/sutil/oracle-sql-loader-commands.html#SUTIL-GUID-84244C46-6AFD-412D-9240-BEB0B5C2718B" rel="noopener noreferrer"&gt;https://docs.oracle.com/en/database/oracle/oracle-database/23/sutil/oracle-sql-loader-commands.html#SUTIL-GUID-84244C46-6AFD-412D-9240-BEB0B5C2718B&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;&lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=5ab0b6a248076bf373a80bc7e83a5dfa4edf13aa" rel="noopener noreferrer"&gt;https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=5ab0b6a248076bf373a80bc7e83a5dfa4edf13aa&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;&lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=ad25744f436ed7809fc754e1a44630b087812fbc" rel="noopener noreferrer"&gt;https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=ad25744f436ed7809fc754e1a44630b087812fbc&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;&lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=ab40db3852dfa093b64c9266dd372fee414e993f" rel="noopener noreferrer"&gt;https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=ab40db3852dfa093b64c9266dd372fee414e993f&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>postgres</category>
    </item>
    <item>
      <title>Analyzing psqlrc settings on GitHub: How PostgreSQL engineers configure PostgreSQL</title>
      <dc:creator>Shinya Kato</dc:creator>
      <pubDate>Sun, 30 Nov 2025 13:48:55 +0000</pubDate>
      <link>https://dev.to/shinyakato_/analyzing-psqlrc-settings-on-github-how-postgresql-engineers-configure-postgresql-1b3f</link>
      <guid>https://dev.to/shinyakato_/analyzing-psqlrc-settings-on-github-how-postgresql-engineers-configure-postgresql-1b3f</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Recently, I read an article titled "&lt;a href="https://qiita.com/reireias/items/d906ab086c3bc4c22147" rel="noopener noreferrer"&gt;Alias Settings of Engineers Around the World&lt;/a&gt;" (in Japanese). As a PostgreSQL engineer, this got me thinking: "If they are customizing their bash aliases, how are they configuring their &lt;code&gt;psql&lt;/code&gt; environments?"&lt;/p&gt;

&lt;p&gt;Driven by curiosity, I decided to investigate GitHub repositories to see how developers commonly configure their &lt;code&gt;psqlrc&lt;/code&gt; files.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is psqlrc?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;psql&lt;/code&gt; is the terminal-based front-end for PostgreSQL, allowing you to execute SQL interactively. Its configuration file is named &lt;code&gt;psqlrc&lt;/code&gt;, and it has the following characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;System-wide settings:&lt;/strong&gt; The system-wide &lt;code&gt;psqlrc&lt;/code&gt; file is stored in &lt;code&gt;../etc/&lt;/code&gt; relative to the directory containing the PostgreSQL executable. This directory can be explicitly set using the environment variable &lt;code&gt;PGSYSCONFDIR&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User-specific settings:&lt;/strong&gt; The user-specific &lt;code&gt;.psqlrc&lt;/code&gt; file is stored in the executing user's home directory. This file can be explicitly set using the environment variable &lt;code&gt;PSQLRC&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versioning:&lt;/strong&gt; You can target specific psql versions by appending the version number to the filename, such as &lt;code&gt;.psqlrc-14&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;References:&lt;/strong&gt; For more details, refer to the &lt;a href="https://www.postgresql.org/docs/current/app-psql.html" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; or the &lt;a href="https://wiki.postgresql.org/wiki/Psqlrc" rel="noopener noreferrer"&gt;PostgreSQL Wiki&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Investigation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Methodology
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; Use the GitHub API to extract URLs of files containing the word &lt;code&gt;psqlrc&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Insert the contents of these files into a PostgreSQL database.&lt;/li&gt;
&lt;li&gt; Analyze the most frequently used settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Extracting URLs via GitHub API
&lt;/h3&gt;

&lt;p&gt;I used the &lt;a href="https://docs.github.com/en/rest/search" rel="noopener noreferrer"&gt;Search API&lt;/a&gt;. Here are the key points to consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The GitHub API returns a maximum of 1,000 results. To bypass this, I sliced the search query by file size.&lt;/li&gt;
&lt;li&gt;The API returns only 100 results per page, so I used a &lt;code&gt;for&lt;/code&gt; loop to fetch all pages.&lt;/li&gt;
&lt;li&gt;To avoid hitting rate limits and angering GitHub, I inserted &lt;code&gt;sleep&lt;/code&gt; commands.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

GITHUB_TOKEN=hoge # Set your own GitHub token here

# API call for files 0 to 1000 bytes
for size in `seq 0 50 950`;
do
  for page in `seq 10`;
  do
    curl -ksS \
      -H "Accept: application/vnd.github.v3+json" \
      -H "Authorization: token ${GITHUB_TOKEN}" \
      -o results/${size}-$((size+49))-${page}.json \
      "[https://api.github.com/search/code?q=filename:psqlrc+size:$](https://api.github.com/search/code?q=filename:psqlrc+size:$){size}..$((size+49))&amp;amp;per_page=100&amp;amp;page=${page}"
    sleep 60
  done
done

# API call for files over 1000 bytes
for page in `seq 10`;
do
  curl -ksS \
    -H "Accept: application/vnd.github.v3+json" \
    -H "Authorization: token ${GITHUB_TOKEN}" \
    -o results/1000-1049-${page}.json \
    "[https://api.github.com/search/code?q=filename:psqlrc+size](https://api.github.com/search/code?q=filename:psqlrc+size):&amp;gt;1000&amp;amp;per_page=100&amp;amp;page=${page}"
  sleep 60
done

# Extract html_url
for size in `seq 0 50 1000`;
do
  for page in `seq 10`;
  do
    cat results/${size}-$((size+49))-${page}.json | \
    jq -r ".items[] | .html_url" | \
    sed "s#/blob/#/raw/#g" &amp;gt;&amp;gt; results/url_list.txt
  done
done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Analyzing the Data in PostgreSQL
&lt;/h3&gt;

&lt;p&gt;I analyzed the &lt;strong&gt;2,005 files&lt;/strong&gt; obtained from the process above. Since I'm a Postgres engineer, I naturally decided to insert the data into PostgreSQL for analysis.&lt;/p&gt;

&lt;p&gt;I'll skip the insertion script, but I stored the &lt;code&gt;psqlrc&lt;/code&gt; contents line by line into a table like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;line_num&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line_num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;line_num&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="k"&gt;statement&lt;/span&gt;
&lt;span class="c1"&gt;----+----------+-----------------------------&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;QUIET&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;auto&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;VERBOSITY&lt;/span&gt; &lt;span class="k"&gt;verbose&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTCONTROL&lt;/span&gt; &lt;span class="n"&gt;ignoredups&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;unset&lt;/span&gt; &lt;span class="n"&gt;QUIET&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I executed the following SQL to rank the commands based on the first word of the &lt;code&gt;statement&lt;/code&gt;. (I excluded comment lines and converted text to lowercase to treat &lt;code&gt;SET&lt;/code&gt; and &lt;code&gt;set&lt;/code&gt; as the same).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;'--'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;command&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;-----------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;8929&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;2565&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;1076&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;1018&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;timing&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;995&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;unset&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;565&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;273&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;207&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;132&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;encoding&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;123&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a summary of the commands and their formats:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\set&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\set [ name [ value [ ... ] ] ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets the psql variable &lt;code&gt;name&lt;/code&gt; to &lt;code&gt;value&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\pset&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\pset [ option [ value ] ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets options affecting the output of query result tables.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\echo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\echo text [ ... ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Prints arguments to standard output, separated by spaces and followed by a newline.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\x [ on | off | auto ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Toggles or sets extended table formatting mode.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\timing&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\timing [ on | off ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Toggles or sets the display of how long each SQL statement takes to execute.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\unset&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\unset name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unsets (deletes) the psql variable &lt;code&gt;name&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\setenv&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\setenv name [ value ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets the environment variable &lt;code&gt;name&lt;/code&gt; to &lt;code&gt;value&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;\r&lt;/code&gt; (&lt;code&gt;\reset&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Resets (clears) the query buffer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;SET&lt;/code&gt; (SQL)&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Changes a run-time parameter.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\encoding&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\encoding [ encoding ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets the client character set encoding.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Let's look at each of them individually.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;\set&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;et'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;item1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;item2&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;-------+-------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;prompt1&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;1013&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;quiet&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;919&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;comp_keyword_case&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;860&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;histcontrol&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;823&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;histfile&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;819&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;prompt2&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;766&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;verbosity&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;717&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;histsize&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;261&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;on_error_rollback&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;254&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;on_error_stop&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;85&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;locks&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;84&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;uptime&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;83&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;clear&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;83&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;70&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;dbsize&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;70&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;activity&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;67&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tablesize&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;64&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;conninfo&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;64&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;waits&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;63&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sp&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;59&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;uselesscol&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;59&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ll&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;57&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;show_slow_queries&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;54&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;autocommit&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;46&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;43&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;version&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;43&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;echo_hidden&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;42&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;menu&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;40&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tsize&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;35&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;extensions&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;35&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;\set PROMPT1&lt;/code&gt;, &lt;code&gt;\set PROMPT2&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;              
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;et'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'prompt1'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                                &lt;span class="k"&gt;statement&lt;/span&gt;                                &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;-------------------------------------------------------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT1&lt;/span&gt; &lt;span class="s1"&gt;'%[%033[1m%]%M %n@%/%R%[%033[0m%]%# '&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;258&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT1&lt;/span&gt; &lt;span class="s1"&gt;'%[%033[1m%][%/] # '&lt;/span&gt;                                       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;53&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT1&lt;/span&gt; &lt;span class="s1"&gt;'%[%033[33;1m%]%x%[%033[0m%]%[%033[1m%]%/%[%033[0m%]%R%# '&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;51&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT1&lt;/span&gt; &lt;span class="s1"&gt;'(%n@%M:%&amp;gt;) [%/] &amp;gt; '&lt;/span&gt;                                       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;30&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT1&lt;/span&gt; &lt;span class="s1"&gt;'%[%033[1m%]%M/%/%R%[%033[0m%]%# '&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;24&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT1&lt;/span&gt; &lt;span class="s1"&gt;'%~%x%# '&lt;/span&gt;                                                  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;23&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT1&lt;/span&gt; &lt;span class="s1"&gt;'%M:%[%033[1;31m%]%&amp;gt;%[%033[0m%] %n@%/%R%#%x '&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;23&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT1&lt;/span&gt; &lt;span class="s1"&gt;'%n@%M %~&amp;gt;'&lt;/span&gt;                                                &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;18&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT1&lt;/span&gt; &lt;span class="s1"&gt;'%M:%&amp;gt; %n@%/%R%#%x '&lt;/span&gt;                                       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;16&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT1&lt;/span&gt; &lt;span class="s1"&gt;'%n@%M:%&amp;gt;%x %/# '&lt;/span&gt;                                          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;12&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;et'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'prompt2'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                   &lt;span class="k"&gt;statement&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;-----------------------------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT2&lt;/span&gt; &lt;span class="s1"&gt;'[more] %R &amp;gt; '&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;305&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT2&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;97&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT2&lt;/span&gt; &lt;span class="s1"&gt;'... &amp;gt; '&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;47&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT2&lt;/span&gt; &lt;span class="s1"&gt;'... # '&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;31&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT2&lt;/span&gt; &lt;span class="s1"&gt;'%M %n@%/%R %# '&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;24&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT2&lt;/span&gt; &lt;span class="s1"&gt;'%R%x%# '&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;15&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT2&lt;/span&gt; &lt;span class="s1"&gt;'%R%# '&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;12&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT2&lt;/span&gt; &lt;span class="s1"&gt;'%[%033[1;33m%]%R%#%[%033[0m%] '&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;12&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT2&lt;/span&gt; &lt;span class="s1"&gt;'&amp;gt; '&lt;/span&gt;                             &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;12&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;PROMPT2&lt;/span&gt; &lt;span class="s1"&gt;'%R&amp;gt; '&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;8&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;PROMPT1&lt;/code&gt;, &lt;code&gt;PROMPT2&lt;/code&gt;, and &lt;code&gt;PROMPT3&lt;/code&gt; are variables that configure the psql command prompt.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PROMPT1:&lt;/strong&gt; The normal prompt issued when psql requests a new command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PROMPT2:&lt;/strong&gt; The prompt issued when more input is expected (e.g., when a command is not terminated by a semicolon or a quote is left open).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PROMPT3:&lt;/strong&gt; The prompt issued during a SQL &lt;code&gt;COPY FROM STDIN&lt;/code&gt; command when row input is expected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It seems many people customize &lt;code&gt;PROMPT1&lt;/code&gt; and &lt;code&gt;PROMPT2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here are examples of what these prompts look like when connected as the &lt;code&gt;rocky&lt;/code&gt; user (superuser) to the &lt;code&gt;postgres&lt;/code&gt; database via a Unix domain socket:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PROMPT1 Examples&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PROMPT1 Setting&lt;/th&gt;
&lt;th&gt;Display Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;%/%R%x%#&lt;/code&gt; (Default)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;postgres=#&lt;/code&gt; (Default)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%[%033[1m%]%M %n@%/%R%[%033[0m%]%#&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[local] rocky@postgres=#&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%[%033[1m%][%/] #&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[postgres] #&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%[%033[33;1m%]%x%[%033[0m%]%[%033[1m%]%/%[%033[0m%]%R%#&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;postgres=#&lt;/code&gt; (Colored)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;(%n@%M:%&amp;gt;) [%/] &amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(rocky@[local]:5432) [postgres] &amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%[%033[1m%]%M/%/%R%[%033[0m%]%#&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[local]/postgres=#&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;PROMPT2 Examples&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PROMPT2 Setting&lt;/th&gt;
&lt;th&gt;Display Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;%/%R%x%#&lt;/code&gt; (Default)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;postgres(#&lt;/code&gt; (Default)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[more] %R &amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[more] ( &amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;''&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;(No display)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;... &amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;... &amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;... #&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;... #&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%M %n@%/%R %#&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[local] rocky@postgres( #&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;It appears many users prefer to display the connection user, database, port, and hostname.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;\set QUIET&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;et'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'quiet'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;statement&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;---------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;QUIET&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;641&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;QUIET&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;78&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;QUIET&lt;/span&gt; &lt;span class="k"&gt;OFF&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;42&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;QUIET&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;42&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;QUIET&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;37&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;QUIET&lt;/span&gt; &lt;span class="n"&gt;yes&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;27&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;QUIET&lt;/span&gt; &lt;span class="k"&gt;off&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;26&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;QUIET&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;18&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;QUIET&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;QUIET&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;QUIETRC&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;QUIET&lt;/code&gt; variable has the same effect as the command-line option &lt;code&gt;-q&lt;/code&gt; (&lt;code&gt;--quiet&lt;/code&gt;). It configures psql to work silently without printing informational messages.&lt;/p&gt;

&lt;p&gt;For example, normally &lt;code&gt;CREATE TABLE&lt;/code&gt; outputs a confirmation text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt;
&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;QUIET&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt;
&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, rather than using it interactively, it seems most users set &lt;code&gt;\set QUIET ON&lt;/code&gt; at the &lt;strong&gt;beginning&lt;/strong&gt; of their &lt;code&gt;psqlrc&lt;/code&gt; and &lt;code&gt;\set QUIET OFF&lt;/code&gt; at the &lt;strong&gt;end&lt;/strong&gt; to suppress the output of the configuration commands running within the &lt;code&gt;psqlrc&lt;/code&gt; itself.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;\set COMP_KEYWORD_CASE&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;et'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'comp_keyword_case'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
               &lt;span class="k"&gt;statement&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;---------------------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;COMP_KEYWORD_CASE&lt;/span&gt; &lt;span class="k"&gt;upper&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;818&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;COMP_KEYWORD_CASE&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;26&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;COMP_KEYWORD_CASE&lt;/span&gt; &lt;span class="k"&gt;preserve&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;upper&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;5&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;COMP_KEYWORD_CASE&lt;/span&gt; &lt;span class="k"&gt;preserve&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;lower&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;COMP_KEYWORD_CASE&lt;/span&gt; &lt;span class="k"&gt;upper&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;COMP_KEYWORD_CASE&lt;/span&gt; &lt;span class="s1"&gt;'upper'&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;comp_keyword_case&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This variable determines whether to use upper or lower case when using tab completion for SQL keywords.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;upper&lt;/code&gt;: Use upper case.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;lower&lt;/code&gt;: Use lower case.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;preserve-upper&lt;/code&gt; (Default): Use the case of the already entered text; otherwise, use upper case.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;preserve-lower&lt;/code&gt;: Use the case of the already entered text; otherwise, use lower case.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The vast majority of users set this to &lt;code&gt;upper&lt;/code&gt; to force uppercase auto-completion.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;\set HISTCONTROL&lt;/code&gt;, &lt;code&gt;\set HISTFILE&lt;/code&gt;, &lt;code&gt;\set HISTSIZE&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;et'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'histcontrol'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
           &lt;span class="k"&gt;statement&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;-------------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTCONTROL&lt;/span&gt; &lt;span class="n"&gt;ignoredups&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;748&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTCONTROL&lt;/span&gt; &lt;span class="n"&gt;ignoreboth&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;60&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTCONTROL&lt;/span&gt; &lt;span class="n"&gt;ignorespace&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;11&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTCONTROL&lt;/span&gt; &lt;span class="n"&gt;ignoredups&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTCONTROL&lt;/span&gt; &lt;span class="k"&gt;none&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can control the command history list using the &lt;code&gt;HISTCONTROL&lt;/code&gt; variable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ignorespace&lt;/code&gt;: Lines starting with a space are not added to the history list.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ignoredups&lt;/code&gt;: Lines matching the previous history entry are not added to the history list.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ignoreboth&lt;/code&gt;: Enables both ignorespace and ignoredups.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;none&lt;/code&gt; (Default): All lines are added to the history list.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It seems many users configure &lt;code&gt;\set HISTCONTROL ignoredups&lt;/code&gt; to prevent lines identical to the previous entry from being added to the history list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;et'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'histfile'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                                                        &lt;span class="k"&gt;statement&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;-------------------------------------------------------------------------------------------------------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTFILE&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;psql_history&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;DBNAME&lt;/span&gt;                                                                                  &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;514&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTFILE&lt;/span&gt; &lt;span class="nv"&gt;`[[ -z $PSQL_HISTFILE ]] &amp;amp;&amp;amp; echo $HOME/.psql_history || echo $PSQL_HISTFILE`&lt;/span&gt;                              &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;46&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTFILE&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;psql_history&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;HOST&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;DBNAME&lt;/span&gt;                                                                          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;39&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTFILE&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;psql&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;DBNAME&lt;/span&gt;                                                                                  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;26&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTFILE&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;psql_history&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;DBNAME&lt;/span&gt;                                                                                   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;18&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTFILE&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;psql_history&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;DBNAME&lt;/span&gt;                                                                                   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;14&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTFILE&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;psql&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;HOST&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;DBNAME&lt;/span&gt;                                                                          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;11&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTFILE&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'OPENSHIFT_DATA_DIR'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;%&amp;gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;psql_history&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;DBNAME&lt;/span&gt;                                                   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;10&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTFILE&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;psql_history&lt;/span&gt;                                                                                           &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;9&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTFILE&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;psql_history&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;DBNAME&lt;/span&gt;                                                                                  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;8&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can configure the filename for saving history using the &lt;code&gt;HISTFILE&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;It seems many users include the database name or hostname in the filename.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;et'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'histsize'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="k"&gt;statement&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;-----------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTSIZE&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;109&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTSIZE&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;31&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTSIZE&lt;/span&gt; &lt;span class="mi"&gt;100000&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;30&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTSIZE&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;23&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTSIZE&lt;/span&gt; &lt;span class="mi"&gt;20000&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;13&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTSIZE&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;10&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTSIZE&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;5&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTSIZE&lt;/span&gt; &lt;span class="mi"&gt;12000&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTSIZE&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;HISTSIZE&lt;/span&gt; &lt;span class="mi"&gt;6000&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can set the maximum number of commands to store in the command history (default is 500) using the &lt;code&gt;HISTSIZE&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;It seems many users configure this to increase the maximum number of commands stored in the history.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;\set VERBOSITY&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;et'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'verbosity'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         &lt;span class="k"&gt;statement&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;--------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;VERBOSITY&lt;/span&gt; &lt;span class="k"&gt;verbose&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;691&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;VERBOSITY&lt;/span&gt; &lt;span class="n"&gt;terse&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;15&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;VERBOSITY&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;6&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;VERBOSITY&lt;/span&gt; &lt;span class="k"&gt;verbose&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;VERBOSITY&lt;/span&gt; &lt;span class="s1"&gt;'terse'&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;VERBOSITY&lt;/span&gt; &lt;span class="k"&gt;verbose&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This controls the verbosity of error reports. The trend is overwhelmingly &lt;code&gt;verbose&lt;/code&gt; (&lt;code&gt;\set VERBOSITY verbose&lt;/code&gt;), ensuring error details are fully displayed.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;\set ON_ERROR_ROLLBACK&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;et'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'on_error_rollback'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                                                        &lt;span class="k"&gt;statement&lt;/span&gt;                                                         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;--------------------------------------------------------------------------------------------------------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_ROLLBACK&lt;/span&gt; &lt;span class="n"&gt;interactive&lt;/span&gt;                                                                                       &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;227&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_ROLLBACK&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;                                                                                                &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;14&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_ROLLBACK&lt;/span&gt;                                                                                                   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_ROLLBACK&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;                                                                                                 &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_ROLLBACK&lt;/span&gt; &lt;span class="k"&gt;off&lt;/span&gt;                                                                                               &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_ROLLBACK&lt;/span&gt; &lt;span class="s1"&gt;'interactive'&lt;/span&gt;                                                                                     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_ROLLBACK&lt;/span&gt; &lt;span class="s1"&gt;'on'&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;                                                                                            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_ROLLBACK&lt;/span&gt; &lt;span class="s1"&gt;'on'&lt;/span&gt;                                                                                              &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_ROLLBACK&lt;/span&gt; &lt;span class="k"&gt;off&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;interactive&lt;/span&gt; &lt;span class="c1"&gt;-- interactive lets you fix your fat fingers... Prefer to redo the whole thing |     1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This controls behavior when an error occurs inside a transaction block.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;on&lt;/code&gt;: If a statement errors, the error is ignored, and the transaction continues.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;interactive&lt;/code&gt;: Errors are ignored only in interactive sessions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;off&lt;/code&gt; (Default): An error aborts the entire transaction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most users set this to &lt;code&gt;interactive&lt;/code&gt;, which allows you to "fix your fat fingers" without losing the whole transaction while typing manually.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;\set ON_ERROR_STOP&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;et'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'on_error_stop'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;statement&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;-------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_STOP&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;69&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_STOP&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;8&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_STOP&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;5&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_STOP&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ON_ERROR_STOP&lt;/span&gt; &lt;span class="k"&gt;off&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By setting &lt;code&gt;\set ON_ERROR_STOP on&lt;/code&gt;, command processing stops immediately after an error. In interactive mode, it returns to the prompt; in scripts, psql exits with error code 3.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;\pset&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;\pset&lt;/code&gt; controls the formatting of table output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\p&lt;/span&gt;&lt;span class="s1"&gt;set'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;item1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="n"&gt;item2&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;-------+--------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;1201&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;374&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;313&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;289&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;144&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;unicode_header_linestyle&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;64&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;unicode_column_linestyle&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;57&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;unicode_border_linestyle&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;57&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;expanded&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;22&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;numericlocale&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;9&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;columns&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;8&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;footer&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;8&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;fieldsep&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;6&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tuples_only&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;5&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;pager_min_lines&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;recordsep&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;\pset null&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\p&lt;/span&gt;&lt;span class="s1"&gt;set'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'null'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;statement&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;---------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="s1"&gt;'[NULL]'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;416&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="s1"&gt;'¤'&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;142&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="err"&gt;¤&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;127&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="s1"&gt;'(null)'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;98&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="s1"&gt;'NULL'&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;93&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="s1"&gt;'[null]'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;51&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;31&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;28&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="err"&gt;∅&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;26&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="s1"&gt;'∅'&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Users configure this to display a specific string (like &lt;code&gt;[NULL]&lt;/code&gt;, &lt;code&gt;(null)&lt;/code&gt;, or &lt;code&gt;¤&lt;/code&gt;) instead of a blank space when a value is &lt;code&gt;NULL&lt;/code&gt;, making it easier to spot.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;\pset linestyle&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\p&lt;/span&gt;&lt;span class="s1"&gt;set'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'linestyle'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         &lt;span class="k"&gt;statement&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;---------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt; &lt;span class="n"&gt;unicode&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;320&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt; &lt;span class="s1"&gt;'unicode'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;44&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt; &lt;span class="n"&gt;ascii&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;5&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt; &lt;span class="n"&gt;unicode&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt; &lt;span class="s1"&gt;'ascii'&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many users set this to &lt;code&gt;unicode&lt;/code&gt; (Default is &lt;code&gt;ascii&lt;/code&gt;) to use smoother lines for tables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example (Unicode):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;           statement           │ count 
───────────────────────────────┼───────
 \pset linestyle unicode       │   320
 \pset linestyle 'unicode'     │    44
 \pset linestyle ascii         │     5
 \pset linestyle u             │     2
 \pset linestyle unicode\r     │     2
 \pset linestyle 'ascii'       │     1
(6 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;\pset border&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\p&lt;/span&gt;&lt;span class="s1"&gt;set'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'border'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                     &lt;span class="k"&gt;statement&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;----------------------------------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;250&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;48&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;7&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;                                   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;-- Makes the borders a little nicer |     1&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This changes the border style of tables (Default is 1).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example (&lt;code&gt;border 0&lt;/code&gt;):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    statement                       count 
-------------------------------------------------- -----
\pset border 2                                       250
\pset border 1                                        48
\pset border 0                                         7
\pset border 3                                         3
\pset border 2\r                                       2
\pset border 1 -- Makes the borders a little nicer     1
\pset border 4                                         1
\pset border 7                                         1
(8 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example (&lt;code&gt;border 2&lt;/code&gt;):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+----------------------------------------------------+-------+
|                    statement                       | count |
+----------------------------------------------------+-------+
| \pset border 2                                     |   250 |
| \pset border 1                                     |    48 |
| \pset border 0                                     |     7 |
| \pset border 3                                     |     3 |
| \pset border 2\r                                   |     2 |
| \pset border 1 -- Makes the borders a little nicer |     1 |
| \pset border 4                                     |     1 |
| \pset border 7                                     |     1 |
+----------------------------------------------------+-------+
(8 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;\pset pager&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\p&lt;/span&gt;&lt;span class="s1"&gt;set'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'pager'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;statement&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;----------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt; &lt;span class="k"&gt;off&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;181&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt; &lt;span class="n"&gt;always&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;69&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;28&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt; &lt;span class="n"&gt;auto&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt; &lt;span class="n"&gt;always&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;off&lt;/code&gt;: Disable the pager.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;always&lt;/code&gt;: Always use the pager.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;on&lt;/code&gt; (Default): Use pager only when needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;\pset format&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\p&lt;/span&gt;&lt;span class="s1"&gt;set'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'format'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;statement&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="n"&gt;wrapped&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;127&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="n"&gt;aligned&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;12&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pset&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="n"&gt;unaligned&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setting &lt;code&gt;wrapped&lt;/code&gt; helps display wide data values by wrapping them across multiple lines to fit the target column width. (Default is &lt;code&gt;aligned&lt;/code&gt;).&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;\echo&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\e&lt;/span&gt;&lt;span class="s1"&gt;cho'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                              &lt;span class="k"&gt;statement&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;----------------------------------------------------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Administrative queries:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;                                    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;35&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;Current Host Server Date Time : '&lt;/span&gt;&lt;span class="nv"&gt;`date`&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;33&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;                                                                &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;29&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Development queries:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;                                       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;28&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t\\&lt;/span&gt;&lt;span class="s1"&gt;h&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s1"&gt;-- Help with SQL commands'&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;20&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t&lt;/span&gt;&lt;span class="s1"&gt;:uselesscol&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;-- Useless columns'&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;20&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t&lt;/span&gt;&lt;span class="s1"&gt;:activity&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;-- Server activity'&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;20&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t&lt;/span&gt;&lt;span class="s1"&gt;:conninfo&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;-- Server connections'&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;20&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t&lt;/span&gt;&lt;span class="s1"&gt;:uptime&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s1"&gt;-- Server uptime'&lt;/span&gt;                            &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;20&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Type :extensions to see the available extensions. &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;20&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t&lt;/span&gt;&lt;span class="s1"&gt;:locks&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s1"&gt;-- Lock info'&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;20&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t&lt;/span&gt;&lt;span class="s1"&gt;:clear&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s1"&gt;-- Clear screen'&lt;/span&gt;                              &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;19&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t&lt;/span&gt;&lt;span class="s1"&gt;:tablesize&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;-- Tables Size'&lt;/span&gt;                             &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;19&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Type :version to see the PostgreSQL version. &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;19&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t&lt;/span&gt;&lt;span class="s1"&gt;:menu&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s1"&gt;-- Help Menu'&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;19&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Type &lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s1"&gt;q to exit. &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;                                         &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;19&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t\\&lt;/span&gt;&lt;span class="s1"&gt;?&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s1"&gt;-- Help with psql commands&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;19&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t&lt;/span&gt;&lt;span class="s1"&gt;:sp&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s1"&gt;-- Current Search Path'&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;19&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t&lt;/span&gt;&lt;span class="s1"&gt;:dbsize&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s1"&gt;-- Database Size'&lt;/span&gt;                            &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;19&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t&lt;/span&gt;&lt;span class="s1"&gt;:ll&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s1"&gt;-- List&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;                                       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;19&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t&lt;/span&gt;&lt;span class="s1"&gt;:settings&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;-- Server Settings'&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;19&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t\t&lt;/span&gt;&lt;span class="s1"&gt;:waits&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s1"&gt;-- Waiting queires'&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;18&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Welcome to PostgreSQL! &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;                                    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;15&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;:activity&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;-- Server activity'&lt;/span&gt;                              &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;11&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;:dbsize&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s1"&gt;-- Database Size'&lt;/span&gt;                                &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;11&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;:tablesize&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;-- Tables Size'&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;11&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;:uptime&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s1"&gt;-- Server uptime'&lt;/span&gt;                                &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;11&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;:conninfo&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;-- Server connections'&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;11&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;:settings&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;-- Server Settings'&lt;/span&gt;                              &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;11&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\\&lt;/span&gt;&lt;span class="s1"&gt;?&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s1"&gt;-- Help with psql commands&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;\echo&lt;/code&gt; is used to print messages.&lt;br&gt;
Looking at the data, users utilize this to display "Welcome" messages, server information (Host, Date), or cheat sheets for custom aliases upon psql startup.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;code&gt;\x&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;item1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;-------+--------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;auto&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;987&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;11&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;off&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;10&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;9&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;\x auto&lt;/code&gt; is the most common setting (987 uses). This automatically switches to extended table formatting (where columns are listed vertically) when the output is too wide to fit the screen.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;code&gt;\timing&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;iming'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;item1&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;---------+-------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;timing&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;833&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;timing&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;159&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;timing&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;off&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;timing&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Using &lt;code&gt;\timing&lt;/code&gt; or &lt;code&gt;\timing on&lt;/code&gt; toggles the display of execution time for every SQL statement.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;code&gt;\unset&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="s1"&gt;nset'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;item1&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;item2&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;--------+------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;unset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;quiet&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;554&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;unset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;timing&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;unset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;quiet&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;unset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;quietrc&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;unset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;singlestep&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;unset&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;quite&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As mentioned in the &lt;code&gt;\set QUIET&lt;/code&gt; section, &lt;code&gt;\unset&lt;/code&gt; is primarily used to &lt;code&gt;\unset QUIET&lt;/code&gt; at the end of the file to restore message output after loading the configuration.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;code&gt;\setenv&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;etenv'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;item1&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="n"&gt;item2&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;---------+----------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;129&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;less&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;89&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;editor&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;41&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;psql_editor&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;9&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;psql_pager&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;psql_editor_linenumber_arg&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;echo&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;              
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt; 
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;etenv'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'pager'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                               &lt;span class="k"&gt;statement&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;-----------------------------------------------------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;PAGER&lt;/span&gt; &lt;span class="s1"&gt;'less -SX'&lt;/span&gt;                                              &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;28&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;PAGER&lt;/span&gt; &lt;span class="k"&gt;less&lt;/span&gt;                                                    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;26&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;PAGER&lt;/span&gt; &lt;span class="n"&gt;pspg&lt;/span&gt;                                                    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;14&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;PAGER&lt;/span&gt; &lt;span class="s1"&gt;'less -S'&lt;/span&gt;                                               &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;11&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;PAGER&lt;/span&gt; &lt;span class="s1"&gt;'pspg --no-mouse -bX --no-commandbar --no-topbar'&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;5&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;PAGER&lt;/span&gt; &lt;span class="s1"&gt;'less'&lt;/span&gt;                                                  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;PAGER&lt;/span&gt; &lt;span class="s1"&gt;'less -XS'&lt;/span&gt;                                              &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;PAGER&lt;/span&gt; &lt;span class="s1"&gt;'pspg -FX -s 17 --no-mouse --no-bars --only-for-tables'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;PAGER&lt;/span&gt; &lt;span class="s1"&gt;'less -FXE'&lt;/span&gt;                                             &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;PAGER&lt;/span&gt; &lt;span class="s1"&gt;'/usr/bin/less'&lt;/span&gt;                                         &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It seems users use less or pspg as their pager by configuring the PAGER or PSQL_PAGER environment variables. Also, it seems they configure options for less by setting the LESS environment variable.&lt;/p&gt;

&lt;p&gt;
  📝 &lt;strong&gt;Note:&lt;/strong&gt;
  &lt;br&gt;
pspg is a pager specifically designed for PostgreSQL tables.&lt;br&gt;
&lt;a href="https://github.com/okbob/pspg" rel="noopener noreferrer"&gt;https://github.com/okbob/pspg&lt;/a&gt;&lt;br&gt;


&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt; 
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s1"&gt;etenv'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'editor'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                 &lt;span class="k"&gt;statement&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;------------------------------------------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;EDITOR&lt;/span&gt; &lt;span class="s1"&gt;'nvim'&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;5&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;EDITOR&lt;/span&gt; &lt;span class="s1"&gt;'vim'&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;5&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;EDITOR&lt;/span&gt; &lt;span class="s1"&gt;'/usr/bin/vim'&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;5&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;EDITOR&lt;/span&gt; &lt;span class="s1"&gt;'/usr/local/bin/vim'&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;EDITOR&lt;/span&gt; &lt;span class="n"&gt;vim&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;EDITOR&lt;/span&gt; &lt;span class="s1"&gt;'/usr/bin/nvim'&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;EDITOR&lt;/span&gt; &lt;span class="n"&gt;emacs&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;EDITOR&lt;/span&gt; &lt;span class="n"&gt;nvim&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;EDITOR&lt;/span&gt; &lt;span class="s1"&gt;'~/.nix-profile/bin/nvim'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setenv&lt;/span&gt; &lt;span class="n"&gt;EDITOR&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;vim&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It seems users use Neovim, Vim, or Emacs as their editor by configuring the EDITOR or PSQL_EDITOR environment variables.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;\r&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This stands for &lt;code&gt;\reset&lt;/code&gt;, which clears the query buffer. In my data, it looks mostly like a parsing artifact where &lt;code&gt;\r&lt;/code&gt; (carriage return) characters were caught, but some users might be ensuring a clean slate.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;SET&lt;/code&gt; (SQL Command)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'set'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;item1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                          &lt;span class="n"&gt;item2&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;-------+--------------------------------------------------------+-------&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt;                                            &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;47&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;intervalstyle&lt;/span&gt;                                          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;41&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;                                               &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;9&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;application_name&lt;/span&gt;                                       &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;7&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;client_min_messages&lt;/span&gt;                                    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;6&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;bytea_output&lt;/span&gt;                                           &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;5&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;client_encoding&lt;/span&gt;                                        &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                                    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;session&lt;/span&gt;                                                &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;site_config_service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;project_service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;work_mem&lt;/span&gt;                                               &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'us/eastern'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;default_transaction_read_only&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dwh&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;stage&lt;/span&gt;                             &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tcp_keepalives_idle&lt;/span&gt;                                    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;maintenance_work_mem&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1gb'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;postgis&lt;/span&gt;                             &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;work_mem&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'512mb'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                                      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;enable_bitmapscan&lt;/span&gt;                                      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;statement_timeout&lt;/span&gt;                                      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt; 
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'set'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'search_path'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                        &lt;span class="k"&gt;statement&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;--------------------------------------------------------+-------&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;pdfbox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mycore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;setcore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;curl7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mycore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;jsonorg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;setcore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;mycore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;setcore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;setcore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;libxml2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;setcore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;expat2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mycore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;setcore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;gnuzip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;setcore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;arxiv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;pdfbox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mycore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;setcore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;statement&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt; 
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'set'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'intervalstyle'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                 &lt;span class="k"&gt;statement&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;------------------------------------------+-------&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;intervalstyle&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="s1"&gt;'postgres_verbose'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;39&lt;/span&gt;
 &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;intervalstyle&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="s1"&gt;'postgres_verbose'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;intervalstyle&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="s1"&gt;'postgres_verbose'&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are standard SQL commands executed at startup.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;search_path&lt;/code&gt;: Users set custom search paths for their schemas.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;intervalstyle&lt;/code&gt;: Users often set this to &lt;code&gt;'postgres_verbose'&lt;/code&gt; to control how interval data types are formatted.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;\encoding&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;psqlrc&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;item1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item2&lt;/span&gt;            
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\e&lt;/span&gt;&lt;span class="s1"&gt;ncoding'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;item1&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;item2&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="c1"&gt;-----------+-----------+-------&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;encoding&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;unicode&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;105&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;encoding&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;utf8&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;6&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;encoding&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;latin1&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;5&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;encoding&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;utf&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;encoding&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sql_ascii&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;encoding&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s1"&gt;'utf8'&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;encoding&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;latin1&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;encoding&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most users explicitly set the client encoding to &lt;code&gt;unicode&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I had never customized my &lt;code&gt;psqlrc&lt;/code&gt; before, so this investigation was a great opportunity to learn about the available settings.&lt;/p&gt;

&lt;p&gt;Personally, since I often connect to multiple different PostgreSQL servers, I plan to customize my &lt;strong&gt;PROMPT&lt;/strong&gt; settings to clearly distinguish between environments (and avoid accidents!).&lt;/p&gt;

&lt;p&gt;I hope this article helps you create a more comfortable &lt;code&gt;psql&lt;/code&gt; life.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>psqlrc</category>
    </item>
    <item>
      <title>Can we use Rust to Develop Extensions for PostgreSQL?</title>
      <dc:creator>Shinya Kato</dc:creator>
      <pubDate>Mon, 24 Nov 2025 01:13:02 +0000</pubDate>
      <link>https://dev.to/shinyakato_/can-we-use-rust-to-develop-extensions-for-postgresql-5431</link>
      <guid>https://dev.to/shinyakato_/can-we-use-rust-to-develop-extensions-for-postgresql-5431</guid>
      <description>&lt;p&gt;Although it has been a while since the event, I am sharing the full transcript of my talk from &lt;a href="https://posetteconf.com/2025/talks/can-we-use-rust-to-develop-extensions-for-postgresql/" rel="noopener noreferrer"&gt;POSETTE 2025&lt;/a&gt;. Please note that some information may be outdated as time has passed.&lt;/p&gt;

&lt;p&gt;Additionally, the Call for Proposals (CFP) for &lt;a href="https://posetteconf.com/2026/cfp/" rel="noopener noreferrer"&gt;POSETTE 2026&lt;/a&gt; is now open. Let's make the next POSETTE a great success together!&lt;/p&gt;

&lt;p&gt;Slides: 

&lt;iframe src="https://www.slideshare.net/slideshow/embed_code/key/lJRWJL65nyDs2A" alt="lJRWJL65nyDs2A on slideshare.net" width="100%" height="487"&gt;
&lt;/iframe&gt;


&lt;br&gt;
YouTube: 

  &lt;iframe src="https://www.youtube.com/embed/0NKFVQq0YuA"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;




&lt;h3&gt;
  
  
  Can We Use Rust to Develop Extensions for PostgreSQL? #1
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1e0vlg5wiyv34w1icol.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1e0vlg5wiyv34w1icol.jpg" alt="Can We Use Rust to Develop Extensions for PostgreSQL? #1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hello everyone.&lt;br&gt;
Thank you for joining my session today.&lt;br&gt;
My name is Shinya Kato and I'm a database engineer at NTT DATA Japan Corporation.&lt;/p&gt;

&lt;p&gt;Today, I will talk about Postgres extensions.&lt;br&gt;
The title of my talk is "Can We Use Rust to Develop Extensions for PostgreSQL".&lt;br&gt;
If you're someone who's passionate about Postgres extension development or curious about how Rust fits into the picture, this presentation is for you.&lt;br&gt;
Let's dive into it.&lt;/p&gt;


&lt;h3&gt;
  
  
  About me #2
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xrfo1mu3st353rg9nt1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xrfo1mu3st353rg9nt1.jpg" alt="About me #2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we go.&lt;/p&gt;

&lt;p&gt;Let me introduce myself a little bit.&lt;br&gt;
As I said, I'm a database engineer at NTT Data Japan Corporation which is the largest IT company in Japan.&lt;br&gt;
I've been here with our company for about 5 years.&lt;/p&gt;

&lt;p&gt;I specialize in Postgres, offering technical support, conducting R&amp;amp;D, contributing to the Postgres project, and maintaining two key extensions: pg_bulkload and pg_rman.&lt;/p&gt;


&lt;h3&gt;
  
  
  Can we use Rust to develop extensions for PostgreSQL? #3
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhcig3hutojxrrupop8hh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhcig3hutojxrrupop8hh.jpg" alt="Can we use Rust to develop extensions for PostgreSQL? #3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To begin, can we use Rust to develop extensions for PostgreSQL?&lt;/p&gt;


&lt;h3&gt;
  
  
  Yes, we can ✅ #4
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsfvr5vvzyknoenjy6y7t.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsfvr5vvzyknoenjy6y7t.jpg" alt="Yes, we can ✅ #4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes, we can.&lt;br&gt;
Instead of legacy C language, it's possible to develop Postgres extensions using modern Rust and frameworks.&lt;/p&gt;


&lt;h3&gt;
  
  
  But limited resources make it challenging ❎ #5
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qojo3iukci7265v9ciz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qojo3iukci7265v9ciz.jpg" alt="But limited resources make it challenging ❎ #5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, getting started with Postgres extension development in Rust can be a little bit challenging due to limited information.&lt;br&gt;
This talk aims to provide assistance for developing Postgres extensions using Rust.&lt;br&gt;
Furthermore, drawing from my own experience implementing Postgres extensions in Rust, I will share practical insights, covering both the pros and cons.&lt;/p&gt;


&lt;h3&gt;
  
  
  Why Rust? #6
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fteum8sj0f5immb1pmu5p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fteum8sj0f5immb1pmu5p.jpg" alt="Why Rust? #6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why Rust?&lt;br&gt;
Currently, system security is compromised by numerous vulnerabilities caused by memory corruption issues.&lt;br&gt;
Google's security team, Project Zero, reports that about 68% of zero-day vulnerabilities are caused by memory-related problems.&lt;br&gt;
These critical memory safety risks are commonly found in C and C++ applications.&lt;/p&gt;

&lt;p&gt;On the other hand, Rust's strong memory safety features make these issues much less likely to occur.&lt;br&gt;
Furthermore, Rust's ownership system guarantees memory safety without sacrificing performance.&lt;br&gt;
This is why a partial migration from C and C++ to Rust is underway.&lt;/p&gt;

&lt;p&gt;[1] &lt;a href="https://googleprojectzero.blogspot.com/p/0day.html" rel="noopener noreferrer"&gt;https://googleprojectzero.blogspot.com/p/0day.html&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Why Rust? #7
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9xlttpaemzxubbnbpcsy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9xlttpaemzxubbnbpcsy.jpg" alt="Why Rust? #7"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, we can point to projects like 'Rust for Linux', which enables implementing Linux kernel modules and device drivers in Rust.&lt;br&gt;
Another significant development is Chrome's ongoing migration of its font handling library from C's FreeType to Rust's Skrifa to ensure safer font processing.&lt;br&gt;
Additionally, in the Postgres ecosystem, Neon is notable for implementing Postgres' storage engine in Rust.&lt;/p&gt;

&lt;p&gt;[2] &lt;a href="https://rust-for-linux.com" rel="noopener noreferrer"&gt;https://rust-for-linux.com&lt;/a&gt;&lt;br&gt;
[3] &lt;a href="https://developer.chrome.com/blog/memory-safety-fonts" rel="noopener noreferrer"&gt;https://developer.chrome.com/blog/memory-safety-fonts&lt;/a&gt;&lt;br&gt;
[4] &lt;a href="https://neon.tech/blog/how-we-scale-an-open-source-multi-tenant-storage-engine-for-postgres-written-rust" rel="noopener noreferrer"&gt;https://neon.tech/blog/how-we-scale-an-open-source-multi-tenant-storage-engine-for-postgres-written-rust&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  What is pgrx? #8
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhe30sfo1yw01979la1xb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhe30sfo1yw01979la1xb.jpg" alt="What is pgrx? #8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, how can we implement Postgres extensions in Rust?&lt;br&gt;
You can easily develop them using pgrx, which is a framework specifically designed for developing Postgres extensions in Rust.&lt;br&gt;
Let me explain the key features of pgrx.&lt;br&gt;
First, pgrx provides an integrated development environment.&lt;br&gt;
Using this environment, you can easily implement Postgres extension features.&lt;br&gt;
Second, it safely exposes the Postgres C API to Rust.&lt;br&gt;
This allows you to securely call Postgres functions from your Rust implementation.&lt;br&gt;
Third, it automatically handles the mapping between Rust types and Postgres types.&lt;br&gt;
For example, if a Rust function returns an &lt;code&gt;i32&lt;/code&gt; type, pgrx converts it to the &lt;code&gt;integer&lt;/code&gt; type;&lt;br&gt;
if it returns an &lt;code&gt;i64&lt;/code&gt; type, it converts it to &lt;code&gt;bigint&lt;/code&gt;;&lt;br&gt;
and if it returns a &lt;code&gt;string&lt;/code&gt; type, it converts it to &lt;code&gt;TEXT&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  Popular PostgreSQL extensions written in Rust #9
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F92s9jqkpkd3cw3so7rfy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F92s9jqkpkd3cw3so7rfy.jpg" alt="Popular PostgreSQL extensions written in Rust #9"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are many popular Postgres extensions written in Rust using pgrx.&lt;br&gt;
ParadeDB is a modern Elasticsearch alternative built on Postgres.&lt;br&gt;
ZomboDB integrates Postgres and Elasticsearch.&lt;br&gt;
PostgresML is a powerful Postgres extension that seamlessly combines data storage and machine learning inference within a database.&lt;br&gt;
PL/Rust is a Rust procedural language handler for Postgres.&lt;/p&gt;

&lt;p&gt;Various other extensions are also being developed, so please refer to GitHub for more details.&lt;/p&gt;

&lt;p&gt;Okey, let's move to next part demo.&lt;/p&gt;


&lt;h3&gt;
  
  
  DEMO #10
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnoup7v006to0qtjepwq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnoup7v006to0qtjepwq.jpg" alt="DEMO #10"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  pgrx: Pros &amp;amp; Cons #11
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxnuafldgkwsnlddperd1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxnuafldgkwsnlddperd1.jpg" alt="pgrx: Pros &amp;amp; Cons #11"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, that's it for the demo.&lt;br&gt;
Based on the explanation so far, I hope you now have a general idea of how to use pgrx.&lt;br&gt;
From this point, I'd like to discuss the pros and cons of pgrx, based on my own experience developing extensions with it.&lt;/p&gt;


&lt;h3&gt;
  
  
  Setting up development environment ✅ #12
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F795hb8c8q1zpbwaxf8an.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F795hb8c8q1zpbwaxf8an.jpg" alt="Setting up development environment ✅ #12"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first point I'd like to introduce is about setting up the development environment.&lt;br&gt;
As you saw in the demo earlier, you can set up the development environment very easily.&lt;br&gt;
With the command &lt;code&gt;cargo pgrx init&lt;/code&gt;, you can set up development environments for all Postgres versions supported by pgrx, from 13 to 17.&lt;br&gt;
You can also create an environment for only a specific version, for example, using a flag like &lt;code&gt;--pg17&lt;/code&gt;.&lt;br&gt;
I believe this feature is very user-friendly, especially for beginners in Postgres extension development.&lt;/p&gt;


&lt;h3&gt;
  
  
  Setting up development environment ❎ #13
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faji61mc5d0bhtmp175tg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faji61mc5d0bhtmp175tg.jpg" alt="Setting up development environment ❎ #13"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, you can only specify major Postgres versions; minor versions cannot be specified.&lt;br&gt;
While you do not often need to worry about minor versions, the ability to specify them would be convenient, for instance, when you want to check the impact of a bug fixed in a specific minor release.&lt;br&gt;
Furthermore, you cannot specify the Postgres master branch, which is currently under development.&lt;br&gt;
Developing a Postgres extension isn't a one-time task; it needs to keep pace with Postgres version upgrades.&lt;br&gt;
When a new major version of Postgres is released, pgrx will likely add support for it eventually.&lt;br&gt;
However, waiting for pgrx to support new major versions after their official release slows down the delivery of updated extensions.&lt;br&gt;
If it were possible to develop extensions against the master branch, I believe pgrx would become an even more practical framework for extension development.&lt;/p&gt;


&lt;h3&gt;
  
  
  Requirements for C-Based Extensions #14
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F263idcsko4jllcg11tf8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F263idcsko4jllcg11tf8.jpg" alt="Requirements for C-Based Extensions #14"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second point I'd like to introduce is automatic SQL generation.&lt;br&gt;
With pgrx, SQL statements like &lt;code&gt;CREATE FUNCTION&lt;/code&gt; can be generated automatically.&lt;br&gt;
But first, let's review how user-defined functions and other components are typically implemented using the traditional C language approach.&lt;/p&gt;

&lt;p&gt;When implementing a user-defined function called &lt;code&gt;func&lt;/code&gt; and providing it as part of an extension using C, you need both a C source file and an SQL file.&lt;br&gt;
On the left, I'm showing the C source file, and on the right is the SQL file.&lt;br&gt;
After implementing the function logic in C, you then define the SQL function using a &lt;code&gt;CREATE FUNCTION&lt;/code&gt; statement that calls the C function.&lt;br&gt;
Furthermore, if your extension provides more complex features like custom types or index support, you also need corresponding SQL definitions such as &lt;code&gt;CREATE OPERATOR&lt;/code&gt;, &lt;code&gt;CREATE OPERATOR CLASS&lt;/code&gt;, or &lt;code&gt;CREATE OPERATOR FAMILY&lt;/code&gt;.&lt;br&gt;
As you can see, this means you need to implement and maintain both the C source file and all these SQL definition files.&lt;/p&gt;


&lt;h3&gt;
  
  
  Automatic SQL generation ✅ #15
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxk5fbil058nb7lv5ecnj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxk5fbil058nb7lv5ecnj.jpg" alt="Automatic SQL generation ✅ #15"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using pgrx, the SQL file is automatically generated based on the Rust function's attributes, argument types, and return value types.&lt;/p&gt;


&lt;h3&gt;
  
  
  Automatic SQL generation ✅ #16
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcuql6dt3pmg6c4b4chu3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcuql6dt3pmg6c4b4chu3.jpg" alt="Automatic SQL generation ✅ #16"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;pg_extern&lt;/code&gt; attribute, you specify parameters equivalent to those used in &lt;code&gt;CREATE FUNCTION&lt;/code&gt;, such as &lt;code&gt;IMMUTABLE&lt;/code&gt;, &lt;code&gt;STRICT&lt;/code&gt;, &lt;code&gt;STABLE&lt;/code&gt;, or &lt;code&gt;VOLATILE&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  Automatic SQL generation ✅ #17
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbemuszdye84ct3hou5cg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbemuszdye84ct3hou5cg.jpg" alt="Automatic SQL generation ✅ #17"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, the Rust function's argument and return value types are mapped directly to the arguments and return type in the generated &lt;code&gt;CREATE FUNCTION&lt;/code&gt; statement.&lt;br&gt;
In this way, automatically generating the SQL reduces the cost of implementing and maintaining SQL files.&lt;/p&gt;


&lt;h3&gt;
  
  
  Automatic SQL generation ✅ #18
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdk1e7mv4bufdsr6tjsxa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdk1e7mv4bufdsr6tjsxa.jpg" alt="Automatic SQL generation ✅ #18"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similar to functions, pgrx can also generate the necessary &lt;code&gt;CREATE FUNCTION&lt;/code&gt; and &lt;code&gt;CREATE OPERATOR&lt;/code&gt; statements for operators.&lt;br&gt;
Just like before, in the &lt;code&gt;pg_operator&lt;/code&gt; attribute, you specify parameters for &lt;code&gt;CREATE FUNCTION&lt;/code&gt;, such as &lt;code&gt;STABLE&lt;/code&gt; or &lt;code&gt;STRICT&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  Automatic SQL generation ✅ #19
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ujvgxc0oms2wjnkdegt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ujvgxc0oms2wjnkdegt.jpg" alt="Automatic SQL generation ✅ #19"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;opname&lt;/code&gt; attribute, you specify the desired operator name.&lt;br&gt;
In the &lt;code&gt;restrict&lt;/code&gt; and &lt;code&gt;join&lt;/code&gt; attributes, you specify operator-specific parameters.&lt;/p&gt;


&lt;h3&gt;
  
  
  Automatic SQL generation ❎ #20
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzqr5b5n9k4ckkiptcsea.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzqr5b5n9k4ckkiptcsea.jpg" alt="Automatic SQL generation ❎ #20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Automatic SQL generation is also available for operator classes, similar to functions and operators.&lt;br&gt;
However, this capability is currently restricted to B-tree and Hash indexes only.&lt;br&gt;
Support for other index types like GIN, GiST, and SP-GiST is currently lacking, which is an important limitation to consider.&lt;br&gt;
For instance, an extension I developed required GIN indexes, so this auto-generation feature wasn't applicable, and I needed to write the necessary SQL definitions directly.&lt;/p&gt;


&lt;h3&gt;
  
  
  Memory management in C/PostgreSQL #21
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fls60rmwfik98lwio60xh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fls60rmwfik98lwio60xh.jpg" alt="Memory management in C/PostgreSQL #21"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The third point I'd like to introduce is memory management.&lt;/p&gt;

&lt;p&gt;Memory management in the C language requires explicit memory allocation and deallocation using malloc and free.&lt;br&gt;
Postgres' implementation, uses a region-based system for memory management, utilizing &lt;code&gt;MemoryContexts&lt;/code&gt;.&lt;br&gt;
This involves creating these &lt;code&gt;MemoryContexts&lt;/code&gt; and allocating memory associated with a specific context.&lt;br&gt;
To free memory, you simply delete the &lt;code&gt;MemoryContext&lt;/code&gt;, which releases all memory associated with it at once.&lt;br&gt;
In this way, Postgres provides an implementation for efficient and relatively easy memory management.&lt;br&gt;
However, even with this system, developers still need to be careful about issues like memory leaks, double frees, and dangling pointers.&lt;/p&gt;


&lt;h3&gt;
  
  
  Memory management in Rust #22
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Futa6rrwu082wka19zpmq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Futa6rrwu082wka19zpmq.jpg" alt="Memory management in Rust #22"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, I will very briefly explain Rust's memory management.&lt;br&gt;
Rust manages memory using a concept called the ownership system, which has three main rules:&lt;br&gt;
Each value in Rust has an owner.&lt;br&gt;
There can only be one owner at a time.&lt;br&gt;
When the owner goes out of scope, the value will be dropped.&lt;/p&gt;


&lt;h3&gt;
  
  
  Memory management in Rust #23
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff52xl2bit6mk6b97fgm9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff52xl2bit6mk6b97fgm9.jpg" alt="Memory management in Rust #23"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As shown in this diagram, when &lt;code&gt;s1&lt;/code&gt; is declared, &lt;code&gt;s1&lt;/code&gt; becomes the owner of the &lt;code&gt;hello&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  Memory management in Rust #24
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuoolj407jw0x5ncr85be.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuoolj407jw0x5ncr85be.jpg" alt="Memory management in Rust #24"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similarly, &lt;code&gt;s2&lt;/code&gt; becomes the owner of &lt;code&gt;world&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  Memory management in Rust #25
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8eslwnvtmw9lqu43rfbj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8eslwnvtmw9lqu43rfbj.jpg" alt="Memory management in Rust #25"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, &lt;code&gt;s2&lt;/code&gt; goes out of scope and then is dropped, freeing its memory.&lt;/p&gt;


&lt;h3&gt;
  
  
  Memory management in Rust #26
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwfjggazqjelkxofs4dcp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwfjggazqjelkxofs4dcp.jpg" alt="Memory management in Rust #26"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Likewise, &lt;code&gt;s1&lt;/code&gt; goes out of scope and is dropped, freeing its memory.&lt;/p&gt;


&lt;h3&gt;
  
  
  Memory management in Rust ✅ #27
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgs2vf18quk06qor7kahw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgs2vf18quk06qor7kahw.jpg" alt="Memory management in Rust ✅ #27"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;pgrx's memory management system is designed to bridge the gap between Postgres' MemoryContexts and Rust's ownership.&lt;br&gt;
Specifically, deallocation of pointers received from the C API is handled by Postgres.&lt;br&gt;
Conversely, objects created in Rust are deallocated by Rust itself, based on its ownership rules.&lt;br&gt;
To help safely manage pointers allocated by C from within Rust, pgrx provides the &lt;code&gt;PgBox&lt;/code&gt; type.&lt;/p&gt;


&lt;h3&gt;
  
  
  Memory management in Rust ❎ #28
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpf84g2unytfg1e1cfuc1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpf84g2unytfg1e1cfuc1.jpg" alt="Memory management in Rust ❎ #28"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's already difficult to understand C and Postgres memory management and Rust's memory management individually.&lt;br&gt;
Then, you also need to learn pgrx memory management.&lt;br&gt;
This makes it much harder.&lt;br&gt;
Let me give some difficult examples.&lt;br&gt;
One is handling memory created in C from your Rust code. Another is passing Rust memory to C and telling Rust not to free it, which goes against Rust's ownership system.&lt;/p&gt;


&lt;h3&gt;
  
  
  Toolchain ✅ #29
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqj1oa4criwp0tt2y0bdi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqj1oa4criwp0tt2y0bdi.jpg" alt="Toolchain ✅ #29"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The fourth point I'd like to introduce is toolchain.&lt;br&gt;
When developing with pgrx, you directly benefit from the rich Rust ecosystem, particularly its excellent toolchain.&lt;br&gt;
This familiarity offers great convenience.&lt;br&gt;
For instance, you have &lt;code&gt;cargo clippy&lt;/code&gt; for Linting to help write more robust and idiomatic Rust.&lt;br&gt;
Code style consistency is easily maintained using &lt;code&gt;cargo fmt&lt;/code&gt; for automatic Formatting.&lt;br&gt;
And crucially for extensions, &lt;code&gt;cargo pgrx test&lt;/code&gt; provides a streamlined way to handle integration testing directly against Postgres.&lt;br&gt;
This ability to use standard Rust tooling really makes the development workflow much smoother.&lt;/p&gt;


&lt;h3&gt;
  
  
  Toolchain ❎ #30
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F493zbl7i7n50j2q0kqb9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F493zbl7i7n50j2q0kqb9.jpg" alt="Toolchain ❎ #30"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's look at a point marked here as a challenge, which relates to toolchain integration.&lt;br&gt;
While the Rust side is well-supported, there's currently weaker integration with some traditional Postgres tools.&lt;br&gt;
Specifically, as noted here, there isn't direct integration with &lt;code&gt;pg_regress&lt;/code&gt;, the standard framework for running SQL-level regression tests in the Postgres ecosystem.&lt;br&gt;
While pgrx provides its own testing mechanism, it doesn't replace the &lt;code&gt;pg_regress&lt;/code&gt; workflow.&lt;br&gt;
This is a recognized limitation, as shown by the GitHub issues listed on the slide.&lt;br&gt;
For now, this means that setting up &lt;code&gt;pg_regress&lt;/code&gt;-style tests might require separate configuration.&lt;/p&gt;

&lt;p&gt;Note: &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ytqizsvctd4yibcaps2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ytqizsvctd4yibcaps2.png" alt="ZomboDB"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[5] &lt;a href="https://github.com/pgcentralfoundation/pgrx/issues/284" rel="noopener noreferrer"&gt;https://github.com/pgcentralfoundation/pgrx/issues/284&lt;/a&gt;&lt;br&gt;
[6] &lt;a href="https://github.com/pgcentralfoundation/pgrx/issues/1511" rel="noopener noreferrer"&gt;https://github.com/pgcentralfoundation/pgrx/issues/1511&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Documentation ✅ #31
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo22eji2xwu6otx0m6kr3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo22eji2xwu6otx0m6kr3.jpg" alt="Documentation ✅ #31"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The fifth point I'd like to introduce is documentation.&lt;/p&gt;

&lt;p&gt;While learning pgrx involves navigating different memory models as we discussed, there are several excellent resources available to help you.&lt;br&gt;
Let me highlight the key ones shown on this slide.&lt;br&gt;
First, for the specific details of the pgrx crate's functions, types, and macros, your primary reference is &lt;code&gt;Docs.rs&lt;/code&gt;, which is the API documentation.&lt;br&gt;
Next, &lt;code&gt;The PGRX Book&lt;/code&gt; serves as the official guide and documentation.&lt;br&gt;
This is the best place to understand core concepts, learn how to set up your environment, and follow tutorials.&lt;br&gt;
Finally, if you want to see practical examples and common patterns, the &lt;code&gt;pgrx-examples&lt;/code&gt; is invaluable.&lt;br&gt;
It contains various code examples that you can learn from and adapt.&lt;br&gt;
I highly recommend utilizing these resources as you explore pgrx development.&lt;/p&gt;

&lt;p&gt;[7] &lt;a href="https://docs.rs/pgrx/latest/pgrx/" rel="noopener noreferrer"&gt;https://docs.rs/pgrx/latest/pgrx/&lt;/a&gt;&lt;br&gt;
[8] &lt;a href="https://github.com/pgcentralfoundation/pgrx/blob/develop/docs/src/SUMMARY.md" rel="noopener noreferrer"&gt;https://github.com/pgcentralfoundation/pgrx/blob/develop/docs/src/SUMMARY.md&lt;/a&gt;&lt;br&gt;
[9] &lt;a href="https://github.com/pgcentralfoundation/pgrx/tree/develop/pgrx-examples" rel="noopener noreferrer"&gt;https://github.com/pgcentralfoundation/pgrx/tree/develop/pgrx-examples&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Documentation ❎ #32
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbhio3ab8rwmuiefx56f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbhio3ab8rwmuiefx56f.jpg" alt="Documentation ❎ #32"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While resources are growing, it's true that there is currently less information available for pgrx development compared to the vast resources accumulated over many years for traditional C extensions.&lt;br&gt;
So, because there isn't enough documentation or examples yet, development can still be quite hard sometimes.&lt;br&gt;
This is especially true for complex problems or unusual situations.&lt;/p&gt;

&lt;p&gt;I hope this presentation was helpful for you.&lt;/p&gt;


&lt;h3&gt;
  
  
  PostgreSQL &amp;amp; Rust: Core vs. Extensions #33
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvuskqq31v4azw6z9jrfd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvuskqq31v4azw6z9jrfd.jpg" alt="PostgreSQL &amp;amp; Rust: Core vs. Extensions #33"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, let's discuss the future of Postgres and Rust.&lt;br&gt;
There have been multiple proposals in the past suggesting the use of Rust for implementing Postgres' core.&lt;br&gt;
However, due to various reasons, the adoption of Rust for the core has been deferred, so the chance of this happening is quite low.&lt;br&gt;
For example, there's the huge existing C codebase, Postgres' unique memory management system, and its specific error handling mechanisms (like &lt;code&gt;PG_TRY()&lt;/code&gt;).&lt;br&gt;
Additionally, Postgres needs to support a wide range of platforms, which presents portability challenges.&lt;br&gt;
But, as mentioned in this talk, Rust-based Postgres extensions are expected to grow substantially in the future.&lt;/p&gt;

&lt;p&gt;[10] &lt;a href="https://www.postgresql.org/message-id/flat/CAASwCXdQUiuUnhycdRvrUmHuzk5PsaGxr54U4t34teQjcjb%3DAQ%40mail.gmail.com" rel="noopener noreferrer"&gt;https://www.postgresql.org/message-id/flat/CAASwCXdQUiuUnhycdRvrUmHuzk5PsaGxr54U4t34teQjcjb%3DAQ%40mail.gmail.com&lt;/a&gt;&lt;br&gt;
[11] &lt;a href="https://www.postgresql.org/message-id/flat/CANvSX4wsVhDrqy4Ku81wHs--aViYthJ_G5G-2VeZ%3DJboEE9TNQ%40mail.gmail.com" rel="noopener noreferrer"&gt;https://www.postgresql.org/message-id/flat/CANvSX4wsVhDrqy4Ku81wHs--aViYthJ_G5G-2VeZ%3DJboEE9TNQ%40mail.gmail.com&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Summary #34
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqe3u5bzclemsu7gkdegu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqe3u5bzclemsu7gkdegu.jpg" alt="Summary #34"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, let's quickly summarize the main points of this presentation.&lt;br&gt;
First, I explained how you can implement Postgres extensions using Rust with the help of pgrx.&lt;br&gt;
We also took some time to discuss the pros and cons of using the pgrx framework.&lt;br&gt;
pgrx offers a powerful way to build extensions.&lt;br&gt;
So, let's try it out!&lt;br&gt;
Thank you.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pgcentralfoundation" rel="noopener noreferrer"&gt;
        pgcentralfoundation
      &lt;/a&gt; / &lt;a href="https://github.com/pgcentralfoundation/pgrx" rel="noopener noreferrer"&gt;
        pgrx
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Build Postgres Extensions with Rust!
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/pgcentralfoundation/pgrx/art/pgrx-logo-color-transparent-475x518.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fpgcentralfoundation%2Fpgrx%2Fart%2Fpgrx-logo-color-transparent-475x518.png" alt="Logo"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;&lt;code&gt;pgrx&lt;/code&gt;&lt;/h1&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Build Postgres Extensions with Rust!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/pgcentralfoundation/pgrx/actions/workflows/tests.yml/badge.svg"&gt;&lt;img src="https://github.com/pgcentralfoundation/pgrx/actions/workflows/tests.yml/badge.svg" alt="GitHub Actions badge"&gt;&lt;/a&gt;
&lt;a href="https://crates.io/crates/pgrx" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/99e06646c53f817aa78f17cac0bd53fda91120bcaf1336292790ac89f503dc33/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f706772782e737667" alt="crates.io badge"&gt;&lt;/a&gt;
&lt;a href="https://docs.rs/pgrx" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/23969544fca769150685fb9b1f7a3c74eae4866794f6433bd927f44e32f82415/68747470733a2f2f646f63732e72732f706772782f62616467652e737667" alt="docs.rs badge"&gt;&lt;/a&gt;
&lt;a href="https://twitter.com/pgrx_rs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/dde012f821d1bef601e2cbf1092fdc0fa11771a2faa1836d6531d5d67437591f/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f706772785f72732e7376673f7374796c653d666c6174" alt="Twitter Follow"&gt;&lt;/a&gt;
&lt;a href="https://discord.gg/PMrpdJsqcJ" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9bda38284ad7e291d08e8b0d26d6e0246d9f055d53c3d6a43b623000a060959d/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f3731303931383534353930363539373933382e737667" alt="Discord Chat"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pgrx&lt;/code&gt; is a framework for developing PostgreSQL extensions in Rust and strives to be as idiomatic and safe as possible.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pgrx&lt;/code&gt; supports Postgres 13 through Postgres 18.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Want to chat with us or get a question answered?&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Please join our &lt;a href="https://discord.gg/PMrpdJsqcJ" rel="nofollow noopener noreferrer"&gt;Discord Server&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;We are also in need of financial &lt;a href="https://checkout.square.site/merchant/MLHG5M9GAXQPV/checkout/2OW2SULDQBSZ2JLHSLRZQLZH" rel="nofollow noopener noreferrer"&gt;sponsorship&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Key Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A fully managed development environment with &lt;a href="https://github.com/pgcentralfoundation/pgrx/cargo-pgrx/README.md" rel="noopener noreferrer"&gt;&lt;code&gt;cargo-pgrx&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cargo pgrx new&lt;/code&gt;: Create new extensions quickly&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cargo pgrx init&lt;/code&gt;: Install new (or register existing) PostgreSQL installs&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cargo pgrx run&lt;/code&gt;: Run your extension and interactively test it in &lt;code&gt;psql&lt;/code&gt; (or &lt;code&gt;pgcli&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cargo pgrx test&lt;/code&gt;: Unit-test your extension across multiple PostgreSQL versions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cargo pgrx package&lt;/code&gt;: Create installation packages for your extension&lt;/li&gt;
&lt;li&gt;More in the &lt;a href="https://github.com/pgcentralfoundation/pgrx/cargo-pgrx/README.md" rel="noopener noreferrer"&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/a&gt;!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Target Multiple Postgres Versions&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Support from Postgres 13 to Postgres 17 from the same codebase&lt;/li&gt;
&lt;li&gt;Use Rust feature gating to use version-specific…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/pgcentralfoundation/pgrx" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




</description>
      <category>postgres</category>
      <category>rust</category>
      <category>pgrx</category>
    </item>
  </channel>
</rss>
