agora inbox for pgsql-hackers@postgresql.org  
help / color / mirror / Atom feed
[PATCH v1] popcount
4+ messages / 2 participants
[nested] [flat]

* [PATCH v1] popcount
@ 2020-12-30 10:51 David Fetter <david@fetter.org>
  0 siblings, 0 replies; 4+ messages in thread

From: David Fetter @ 2020-12-30 10:51 UTC (permalink / raw)


Now it's accessible to SQL for the BIT VARYING and BYTEA types.

diff --git doc/src/sgml/func.sgml doc/src/sgml/func.sgml
index 5021ac1ca9..439a3a4a06 100644
--- doc/src/sgml/func.sgml
+++ doc/src/sgml/func.sgml
@@ -4069,6 +4069,23 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
        </para></entry>
       </row>
 
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <indexterm>
+         <primary>popcount</primary>
+        </indexterm>
+        <function>popcount</function> ( <parameter>bytes</parameter> <type>bytea</type> )
+        <returnvalue>integer</returnvalue>
+       </para>
+       <para>
+        Counts the number of bits set in a binary string.
+       </para>
+       <para>
+        <literal>popcount('\xdeadbeef'::bytea)</literal>
+        <returnvalue>24</returnvalue>
+       </para></entry>
+      </row>
+
       <row>
        <entry role="func_table_entry"><para role="func_signature">
         <indexterm>
@@ -4830,6 +4847,24 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
         <returnvalue>101010001010101010</returnvalue>
        </para></entry>
       </row>
+
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <indexterm>
+         <primary>popcount</primary>
+        </indexterm>
+        <function>popcount</function> ( <parameter>bits</parameter> <type>bit</type> )
+        <returnvalue>int4</returnvalue>
+       </para>
+       <para>
+        Counts the bits set in a bit string.
+       </para>
+       <para>
+        <literal>popcount(B'101010101010101010')</literal>
+        <returnvalue>9</returnvalue>
+       </para></entry>
+      </row>
+
      </tbody>
     </tgroup>
    </table>
diff --git src/include/catalog/pg_proc.dat src/include/catalog/pg_proc.dat
index 139f4a08bd..0e6d0636fa 100644
--- src/include/catalog/pg_proc.dat
+++ src/include/catalog/pg_proc.dat
@@ -1446,6 +1446,9 @@
 { oid => '752', descr => 'substitute portion of string',
   proname => 'overlay', prorettype => 'bytea',
   proargtypes => 'bytea bytea int4', prosrc => 'byteaoverlay_no_len' },
+{ oid => '8436', descr => 'count set bits',
+  proname => 'popcount', prorettype => 'int4', proargtypes => 'bytea',
+  prosrc => 'byteapopcount'},
 
 { oid => '725',
   proname => 'dist_pl', prorettype => 'float8', proargtypes => 'point line',
@@ -3865,6 +3868,9 @@
 { oid => '3033', descr => 'set bit',
   proname => 'set_bit', prorettype => 'bit', proargtypes => 'bit int4 int4',
   prosrc => 'bitsetbit' },
+{ oid => '8435', descr => 'count set bits',
+  proname => 'popcount', prorettype => 'int4', proargtypes => 'bit',
+  prosrc => 'bitpopcount'},
 
 # for macaddr type support
 { oid => '436', descr => 'I/O',
diff --git src/backend/utils/adt/varbit.c src/backend/utils/adt/varbit.c
index 3c03459f51..e92d1a7f8f 100644
--- src/backend/utils/adt/varbit.c
+++ src/backend/utils/adt/varbit.c
@@ -29,6 +29,8 @@
  *-------------------------------------------------------------------------
  */
 
+#include <math.h>
+
 #include "postgres.h"
 
 #include "access/htup_details.h"
@@ -36,6 +38,7 @@
 #include "libpq/pqformat.h"
 #include "nodes/nodeFuncs.h"
 #include "nodes/supportnodes.h"
+#include "port/pg_bitutils.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/varbit.h"
@@ -1872,3 +1875,24 @@ bitgetbit(PG_FUNCTION_ARGS)
 	else
 		PG_RETURN_INT32(0);
 }
+
+/*
+ * bitpopcount
+ *
+ * Returns the number of bits set in a bit array.
+ *
+ */
+Datum
+bitpopcount(PG_FUNCTION_ARGS)
+{
+	VarBit		*arg1 = PG_GETARG_VARBIT_P(0);
+	bits8		*p;
+	int			len, popcount;
+
+	len = ceil(VARBITLEN(arg1) / (float4)BITS_PER_BYTE);
+	p = VARBITS(arg1);
+
+	popcount = (int)pg_popcount((const char *)p, len);
+
+	PG_RETURN_INT32(popcount);
+}
diff --git src/backend/utils/adt/varlena.c src/backend/utils/adt/varlena.c
index 9300d19e0c..9e788babd3 100644
--- src/backend/utils/adt/varlena.c
+++ src/backend/utils/adt/varlena.c
@@ -3415,6 +3415,21 @@ bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
 	return result;
 }
 
+/*
+ * popcount
+ */
+Datum
+byteapopcount(PG_FUNCTION_ARGS)
+{
+	bytea	*t1 = PG_GETARG_BYTEA_PP(0);
+	int		len, result;
+
+	len = VARSIZE_ANY_EXHDR(t1);
+	result = pg_popcount(VARDATA_ANY(t1), len);
+
+	PG_RETURN_INT32(result);
+}
+
 /*
  * byteapos -
  *	  Return the position of the specified substring.
diff --git src/test/regress/expected/bit.out src/test/regress/expected/bit.out
index a1fab7ebcb..c91ad3d0d5 100644
--- src/test/regress/expected/bit.out
+++ src/test/regress/expected/bit.out
@@ -681,6 +681,19 @@ SELECT overlay(B'0101011100' placing '001' from 20);
  0101011100001
 (1 row)
 
+-- Popcount
+SELECT popcount(B'0101011100'::bit(10));
+ popcount 
+----------
+        5
+(1 row)
+
+SELECT popcount(B'1111111111'::bit(10));
+ popcount 
+----------
+       10
+(1 row)
+
 -- This table is intentionally left around to exercise pg_dump/pg_upgrade
 CREATE TABLE bit_defaults(
   b1 bit(4) DEFAULT '1001',
diff --git src/test/regress/expected/strings.out src/test/regress/expected/strings.out
index 298b6c48c2..9780639038 100644
--- src/test/regress/expected/strings.out
+++ src/test/regress/expected/strings.out
@@ -2126,3 +2126,10 @@ SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 5
  Th\000o\x02\x03
 (1 row)
 
+SET bytea_output TO hex;
+SELECT popcount(E'\\xdeadbeef'::bytea);
+ popcount 
+----------
+       24
+(1 row)
+
diff --git src/test/regress/sql/bit.sql src/test/regress/sql/bit.sql
index 7681d4ab4d..3cd9fb65d3 100644
--- src/test/regress/sql/bit.sql
+++ src/test/regress/sql/bit.sql
@@ -207,6 +207,10 @@ SELECT overlay(B'0101011100' placing '101' from 6);
 SELECT overlay(B'0101011100' placing '001' from 11);
 SELECT overlay(B'0101011100' placing '001' from 20);
 
+-- Popcount
+SELECT popcount(B'0101011100'::bit(10));
+SELECT popcount(B'1111111111'::bit(10));
+
 -- This table is intentionally left around to exercise pg_dump/pg_upgrade
 CREATE TABLE bit_defaults(
   b1 bit(4) DEFAULT '1001',
diff --git src/test/regress/sql/strings.sql src/test/regress/sql/strings.sql
index ad5221ab6b..a35e993ab0 100644
--- src/test/regress/sql/strings.sql
+++ src/test/regress/sql/strings.sql
@@ -717,3 +717,6 @@ SELECT btrim(E'\\000trim\\000'::bytea, ''::bytea);
 SELECT encode(overlay(E'Th\\000omas'::bytea placing E'Th\\001omas'::bytea from 2),'escape');
 SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 8),'escape');
 SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 5 for 3),'escape');
+
+SET bytea_output TO hex;
+SELECT popcount(E'\\xdeadbeef'::bytea);


^ permalink  raw  reply  [nested|flat] 4+ messages in thread

* [PATCH v5] popcount
@ 2020-12-30 10:51 David Fetter <david@fetter.org>
  0 siblings, 0 replies; 4+ messages in thread

From: David Fetter @ 2020-12-30 10:51 UTC (permalink / raw)


Now it's accessible to SQL for the BIT VARYING and BYTEA types.

diff --git doc/src/sgml/func.sgml doc/src/sgml/func.sgml
index 68fe6a95b4..066431fd3c 100644
--- doc/src/sgml/func.sgml
+++ doc/src/sgml/func.sgml
@@ -4030,6 +4030,23 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
       </para></entry>
      </row>
 
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <indexterm>
+         <primary>bit_count</primary>
+        </indexterm>
+        <function>bit_count</function> ( <parameter>bytes</parameter> <type>bytea</type> )
+        <returnvalue>bigint</returnvalue>
+       </para>
+       <para>
+        Counts the number of bits set in a binary string.
+       </para>
+       <para>
+        <literal>bit_count('\xdeadbeef'::bytea)</literal>
+        <returnvalue>24</returnvalue>
+       </para></entry>
+      </row>
+
       <row>
        <entry role="func_table_entry"><para role="func_signature">
         <indexterm>
@@ -4830,6 +4847,23 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
        </para></entry>
       </row>
 
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <indexterm>
+         <primary>bit_count</primary>
+        </indexterm>
+        <function>bit_count</function> ( <parameter>bits</parameter> <type>bit</type> )
+        <returnvalue>bigint</returnvalue>
+       </para>
+       <para>
+        Counts the bits set in a bit string.
+       </para>
+       <para>
+        <literal>bit_count(B'101010101010101010')</literal>
+        <returnvalue>9</returnvalue>
+       </para></entry>
+      </row>
+
       <row>
        <entry role="func_table_entry"><para role="func_signature">
         <indexterm>
@@ -4869,6 +4903,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
         <returnvalue>101010001010101010</returnvalue>
        </para></entry>
       </row>
+
      </tbody>
     </tgroup>
    </table>
diff --git src/include/catalog/pg_proc.dat src/include/catalog/pg_proc.dat
index e259531f60..feb00eccf9 100644
--- src/include/catalog/pg_proc.dat
+++ src/include/catalog/pg_proc.dat
@@ -1446,6 +1446,9 @@
 { oid => '752', descr => 'substitute portion of string',
   proname => 'overlay', prorettype => 'bytea',
   proargtypes => 'bytea bytea int4', prosrc => 'byteaoverlay_no_len' },
+{ oid => '8436', descr => 'count set bits',
+  proname => 'bit_count', prorettype => 'int8', proargtypes => 'bytea',
+  prosrc => 'byteapopcount'},
 
 { oid => '725',
   proname => 'dist_pl', prorettype => 'float8', proargtypes => 'point line',
@@ -3876,6 +3879,9 @@
 { oid => '3033', descr => 'set bit',
   proname => 'set_bit', prorettype => 'bit', proargtypes => 'bit int4 int4',
   prosrc => 'bitsetbit' },
+{ oid => '8435', descr => 'count set bits',
+  proname => 'bit_count', prorettype => 'int8', proargtypes => 'bit',
+  prosrc => 'bitpopcount'},
 
 # for macaddr type support
 { oid => '436', descr => 'I/O',
diff --git src/backend/utils/adt/varbit.c src/backend/utils/adt/varbit.c
index 2235866244..c9c6c73422 100644
--- src/backend/utils/adt/varbit.c
+++ src/backend/utils/adt/varbit.c
@@ -36,6 +36,7 @@
 #include "libpq/pqformat.h"
 #include "nodes/nodeFuncs.h"
 #include "nodes/supportnodes.h"
+#include "port/pg_bitutils.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/varbit.h"
@@ -1878,3 +1879,30 @@ bitgetbit(PG_FUNCTION_ARGS)
 	else
 		PG_RETURN_INT32(0);
 }
+
+/*
+ * bitpopcount
+ *
+ * Returns the number of bits set in a bit string.
+ *
+ */
+Datum
+bitpopcount(PG_FUNCTION_ARGS)
+{
+	/* There's really no chance of an overflow here because
+	 * to get to INT64_MAX set bits, an object would have to be
+	 * an exbibyte long, exceeding what PostgreSQL can currently
+	 * store by a factor of 2^28
+	 */
+	int64		popcount;
+	VarBit		*arg1 = PG_GETARG_VARBIT_P(0);
+	bits8		*p;
+	int			len;
+
+	p = VARBITS(arg1);
+	len = (VARBITLEN(arg1) + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
+
+	popcount = pg_popcount((char *)p, len);
+
+	PG_RETURN_INT64(popcount);
+}
diff --git src/backend/utils/adt/varlena.c src/backend/utils/adt/varlena.c
index 0bc345aa4d..95091887a9 100644
--- src/backend/utils/adt/varlena.c
+++ src/backend/utils/adt/varlena.c
@@ -3440,6 +3440,22 @@ bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
 	return result;
 }
 
+/*
+ * popcount
+ */
+Datum
+byteapopcount(PG_FUNCTION_ARGS)
+{
+	bytea	*t1 = PG_GETARG_BYTEA_PP(0);
+	int		len;
+	int64	result;
+
+	len = VARSIZE_ANY_EXHDR(t1);
+	result = pg_popcount(VARDATA_ANY(t1), len);
+
+	PG_RETURN_INT64(result);
+}
+
 /*
  * byteapos -
  *	  Return the position of the specified substring.
diff --git src/test/regress/expected/bit.out src/test/regress/expected/bit.out
index a7f95b846d..9b6b3d0c4f 100644
--- src/test/regress/expected/bit.out
+++ src/test/regress/expected/bit.out
@@ -710,6 +710,19 @@ SELECT overlay(B'0101011100' placing '001' from 20);
  0101011100001
 (1 row)
 
+-- Popcount
+SELECT bit_count(B'0101011100'::bit(10));
+ bit_count 
+-----------
+         5
+(1 row)
+
+SELECT bit_count(B'1111111111'::bit(10));
+ bit_count 
+-----------
+        10
+(1 row)
+
 -- This table is intentionally left around to exercise pg_dump/pg_upgrade
 CREATE TABLE bit_defaults(
   b1 bit(4) DEFAULT '1001',
diff --git src/test/regress/expected/strings.out src/test/regress/expected/strings.out
index fb4573d85f..e8c6a99e9d 100644
--- src/test/regress/expected/strings.out
+++ src/test/regress/expected/strings.out
@@ -2227,3 +2227,10 @@ SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 5
  Th\000o\x02\x03
 (1 row)
 
+SET bytea_output TO hex;
+SELECT bit_count(E'\\xdeadbeef'::bytea);
+ bit_count 
+-----------
+        24
+(1 row)
+
diff --git src/test/regress/sql/bit.sql src/test/regress/sql/bit.sql
index ea01742c4a..271aa5ea3c 100644
--- src/test/regress/sql/bit.sql
+++ src/test/regress/sql/bit.sql
@@ -215,6 +215,10 @@ SELECT overlay(B'0101011100' placing '101' from 6);
 SELECT overlay(B'0101011100' placing '001' from 11);
 SELECT overlay(B'0101011100' placing '001' from 20);
 
+-- Popcount
+SELECT bit_count(B'0101011100'::bit(10));
+SELECT bit_count(B'1111111111'::bit(10));
+
 -- This table is intentionally left around to exercise pg_dump/pg_upgrade
 CREATE TABLE bit_defaults(
   b1 bit(4) DEFAULT '1001',
diff --git src/test/regress/sql/strings.sql src/test/regress/sql/strings.sql
index 57a48c9d0b..3fb2d66a9f 100644
--- src/test/regress/sql/strings.sql
+++ src/test/regress/sql/strings.sql
@@ -742,3 +742,6 @@ SELECT btrim(E'\\000trim\\000'::bytea, ''::bytea);
 SELECT encode(overlay(E'Th\\000omas'::bytea placing E'Th\\001omas'::bytea from 2),'escape');
 SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 8),'escape');
 SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 5 for 3),'escape');
+
+SET bytea_output TO hex;
+SELECT bit_count(E'\\xdeadbeef'::bytea);


^ permalink  raw  reply  [nested|flat] 4+ messages in thread

* [PATCH v2] popcount
@ 2020-12-30 10:51 David Fetter <david@fetter.org>
  0 siblings, 0 replies; 4+ messages in thread

From: David Fetter @ 2020-12-30 10:51 UTC (permalink / raw)


Now it's accessible to SQL for the BIT VARYING and BYTEA types.

diff --git doc/src/sgml/func.sgml doc/src/sgml/func.sgml
index 5021ac1ca9..439a3a4a06 100644
--- doc/src/sgml/func.sgml
+++ doc/src/sgml/func.sgml
@@ -4069,6 +4069,23 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
        </para></entry>
       </row>
 
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <indexterm>
+         <primary>popcount</primary>
+        </indexterm>
+        <function>popcount</function> ( <parameter>bytes</parameter> <type>bytea</type> )
+        <returnvalue>integer</returnvalue>
+       </para>
+       <para>
+        Counts the number of bits set in a binary string.
+       </para>
+       <para>
+        <literal>popcount('\xdeadbeef'::bytea)</literal>
+        <returnvalue>24</returnvalue>
+       </para></entry>
+      </row>
+
       <row>
        <entry role="func_table_entry"><para role="func_signature">
         <indexterm>
@@ -4830,6 +4847,24 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
         <returnvalue>101010001010101010</returnvalue>
        </para></entry>
       </row>
+
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <indexterm>
+         <primary>popcount</primary>
+        </indexterm>
+        <function>popcount</function> ( <parameter>bits</parameter> <type>bit</type> )
+        <returnvalue>int4</returnvalue>
+       </para>
+       <para>
+        Counts the bits set in a bit string.
+       </para>
+       <para>
+        <literal>popcount(B'101010101010101010')</literal>
+        <returnvalue>9</returnvalue>
+       </para></entry>
+      </row>
+
      </tbody>
     </tgroup>
    </table>
diff --git src/include/catalog/pg_proc.dat src/include/catalog/pg_proc.dat
index 139f4a08bd..82e3d50114 100644
--- src/include/catalog/pg_proc.dat
+++ src/include/catalog/pg_proc.dat
@@ -1446,6 +1446,9 @@
 { oid => '752', descr => 'substitute portion of string',
   proname => 'overlay', prorettype => 'bytea',
   proargtypes => 'bytea bytea int4', prosrc => 'byteaoverlay_no_len' },
+{ oid => '8436', descr => 'count set bits',
+  proname => 'popcount', prorettype => 'int8', proargtypes => 'bytea',
+  prosrc => 'byteapopcount'},
 
 { oid => '725',
   proname => 'dist_pl', prorettype => 'float8', proargtypes => 'point line',
@@ -3865,6 +3868,9 @@
 { oid => '3033', descr => 'set bit',
   proname => 'set_bit', prorettype => 'bit', proargtypes => 'bit int4 int4',
   prosrc => 'bitsetbit' },
+{ oid => '8435', descr => 'count set bits',
+  proname => 'popcount', prorettype => 'int8', proargtypes => 'bit',
+  prosrc => 'bitpopcount'},
 
 # for macaddr type support
 { oid => '436', descr => 'I/O',
diff --git src/backend/utils/adt/varbit.c src/backend/utils/adt/varbit.c
index 3c03459f51..a71c2b6bf4 100644
--- src/backend/utils/adt/varbit.c
+++ src/backend/utils/adt/varbit.c
@@ -36,6 +36,7 @@
 #include "libpq/pqformat.h"
 #include "nodes/nodeFuncs.h"
 #include "nodes/supportnodes.h"
+#include "port/pg_bitutils.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/varbit.h"
@@ -1872,3 +1873,29 @@ bitgetbit(PG_FUNCTION_ARGS)
 	else
 		PG_RETURN_INT32(0);
 }
+
+/*
+ * bitpopcount
+ *
+ * Returns the number of bits set in a bit array.
+ *
+ */
+Datum
+bitpopcount(PG_FUNCTION_ARGS)
+{
+	VarBit		*arg1 = PG_GETARG_VARBIT_P(0);
+	bits8		*p;
+	int			len;
+	int8		popcount;
+
+	/*
+	 * ceil(VARBITLEN(ARG1)/BITS_PER_BYTE)
+	 * done to minimize branches and instructions.
+	 */
+	len = (VARBITLEN(arg1) + BITS_PER_BYTE + 1) / BITS_PER_BYTE;
+	p = VARBITS(arg1);
+
+	popcount = pg_popcount((const char *)p, len);
+
+	PG_RETURN_INT64(popcount);
+}
diff --git src/backend/utils/adt/varlena.c src/backend/utils/adt/varlena.c
index 9300d19e0c..9c5e5b5592 100644
--- src/backend/utils/adt/varlena.c
+++ src/backend/utils/adt/varlena.c
@@ -3415,6 +3415,22 @@ bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
 	return result;
 }
 
+/*
+ * popcount
+ */
+Datum
+byteapopcount(PG_FUNCTION_ARGS)
+{
+	bytea	*t1 = PG_GETARG_BYTEA_PP(0);
+	int		len;
+	int8	result;
+
+	len = VARSIZE_ANY_EXHDR(t1);
+	result = pg_popcount(VARDATA_ANY(t1), len);
+
+	PG_RETURN_INT64(result);
+}
+
 /*
  * byteapos -
  *	  Return the position of the specified substring.
diff --git src/test/regress/expected/bit.out src/test/regress/expected/bit.out
index a1fab7ebcb..c91ad3d0d5 100644
--- src/test/regress/expected/bit.out
+++ src/test/regress/expected/bit.out
@@ -681,6 +681,19 @@ SELECT overlay(B'0101011100' placing '001' from 20);
  0101011100001
 (1 row)
 
+-- Popcount
+SELECT popcount(B'0101011100'::bit(10));
+ popcount 
+----------
+        5
+(1 row)
+
+SELECT popcount(B'1111111111'::bit(10));
+ popcount 
+----------
+       10
+(1 row)
+
 -- This table is intentionally left around to exercise pg_dump/pg_upgrade
 CREATE TABLE bit_defaults(
   b1 bit(4) DEFAULT '1001',
diff --git src/test/regress/expected/strings.out src/test/regress/expected/strings.out
index 298b6c48c2..9780639038 100644
--- src/test/regress/expected/strings.out
+++ src/test/regress/expected/strings.out
@@ -2126,3 +2126,10 @@ SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 5
  Th\000o\x02\x03
 (1 row)
 
+SET bytea_output TO hex;
+SELECT popcount(E'\\xdeadbeef'::bytea);
+ popcount 
+----------
+       24
+(1 row)
+
diff --git src/test/regress/sql/bit.sql src/test/regress/sql/bit.sql
index 7681d4ab4d..3cd9fb65d3 100644
--- src/test/regress/sql/bit.sql
+++ src/test/regress/sql/bit.sql
@@ -207,6 +207,10 @@ SELECT overlay(B'0101011100' placing '101' from 6);
 SELECT overlay(B'0101011100' placing '001' from 11);
 SELECT overlay(B'0101011100' placing '001' from 20);
 
+-- Popcount
+SELECT popcount(B'0101011100'::bit(10));
+SELECT popcount(B'1111111111'::bit(10));
+
 -- This table is intentionally left around to exercise pg_dump/pg_upgrade
 CREATE TABLE bit_defaults(
   b1 bit(4) DEFAULT '1001',
diff --git src/test/regress/sql/strings.sql src/test/regress/sql/strings.sql
index ad5221ab6b..a35e993ab0 100644
--- src/test/regress/sql/strings.sql
+++ src/test/regress/sql/strings.sql
@@ -717,3 +717,6 @@ SELECT btrim(E'\\000trim\\000'::bytea, ''::bytea);
 SELECT encode(overlay(E'Th\\000omas'::bytea placing E'Th\\001omas'::bytea from 2),'escape');
 SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 8),'escape');
 SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 5 for 3),'escape');
+
+SET bytea_output TO hex;
+SELECT popcount(E'\\xdeadbeef'::bytea);


^ permalink  raw  reply  [nested|flat] 4+ messages in thread

* [PATCH v2 3/4] psql: bump minimum supported version to v10
@ 2026-04-17 18:34 Nathan Bossart <nathan@postgresql.org>
  0 siblings, 0 replies; 4+ messages in thread

From: Nathan Bossart @ 2026-04-17 18:34 UTC (permalink / raw)

---
 doc/src/sgml/ref/psql-ref.sgml |   2 +-
 src/bin/psql/command.c         |  23 +--
 src/bin/psql/describe.c        | 255 +--------------------------------
 3 files changed, 11 insertions(+), 269 deletions(-)

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 7c05afd4719..56c2692e618 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -5523,7 +5523,7 @@ PSQL_EDITOR_LINENUMBER_ARG='--line '
        or an older major version.  Backslash commands are particularly likely
        to fail if the server is of a newer version than <application>psql</application>
        itself.  However, backslash commands of the <literal>\d</literal> family should
-       work with servers of versions back to 9.2, though not necessarily with
+       work with servers of versions back to 10, though not necessarily with
        servers newer than <application>psql</application> itself.  The general
        functionality of running SQL commands and displaying query results
        should also work with servers of a newer major version, but this cannot
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 493400f9090..c9573d4b765 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -4471,10 +4471,10 @@ connection_warnings(bool in_startup)
 
 		/*
 		 * Warn if server's major version is newer than ours, or if server
-		 * predates our support cutoff (currently 9.2).
+		 * predates our support cutoff (currently 10).
 		 */
 		if (pset.sversion / 100 > client_ver / 100 ||
-			pset.sversion < 90200)
+			pset.sversion < 100000)
 			printf(_("WARNING: %s major version %s, server major version %s.\n"
 					 "         Some psql features might not work.\n"),
 				   pset.progname,
@@ -6272,15 +6272,13 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid,
 			 * ensure the right view gets replaced.  Also, check relation kind
 			 * to be sure it's a view.
 			 *
-			 * Starting with PG 9.4, views may have WITH [LOCAL|CASCADED]
+			 * Views may have WITH [LOCAL|CASCADED]
 			 * CHECK OPTION.  These are not part of the view definition
 			 * returned by pg_get_viewdef() and so need to be retrieved
-			 * separately.  Materialized views (introduced in 9.3) may have
+			 * separately.  Materialized views may have
 			 * arbitrary storage parameter reloptions.
 			 */
 			printfPQExpBuffer(query, "/* %s */\n", _("Get view's definition and details"));
-			if (pset.sversion >= 90400)
-			{
 				appendPQExpBuffer(query,
 								  "SELECT nspname, relname, relkind, "
 								  "pg_catalog.pg_get_viewdef(c.oid, true), "
@@ -6291,19 +6289,6 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid,
 								  "LEFT JOIN pg_catalog.pg_namespace n "
 								  "ON c.relnamespace = n.oid WHERE c.oid = %u",
 								  oid);
-			}
-			else
-			{
-				appendPQExpBuffer(query,
-								  "SELECT nspname, relname, relkind, "
-								  "pg_catalog.pg_get_viewdef(c.oid, true), "
-								  "c.reloptions AS reloptions, "
-								  "NULL AS checkoption "
-								  "FROM pg_catalog.pg_class c "
-								  "LEFT JOIN pg_catalog.pg_namespace n "
-								  "ON c.relnamespace = n.oid WHERE c.oid = %u",
-								  oid);
-			}
 			break;
 	}
 
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index e1449654f96..76d299fb55c 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -3,9 +3,9 @@
  *
  * Support for the various \d ("describe") commands.  Note that the current
  * expectation is that all functions in this file will succeed when working
- * with servers of versions 9.2 and up.  It's okay to omit irrelevant
+ * with servers of versions 10 and up.  It's okay to omit irrelevant
  * information for an old server, but not to fail outright.  (But failing
- * against a pre-9.2 server is allowed.)
+ * against a pre-10 server is allowed.)
  *
  * Copyright (c) 2000-2026, PostgreSQL Global Development Group
  *
@@ -98,20 +98,12 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
 					  gettext_noop("Result data type"),
 					  gettext_noop("Argument data types"));
 
-	if (pset.sversion >= 110000)
 		appendPQExpBuffer(&buf,
 						  "  pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"\n"
 						  "FROM pg_catalog.pg_proc p\n"
 						  "     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n"
 						  "WHERE p.prokind = " CppAsString2(PROKIND_AGGREGATE) "\n",
 						  gettext_noop("Description"));
-	else
-		appendPQExpBuffer(&buf,
-						  "  pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"\n"
-						  "FROM pg_catalog.pg_proc p\n"
-						  "     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n"
-						  "WHERE p.proisagg\n",
-						  gettext_noop("Description"));
 
 	if (!showSystem && !pattern)
 		appendPQExpBufferStr(&buf, "      AND n.nspname <> 'pg_catalog'\n"
@@ -154,16 +146,6 @@ describeAccessMethods(const char *pattern, bool verbose)
 	printQueryOpt myopt = pset.popt;
 	static const bool translate_columns[] = {false, true, false, false};
 
-	if (pset.sversion < 90600)
-	{
-		char		sverbuf[32];
-
-		pg_log_error("The server (version %s) does not support access methods.",
-					 formatPGVersionNumber(pset.sversion, false,
-										   sverbuf, sizeof(sverbuf)));
-		return true;
-	}
-
 	initPQExpBuffer(&buf);
 
 	printfPQExpBuffer(&buf, "/* %s */\n", _("Get matching access methods"));
@@ -312,9 +294,6 @@ describeFunctions(const char *functypes, const char *func_pattern,
 	printQueryOpt myopt = pset.popt;
 	static const bool translate_columns[] = {false, false, false, false, true, true, true, false, true, true, false, false, false, false};
 
-	/* No "Parallel" column before 9.6 */
-	static const bool translate_columns_pre_96[] = {false, false, false, false, true, true, false, true, true, false, false, false, false};
-
 	if (strlen(functypes) != strspn(functypes, df_options))
 	{
 		pg_log_error("\\df only takes [%s] as options", df_options);
@@ -400,7 +379,6 @@ describeFunctions(const char *functypes, const char *func_pattern,
 						  gettext_noop("stable"),
 						  gettext_noop("volatile"),
 						  gettext_noop("Volatility"));
-		if (pset.sversion >= 90600)
 			appendPQExpBuffer(&buf,
 							  ",\n CASE\n"
 							  "  WHEN p.proparallel = "
@@ -613,16 +591,8 @@ describeFunctions(const char *functypes, const char *func_pattern,
 
 	myopt.title = _("List of functions");
 	myopt.translate_header = true;
-	if (pset.sversion >= 90600)
-	{
 		myopt.translate_columns = translate_columns;
 		myopt.n_translate_columns = lengthof(translate_columns);
-	}
-	else
-	{
-		myopt.translate_columns = translate_columns_pre_96;
-		myopt.n_translate_columns = lengthof(translate_columns_pre_96);
-	}
 
 	printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
@@ -1108,38 +1078,6 @@ permissionsList(const char *pattern, bool showSystem)
 					  "  ), E'\\n') AS \"%s\"",
 					  gettext_noop("Column privileges"));
 
-	if (pset.sversion >= 90500 && pset.sversion < 100000)
-		appendPQExpBuffer(&buf,
-						  ",\n  pg_catalog.array_to_string(ARRAY(\n"
-						  "    SELECT polname\n"
-						  "    || CASE WHEN polcmd != '*' THEN\n"
-						  "           E' (' || polcmd::pg_catalog.text || E'):'\n"
-						  "       ELSE E':'\n"
-						  "       END\n"
-						  "    || CASE WHEN polqual IS NOT NULL THEN\n"
-						  "           E'\\n  (u): ' || pg_catalog.pg_get_expr(polqual, polrelid)\n"
-						  "       ELSE E''\n"
-						  "       END\n"
-						  "    || CASE WHEN polwithcheck IS NOT NULL THEN\n"
-						  "           E'\\n  (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid)\n"
-						  "       ELSE E''\n"
-						  "       END"
-						  "    || CASE WHEN polroles <> '{0}' THEN\n"
-						  "           E'\\n  to: ' || pg_catalog.array_to_string(\n"
-						  "               ARRAY(\n"
-						  "                   SELECT rolname\n"
-						  "                   FROM pg_catalog.pg_roles\n"
-						  "                   WHERE oid = ANY (polroles)\n"
-						  "                   ORDER BY 1\n"
-						  "               ), E', ')\n"
-						  "       ELSE E''\n"
-						  "       END\n"
-						  "    FROM pg_catalog.pg_policy pol\n"
-						  "    WHERE polrelid = c.oid), E'\\n')\n"
-						  "    AS \"%s\"",
-						  gettext_noop("Policies"));
-
-	if (pset.sversion >= 100000)
 		appendPQExpBuffer(&buf,
 						  ",\n  pg_catalog.array_to_string(ARRAY(\n"
 						  "    SELECT polname\n"
@@ -1666,7 +1604,7 @@ describeOneTableDetails(const char *schemaname,
 						   : "''"),
 						  oid);
 	}
-	else if (pset.sversion >= 100000)
+	else
 	{
 		appendPQExpBuffer(&buf,
 						  "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
@@ -1683,57 +1621,6 @@ describeOneTableDetails(const char *schemaname,
 						   : "''"),
 						  oid);
 	}
-	else if (pset.sversion >= 90500)
-	{
-		appendPQExpBuffer(&buf,
-						  "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
-						  "c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, "
-						  "c.relhasoids, false as relispartition, %s, c.reltablespace, "
-						  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
-						  "c.relpersistence, c.relreplident\n"
-						  "FROM pg_catalog.pg_class c\n "
-						  "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
-						  "WHERE c.oid = '%s';",
-						  (verbose ?
-						   "pg_catalog.array_to_string(c.reloptions || "
-						   "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
-						   : "''"),
-						  oid);
-	}
-	else if (pset.sversion >= 90400)
-	{
-		appendPQExpBuffer(&buf,
-						  "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
-						  "c.relhastriggers, false, false, c.relhasoids, "
-						  "false as relispartition, %s, c.reltablespace, "
-						  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
-						  "c.relpersistence, c.relreplident\n"
-						  "FROM pg_catalog.pg_class c\n "
-						  "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
-						  "WHERE c.oid = '%s';",
-						  (verbose ?
-						   "pg_catalog.array_to_string(c.reloptions || "
-						   "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
-						   : "''"),
-						  oid);
-	}
-	else
-	{
-		appendPQExpBuffer(&buf,
-						  "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
-						  "c.relhastriggers, false, false, c.relhasoids, "
-						  "false as relispartition, %s, c.reltablespace, "
-						  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
-						  "c.relpersistence\n"
-						  "FROM pg_catalog.pg_class c\n "
-						  "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
-						  "WHERE c.oid = '%s';",
-						  (verbose ?
-						   "pg_catalog.array_to_string(c.reloptions || "
-						   "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
-						   : "''"),
-						  oid);
-	}
 
 	res = PSQLexec(buf.data);
 	if (!res)
@@ -1761,8 +1648,7 @@ describeOneTableDetails(const char *schemaname,
 	tableinfo.reloftype = (strcmp(PQgetvalue(res, 0, 11), "") != 0) ?
 		pg_strdup(PQgetvalue(res, 0, 11)) : NULL;
 	tableinfo.relpersistence = *(PQgetvalue(res, 0, 12));
-	tableinfo.relreplident = (pset.sversion >= 90400) ?
-		*(PQgetvalue(res, 0, 13)) : 'd';
+	tableinfo.relreplident = *(PQgetvalue(res, 0, 13));
 	if (pset.sversion >= 120000)
 		tableinfo.relam = PQgetisnull(res, 0, 14) ?
 			NULL : pg_strdup(PQgetvalue(res, 0, 14));
@@ -1781,8 +1667,6 @@ describeOneTableDetails(const char *schemaname,
 		char	   *footers[3] = {NULL, NULL, NULL};
 
 		printfPQExpBuffer(&buf, "/* %s */\n", _("Get sequence information"));
-		if (pset.sversion >= 100000)
-		{
 			appendPQExpBuffer(&buf,
 							  "SELECT pg_catalog.format_type(seqtypid, NULL) AS \"%s\",\n"
 							  "       seqstart AS \"%s\",\n"
@@ -1804,30 +1688,6 @@ describeOneTableDetails(const char *schemaname,
 							  "FROM pg_catalog.pg_sequence\n"
 							  "WHERE seqrelid = '%s';",
 							  oid);
-		}
-		else
-		{
-			appendPQExpBuffer(&buf,
-							  "SELECT 'bigint' AS \"%s\",\n"
-							  "       start_value AS \"%s\",\n"
-							  "       min_value AS \"%s\",\n"
-							  "       max_value AS \"%s\",\n"
-							  "       increment_by AS \"%s\",\n"
-							  "       CASE WHEN is_cycled THEN '%s' ELSE '%s' END AS \"%s\",\n"
-							  "       cache_value AS \"%s\"\n",
-							  gettext_noop("Type"),
-							  gettext_noop("Start"),
-							  gettext_noop("Minimum"),
-							  gettext_noop("Maximum"),
-							  gettext_noop("Increment"),
-							  gettext_noop("yes"),
-							  gettext_noop("no"),
-							  gettext_noop("Cycles?"),
-							  gettext_noop("Cache"));
-			appendPQExpBuffer(&buf, "FROM %s", fmtId(schemaname));
-			/* must be separate because fmtId isn't reentrant */
-			appendPQExpBuffer(&buf, ".%s;", fmtId(relationname));
-		}
 
 		res = PSQLexec(buf.data);
 		if (!res)
@@ -2045,10 +1905,7 @@ describeOneTableDetails(const char *schemaname,
 		appendPQExpBufferStr(&buf, ",\n  (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t\n"
 							 "   WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS attcollation");
 		attcoll_col = cols++;
-		if (pset.sversion >= 100000)
 			appendPQExpBufferStr(&buf, ",\n  a.attidentity");
-		else
-			appendPQExpBufferStr(&buf, ",\n  ''::pg_catalog.char AS attidentity");
 		attidentity_col = cols++;
 		if (pset.sversion >= 120000)
 			appendPQExpBufferStr(&buf, ",\n  a.attgenerated");
@@ -2059,14 +1916,11 @@ describeOneTableDetails(const char *schemaname,
 	if (tableinfo.relkind == RELKIND_INDEX ||
 		tableinfo.relkind == RELKIND_PARTITIONED_INDEX)
 	{
-		if (pset.sversion >= 110000)
-		{
 			appendPQExpBuffer(&buf, ",\n  CASE WHEN a.attnum <= (SELECT i.indnkeyatts FROM pg_catalog.pg_index i WHERE i.indexrelid = '%s') THEN '%s' ELSE '%s' END AS is_key",
 							  oid,
 							  gettext_noop("yes"),
 							  gettext_noop("no"));
 			isindexkey_col = cols++;
-		}
 		appendPQExpBufferStr(&buf, ",\n  pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE) AS indexdef");
 		indexdef_col = cols++;
 	}
@@ -2461,10 +2315,7 @@ describeOneTableDetails(const char *schemaname,
 							 CppAsString2(CONSTRAINT_EXCLUSION) ") AND "
 							 "condeferred) AS condeferred,\n");
 
-		if (pset.sversion >= 90400)
 			appendPQExpBufferStr(&buf, "i.indisreplident,\n");
-		else
-			appendPQExpBufferStr(&buf, "false AS indisreplident,\n");
 
 		if (pset.sversion >= 150000)
 			appendPQExpBufferStr(&buf, "i.indnullsnotdistinct,\n");
@@ -2569,10 +2420,7 @@ describeOneTableDetails(const char *schemaname,
 								 "pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),\n  "
 								 "pg_catalog.pg_get_constraintdef(con.oid, true), "
 								 "contype, condeferrable, condeferred");
-			if (pset.sversion >= 90400)
 				appendPQExpBufferStr(&buf, ", i.indisreplident");
-			else
-				appendPQExpBufferStr(&buf, ", false AS indisreplident");
 			appendPQExpBufferStr(&buf, ", c2.reltablespace");
 			if (pset.sversion >= 180000)
 				appendPQExpBufferStr(&buf, ", con.conperiod");
@@ -2823,17 +2671,11 @@ describeOneTableDetails(const char *schemaname,
 		PQclear(result);
 
 		/* print any row-level policies */
-		if (pset.sversion >= 90500)
-		{
 			printfPQExpBuffer(&buf, "/* %s */\n",
 							  _("Get row-level policies for this table"));
 			appendPQExpBufferStr(&buf, "SELECT pol.polname,");
-			if (pset.sversion >= 100000)
 				appendPQExpBufferStr(&buf,
 									 " pol.polpermissive,\n");
-			else
-				appendPQExpBufferStr(&buf,
-									 " 't' as polpermissive,\n");
 			appendPQExpBuffer(&buf,
 							  "  CASE WHEN pol.polroles = '{0}' THEN NULL ELSE pg_catalog.array_to_string(array(select rolname from pg_catalog.pg_roles where oid = any (pol.polroles) order by 1),',') END,\n"
 							  "  pg_catalog.pg_get_expr(pol.polqual, pol.polrelid),\n"
@@ -2904,7 +2746,6 @@ describeOneTableDetails(const char *schemaname,
 				printTableAddFooter(&cont, buf.data);
 			}
 			PQclear(result);
-		}
 
 		/* print any extended statistics */
 		if (pset.sversion >= 140000)
@@ -3007,7 +2848,7 @@ describeOneTableDetails(const char *schemaname,
 			}
 			PQclear(result);
 		}
-		else if (pset.sversion >= 100000)
+		else
 		{
 			printfPQExpBuffer(&buf, "/* %s */\n",
 							  _("Get extended statistics for this table"));
@@ -3173,8 +3014,6 @@ describeOneTableDetails(const char *schemaname,
 		}
 
 		/* print any publications */
-		if (pset.sversion >= 100000)
-		{
 			printfPQExpBuffer(&buf, "/* %s */\n",
 							  _("Get publications that publish this table"));
 			if (pset.sversion >= 150000)
@@ -3284,7 +3123,6 @@ describeOneTableDetails(const char *schemaname,
 				printTableAddFooter(&cont, buf.data);
 			}
 			PQclear(result);
-		}
 
 		/* Print publications where the table is in the EXCEPT clause */
 		if (pset.sversion >= 190000)
@@ -3706,7 +3544,7 @@ describeOneTableDetails(const char *schemaname,
 							  "ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT',"
 							  " c.oid::pg_catalog.regclass::pg_catalog.text;",
 							  oid);
-		else if (pset.sversion >= 100000)
+		else
 			appendPQExpBuffer(&buf,
 							  "SELECT c.oid::pg_catalog.regclass, c.relkind,"
 							  " false AS inhdetachpending,"
@@ -3716,14 +3554,6 @@ describeOneTableDetails(const char *schemaname,
 							  "ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT',"
 							  " c.oid::pg_catalog.regclass::pg_catalog.text;",
 							  oid);
-		else
-			appendPQExpBuffer(&buf,
-							  "SELECT c.oid::pg_catalog.regclass, c.relkind,"
-							  " false AS inhdetachpending, NULL\n"
-							  "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n"
-							  "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n"
-							  "ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;",
-							  oid);
 
 		result = PSQLexec(buf.data);
 		if (!result)
@@ -3964,11 +3794,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
 		ncols++;
 	}
 	appendPQExpBufferStr(&buf, "\n, r.rolreplication");
-
-	if (pset.sversion >= 90500)
-	{
 		appendPQExpBufferStr(&buf, "\n, r.rolbypassrls");
-	}
 
 	appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_roles r\n");
 
@@ -4023,7 +3849,6 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
 		if (strcmp(PQgetvalue(res, i, (verbose ? 9 : 8)), "t") == 0)
 			add_role_attribute(&buf, _("Replication"));
 
-		if (pset.sversion >= 90500)
 			if (strcmp(PQgetvalue(res, i, (verbose ? 10 : 9)), "t") == 0)
 				add_role_attribute(&buf, _("Bypass RLS"));
 
@@ -4514,19 +4339,6 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
 	const char *tabletitle;
 	bool		mixed_output = false;
 
-	/*
-	 * Note: Declarative table partitioning is only supported as of Pg 10.0.
-	 */
-	if (pset.sversion < 100000)
-	{
-		char		sverbuf[32];
-
-		pg_log_error("The server (version %s) does not support declarative table partitioning.",
-					 formatPGVersionNumber(pset.sversion, false,
-										   sverbuf, sizeof(sverbuf)));
-		return true;
-	}
-
 	/* If no relation kind was selected, show them all */
 	if (!showTables && !showIndexes)
 		showTables = showIndexes = true;
@@ -5034,16 +4846,6 @@ listEventTriggers(const char *pattern, bool verbose)
 	static const bool translate_columns[] =
 	{false, false, false, true, false, false, false};
 
-	if (pset.sversion < 90300)
-	{
-		char		sverbuf[32];
-
-		pg_log_error("The server (version %s) does not support event triggers.",
-					 formatPGVersionNumber(pset.sversion, false,
-										   sverbuf, sizeof(sverbuf)));
-		return true;
-	}
-
 	initPQExpBuffer(&buf);
 
 	printfPQExpBuffer(&buf, "/* %s */\n", _("Get matching event triggers"));
@@ -5113,16 +4915,6 @@ listExtendedStats(const char *pattern, bool verbose)
 	PGresult   *res;
 	printQueryOpt myopt = pset.popt;
 
-	if (pset.sversion < 100000)
-	{
-		char		sverbuf[32];
-
-		pg_log_error("The server (version %s) does not support extended statistics.",
-					 formatPGVersionNumber(pset.sversion, false,
-										   sverbuf, sizeof(sverbuf)));
-		return true;
-	}
-
 	initPQExpBuffer(&buf);
 
 	printfPQExpBuffer(&buf, "/* %s */\n", _("Get matching extended statistics"));
@@ -5352,7 +5144,6 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
 					  gettext_noop("Schema"),
 					  gettext_noop("Name"));
 
-	if (pset.sversion >= 100000)
 		appendPQExpBuffer(&buf,
 						  "  CASE c.collprovider "
 						  "WHEN " CppAsString2(COLLPROVIDER_DEFAULT) " THEN 'default' "
@@ -5361,10 +5152,6 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
 						  "WHEN " CppAsString2(COLLPROVIDER_ICU) " THEN 'icu' "
 						  "END AS \"%s\",\n",
 						  gettext_noop("Provider"));
-	else
-		appendPQExpBuffer(&buf,
-						  "  'libc' AS \"%s\",\n",
-						  gettext_noop("Provider"));
 
 	appendPQExpBuffer(&buf,
 					  "  c.collcollate AS \"%s\",\n"
@@ -6688,16 +6475,6 @@ listPublications(const char *pattern)
 	printQueryOpt myopt = pset.popt;
 	static const bool translate_columns[] = {false, false, false, false, false, false, false, false, false, false};
 
-	if (pset.sversion < 100000)
-	{
-		char		sverbuf[32];
-
-		pg_log_error("The server (version %s) does not support publications.",
-					 formatPGVersionNumber(pset.sversion, false,
-										   sverbuf, sizeof(sverbuf)));
-		return true;
-	}
-
 	initPQExpBuffer(&buf);
 
 	printfPQExpBuffer(&buf, "/* %s */\n", _("Get matching publications"));
@@ -6835,16 +6612,6 @@ describePublications(const char *pattern)
 	PQExpBufferData title;
 	printTableContent cont;
 
-	if (pset.sversion < 100000)
-	{
-		char		sverbuf[32];
-
-		pg_log_error("The server (version %s) does not support publications.",
-					 formatPGVersionNumber(pset.sversion, false,
-										   sverbuf, sizeof(sverbuf)));
-		return true;
-	}
-
 	has_pubsequence = (pset.sversion >= 190000);
 	has_pubtruncate = (pset.sversion >= 110000);
 	has_pubgencols = (pset.sversion >= 180000);
@@ -7095,16 +6862,6 @@ describeSubscriptions(const char *pattern, bool verbose)
 		false, false, false, false, false, false, false, false, false, false,
 	false, false, false, false, false, false, false};
 
-	if (pset.sversion < 100000)
-	{
-		char		sverbuf[32];
-
-		pg_log_error("The server (version %s) does not support subscriptions.",
-					 formatPGVersionNumber(pset.sversion, false,
-										   sverbuf, sizeof(sverbuf)));
-		return true;
-	}
-
 	initPQExpBuffer(&buf);
 
 	printfPQExpBuffer(&buf, "/* %s */\n", _("Get matching subscriptions"));
-- 
2.50.1 (Apple Git-155)


--CT89ko5pLUrsvFtH
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=v2-0004-run-pgindent.patch



^ permalink  raw  reply  [nested|flat] 4+ messages in thread


end of thread, other threads:[~2026-04-17 18:34 UTC | newest]

Thread overview: 4+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2020-12-30 10:51 [PATCH v1] popcount David Fetter <david@fetter.org>
2020-12-30 10:51 [PATCH v5] popcount David Fetter <david@fetter.org>
2020-12-30 10:51 [PATCH v2] popcount David Fetter <david@fetter.org>
2026-04-17 18:34 [PATCH v2 3/4] psql: bump minimum supported version to v10 Nathan Bossart <nathan@postgresql.org>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox