public inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH v24 1/7] Built-in compression method
2+ messages / 2 participants
[nested] [flat]

* [PATCH v24 1/7] Built-in compression method
@ 2021-02-05 12:51  dilipkumar <[email protected]>
  0 siblings, 0 replies; 2+ messages in thread

From: dilipkumar @ 2021-02-05 12:51 UTC (permalink / raw)

Add syntax allowing a compression method to be specified.
As of now there is only 2 option for build-in compression
method (pglz, lz4) which can be set while creating a table
or adding a new column.  No option for altering the
compression method for an existing column.

Dilip Kumar based on the patches from Ildus Kurbangaliev.
Design input from Robert Haas and Tomas Vondra.
Reviewed by Robert Haas, Tomas Vondra, Alexander Korotkov and Justin Pryzby

Discussions:
https://www.postgresql.org/message-id/[email protected]
https://www.postgresql.org/message-id/CA%2BTgmoaKDW1Oi9V%3Djc9hOGyf77NbkNEABuqgHD1Cq%3D%3D1QsOcxg%40...
https://www.postgresql.org/message-id/CA%2BTgmobSDVgUage9qQ5P_%3DF_9jaMkCgyKxUQGtFQU7oN4kX-AA%40mail...
https://www.postgresql.org/message-id/20201005160355.byp74sh3ejsv7wrj%40development
https://www.postgresql.org/message-id/CAFiTN-tzTTT2oqWdRGLv1dvvS5MC1W%2BLE%2B3bqWPJUZj4GnHOJg%40mail...
---
 configure                                     | 116 ++++++++++
 configure.ac                                  |  17 ++
 contrib/test_decoding/expected/ddl.out        |  50 ++---
 doc/src/sgml/ddl.sgml                         |   3 +
 doc/src/sgml/ref/create_table.sgml            |  25 +++
 src/backend/access/Makefile                   |   2 +-
 src/backend/access/brin/brin_tuple.c          |   5 +-
 src/backend/access/common/detoast.c           | 103 ++++++---
 src/backend/access/common/indextuple.c        |   4 +-
 src/backend/access/common/toast_internals.c   |  63 +++---
 src/backend/access/common/tupdesc.c           |   8 +
 src/backend/access/compression/Makefile       |  17 ++
 src/backend/access/compression/compress_lz4.c | 164 ++++++++++++++
 .../access/compression/compress_pglz.c        | 138 ++++++++++++
 src/backend/access/table/toast_helper.c       |   5 +-
 src/backend/bootstrap/bootstrap.c             |   5 +
 src/backend/catalog/genbki.pl                 |   7 +-
 src/backend/catalog/heap.c                    |   4 +
 src/backend/catalog/index.c                   |   2 +
 src/backend/catalog/toasting.c                |   5 +
 src/backend/commands/amcmds.c                 |  10 +
 src/backend/commands/createas.c               |  14 ++
 src/backend/commands/matview.c                |  14 ++
 src/backend/commands/tablecmds.c              | 111 +++++++++-
 src/backend/executor/nodeModifyTable.c        | 122 +++++++++++
 src/backend/nodes/copyfuncs.c                 |   1 +
 src/backend/nodes/equalfuncs.c                |   1 +
 src/backend/nodes/nodeFuncs.c                 |   2 +
 src/backend/nodes/outfuncs.c                  |   1 +
 src/backend/parser/gram.y                     |  26 ++-
 src/backend/parser/parse_utilcmd.c            |   8 +
 src/backend/utils/adt/pseudotypes.c           |   1 +
 src/backend/utils/adt/varlena.c               |  42 ++++
 src/bin/pg_dump/pg_backup.h                   |   1 +
 src/bin/pg_dump/pg_dump.c                     |  36 +++-
 src/bin/pg_dump/pg_dump.h                     |   1 +
 src/bin/pg_dump/t/002_pg_dump.pl              |  12 +-
 src/bin/psql/describe.c                       |  28 ++-
 src/include/access/compressamapi.h            |  99 +++++++++
 src/include/access/detoast.h                  |   8 +
 src/include/access/toast_helper.h             |   1 +
 src/include/access/toast_internals.h          |  19 +-
 src/include/catalog/pg_am.dat                 |   6 +
 src/include/catalog/pg_am.h                   |   1 +
 src/include/catalog/pg_attribute.h            |   8 +-
 src/include/catalog/pg_proc.dat               |  20 ++
 src/include/catalog/pg_type.dat               |   5 +
 src/include/commands/defrem.h                 |   1 +
 src/include/executor/executor.h               |   4 +-
 src/include/nodes/execnodes.h                 |   6 +
 src/include/nodes/nodes.h                     |   1 +
 src/include/nodes/parsenodes.h                |   2 +
 src/include/parser/kwlist.h                   |   1 +
 src/include/pg_config.h.in                    |   3 +
 src/include/postgres.h                        |  12 +-
 src/test/regress/expected/compression.out     | 201 ++++++++++++++++++
 src/test/regress/expected/compression_1.out   | 189 ++++++++++++++++
 src/test/regress/expected/psql.out            |  68 +++---
 src/test/regress/parallel_schedule            |   2 +-
 src/test/regress/serial_schedule              |   1 +
 src/test/regress/sql/compression.sql          |  85 ++++++++
 src/tools/msvc/Solution.pm                    |   1 +
 src/tools/pgindent/typedefs.list              |   1 +
 63 files changed, 1771 insertions(+), 148 deletions(-)
 create mode 100644 src/backend/access/compression/Makefile
 create mode 100644 src/backend/access/compression/compress_lz4.c
 create mode 100644 src/backend/access/compression/compress_pglz.c
 create mode 100644 src/include/access/compressamapi.h
 create mode 100644 src/test/regress/expected/compression.out
 create mode 100644 src/test/regress/expected/compression_1.out
 create mode 100644 src/test/regress/sql/compression.sql

diff --git a/configure b/configure
index ce9ea36999..0895b2f326 100755
--- a/configure
+++ b/configure
@@ -699,6 +699,7 @@ with_gnu_ld
 LD
 LDFLAGS_SL
 LDFLAGS_EX
+with_lz4
 with_zlib
 with_system_tzdata
 with_libxslt
@@ -864,6 +865,7 @@ with_libxml
 with_libxslt
 with_system_tzdata
 with_zlib
+with_lz4
 with_gnu_ld
 with_ssl
 with_openssl
@@ -1569,6 +1571,7 @@ Optional Packages:
   --with-system-tzdata=DIR
                           use system time zone data in DIR
   --without-zlib          do not use Zlib
+  --with-lz4              build with LZ4 support
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
   --with-ssl=LIB          use LIB for SSL/TLS support (openssl)
   --with-openssl          obsolete spelling of --with-ssl=openssl
@@ -8563,6 +8566,39 @@ fi
 
 
 
+#
+# LZ4
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with LZ4 support" >&5
+$as_echo_n "checking whether to build with LZ4 support... " >&6; }
+
+
+
+# Check whether --with-lz4 was given.
+if test "${with_lz4+set}" = set; then :
+  withval=$with_lz4;
+  case $withval in
+    yes)
+
+$as_echo "#define USE_LZ4 1" >>confdefs.h
+
+      ;;
+    no)
+      :
+      ;;
+    *)
+      as_fn_error $? "no argument expected for --with-lz4 option" "$LINENO" 5
+      ;;
+  esac
+
+else
+  with_lz4=no
+
+fi
+
+
+
+
 #
 # Assignments
 #
@@ -12054,6 +12090,56 @@ fi
 
 fi
 
+if test "$with_lz4" = yes ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5
+$as_echo_n "checking for LZ4_compress in -llz4... " >&6; }
+if ${ac_cv_lib_lz4_LZ4_compress+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-llz4  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char LZ4_compress ();
+int
+main ()
+{
+return LZ4_compress ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_lz4_LZ4_compress=yes
+else
+  ac_cv_lib_lz4_LZ4_compress=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5
+$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; }
+if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBLZ4 1
+_ACEOF
+
+  LIBS="-llz4 $LIBS"
+
+else
+  as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5
+fi
+
+fi
+
 if test "$enable_spinlocks" = yes; then
 
 $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h
@@ -13320,6 +13406,36 @@ Use --without-zlib to disable zlib support." "$LINENO" 5
 fi
 
 
+fi
+
+if test "$with_lz4" = yes ; then
+  for ac_header in lz4/lz4.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "lz4/lz4.h" "ac_cv_header_lz4_lz4_h" "$ac_includes_default"
+if test "x$ac_cv_header_lz4_lz4_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LZ4_LZ4_H 1
+_ACEOF
+
+else
+  for ac_header in lz4.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "lz4.h" "ac_cv_header_lz4_h" "$ac_includes_default"
+if test "x$ac_cv_header_lz4_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LZ4_H 1
+_ACEOF
+
+else
+  as_fn_error $? "lz4.h header file is required for LZ4" "$LINENO" 5
+fi
+
+done
+
+fi
+
+done
+
 fi
 
 if test "$with_gssapi" = yes ; then
diff --git a/configure.ac b/configure.ac
index 07da84d401..63940b78a0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -986,6 +986,14 @@ PGAC_ARG_BOOL(with, zlib, yes,
               [do not use Zlib])
 AC_SUBST(with_zlib)
 
+#
+# LZ4
+#
+AC_MSG_CHECKING([whether to build with LZ4 support])
+PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support],
+              [AC_DEFINE([USE_LZ4], 1, [Define to 1 to build with LZ4 support. (--with-lz4)])])
+AC_SUBST(with_lz4)
+
 #
 # Assignments
 #
@@ -1173,6 +1181,10 @@ failure.  It is possible the compiler isn't looking in the proper directory.
 Use --without-zlib to disable zlib support.])])
 fi
 
+if test "$with_lz4" = yes ; then
+  AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])])
+fi
+
 if test "$enable_spinlocks" = yes; then
   AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.])
 else
@@ -1406,6 +1418,11 @@ failure.  It is possible the compiler isn't looking in the proper directory.
 Use --without-zlib to disable zlib support.])])
 fi
 
+if test "$with_lz4" = yes ; then
+  AC_CHECK_HEADERS(lz4/lz4.h, [],
+	[AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])])
+fi
+
 if test "$with_gssapi" = yes ; then
   AC_CHECK_HEADERS(gssapi/gssapi.h, [],
 	[AC_CHECK_HEADERS(gssapi.h, [], [AC_MSG_ERROR([gssapi.h header file is required for GSSAPI])])])
diff --git a/contrib/test_decoding/expected/ddl.out b/contrib/test_decoding/expected/ddl.out
index 4ff0044c78..6ee077678d 100644
--- a/contrib/test_decoding/expected/ddl.out
+++ b/contrib/test_decoding/expected/ddl.out
@@ -438,12 +438,12 @@ CREATE TABLE replication_metadata (
 WITH (user_catalog_table = true)
 ;
 \d+ replication_metadata
-                                                 Table "public.replication_metadata"
-  Column  |  Type   | Collation | Nullable |                     Default                      | Storage  | Stats target | Description 
-----------+---------+-----------+----------+--------------------------------------------------+----------+--------------+-------------
- id       | integer |           | not null | nextval('replication_metadata_id_seq'::regclass) | plain    |              | 
- relation | name    |           | not null |                                                  | plain    |              | 
- options  | text[]  |           |          |                                                  | extended |              | 
+                                                        Table "public.replication_metadata"
+  Column  |  Type   | Collation | Nullable |                     Default                      | Storage  | Compression | Stats target | Description 
+----------+---------+-----------+----------+--------------------------------------------------+----------+-------------+--------------+-------------
+ id       | integer |           | not null | nextval('replication_metadata_id_seq'::regclass) | plain    |             |              | 
+ relation | name    |           | not null |                                                  | plain    |             |              | 
+ options  | text[]  |           |          |                                                  | extended | pglz        |              | 
 Indexes:
     "replication_metadata_pkey" PRIMARY KEY, btree (id)
 Options: user_catalog_table=true
@@ -452,12 +452,12 @@ INSERT INTO replication_metadata(relation, options)
 VALUES ('foo', ARRAY['a', 'b']);
 ALTER TABLE replication_metadata RESET (user_catalog_table);
 \d+ replication_metadata
-                                                 Table "public.replication_metadata"
-  Column  |  Type   | Collation | Nullable |                     Default                      | Storage  | Stats target | Description 
-----------+---------+-----------+----------+--------------------------------------------------+----------+--------------+-------------
- id       | integer |           | not null | nextval('replication_metadata_id_seq'::regclass) | plain    |              | 
- relation | name    |           | not null |                                                  | plain    |              | 
- options  | text[]  |           |          |                                                  | extended |              | 
+                                                        Table "public.replication_metadata"
+  Column  |  Type   | Collation | Nullable |                     Default                      | Storage  | Compression | Stats target | Description 
+----------+---------+-----------+----------+--------------------------------------------------+----------+-------------+--------------+-------------
+ id       | integer |           | not null | nextval('replication_metadata_id_seq'::regclass) | plain    |             |              | 
+ relation | name    |           | not null |                                                  | plain    |             |              | 
+ options  | text[]  |           |          |                                                  | extended | pglz        |              | 
 Indexes:
     "replication_metadata_pkey" PRIMARY KEY, btree (id)
 
@@ -465,12 +465,12 @@ INSERT INTO replication_metadata(relation, options)
 VALUES ('bar', ARRAY['a', 'b']);
 ALTER TABLE replication_metadata SET (user_catalog_table = true);
 \d+ replication_metadata
-                                                 Table "public.replication_metadata"
-  Column  |  Type   | Collation | Nullable |                     Default                      | Storage  | Stats target | Description 
-----------+---------+-----------+----------+--------------------------------------------------+----------+--------------+-------------
- id       | integer |           | not null | nextval('replication_metadata_id_seq'::regclass) | plain    |              | 
- relation | name    |           | not null |                                                  | plain    |              | 
- options  | text[]  |           |          |                                                  | extended |              | 
+                                                        Table "public.replication_metadata"
+  Column  |  Type   | Collation | Nullable |                     Default                      | Storage  | Compression | Stats target | Description 
+----------+---------+-----------+----------+--------------------------------------------------+----------+-------------+--------------+-------------
+ id       | integer |           | not null | nextval('replication_metadata_id_seq'::regclass) | plain    |             |              | 
+ relation | name    |           | not null |                                                  | plain    |             |              | 
+ options  | text[]  |           |          |                                                  | extended | pglz        |              | 
 Indexes:
     "replication_metadata_pkey" PRIMARY KEY, btree (id)
 Options: user_catalog_table=true
@@ -483,13 +483,13 @@ ALTER TABLE replication_metadata ALTER COLUMN rewritemeornot TYPE text;
 ERROR:  cannot rewrite table "replication_metadata" used as a catalog table
 ALTER TABLE replication_metadata SET (user_catalog_table = false);
 \d+ replication_metadata
-                                                    Table "public.replication_metadata"
-     Column     |  Type   | Collation | Nullable |                     Default                      | Storage  | Stats target | Description 
-----------------+---------+-----------+----------+--------------------------------------------------+----------+--------------+-------------
- id             | integer |           | not null | nextval('replication_metadata_id_seq'::regclass) | plain    |              | 
- relation       | name    |           | not null |                                                  | plain    |              | 
- options        | text[]  |           |          |                                                  | extended |              | 
- rewritemeornot | integer |           |          |                                                  | plain    |              | 
+                                                           Table "public.replication_metadata"
+     Column     |  Type   | Collation | Nullable |                     Default                      | Storage  | Compression | Stats target | Description 
+----------------+---------+-----------+----------+--------------------------------------------------+----------+-------------+--------------+-------------
+ id             | integer |           | not null | nextval('replication_metadata_id_seq'::regclass) | plain    |             |              | 
+ relation       | name    |           | not null |                                                  | plain    |             |              | 
+ options        | text[]  |           |          |                                                  | extended | pglz        |              | 
+ rewritemeornot | integer |           |          |                                                  | plain    |             |              | 
 Indexes:
     "replication_metadata_pkey" PRIMARY KEY, btree (id)
 Options: user_catalog_table=false
diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml
index 1e9a4625cc..4d7ed698b9 100644
--- a/doc/src/sgml/ddl.sgml
+++ b/doc/src/sgml/ddl.sgml
@@ -3762,6 +3762,9 @@ CREATE TABLE measurement (
        <productname>PostgreSQL</productname>
        tables (or, possibly, foreign tables).  It is possible to specify a
        tablespace and storage parameters for each partition separately.
+       By default, each column in a partition inherits the compression method
+       from parent table's column, however a different compression method can be
+       set for each partition.
       </para>
 
       <para>
diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index 569f4c9da7..51a7a977a5 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -69,6 +69,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
   GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( <replaceable>sequence_options</replaceable> ) ] |
   UNIQUE <replaceable class="parameter">index_parameters</replaceable> |
   PRIMARY KEY <replaceable class="parameter">index_parameters</replaceable> |
+  COMPRESSION <replaceable class="parameter">compression_method</replaceable> |
   REFERENCES <replaceable class="parameter">reftable</replaceable> [ ( <replaceable class="parameter">refcolumn</replaceable> ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
     [ ON DELETE <replaceable class="parameter">referential_action</replaceable> ] [ ON UPDATE <replaceable class="parameter">referential_action</replaceable> ] }
 [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
@@ -605,6 +606,17 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
         </listitem>
        </varlistentry>
 
+       <varlistentry>
+        <term><literal>INCLUDING COMPRESSION</literal></term>
+        <listitem>
+         <para>
+          Compression method of the columns will be copied.  The default
+          behavior is to exclude compression methods, resulting in the columns
+          having the default compression method.
+         </para>
+        </listitem>
+       </varlistentry>
+
        <varlistentry>
         <term><literal>INCLUDING CONSTRAINTS</literal></term>
         <listitem>
@@ -981,6 +993,19 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
     </listitem>
    </varlistentry>
 
+   <varlistentry>
+    <term><literal>COMPRESSION <replaceable class="parameter">compression_method</replaceable></literal></term>
+    <listitem>
+     <para>
+      This sets the compression method for a column.  The supported compression
+      methods are <literal>pglz</literal> and <literal>lz4</literal>.
+      <literal>lz4</literal> is available only if <literal>--with-lz4</literal>
+      was used when building <productname>PostgreSQL</productname>. The default
+      is <literal>pglz</literal>.
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry id="sql-createtable-exclude">
     <term><literal>EXCLUDE [ USING <replaceable class="parameter">index_method</replaceable> ] ( <replaceable class="parameter">exclude_element</replaceable> WITH <replaceable class="parameter">operator</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> [ WHERE ( <replaceable class="parameter">predicate</replaceable> ) ]</literal></term>
     <listitem>
diff --git a/src/backend/access/Makefile b/src/backend/access/Makefile
index 0880e0a8bb..ba08bdd63e 100644
--- a/src/backend/access/Makefile
+++ b/src/backend/access/Makefile
@@ -8,7 +8,7 @@ subdir = src/backend/access
 top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
-SUBDIRS	    = brin common gin gist hash heap index nbtree rmgrdesc spgist \
+SUBDIRS	    = brin common compression gin gist hash heap index nbtree rmgrdesc spgist \
 			  table tablesample transam
 
 include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/access/brin/brin_tuple.c b/src/backend/access/brin/brin_tuple.c
index a7eb1c9473..0ab5712c71 100644
--- a/src/backend/access/brin/brin_tuple.c
+++ b/src/backend/access/brin/brin_tuple.c
@@ -213,7 +213,10 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple,
 				(atttype->typstorage == TYPSTORAGE_EXTENDED ||
 				 atttype->typstorage == TYPSTORAGE_MAIN))
 			{
-				Datum		cvalue = toast_compress_datum(value);
+				Form_pg_attribute att = TupleDescAttr(brdesc->bd_tupdesc,
+													  keyno);
+				Datum		cvalue = toast_compress_datum(value,
+														  att->attcompression);
 
 				if (DatumGetPointer(cvalue) != NULL)
 				{
diff --git a/src/backend/access/common/detoast.c b/src/backend/access/common/detoast.c
index d1cdbaf648..b78d49167b 100644
--- a/src/backend/access/common/detoast.c
+++ b/src/backend/access/common/detoast.c
@@ -13,6 +13,7 @@
 
 #include "postgres.h"
 
+#include "access/compressamapi.h"
 #include "access/detoast.h"
 #include "access/table.h"
 #include "access/tableam.h"
@@ -457,28 +458,78 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset,
 }
 
 /* ----------
- * toast_decompress_datum -
+ * toast_get_compression_oid -
  *
- * Decompress a compressed version of a varlena datum
+ * Returns the Oid of the compression method stored in the compressed data.  If
+ * the varlena is not compressed then returns InvalidOid.
  */
-static struct varlena *
-toast_decompress_datum(struct varlena *attr)
+Oid
+toast_get_compression_oid(struct varlena *attr)
 {
-	struct varlena *result;
+	if (VARATT_IS_EXTERNAL_ONDISK(attr))
+	{
+		struct varatt_external toast_pointer;
+
+		VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
+
+		/* fast path for non-compressed external datums */
+		if (!VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer))
+			return InvalidOid;
+
+		/*
+		 * Just fetch the toast compress header to know the compression method
+		 * in the compressed data.
+		 */
+		attr = toast_fetch_datum_slice(attr, 0, VARHDRSZ_COMPRESS);
+	}
+	else if (!VARATT_IS_COMPRESSED(attr))
+		return InvalidOid;
+
+	return CompressionIdToOid(TOAST_COMPRESS_METHOD(attr));
+}
+
+/* ----------
+ * toast_get_compression_handler - get the compression handler routines
+ *
+ * helper function for toast_decompress_datum and toast_decompress_datum_slice
+ */
+static inline const CompressionAmRoutine *
+toast_get_compression_handler(struct varlena *attr)
+{
+	const CompressionAmRoutine *cmroutine;
+	CompressionId cmid;
 
 	Assert(VARATT_IS_COMPRESSED(attr));
 
-	result = (struct varlena *)
-		palloc(TOAST_COMPRESS_RAWSIZE(attr) + VARHDRSZ);
-	SET_VARSIZE(result, TOAST_COMPRESS_RAWSIZE(attr) + VARHDRSZ);
+	cmid = TOAST_COMPRESS_METHOD(attr);
 
-	if (pglz_decompress(TOAST_COMPRESS_RAWDATA(attr),
-						TOAST_COMPRESS_SIZE(attr),
-						VARDATA(result),
-						TOAST_COMPRESS_RAWSIZE(attr), true) < 0)
-		elog(ERROR, "compressed data is corrupted");
+	/* Get the handler routines for the compression method */
+	switch (cmid)
+	{
+		case PGLZ_COMPRESSION_ID:
+			cmroutine = &pglz_compress_methods;
+			break;
+		case LZ4_COMPRESSION_ID:
+			cmroutine = &lz4_compress_methods;
+			break;
+		default:
+			elog(ERROR, "invalid compression method id %d", cmid);
+	}
 
-	return result;
+	return cmroutine;
+}
+
+/* ----------
+ * toast_decompress_datum -
+ *
+ * Decompress a compressed version of a varlena datum
+ */
+static struct varlena *
+toast_decompress_datum(struct varlena *attr)
+{
+	const CompressionAmRoutine *cmroutine = toast_get_compression_handler(attr);
+
+	return cmroutine->datum_decompress(attr);
 }
 
 
@@ -492,22 +543,16 @@ toast_decompress_datum(struct varlena *attr)
 static struct varlena *
 toast_decompress_datum_slice(struct varlena *attr, int32 slicelength)
 {
-	struct varlena *result;
-	int32		rawsize;
-
-	Assert(VARATT_IS_COMPRESSED(attr));
-
-	result = (struct varlena *) palloc(slicelength + VARHDRSZ);
-
-	rawsize = pglz_decompress(TOAST_COMPRESS_RAWDATA(attr),
-							  VARSIZE(attr) - TOAST_COMPRESS_HDRSZ,
-							  VARDATA(result),
-							  slicelength, false);
-	if (rawsize < 0)
-		elog(ERROR, "compressed data is corrupted");
+	const CompressionAmRoutine *cmroutine = toast_get_compression_handler(attr);
 
-	SET_VARSIZE(result, rawsize + VARHDRSZ);
-	return result;
+	/*
+	 * If the handler supports the slice decompression then decompress the
+	 * slice otherwise decompress complete data.
+	 */
+	if (cmroutine->datum_decompress_slice)
+		return cmroutine->datum_decompress_slice(attr, slicelength);
+	else
+		return cmroutine->datum_decompress(attr);
 }
 
 /* ----------
diff --git a/src/backend/access/common/indextuple.c b/src/backend/access/common/indextuple.c
index b72a138497..1d43d5d2ff 100644
--- a/src/backend/access/common/indextuple.c
+++ b/src/backend/access/common/indextuple.c
@@ -16,6 +16,7 @@
 
 #include "postgres.h"
 
+#include "access/compressamapi.h"
 #include "access/detoast.h"
 #include "access/heaptoast.h"
 #include "access/htup_details.h"
@@ -103,7 +104,8 @@ index_form_tuple(TupleDesc tupleDescriptor,
 			(att->attstorage == TYPSTORAGE_EXTENDED ||
 			 att->attstorage == TYPSTORAGE_MAIN))
 		{
-			Datum		cvalue = toast_compress_datum(untoasted_values[i]);
+			Datum		cvalue = toast_compress_datum(untoasted_values[i],
+													  att->attcompression);
 
 			if (DatumGetPointer(cvalue) != NULL)
 			{
diff --git a/src/backend/access/common/toast_internals.c b/src/backend/access/common/toast_internals.c
index 9b9da0f41b..b04c5a5eb8 100644
--- a/src/backend/access/common/toast_internals.c
+++ b/src/backend/access/common/toast_internals.c
@@ -44,46 +44,51 @@ static bool toastid_valueid_exists(Oid toastrelid, Oid valueid);
  * ----------
  */
 Datum
-toast_compress_datum(Datum value)
+toast_compress_datum(Datum value, Oid cmoid)
 {
-	struct varlena *tmp;
-	int32		valsize = VARSIZE_ANY_EXHDR(DatumGetPointer(value));
-	int32		len;
+	struct varlena *tmp = NULL;
+	int32		valsize;
+	const CompressionAmRoutine *cmroutine = NULL;
 
 	Assert(!VARATT_IS_EXTERNAL(DatumGetPointer(value)));
 	Assert(!VARATT_IS_COMPRESSED(DatumGetPointer(value)));
 
-	/*
-	 * No point in wasting a palloc cycle if value size is out of the allowed
-	 * range for compression
-	 */
-	if (valsize < PGLZ_strategy_default->min_input_size ||
-		valsize > PGLZ_strategy_default->max_input_size)
-		return PointerGetDatum(NULL);
+	Assert(OidIsValid(cmoid));
+
+	/* Get the handler routines for the compression method */
+	switch (cmoid)
+	{
+		case PGLZ_COMPRESSION_AM_OID:
+			cmroutine = &pglz_compress_methods;
+			break;
+		case LZ4_COMPRESSION_AM_OID:
+			cmroutine = &lz4_compress_methods;
+			break;
+		default:
+			elog(ERROR, "Invalid compression method oid %u", cmoid);
+	}
 
-	tmp = (struct varlena *) palloc(PGLZ_MAX_OUTPUT(valsize) +
-									TOAST_COMPRESS_HDRSZ);
+	/* Call the actual compression function */
+	tmp = cmroutine->datum_compress((const struct varlena *) value);
+	if (!tmp)
+		return PointerGetDatum(NULL);
 
 	/*
-	 * We recheck the actual size even if pglz_compress() reports success,
-	 * because it might be satisfied with having saved as little as one byte
-	 * in the compressed data --- which could turn into a net loss once you
-	 * consider header and alignment padding.  Worst case, the compressed
-	 * format might require three padding bytes (plus header, which is
-	 * included in VARSIZE(tmp)), whereas the uncompressed format would take
-	 * only one header byte and no padding if the value is short enough.  So
-	 * we insist on a savings of more than 2 bytes to ensure we have a gain.
+	 * We recheck the actual size even if compression reports success, because
+	 * it might be satisfied with having saved as little as one byte in the
+	 * compressed data --- which could turn into a net loss once you consider
+	 * header and alignment padding.  Worst case, the compressed format might
+	 * require three padding bytes (plus header, which is included in
+	 * VARSIZE(tmp)), whereas the uncompressed format would take only one
+	 * header byte and no padding if the value is short enough.  So we insist
+	 * on a savings of more than 2 bytes to ensure we have a gain.
 	 */
-	len = pglz_compress(VARDATA_ANY(DatumGetPointer(value)),
-						valsize,
-						TOAST_COMPRESS_RAWDATA(tmp),
-						PGLZ_strategy_default);
-	if (len >= 0 &&
-		len + TOAST_COMPRESS_HDRSZ < valsize - 2)
+	valsize = VARSIZE_ANY_EXHDR(DatumGetPointer(value));
+
+	if (VARSIZE(tmp) < valsize - 2)
 	{
-		TOAST_COMPRESS_SET_RAWSIZE(tmp, valsize);
-		SET_VARSIZE_COMPRESSED(tmp, len + TOAST_COMPRESS_HDRSZ);
 		/* successful compression */
+		TOAST_COMPRESS_SET_SIZE_AND_METHOD(tmp, valsize, CompressionOidToId(cmoid));
 		return PointerGetDatum(tmp);
 	}
 	else
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index 902f59440c..ca26fab487 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -19,6 +19,7 @@
 
 #include "postgres.h"
 
+#include "access/compressamapi.h"
 #include "access/htup_details.h"
 #include "access/tupdesc_details.h"
 #include "catalog/pg_collation.h"
@@ -470,6 +471,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
 			return false;
 		if (attr1->attcollation != attr2->attcollation)
 			return false;
+		if (attr1->attcompression != attr2->attcompression)
+			return false;
 		/* attacl, attoptions and attfdwoptions are not even present... */
 	}
 
@@ -664,6 +667,11 @@ TupleDescInitEntry(TupleDesc desc,
 	att->attstorage = typeForm->typstorage;
 	att->attcollation = typeForm->typcollation;
 
+	if (IsStorageCompressible(typeForm->typstorage))
+		att->attcompression = DefaultCompressionOid;
+	else
+		att->attcompression = InvalidOid;
+
 	ReleaseSysCache(tuple);
 }
 
diff --git a/src/backend/access/compression/Makefile b/src/backend/access/compression/Makefile
new file mode 100644
index 0000000000..779f54e785
--- /dev/null
+++ b/src/backend/access/compression/Makefile
@@ -0,0 +1,17 @@
+#-------------------------------------------------------------------------
+#
+# Makefile--
+#    Makefile for access/compression
+#
+# IDENTIFICATION
+#    src/backend/access/compression/Makefile
+#
+#-------------------------------------------------------------------------
+
+subdir = src/backend/access/compression
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+
+OBJS = compress_pglz.o compress_lz4.o
+
+include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/access/compression/compress_lz4.c b/src/backend/access/compression/compress_lz4.c
new file mode 100644
index 0000000000..1856cf7df7
--- /dev/null
+++ b/src/backend/access/compression/compress_lz4.c
@@ -0,0 +1,164 @@
+/*-------------------------------------------------------------------------
+ *
+ * compress_lz4.c
+ *		lz4 compression method.
+ *
+ * Portions Copyright (c) 2021, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ *	  src/backend/access/compression/compress_lz4.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#ifdef HAVE_LIBLZ4
+#include <lz4.h>
+#endif
+
+#include "access/compressamapi.h"
+#include "fmgr.h"
+#include "utils/builtins.h"
+
+/*
+ * lz4_cmcompress - compression routine for lz4 compression method
+ *
+ * Compresses source into dest using the default strategy. Returns the
+ * compressed varlena, or NULL if compression fails.
+ */
+static struct varlena *
+lz4_cmcompress(const struct varlena *value)
+{
+#ifndef HAVE_LIBLZ4
+	ereport(ERROR,
+			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+			 errmsg("not built with lz4 support")));
+#else
+	int32		valsize;
+	int32		len;
+	int32		max_size;
+	struct varlena *tmp = NULL;
+
+	valsize = VARSIZE_ANY_EXHDR(value);
+
+	/*
+	 * Get maximum size of the compressed data that lz4 compression may output
+	 * and allocate the memory for holding the compressed data and the header.
+	 */
+	max_size = LZ4_compressBound(valsize);
+	tmp = (struct varlena *) palloc(max_size + VARHDRSZ_COMPRESS);
+
+	len = LZ4_compress_default(VARDATA_ANY(value),
+							   (char *) tmp + VARHDRSZ_COMPRESS,
+							   valsize, max_size);
+	if (len <= 0)
+		elog(ERROR, "could not compress data with lz4");
+
+	/* data is incompressible so just free the memory and return NULL */
+	if (len > valsize)
+	{
+		pfree(tmp);
+		return NULL;
+	}
+
+	SET_VARSIZE_COMPRESSED(tmp, len + VARHDRSZ_COMPRESS);
+
+	return tmp;
+#endif
+}
+
+/*
+ * lz4_cmdecompress - decompression routine for lz4 compression method
+ *
+ * Returns the decompressed varlena.
+ */
+static struct varlena *
+lz4_cmdecompress(const struct varlena *value)
+{
+#ifndef HAVE_LIBLZ4
+	ereport(ERROR,
+			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+			 errmsg("not built with lz4 support")));
+#else
+	int32		rawsize;
+	struct varlena *result;
+
+	/* allocate memory for holding the uncompressed data */
+	result = (struct varlena *) palloc(VARRAWSIZE_4B_C(value) + VARHDRSZ);
+
+	/* decompress data using lz4 routine */
+	rawsize = LZ4_decompress_safe((char *) value + VARHDRSZ_COMPRESS,
+								  VARDATA(result),
+								  VARSIZE(value) - VARHDRSZ_COMPRESS,
+								  VARRAWSIZE_4B_C(value));
+	if (rawsize < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_DATA_CORRUPTED),
+				 errmsg_internal("compressed lz4 data is corrupt")));
+
+
+	SET_VARSIZE(result, rawsize + VARHDRSZ);
+
+	return result;
+#endif
+}
+
+/*
+ * lz4_cmdecompress_slice - slice decompression routine for lz4 compression
+ *
+ * Decompresses part of the data. Returns the decompressed varlena.
+ */
+static struct varlena *
+lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength)
+{
+#ifndef HAVE_LIBLZ4
+	ereport(ERROR,
+			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+			 errmsg("not built with lz4 support")));
+#else
+	int32		rawsize;
+	struct varlena *result;
+
+	/* allocate memory for holding the uncompressed data */
+	result = (struct varlena *) palloc(VARRAWSIZE_4B_C(value) + VARHDRSZ);
+
+	/* decompress partial data using lz4 routine */
+	rawsize = LZ4_decompress_safe_partial((char *) value + VARHDRSZ_COMPRESS,
+										  VARDATA(result),
+										  VARSIZE(value) - VARHDRSZ_COMPRESS,
+										  slicelength,
+										  VARRAWSIZE_4B_C(value));
+	if (rawsize < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_DATA_CORRUPTED),
+				 errmsg_internal("compressed lz4 data is corrupt")));
+
+	SET_VARSIZE(result, rawsize + VARHDRSZ);
+
+	return result;
+#endif
+}
+
+/* ------------------------------------------------------------------------
+ * Definition of the lz4 compression access method.
+ * ------------------------------------------------------------------------
+ */
+const CompressionAmRoutine lz4_compress_methods = {
+	.type = T_CompressionAmRoutine,
+	.datum_compress = lz4_cmcompress,
+	.datum_decompress = lz4_cmdecompress,
+	.datum_decompress_slice = lz4_cmdecompress_slice
+};
+
+/* lz4 compression handler function */
+Datum
+lz4handler(PG_FUNCTION_ARGS)
+{
+#ifndef HAVE_LIBLZ4
+	ereport(ERROR,
+			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+			 errmsg("not built with lz4 support")));
+#else
+	PG_RETURN_POINTER(&lz4_compress_methods);
+#endif
+}
diff --git a/src/backend/access/compression/compress_pglz.c b/src/backend/access/compression/compress_pglz.c
new file mode 100644
index 0000000000..8a4bf427cf
--- /dev/null
+++ b/src/backend/access/compression/compress_pglz.c
@@ -0,0 +1,138 @@
+/*-------------------------------------------------------------------------
+ *
+ * compress_pglz.c
+ *	  pglz compression method
+ *
+ * Portions Copyright (c) 2021, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ *	  src/backend/access/compression/compress_pglz.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "access/compressamapi.h"
+#include "common/pg_lzcompress.h"
+
+#include "fmgr.h"
+#include "utils/builtins.h"
+
+/*
+ * pglz_cmcompress - compression routine for pglz compression method
+ *
+ * Compresses source into dest using the default strategy. Returns the
+ * compressed varlena, or NULL if compression fails.
+ */
+static struct varlena *
+pglz_cmcompress(const struct varlena *value)
+{
+	int32		valsize,
+				len;
+	struct varlena *tmp = NULL;
+
+	valsize = VARSIZE_ANY_EXHDR(DatumGetPointer(value));
+
+	/*
+	 * No point in wasting a palloc cycle if value size is outside the allowed
+	 * range for compression.
+	 */
+	if (valsize < PGLZ_strategy_default->min_input_size ||
+		valsize > PGLZ_strategy_default->max_input_size)
+		return NULL;
+
+	/*
+	 * Get maximum size of the compressed data that pglz compression may output
+	 * and allocate the memory for holding the compressed data and the header.
+	 */
+	tmp = (struct varlena *) palloc(PGLZ_MAX_OUTPUT(valsize) +
+									VARHDRSZ_COMPRESS);
+
+	len = pglz_compress(VARDATA_ANY(value),
+						valsize,
+						(char *) tmp + VARHDRSZ_COMPRESS,
+						NULL);
+	if (len < 0)
+	{
+		pfree(tmp);
+		return NULL;
+	}
+
+	SET_VARSIZE_COMPRESSED(tmp, len + VARHDRSZ_COMPRESS);
+
+	return tmp;
+}
+
+/*
+ * pglz_cmdecompress - decompression routine for pglz compression method
+ *
+ * Returns the decompressed varlena.
+ */
+static struct varlena *
+pglz_cmdecompress(const struct varlena *value)
+{
+	struct varlena *result;
+	int32		rawsize;
+
+	result = (struct varlena *) palloc(VARRAWSIZE_4B_C(value) + VARHDRSZ);
+
+	rawsize = pglz_decompress((char *) value + VARHDRSZ_COMPRESS,
+							  VARSIZE(value) - VARHDRSZ_COMPRESS,
+							  VARDATA(result),
+							  VARRAWSIZE_4B_C(value), true);
+	if (rawsize < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_DATA_CORRUPTED),
+				 errmsg_internal("compressed pglz data is corrupt")));
+
+	SET_VARSIZE(result, rawsize + VARHDRSZ);
+
+	return result;
+}
+
+/*
+ * pglz_decompress - slice decompression routine for pglz compression method
+ *
+ * Decompresses part of the data. Returns the decompressed varlena.
+ */
+static struct varlena *
+pglz_cmdecompress_slice(const struct varlena *value,
+						int32 slicelength)
+{
+	struct varlena *result;
+	int32		rawsize;
+
+	result = (struct varlena *) palloc(slicelength + VARHDRSZ);
+
+	rawsize = pglz_decompress((char *) value + VARHDRSZ_COMPRESS,
+							  VARSIZE(value) - VARHDRSZ_COMPRESS,
+							  VARDATA(result),
+							  slicelength, false);
+	if (rawsize < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_DATA_CORRUPTED),
+				 errmsg_internal("compressed pglz data is corrupt")));
+
+	SET_VARSIZE(result, rawsize + VARHDRSZ);
+
+	return result;
+}
+
+/* ------------------------------------------------------------------------
+ * Definition of the pglz compression access method.
+ * ------------------------------------------------------------------------
+ */
+const CompressionAmRoutine pglz_compress_methods = {
+	.type = T_CompressionAmRoutine,
+	.datum_compress = pglz_cmcompress,
+	.datum_decompress = pglz_cmdecompress,
+	.datum_decompress_slice = pglz_cmdecompress_slice
+};
+
+/* pglz compression handler function */
+Datum
+pglzhandler(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_POINTER(&pglz_compress_methods);
+}
diff --git a/src/backend/access/table/toast_helper.c b/src/backend/access/table/toast_helper.c
index fb36151ce5..53f78f9c3e 100644
--- a/src/backend/access/table/toast_helper.c
+++ b/src/backend/access/table/toast_helper.c
@@ -54,6 +54,7 @@ toast_tuple_init(ToastTupleContext *ttc)
 
 		ttc->ttc_attr[i].tai_colflags = 0;
 		ttc->ttc_attr[i].tai_oldexternal = NULL;
+		ttc->ttc_attr[i].tai_compression = att->attcompression;
 
 		if (ttc->ttc_oldvalues != NULL)
 		{
@@ -226,9 +227,11 @@ void
 toast_tuple_try_compression(ToastTupleContext *ttc, int attribute)
 {
 	Datum	   *value = &ttc->ttc_values[attribute];
-	Datum		new_value = toast_compress_datum(*value);
+	Datum		new_value;
 	ToastAttrInfo *attr = &ttc->ttc_attr[attribute];
 
+	new_value = toast_compress_datum(*value, attr->tai_compression);
+
 	if (DatumGetPointer(new_value) != NULL)
 	{
 		/* successful compression */
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 6f615e6622..9b451eaa71 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -17,6 +17,7 @@
 #include <unistd.h>
 #include <signal.h>
 
+#include "access/compressamapi.h"
 #include "access/genam.h"
 #include "access/heapam.h"
 #include "access/htup_details.h"
@@ -731,6 +732,10 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
 	attrtypes[attnum]->attcacheoff = -1;
 	attrtypes[attnum]->atttypmod = -1;
 	attrtypes[attnum]->attislocal = true;
+	if (IsStorageCompressible(attrtypes[attnum]->attstorage))
+		attrtypes[attnum]->attcompression = DefaultCompressionOid;
+	else
+		attrtypes[attnum]->attcompression = InvalidOid;
 
 	if (nullness == BOOTCOL_NULL_FORCE_NOT_NULL)
 	{
diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index b159958112..f5bb37b972 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -187,7 +187,9 @@ my $GenbkiNextOid = $FirstGenbkiObjectId;
 my $C_COLLATION_OID =
   Catalog::FindDefinedSymbolFromData($catalog_data{pg_collation},
 	'C_COLLATION_OID');
-
+my $PGLZ_COMPRESSION_AM_OID =
+  Catalog::FindDefinedSymbolFromData($catalog_data{pg_am},
+	'PGLZ_COMPRESSION_AM_OID');
 
 # Fill in pg_class.relnatts by looking at the referenced catalog's schema.
 # This is ugly but there's no better place; Catalog::AddDefaultValues
@@ -906,6 +908,9 @@ sub morph_row_for_pgattr
 	$row->{attcollation} =
 	  $type->{typcollation} ne '0' ? $C_COLLATION_OID : 0;
 
+	$row->{attcompression} =
+	  $type->{typstorage} ne 'p' && $type->{typstorage} ne 'e' ? $PGLZ_COMPRESSION_AM_OID : 0;
+
 	if (defined $attr->{forcenotnull})
 	{
 		$row->{attnotnull} = 't';
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 9abc4a1f55..b53b6b50e6 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -29,6 +29,7 @@
  */
 #include "postgres.h"
 
+#include "access/compressamapi.h"
 #include "access/genam.h"
 #include "access/htup_details.h"
 #include "access/multixact.h"
@@ -789,6 +790,7 @@ InsertPgAttributeTuples(Relation pg_attribute_rel,
 		slot[slotCount]->tts_values[Anum_pg_attribute_attislocal - 1] = BoolGetDatum(attrs->attislocal);
 		slot[slotCount]->tts_values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(attrs->attinhcount);
 		slot[slotCount]->tts_values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(attrs->attcollation);
+		slot[slotCount]->tts_values[Anum_pg_attribute_attcompression - 1] = CharGetDatum(attrs->attcompression);
 		if (attoptions && attoptions[natts] != (Datum) 0)
 			slot[slotCount]->tts_values[Anum_pg_attribute_attoptions - 1] = attoptions[natts];
 		else
@@ -1715,6 +1717,8 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
 		/* Unset this so no one tries to look up the generation expression */
 		attStruct->attgenerated = '\0';
 
+		attStruct->attcompression = InvalidOid;
+
 		/*
 		 * Change the column name to something that isn't likely to conflict
 		 */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 1514937748..d1d6bdf470 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -24,6 +24,7 @@
 #include <unistd.h>
 
 #include "access/amapi.h"
+#include "access/compressamapi.h"
 #include "access/heapam.h"
 #include "access/multixact.h"
 #include "access/reloptions.h"
@@ -348,6 +349,7 @@ ConstructTupleDescriptor(Relation heapRelation,
 			to->attbyval = from->attbyval;
 			to->attstorage = from->attstorage;
 			to->attalign = from->attalign;
+			to->attcompression = from->attcompression;
 		}
 		else
 		{
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index d7b806020d..a549481557 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -220,6 +220,11 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
 	TupleDescAttr(tupdesc, 1)->attstorage = TYPSTORAGE_PLAIN;
 	TupleDescAttr(tupdesc, 2)->attstorage = TYPSTORAGE_PLAIN;
 
+	/* Toast field should not be compressed */
+	TupleDescAttr(tupdesc, 0)->attcompression = InvalidOid;
+	TupleDescAttr(tupdesc, 1)->attcompression = InvalidOid;
+	TupleDescAttr(tupdesc, 2)->attcompression = InvalidOid;
+
 	/*
 	 * Toast tables for regular relations go in pg_toast; those for temp
 	 * relations go into the per-backend temp-toast-table namespace.
diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c
index eff9535ed0..3ad4a61739 100644
--- a/src/backend/commands/amcmds.c
+++ b/src/backend/commands/amcmds.c
@@ -175,6 +175,16 @@ get_table_am_oid(const char *amname, bool missing_ok)
 	return get_am_type_oid(amname, AMTYPE_TABLE, missing_ok);
 }
 
+/*
+ * get_compression_am_oid - given an access method name, look up its OID
+ *		and verify it corresponds to an compression AM.
+ */
+Oid
+get_compression_am_oid(const char *amname, bool missing_ok)
+{
+	return get_am_type_oid(amname, AMTYPE_COMPRESSION, missing_ok);
+}
+
 /*
  * get_am_oid - given an access method name, look up its OID.
  *		The type is not checked.
diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
index dce882012e..1d17dc0d6b 100644
--- a/src/backend/commands/createas.c
+++ b/src/backend/commands/createas.c
@@ -61,6 +61,7 @@ typedef struct
 	CommandId	output_cid;		/* cmin to insert in output tuples */
 	int			ti_options;		/* table_tuple_insert performance options */
 	BulkInsertState bistate;	/* bulk insert state */
+	TupleTableSlot *decompress_tuple_slot;	/* to hold the decompress tuple */
 } DR_intorel;
 
 /* utility functions for CTAS definition creation */
@@ -581,6 +582,15 @@ intorel_receive(TupleTableSlot *slot, DestReceiver *self)
 	/* Nothing to insert if WITH NO DATA is specified. */
 	if (!myState->into->skipData)
 	{
+		/*
+		 * Compare the compression method of the compressed attribute in the
+		 * source tuple with target attribute and if those are different then
+		 * decompress those attributes.
+		 */
+		slot = CompareCompressionMethodAndDecompress(slot,
+													 &myState->decompress_tuple_slot,
+													 myState->rel->rd_att);
+
 		/*
 		 * Note that the input slot might not be of the type of the target
 		 * relation. That's supported by table_tuple_insert(), but slightly
@@ -619,6 +629,10 @@ intorel_shutdown(DestReceiver *self)
 	/* close rel, but keep lock until commit */
 	table_close(myState->rel, NoLock);
 	myState->rel = NULL;
+
+	/* release the slot used for decompressing the tuple */
+	if (myState->decompress_tuple_slot)
+		ExecDropSingleTupleTableSlot(myState->decompress_tuple_slot);
 }
 
 /*
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index c5c25ce11d..713fc3fceb 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -56,6 +56,7 @@ typedef struct
 	CommandId	output_cid;		/* cmin to insert in output tuples */
 	int			ti_options;		/* table_tuple_insert performance options */
 	BulkInsertState bistate;	/* bulk insert state */
+	TupleTableSlot *decompress_tuple_slot;	/* to hold the decompress tuple */
 } DR_transientrel;
 
 static int	matview_maintenance_depth = 0;
@@ -486,6 +487,15 @@ transientrel_receive(TupleTableSlot *slot, DestReceiver *self)
 {
 	DR_transientrel *myState = (DR_transientrel *) self;
 
+	/*
+	 * Compare the compression method of the compressed attribute in the
+	 * source tuple with target attribute and if those are different then
+	 * decompress those attributes.
+	 */
+	slot = CompareCompressionMethodAndDecompress(slot,
+												 &myState->decompress_tuple_slot,
+												 myState->transientrel->rd_att);
+
 	/*
 	 * Note that the input slot might not be of the type of the target
 	 * relation. That's supported by table_tuple_insert(), but slightly less
@@ -521,6 +531,10 @@ transientrel_shutdown(DestReceiver *self)
 	/* close transientrel, but keep lock until commit */
 	table_close(myState->transientrel, NoLock);
 	myState->transientrel = NULL;
+
+	/* release the slot used for decompressing the tuple */
+	if (myState->decompress_tuple_slot)
+		ExecDropSingleTupleTableSlot(myState->decompress_tuple_slot);
 }
 
 /*
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 420991e315..dd81d5bf4e 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -15,6 +15,7 @@
 #include "postgres.h"
 
 #include "access/attmap.h"
+#include "access/compressamapi.h"
 #include "access/genam.h"
 #include "access/heapam.h"
 #include "access/heapam_xlog.h"
@@ -559,7 +560,7 @@ static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx,
 static List *GetParentedForeignKeyRefs(Relation partition);
 static void ATDetachCheckNoForeignKeyRefs(Relation partition);
 static void ATExecAlterCollationRefreshVersion(Relation rel, List *coll);
-
+static Oid GetAttributeCompression(Form_pg_attribute att, char *compression);
 
 /* ----------------------------------------------------------------
  *		DefineRelation
@@ -853,6 +854,18 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
 
 		if (colDef->generated)
 			attr->attgenerated = colDef->generated;
+
+		/*
+		 * lookup attribute's compression method and store its Oid in the
+		 * attr->attcompression.
+		 */
+		if (relkind == RELKIND_RELATION ||
+			relkind == RELKIND_PARTITIONED_TABLE ||
+			relkind == RELKIND_MATVIEW)
+			attr->attcompression =
+				GetAttributeCompression(attr, colDef->compression);
+		else
+			attr->attcompression = InvalidOid;
 	}
 
 	/*
@@ -2397,6 +2410,21 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
 									   storage_name(def->storage),
 									   storage_name(attribute->attstorage))));
 
+				/* Copy/check compression parameter */
+				if (OidIsValid(attribute->attcompression))
+				{
+					char *compression = get_am_name(attribute->attcompression);
+
+					if (!def->compression)
+						def->compression = compression;
+					else if (strcmp(def->compression, compression) != 0)
+						ereport(ERROR,
+								(errcode(ERRCODE_DATATYPE_MISMATCH),
+								 errmsg("column \"%s\" has a compression method conflict",
+										attributeName),
+								 errdetail("%s versus %s", def->compression, compression)));
+				}
+
 				def->inhcount++;
 				/* Merge of NOT NULL constraints = OR 'em together */
 				def->is_not_null |= attribute->attnotnull;
@@ -2431,6 +2459,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
 				def->collOid = attribute->attcollation;
 				def->constraints = NIL;
 				def->location = -1;
+				def->compression = get_am_name(attribute->attcompression);
 				inhSchema = lappend(inhSchema, def);
 				newattmap->attnums[parent_attno - 1] = ++child_attno;
 			}
@@ -2676,6 +2705,19 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
 									   storage_name(def->storage),
 									   storage_name(newdef->storage))));
 
+				/* Copy compression parameter */
+				if (!def->compression)
+					def->compression = newdef->compression;
+				else if (newdef->compression)
+				{
+					if (strcmp(def->compression, newdef->compression))
+						ereport(ERROR,
+								(errcode(ERRCODE_DATATYPE_MISMATCH),
+								 errmsg("column \"%s\" has a compression method conflict",
+										attributeName),
+								 errdetail("%s versus %s", def->compression, newdef->compression)));
+				}
+
 				/* Mark the column as locally defined */
 				def->is_local = true;
 				/* Merge of NOT NULL constraints = OR 'em together */
@@ -6341,6 +6383,18 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
 	attribute.attislocal = colDef->is_local;
 	attribute.attinhcount = colDef->inhcount;
 	attribute.attcollation = collOid;
+
+	/*
+	 * lookup attribute's compression method and store its Oid in the
+	 * attr->attcompression.
+	 */
+	if (rel->rd_rel->relkind == RELKIND_RELATION ||
+		rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+		attribute.attcompression = GetAttributeCompression(&attribute,
+														   colDef->compression);
+	else
+		attribute.attcompression = InvalidOid;
+
 	/* attribute.attacl is handled by InsertPgAttributeTuples() */
 
 	ReleaseSysCache(typeTuple);
@@ -11860,6 +11914,22 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
 
 	ReleaseSysCache(typeTuple);
 
+	/* Setup attribute compression */
+	if (rel->rd_rel->relkind == RELKIND_RELATION ||
+		rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+	{
+		/*
+		 * InvalidOid for the plain/external storage otherwise default
+		 * compression id.
+		 */
+		if (!IsStorageCompressible(tform->typstorage))
+			attTup->attcompression = InvalidOid;
+		else if (!OidIsValid(attTup->attcompression))
+			attTup->attcompression = DefaultCompressionOid;
+	}
+	else
+		attTup->attcompression = InvalidOid;
+
 	CatalogTupleUpdate(attrelation, &heapTup->t_self, heapTup);
 
 	table_close(attrelation, RowExclusiveLock);
@@ -17665,3 +17735,42 @@ ATExecAlterCollationRefreshVersion(Relation rel, List *coll)
 	index_update_collation_versions(rel->rd_id, get_collation_oid(coll, false));
 	CacheInvalidateRelcache(rel);
 }
+
+/*
+ * resolve column compression specification to an OID.
+ */
+static Oid
+GetAttributeCompression(Form_pg_attribute att, char *compression)
+{
+	char		typstorage = get_typstorage(att->atttypid);
+	Oid			amoid;
+
+	/*
+	 * No compression for the plain/external storage, refer comments atop
+	 * attcompression parameter in pg_attribute.h
+	 */
+	if (!IsStorageCompressible(typstorage))
+	{
+		if (compression == NULL)
+			return InvalidOid;
+
+		ereport(ERROR,
+				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+				 errmsg("column data type %s does not support compression",
+						format_type_be(att->atttypid))));
+	}
+
+	/* fallback to default compression if it's not specified */
+	if (compression == NULL)
+		return DefaultCompressionOid;
+
+	amoid = get_compression_am_oid(compression, false);
+
+#ifndef HAVE_LIBLZ4
+	if (amoid == LZ4_COMPRESSION_AM_OID)
+		ereport(ERROR,
+				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+				 errmsg("not built with lz4 support")));
+#endif
+	return amoid;
+}
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 2993ba43e3..f77deee399 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -37,6 +37,8 @@
 
 #include "postgres.h"
 
+#include "access/compressamapi.h"
+#include "access/detoast.h"
 #include "access/heapam.h"
 #include "access/htup_details.h"
 #include "access/tableam.h"
@@ -2036,6 +2038,113 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate,
 	return slot;
 }
 
+/*
+ * Compare the compression method of each compressed value with the
+ * compression method of the target attribute.  If the compression method
+ * of the compressed value is not supported in the target attribute then
+ * decompress the value.  If any of the value need to decompress then we
+ * need to store that into the new slot.
+ *
+ * The slot will hold the input slot but if any of the value need to be
+ * decompressed then the new slot will be stored into this and the old
+ * slot will be dropped.
+ */
+TupleTableSlot *
+CompareCompressionMethodAndDecompress(TupleTableSlot *slot,
+									  TupleTableSlot **outslot,
+									  TupleDesc targetTupDesc)
+{
+	int			i;
+	int			attnum;
+	int			natts = slot->tts_tupleDescriptor->natts;
+	bool		decompressed_any = false;
+	bool		slot_tup_deformed = false;
+	Oid			cmoid;
+	TupleDesc	tupleDesc = slot->tts_tupleDescriptor;
+
+	if (natts == 0)
+		return slot;
+
+	/*
+	 * Loop over all the attributes in the tuple and check if any attribute is
+	 * compressed and its compression method is not same as the target
+	 * atrribute's compression method then decompress it.
+	 */
+	for (i = 0; i < natts; i++)
+	{
+		attnum = tupleDesc->attrs[i].attnum;
+
+		if (TupleDescAttr(tupleDesc, i)->attlen == -1)
+		{
+			struct varlena *new_value;
+
+			/* fetch the values of all the attribute, if not already done */
+			if (!slot_tup_deformed)
+			{
+				slot_getallattrs(slot);
+				slot_tup_deformed = true;
+			}
+
+			/* nothing to be done, if the value is null */
+			if (slot->tts_isnull[attnum - 1])
+				continue;
+
+			new_value = (struct varlena *)
+				DatumGetPointer(slot->tts_values[attnum - 1]);
+
+			/*
+			 * Get the compression method Oid stored in the toast header and
+			 * compare it with the compression method of the target.
+			 */
+			cmoid = toast_get_compression_oid(new_value);
+			if (OidIsValid(cmoid) &&
+				targetTupDesc->attrs[i].attcompression != cmoid)
+			{
+				new_value = detoast_attr(new_value);
+				slot->tts_values[attnum - 1] = PointerGetDatum(new_value);
+				decompressed_any = true;
+			}
+		}
+	}
+
+	/*
+	 * If we have decompressed any of the fields then we need to copy the
+	 * values/null array from oldslot to the new slot and materialize the new
+	 * slot.
+	 */
+	if (decompressed_any)
+	{
+		TupleTableSlot *newslot = *outslot;
+
+		/*
+		 * If the called has passed an invalid slot then create a new slot.
+		 * Otherwise, just clear the existing tuple from the slot.  This slot
+		 * should be stored by the caller so that it can be reused for
+		 * decompressing the subsequent tuples.
+		 */
+		if (newslot == NULL)
+			newslot = MakeSingleTupleTableSlot(tupleDesc, slot->tts_ops);
+		else
+			ExecClearTuple(newslot);
+
+		/*
+		 * Copy the value/null array to the new slot and materialize it,
+		 * before clearing the tuple from the old slot.
+		 */
+		memcpy(newslot->tts_values, slot->tts_values, natts * sizeof(Datum));
+		memcpy(newslot->tts_isnull, slot->tts_isnull, natts * sizeof(bool));
+		ExecStoreVirtualTuple(newslot);
+		ExecMaterializeSlot(newslot);
+		ExecClearTuple(slot);
+
+		*outslot = newslot;
+
+		return newslot;
+	}
+
+	return slot;
+}
+
 /* ----------------------------------------------------------------
  *	   ExecModifyTable
  *
@@ -2244,6 +2353,15 @@ ExecModifyTable(PlanState *pstate)
 				slot = ExecFilterJunk(junkfilter, slot);
 		}
 
+		/*
+		 * Compare the compression method of the compressed attribute in the
+		 * source tuple with target attribute and if those are different then
+		 * decompress those attributes.
+		 */
+		slot = CompareCompressionMethodAndDecompress(slot,
+									&node->mt_decompress_tuple_slot,
+									resultRelInfo->ri_RelationDesc->rd_att);
+
 		switch (operation)
 		{
 			case CMD_INSERT:
@@ -2876,6 +2994,10 @@ ExecEndModifyTable(ModifyTableState *node)
 			ExecDropSingleTupleTableSlot(node->mt_root_tuple_slot);
 	}
 
+	/* release the slot used for decompressing the tuple */
+	if (node->mt_decompress_tuple_slot)
+		ExecDropSingleTupleTableSlot(node->mt_decompress_tuple_slot);
+
 	/*
 	 * Free the exprcontext
 	 */
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 65bbc18ecb..1338e04409 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2966,6 +2966,7 @@ _copyColumnDef(const ColumnDef *from)
 
 	COPY_STRING_FIELD(colname);
 	COPY_NODE_FIELD(typeName);
+	COPY_STRING_FIELD(compression);
 	COPY_SCALAR_FIELD(inhcount);
 	COPY_SCALAR_FIELD(is_local);
 	COPY_SCALAR_FIELD(is_not_null);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index c2d73626fc..f3592003da 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -2599,6 +2599,7 @@ _equalColumnDef(const ColumnDef *a, const ColumnDef *b)
 {
 	COMPARE_STRING_FIELD(colname);
 	COMPARE_NODE_FIELD(typeName);
+	COMPARE_STRING_FIELD(compression);
 	COMPARE_SCALAR_FIELD(inhcount);
 	COMPARE_SCALAR_FIELD(is_local);
 	COMPARE_SCALAR_FIELD(is_not_null);
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index 49357ac5c2..38226530c6 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -3897,6 +3897,8 @@ raw_expression_tree_walker(Node *node,
 
 				if (walker(coldef->typeName, context))
 					return true;
+				if (walker(coldef->compression, context))
+					return true;
 				if (walker(coldef->raw_default, context))
 					return true;
 				if (walker(coldef->collClause, context))
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index f5dcedf6e8..0605ef3f84 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -2863,6 +2863,7 @@ _outColumnDef(StringInfo str, const ColumnDef *node)
 
 	WRITE_STRING_FIELD(colname);
 	WRITE_NODE_FIELD(typeName);
+	WRITE_STRING_FIELD(compression);
 	WRITE_INT_FIELD(inhcount);
 	WRITE_BOOL_FIELD(is_local);
 	WRITE_BOOL_FIELD(is_not_null);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index dd72a9fc3c..52d92df25d 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -596,6 +596,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type <list>		hash_partbound
 %type <defelt>		hash_partbound_elem
 
+%type <str>	optColumnCompression
+
 /*
  * Non-keyword token types.  These are hard-wired into the "flex" lexer.
  * They must be listed first so that their numeric codes do not depend on
@@ -631,9 +633,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 	CACHE CALL CALLED CASCADE CASCADED CASE CAST CATALOG_P CHAIN CHAR_P
 	CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
 	CLUSTER COALESCE COLLATE COLLATION COLUMN COLUMNS COMMENT COMMENTS COMMIT
-	COMMITTED CONCURRENTLY CONFIGURATION CONFLICT CONNECTION CONSTRAINT
-	CONSTRAINTS CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE
-	CROSS CSV CUBE CURRENT_P
+	COMMITTED COMPRESSION CONCURRENTLY CONFIGURATION CONFLICT
+	CONNECTION CONSTRAINT CONSTRAINTS CONTENT_P CONTINUE_P CONVERSION_P COPY
+	COST CREATE CROSS CSV CUBE CURRENT_P
 	CURRENT_CATALOG CURRENT_DATE CURRENT_ROLE CURRENT_SCHEMA
 	CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
 
@@ -3421,11 +3423,12 @@ TypedTableElement:
 			| TableConstraint					{ $$ = $1; }
 		;
 
-columnDef:	ColId Typename create_generic_options ColQualList
+columnDef:	ColId Typename optColumnCompression create_generic_options ColQualList
 				{
 					ColumnDef *n = makeNode(ColumnDef);
 					n->colname = $1;
 					n->typeName = $2;
+					n->compression = $3;
 					n->inhcount = 0;
 					n->is_local = true;
 					n->is_not_null = false;
@@ -3434,8 +3437,8 @@ columnDef:	ColId Typename create_generic_options ColQualList
 					n->raw_default = NULL;
 					n->cooked_default = NULL;
 					n->collOid = InvalidOid;
-					n->fdwoptions = $3;
-					SplitColQualList($4, &n->constraints, &n->collClause,
+					n->fdwoptions = $4;
+					SplitColQualList($5, &n->constraints, &n->collClause,
 									 yyscanner);
 					n->location = @1;
 					$$ = (Node *)n;
@@ -3480,6 +3483,14 @@ columnOptions:	ColId ColQualList
 				}
 		;
 
+optColumnCompression:
+					COMPRESSION name
+					{
+						$$ = $2;
+					}
+					| /*EMPTY*/	{ $$ = NULL; }
+				;
+
 ColQualList:
 			ColQualList ColConstraint				{ $$ = lappend($1, $2); }
 			| /*EMPTY*/								{ $$ = NIL; }
@@ -3710,6 +3721,7 @@ TableLikeOption:
 				| INDEXES			{ $$ = CREATE_TABLE_LIKE_INDEXES; }
 				| STATISTICS		{ $$ = CREATE_TABLE_LIKE_STATISTICS; }
 				| STORAGE			{ $$ = CREATE_TABLE_LIKE_STORAGE; }
+				| COMPRESSION		{ $$ = CREATE_TABLE_LIKE_COMPRESSION; }
 				| ALL				{ $$ = CREATE_TABLE_LIKE_ALL; }
 		;
 
@@ -15285,6 +15297,7 @@ unreserved_keyword:
 			| COMMENTS
 			| COMMIT
 			| COMMITTED
+			| COMPRESSION
 			| CONFIGURATION
 			| CONFLICT
 			| CONNECTION
@@ -15805,6 +15818,7 @@ bare_label_keyword:
 			| COMMENTS
 			| COMMIT
 			| COMMITTED
+			| COMPRESSION
 			| CONCURRENTLY
 			| CONFIGURATION
 			| CONFLICT
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index b31f3afa03..cf4413da64 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -27,6 +27,7 @@
 #include "postgres.h"
 
 #include "access/amapi.h"
+#include "access/compressamapi.h"
 #include "access/htup_details.h"
 #include "access/relation.h"
 #include "access/reloptions.h"
@@ -1082,6 +1083,13 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
 		else
 			def->storage = 0;
 
+		/* Likewise, copy compression if requested */
+		if ((table_like_clause->options & CREATE_TABLE_LIKE_COMPRESSION) != 0
+			&& OidIsValid(attribute->attcompression))
+			def->compression = get_am_name(attribute->attcompression);
+		else
+			def->compression = NULL;
+
 		/* Likewise, copy comment if requested */
 		if ((table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS) &&
 			(comment = GetComment(attribute->attrelid,
diff --git a/src/backend/utils/adt/pseudotypes.c b/src/backend/utils/adt/pseudotypes.c
index c2f910d606..fe133c76c2 100644
--- a/src/backend/utils/adt/pseudotypes.c
+++ b/src/backend/utils/adt/pseudotypes.c
@@ -383,6 +383,7 @@ PSEUDOTYPE_DUMMY_IO_FUNCS(language_handler);
 PSEUDOTYPE_DUMMY_IO_FUNCS(fdw_handler);
 PSEUDOTYPE_DUMMY_IO_FUNCS(table_am_handler);
 PSEUDOTYPE_DUMMY_IO_FUNCS(index_am_handler);
+PSEUDOTYPE_DUMMY_IO_FUNCS(compression_am_handler);
 PSEUDOTYPE_DUMMY_IO_FUNCS(tsm_handler);
 PSEUDOTYPE_DUMMY_IO_FUNCS(internal);
 PSEUDOTYPE_DUMMY_IO_FUNCS(anyelement);
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 479ed9ae54..a35abe5f1a 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -17,9 +17,11 @@
 #include <ctype.h>
 #include <limits.h>
 
+#include "access/compressamapi.h"
 #include "access/detoast.h"
 #include "catalog/pg_collation.h"
 #include "catalog/pg_type.h"
+#include "commands/defrem.h"
 #include "common/hashfn.h"
 #include "common/hex.h"
 #include "common/int.h"
@@ -5299,6 +5301,46 @@ pg_column_size(PG_FUNCTION_ARGS)
 	PG_RETURN_INT32(result);
 }
 
+/*
+ * Return the compression method stored in the compressed attribute.  Return
+ * NULL for non varlena type or the uncompressed data.
+ */
+Datum
+pg_column_compression(PG_FUNCTION_ARGS)
+{
+	Datum		value = PG_GETARG_DATUM(0);
+	int			typlen;
+	Oid			cmoid;
+
+	/* On first call, get the input type's typlen, and save at *fn_extra */
+	if (fcinfo->flinfo->fn_extra == NULL)
+	{
+		/* Lookup the datatype of the supplied argument */
+		Oid			argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
+
+		typlen = get_typlen(argtypeid);
+		if (typlen == 0)		/* should not happen */
+			elog(ERROR, "cache lookup failed for type %u", argtypeid);
+
+		fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
+													  sizeof(int));
+		*((int *) fcinfo->flinfo->fn_extra) = typlen;
+	}
+	else
+		typlen = *((int *) fcinfo->flinfo->fn_extra);
+
+	if (typlen != -1)
+		PG_RETURN_NULL();
+
+	cmoid =
+		toast_get_compression_oid((struct varlena *) DatumGetPointer(value));
+
+	if (!OidIsValid(cmoid))
+		PG_RETURN_NULL();
+	else
+		PG_RETURN_TEXT_P(cstring_to_text(get_am_name(cmoid)));
+}
+
 /*
  * string_agg - Concatenates values and returns string.
  *
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index eea9f30a79..7332f93a25 100644
--- a/src/bin/pg_dump/pg_backup.h
+++ b/src/bin/pg_dump/pg_backup.h
@@ -160,6 +160,7 @@ typedef struct _dumpOptions
 	int			no_subscriptions;
 	int			no_synchronized_snapshots;
 	int			no_unlogged_table_data;
+	int			no_compression_methods;
 	int			serializable_deferrable;
 	int			disable_triggers;
 	int			outputNoTablespaces;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index eb988d7eb4..46044cb92a 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -387,6 +387,7 @@ main(int argc, char **argv)
 		{"no-synchronized-snapshots", no_argument, &dopt.no_synchronized_snapshots, 1},
 		{"no-unlogged-table-data", no_argument, &dopt.no_unlogged_table_data, 1},
 		{"no-subscriptions", no_argument, &dopt.no_subscriptions, 1},
+		{"no-compression-methods", no_argument, &dopt.no_compression_methods, 1},
 		{"no-sync", no_argument, NULL, 7},
 		{"on-conflict-do-nothing", no_argument, &dopt.do_nothing, 1},
 		{"rows-per-insert", required_argument, NULL, 10},
@@ -1047,6 +1048,7 @@ help(const char *progname)
 	printf(_("  --no-publications            do not dump publications\n"));
 	printf(_("  --no-security-labels         do not dump security label assignments\n"));
 	printf(_("  --no-subscriptions           do not dump subscriptions\n"));
+	printf(_("  --no-compression-methods     do not dump compression methods\n"));
 	printf(_("  --no-synchronized-snapshots  do not use synchronized snapshots in parallel jobs\n"));
 	printf(_("  --no-tablespaces             do not dump tablespace assignments\n"));
 	printf(_("  --no-unlogged-table-data     do not dump unlogged table data\n"));
@@ -8617,6 +8619,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
 {
 	DumpOptions *dopt = fout->dopt;
 	PQExpBuffer q = createPQExpBuffer();
+	bool		createWithCompression;
 
 	for (int i = 0; i < numTables; i++)
 	{
@@ -8702,6 +8705,15 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
 			appendPQExpBufferStr(q,
 								 "'' AS attidentity,\n");
 
+		createWithCompression = (fout->remoteVersion >= 140000);
+
+		if (createWithCompression)
+			appendPQExpBuffer(q,
+							  "am.amname AS attcmname,\n");
+		else
+			appendPQExpBuffer(q,
+							  "NULL AS attcmname,\n");
+
 		if (fout->remoteVersion >= 110000)
 			appendPQExpBufferStr(q,
 								 "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
@@ -8720,7 +8732,12 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
 		/* need left join here to not fail on dropped columns ... */
 		appendPQExpBuffer(q,
 						  "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
-						  "ON a.atttypid = t.oid\n"
+						  "ON a.atttypid = t.oid\n");
+
+		if (createWithCompression)
+			appendPQExpBuffer(q, "LEFT JOIN pg_catalog.pg_am am "
+							  "ON a.attcompression = am.oid\n");
+		appendPQExpBuffer(q,
 						  "WHERE a.attrelid = '%u'::pg_catalog.oid "
 						  "AND a.attnum > 0::pg_catalog.int2\n"
 						  "ORDER BY a.attnum",
@@ -8747,6 +8764,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
 		tbinfo->attcollation = (Oid *) pg_malloc(ntups * sizeof(Oid));
 		tbinfo->attfdwoptions = (char **) pg_malloc(ntups * sizeof(char *));
 		tbinfo->attmissingval = (char **) pg_malloc(ntups * sizeof(char *));
+		tbinfo->attcmnames = (char **) pg_malloc(ntups * sizeof(char *));
 		tbinfo->notnull = (bool *) pg_malloc(ntups * sizeof(bool));
 		tbinfo->inhNotNull = (bool *) pg_malloc(ntups * sizeof(bool));
 		tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(ntups * sizeof(AttrDefInfo *));
@@ -8775,6 +8793,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
 			tbinfo->attcollation[j] = atooid(PQgetvalue(res, j, PQfnumber(res, "attcollation")));
 			tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, j, PQfnumber(res, "attfdwoptions")));
 			tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, j, PQfnumber(res, "attmissingval")));
+			tbinfo->attcmnames[j] = pg_strdup(PQgetvalue(res, j, PQfnumber(res, "attcmname")));
 			tbinfo->attrdefs[j] = NULL; /* fix below */
 			if (PQgetvalue(res, j, PQfnumber(res, "atthasdef"))[0] == 't')
 				hasdefaults = true;
@@ -15832,6 +15851,7 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
 				{
 					bool		print_default;
 					bool		print_notnull;
+					bool		has_non_default_compression;
 
 					/*
 					 * Default value --- suppress if to be printed separately.
@@ -15856,6 +15876,9 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
 						!dopt->binary_upgrade)
 						continue;
 
+					has_non_default_compression = (tbinfo->attcmnames[j] &&
+												   (strcmp(tbinfo->attcmnames[j], "pglz") != 0));
+
 					/* Format properly if not first attr */
 					if (actual_atts == 0)
 						appendPQExpBufferStr(q, " (");
@@ -15891,6 +15914,17 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
 										  tbinfo->atttypnames[j]);
 					}
 
+					/*
+					 * Attribute compression
+					 */
+					if (!dopt->no_compression_methods &&
+						tbinfo->attcmnames[j] && strlen(tbinfo->attcmnames[j]) &&
+						(has_non_default_compression || dopt->binary_upgrade))
+					{
+						appendPQExpBuffer(q, " COMPRESSION %s",
+										  tbinfo->attcmnames[j]);
+					}
+
 					if (print_default)
 					{
 						if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_STORED)
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 0a2213fb06..1789e18f46 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -326,6 +326,7 @@ typedef struct _tableInfo
 	char	   *partbound;		/* partition bound definition */
 	bool		needs_override; /* has GENERATED ALWAYS AS IDENTITY */
 	char	   *amname;			/* relation access method */
+	char	  **attcmnames;		/* per-attribute current compression method */
 
 	/*
 	 * Stuff computed only for dumpable tables.
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index 737e46464a..97791f8dbe 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -2284,9 +2284,9 @@ my %tests = (
 		regexp => qr/^
 			\QCREATE TABLE dump_test.test_table (\E\n
 			\s+\Qcol1 integer NOT NULL,\E\n
-			\s+\Qcol2 text,\E\n
-			\s+\Qcol3 text,\E\n
-			\s+\Qcol4 text,\E\n
+			\s+\Qcol2 text\E\D*,\n
+			\s+\Qcol3 text\E\D*,\n
+			\s+\Qcol4 text\E\D*,\n
 			\s+\QCONSTRAINT test_table_col1_check CHECK ((col1 <= 1000))\E\n
 			\Q)\E\n
 			\QWITH (autovacuum_enabled='false', fillfactor='80');\E\n/xm,
@@ -2326,7 +2326,7 @@ my %tests = (
 		regexp => qr/^
 			\QCREATE TABLE dump_test.test_second_table (\E
 			\n\s+\Qcol1 integer,\E
-			\n\s+\Qcol2 text\E
+			\n\s+\Qcol2 text\E\D*
 			\n\);
 			/xm,
 		like =>
@@ -2441,7 +2441,7 @@ my %tests = (
 			\n\s+\Qcol1 integer,\E
 			\n\s+\Qcol2 boolean,\E
 			\n\s+\Qcol3 boolean,\E
-			\n\s+\Qcol4 bit(5),\E
+			\n\s+\Qcol4 bit(5)\E\D*,
 			\n\s+\Qcol5 double precision\E
 			\n\);
 			/xm,
@@ -2459,7 +2459,7 @@ my %tests = (
 		regexp => qr/^
 			\QCREATE TABLE dump_test.test_table_identity (\E\n
 			\s+\Qcol1 integer NOT NULL,\E\n
-			\s+\Qcol2 text\E\n
+			\s+\Qcol2 text\E\D*\n
 			\);
 			.*
 			\QALTER TABLE dump_test.test_table_identity ALTER COLUMN col1 ADD GENERATED ALWAYS AS IDENTITY (\E\n
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 20af5a92b4..ba464d463e 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -170,10 +170,12 @@ describeAccessMethods(const char *pattern, bool verbose)
 					  "  CASE amtype"
 					  " WHEN 'i' THEN '%s'"
 					  " WHEN 't' THEN '%s'"
+					  " WHEN 'c' THEN '%s'"
 					  " END AS \"%s\"",
 					  gettext_noop("Name"),
 					  gettext_noop("Index"),
 					  gettext_noop("Table"),
+					  gettext_noop("Compression"),
 					  gettext_noop("Type"));
 
 	if (verbose)
@@ -1459,7 +1461,7 @@ describeOneTableDetails(const char *schemaname,
 	bool		printTableInitialized = false;
 	int			i;
 	char	   *view_def = NULL;
-	char	   *headers[11];
+	char	   *headers[12];
 	PQExpBufferData title;
 	PQExpBufferData tmpbuf;
 	int			cols;
@@ -1475,7 +1477,8 @@ describeOneTableDetails(const char *schemaname,
 				fdwopts_col = -1,
 				attstorage_col = -1,
 				attstattarget_col = -1,
-				attdescr_col = -1;
+				attdescr_col = -1,
+				attcompression_col = -1;
 	int			numrows;
 	struct
 	{
@@ -1892,6 +1895,20 @@ describeOneTableDetails(const char *schemaname,
 		appendPQExpBufferStr(&buf, ",\n  a.attstorage");
 		attstorage_col = cols++;
 
+		/* compresssion info */
+		if (pset.sversion >= 140000 &&
+			(tableinfo.relkind == RELKIND_RELATION ||
+			 tableinfo.relkind == RELKIND_PARTITIONED_TABLE ||
+			 tableinfo.relkind == RELKIND_MATVIEW))
+		{
+			appendPQExpBufferStr(&buf, ",\n  CASE WHEN attcompression = 0 THEN NULL ELSE "
+								 " (SELECT am.amname "
+								 "  FROM pg_catalog.pg_am am "
+								 "  WHERE am.oid = a.attcompression) "
+								 " END AS attcompression");
+			attcompression_col = cols++;
+		}
+
 		/* stats target, if relevant to relkind */
 		if (tableinfo.relkind == RELKIND_RELATION ||
 			tableinfo.relkind == RELKIND_INDEX ||
@@ -2018,6 +2035,8 @@ describeOneTableDetails(const char *schemaname,
 		headers[cols++] = gettext_noop("FDW options");
 	if (attstorage_col >= 0)
 		headers[cols++] = gettext_noop("Storage");
+	if (attcompression_col >= 0)
+		headers[cols++] = gettext_noop("Compression");
 	if (attstattarget_col >= 0)
 		headers[cols++] = gettext_noop("Stats target");
 	if (attdescr_col >= 0)
@@ -2097,6 +2116,11 @@ describeOneTableDetails(const char *schemaname,
 							  false, false);
 		}
 
+		/* Column compression */
+		if (attcompression_col >= 0)
+			printTableAddCell(&cont, PQgetvalue(res, i, attcompression_col),
+							  false, false);
+
 		/* Statistics target, if the relkind supports this feature */
 		if (attstattarget_col >= 0)
 			printTableAddCell(&cont, PQgetvalue(res, i, attstattarget_col),
diff --git a/src/include/access/compressamapi.h b/src/include/access/compressamapi.h
new file mode 100644
index 0000000000..5a8e23d926
--- /dev/null
+++ b/src/include/access/compressamapi.h
@@ -0,0 +1,99 @@
+/*-------------------------------------------------------------------------
+ *
+ * compressamapi.h
+ *	  API for Postgres compression methods.
+ *
+ * Portions Copyright (c) 2021, PostgreSQL Global Development Group
+ *
+ * src/include/access/compressamapi.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef COMPRESSAMAPI_H
+#define COMPRESSAMAPI_H
+
+#include "postgres.h"
+
+#include "catalog/pg_am_d.h"
+#include "nodes/nodes.h"
+
+/*
+ * Built-in compression method-id.  The toast compression header will store
+ * this in the first 2 bits of the raw length.  These built-in compression
+ * method-id are directly mapped to the built-in compression method oid.
+ */
+typedef enum CompressionId
+{
+	PGLZ_COMPRESSION_ID = 0,
+	LZ4_COMPRESSION_ID = 1
+} CompressionId;
+
+/* Use default compression method if it is not specified. */
+#define DefaultCompressionOid	PGLZ_COMPRESSION_AM_OID
+#define IsStorageCompressible(storage) ((storage) != TYPSTORAGE_PLAIN && \
+										(storage) != TYPSTORAGE_EXTERNAL)
+/* compression handler routines */
+typedef struct varlena *(*cmcompress_function) (const struct varlena *value);
+typedef struct varlena *(*cmdecompress_function) (const struct varlena *value);
+typedef struct varlena *(*cmdecompress_slice_function)
+			(const struct varlena *value, int32 slicelength);
+
+/*
+ * API struct for a compression AM.
+ *
+ * 'datum_compress' - varlena compression function.
+ * 'datum_decompress' - varlena decompression function.
+ * 'datum_decompress_slice' - varlena slice decompression functions.
+ */
+typedef struct CompressionAmRoutine
+{
+	NodeTag		type;
+
+	cmcompress_function datum_compress;
+	cmdecompress_function datum_decompress;
+	cmdecompress_slice_function datum_decompress_slice;
+} CompressionAmRoutine;
+
+extern const CompressionAmRoutine pglz_compress_methods;
+extern const CompressionAmRoutine lz4_compress_methods;
+
+/*
+ * CompressionOidToId - Convert compression Oid to built-in compression id.
+ *
+ * For more details refer comment atop CompressionId in compressamapi.h
+ */
+static inline CompressionId
+CompressionOidToId(Oid cmoid)
+{
+	switch (cmoid)
+	{
+		case PGLZ_COMPRESSION_AM_OID:
+			return PGLZ_COMPRESSION_ID;
+		case LZ4_COMPRESSION_AM_OID:
+			return LZ4_COMPRESSION_ID;
+		default:
+			elog(ERROR, "invalid compression method oid %u", cmoid);
+	}
+}
+
+/*
+ * CompressionIdToOid - Convert built-in compression id to Oid
+ *
+ * For more details refer comment atop CompressionId in compressamapi.h
+ */
+static inline Oid
+CompressionIdToOid(CompressionId cmid)
+{
+	switch (cmid)
+	{
+		case PGLZ_COMPRESSION_ID:
+			return PGLZ_COMPRESSION_AM_OID;
+		case LZ4_COMPRESSION_ID:
+			return LZ4_COMPRESSION_AM_OID;
+		default:
+			elog(ERROR, "invalid compression method id %d", cmid);
+	}
+}
+
+#endif							/* COMPRESSAMAPI_H */
diff --git a/src/include/access/detoast.h b/src/include/access/detoast.h
index 0adf53c77b..6cdc37542d 100644
--- a/src/include/access/detoast.h
+++ b/src/include/access/detoast.h
@@ -89,4 +89,12 @@ extern Size toast_raw_datum_size(Datum value);
  */
 extern Size toast_datum_size(Datum value);
 
+/* ----------
+ * toast_get_compression_oid -
+ *
+ *	Return the compression method oid from the compressed value
+ * ----------
+ */
+extern Oid toast_get_compression_oid(struct varlena *attr);
+
 #endif							/* DETOAST_H */
diff --git a/src/include/access/toast_helper.h b/src/include/access/toast_helper.h
index a9a6d644bc..dca0bc37f3 100644
--- a/src/include/access/toast_helper.h
+++ b/src/include/access/toast_helper.h
@@ -32,6 +32,7 @@ typedef struct
 	struct varlena *tai_oldexternal;
 	int32		tai_size;
 	uint8		tai_colflags;
+	Oid			tai_compression;
 } ToastAttrInfo;
 
 /*
diff --git a/src/include/access/toast_internals.h b/src/include/access/toast_internals.h
index cedfb890d8..31ff91a09c 100644
--- a/src/include/access/toast_internals.h
+++ b/src/include/access/toast_internals.h
@@ -12,6 +12,7 @@
 #ifndef TOAST_INTERNALS_H
 #define TOAST_INTERNALS_H
 
+#include "access/compressamapi.h"
 #include "storage/lockdefs.h"
 #include "utils/relcache.h"
 #include "utils/snapshot.h"
@@ -22,22 +23,22 @@
 typedef struct toast_compress_header
 {
 	int32		vl_len_;		/* varlena header (do not touch directly!) */
-	int32		rawsize;
+	uint32		info;			/* 2 bits for compression method and 30 bits
+								 * rawsize */
 } toast_compress_header;
 
 /*
  * Utilities for manipulation of header information for compressed
  * toast entries.
  */
-#define TOAST_COMPRESS_HDRSZ		((int32) sizeof(toast_compress_header))
-#define TOAST_COMPRESS_RAWSIZE(ptr) (((toast_compress_header *) (ptr))->rawsize)
-#define TOAST_COMPRESS_SIZE(ptr)	((int32) VARSIZE_ANY(ptr) - TOAST_COMPRESS_HDRSZ)
-#define TOAST_COMPRESS_RAWDATA(ptr) \
-	(((char *) (ptr)) + TOAST_COMPRESS_HDRSZ)
-#define TOAST_COMPRESS_SET_RAWSIZE(ptr, len) \
-	(((toast_compress_header *) (ptr))->rawsize = (len))
+#define TOAST_COMPRESS_METHOD(ptr)  (((toast_compress_header *) (ptr))->info >> VARLENA_RAWSIZE_BITS)
+#define TOAST_COMPRESS_SET_SIZE_AND_METHOD(ptr, len, cm_method) \
+	do { \
+		Assert((len) > 0 && (len) <= VARLENA_RAWSIZE_MASK); \
+		((toast_compress_header *) (ptr))->info = ((len) | (cm_method) << VARLENA_RAWSIZE_BITS); \
+	} while (0)
 
-extern Datum toast_compress_datum(Datum value);
+extern Datum toast_compress_datum(Datum value, Oid cmoid);
 extern Oid	toast_get_valid_index(Oid toastoid, LOCKMODE lock);
 
 extern void toast_delete_datum(Relation rel, Datum value, bool is_speculative);
diff --git a/src/include/catalog/pg_am.dat b/src/include/catalog/pg_am.dat
index 6082f0e6a8..605684408c 100644
--- a/src/include/catalog/pg_am.dat
+++ b/src/include/catalog/pg_am.dat
@@ -33,5 +33,11 @@
 { oid => '3580', oid_symbol => 'BRIN_AM_OID',
   descr => 'block range index (BRIN) access method',
   amname => 'brin', amhandler => 'brinhandler', amtype => 'i' },
+{ oid => '4572', oid_symbol => 'PGLZ_COMPRESSION_AM_OID',
+  descr => 'pglz compression access method',
+  amname => 'pglz', amhandler => 'pglzhandler', amtype => 'c' },
+{ oid => '4573', oid_symbol => 'LZ4_COMPRESSION_AM_OID',
+  descr => 'lz4 compression access method',
+  amname => 'lz4', amhandler => 'lz4handler', amtype => 'c' },
 
 ]
diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h
index ced86faef8..65079f3821 100644
--- a/src/include/catalog/pg_am.h
+++ b/src/include/catalog/pg_am.h
@@ -59,6 +59,7 @@ DECLARE_UNIQUE_INDEX_PKEY(pg_am_oid_index, 2652, on pg_am using btree(oid oid_op
  */
 #define AMTYPE_INDEX					'i' /* index access method */
 #define AMTYPE_TABLE					't' /* table access method */
+#define AMTYPE_COMPRESSION				'c'	/* compression access method */
 
 #endif							/* EXPOSE_TO_CLIENT_CODE */
 
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index 3db42abf08..797e78b17c 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -160,6 +160,12 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
 	/* attribute's collation, if any */
 	Oid			attcollation BKI_LOOKUP_OPT(pg_collation);
 
+	/*
+	 * OID of compression AM.  Must be InvalidOid if and only if typstorage is
+	 * 'plain' or 'external'.
+	 */
+	Oid			attcompression BKI_DEFAULT(0);
+
 #ifdef CATALOG_VARLEN			/* variable-length fields start here */
 	/* NOTE: The following fields are not present in tuple descriptors. */
 
@@ -187,7 +193,7 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
  * can access fields beyond attcollation except in a real tuple!
  */
 #define ATTRIBUTE_FIXED_PART_SIZE \
-	(offsetof(FormData_pg_attribute,attcollation) + sizeof(Oid))
+	(offsetof(FormData_pg_attribute,attcompression) + sizeof(Oid))
 
 /* ----------------
  *		Form_pg_attribute corresponds to a pointer to a tuple with
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 4e0c9be58c..4a13844ce6 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -941,6 +941,15 @@
   prorettype => 'void', proargtypes => 'regclass int8',
   prosrc => 'brin_desummarize_range' },
 
+{ oid => '6015', descr => 'pglz compression access method handler',
+  proname => 'pglzhandler', provolatile => 'v',
+  prorettype => 'compression_am_handler', proargtypes => 'internal',
+  prosrc => 'pglzhandler' },
+{ oid => '6016', descr => 'lz4 compression access method handler',
+  proname => 'lz4handler', provolatile => 'v',
+  prorettype => 'compression_am_handler', proargtypes => 'internal',
+  prosrc => 'lz4handler' },
+
 { oid => '338', descr => 'validate an operator class',
   proname => 'amvalidate', provolatile => 'v', prorettype => 'bool',
   proargtypes => 'oid', prosrc => 'amvalidate' },
@@ -7095,6 +7104,10 @@
   descr => 'bytes required to store the value, perhaps with compression',
   proname => 'pg_column_size', provolatile => 's', prorettype => 'int4',
   proargtypes => 'any', prosrc => 'pg_column_size' },
+{ oid => '2121',
+  descr => 'compression method for the compressed datum',
+  proname => 'pg_column_compression', provolatile => 's', prorettype => 'text',
+  proargtypes => 'any', prosrc => 'pg_column_compression' },
 { oid => '2322',
   descr => 'total disk space usage for the specified tablespace',
   proname => 'pg_tablespace_size', provolatile => 'v', prorettype => 'int8',
@@ -7265,6 +7278,13 @@
 { oid => '268', descr => 'I/O',
   proname => 'table_am_handler_out', prorettype => 'cstring',
   proargtypes => 'table_am_handler', prosrc => 'table_am_handler_out' },
+{ oid => '560', descr => 'I/O',
+  proname => 'compression_am_handler_in', proisstrict => 'f',
+  prorettype => 'compression_am_handler', proargtypes => 'cstring',
+  prosrc => 'compression_am_handler_in' },
+{ oid => '561', descr => 'I/O',
+  proname => 'compression_am_handler_out', prorettype => 'cstring',
+  proargtypes => 'compression_am_handler', prosrc => 'compression_am_handler_out' },
 { oid => '5086', descr => 'I/O',
   proname => 'anycompatible_in', prorettype => 'anycompatible',
   proargtypes => 'cstring', prosrc => 'anycompatible_in' },
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index 8959c2f53b..306aabf6c1 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -626,6 +626,11 @@
   typcategory => 'P', typinput => 'index_am_handler_in',
   typoutput => 'index_am_handler_out', typreceive => '-', typsend => '-',
   typalign => 'i' },
+ { oid => '5559',
+  typname => 'compression_am_handler', typlen => '4', typbyval => 't', typtype => 'p',
+  typcategory => 'P', typinput => 'compression_am_handler_in',
+  typoutput => 'compression_am_handler_out', typreceive => '-', typsend => '-',
+  typalign => 'i' },
 { oid => '3310',
   descr => 'pseudo-type for the result of a tablesample method function',
   typname => 'tsm_handler', typlen => '4', typbyval => 't', typtype => 'p',
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 1a79540c94..e5aea8a240 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -139,6 +139,7 @@ extern Datum transformGenericOptions(Oid catalogId,
 extern ObjectAddress CreateAccessMethod(CreateAmStmt *stmt);
 extern Oid	get_index_am_oid(const char *amname, bool missing_ok);
 extern Oid	get_table_am_oid(const char *amname, bool missing_ok);
+extern Oid	get_compression_am_oid(const char *amname, bool missing_ok);
 extern Oid	get_am_oid(const char *amname, bool missing_ok);
 extern char *get_am_name(Oid amOid);
 
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index 071e363d54..6495162a33 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -621,5 +621,7 @@ extern void CheckCmdReplicaIdentity(Relation rel, CmdType cmd);
 
 extern void CheckSubscriptionRelkind(char relkind, const char *nspname,
 									 const char *relname);
-
+extern TupleTableSlot *CompareCompressionMethodAndDecompress(TupleTableSlot *slot,
+												  TupleTableSlot **outslot,
+												  TupleDesc targetTupDesc);
 #endif							/* EXECUTOR_H  */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index b6a88ff76b..18e8ecfd90 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1182,6 +1182,12 @@ typedef struct ModifyTableState
 	 */
 	TupleTableSlot *mt_root_tuple_slot;
 
+	/*
+	 * Slot for storing the modified tuple, incase the target attribute's
+	 * compression method doesn't match with the source table.
+	 */
+	TupleTableSlot *mt_decompress_tuple_slot;
+
 	/* Tuple-routing support info */
 	struct PartitionTupleRouting *mt_partition_tuple_routing;
 
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 40ae489c23..20d6f96f62 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -512,6 +512,7 @@ typedef enum NodeTag
 	T_IndexAmRoutine,			/* in access/amapi.h */
 	T_TableAmRoutine,			/* in access/tableam.h */
 	T_TsmRoutine,				/* in access/tsmapi.h */
+	T_CompressionAmRoutine,		/* in access/compressamapi.h */
 	T_ForeignKeyCacheInfo,		/* in utils/rel.h */
 	T_CallContext,				/* in nodes/parsenodes.h */
 	T_SupportRequestSimplify,	/* in nodes/supportnodes.h */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 236832a2ca..19d2ba26bf 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -646,6 +646,7 @@ typedef struct ColumnDef
 	NodeTag		type;
 	char	   *colname;		/* name of column */
 	TypeName   *typeName;		/* type of column */
+	char	   *compression;	/* compression method for column */
 	int			inhcount;		/* number of times column is inherited */
 	bool		is_local;		/* column has local (non-inherited) def'n */
 	bool		is_not_null;	/* NOT NULL constraint specified? */
@@ -685,6 +686,7 @@ typedef enum TableLikeOption
 	CREATE_TABLE_LIKE_INDEXES = 1 << 5,
 	CREATE_TABLE_LIKE_STATISTICS = 1 << 6,
 	CREATE_TABLE_LIKE_STORAGE = 1 << 7,
+	CREATE_TABLE_LIKE_COMPRESSION = 1 << 8,
 	CREATE_TABLE_LIKE_ALL = PG_INT32_MAX
 } TableLikeOption;
 
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 28083aaac9..ca1f950cbe 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -88,6 +88,7 @@ PG_KEYWORD("comment", COMMENT, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("comments", COMMENTS, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("commit", COMMIT, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("committed", COMMITTED, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("compression", COMPRESSION, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("concurrently", CONCURRENTLY, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL)
 PG_KEYWORD("configuration", CONFIGURATION, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("conflict", CONFLICT, UNRESERVED_KEYWORD, BARE_LABEL)
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 55cab4d2bf..53d378b67d 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -346,6 +346,9 @@
 /* Define to 1 if you have the `z' library (-lz). */
 #undef HAVE_LIBZ
 
+/* Define to 1 if you have the `lz4' library (-llz4). */
+#undef HAVE_LIBLZ4
+
 /* Define to 1 if you have the `link' function. */
 #undef HAVE_LINK
 
diff --git a/src/include/postgres.h b/src/include/postgres.h
index 2ed572004d..667927fd7c 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -145,7 +145,8 @@ typedef union
 	struct						/* Compressed-in-line format */
 	{
 		uint32		va_header;
-		uint32		va_rawsize; /* Original data size (excludes header) */
+		uint32		va_info;	/* Original data size (excludes header) and
+								 * flags */
 		char		va_data[FLEXIBLE_ARRAY_MEMBER]; /* Compressed data */
 	}			va_compressed;
 } varattrib_4b;
@@ -274,14 +275,21 @@ typedef struct
 	(VARSIZE(PTR) - VARHDRSZ + VARHDRSZ_SHORT)
 
 #define VARHDRSZ_EXTERNAL		offsetof(varattrib_1b_e, va_data)
+#define VARHDRSZ_COMPRESS		offsetof(varattrib_4b, va_compressed.va_data)
 
 #define VARDATA_4B(PTR)		(((varattrib_4b *) (PTR))->va_4byte.va_data)
 #define VARDATA_4B_C(PTR)	(((varattrib_4b *) (PTR))->va_compressed.va_data)
 #define VARDATA_1B(PTR)		(((varattrib_1b *) (PTR))->va_data)
 #define VARDATA_1B_E(PTR)	(((varattrib_1b_e *) (PTR))->va_data)
 
+#define VARLENA_RAWSIZE_BITS	30
+#define VARLENA_RAWSIZE_MASK	((1U << VARLENA_RAWSIZE_BITS) - 1)
+
+/* va_info in va_compress contains raw size of datum and optional flags */
 #define VARRAWSIZE_4B_C(PTR) \
-	(((varattrib_4b *) (PTR))->va_compressed.va_rawsize)
+	(((varattrib_4b *) (PTR))->va_compressed.va_info & VARLENA_RAWSIZE_MASK)
+#define VARFLAGS_4B_C(PTR) \
+	(((varattrib_4b *) (PTR))->va_compressed.va_info >> VARLENA_RAWSIZE_BITS)
 
 /* Externally visible macros */
 
diff --git a/src/test/regress/expected/compression.out b/src/test/regress/expected/compression.out
new file mode 100644
index 0000000000..167878e78b
--- /dev/null
+++ b/src/test/regress/expected/compression.out
@@ -0,0 +1,201 @@
+\set HIDE_COMPRESSAM off
+-- test creating table with compression method
+CREATE TABLE cmdata(f1 text COMPRESSION pglz);
+CREATE INDEX idx ON cmdata(f1);
+INSERT INTO cmdata VALUES(repeat('1234567890',1000));
+\d+ cmdata
+                                 Table "public.cmdata"
+ Column | Type | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------+-----------+----------+---------+----------+--------------+-------------
+ f1     | text |           |          |         | extended |              | 
+Indexes:
+    "idx" btree (f1)
+
+CREATE TABLE cmdata1(f1 TEXT COMPRESSION lz4);
+INSERT INTO cmdata1 VALUES(repeat('1234567890',1004));
+\d+ cmdata1
+                                 Table "public.cmdata1"
+ Column | Type | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------+-----------+----------+---------+----------+--------------+-------------
+ f1     | text |           |          |         | extended |              | 
+
+-- try setting compression for incompressible data type
+CREATE TABLE cmdata2 (f1 int COMPRESSION pglz);
+ERROR:  column data type integer does not support compression
+-- verify stored compression method
+SELECT pg_column_compression(f1) FROM cmdata;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+SELECT pg_column_compression(f1) FROM cmdata1;
+ pg_column_compression 
+-----------------------
+ lz4
+(1 row)
+
+-- decompress data slice
+SELECT SUBSTR(f1, 200, 5) FROM cmdata;
+ substr 
+--------
+ 01234
+(1 row)
+
+SELECT SUBSTR(f1, 2000, 50) FROM cmdata1;
+                       substr                       
+----------------------------------------------------
+ 01234567890123456789012345678901234567890123456789
+(1 row)
+
+-- copy with table creation
+SELECT * INTO cmmove1 FROM cmdata;
+SELECT pg_column_compression(f1) FROM cmmove1;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+-- update using datum from different table
+CREATE TABLE cmmove2(f1 text COMPRESSION pglz);
+INSERT INTO cmmove2 VALUES (repeat('1234567890',1004));
+SELECT pg_column_compression(f1) FROM cmmove2;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+UPDATE cmmove2 SET f1 = cmdata.f1 FROM cmdata;
+SELECT pg_column_compression(f1) FROM cmmove2;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+UPDATE cmmove2 SET f1 = cmdata1.f1 FROM cmdata1;
+SELECT pg_column_compression(f1) FROM cmmove2;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+-- copy to existing table
+CREATE TABLE cmmove3(f1 text COMPRESSION pglz);
+INSERT INTO cmmove3 SELECT * FROM cmdata;
+INSERT INTO cmmove3 SELECT * FROM cmdata1;
+SELECT pg_column_compression(f1) FROM cmmove2;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+-- test external compressed data
+CREATE OR REPLACE FUNCTION large_val() RETURNS TEXT LANGUAGE SQL AS
+'select array_agg(md5(g::text))::text from generate_series(1, 256) g';
+CREATE TABLE cmdata2 (f1 text COMPRESSION pglz);
+INSERT INTO cmdata2 select large_val() || repeat('a', 4000);
+SELECT pg_column_compression(f1) FROM cmdata2;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+INSERT INTO cmdata1 SELECT * FROM cmdata2;
+SELECT pg_column_compression(f1) FROM cmdata1;
+ pg_column_compression 
+-----------------------
+ lz4
+ lz4
+(2 rows)
+
+DROP TABLE cmdata2;
+-- test LIKE INCLUDING COMPRESSION
+CREATE TABLE cmdata2 (LIKE cmdata1 INCLUDING COMPRESSION);
+\d+ cmdata2
+                                 Table "public.cmdata2"
+ Column | Type | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------+-----------+----------+---------+----------+--------------+-------------
+ f1     | text |           |          |         | extended |              | 
+
+-- test compression with materialized view
+CREATE MATERIALIZED VIEW mv(x) AS SELECT * FROM cmdata1;
+\d+ mv
+                             Materialized view "public.mv"
+ Column | Type | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------+-----------+----------+---------+----------+--------------+-------------
+ x      | text |           |          |         | extended |              | 
+View definition:
+ SELECT cmdata1.f1 AS x
+   FROM cmdata1;
+
+SELECT pg_column_compression(f1) FROM cmdata1;
+ pg_column_compression 
+-----------------------
+ lz4
+ lz4
+(2 rows)
+
+SELECT pg_column_compression(x) FROM mv;
+ pg_column_compression 
+-----------------------
+ pglz
+ pglz
+(2 rows)
+
+-- test compression with partition
+CREATE TABLE cmpart(f1 text COMPRESSION lz4) PARTITION BY HASH(f1);
+CREATE TABLE cmpart1 PARTITION OF cmpart FOR VALUES WITH (MODULUS 2, REMAINDER 0);
+CREATE TABLE cmpart2(f1 text COMPRESSION pglz);
+ALTER TABLE cmpart ATTACH PARTITION cmpart2 FOR VALUES WITH (MODULUS 2, REMAINDER 1);
+INSERT INTO cmpart VALUES (repeat('123456789',1004));
+INSERT INTO cmpart VALUES (repeat('123456789',4004));
+SELECT pg_column_compression(f1) FROM cmpart;
+ pg_column_compression 
+-----------------------
+ lz4
+ pglz
+(2 rows)
+
+-- test compression with inheritence, error
+CREATE TABLE cminh() INHERITS(cmdata, cmdata1);
+NOTICE:  merging multiple inherited definitions of column "f1"
+ERROR:  column "f1" has a compression method conflict
+DETAIL:  pglz versus lz4
+CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata);
+NOTICE:  merging column "f1" with inherited definition
+ERROR:  column "f1" has a compression method conflict
+DETAIL:  pglz versus lz4
+-- check data is ok
+SELECT length(f1) FROM cmdata;
+ length 
+--------
+  10000
+(1 row)
+
+SELECT length(f1) FROM cmdata1;
+ length 
+--------
+  10040
+  12449
+(2 rows)
+
+SELECT length(f1) FROM cmmove1;
+ length 
+--------
+  10000
+(1 row)
+
+SELECT length(f1) FROM cmmove2;
+ length 
+--------
+  10040
+(1 row)
+
+SELECT length(f1) FROM cmmove3;
+ length 
+--------
+  10000
+  10040
+(2 rows)
+
+\set HIDE_COMPRESSAM on
diff --git a/src/test/regress/expected/compression_1.out b/src/test/regress/expected/compression_1.out
new file mode 100644
index 0000000000..329e7881b0
--- /dev/null
+++ b/src/test/regress/expected/compression_1.out
@@ -0,0 +1,189 @@
+\set HIDE_COMPRESSAM off
+-- test creating table with compression method
+CREATE TABLE cmdata(f1 text COMPRESSION pglz);
+CREATE INDEX idx ON cmdata(f1);
+INSERT INTO cmdata VALUES(repeat('1234567890',1000));
+\d+ cmdata
+                                 Table "public.cmdata"
+ Column | Type | Collation | Nullable | Default | Storage  | Stats target | Description 
+--------+------+-----------+----------+---------+----------+--------------+-------------
+ f1     | text |           |          |         | extended |              | 
+Indexes:
+    "idx" btree (f1)
+
+CREATE TABLE cmdata1(f1 TEXT COMPRESSION lz4);
+ERROR:  not built with lz4 support
+INSERT INTO cmdata1 VALUES(repeat('1234567890',1004));
+ERROR:  relation "cmdata1" does not exist
+LINE 1: INSERT INTO cmdata1 VALUES(repeat('1234567890',1004));
+                    ^
+\d+ cmdata1
+-- try setting compression for incompressible data type
+CREATE TABLE cmdata2 (f1 int COMPRESSION pglz);
+ERROR:  column data type integer does not support compression
+-- verify stored compression method
+SELECT pg_column_compression(f1) FROM cmdata;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+SELECT pg_column_compression(f1) FROM cmdata1;
+ERROR:  relation "cmdata1" does not exist
+LINE 1: SELECT pg_column_compression(f1) FROM cmdata1;
+                                              ^
+-- decompress data slice
+SELECT SUBSTR(f1, 200, 5) FROM cmdata;
+ substr 
+--------
+ 01234
+(1 row)
+
+SELECT SUBSTR(f1, 2000, 50) FROM cmdata1;
+ERROR:  relation "cmdata1" does not exist
+LINE 1: SELECT SUBSTR(f1, 2000, 50) FROM cmdata1;
+                                         ^
+-- copy with table creation
+SELECT * INTO cmmove1 FROM cmdata;
+SELECT pg_column_compression(f1) FROM cmmove1;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+-- update using datum from different table
+CREATE TABLE cmmove2(f1 text COMPRESSION pglz);
+INSERT INTO cmmove2 VALUES (repeat('1234567890',1004));
+SELECT pg_column_compression(f1) FROM cmmove2;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+UPDATE cmmove2 SET f1 = cmdata.f1 FROM cmdata;
+SELECT pg_column_compression(f1) FROM cmmove2;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+UPDATE cmmove2 SET f1 = cmdata1.f1 FROM cmdata1;
+ERROR:  relation "cmdata1" does not exist
+LINE 1: UPDATE cmmove2 SET f1 = cmdata1.f1 FROM cmdata1;
+                                                ^
+SELECT pg_column_compression(f1) FROM cmmove2;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+-- copy to existing table
+CREATE TABLE cmmove3(f1 text COMPRESSION pglz);
+INSERT INTO cmmove3 SELECT * FROM cmdata;
+INSERT INTO cmmove3 SELECT * FROM cmdata1;
+ERROR:  relation "cmdata1" does not exist
+LINE 1: INSERT INTO cmmove3 SELECT * FROM cmdata1;
+                                          ^
+SELECT pg_column_compression(f1) FROM cmmove2;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+-- test external compressed data
+CREATE OR REPLACE FUNCTION large_val() RETURNS TEXT LANGUAGE SQL AS
+'select array_agg(md5(g::text))::text from generate_series(1, 256) g';
+CREATE TABLE cmdata2 (f1 text COMPRESSION pglz);
+INSERT INTO cmdata2 select large_val() || repeat('a', 4000);
+SELECT pg_column_compression(f1) FROM cmdata2;
+ pg_column_compression 
+-----------------------
+ pglz
+(1 row)
+
+INSERT INTO cmdata1 SELECT * FROM cmdata2;
+ERROR:  relation "cmdata1" does not exist
+LINE 1: INSERT INTO cmdata1 SELECT * FROM cmdata2;
+                    ^
+SELECT pg_column_compression(f1) FROM cmdata1;
+ERROR:  relation "cmdata1" does not exist
+LINE 1: SELECT pg_column_compression(f1) FROM cmdata1;
+                                              ^
+DROP TABLE cmdata2;
+-- test LIKE INCLUDING COMPRESSION
+CREATE TABLE cmdata2 (LIKE cmdata1 INCLUDING COMPRESSION);
+ERROR:  relation "cmdata1" does not exist
+LINE 1: CREATE TABLE cmdata2 (LIKE cmdata1 INCLUDING COMPRESSION);
+                                   ^
+\d+ cmdata2
+-- test compression with materialized view
+CREATE MATERIALIZED VIEW mv(x) AS SELECT * FROM cmdata1;
+ERROR:  relation "cmdata1" does not exist
+LINE 1: CREATE MATERIALIZED VIEW mv(x) AS SELECT * FROM cmdata1;
+                                                        ^
+\d+ mv
+SELECT pg_column_compression(f1) FROM cmdata1;
+ERROR:  relation "cmdata1" does not exist
+LINE 1: SELECT pg_column_compression(f1) FROM cmdata1;
+                                              ^
+SELECT pg_column_compression(x) FROM mv;
+ERROR:  relation "mv" does not exist
+LINE 1: SELECT pg_column_compression(x) FROM mv;
+                                             ^
+-- test compression with partition
+CREATE TABLE cmpart(f1 text COMPRESSION lz4) PARTITION BY HASH(f1);
+ERROR:  not built with lz4 support
+CREATE TABLE cmpart1 PARTITION OF cmpart FOR VALUES WITH (MODULUS 2, REMAINDER 0);
+ERROR:  relation "cmpart" does not exist
+CREATE TABLE cmpart2(f1 text COMPRESSION pglz);
+ALTER TABLE cmpart ATTACH PARTITION cmpart2 FOR VALUES WITH (MODULUS 2, REMAINDER 1);
+ERROR:  relation "cmpart" does not exist
+INSERT INTO cmpart VALUES (repeat('123456789',1004));
+ERROR:  relation "cmpart" does not exist
+LINE 1: INSERT INTO cmpart VALUES (repeat('123456789',1004));
+                    ^
+INSERT INTO cmpart VALUES (repeat('123456789',4004));
+ERROR:  relation "cmpart" does not exist
+LINE 1: INSERT INTO cmpart VALUES (repeat('123456789',4004));
+                    ^
+SELECT pg_column_compression(f1) FROM cmpart;
+ERROR:  relation "cmpart" does not exist
+LINE 1: SELECT pg_column_compression(f1) FROM cmpart;
+                                              ^
+-- test compression with inheritence, error
+CREATE TABLE cminh() INHERITS(cmdata, cmdata1);
+ERROR:  relation "cmdata1" does not exist
+CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata);
+NOTICE:  merging column "f1" with inherited definition
+ERROR:  column "f1" has a compression method conflict
+DETAIL:  pglz versus lz4
+-- check data is ok
+SELECT length(f1) FROM cmdata;
+ length 
+--------
+  10000
+(1 row)
+
+SELECT length(f1) FROM cmdata1;
+ERROR:  relation "cmdata1" does not exist
+LINE 1: SELECT length(f1) FROM cmdata1;
+                               ^
+SELECT length(f1) FROM cmmove1;
+ length 
+--------
+  10000
+(1 row)
+
+SELECT length(f1) FROM cmmove2;
+ length 
+--------
+  10000
+(1 row)
+
+SELECT length(f1) FROM cmmove3;
+ length 
+--------
+  10000
+(1 row)
+
+\set HIDE_COMPRESSAM on
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 7204fdb0b4..14f3fa3fc8 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -4898,8 +4898,8 @@ Indexes:
 -- check printing info about access methods
 \dA
 List of access methods
-  Name  | Type  
---------+-------
+  Name  |    Type     
+--------+-------------
  brin   | Index
  btree  | Index
  gin    | Index
@@ -4907,13 +4907,15 @@ List of access methods
  hash   | Index
  heap   | Table
  heap2  | Table
+ lz4    | Compression
+ pglz   | Compression
  spgist | Index
-(8 rows)
+(10 rows)
 
 \dA *
 List of access methods
-  Name  | Type  
---------+-------
+  Name  |    Type     
+--------+-------------
  brin   | Index
  btree  | Index
  gin    | Index
@@ -4921,8 +4923,10 @@ List of access methods
  hash   | Index
  heap   | Table
  heap2  | Table
+ lz4    | Compression
+ pglz   | Compression
  spgist | Index
-(8 rows)
+(10 rows)
 
 \dA h*
 List of access methods
@@ -4947,32 +4951,36 @@ List of access methods
 
 \dA: extra argument "bar" ignored
 \dA+
-                             List of access methods
-  Name  | Type  |       Handler        |              Description               
---------+-------+----------------------+----------------------------------------
- brin   | Index | brinhandler          | block range index (BRIN) access method
- btree  | Index | bthandler            | b-tree index access method
- gin    | Index | ginhandler           | GIN index access method
- gist   | Index | gisthandler          | GiST index access method
- hash   | Index | hashhandler          | hash index access method
- heap   | Table | heap_tableam_handler | heap table access method
- heap2  | Table | heap_tableam_handler | 
- spgist | Index | spghandler           | SP-GiST index access method
-(8 rows)
+                                List of access methods
+  Name  |    Type     |       Handler        |              Description               
+--------+-------------+----------------------+----------------------------------------
+ brin   | Index       | brinhandler          | block range index (BRIN) access method
+ btree  | Index       | bthandler            | b-tree index access method
+ gin    | Index       | ginhandler           | GIN index access method
+ gist   | Index       | gisthandler          | GiST index access method
+ hash   | Index       | hashhandler          | hash index access method
+ heap   | Table       | heap_tableam_handler | heap table access method
+ heap2  | Table       | heap_tableam_handler | 
+ lz4    | Compression | lz4handler           | lz4 compression access method
+ pglz   | Compression | pglzhandler          | pglz compression access method
+ spgist | Index       | spghandler           | SP-GiST index access method
+(10 rows)
 
 \dA+ *
-                             List of access methods
-  Name  | Type  |       Handler        |              Description               
---------+-------+----------------------+----------------------------------------
- brin   | Index | brinhandler          | block range index (BRIN) access method
- btree  | Index | bthandler            | b-tree index access method
- gin    | Index | ginhandler           | GIN index access method
- gist   | Index | gisthandler          | GiST index access method
- hash   | Index | hashhandler          | hash index access method
- heap   | Table | heap_tableam_handler | heap table access method
- heap2  | Table | heap_tableam_handler | 
- spgist | Index | spghandler           | SP-GiST index access method
-(8 rows)
+                                List of access methods
+  Name  |    Type     |       Handler        |              Description               
+--------+-------------+----------------------+----------------------------------------
+ brin   | Index       | brinhandler          | block range index (BRIN) access method
+ btree  | Index       | bthandler            | b-tree index access method
+ gin    | Index       | ginhandler           | GIN index access method
+ gist   | Index       | gisthandler          | GiST index access method
+ hash   | Index       | hashhandler          | hash index access method
+ heap   | Table       | heap_tableam_handler | heap table access method
+ heap2  | Table       | heap_tableam_handler | 
+ lz4    | Compression | lz4handler           | lz4 compression access method
+ pglz   | Compression | pglzhandler          | pglz compression access method
+ spgist | Index       | spghandler           | SP-GiST index access method
+(10 rows)
 
 \dA+ h*
                      List of access methods
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 12bb67e491..e9c0fc9760 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -114,7 +114,7 @@ test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion tr
 # ----------
 # Another group of parallel tests
 # ----------
-test: partition_join partition_prune reloptions hash_part indexing partition_aggregate partition_info tuplesort explain
+test: partition_join partition_prune reloptions hash_part indexing partition_aggregate partition_info tuplesort explain compression
 
 # event triggers cannot run concurrently with any test that runs DDL
 # oidjoins is read-only, though, and should run late for best coverage
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index 59b416fd80..4d5577bae3 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -199,6 +199,7 @@ test: partition_aggregate
 test: partition_info
 test: tuplesort
 test: explain
+test: compression
 test: event_trigger
 test: oidjoins
 test: fast_default
diff --git a/src/test/regress/sql/compression.sql b/src/test/regress/sql/compression.sql
new file mode 100644
index 0000000000..450416ecb4
--- /dev/null
+++ b/src/test/regress/sql/compression.sql
@@ -0,0 +1,85 @@
+\set HIDE_COMPRESSAM off
+
+-- test creating table with compression method
+CREATE TABLE cmdata(f1 text COMPRESSION pglz);
+CREATE INDEX idx ON cmdata(f1);
+INSERT INTO cmdata VALUES(repeat('1234567890',1000));
+\d+ cmdata
+
+CREATE TABLE cmdata1(f1 TEXT COMPRESSION lz4);
+INSERT INTO cmdata1 VALUES(repeat('1234567890',1004));
+\d+ cmdata1
+
+-- try setting compression for incompressible data type
+CREATE TABLE cmdata2 (f1 int COMPRESSION pglz);
+
+-- verify stored compression method
+SELECT pg_column_compression(f1) FROM cmdata;
+SELECT pg_column_compression(f1) FROM cmdata1;
+
+-- decompress data slice
+SELECT SUBSTR(f1, 200, 5) FROM cmdata;
+SELECT SUBSTR(f1, 2000, 50) FROM cmdata1;
+
+-- copy with table creation
+SELECT * INTO cmmove1 FROM cmdata;
+SELECT pg_column_compression(f1) FROM cmmove1;
+
+-- update using datum from different table
+CREATE TABLE cmmove2(f1 text COMPRESSION pglz);
+INSERT INTO cmmove2 VALUES (repeat('1234567890',1004));
+SELECT pg_column_compression(f1) FROM cmmove2;
+
+UPDATE cmmove2 SET f1 = cmdata.f1 FROM cmdata;
+SELECT pg_column_compression(f1) FROM cmmove2;
+UPDATE cmmove2 SET f1 = cmdata1.f1 FROM cmdata1;
+SELECT pg_column_compression(f1) FROM cmmove2;
+
+-- copy to existing table
+CREATE TABLE cmmove3(f1 text COMPRESSION pglz);
+INSERT INTO cmmove3 SELECT * FROM cmdata;
+INSERT INTO cmmove3 SELECT * FROM cmdata1;
+SELECT pg_column_compression(f1) FROM cmmove2;
+
+-- test external compressed data
+CREATE OR REPLACE FUNCTION large_val() RETURNS TEXT LANGUAGE SQL AS
+'select array_agg(md5(g::text))::text from generate_series(1, 256) g';
+CREATE TABLE cmdata2 (f1 text COMPRESSION pglz);
+INSERT INTO cmdata2 select large_val() || repeat('a', 4000);
+SELECT pg_column_compression(f1) FROM cmdata2;
+INSERT INTO cmdata1 SELECT * FROM cmdata2;
+SELECT pg_column_compression(f1) FROM cmdata1;
+DROP TABLE cmdata2;
+
+-- test LIKE INCLUDING COMPRESSION
+CREATE TABLE cmdata2 (LIKE cmdata1 INCLUDING COMPRESSION);
+\d+ cmdata2
+
+-- test compression with materialized view
+CREATE MATERIALIZED VIEW mv(x) AS SELECT * FROM cmdata1;
+\d+ mv
+SELECT pg_column_compression(f1) FROM cmdata1;
+SELECT pg_column_compression(x) FROM mv;
+
+-- test compression with partition
+CREATE TABLE cmpart(f1 text COMPRESSION lz4) PARTITION BY HASH(f1);
+CREATE TABLE cmpart1 PARTITION OF cmpart FOR VALUES WITH (MODULUS 2, REMAINDER 0);
+CREATE TABLE cmpart2(f1 text COMPRESSION pglz);
+
+ALTER TABLE cmpart ATTACH PARTITION cmpart2 FOR VALUES WITH (MODULUS 2, REMAINDER 1);
+INSERT INTO cmpart VALUES (repeat('123456789',1004));
+INSERT INTO cmpart VALUES (repeat('123456789',4004));
+SELECT pg_column_compression(f1) FROM cmpart;
+
+-- test compression with inheritence, error
+CREATE TABLE cminh() INHERITS(cmdata, cmdata1);
+CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata);
+
+-- check data is ok
+SELECT length(f1) FROM cmdata;
+SELECT length(f1) FROM cmdata1;
+SELECT length(f1) FROM cmmove1;
+SELECT length(f1) FROM cmmove2;
+SELECT length(f1) FROM cmmove3;
+
+\set HIDE_COMPRESSAM on
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 2aa062b2c9..c64b369047 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -307,6 +307,7 @@ sub GenerateFiles
 		HAVE_LIBXML2                                => undef,
 		HAVE_LIBXSLT                                => undef,
 		HAVE_LIBZ                   => $self->{options}->{zlib} ? 1 : undef,
+		HAVE_LIBLZ4                 => undef,
 		HAVE_LINK                   => undef,
 		HAVE_LOCALE_T               => 1,
 		HAVE_LONG_INT_64            => undef,
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index bab4f3adb3..46cac11d39 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -395,6 +395,7 @@ CompositeIOData
 CompositeTypeStmt
 CompoundAffixFlag
 CompressionAlgorithm
+CompressionAmRoutine
 CompressorState
 ComputeXidHorizonsResult
 ConditionVariable
-- 
2.17.0


--YZ5djTAD1cGYuMQK
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
 filename="v24-0002-psql-Add-HIDE_COMPRESSAM-for-regress-testing.patch"



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

* Remove some useless casts to (void *)
@ 2023-02-02 22:22  Peter Eisentraut <[email protected]>
  0 siblings, 0 replies; 2+ messages in thread

From: Peter Eisentraut @ 2023-02-02 22:22 UTC (permalink / raw)
  To: pgsql-hackers

I have found that in some corners of the code some calls to standard C 
functions are decorated with casts to (void *) for no reason, and this 
code pattern then gets copied around.  I have gone through and cleaned 
this up a bit, in the attached patches.

The involved functions are: repalloc, memcpy, memset, memmove, memcmp, 
qsort, bsearch

Also hash_search(), for which there was a historical reason (the 
argument used to be char *), but not anymore.
From b4f050d23761187e05576cfbe8277b593d9c19fb Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:34 +0100
Subject: [PATCH 1/8] Remove useless casts to (void *) (hash_search)

Some of these appear to be leftovers from when hash_search took a char
* argument (changed in 5999e78fc45dcb91784b64b6e9ae43f4e4f68ca2).
---
 contrib/postgres_fdw/shippable.c              |  6 +--
 src/backend/access/gist/gistbuild.c           |  4 +-
 src/backend/access/gist/gistbuildbuffers.c    |  2 +-
 src/backend/access/transam/xlogutils.c        |  6 +--
 src/backend/catalog/storage.c                 |  4 +-
 src/backend/optimizer/util/predtest.c         |  2 +-
 src/backend/parser/parse_oper.c               |  6 +--
 src/backend/replication/logical/relation.c    |  6 +--
 .../replication/logical/reorderbuffer.c       | 16 +++---
 src/backend/replication/pgoutput/pgoutput.c   |  2 +-
 src/backend/storage/buffer/buf_table.c        |  6 +--
 src/backend/storage/buffer/bufmgr.c           |  8 +--
 src/backend/storage/buffer/localbuf.c         | 12 ++---
 src/backend/storage/lmgr/lock.c               | 50 +++++++++----------
 src/backend/storage/smgr/smgr.c               |  6 +--
 src/backend/storage/sync/sync.c               |  4 +-
 src/backend/tsearch/ts_typanalyze.c           |  4 +-
 src/backend/utils/adt/array_typanalyze.c      |  4 +-
 src/backend/utils/adt/ri_triggers.c           |  8 +--
 src/backend/utils/cache/attoptcache.c         |  6 +--
 src/backend/utils/cache/relcache.c            | 12 ++---
 src/backend/utils/cache/relfilenumbermap.c    |  6 +--
 src/backend/utils/cache/spccache.c            |  6 +--
 src/backend/utils/cache/ts_cache.c            | 12 ++---
 src/backend/utils/cache/typcache.c            |  8 +--
 src/backend/utils/time/combocid.c             |  2 +-
 src/pl/plpgsql/src/pl_comp.c                  |  6 +--
 src/pl/plpgsql/src/pl_exec.c                  |  2 +-
 28 files changed, 108 insertions(+), 108 deletions(-)

diff --git a/contrib/postgres_fdw/shippable.c b/contrib/postgres_fdw/shippable.c
index 1b47a30dbf..a500b90390 100644
--- a/contrib/postgres_fdw/shippable.c
+++ b/contrib/postgres_fdw/shippable.c
@@ -77,7 +77,7 @@ InvalidateShippableCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
 	while ((entry = (ShippableCacheEntry *) hash_seq_search(&status)) != NULL)
 	{
 		if (hash_search(ShippableCacheHash,
-						(void *) &entry->key,
+						&entry->key,
 						HASH_REMOVE,
 						NULL) == NULL)
 			elog(ERROR, "hash table corrupted");
@@ -184,7 +184,7 @@ is_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo)
 	/* See if we already cached the result. */
 	entry = (ShippableCacheEntry *)
 		hash_search(ShippableCacheHash,
-					(void *) &key,
+					&key,
 					HASH_FIND,
 					NULL);
 
@@ -200,7 +200,7 @@ is_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo)
 		 */
 		entry = (ShippableCacheEntry *)
 			hash_search(ShippableCacheHash,
-						(void *) &key,
+						&key,
 						HASH_ENTER,
 						NULL);
 
diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c
index d21a308d41..7a6d93bb87 100644
--- a/src/backend/access/gist/gistbuild.c
+++ b/src/backend/access/gist/gistbuild.c
@@ -1587,7 +1587,7 @@ gistMemorizeParent(GISTBuildState *buildstate, BlockNumber child, BlockNumber pa
 	bool		found;
 
 	entry = (ParentMapEntry *) hash_search(buildstate->parentMap,
-										   (const void *) &child,
+										   &child,
 										   HASH_ENTER,
 										   &found);
 	entry->parentblkno = parent;
@@ -1625,7 +1625,7 @@ gistGetParent(GISTBuildState *buildstate, BlockNumber child)
 
 	/* Find node buffer in hash table */
 	entry = (ParentMapEntry *) hash_search(buildstate->parentMap,
-										   (const void *) &child,
+										   &child,
 										   HASH_FIND,
 										   &found);
 	if (!found)
diff --git a/src/backend/access/gist/gistbuildbuffers.c b/src/backend/access/gist/gistbuildbuffers.c
index 3399a6ae68..95cbed4337 100644
--- a/src/backend/access/gist/gistbuildbuffers.c
+++ b/src/backend/access/gist/gistbuildbuffers.c
@@ -122,7 +122,7 @@ gistGetNodeBuffer(GISTBuildBuffers *gfbb, GISTSTATE *giststate,
 
 	/* Find node buffer in hash table */
 	nodeBuffer = (GISTNodeBuffer *) hash_search(gfbb->nodeBuffersTab,
-												(const void *) &nodeBlocknum,
+												&nodeBlocknum,
 												HASH_ENTER,
 												&found);
 	if (!found)
diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c
index 87ca9dfef1..2c28956b1a 100644
--- a/src/backend/access/transam/xlogutils.c
+++ b/src/backend/access/transam/xlogutils.c
@@ -151,7 +151,7 @@ log_invalid_page(RelFileLocator locator, ForkNumber forkno, BlockNumber blkno,
 	key.forkno = forkno;
 	key.blkno = blkno;
 	hentry = (xl_invalid_page *)
-		hash_search(invalid_page_tab, (void *) &key, HASH_ENTER, &found);
+		hash_search(invalid_page_tab, &key, HASH_ENTER, &found);
 
 	if (!found)
 	{
@@ -193,7 +193,7 @@ forget_invalid_pages(RelFileLocator locator, ForkNumber forkno,
 			}
 
 			if (hash_search(invalid_page_tab,
-							(void *) &hentry->key,
+							&hentry->key,
 							HASH_REMOVE, NULL) == NULL)
 				elog(ERROR, "hash table corrupted");
 		}
@@ -226,7 +226,7 @@ forget_invalid_pages_db(Oid dbid)
 			}
 
 			if (hash_search(invalid_page_tab,
-							(void *) &hentry->key,
+							&hentry->key,
 							HASH_REMOVE, NULL) == NULL)
 				elog(ERROR, "hash table corrupted");
 		}
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index 039ada94c4..af1491aa1d 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -603,7 +603,7 @@ SerializePendingSyncs(Size maxSize, char *startAddress)
 	/* remove deleted rnodes */
 	for (delete = pendingDeletes; delete != NULL; delete = delete->next)
 		if (delete->atCommit)
-			(void) hash_search(tmphash, (void *) &delete->rlocator,
+			(void) hash_search(tmphash, &delete->rlocator,
 							   HASH_REMOVE, NULL);
 
 	hash_seq_init(&scan, tmphash);
@@ -748,7 +748,7 @@ smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
 	/* Skip syncing nodes that smgrDoPendingDeletes() will delete. */
 	for (pending = pendingDeletes; pending != NULL; pending = pending->next)
 		if (pending->atCommit)
-			(void) hash_search(pendingSyncHash, (void *) &pending->rlocator,
+			(void) hash_search(pendingSyncHash, &pending->rlocator,
 							   HASH_REMOVE, NULL);
 
 	hash_seq_init(&scan, pendingSyncHash);
diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c
index f6e12856dd..237c883874 100644
--- a/src/backend/optimizer/util/predtest.c
+++ b/src/backend/optimizer/util/predtest.c
@@ -2040,7 +2040,7 @@ lookup_proof_cache(Oid pred_op, Oid clause_op, bool refute_it)
 	key.pred_op = pred_op;
 	key.clause_op = clause_op;
 	cache_entry = (OprProofCacheEntry *) hash_search(OprProofCacheHash,
-													 (void *) &key,
+													 &key,
 													 HASH_ENTER, &cfound);
 	if (!cfound)
 	{
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
index 8801f30898..bdc8f8e26a 100644
--- a/src/backend/parser/parse_oper.c
+++ b/src/backend/parser/parse_oper.c
@@ -1017,7 +1017,7 @@ find_oper_cache_entry(OprCacheKey *key)
 
 	/* Look for an existing entry */
 	oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
-											 (void *) key,
+											 key,
 											 HASH_FIND, NULL);
 	if (oprentry == NULL)
 		return InvalidOid;
@@ -1038,7 +1038,7 @@ make_oper_cache_entry(OprCacheKey *key, Oid opr_oid)
 	Assert(OprCacheHash != NULL);
 
 	oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
-											 (void *) key,
+											 key,
 											 HASH_ENTER, NULL);
 	oprentry->opr_oid = opr_oid;
 }
@@ -1060,7 +1060,7 @@ InvalidateOprCacheCallBack(Datum arg, int cacheid, uint32 hashvalue)
 	while ((hentry = (OprCacheEntry *) hash_seq_search(&status)) != NULL)
 	{
 		if (hash_search(OprCacheHash,
-						(void *) &hentry->key,
+						&hentry->key,
 						HASH_REMOVE, NULL) == NULL)
 			elog(ERROR, "hash table corrupted");
 	}
diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c
index ca88ae171c..9f139c64db 100644
--- a/src/backend/replication/logical/relation.c
+++ b/src/backend/replication/logical/relation.c
@@ -167,7 +167,7 @@ logicalrep_relmap_update(LogicalRepRelation *remoterel)
 	/*
 	 * HASH_ENTER returns the existing entry if present or creates a new one.
 	 */
-	entry = hash_search(LogicalRepRelMap, (void *) &remoterel->remoteid,
+	entry = hash_search(LogicalRepRelMap, &remoterel->remoteid,
 						HASH_ENTER, &found);
 
 	if (found)
@@ -326,7 +326,7 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode)
 		logicalrep_relmap_init();
 
 	/* Search for existing entry. */
-	entry = hash_search(LogicalRepRelMap, (void *) &remoteid,
+	entry = hash_search(LogicalRepRelMap, &remoteid,
 						HASH_FIND, &found);
 
 	if (!found)
@@ -598,7 +598,7 @@ logicalrep_partition_open(LogicalRepRelMapEntry *root,
 
 	/* Search for existing entry. */
 	part_entry = (LogicalRepPartMapEntry *) hash_search(LogicalRepPartMap,
-														(void *) &partOid,
+														&partOid,
 														HASH_ENTER, &found);
 
 	entry = &part_entry->relmapentry;
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index efe057b4de..02319d5c2f 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -657,7 +657,7 @@ ReorderBufferTXNByXid(ReorderBuffer *rb, TransactionId xid, bool create,
 	/* search the lookup table */
 	ent = (ReorderBufferTXNByIdEnt *)
 		hash_search(rb->by_txn,
-					(void *) &xid,
+					&xid,
 					create ? HASH_ENTER : HASH_FIND,
 					&found);
 	if (found)
@@ -1582,7 +1582,7 @@ ReorderBufferCleanupTXN(ReorderBuffer *rb, ReorderBufferTXN *txn)
 
 	/* now remove reference from buffer */
 	hash_search(rb->by_txn,
-				(void *) &txn->xid,
+				&txn->xid,
 				HASH_REMOVE,
 				&found);
 	Assert(found);
@@ -1763,7 +1763,7 @@ ReorderBufferBuildTupleCidHash(ReorderBuffer *rb, ReorderBufferTXN *txn)
 
 		ent = (ReorderBufferTupleCidEnt *)
 			hash_search(txn->tuplecid_hash,
-						(void *) &key,
+						&key,
 						HASH_ENTER,
 						&found);
 		if (!found)
@@ -4654,7 +4654,7 @@ ReorderBufferToastAppendChunk(ReorderBuffer *rb, ReorderBufferTXN *txn,
 
 	ent = (ReorderBufferToastEnt *)
 		hash_search(txn->toast_hash,
-					(void *) &chunk_id,
+					&chunk_id,
 					HASH_ENTER,
 					&found);
 
@@ -4811,7 +4811,7 @@ ReorderBufferToastReplace(ReorderBuffer *rb, ReorderBufferTXN *txn,
 		 */
 		ent = (ReorderBufferToastEnt *)
 			hash_search(txn->toast_hash,
-						(void *) &toast_pointer.va_valueid,
+						&toast_pointer.va_valueid,
 						HASH_FIND,
 						NULL);
 		if (ent == NULL)
@@ -5054,7 +5054,7 @@ ApplyLogicalMappingFile(HTAB *tuplecid_data, Oid relid, const char *fname)
 
 		ent = (ReorderBufferTupleCidEnt *)
 			hash_search(tuplecid_data,
-						(void *) &key,
+						&key,
 						HASH_FIND,
 						NULL);
 
@@ -5068,7 +5068,7 @@ ApplyLogicalMappingFile(HTAB *tuplecid_data, Oid relid, const char *fname)
 
 		new_ent = (ReorderBufferTupleCidEnt *)
 			hash_search(tuplecid_data,
-						(void *) &key,
+						&key,
 						HASH_ENTER,
 						&found);
 
@@ -5250,7 +5250,7 @@ ResolveCminCmaxDuringDecoding(HTAB *tuplecid_data,
 restart:
 	ent = (ReorderBufferTupleCidEnt *)
 		hash_search(tuplecid_data,
-					(void *) &key,
+					&key,
 					HASH_FIND,
 					NULL);
 
diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
index 1a80d67bb9..e4938d8888 100644
--- a/src/backend/replication/pgoutput/pgoutput.c
+++ b/src/backend/replication/pgoutput/pgoutput.c
@@ -2026,7 +2026,7 @@ get_rel_sync_entry(PGOutputData *data, Relation relation)
 
 	/* Find cached relation info, creating if not found */
 	entry = (RelationSyncEntry *) hash_search(RelationSyncCache,
-											  (void *) &relid,
+											  &relid,
 											  HASH_ENTER, &found);
 	Assert(entry != NULL);
 
diff --git a/src/backend/storage/buffer/buf_table.c b/src/backend/storage/buffer/buf_table.c
index e61546a5ff..2b96639a5a 100644
--- a/src/backend/storage/buffer/buf_table.c
+++ b/src/backend/storage/buffer/buf_table.c
@@ -94,7 +94,7 @@ BufTableLookup(BufferTag *tagPtr, uint32 hashcode)
 
 	result = (BufferLookupEnt *)
 		hash_search_with_hash_value(SharedBufHash,
-									(void *) tagPtr,
+									tagPtr,
 									hashcode,
 									HASH_FIND,
 									NULL);
@@ -126,7 +126,7 @@ BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id)
 
 	result = (BufferLookupEnt *)
 		hash_search_with_hash_value(SharedBufHash,
-									(void *) tagPtr,
+									tagPtr,
 									hashcode,
 									HASH_ENTER,
 									&found);
@@ -152,7 +152,7 @@ BufTableDelete(BufferTag *tagPtr, uint32 hashcode)
 
 	result = (BufferLookupEnt *)
 		hash_search_with_hash_value(SharedBufHash,
-									(void *) tagPtr,
+									tagPtr,
 									hashcode,
 									HASH_REMOVE,
 									NULL);
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 800a4248c9..cbde861789 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -262,7 +262,7 @@ ReservePrivateRefCountEntry(void)
 
 		/* enter victim array entry into hashtable */
 		hashent = hash_search(PrivateRefCountHash,
-							  (void *) &(ReservedRefCountEntry->buffer),
+							  &(ReservedRefCountEntry->buffer),
 							  HASH_ENTER,
 							  &found);
 		Assert(!found);
@@ -337,7 +337,7 @@ GetPrivateRefCountEntry(Buffer buffer, bool do_move)
 		return NULL;
 
 	res = hash_search(PrivateRefCountHash,
-					  (void *) &buffer,
+					  &buffer,
 					  HASH_FIND,
 					  NULL);
 
@@ -369,7 +369,7 @@ GetPrivateRefCountEntry(Buffer buffer, bool do_move)
 
 		/* delete from hashtable */
 		hash_search(PrivateRefCountHash,
-					(void *) &buffer,
+					&buffer,
 					HASH_REMOVE,
 					&found);
 		Assert(found);
@@ -431,7 +431,7 @@ ForgetPrivateRefCountEntry(PrivateRefCountEntry *ref)
 		Buffer		buffer = ref->buffer;
 
 		hash_search(PrivateRefCountHash,
-					(void *) &buffer,
+					&buffer,
 					HASH_REMOVE,
 					&found);
 		Assert(found);
diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c
index 8372acc383..0229a2eca1 100644
--- a/src/backend/storage/buffer/localbuf.c
+++ b/src/backend/storage/buffer/localbuf.c
@@ -76,7 +76,7 @@ PrefetchLocalBuffer(SMgrRelation smgr, ForkNumber forkNum,
 
 	/* See if the desired buffer already exists */
 	hresult = (LocalBufferLookupEnt *)
-		hash_search(LocalBufHash, (void *) &newTag, HASH_FIND, NULL);
+		hash_search(LocalBufHash, &newTag, HASH_FIND, NULL);
 
 	if (hresult)
 	{
@@ -125,7 +125,7 @@ LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum,
 
 	/* See if the desired buffer already exists */
 	hresult = (LocalBufferLookupEnt *)
-		hash_search(LocalBufHash, (void *) &newTag, HASH_FIND, NULL);
+		hash_search(LocalBufHash, &newTag, HASH_FIND, NULL);
 
 	if (hresult)
 	{
@@ -248,7 +248,7 @@ LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum,
 	if (buf_state & BM_TAG_VALID)
 	{
 		hresult = (LocalBufferLookupEnt *)
-			hash_search(LocalBufHash, (void *) &bufHdr->tag,
+			hash_search(LocalBufHash, &bufHdr->tag,
 						HASH_REMOVE, NULL);
 		if (!hresult)			/* shouldn't happen */
 			elog(ERROR, "local buffer hash table corrupted");
@@ -259,7 +259,7 @@ LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum,
 	}
 
 	hresult = (LocalBufferLookupEnt *)
-		hash_search(LocalBufHash, (void *) &newTag, HASH_ENTER, &found);
+		hash_search(LocalBufHash, &newTag, HASH_ENTER, &found);
 	if (found)					/* shouldn't happen */
 		elog(ERROR, "local buffer hash table corrupted");
 	hresult->id = b;
@@ -351,7 +351,7 @@ DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber forkNum,
 
 			/* Remove entry from hashtable */
 			hresult = (LocalBufferLookupEnt *)
-				hash_search(LocalBufHash, (void *) &bufHdr->tag,
+				hash_search(LocalBufHash, &bufHdr->tag,
 							HASH_REMOVE, NULL);
 			if (!hresult)		/* shouldn't happen */
 				elog(ERROR, "local buffer hash table corrupted");
@@ -396,7 +396,7 @@ DropRelationAllLocalBuffers(RelFileLocator rlocator)
 					 LocalRefCount[i]);
 			/* Remove entry from hashtable */
 			hresult = (LocalBufferLookupEnt *)
-				hash_search(LocalBufHash, (void *) &bufHdr->tag,
+				hash_search(LocalBufHash, &bufHdr->tag,
 							HASH_REMOVE, NULL);
 			if (!hresult)		/* shouldn't happen */
 				elog(ERROR, "local buffer hash table corrupted");
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 49d62a0dc7..a87372f33f 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -608,7 +608,7 @@ LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode)
 	localtag.mode = lockmode;
 
 	locallock = (LOCALLOCK *) hash_search(LockMethodLocalHash,
-										  (void *) &localtag,
+										  &localtag,
 										  HASH_FIND, NULL);
 
 	return (locallock && locallock->nLocks > 0);
@@ -663,7 +663,7 @@ LockHasWaiters(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
 	localtag.mode = lockmode;
 
 	locallock = (LOCALLOCK *) hash_search(LockMethodLocalHash,
-										  (void *) &localtag,
+										  &localtag,
 										  HASH_FIND, NULL);
 
 	/*
@@ -825,7 +825,7 @@ LockAcquireExtended(const LOCKTAG *locktag,
 	localtag.mode = lockmode;
 
 	locallock = (LOCALLOCK *) hash_search(LockMethodLocalHash,
-										  (void *) &localtag,
+										  &localtag,
 										  HASH_ENTER, &found);
 
 	/*
@@ -1061,7 +1061,7 @@ LockAcquireExtended(const LOCKTAG *locktag,
 				dlist_delete(&proclock->lockLink);
 				dlist_delete(&proclock->procLink);
 				if (!hash_search_with_hash_value(LockMethodProcLockHash,
-												 (void *) &(proclock->tag),
+												 &(proclock->tag),
 												 proclock_hashcode,
 												 HASH_REMOVE,
 												 NULL))
@@ -1180,7 +1180,7 @@ SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc,
 	 * Find or create a lock with this tag.
 	 */
 	lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-												(const void *) locktag,
+												locktag,
 												hashcode,
 												HASH_ENTER_NULL,
 												&found);
@@ -1222,7 +1222,7 @@ SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc,
 	 * Find or create a proclock entry with this tag
 	 */
 	proclock = (PROCLOCK *) hash_search_with_hash_value(LockMethodProcLockHash,
-														(void *) &proclocktag,
+														&proclocktag,
 														proclock_hashcode,
 														HASH_ENTER_NULL,
 														&found);
@@ -1239,7 +1239,7 @@ SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc,
 			 */
 			Assert(dlist_is_empty(&(lock->procLocks)));
 			if (!hash_search_with_hash_value(LockMethodLockHash,
-											 (void *) &(lock->tag),
+											 &(lock->tag),
 											 hashcode,
 											 HASH_REMOVE,
 											 NULL))
@@ -1391,7 +1391,7 @@ RemoveLocalLock(LOCALLOCK *locallock)
 	}
 
 	if (!hash_search(LockMethodLocalHash,
-					 (void *) &(locallock->tag),
+					 &(locallock->tag),
 					 HASH_REMOVE, NULL))
 		elog(WARNING, "locallock table corrupted");
 
@@ -1644,7 +1644,7 @@ CleanUpLock(LOCK *lock, PROCLOCK *proclock,
 		dlist_delete(&proclock->procLink);
 		proclock_hashcode = ProcLockHashCode(&proclock->tag, hashcode);
 		if (!hash_search_with_hash_value(LockMethodProcLockHash,
-										 (void *) &(proclock->tag),
+										 &(proclock->tag),
 										 proclock_hashcode,
 										 HASH_REMOVE,
 										 NULL))
@@ -1660,7 +1660,7 @@ CleanUpLock(LOCK *lock, PROCLOCK *proclock,
 		LOCK_PRINT("CleanUpLock: deleting", lock, 0);
 		Assert(dlist_is_empty(&lock->procLocks));
 		if (!hash_search_with_hash_value(LockMethodLockHash,
-										 (void *) &(lock->tag),
+										 &(lock->tag),
 										 hashcode,
 										 HASH_REMOVE,
 										 NULL))
@@ -1998,7 +1998,7 @@ LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
 	localtag.mode = lockmode;
 
 	locallock = (LOCALLOCK *) hash_search(LockMethodLocalHash,
-										  (void *) &localtag,
+										  &localtag,
 										  HASH_FIND, NULL);
 
 	/*
@@ -2112,7 +2112,7 @@ LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
 
 		Assert(EligibleForRelationFastPath(locktag, lockmode));
 		lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-													(const void *) locktag,
+													locktag,
 													locallock->hashcode,
 													HASH_FIND,
 													NULL);
@@ -2123,7 +2123,7 @@ LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
 		proclocktag.myLock = lock;
 		proclocktag.myProc = MyProc;
 		locallock->proclock = (PROCLOCK *) hash_search(LockMethodProcLockHash,
-													   (void *) &proclocktag,
+													   &proclocktag,
 													   HASH_FIND,
 													   NULL);
 		if (!locallock->proclock)
@@ -2851,7 +2851,7 @@ FastPathGetRelationLockEntry(LOCALLOCK *locallock)
 		LWLockAcquire(partitionLock, LW_SHARED);
 
 		lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-													(void *) locktag,
+													locktag,
 													locallock->hashcode,
 													HASH_FIND,
 													NULL);
@@ -2864,7 +2864,7 @@ FastPathGetRelationLockEntry(LOCALLOCK *locallock)
 		proclock_hashcode = ProcLockHashCode(&proclocktag, locallock->hashcode);
 		proclock = (PROCLOCK *)
 			hash_search_with_hash_value(LockMethodProcLockHash,
-										(void *) &proclocktag,
+										&proclocktag,
 										proclock_hashcode,
 										HASH_FIND,
 										NULL);
@@ -3028,7 +3028,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
 	LWLockAcquire(partitionLock, LW_SHARED);
 
 	lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-												(const void *) locktag,
+												locktag,
 												hashcode,
 												HASH_FIND,
 												NULL);
@@ -3125,7 +3125,7 @@ LockRefindAndRelease(LockMethod lockMethodTable, PGPROC *proc,
 	 * Re-find the lock object (it had better be there).
 	 */
 	lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-												(void *) locktag,
+												locktag,
 												hashcode,
 												HASH_FIND,
 												NULL);
@@ -3141,7 +3141,7 @@ LockRefindAndRelease(LockMethod lockMethodTable, PGPROC *proc,
 	proclock_hashcode = ProcLockHashCode(&proclocktag, hashcode);
 
 	proclock = (PROCLOCK *) hash_search_with_hash_value(LockMethodProcLockHash,
-														(void *) &proclocktag,
+														&proclocktag,
 														proclock_hashcode,
 														HASH_FIND,
 														NULL);
@@ -3255,7 +3255,7 @@ CheckForSessionAndXactLocks(void)
 
 		/* Otherwise, find or make an entry in lockhtab */
 		hentry = (PerLockTagEntry *) hash_search(lockhtab,
-												 (void *) &locallock->tag.lock,
+												 &locallock->tag.lock,
 												 HASH_ENTER, &found);
 		if (!found)				/* initialize, if newly created */
 			hentry->sessLock = hentry->xactLock = false;
@@ -3555,8 +3555,8 @@ PostPrepare_Locks(TransactionId xid)
 			 * given lock with my own proc.
 			 */
 			if (!hash_update_hash_key(LockMethodProcLockHash,
-									  (void *) proclock,
-									  (void *) &proclocktag))
+									  proclock,
+									  &proclocktag))
 				elog(PANIC, "duplicate entry found while reassigning a prepared transaction's locks");
 
 			/* Re-link into the new proc's proclock list */
@@ -4202,7 +4202,7 @@ lock_twophase_recover(TransactionId xid, uint16 info,
 	 * Find or create a lock with this tag.
 	 */
 	lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-												(void *) locktag,
+												locktag,
 												hashcode,
 												HASH_ENTER_NULL,
 												&found);
@@ -4250,7 +4250,7 @@ lock_twophase_recover(TransactionId xid, uint16 info,
 	 * Find or create a proclock entry with this tag
 	 */
 	proclock = (PROCLOCK *) hash_search_with_hash_value(LockMethodProcLockHash,
-														(void *) &proclocktag,
+														&proclocktag,
 														proclock_hashcode,
 														HASH_ENTER_NULL,
 														&found);
@@ -4267,7 +4267,7 @@ lock_twophase_recover(TransactionId xid, uint16 info,
 			 */
 			Assert(dlist_is_empty(&lock->procLocks));
 			if (!hash_search_with_hash_value(LockMethodLockHash,
-											 (void *) &(lock->tag),
+											 &(lock->tag),
 											 hashcode,
 											 HASH_REMOVE,
 											 NULL))
@@ -4679,7 +4679,7 @@ LockWaiterCount(const LOCKTAG *locktag)
 	LWLockAcquire(partitionLock, LW_EXCLUSIVE);
 
 	lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-												(const void *) locktag,
+												locktag,
 												hashcode,
 												HASH_FIND,
 												&found);
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c
index 80eb6311e7..b2bd749d77 100644
--- a/src/backend/storage/smgr/smgr.c
+++ b/src/backend/storage/smgr/smgr.c
@@ -165,7 +165,7 @@ smgropen(RelFileLocator rlocator, BackendId backend)
 	brlocator.locator = rlocator;
 	brlocator.backend = backend;
 	reln = (SMgrRelation) hash_search(SMgrRelationHash,
-									  (void *) &brlocator,
+									  &brlocator,
 									  HASH_ENTER, &found);
 
 	/* Initialize it if not present before */
@@ -267,7 +267,7 @@ smgrclose(SMgrRelation reln)
 		dlist_delete(&reln->node);
 
 	if (hash_search(SMgrRelationHash,
-					(void *) &(reln->smgr_rlocator),
+					&(reln->smgr_rlocator),
 					HASH_REMOVE, NULL) == NULL)
 		elog(ERROR, "SMgrRelation hashtable corrupted");
 
@@ -352,7 +352,7 @@ smgrcloserellocator(RelFileLocatorBackend rlocator)
 		return;
 
 	reln = (SMgrRelation) hash_search(SMgrRelationHash,
-									  (void *) &rlocator,
+									  &rlocator,
 									  HASH_FIND, NULL);
 	if (reln != NULL)
 		smgrclose(reln);
diff --git a/src/backend/storage/sync/sync.c b/src/backend/storage/sync/sync.c
index 7135150b16..768d1dbfc4 100644
--- a/src/backend/storage/sync/sync.c
+++ b/src/backend/storage/sync/sync.c
@@ -501,7 +501,7 @@ RememberSyncRequest(const FileTag *ftag, SyncRequestType type)
 
 		/* Cancel previously entered request */
 		entry = (PendingFsyncEntry *) hash_search(pendingOps,
-												  (void *) ftag,
+												  ftag,
 												  HASH_FIND,
 												  NULL);
 		if (entry != NULL)
@@ -557,7 +557,7 @@ RememberSyncRequest(const FileTag *ftag, SyncRequestType type)
 		Assert(type == SYNC_REQUEST);
 
 		entry = (PendingFsyncEntry *) hash_search(pendingOps,
-												  (void *) ftag,
+												  ftag,
 												  HASH_ENTER,
 												  &found);
 		/* if new entry, or was previously canceled, initialize it */
diff --git a/src/backend/tsearch/ts_typanalyze.c b/src/backend/tsearch/ts_typanalyze.c
index ae4b5d10f2..75ecd72efe 100644
--- a/src/backend/tsearch/ts_typanalyze.c
+++ b/src/backend/tsearch/ts_typanalyze.c
@@ -254,7 +254,7 @@ compute_tsvector_stats(VacAttrStats *stats,
 
 			/* Lookup current lexeme in hashtable, adding it if new */
 			item = (TrackItem *) hash_search(lexemes_tab,
-											 (const void *) &hash_key,
+											 &hash_key,
 											 HASH_ENTER, &found);
 
 			if (found)
@@ -464,7 +464,7 @@ prune_lexemes_hashtable(HTAB *lexemes_tab, int b_current)
 		{
 			char	   *lexeme = item->key.lexeme;
 
-			if (hash_search(lexemes_tab, (const void *) &item->key,
+			if (hash_search(lexemes_tab, &item->key,
 							HASH_REMOVE, NULL) == NULL)
 				elog(ERROR, "hash table corrupted");
 			pfree(lexeme);
diff --git a/src/backend/utils/adt/array_typanalyze.c b/src/backend/utils/adt/array_typanalyze.c
index 5841d7d6fc..52e160d6bb 100644
--- a/src/backend/utils/adt/array_typanalyze.c
+++ b/src/backend/utils/adt/array_typanalyze.c
@@ -362,7 +362,7 @@ compute_array_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
 			/* Lookup current element in hashtable, adding it if new */
 			elem_value = elem_values[j];
 			item = (TrackItem *) hash_search(elements_tab,
-											 (const void *) &elem_value,
+											 &elem_value,
 											 HASH_ENTER, &found);
 
 			if (found)
@@ -690,7 +690,7 @@ prune_element_hashtable(HTAB *elements_tab, int b_current)
 		{
 			Datum		value = item->key;
 
-			if (hash_search(elements_tab, (const void *) &item->key,
+			if (hash_search(elements_tab, &item->key,
 							HASH_REMOVE, NULL) == NULL)
 				elog(ERROR, "hash table corrupted");
 			/* We should free memory if element is not passed by value */
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 995571ae04..375b17b9f3 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -2129,7 +2129,7 @@ ri_LoadConstraintInfo(Oid constraintOid)
 	 * Find or create a hash entry.  If we find a valid one, just return it.
 	 */
 	riinfo = (RI_ConstraintInfo *) hash_search(ri_constraint_cache,
-											   (void *) &constraintOid,
+											   &constraintOid,
 											   HASH_ENTER, &found);
 	if (!found)
 		riinfo->valid = false;
@@ -2724,7 +2724,7 @@ ri_FetchPreparedPlan(RI_QueryKey *key)
 	 * Lookup for the key
 	 */
 	entry = (RI_QueryHashEntry *) hash_search(ri_query_cache,
-											  (void *) key,
+											  key,
 											  HASH_FIND, NULL);
 	if (entry == NULL)
 		return NULL;
@@ -2777,7 +2777,7 @@ ri_HashPreparedPlan(RI_QueryKey *key, SPIPlanPtr plan)
 	 * invalid by ri_FetchPreparedPlan.
 	 */
 	entry = (RI_QueryHashEntry *) hash_search(ri_query_cache,
-											  (void *) key,
+											  key,
 											  HASH_ENTER, &found);
 	Assert(!found || entry->plan == NULL);
 	entry->plan = plan;
@@ -2927,7 +2927,7 @@ ri_HashCompareOp(Oid eq_opr, Oid typeid)
 	key.eq_opr = eq_opr;
 	key.typeid = typeid;
 	entry = (RI_CompareHashEntry *) hash_search(ri_compare_cache,
-												(void *) &key,
+												&key,
 												HASH_ENTER, &found);
 	if (!found)
 		entry->valid = false;
diff --git a/src/backend/utils/cache/attoptcache.c b/src/backend/utils/cache/attoptcache.c
index 28a99f0fc4..6769d4765b 100644
--- a/src/backend/utils/cache/attoptcache.c
+++ b/src/backend/utils/cache/attoptcache.c
@@ -63,7 +63,7 @@ InvalidateAttoptCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
 		if (attopt->opts)
 			pfree(attopt->opts);
 		if (hash_search(AttoptCacheHash,
-						(void *) &attopt->key,
+						&attopt->key,
 						HASH_REMOVE,
 						NULL) == NULL)
 			elog(ERROR, "hash table corrupted");
@@ -116,7 +116,7 @@ get_attribute_options(Oid attrelid, int attnum)
 	key.attnum = attnum;
 	attopt =
 		(AttoptCacheEntry *) hash_search(AttoptCacheHash,
-										 (void *) &key,
+										 &key,
 										 HASH_FIND,
 										 NULL);
 
@@ -163,7 +163,7 @@ get_attribute_options(Oid attrelid, int attnum)
 		 * pg_attribute, since the read could cause a cache flush.
 		 */
 		attopt = (AttoptCacheEntry *) hash_search(AttoptCacheHash,
-												  (void *) &key,
+												  &key,
 												  HASH_ENTER,
 												  NULL);
 		attopt->opts = opts;
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index d171cfcf2f..dfda0ab7d6 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -210,7 +210,7 @@ static int	EOXactTupleDescArrayLen = 0;
 do { \
 	RelIdCacheEnt *hentry; bool found; \
 	hentry = (RelIdCacheEnt *) hash_search(RelationIdCache, \
-										   (void *) &((RELATION)->rd_id), \
+										   &((RELATION)->rd_id), \
 										   HASH_ENTER, &found); \
 	if (found) \
 	{ \
@@ -232,7 +232,7 @@ do { \
 do { \
 	RelIdCacheEnt *hentry; \
 	hentry = (RelIdCacheEnt *) hash_search(RelationIdCache, \
-										   (void *) &(ID), \
+										   &(ID), \
 										   HASH_FIND, NULL); \
 	if (hentry) \
 		RELATION = hentry->reldesc; \
@@ -244,7 +244,7 @@ do { \
 do { \
 	RelIdCacheEnt *hentry; \
 	hentry = (RelIdCacheEnt *) hash_search(RelationIdCache, \
-										   (void *) &((RELATION)->rd_id), \
+										   &((RELATION)->rd_id), \
 										   HASH_REMOVE, NULL); \
 	if (hentry == NULL) \
 		elog(WARNING, "failed to delete relcache entry for OID %u", \
@@ -1663,7 +1663,7 @@ LookupOpclassInfo(Oid operatorClassOid,
 	}
 
 	opcentry = (OpClassCacheEnt *) hash_search(OpClassCache,
-											   (void *) &operatorClassOid,
+											   &operatorClassOid,
 											   HASH_ENTER, &found);
 
 	if (!found)
@@ -3210,7 +3210,7 @@ AtEOXact_RelationCache(bool isCommit)
 		for (i = 0; i < eoxact_list_len; i++)
 		{
 			idhentry = (RelIdCacheEnt *) hash_search(RelationIdCache,
-													 (void *) &eoxact_list[i],
+													 &eoxact_list[i],
 													 HASH_FIND,
 													 NULL);
 			if (idhentry != NULL)
@@ -3359,7 +3359,7 @@ AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid,
 		for (i = 0; i < eoxact_list_len; i++)
 		{
 			idhentry = (RelIdCacheEnt *) hash_search(RelationIdCache,
-													 (void *) &eoxact_list[i],
+													 &eoxact_list[i],
 													 HASH_FIND,
 													 NULL);
 			if (idhentry != NULL)
diff --git a/src/backend/utils/cache/relfilenumbermap.c b/src/backend/utils/cache/relfilenumbermap.c
index 57c3254795..220f33d43f 100644
--- a/src/backend/utils/cache/relfilenumbermap.c
+++ b/src/backend/utils/cache/relfilenumbermap.c
@@ -72,7 +72,7 @@ RelfilenumberMapInvalidateCallback(Datum arg, Oid relid)
 			entry->relid == relid)	/* individual flushed relation */
 		{
 			if (hash_search(RelfilenumberMapHash,
-							(void *) &entry->key,
+							&entry->key,
 							HASH_REMOVE,
 							NULL) == NULL)
 				elog(ERROR, "hash table corrupted");
@@ -164,7 +164,7 @@ RelidByRelfilenumber(Oid reltablespace, RelFileNumber relfilenumber)
 	 * since querying invalid values isn't supposed to be a frequent thing,
 	 * but it's basically free.
 	 */
-	entry = hash_search(RelfilenumberMapHash, (void *) &key, HASH_FIND, &found);
+	entry = hash_search(RelfilenumberMapHash, &key, HASH_FIND, &found);
 
 	if (found)
 		return entry->relid;
@@ -235,7 +235,7 @@ RelidByRelfilenumber(Oid reltablespace, RelFileNumber relfilenumber)
 	 * caused cache invalidations to be executed which would have deleted a
 	 * new entry if we had entered it above.
 	 */
-	entry = hash_search(RelfilenumberMapHash, (void *) &key, HASH_ENTER, &found);
+	entry = hash_search(RelfilenumberMapHash, &key, HASH_ENTER, &found);
 	if (found)
 		elog(ERROR, "corrupted hashtable");
 	entry->relid = relid;
diff --git a/src/backend/utils/cache/spccache.c b/src/backend/utils/cache/spccache.c
index aabe6ba64b..136fd737d3 100644
--- a/src/backend/utils/cache/spccache.c
+++ b/src/backend/utils/cache/spccache.c
@@ -63,7 +63,7 @@ InvalidateTableSpaceCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
 		if (spc->opts)
 			pfree(spc->opts);
 		if (hash_search(TableSpaceCacheHash,
-						(void *) &spc->oid,
+						&spc->oid,
 						HASH_REMOVE,
 						NULL) == NULL)
 			elog(ERROR, "hash table corrupted");
@@ -121,7 +121,7 @@ get_tablespace(Oid spcid)
 	if (!TableSpaceCacheHash)
 		InitializeTableSpaceCache();
 	spc = (TableSpaceCacheEntry *) hash_search(TableSpaceCacheHash,
-											   (void *) &spcid,
+											   &spcid,
 											   HASH_FIND,
 											   NULL);
 	if (spc)
@@ -163,7 +163,7 @@ get_tablespace(Oid spcid)
 	 * flush.
 	 */
 	spc = (TableSpaceCacheEntry *) hash_search(TableSpaceCacheHash,
-											   (void *) &spcid,
+											   &spcid,
 											   HASH_ENTER,
 											   NULL);
 	spc->opts = opts;
diff --git a/src/backend/utils/cache/ts_cache.c b/src/backend/utils/cache/ts_cache.c
index 519fa9fa73..3f256f9bf9 100644
--- a/src/backend/utils/cache/ts_cache.c
+++ b/src/backend/utils/cache/ts_cache.c
@@ -139,7 +139,7 @@ lookup_ts_parser_cache(Oid prsId)
 
 	/* Try to look up an existing entry */
 	entry = (TSParserCacheEntry *) hash_search(TSParserCacheHash,
-											   (void *) &prsId,
+											   &prsId,
 											   HASH_FIND, NULL);
 	if (entry == NULL || !entry->isvalid)
 	{
@@ -173,7 +173,7 @@ lookup_ts_parser_cache(Oid prsId)
 			/* Now make the cache entry */
 			entry = (TSParserCacheEntry *)
 				hash_search(TSParserCacheHash,
-							(void *) &prsId,
+							&prsId,
 							HASH_ENTER, &found);
 			Assert(!found);		/* it wasn't there a moment ago */
 		}
@@ -238,7 +238,7 @@ lookup_ts_dictionary_cache(Oid dictId)
 
 	/* Try to look up an existing entry */
 	entry = (TSDictionaryCacheEntry *) hash_search(TSDictionaryCacheHash,
-												   (void *) &dictId,
+												   &dictId,
 												   HASH_FIND, NULL);
 	if (entry == NULL || !entry->isvalid)
 	{
@@ -288,7 +288,7 @@ lookup_ts_dictionary_cache(Oid dictId)
 			/* Now make the cache entry */
 			entry = (TSDictionaryCacheEntry *)
 				hash_search(TSDictionaryCacheHash,
-							(void *) &dictId,
+							&dictId,
 							HASH_ENTER, &found);
 			Assert(!found);		/* it wasn't there a moment ago */
 
@@ -401,7 +401,7 @@ lookup_ts_config_cache(Oid cfgId)
 
 	/* Try to look up an existing entry */
 	entry = (TSConfigCacheEntry *) hash_search(TSConfigCacheHash,
-											   (void *) &cfgId,
+											   &cfgId,
 											   HASH_FIND, NULL);
 	if (entry == NULL || !entry->isvalid)
 	{
@@ -441,7 +441,7 @@ lookup_ts_config_cache(Oid cfgId)
 			/* Now make the cache entry */
 			entry = (TSConfigCacheEntry *)
 				hash_search(TSConfigCacheHash,
-							(void *) &cfgId,
+							&cfgId,
 							HASH_ENTER, &found);
 			Assert(!found);		/* it wasn't there a moment ago */
 		}
diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c
index 4a3e0fdb7f..ed6360ce2b 100644
--- a/src/backend/utils/cache/typcache.c
+++ b/src/backend/utils/cache/typcache.c
@@ -364,7 +364,7 @@ lookup_type_cache(Oid type_id, int flags)
 
 	/* Try to look up an existing entry */
 	typentry = (TypeCacheEntry *) hash_search(TypeCacheHash,
-											  (void *) &type_id,
+											  &type_id,
 											  HASH_FIND, NULL);
 	if (typentry == NULL)
 	{
@@ -392,7 +392,7 @@ lookup_type_cache(Oid type_id, int flags)
 
 		/* Now make the typcache entry */
 		typentry = (TypeCacheEntry *) hash_search(TypeCacheHash,
-												  (void *) &type_id,
+												  &type_id,
 												  HASH_ENTER, &found);
 		Assert(!found);			/* it wasn't there a moment ago */
 
@@ -1974,7 +1974,7 @@ assign_record_type_typmod(TupleDesc tupDesc)
 	 * the allocations succeed before we create the new entry.
 	 */
 	recentry = (RecordCacheEntry *) hash_search(RecordCacheHash,
-												(void *) &tupDesc,
+												&tupDesc,
 												HASH_FIND, &found);
 	if (found && recentry->tupdesc != NULL)
 	{
@@ -2012,7 +2012,7 @@ assign_record_type_typmod(TupleDesc tupDesc)
 
 	/* Fully initialized; create the hash table entry */
 	recentry = (RecordCacheEntry *) hash_search(RecordCacheHash,
-												(void *) &tupDesc,
+												&tupDesc,
 												HASH_ENTER, NULL);
 	recentry->tupdesc = entDesc;
 
diff --git a/src/backend/utils/time/combocid.c b/src/backend/utils/time/combocid.c
index c7124d284f..0e94bc93f7 100644
--- a/src/backend/utils/time/combocid.c
+++ b/src/backend/utils/time/combocid.c
@@ -253,7 +253,7 @@ GetComboCommandId(CommandId cmin, CommandId cmax)
 	key.cmin = cmin;
 	key.cmax = cmax;
 	entry = (ComboCidEntry) hash_search(comboHash,
-										(void *) &key,
+										&key,
 										HASH_ENTER,
 										&found);
 
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 8ce4186240..7db912fd18 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -2627,7 +2627,7 @@ plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
 	plpgsql_HashEnt *hentry;
 
 	hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
-											 (void *) func_key,
+											 func_key,
 											 HASH_FIND,
 											 NULL);
 	if (hentry)
@@ -2644,7 +2644,7 @@ plpgsql_HashTableInsert(PLpgSQL_function *function,
 	bool		found;
 
 	hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
-											 (void *) func_key,
+											 func_key,
 											 HASH_ENTER,
 											 &found);
 	if (found)
@@ -2665,7 +2665,7 @@ plpgsql_HashTableDelete(PLpgSQL_function *function)
 		return;
 
 	hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
-											 (void *) function->fn_hashkey,
+											 function->fn_hashkey,
 											 HASH_REMOVE,
 											 NULL);
 	if (hentry == NULL)
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 37da624388..70a002a0f6 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -7775,7 +7775,7 @@ get_cast_hashentry(PLpgSQL_execstate *estate,
 	cast_key.srctypmod = srctypmod;
 	cast_key.dsttypmod = dsttypmod;
 	cast_entry = (plpgsql_CastHashEntry *) hash_search(estate->cast_hash,
-													   (void *) &cast_key,
+													   &cast_key,
 													   HASH_ENTER, &found);
 	if (!found)					/* initialize if new entry */
 		cast_entry->cast_cexpr = NULL;
-- 
2.39.1


From 597d41490d8eda8e3d9361ae39788813828712fc Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:35 +0100
Subject: [PATCH 2/8] Remove useless casts to (void *) (repalloc)

---
 contrib/ltree/ltxtquery_io.c            | 2 +-
 src/backend/access/gist/gistutil.c      | 2 +-
 src/backend/tsearch/spell.c             | 4 ++--
 src/backend/tsearch/ts_parse.c          | 6 +++---
 src/backend/tsearch/ts_utils.c          | 2 +-
 src/backend/utils/adt/tsgistidx.c       | 2 +-
 src/backend/utils/adt/tsquery.c         | 2 +-
 src/backend/utils/adt/tsquery_cleanup.c | 2 +-
 src/backend/utils/adt/tsvector.c        | 4 ++--
 9 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/contrib/ltree/ltxtquery_io.c b/contrib/ltree/ltxtquery_io.c
index d9910e6c99..82d617f1ae 100644
--- a/contrib/ltree/ltxtquery_io.c
+++ b/contrib/ltree/ltxtquery_io.c
@@ -195,7 +195,7 @@ pushval_asis(QPRS_STATE *state, int type, char *strval, int lenval, uint16 flag)
 		int32		tmp = state->curop - state->op;
 
 		state->lenop *= 2;
-		state->op = (char *) repalloc((void *) state->op, state->lenop);
+		state->op = (char *) repalloc(state->op, state->lenop);
 		state->curop = state->op + tmp;
 	}
 	memcpy((void *) state->curop, (void *) strval, lenval);
diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c
index 56451fede1..b4d843a0ff 100644
--- a/src/backend/access/gist/gistutil.c
+++ b/src/backend/access/gist/gistutil.c
@@ -113,7 +113,7 @@ gistextractpage(Page page, int *len /* out */ )
 IndexTuple *
 gistjoinvector(IndexTuple *itvec, int *len, IndexTuple *additvec, int addlen)
 {
-	itvec = (IndexTuple *) repalloc((void *) itvec, sizeof(IndexTuple) * ((*len) + addlen));
+	itvec = (IndexTuple *) repalloc(itvec, sizeof(IndexTuple) * ((*len) + addlen));
 	memmove(&itvec[*len], additvec, sizeof(IndexTuple) * addlen);
 	*len += addlen;
 	return itvec;
diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c
index 83838ab438..c8dfed6178 100644
--- a/src/backend/tsearch/spell.c
+++ b/src/backend/tsearch/spell.c
@@ -695,7 +695,7 @@ NIAddAffix(IspellDict *Conf, const char *flag, char flagflags, const char *mask,
 		if (Conf->maffixes)
 		{
 			Conf->maffixes *= 2;
-			Conf->Affix = (AFFIX *) repalloc((void *) Conf->Affix, Conf->maffixes * sizeof(AFFIX));
+			Conf->Affix = (AFFIX *) repalloc(Conf->Affix, Conf->maffixes * sizeof(AFFIX));
 		}
 		else
 		{
@@ -1116,7 +1116,7 @@ addCompoundAffixFlagValue(IspellDict *Conf, char *s, uint32 val)
 		{
 			Conf->mCompoundAffixFlag *= 2;
 			Conf->CompoundAffixFlags = (CompoundAffixFlag *)
-				repalloc((void *) Conf->CompoundAffixFlags,
+				repalloc(Conf->CompoundAffixFlags,
 						 Conf->mCompoundAffixFlag * sizeof(CompoundAffixFlag));
 		}
 		else
diff --git a/src/backend/tsearch/ts_parse.c b/src/backend/tsearch/ts_parse.c
index 9b6d934958..25d9852778 100644
--- a/src/backend/tsearch/ts_parse.c
+++ b/src/backend/tsearch/ts_parse.c
@@ -410,7 +410,7 @@ parsetext(Oid cfgId, ParsedText *prs, char *buf, int buflen)
 				if (prs->curwords == prs->lenwords)
 				{
 					prs->lenwords *= 2;
-					prs->words = (ParsedWord *) repalloc((void *) prs->words, prs->lenwords * sizeof(ParsedWord));
+					prs->words = (ParsedWord *) repalloc(prs->words, prs->lenwords * sizeof(ParsedWord));
 				}
 
 				if (ptr->flags & TSL_ADDPOS)
@@ -442,7 +442,7 @@ hladdword(HeadlineParsedText *prs, char *buf, int buflen, int type)
 	if (prs->curwords >= prs->lenwords)
 	{
 		prs->lenwords *= 2;
-		prs->words = (HeadlineWordEntry *) repalloc((void *) prs->words, prs->lenwords * sizeof(HeadlineWordEntry));
+		prs->words = (HeadlineWordEntry *) repalloc(prs->words, prs->lenwords * sizeof(HeadlineWordEntry));
 	}
 	memset(&(prs->words[prs->curwords]), 0, sizeof(HeadlineWordEntry));
 	prs->words[prs->curwords].type = (uint8) type;
@@ -470,7 +470,7 @@ hlfinditem(HeadlineParsedText *prs, TSQuery query, int32 pos, char *buf, int buf
 	while (prs->curwords + query->size >= prs->lenwords)
 	{
 		prs->lenwords *= 2;
-		prs->words = (HeadlineWordEntry *) repalloc((void *) prs->words, prs->lenwords * sizeof(HeadlineWordEntry));
+		prs->words = (HeadlineWordEntry *) repalloc(prs->words, prs->lenwords * sizeof(HeadlineWordEntry));
 	}
 
 	word = &(prs->words[prs->curwords - 1]);
diff --git a/src/backend/tsearch/ts_utils.c b/src/backend/tsearch/ts_utils.c
index bb954184d3..c46867d074 100644
--- a/src/backend/tsearch/ts_utils.c
+++ b/src/backend/tsearch/ts_utils.c
@@ -109,7 +109,7 @@ readstoplist(const char *fname, StopList *s, char *(*wordop) (const char *))
 				else
 				{
 					reallen *= 2;
-					stop = (char **) repalloc((void *) stop,
+					stop = (char **) repalloc(stop,
 											  sizeof(char *) * reallen);
 				}
 			}
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
index f0411bf48f..a360b26ee2 100644
--- a/src/backend/utils/adt/tsgistidx.c
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -204,7 +204,7 @@ gtsvector_compress(PG_FUNCTION_ARGS)
 			 * val->size
 			 */
 			len = CALCGTSIZE(ARRKEY, len);
-			res = (SignTSVector *) repalloc((void *) res, len);
+			res = (SignTSVector *) repalloc(res, len);
 			SET_VARSIZE(res, len);
 		}
 
diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
index 25150c6d16..e22a2c20a0 100644
--- a/src/backend/utils/adt/tsquery.c
+++ b/src/backend/utils/adt/tsquery.c
@@ -602,7 +602,7 @@ pushValue(TSQueryParserState state, char *strval, int lenval, int16 weight, bool
 		int			used = state->curop - state->op;
 
 		state->lenop *= 2;
-		state->op = (char *) repalloc((void *) state->op, state->lenop);
+		state->op = (char *) repalloc(state->op, state->lenop);
 		state->curop = state->op + used;
 	}
 	memcpy((void *) state->curop, (void *) strval, lenval);
diff --git a/src/backend/utils/adt/tsquery_cleanup.c b/src/backend/utils/adt/tsquery_cleanup.c
index 59b3e859c3..7b9210c321 100644
--- a/src/backend/utils/adt/tsquery_cleanup.c
+++ b/src/backend/utils/adt/tsquery_cleanup.c
@@ -67,7 +67,7 @@ plainnode(PLAINTREE *state, NODE *node)
 	if (state->cur == state->len)
 	{
 		state->len *= 2;
-		state->ptr = (QueryItem *) repalloc((void *) state->ptr, state->len * sizeof(QueryItem));
+		state->ptr = (QueryItem *) repalloc(state->ptr, state->len * sizeof(QueryItem));
 	}
 	memcpy((void *) &(state->ptr[state->cur]), (void *) node->valnode, sizeof(QueryItem));
 	if (node->valnode->type == QI_VAL)
diff --git a/src/backend/utils/adt/tsvector.c b/src/backend/utils/adt/tsvector.c
index c7e20ce4ec..77673864a2 100644
--- a/src/backend/utils/adt/tsvector.c
+++ b/src/backend/utils/adt/tsvector.c
@@ -232,14 +232,14 @@ tsvectorin(PG_FUNCTION_ARGS)
 		{
 			arrlen *= 2;
 			arr = (WordEntryIN *)
-				repalloc((void *) arr, sizeof(WordEntryIN) * arrlen);
+				repalloc(arr, sizeof(WordEntryIN) * arrlen);
 		}
 		while ((cur - tmpbuf) + toklen >= buflen)
 		{
 			int			dist = cur - tmpbuf;
 
 			buflen *= 2;
-			tmpbuf = (char *) repalloc((void *) tmpbuf, buflen);
+			tmpbuf = (char *) repalloc(tmpbuf, buflen);
 			cur = tmpbuf + dist;
 		}
 		arr[len].entry.len = toklen;
-- 
2.39.1


From 5104fe8d3c2569d74ef77626684d9a38372d36f8 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:34 +0100
Subject: [PATCH 3/8] Remove useless casts to (void *) (memcpy)

---
 contrib/btree_gist/btree_bit.c          | 2 +-
 contrib/btree_gist/btree_interval.c     | 4 ++--
 contrib/btree_gist/btree_utils_num.c    | 6 +++---
 contrib/btree_gist/btree_uuid.c         | 4 ++--
 contrib/ltree/ltxtquery_io.c            | 4 ++--
 contrib/pg_trgm/trgm_gist.c             | 2 +-
 doc/src/sgml/xfunc.sgml                 | 4 ++--
 src/backend/access/gist/gistproc.c      | 4 ++--
 src/backend/storage/ipc/procarray.c     | 4 ++--
 src/backend/utils/adt/tsgistidx.c       | 2 +-
 src/backend/utils/adt/tsquery.c         | 4 ++--
 src/backend/utils/adt/tsquery_cleanup.c | 2 +-
 src/backend/utils/adt/tsvector.c        | 2 +-
 src/tutorial/funcs.c                    | 4 ++--
 14 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/contrib/btree_gist/btree_bit.c b/contrib/btree_gist/btree_bit.c
index 5b246bcde4..6790f22b4b 100644
--- a/contrib/btree_gist/btree_bit.c
+++ b/contrib/btree_gist/btree_bit.c
@@ -84,7 +84,7 @@ gbt_bit_xfrm(bytea *leaf)
 	while (sz < padded_sz)
 		((char *) out)[sz++] = 0;
 	SET_VARSIZE(out, padded_sz);
-	memcpy((void *) VARDATA(out), (void *) VARBITS(leaf), VARBITBYTES(leaf));
+	memcpy(VARDATA(out), VARBITS(leaf), VARBITBYTES(leaf));
 	return out;
 }
 
diff --git a/contrib/btree_gist/btree_interval.c b/contrib/btree_gist/btree_interval.c
index 2c98b330cd..b0afdf02bb 100644
--- a/contrib/btree_gist/btree_interval.c
+++ b/contrib/btree_gist/btree_interval.c
@@ -157,8 +157,8 @@ gbt_intv_compress(PG_FUNCTION_ARGS)
 		{
 			Interval   *key = DatumGetIntervalP(entry->key);
 
-			memcpy((void *) r, (void *) key, INTERVALSIZE);
-			memcpy((void *) (r + INTERVALSIZE), (void *) key, INTERVALSIZE);
+			memcpy(r, key, INTERVALSIZE);
+			memcpy(r + INTERVALSIZE, key, INTERVALSIZE);
 		}
 		else
 		{
diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c
index 05c154afa3..cfbecbea65 100644
--- a/contrib/btree_gist/btree_utils_num.c
+++ b/contrib/btree_gist/btree_utils_num.c
@@ -87,8 +87,8 @@ gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 
 		Assert(tinfo->indexsize >= 2 * tinfo->size);
 
-		memcpy((void *) &r[0], leaf, tinfo->size);
-		memcpy((void *) &r[tinfo->size], leaf, tinfo->size);
+		memcpy(&r[0], leaf, tinfo->size);
+		memcpy(&r[tinfo->size], leaf, tinfo->size);
 		retval = palloc(sizeof(GISTENTRY));
 		gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page,
 					  entry->offset, false);
@@ -184,7 +184,7 @@ gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_nin
 	o.lower = &((GBT_NUMKEY *) out)[0];
 	o.upper = &((GBT_NUMKEY *) out)[tinfo->size];
 
-	memcpy((void *) out, (void *) cur, 2 * tinfo->size);
+	memcpy(out, cur, 2 * tinfo->size);
 
 	for (i = 1; i < numranges; i++)
 	{
diff --git a/contrib/btree_gist/btree_uuid.c b/contrib/btree_gist/btree_uuid.c
index b81875979a..fe8c679cbe 100644
--- a/contrib/btree_gist/btree_uuid.c
+++ b/contrib/btree_gist/btree_uuid.c
@@ -110,8 +110,8 @@ gbt_uuid_compress(PG_FUNCTION_ARGS)
 
 		retval = palloc(sizeof(GISTENTRY));
 
-		memcpy((void *) r, (void *) key, UUID_LEN);
-		memcpy((void *) (r + UUID_LEN), (void *) key, UUID_LEN);
+		memcpy(r, key, UUID_LEN);
+		memcpy(r + UUID_LEN, key, UUID_LEN);
 		gistentryinit(*retval, PointerGetDatum(r),
 					  entry->rel, entry->page,
 					  entry->offset, false);
diff --git a/contrib/ltree/ltxtquery_io.c b/contrib/ltree/ltxtquery_io.c
index 82d617f1ae..0d29e15630 100644
--- a/contrib/ltree/ltxtquery_io.c
+++ b/contrib/ltree/ltxtquery_io.c
@@ -198,7 +198,7 @@ pushval_asis(QPRS_STATE *state, int type, char *strval, int lenval, uint16 flag)
 		state->op = (char *) repalloc(state->op, state->lenop);
 		state->curop = state->op + tmp;
 	}
-	memcpy((void *) state->curop, (void *) strval, lenval);
+	memcpy(state->curop, strval, lenval);
 	state->curop += lenval;
 	*(state->curop) = '\0';
 	state->curop++;
@@ -391,7 +391,7 @@ queryin(char *buf, struct Node *escontext)
 	}
 
 	/* set user-friendly operand view */
-	memcpy((void *) GETOPERAND(query), (void *) state.op, state.sumlen);
+	memcpy(GETOPERAND(query), state.op, state.sumlen);
 	pfree(state.op);
 
 	/* set left operand's position for every operator */
diff --git a/contrib/pg_trgm/trgm_gist.c b/contrib/pg_trgm/trgm_gist.c
index ef5d8cca78..68ebf1767b 100644
--- a/contrib/pg_trgm/trgm_gist.c
+++ b/contrib/pg_trgm/trgm_gist.c
@@ -755,7 +755,7 @@ fillcache(CACHESIGN *item, TRGM *key, BITVECP sign, int siglen)
 	else if (ISALLTRUE(key))
 		item->allistrue = true;
 	else
-		memcpy((void *) item->sign, (void *) GETSIGN(key), siglen);
+		memcpy(item->sign, GETSIGN(key), siglen);
 }
 
 #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index 52e5aa17bf..e2a5496c34 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -2456,8 +2456,8 @@ <title>Version 1 Calling Conventions</title>
      * VARDATA is a pointer to the data region of the new struct.  The source
      * could be a short datum, so retrieve its data through VARDATA_ANY.
      */
-    memcpy((void *) VARDATA(new_t), /* destination */
-           (void *) VARDATA_ANY(t), /* source */
+    memcpy(VARDATA(new_t),          /* destination */
+           VARDATA_ANY(t),          /* source */
            VARSIZE_ANY_EXHDR(t));   /* how many bytes */
     PG_RETURN_TEXT_P(new_t);
 }
diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c
index eb9178d456..4881034069 100644
--- a/src/backend/access/gist/gistproc.c
+++ b/src/backend/access/gist/gistproc.c
@@ -173,7 +173,7 @@ gist_box_union(PG_FUNCTION_ARGS)
 	numranges = entryvec->n;
 	pageunion = (BOX *) palloc(sizeof(BOX));
 	cur = DatumGetBoxP(entryvec->vector[0].key);
-	memcpy((void *) pageunion, (void *) cur, sizeof(BOX));
+	memcpy(pageunion, cur, sizeof(BOX));
 
 	for (i = 1; i < numranges; i++)
 	{
@@ -1043,7 +1043,7 @@ gist_poly_compress(PG_FUNCTION_ARGS)
 		BOX		   *r;
 
 		r = (BOX *) palloc(sizeof(BOX));
-		memcpy((void *) r, (void *) &(in->boundbox), sizeof(BOX));
+		memcpy(r, &(in->boundbox), sizeof(BOX));
 
 		retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
 		gistentryinit(*retval, PointerGetDatum(r),
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 4340bf9641..a7071b2fce 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -2394,7 +2394,7 @@ GetSnapshotData(Snapshot snapshot)
 						pg_read_barrier();	/* pairs with GetNewTransactionId */
 
 						memcpy(snapshot->subxip + subcount,
-							   (void *) proc->subxids.xids,
+							   proc->subxids.xids,
 							   nsubxids * sizeof(TransactionId));
 						subcount += nsubxids;
 					}
@@ -2846,7 +2846,7 @@ GetRunningTransactionData(void)
 				/* barrier not really required, as XidGenLock is held, but ... */
 				pg_read_barrier();	/* pairs with GetNewTransactionId */
 
-				memcpy(&xids[count], (void *) proc->subxids.xids,
+				memcpy(&xids[count], proc->subxids.xids,
 					   nsubxids * sizeof(TransactionId));
 				count += nsubxids;
 				subcount += nsubxids;
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
index a360b26ee2..e27e08d996 100644
--- a/src/backend/utils/adt/tsgistidx.c
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -577,7 +577,7 @@ fillcache(CACHESIGN *item, SignTSVector *key, int siglen)
 	else if (ISALLTRUE(key))
 		item->allistrue = true;
 	else
-		memcpy((void *) item->sign, (void *) GETSIGN(key), siglen);
+		memcpy(item->sign, GETSIGN(key), siglen);
 }
 
 #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
index e22a2c20a0..67ad876a27 100644
--- a/src/backend/utils/adt/tsquery.c
+++ b/src/backend/utils/adt/tsquery.c
@@ -605,7 +605,7 @@ pushValue(TSQueryParserState state, char *strval, int lenval, int16 weight, bool
 		state->op = (char *) repalloc(state->op, state->lenop);
 		state->curop = state->op + used;
 	}
-	memcpy((void *) state->curop, (void *) strval, lenval);
+	memcpy(state->curop, strval, lenval);
 	state->curop += lenval;
 	*(state->curop) = '\0';
 	state->curop++;
@@ -924,7 +924,7 @@ parse_tsquery(char *buf,
 	}
 
 	/* Copy all the operand strings to TSQuery */
-	memcpy((void *) GETOPERAND(query), (void *) state.op, state.sumlen);
+	memcpy(GETOPERAND(query), state.op, state.sumlen);
 	pfree(state.op);
 
 	/*
diff --git a/src/backend/utils/adt/tsquery_cleanup.c b/src/backend/utils/adt/tsquery_cleanup.c
index 7b9210c321..dc31665770 100644
--- a/src/backend/utils/adt/tsquery_cleanup.c
+++ b/src/backend/utils/adt/tsquery_cleanup.c
@@ -69,7 +69,7 @@ plainnode(PLAINTREE *state, NODE *node)
 		state->len *= 2;
 		state->ptr = (QueryItem *) repalloc(state->ptr, state->len * sizeof(QueryItem));
 	}
-	memcpy((void *) &(state->ptr[state->cur]), (void *) node->valnode, sizeof(QueryItem));
+	memcpy(&(state->ptr[state->cur]), node->valnode, sizeof(QueryItem));
 	if (node->valnode->type == QI_VAL)
 		state->cur++;
 	else if (node->valnode->qoperator.oper == OP_NOT)
diff --git a/src/backend/utils/adt/tsvector.c b/src/backend/utils/adt/tsvector.c
index 77673864a2..e5b05960e3 100644
--- a/src/backend/utils/adt/tsvector.c
+++ b/src/backend/utils/adt/tsvector.c
@@ -244,7 +244,7 @@ tsvectorin(PG_FUNCTION_ARGS)
 		}
 		arr[len].entry.len = toklen;
 		arr[len].entry.pos = cur - tmpbuf;
-		memcpy((void *) cur, (void *) token, toklen);
+		memcpy(cur, token, toklen);
 		cur += toklen;
 
 		if (poslen != 0)
diff --git a/src/tutorial/funcs.c b/src/tutorial/funcs.c
index cdd155ebbd..ceffb56835 100644
--- a/src/tutorial/funcs.c
+++ b/src/tutorial/funcs.c
@@ -78,8 +78,8 @@ copytext(PG_FUNCTION_ARGS)
 	 * VARDATA is a pointer to the data region of the new struct.  The source
 	 * could be a short datum, so retrieve its data through VARDATA_ANY.
 	 */
-	memcpy((void *) VARDATA(new_t), /* destination */
-		   (void *) VARDATA_ANY(t), /* source */
+	memcpy(VARDATA(new_t),          /* destination */
+		   VARDATA_ANY(t),          /* source */
 		   VARSIZE_ANY_EXHDR(t));	/* how many bytes */
 	PG_RETURN_TEXT_P(new_t);
 }
-- 
2.39.1


From ac0833f8a98d4561c0378fbf98345307b578bcbf Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:34 +0100
Subject: [PATCH 4/8] Remove useless casts to (void *) (memset)

---
 contrib/hstore/hstore_gist.c      | 4 ++--
 contrib/intarray/_intbig_gist.c   | 4 ++--
 contrib/ltree/_ltree_gist.c       | 4 ++--
 contrib/pg_trgm/trgm_gist.c       | 6 +++---
 src/backend/tsearch/ts_utils.c    | 3 +--
 src/backend/utils/adt/tsgistidx.c | 6 +++---
 src/bin/pg_dump/parallel.c        | 2 +-
 7 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/contrib/hstore/hstore_gist.c b/contrib/hstore/hstore_gist.c
index 5d8b806d30..d31da564fe 100644
--- a/contrib/hstore/hstore_gist.c
+++ b/contrib/hstore/hstore_gist.c
@@ -465,7 +465,7 @@ ghstore_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_l) || ISALLTRUE(_j))
 			{
 				if (!ISALLTRUE(datum_l))
-					memset((void *) union_l, 0xff, siglen);
+					memset(union_l, 0xff, siglen);
 			}
 			else
 			{
@@ -481,7 +481,7 @@ ghstore_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_r) || ISALLTRUE(_j))
 			{
 				if (!ISALLTRUE(datum_r))
-					memset((void *) union_r, 0xff, siglen);
+					memset(union_r, 0xff, siglen);
 			}
 			else
 			{
diff --git a/contrib/intarray/_intbig_gist.c b/contrib/intarray/_intbig_gist.c
index dadc18646a..f8fca44ea5 100644
--- a/contrib/intarray/_intbig_gist.c
+++ b/contrib/intarray/_intbig_gist.c
@@ -424,7 +424,7 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_l) || ISALLTRUE(_j))
 			{
 				if (!ISALLTRUE(datum_l))
-					memset((void *) union_l, 0xff, siglen);
+					memset(union_l, 0xff, siglen);
 			}
 			else
 			{
@@ -440,7 +440,7 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_r) || ISALLTRUE(_j))
 			{
 				if (!ISALLTRUE(datum_r))
-					memset((void *) union_r, 0xff, siglen);
+					memset(union_r, 0xff, siglen);
 			}
 			else
 			{
diff --git a/contrib/ltree/_ltree_gist.c b/contrib/ltree/_ltree_gist.c
index 385a10283b..4d9ee53f08 100644
--- a/contrib/ltree/_ltree_gist.c
+++ b/contrib/ltree/_ltree_gist.c
@@ -348,7 +348,7 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
 			if (LTG_ISALLTRUE(datum_l) || LTG_ISALLTRUE(_j))
 			{
 				if (!LTG_ISALLTRUE(datum_l))
-					memset((void *) union_l, 0xff, siglen);
+					memset(union_l, 0xff, siglen);
 			}
 			else
 			{
@@ -364,7 +364,7 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
 			if (LTG_ISALLTRUE(datum_r) || LTG_ISALLTRUE(_j))
 			{
 				if (!LTG_ISALLTRUE(datum_r))
-					memset((void *) union_r, 0xff, siglen);
+					memset(union_r, 0xff, siglen);
 			}
 			else
 			{
diff --git a/contrib/pg_trgm/trgm_gist.c b/contrib/pg_trgm/trgm_gist.c
index 68ebf1767b..ed2b010b93 100644
--- a/contrib/pg_trgm/trgm_gist.c
+++ b/contrib/pg_trgm/trgm_gist.c
@@ -102,7 +102,7 @@ makesign(BITVECP sign, TRGM *a, int siglen)
 	trgm	   *ptr = GETARR(a);
 	int32		tmp = 0;
 
-	MemSet((void *) sign, 0, siglen);
+	MemSet(sign, 0, siglen);
 	SETBIT(sign, SIGLENBIT(siglen));	/* set last unused bit */
 	for (k = 0; k < len; k++)
 	{
@@ -921,7 +921,7 @@ gtrgm_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_l) || cache[j].allistrue)
 			{
 				if (!ISALLTRUE(datum_l))
-					memset((void *) GETSIGN(datum_l), 0xff, siglen);
+					memset(GETSIGN(datum_l), 0xff, siglen);
 			}
 			else
 			{
@@ -937,7 +937,7 @@ gtrgm_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_r) || cache[j].allistrue)
 			{
 				if (!ISALLTRUE(datum_r))
-					memset((void *) GETSIGN(datum_r), 0xff, siglen);
+					memset(GETSIGN(datum_r), 0xff, siglen);
 			}
 			else
 			{
diff --git a/src/backend/tsearch/ts_utils.c b/src/backend/tsearch/ts_utils.c
index c46867d074..7c4c2a9112 100644
--- a/src/backend/tsearch/ts_utils.c
+++ b/src/backend/tsearch/ts_utils.c
@@ -109,8 +109,7 @@ readstoplist(const char *fname, StopList *s, char *(*wordop) (const char *))
 				else
 				{
 					reallen *= 2;
-					stop = (char **) repalloc(stop,
-											  sizeof(char *) * reallen);
+					stop = (char **) repalloc(stop, sizeof(char *) * reallen);
 				}
 			}
 
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
index e27e08d996..ca4563290f 100644
--- a/src/backend/utils/adt/tsgistidx.c
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -143,7 +143,7 @@ makesign(BITVECP sign, SignTSVector *a, int siglen)
 				len = ARRNELEM(a);
 	int32	   *ptr = GETARR(a);
 
-	MemSet((void *) sign, 0, siglen);
+	MemSet(sign, 0, siglen);
 	for (k = 0; k < len; k++)
 		HASH(sign, ptr[k], siglen);
 }
@@ -755,7 +755,7 @@ gtsvector_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_l) || cache[j].allistrue)
 			{
 				if (!ISALLTRUE(datum_l))
-					memset((void *) GETSIGN(datum_l), 0xff, siglen);
+					memset(GETSIGN(datum_l), 0xff, siglen);
 			}
 			else
 			{
@@ -771,7 +771,7 @@ gtsvector_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_r) || cache[j].allistrue)
 			{
 				if (!ISALLTRUE(datum_r))
-					memset((void *) GETSIGN(datum_r), 0xff, siglen);
+					memset(GETSIGN(datum_r), 0xff, siglen);
 			}
 			else
 			{
diff --git a/src/bin/pg_dump/parallel.c b/src/bin/pg_dump/parallel.c
index 9bfb95557a..da0723ad38 100644
--- a/src/bin/pg_dump/parallel.c
+++ b/src/bin/pg_dump/parallel.c
@@ -1736,7 +1736,7 @@ pgpipe(int handles[2])
 		return -1;
 	}
 
-	memset((void *) &serv_addr, 0, sizeof(serv_addr));
+	memset(&serv_addr, 0, sizeof(serv_addr));
 	serv_addr.sin_family = AF_INET;
 	serv_addr.sin_port = pg_hton16(0);
 	serv_addr.sin_addr.s_addr = pg_hton32(INADDR_LOOPBACK);
-- 
2.39.1


From 7da5b5474a65d5a5a3fd104a624f3e9048f973dd Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:35 +0100
Subject: [PATCH 5/8] Remove useless casts to (void *) (memmove)

---
 contrib/intarray/_int_gist.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/contrib/intarray/_int_gist.c b/contrib/intarray/_int_gist.c
index 331fa25fcf..2d72e7dafb 100644
--- a/contrib/intarray/_int_gist.c
+++ b/contrib/intarray/_int_gist.c
@@ -243,7 +243,7 @@ g_int_compress(PG_FUNCTION_ARGS)
 			/*
 			 * shunt everything down to start at the right place
 			 */
-			memmove((void *) &dr[0], (void *) &dr[2 * j], 2 * (len - j) * sizeof(int32));
+			memmove(&dr[0], &dr[2 * j], 2 * (len - j) * sizeof(int32));
 		}
 
 		/*
@@ -260,7 +260,7 @@ g_int_compress(PG_FUNCTION_ARGS)
 					min = ((int64) dr[i] - (int64) dr[i - 1]);
 					cand = i;
 				}
-			memmove((void *) &dr[cand - 1], (void *) &dr[cand + 1], (len - cand - 1) * sizeof(int32));
+			memmove(&dr[cand - 1], &dr[cand + 1], (len - cand - 1) * sizeof(int32));
 			len -= 2;
 		}
 
-- 
2.39.1


From 122a9bc37bb9e095665e3b44095f0394983a647a Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:35 +0100
Subject: [PATCH 6/8] Remove useless casts to (void *) (memcmp)

---
 contrib/citext/citext.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/citext/citext.c b/contrib/citext/citext.c
index 976c578e1c..26af935a70 100644
--- a/contrib/citext/citext.c
+++ b/contrib/citext/citext.c
@@ -80,7 +80,7 @@ internal_citext_pattern_cmp(text *left, text *right, Oid collid)
 	llen = strlen(lcstr);
 	rlen = strlen(rcstr);
 
-	result = memcmp((void *) lcstr, (void *) rcstr, Min(llen, rlen));
+	result = memcmp(lcstr, rcstr, Min(llen, rlen));
 	if (result == 0)
 	{
 		if (llen < rlen)
-- 
2.39.1


From 2b7d664f2f7d475f84ead47eafde28157fcaf061 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:35 +0100
Subject: [PATCH 7/8] Remove useless casts to (void *) (qsort)

---
 contrib/btree_gist/btree_utils_num.c        |  2 +-
 contrib/btree_gist/btree_utils_var.c        |  4 ++--
 contrib/hstore/hstore_gist.c                |  2 +-
 contrib/hstore/hstore_io.c                  |  2 +-
 contrib/intarray/_int_gist.c                |  2 +-
 contrib/intarray/_int_tool.c                |  2 +-
 contrib/intarray/_intbig_gist.c             |  2 +-
 contrib/ltree/_ltree_gist.c                 |  2 +-
 contrib/ltree/ltree_gist.c                  |  2 +-
 contrib/pg_surgery/heap_surgery.c           |  2 +-
 contrib/pg_trgm/trgm_gist.c                 |  2 +-
 contrib/pg_trgm/trgm_op.c                   |  4 ++--
 src/backend/access/brin/brin_minmax_multi.c |  6 +++---
 src/backend/access/gin/ginutil.c            |  2 +-
 src/backend/access/nbtree/nbtutils.c        |  4 ++--
 src/backend/catalog/dependency.c            |  6 +++---
 src/backend/catalog/pg_shdepend.c           |  2 +-
 src/backend/commands/analyze.c              |  8 ++++----
 src/backend/commands/collationcmds.c        |  2 +-
 src/backend/executor/nodeTidscan.c          |  2 +-
 src/backend/nodes/tidbitmap.c               |  8 ++++----
 src/backend/partitioning/partbounds.c       |  4 ++--
 src/backend/statistics/extended_stats.c     |  2 +-
 src/backend/statistics/mcv.c                |  4 ++--
 src/backend/statistics/mvdistinct.c         |  2 +-
 src/backend/tsearch/spell.c                 |  8 ++++----
 src/backend/tsearch/to_tsany.c              |  2 +-
 src/backend/utils/adt/tsgistidx.c           |  2 +-
 src/backend/utils/adt/tsquery_gist.c        |  2 +-
 src/backend/utils/adt/tsquery_util.c        |  2 +-
 src/backend/utils/adt/tsrank.c              |  4 ++--
 src/backend/utils/adt/tsvector.c            | 10 +++++-----
 src/bin/pg_dump/pg_backup_archiver.c        |  2 +-
 src/bin/pg_dump/pg_dump_sort.c              |  2 +-
 src/bin/pg_upgrade/function.c               |  2 +-
 src/bin/pgbench/pgbench.c                   |  2 +-
 36 files changed, 59 insertions(+), 59 deletions(-)

diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c
index cfbecbea65..346ee837d7 100644
--- a/contrib/btree_gist/btree_utils_num.c
+++ b/contrib/btree_gist/btree_utils_num.c
@@ -360,7 +360,7 @@ gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 		arr[i].t = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
 		arr[i].i = i;
 	}
-	qsort_arg((void *) &arr[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1, sizeof(Nsrt), (qsort_arg_comparator) tinfo->f_cmp, (void *) flinfo);
+	qsort_arg(&arr[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1, sizeof(Nsrt), (qsort_arg_comparator) tinfo->f_cmp, flinfo);
 
 	/* We do simply create two parts */
 
diff --git a/contrib/btree_gist/btree_utils_var.c b/contrib/btree_gist/btree_utils_var.c
index 3ef82d0e20..0c0e952f73 100644
--- a/contrib/btree_gist/btree_utils_var.c
+++ b/contrib/btree_gist/btree_utils_var.c
@@ -502,11 +502,11 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 	varg.tinfo = tinfo;
 	varg.collation = collation;
 	varg.flinfo = flinfo;
-	qsort_arg((void *) &arr[FirstOffsetNumber],
+	qsort_arg(&arr[FirstOffsetNumber],
 			  maxoff - FirstOffsetNumber + 1,
 			  sizeof(Vsrt),
 			  gbt_vsrt_cmp,
-			  (void *) &varg);
+			  &varg);
 
 	/* We do simply create two parts */
 
diff --git a/contrib/hstore/hstore_gist.c b/contrib/hstore/hstore_gist.c
index d31da564fe..3df00493e8 100644
--- a/contrib/hstore/hstore_gist.c
+++ b/contrib/hstore/hstore_gist.c
@@ -436,7 +436,7 @@ ghstore_picksplit(PG_FUNCTION_ARGS)
 		size_beta = hemdist(datum_r, _j, siglen);
 		costvector[j - 1].cost = abs(size_alpha - size_beta);
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	union_l = GETSIGN(datum_l);
 	union_r = GETSIGN(datum_r);
diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c
index ae09cede8c..cec7df71a2 100644
--- a/contrib/hstore/hstore_io.c
+++ b/contrib/hstore/hstore_io.c
@@ -365,7 +365,7 @@ hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
 		return l;
 	}
 
-	qsort((void *) a, l, sizeof(Pairs), comparePairs);
+	qsort(a, l, sizeof(Pairs), comparePairs);
 
 	/*
 	 * We can't use qunique here because we have some clean-up code to run on
diff --git a/contrib/intarray/_int_gist.c b/contrib/intarray/_int_gist.c
index 2d72e7dafb..7a48ce624d 100644
--- a/contrib/intarray/_int_gist.c
+++ b/contrib/intarray/_int_gist.c
@@ -542,7 +542,7 @@ g_int_picksplit(PG_FUNCTION_ARGS)
 		pfree(union_d);
 		costvector[i - 1].cost = fabsf((size_alpha - size_l) - (size_beta - size_r));
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	/*
 	 * Now split up the regions between the two seeds.  An important property
diff --git a/contrib/intarray/_int_tool.c b/contrib/intarray/_int_tool.c
index 5ab6eb81e8..68f624e085 100644
--- a/contrib/intarray/_int_tool.c
+++ b/contrib/intarray/_int_tool.c
@@ -212,7 +212,7 @@ isort(int32 *a, int len)
 {
 	bool		r = false;
 
-	qsort_arg(a, len, sizeof(int32), isort_cmp, (void *) &r);
+	qsort_arg(a, len, sizeof(int32), isort_cmp, &r);
 	return r;
 }
 
diff --git a/contrib/intarray/_intbig_gist.c b/contrib/intarray/_intbig_gist.c
index f8fca44ea5..bfba5eef1d 100644
--- a/contrib/intarray/_intbig_gist.c
+++ b/contrib/intarray/_intbig_gist.c
@@ -395,7 +395,7 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 		size_beta = hemdist(datum_r, _j, siglen);
 		costvector[j - 1].cost = abs(size_alpha - size_beta);
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	union_l = GETSIGN(datum_l);
 	union_r = GETSIGN(datum_r);
diff --git a/contrib/ltree/_ltree_gist.c b/contrib/ltree/_ltree_gist.c
index 4d9ee53f08..e89a39a5b5 100644
--- a/contrib/ltree/_ltree_gist.c
+++ b/contrib/ltree/_ltree_gist.c
@@ -319,7 +319,7 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
 		size_beta = hemdist(datum_r, _j, siglen);
 		costvector[j - 1].cost = abs(size_alpha - size_beta);
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	union_l = LTG_SIGN(datum_l);
 	union_r = LTG_SIGN(datum_r);
diff --git a/contrib/ltree/ltree_gist.c b/contrib/ltree/ltree_gist.c
index 5d2db6c62b..3cba2269d8 100644
--- a/contrib/ltree/ltree_gist.c
+++ b/contrib/ltree/ltree_gist.c
@@ -328,7 +328,7 @@ ltree_picksplit(PG_FUNCTION_ARGS)
 		array[j].r = LTG_GETLNODE(lu, siglen);
 	}
 
-	qsort((void *) &array[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1,
+	qsort(&array[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1,
 		  sizeof(RIX), treekey_cmp);
 
 	lu_l = lu_r = ru_l = ru_r = NULL;
diff --git a/contrib/pg_surgery/heap_surgery.c b/contrib/pg_surgery/heap_surgery.c
index 61b184597a..88a40ab7d3 100644
--- a/contrib/pg_surgery/heap_surgery.c
+++ b/contrib/pg_surgery/heap_surgery.c
@@ -131,7 +131,7 @@ heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt)
 	 * array.
 	 */
 	if (ntids > 1)
-		qsort((void *) tids, ntids, sizeof(ItemPointerData), tidcmp);
+		qsort(tids, ntids, sizeof(ItemPointerData), tidcmp);
 
 	curr_start_ptr = next_start_ptr = 0;
 	nblocks = RelationGetNumberOfBlocks(rel);
diff --git a/contrib/pg_trgm/trgm_gist.c b/contrib/pg_trgm/trgm_gist.c
index ed2b010b93..9ef2e38560 100644
--- a/contrib/pg_trgm/trgm_gist.c
+++ b/contrib/pg_trgm/trgm_gist.c
@@ -872,7 +872,7 @@ gtrgm_picksplit(PG_FUNCTION_ARGS)
 		size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]), siglen);
 		costvector[j - 1].cost = abs(size_alpha - size_beta);
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	for (k = 0; k < maxoff; k++)
 	{
diff --git a/contrib/pg_trgm/trgm_op.c b/contrib/pg_trgm/trgm_op.c
index 2c644bc148..49d4497b4f 100644
--- a/contrib/pg_trgm/trgm_op.c
+++ b/contrib/pg_trgm/trgm_op.c
@@ -376,7 +376,7 @@ generate_trgm(char *str, int slen)
 	 */
 	if (len > 1)
 	{
-		qsort((void *) GETARR(trg), len, sizeof(trgm), comp_trgm);
+		qsort(GETARR(trg), len, sizeof(trgm), comp_trgm);
 		len = qunique(GETARR(trg), len, sizeof(trgm), comp_trgm);
 	}
 
@@ -929,7 +929,7 @@ generate_wildcard_trgm(const char *str, int slen)
 	 */
 	if (len > 1)
 	{
-		qsort((void *) GETARR(trg), len, sizeof(trgm), comp_trgm);
+		qsort(GETARR(trg), len, sizeof(trgm), comp_trgm);
 		len = qunique(GETARR(trg), len, sizeof(trgm), comp_trgm);
 	}
 
diff --git a/src/backend/access/brin/brin_minmax_multi.c b/src/backend/access/brin/brin_minmax_multi.c
index ac670fd02d..0ace6035be 100644
--- a/src/backend/access/brin/brin_minmax_multi.c
+++ b/src/backend/access/brin/brin_minmax_multi.c
@@ -543,7 +543,7 @@ range_deduplicate_values(Ranges *range)
 	 */
 	qsort_arg(&range->values[start],
 			  range->nvalues, sizeof(Datum),
-			  compare_values, (void *) &cxt);
+			  compare_values, &cxt);
 
 	n = 1;
 	for (i = 1; i < range->nvalues; i++)
@@ -1197,7 +1197,7 @@ sort_expanded_ranges(FmgrInfo *cmp, Oid colloid,
 	 * some of the points) and do merge sort.
 	 */
 	qsort_arg(eranges, neranges, sizeof(ExpandedRange),
-			  compare_expanded_ranges, (void *) &cxt);
+			  compare_expanded_ranges, &cxt);
 
 	/*
 	 * Deduplicate the ranges - simply compare each range to the preceding
@@ -1535,7 +1535,7 @@ reduce_expanded_ranges(ExpandedRange *eranges, int neranges,
 	 * sorted result.
 	 */
 	qsort_arg(values, nvalues, sizeof(Datum),
-			  compare_values, (void *) &cxt);
+			  compare_values, &cxt);
 
 	/* We have nvalues boundary values, which means nvalues/2 ranges. */
 	for (i = 0; i < (nvalues / 2); i++)
diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
index e7cc452a8a..f05128ecf5 100644
--- a/src/backend/access/gin/ginutil.c
+++ b/src/backend/access/gin/ginutil.c
@@ -560,7 +560,7 @@ ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
 		arg.collation = ginstate->supportCollation[attnum - 1];
 		arg.haveDups = false;
 		qsort_arg(keydata, *nentries, sizeof(keyEntryData),
-				  cmpEntries, (void *) &arg);
+				  cmpEntries, &arg);
 
 		if (arg.haveDups)
 		{
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index 8003583c0a..7da499c4dd 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -488,8 +488,8 @@ _bt_sort_array_elements(IndexScanDesc scan, ScanKey skey,
 	fmgr_info(cmp_proc, &cxt.flinfo);
 	cxt.collation = skey->sk_collation;
 	cxt.reverse = reverse;
-	qsort_arg((void *) elems, nelems, sizeof(Datum),
-			  _bt_compare_array_elements, (void *) &cxt);
+	qsort_arg(elems, nelems, sizeof(Datum),
+			  _bt_compare_array_elements, &cxt);
 
 	/* Now scan the sorted elements and remove duplicates */
 	return qunique_arg(elems, nelems, sizeof(Datum),
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 7acf654bf8..f8a136ba0a 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -967,7 +967,7 @@ findDependentObjects(const ObjectAddress *object,
 	 * first within ObjectAddressAndFlags.
 	 */
 	if (numDependentObjects > 1)
-		qsort((void *) dependentObjects, numDependentObjects,
+		qsort(dependentObjects, numDependentObjects,
 			  sizeof(ObjectAddressAndFlags),
 			  object_address_comparator);
 
@@ -2442,7 +2442,7 @@ eliminate_duplicate_dependencies(ObjectAddresses *addrs)
 		return;					/* nothing to do */
 
 	/* Sort the refs so that duplicates are adjacent */
-	qsort((void *) addrs->refs, addrs->numrefs, sizeof(ObjectAddress),
+	qsort(addrs->refs, addrs->numrefs, sizeof(ObjectAddress),
 		  object_address_comparator);
 
 	/* Remove dups */
@@ -2809,7 +2809,7 @@ void
 sort_object_addresses(ObjectAddresses *addrs)
 {
 	if (addrs->numrefs > 1)
-		qsort((void *) addrs->refs, addrs->numrefs,
+		qsort(addrs->refs, addrs->numrefs,
 			  sizeof(ObjectAddress),
 			  object_address_comparator);
 }
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index 1ce0ba94e3..64d326f073 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -762,7 +762,7 @@ checkSharedDependencies(Oid classId, Oid objectId,
 	 * Sort and report local and shared objects.
 	 */
 	if (numobjects > 1)
-		qsort((void *) objects, numobjects,
+		qsort(objects, numobjects,
 			  sizeof(ShDependObjectInfo), shared_dependency_comparator);
 
 	for (int i = 0; i < numobjects; i++)
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index c86e690980..65750958bb 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -1304,7 +1304,7 @@ acquire_sample_rows(Relation onerel, int elevel,
 	 * tuples are already sorted.
 	 */
 	if (numrows == targrows)
-		qsort_interruptible((void *) rows, numrows, sizeof(HeapTuple),
+		qsort_interruptible(rows, numrows, sizeof(HeapTuple),
 							compare_rows, NULL);
 
 	/*
@@ -2479,8 +2479,8 @@ compute_scalar_stats(VacAttrStatsP stats,
 		/* Sort the collected values */
 		cxt.ssup = &ssup;
 		cxt.tupnoLink = tupnoLink;
-		qsort_interruptible((void *) values, values_cnt, sizeof(ScalarItem),
-							compare_scalars, (void *) &cxt);
+		qsort_interruptible(values, values_cnt, sizeof(ScalarItem),
+							compare_scalars, &cxt);
 
 		/*
 		 * Now scan the values in order, find the most common ones, and also
@@ -2724,7 +2724,7 @@ compute_scalar_stats(VacAttrStatsP stats,
 						deltafrac;
 
 			/* Sort the MCV items into position order to speed next loop */
-			qsort_interruptible((void *) track, num_mcv, sizeof(ScalarMCVItem),
+			qsort_interruptible(track, num_mcv, sizeof(ScalarMCVItem),
 								compare_mcvs, NULL);
 
 			/*
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 6a4311cc63..eb62d285ea 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -878,7 +878,7 @@ pg_import_system_collations(PG_FUNCTION_ARGS)
 		 * created such a pg_collation entry above, and that one will win.)
 		 */
 		if (naliases > 1)
-			qsort((void *) aliases, naliases, sizeof(CollAliasData), cmpaliases);
+			qsort(aliases, naliases, sizeof(CollAliasData), cmpaliases);
 
 		/* Now add aliases, ignoring any that match pre-existing entries */
 		for (i = 0; i < naliases; i++)
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index fe6a964ee1..862bd0330b 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -266,7 +266,7 @@ TidListEval(TidScanState *tidstate)
 		/* CurrentOfExpr could never appear OR'd with something else */
 		Assert(!tidstate->tss_isCurrentOf);
 
-		qsort((void *) tidList, numTids, sizeof(ItemPointerData),
+		qsort(tidList, numTids, sizeof(ItemPointerData),
 			  itemptr_comparator);
 		numTids = qunique(tidList, numTids, sizeof(ItemPointerData),
 						  itemptr_comparator);
diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c
index 8c640ce16a..29a1858441 100644
--- a/src/backend/nodes/tidbitmap.c
+++ b/src/backend/nodes/tidbitmap.c
@@ -853,11 +853,11 @@ tbm_prepare_shared_iterate(TIDBitmap *tbm)
 		if (ptbase != NULL)
 			pg_atomic_init_u32(&ptbase->refcount, 0);
 		if (npages > 1)
-			qsort_arg((void *) (ptpages->index), npages, sizeof(int),
-					  tbm_shared_comparator, (void *) ptbase->ptentry);
+			qsort_arg(ptpages->index, npages, sizeof(int),
+					  tbm_shared_comparator, ptbase->ptentry);
 		if (nchunks > 1)
-			qsort_arg((void *) (ptchunks->index), nchunks, sizeof(int),
-					  tbm_shared_comparator, (void *) ptbase->ptentry);
+			qsort_arg(ptchunks->index, nchunks, sizeof(int),
+					  tbm_shared_comparator, ptbase->ptentry);
 	}
 
 	/*
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index ed880c496a..a69c1d1e77 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -531,7 +531,7 @@ create_list_bounds(PartitionBoundSpec **boundspecs, int nparts,
 	Assert(j == ndatums);
 
 	qsort_arg(all_values, ndatums, sizeof(PartitionListValue),
-			  qsort_partition_list_value_cmp, (void *) key);
+			  qsort_partition_list_value_cmp, key);
 
 	boundinfo->ndatums = ndatums;
 	boundinfo->datums = (Datum **) palloc0(ndatums * sizeof(Datum *));
@@ -737,7 +737,7 @@ create_range_bounds(PartitionBoundSpec **boundspecs, int nparts,
 	qsort_arg(all_bounds, ndatums,
 			  sizeof(PartitionRangeBound *),
 			  qsort_partition_rbound_cmp,
-			  (void *) key);
+			  key);
 
 	/* Save distinct bounds from all_bounds into rbounds. */
 	rbounds = (PartitionRangeBound **)
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index bdc21bb457..572d9b4464 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -1129,7 +1129,7 @@ build_sorted_items(StatsBuildData *data, int *nitems,
 	}
 
 	/* do the sort, using the multi-sort */
-	qsort_interruptible((void *) items, nrows, sizeof(SortItem),
+	qsort_interruptible(items, nrows, sizeof(SortItem),
 						multi_sort_compare, mss);
 
 	return items;
diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c
index 2d2a87d3a6..e21e0e87e4 100644
--- a/src/backend/statistics/mcv.c
+++ b/src/backend/statistics/mcv.c
@@ -457,7 +457,7 @@ build_distinct_groups(int numrows, SortItem *items, MultiSortSupport mss,
 	Assert(j + 1 == ngroups);
 
 	/* Sort the distinct groups by frequency (in descending order). */
-	qsort_interruptible((void *) groups, ngroups, sizeof(SortItem),
+	qsort_interruptible(groups, ngroups, sizeof(SortItem),
 						compare_sort_item_count, NULL);
 
 	*ndistinct = ngroups;
@@ -528,7 +528,7 @@ build_column_frequencies(SortItem *groups, int ngroups,
 		}
 
 		/* sort the values, deduplicate */
-		qsort_interruptible((void *) result[dim], ngroups, sizeof(SortItem),
+		qsort_interruptible(result[dim], ngroups, sizeof(SortItem),
 							sort_item_compare, ssup);
 
 		/*
diff --git a/src/backend/statistics/mvdistinct.c b/src/backend/statistics/mvdistinct.c
index 13301a3157..df5cc3e13a 100644
--- a/src/backend/statistics/mvdistinct.c
+++ b/src/backend/statistics/mvdistinct.c
@@ -489,7 +489,7 @@ ndistinct_for_combination(double totalrows, StatsBuildData *data,
 	}
 
 	/* We can sort the array now ... */
-	qsort_interruptible((void *) items, numrows, sizeof(SortItem),
+	qsort_interruptible(items, numrows, sizeof(SortItem),
 						multi_sort_compare, mss);
 
 	/* ... and count the number of distinct combinations */
diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c
index c8dfed6178..cc04b87164 100644
--- a/src/backend/tsearch/spell.c
+++ b/src/backend/tsearch/spell.c
@@ -1305,7 +1305,7 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
 	tsearch_readline_end(&trst);
 
 	if (Conf->nCompoundAffixFlag > 1)
-		qsort((void *) Conf->CompoundAffixFlags, Conf->nCompoundAffixFlag,
+		qsort(Conf->CompoundAffixFlags, Conf->nCompoundAffixFlag,
 			  sizeof(CompoundAffixFlag), cmpcmdflag);
 
 	if (!tsearch_readline_begin(&trst, filename))
@@ -1789,7 +1789,7 @@ NISortDictionary(IspellDict *Conf)
 	else
 	{
 		/* Count the number of different flags used in the dictionary */
-		qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *),
+		qsort(Conf->Spell, Conf->nspell, sizeof(SPELL *),
 			  cmpspellaffix);
 
 		naffix = 0;
@@ -1827,7 +1827,7 @@ NISortDictionary(IspellDict *Conf)
 	}
 
 	/* Start build a prefix tree */
-	qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspell);
+	qsort(Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspell);
 	Conf->Dictionary = mkSPNode(Conf, 0, Conf->nspell, 0);
 }
 
@@ -2001,7 +2001,7 @@ NISortAffixes(IspellDict *Conf)
 
 	/* Store compound affixes in the Conf->CompoundAffix array */
 	if (Conf->naffixes > 1)
-		qsort((void *) Conf->Affix, Conf->naffixes, sizeof(AFFIX), cmpaffix);
+		qsort(Conf->Affix, Conf->naffixes, sizeof(AFFIX), cmpaffix);
 	Conf->CompoundAffix = ptr = (CMPDAffix *) palloc(sizeof(CMPDAffix) * Conf->naffixes);
 	ptr->affix = NULL;
 
diff --git a/src/backend/tsearch/to_tsany.c b/src/backend/tsearch/to_tsany.c
index f9a87e43ab..3b6d41f9e8 100644
--- a/src/backend/tsearch/to_tsany.c
+++ b/src/backend/tsearch/to_tsany.c
@@ -97,7 +97,7 @@ uniqueWORD(ParsedWord *a, int32 l)
 	/*
 	 * Sort words with its positions
 	 */
-	qsort((void *) a, l, sizeof(ParsedWord), compareWORD);
+	qsort(a, l, sizeof(ParsedWord), compareWORD);
 
 	/*
 	 * Initialize first word and its first position
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
index ca4563290f..f0cd2866ff 100644
--- a/src/backend/utils/adt/tsgistidx.c
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -704,7 +704,7 @@ gtsvector_picksplit(PG_FUNCTION_ARGS)
 		size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]), siglen);
 		costvector[j - 1].cost = abs(size_alpha - size_beta);
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	for (k = 0; k < maxoff; k++)
 	{
diff --git a/src/backend/utils/adt/tsquery_gist.c b/src/backend/utils/adt/tsquery_gist.c
index b7941ffaca..7c99348d44 100644
--- a/src/backend/utils/adt/tsquery_gist.c
+++ b/src/backend/utils/adt/tsquery_gist.c
@@ -222,7 +222,7 @@ gtsquery_picksplit(PG_FUNCTION_ARGS)
 		size_beta = hemdist(GETENTRY(entryvec, seed_2), GETENTRY(entryvec, j));
 		costvector[j - 1].cost = abs(size_alpha - size_beta);
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	for (k = 0; k < maxoff; k++)
 	{
diff --git a/src/backend/utils/adt/tsquery_util.c b/src/backend/utils/adt/tsquery_util.c
index f266b9f067..7b6970a6f8 100644
--- a/src/backend/utils/adt/tsquery_util.c
+++ b/src/backend/utils/adt/tsquery_util.c
@@ -173,7 +173,7 @@ QTNSort(QTNode *in)
 	for (i = 0; i < in->nchild; i++)
 		QTNSort(in->child[i]);
 	if (in->nchild > 1 && in->valnode->qoperator.oper != OP_PHRASE)
-		qsort((void *) in->child, in->nchild, sizeof(QTNode *), cmpQTN);
+		qsort(in->child, in->nchild, sizeof(QTNode *), cmpQTN);
 }
 
 /*
diff --git a/src/backend/utils/adt/tsrank.c b/src/backend/utils/adt/tsrank.c
index 1ae555f7f7..e5b850ea8e 100644
--- a/src/backend/utils/adt/tsrank.c
+++ b/src/backend/utils/adt/tsrank.c
@@ -176,7 +176,7 @@ SortAndUniqItems(TSQuery q, int *size)
 	if (*size < 2)
 		return res;
 
-	qsort_arg(res, *size, sizeof(QueryOperand *), compareQueryOperand, (void *) operand);
+	qsort_arg(res, *size, sizeof(QueryOperand *), compareQueryOperand, operand);
 
 	ptr = res + 1;
 	prevptr = res;
@@ -804,7 +804,7 @@ get_docrep(TSVector txt, QueryRepresentation *qr, int *doclen)
 		/*
 		 * Sort representation in ascending order by pos and entry
 		 */
-		qsort((void *) doc, cur, sizeof(DocRepresentation), compareDocR);
+		qsort(doc, cur, sizeof(DocRepresentation), compareDocR);
 
 		/*
 		 * Join QueryItem per WordEntry and it's position
diff --git a/src/backend/utils/adt/tsvector.c b/src/backend/utils/adt/tsvector.c
index e5b05960e3..03db27194a 100644
--- a/src/backend/utils/adt/tsvector.c
+++ b/src/backend/utils/adt/tsvector.c
@@ -58,7 +58,7 @@ uniquePos(WordEntryPos *a, int l)
 	if (l <= 1)
 		return l;
 
-	qsort((void *) a, l, sizeof(WordEntryPos), compareWordEntryPos);
+	qsort(a, l, sizeof(WordEntryPos), compareWordEntryPos);
 
 	res = a;
 	ptr = a + 1;
@@ -107,8 +107,8 @@ uniqueentry(WordEntryIN *a, int l, char *buf, int *outbuflen)
 	Assert(l >= 1);
 
 	if (l > 1)
-		qsort_arg((void *) a, l, sizeof(WordEntryIN), compareentry,
-				  (void *) buf);
+		qsort_arg(a, l, sizeof(WordEntryIN), compareentry,
+				  buf);
 
 	buflen = 0;
 	res = a;
@@ -552,8 +552,8 @@ tsvectorrecv(PG_FUNCTION_ARGS)
 	SET_VARSIZE(vec, hdrlen + datalen);
 
 	if (needSort)
-		qsort_arg((void *) ARRPTR(vec), vec->size, sizeof(WordEntry),
-				  compareentry, (void *) STRPTR(vec));
+		qsort_arg(ARRPTR(vec), vec->size, sizeof(WordEntry),
+				  compareentry, STRPTR(vec));
 
 	PG_RETURN_TSVECTOR(vec);
 }
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index cb4386f871..71d3bc25fb 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -2363,7 +2363,7 @@ WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
 		}
 
 		if (ntes > 1)
-			qsort((void *) tes, ntes, sizeof(TocEntry *),
+			qsort(tes, ntes, sizeof(TocEntry *),
 				  TocEntrySizeCompare);
 
 		for (int i = 0; i < ntes; i++)
diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c
index f963b9a449..8266c117a3 100644
--- a/src/bin/pg_dump/pg_dump_sort.c
+++ b/src/bin/pg_dump/pg_dump_sort.c
@@ -186,7 +186,7 @@ void
 sortDumpableObjectsByTypeName(DumpableObject **objs, int numObjs)
 {
 	if (numObjs > 1)
-		qsort((void *) objs, numObjs, sizeof(DumpableObject *),
+		qsort(objs, numObjs, sizeof(DumpableObject *),
 			  DOTypeNameCompare);
 }
 
diff --git a/src/bin/pg_upgrade/function.c b/src/bin/pg_upgrade/function.c
index 9ad75446ee..dc8800c7cd 100644
--- a/src/bin/pg_upgrade/function.c
+++ b/src/bin/pg_upgrade/function.c
@@ -136,7 +136,7 @@ check_loadable_libraries(void)
 	 * consistent order, which is important for reproducible behavior if one
 	 * library depends on another.
 	 */
-	qsort((void *) os_info.libraries, os_info.num_libraries,
+	qsort(os_info.libraries, os_info.num_libraries,
 		  sizeof(LibraryInfo), library_name_compare);
 
 	for (libnum = 0; libnum < os_info.num_libraries; libnum++)
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 9c12ffaea9..d2d6431a28 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -1604,7 +1604,7 @@ lookupVariable(Variables *variables, char *name)
 	/* Sort if we have to */
 	if (!variables->vars_sorted)
 	{
-		qsort((void *) variables->vars, variables->nvars, sizeof(Variable),
+		qsort(variables->vars, variables->nvars, sizeof(Variable),
 			  compareVariableNames);
 		variables->vars_sorted = true;
 	}
-- 
2.39.1


From 5ccd209c0fd26625597757cecc5c7acc0f2b7b18 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:35 +0100
Subject: [PATCH 8/8] Remove useless casts to (void *) (bsearch)

---
 src/backend/commands/vacuum.c | 4 ++--
 src/backend/tsearch/spell.c   | 2 +-
 src/bin/pgbench/pgbench.c     | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 7b1a4b127e..aa79d9de4d 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -2384,8 +2384,8 @@ vac_tid_reaped(ItemPointer itemptr, void *state)
 	if (item < litem || item > ritem)
 		return false;
 
-	res = (ItemPointer) bsearch((void *) itemptr,
-								(void *) dead_items->items,
+	res = (ItemPointer) bsearch(itemptr,
+								dead_items->items,
 								dead_items->num_items,
 								sizeof(ItemPointerData),
 								vac_cmp_itemptr);
diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c
index cc04b87164..8d48cad251 100644
--- a/src/backend/tsearch/spell.c
+++ b/src/backend/tsearch/spell.c
@@ -1158,7 +1158,7 @@ getCompoundAffixFlagValue(IspellDict *Conf, char *s)
 		setCompoundAffixFlagValue(Conf, &key, sflag, 0);
 
 		found = (CompoundAffixFlag *)
-			bsearch(&key, (void *) Conf->CompoundAffixFlags,
+			bsearch(&key, Conf->CompoundAffixFlags,
 					Conf->nCompoundAffixFlag, sizeof(CompoundAffixFlag),
 					cmpcmdflag);
 		if (found != NULL)
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index d2d6431a28..508ed218e8 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -1611,8 +1611,8 @@ lookupVariable(Variables *variables, char *name)
 
 	/* Now we can search */
 	key.name = name;
-	return (Variable *) bsearch((void *) &key,
-								(void *) variables->vars,
+	return (Variable *) bsearch(&key,
+								variables->vars,
 								variables->nvars,
 								sizeof(Variable),
 								compareVariableNames);
-- 
2.39.1



Attachments:

  [text/plain] 0001-Remove-useless-casts-to-void-hash_search.patch (40.2K, ../../[email protected]/2-0001-Remove-useless-casts-to-void-hash_search.patch)
  download | inline diff:
From b4f050d23761187e05576cfbe8277b593d9c19fb Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:34 +0100
Subject: [PATCH 1/8] Remove useless casts to (void *) (hash_search)

Some of these appear to be leftovers from when hash_search took a char
* argument (changed in 5999e78fc45dcb91784b64b6e9ae43f4e4f68ca2).
---
 contrib/postgres_fdw/shippable.c              |  6 +--
 src/backend/access/gist/gistbuild.c           |  4 +-
 src/backend/access/gist/gistbuildbuffers.c    |  2 +-
 src/backend/access/transam/xlogutils.c        |  6 +--
 src/backend/catalog/storage.c                 |  4 +-
 src/backend/optimizer/util/predtest.c         |  2 +-
 src/backend/parser/parse_oper.c               |  6 +--
 src/backend/replication/logical/relation.c    |  6 +--
 .../replication/logical/reorderbuffer.c       | 16 +++---
 src/backend/replication/pgoutput/pgoutput.c   |  2 +-
 src/backend/storage/buffer/buf_table.c        |  6 +--
 src/backend/storage/buffer/bufmgr.c           |  8 +--
 src/backend/storage/buffer/localbuf.c         | 12 ++---
 src/backend/storage/lmgr/lock.c               | 50 +++++++++----------
 src/backend/storage/smgr/smgr.c               |  6 +--
 src/backend/storage/sync/sync.c               |  4 +-
 src/backend/tsearch/ts_typanalyze.c           |  4 +-
 src/backend/utils/adt/array_typanalyze.c      |  4 +-
 src/backend/utils/adt/ri_triggers.c           |  8 +--
 src/backend/utils/cache/attoptcache.c         |  6 +--
 src/backend/utils/cache/relcache.c            | 12 ++---
 src/backend/utils/cache/relfilenumbermap.c    |  6 +--
 src/backend/utils/cache/spccache.c            |  6 +--
 src/backend/utils/cache/ts_cache.c            | 12 ++---
 src/backend/utils/cache/typcache.c            |  8 +--
 src/backend/utils/time/combocid.c             |  2 +-
 src/pl/plpgsql/src/pl_comp.c                  |  6 +--
 src/pl/plpgsql/src/pl_exec.c                  |  2 +-
 28 files changed, 108 insertions(+), 108 deletions(-)

diff --git a/contrib/postgres_fdw/shippable.c b/contrib/postgres_fdw/shippable.c
index 1b47a30dbf..a500b90390 100644
--- a/contrib/postgres_fdw/shippable.c
+++ b/contrib/postgres_fdw/shippable.c
@@ -77,7 +77,7 @@ InvalidateShippableCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
 	while ((entry = (ShippableCacheEntry *) hash_seq_search(&status)) != NULL)
 	{
 		if (hash_search(ShippableCacheHash,
-						(void *) &entry->key,
+						&entry->key,
 						HASH_REMOVE,
 						NULL) == NULL)
 			elog(ERROR, "hash table corrupted");
@@ -184,7 +184,7 @@ is_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo)
 	/* See if we already cached the result. */
 	entry = (ShippableCacheEntry *)
 		hash_search(ShippableCacheHash,
-					(void *) &key,
+					&key,
 					HASH_FIND,
 					NULL);
 
@@ -200,7 +200,7 @@ is_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo)
 		 */
 		entry = (ShippableCacheEntry *)
 			hash_search(ShippableCacheHash,
-						(void *) &key,
+						&key,
 						HASH_ENTER,
 						NULL);
 
diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c
index d21a308d41..7a6d93bb87 100644
--- a/src/backend/access/gist/gistbuild.c
+++ b/src/backend/access/gist/gistbuild.c
@@ -1587,7 +1587,7 @@ gistMemorizeParent(GISTBuildState *buildstate, BlockNumber child, BlockNumber pa
 	bool		found;
 
 	entry = (ParentMapEntry *) hash_search(buildstate->parentMap,
-										   (const void *) &child,
+										   &child,
 										   HASH_ENTER,
 										   &found);
 	entry->parentblkno = parent;
@@ -1625,7 +1625,7 @@ gistGetParent(GISTBuildState *buildstate, BlockNumber child)
 
 	/* Find node buffer in hash table */
 	entry = (ParentMapEntry *) hash_search(buildstate->parentMap,
-										   (const void *) &child,
+										   &child,
 										   HASH_FIND,
 										   &found);
 	if (!found)
diff --git a/src/backend/access/gist/gistbuildbuffers.c b/src/backend/access/gist/gistbuildbuffers.c
index 3399a6ae68..95cbed4337 100644
--- a/src/backend/access/gist/gistbuildbuffers.c
+++ b/src/backend/access/gist/gistbuildbuffers.c
@@ -122,7 +122,7 @@ gistGetNodeBuffer(GISTBuildBuffers *gfbb, GISTSTATE *giststate,
 
 	/* Find node buffer in hash table */
 	nodeBuffer = (GISTNodeBuffer *) hash_search(gfbb->nodeBuffersTab,
-												(const void *) &nodeBlocknum,
+												&nodeBlocknum,
 												HASH_ENTER,
 												&found);
 	if (!found)
diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c
index 87ca9dfef1..2c28956b1a 100644
--- a/src/backend/access/transam/xlogutils.c
+++ b/src/backend/access/transam/xlogutils.c
@@ -151,7 +151,7 @@ log_invalid_page(RelFileLocator locator, ForkNumber forkno, BlockNumber blkno,
 	key.forkno = forkno;
 	key.blkno = blkno;
 	hentry = (xl_invalid_page *)
-		hash_search(invalid_page_tab, (void *) &key, HASH_ENTER, &found);
+		hash_search(invalid_page_tab, &key, HASH_ENTER, &found);
 
 	if (!found)
 	{
@@ -193,7 +193,7 @@ forget_invalid_pages(RelFileLocator locator, ForkNumber forkno,
 			}
 
 			if (hash_search(invalid_page_tab,
-							(void *) &hentry->key,
+							&hentry->key,
 							HASH_REMOVE, NULL) == NULL)
 				elog(ERROR, "hash table corrupted");
 		}
@@ -226,7 +226,7 @@ forget_invalid_pages_db(Oid dbid)
 			}
 
 			if (hash_search(invalid_page_tab,
-							(void *) &hentry->key,
+							&hentry->key,
 							HASH_REMOVE, NULL) == NULL)
 				elog(ERROR, "hash table corrupted");
 		}
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index 039ada94c4..af1491aa1d 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -603,7 +603,7 @@ SerializePendingSyncs(Size maxSize, char *startAddress)
 	/* remove deleted rnodes */
 	for (delete = pendingDeletes; delete != NULL; delete = delete->next)
 		if (delete->atCommit)
-			(void) hash_search(tmphash, (void *) &delete->rlocator,
+			(void) hash_search(tmphash, &delete->rlocator,
 							   HASH_REMOVE, NULL);
 
 	hash_seq_init(&scan, tmphash);
@@ -748,7 +748,7 @@ smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
 	/* Skip syncing nodes that smgrDoPendingDeletes() will delete. */
 	for (pending = pendingDeletes; pending != NULL; pending = pending->next)
 		if (pending->atCommit)
-			(void) hash_search(pendingSyncHash, (void *) &pending->rlocator,
+			(void) hash_search(pendingSyncHash, &pending->rlocator,
 							   HASH_REMOVE, NULL);
 
 	hash_seq_init(&scan, pendingSyncHash);
diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c
index f6e12856dd..237c883874 100644
--- a/src/backend/optimizer/util/predtest.c
+++ b/src/backend/optimizer/util/predtest.c
@@ -2040,7 +2040,7 @@ lookup_proof_cache(Oid pred_op, Oid clause_op, bool refute_it)
 	key.pred_op = pred_op;
 	key.clause_op = clause_op;
 	cache_entry = (OprProofCacheEntry *) hash_search(OprProofCacheHash,
-													 (void *) &key,
+													 &key,
 													 HASH_ENTER, &cfound);
 	if (!cfound)
 	{
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
index 8801f30898..bdc8f8e26a 100644
--- a/src/backend/parser/parse_oper.c
+++ b/src/backend/parser/parse_oper.c
@@ -1017,7 +1017,7 @@ find_oper_cache_entry(OprCacheKey *key)
 
 	/* Look for an existing entry */
 	oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
-											 (void *) key,
+											 key,
 											 HASH_FIND, NULL);
 	if (oprentry == NULL)
 		return InvalidOid;
@@ -1038,7 +1038,7 @@ make_oper_cache_entry(OprCacheKey *key, Oid opr_oid)
 	Assert(OprCacheHash != NULL);
 
 	oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
-											 (void *) key,
+											 key,
 											 HASH_ENTER, NULL);
 	oprentry->opr_oid = opr_oid;
 }
@@ -1060,7 +1060,7 @@ InvalidateOprCacheCallBack(Datum arg, int cacheid, uint32 hashvalue)
 	while ((hentry = (OprCacheEntry *) hash_seq_search(&status)) != NULL)
 	{
 		if (hash_search(OprCacheHash,
-						(void *) &hentry->key,
+						&hentry->key,
 						HASH_REMOVE, NULL) == NULL)
 			elog(ERROR, "hash table corrupted");
 	}
diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c
index ca88ae171c..9f139c64db 100644
--- a/src/backend/replication/logical/relation.c
+++ b/src/backend/replication/logical/relation.c
@@ -167,7 +167,7 @@ logicalrep_relmap_update(LogicalRepRelation *remoterel)
 	/*
 	 * HASH_ENTER returns the existing entry if present or creates a new one.
 	 */
-	entry = hash_search(LogicalRepRelMap, (void *) &remoterel->remoteid,
+	entry = hash_search(LogicalRepRelMap, &remoterel->remoteid,
 						HASH_ENTER, &found);
 
 	if (found)
@@ -326,7 +326,7 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode)
 		logicalrep_relmap_init();
 
 	/* Search for existing entry. */
-	entry = hash_search(LogicalRepRelMap, (void *) &remoteid,
+	entry = hash_search(LogicalRepRelMap, &remoteid,
 						HASH_FIND, &found);
 
 	if (!found)
@@ -598,7 +598,7 @@ logicalrep_partition_open(LogicalRepRelMapEntry *root,
 
 	/* Search for existing entry. */
 	part_entry = (LogicalRepPartMapEntry *) hash_search(LogicalRepPartMap,
-														(void *) &partOid,
+														&partOid,
 														HASH_ENTER, &found);
 
 	entry = &part_entry->relmapentry;
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index efe057b4de..02319d5c2f 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -657,7 +657,7 @@ ReorderBufferTXNByXid(ReorderBuffer *rb, TransactionId xid, bool create,
 	/* search the lookup table */
 	ent = (ReorderBufferTXNByIdEnt *)
 		hash_search(rb->by_txn,
-					(void *) &xid,
+					&xid,
 					create ? HASH_ENTER : HASH_FIND,
 					&found);
 	if (found)
@@ -1582,7 +1582,7 @@ ReorderBufferCleanupTXN(ReorderBuffer *rb, ReorderBufferTXN *txn)
 
 	/* now remove reference from buffer */
 	hash_search(rb->by_txn,
-				(void *) &txn->xid,
+				&txn->xid,
 				HASH_REMOVE,
 				&found);
 	Assert(found);
@@ -1763,7 +1763,7 @@ ReorderBufferBuildTupleCidHash(ReorderBuffer *rb, ReorderBufferTXN *txn)
 
 		ent = (ReorderBufferTupleCidEnt *)
 			hash_search(txn->tuplecid_hash,
-						(void *) &key,
+						&key,
 						HASH_ENTER,
 						&found);
 		if (!found)
@@ -4654,7 +4654,7 @@ ReorderBufferToastAppendChunk(ReorderBuffer *rb, ReorderBufferTXN *txn,
 
 	ent = (ReorderBufferToastEnt *)
 		hash_search(txn->toast_hash,
-					(void *) &chunk_id,
+					&chunk_id,
 					HASH_ENTER,
 					&found);
 
@@ -4811,7 +4811,7 @@ ReorderBufferToastReplace(ReorderBuffer *rb, ReorderBufferTXN *txn,
 		 */
 		ent = (ReorderBufferToastEnt *)
 			hash_search(txn->toast_hash,
-						(void *) &toast_pointer.va_valueid,
+						&toast_pointer.va_valueid,
 						HASH_FIND,
 						NULL);
 		if (ent == NULL)
@@ -5054,7 +5054,7 @@ ApplyLogicalMappingFile(HTAB *tuplecid_data, Oid relid, const char *fname)
 
 		ent = (ReorderBufferTupleCidEnt *)
 			hash_search(tuplecid_data,
-						(void *) &key,
+						&key,
 						HASH_FIND,
 						NULL);
 
@@ -5068,7 +5068,7 @@ ApplyLogicalMappingFile(HTAB *tuplecid_data, Oid relid, const char *fname)
 
 		new_ent = (ReorderBufferTupleCidEnt *)
 			hash_search(tuplecid_data,
-						(void *) &key,
+						&key,
 						HASH_ENTER,
 						&found);
 
@@ -5250,7 +5250,7 @@ ResolveCminCmaxDuringDecoding(HTAB *tuplecid_data,
 restart:
 	ent = (ReorderBufferTupleCidEnt *)
 		hash_search(tuplecid_data,
-					(void *) &key,
+					&key,
 					HASH_FIND,
 					NULL);
 
diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
index 1a80d67bb9..e4938d8888 100644
--- a/src/backend/replication/pgoutput/pgoutput.c
+++ b/src/backend/replication/pgoutput/pgoutput.c
@@ -2026,7 +2026,7 @@ get_rel_sync_entry(PGOutputData *data, Relation relation)
 
 	/* Find cached relation info, creating if not found */
 	entry = (RelationSyncEntry *) hash_search(RelationSyncCache,
-											  (void *) &relid,
+											  &relid,
 											  HASH_ENTER, &found);
 	Assert(entry != NULL);
 
diff --git a/src/backend/storage/buffer/buf_table.c b/src/backend/storage/buffer/buf_table.c
index e61546a5ff..2b96639a5a 100644
--- a/src/backend/storage/buffer/buf_table.c
+++ b/src/backend/storage/buffer/buf_table.c
@@ -94,7 +94,7 @@ BufTableLookup(BufferTag *tagPtr, uint32 hashcode)
 
 	result = (BufferLookupEnt *)
 		hash_search_with_hash_value(SharedBufHash,
-									(void *) tagPtr,
+									tagPtr,
 									hashcode,
 									HASH_FIND,
 									NULL);
@@ -126,7 +126,7 @@ BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id)
 
 	result = (BufferLookupEnt *)
 		hash_search_with_hash_value(SharedBufHash,
-									(void *) tagPtr,
+									tagPtr,
 									hashcode,
 									HASH_ENTER,
 									&found);
@@ -152,7 +152,7 @@ BufTableDelete(BufferTag *tagPtr, uint32 hashcode)
 
 	result = (BufferLookupEnt *)
 		hash_search_with_hash_value(SharedBufHash,
-									(void *) tagPtr,
+									tagPtr,
 									hashcode,
 									HASH_REMOVE,
 									NULL);
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 800a4248c9..cbde861789 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -262,7 +262,7 @@ ReservePrivateRefCountEntry(void)
 
 		/* enter victim array entry into hashtable */
 		hashent = hash_search(PrivateRefCountHash,
-							  (void *) &(ReservedRefCountEntry->buffer),
+							  &(ReservedRefCountEntry->buffer),
 							  HASH_ENTER,
 							  &found);
 		Assert(!found);
@@ -337,7 +337,7 @@ GetPrivateRefCountEntry(Buffer buffer, bool do_move)
 		return NULL;
 
 	res = hash_search(PrivateRefCountHash,
-					  (void *) &buffer,
+					  &buffer,
 					  HASH_FIND,
 					  NULL);
 
@@ -369,7 +369,7 @@ GetPrivateRefCountEntry(Buffer buffer, bool do_move)
 
 		/* delete from hashtable */
 		hash_search(PrivateRefCountHash,
-					(void *) &buffer,
+					&buffer,
 					HASH_REMOVE,
 					&found);
 		Assert(found);
@@ -431,7 +431,7 @@ ForgetPrivateRefCountEntry(PrivateRefCountEntry *ref)
 		Buffer		buffer = ref->buffer;
 
 		hash_search(PrivateRefCountHash,
-					(void *) &buffer,
+					&buffer,
 					HASH_REMOVE,
 					&found);
 		Assert(found);
diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c
index 8372acc383..0229a2eca1 100644
--- a/src/backend/storage/buffer/localbuf.c
+++ b/src/backend/storage/buffer/localbuf.c
@@ -76,7 +76,7 @@ PrefetchLocalBuffer(SMgrRelation smgr, ForkNumber forkNum,
 
 	/* See if the desired buffer already exists */
 	hresult = (LocalBufferLookupEnt *)
-		hash_search(LocalBufHash, (void *) &newTag, HASH_FIND, NULL);
+		hash_search(LocalBufHash, &newTag, HASH_FIND, NULL);
 
 	if (hresult)
 	{
@@ -125,7 +125,7 @@ LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum,
 
 	/* See if the desired buffer already exists */
 	hresult = (LocalBufferLookupEnt *)
-		hash_search(LocalBufHash, (void *) &newTag, HASH_FIND, NULL);
+		hash_search(LocalBufHash, &newTag, HASH_FIND, NULL);
 
 	if (hresult)
 	{
@@ -248,7 +248,7 @@ LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum,
 	if (buf_state & BM_TAG_VALID)
 	{
 		hresult = (LocalBufferLookupEnt *)
-			hash_search(LocalBufHash, (void *) &bufHdr->tag,
+			hash_search(LocalBufHash, &bufHdr->tag,
 						HASH_REMOVE, NULL);
 		if (!hresult)			/* shouldn't happen */
 			elog(ERROR, "local buffer hash table corrupted");
@@ -259,7 +259,7 @@ LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum,
 	}
 
 	hresult = (LocalBufferLookupEnt *)
-		hash_search(LocalBufHash, (void *) &newTag, HASH_ENTER, &found);
+		hash_search(LocalBufHash, &newTag, HASH_ENTER, &found);
 	if (found)					/* shouldn't happen */
 		elog(ERROR, "local buffer hash table corrupted");
 	hresult->id = b;
@@ -351,7 +351,7 @@ DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber forkNum,
 
 			/* Remove entry from hashtable */
 			hresult = (LocalBufferLookupEnt *)
-				hash_search(LocalBufHash, (void *) &bufHdr->tag,
+				hash_search(LocalBufHash, &bufHdr->tag,
 							HASH_REMOVE, NULL);
 			if (!hresult)		/* shouldn't happen */
 				elog(ERROR, "local buffer hash table corrupted");
@@ -396,7 +396,7 @@ DropRelationAllLocalBuffers(RelFileLocator rlocator)
 					 LocalRefCount[i]);
 			/* Remove entry from hashtable */
 			hresult = (LocalBufferLookupEnt *)
-				hash_search(LocalBufHash, (void *) &bufHdr->tag,
+				hash_search(LocalBufHash, &bufHdr->tag,
 							HASH_REMOVE, NULL);
 			if (!hresult)		/* shouldn't happen */
 				elog(ERROR, "local buffer hash table corrupted");
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 49d62a0dc7..a87372f33f 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -608,7 +608,7 @@ LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode)
 	localtag.mode = lockmode;
 
 	locallock = (LOCALLOCK *) hash_search(LockMethodLocalHash,
-										  (void *) &localtag,
+										  &localtag,
 										  HASH_FIND, NULL);
 
 	return (locallock && locallock->nLocks > 0);
@@ -663,7 +663,7 @@ LockHasWaiters(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
 	localtag.mode = lockmode;
 
 	locallock = (LOCALLOCK *) hash_search(LockMethodLocalHash,
-										  (void *) &localtag,
+										  &localtag,
 										  HASH_FIND, NULL);
 
 	/*
@@ -825,7 +825,7 @@ LockAcquireExtended(const LOCKTAG *locktag,
 	localtag.mode = lockmode;
 
 	locallock = (LOCALLOCK *) hash_search(LockMethodLocalHash,
-										  (void *) &localtag,
+										  &localtag,
 										  HASH_ENTER, &found);
 
 	/*
@@ -1061,7 +1061,7 @@ LockAcquireExtended(const LOCKTAG *locktag,
 				dlist_delete(&proclock->lockLink);
 				dlist_delete(&proclock->procLink);
 				if (!hash_search_with_hash_value(LockMethodProcLockHash,
-												 (void *) &(proclock->tag),
+												 &(proclock->tag),
 												 proclock_hashcode,
 												 HASH_REMOVE,
 												 NULL))
@@ -1180,7 +1180,7 @@ SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc,
 	 * Find or create a lock with this tag.
 	 */
 	lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-												(const void *) locktag,
+												locktag,
 												hashcode,
 												HASH_ENTER_NULL,
 												&found);
@@ -1222,7 +1222,7 @@ SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc,
 	 * Find or create a proclock entry with this tag
 	 */
 	proclock = (PROCLOCK *) hash_search_with_hash_value(LockMethodProcLockHash,
-														(void *) &proclocktag,
+														&proclocktag,
 														proclock_hashcode,
 														HASH_ENTER_NULL,
 														&found);
@@ -1239,7 +1239,7 @@ SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc,
 			 */
 			Assert(dlist_is_empty(&(lock->procLocks)));
 			if (!hash_search_with_hash_value(LockMethodLockHash,
-											 (void *) &(lock->tag),
+											 &(lock->tag),
 											 hashcode,
 											 HASH_REMOVE,
 											 NULL))
@@ -1391,7 +1391,7 @@ RemoveLocalLock(LOCALLOCK *locallock)
 	}
 
 	if (!hash_search(LockMethodLocalHash,
-					 (void *) &(locallock->tag),
+					 &(locallock->tag),
 					 HASH_REMOVE, NULL))
 		elog(WARNING, "locallock table corrupted");
 
@@ -1644,7 +1644,7 @@ CleanUpLock(LOCK *lock, PROCLOCK *proclock,
 		dlist_delete(&proclock->procLink);
 		proclock_hashcode = ProcLockHashCode(&proclock->tag, hashcode);
 		if (!hash_search_with_hash_value(LockMethodProcLockHash,
-										 (void *) &(proclock->tag),
+										 &(proclock->tag),
 										 proclock_hashcode,
 										 HASH_REMOVE,
 										 NULL))
@@ -1660,7 +1660,7 @@ CleanUpLock(LOCK *lock, PROCLOCK *proclock,
 		LOCK_PRINT("CleanUpLock: deleting", lock, 0);
 		Assert(dlist_is_empty(&lock->procLocks));
 		if (!hash_search_with_hash_value(LockMethodLockHash,
-										 (void *) &(lock->tag),
+										 &(lock->tag),
 										 hashcode,
 										 HASH_REMOVE,
 										 NULL))
@@ -1998,7 +1998,7 @@ LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
 	localtag.mode = lockmode;
 
 	locallock = (LOCALLOCK *) hash_search(LockMethodLocalHash,
-										  (void *) &localtag,
+										  &localtag,
 										  HASH_FIND, NULL);
 
 	/*
@@ -2112,7 +2112,7 @@ LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
 
 		Assert(EligibleForRelationFastPath(locktag, lockmode));
 		lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-													(const void *) locktag,
+													locktag,
 													locallock->hashcode,
 													HASH_FIND,
 													NULL);
@@ -2123,7 +2123,7 @@ LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
 		proclocktag.myLock = lock;
 		proclocktag.myProc = MyProc;
 		locallock->proclock = (PROCLOCK *) hash_search(LockMethodProcLockHash,
-													   (void *) &proclocktag,
+													   &proclocktag,
 													   HASH_FIND,
 													   NULL);
 		if (!locallock->proclock)
@@ -2851,7 +2851,7 @@ FastPathGetRelationLockEntry(LOCALLOCK *locallock)
 		LWLockAcquire(partitionLock, LW_SHARED);
 
 		lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-													(void *) locktag,
+													locktag,
 													locallock->hashcode,
 													HASH_FIND,
 													NULL);
@@ -2864,7 +2864,7 @@ FastPathGetRelationLockEntry(LOCALLOCK *locallock)
 		proclock_hashcode = ProcLockHashCode(&proclocktag, locallock->hashcode);
 		proclock = (PROCLOCK *)
 			hash_search_with_hash_value(LockMethodProcLockHash,
-										(void *) &proclocktag,
+										&proclocktag,
 										proclock_hashcode,
 										HASH_FIND,
 										NULL);
@@ -3028,7 +3028,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
 	LWLockAcquire(partitionLock, LW_SHARED);
 
 	lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-												(const void *) locktag,
+												locktag,
 												hashcode,
 												HASH_FIND,
 												NULL);
@@ -3125,7 +3125,7 @@ LockRefindAndRelease(LockMethod lockMethodTable, PGPROC *proc,
 	 * Re-find the lock object (it had better be there).
 	 */
 	lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-												(void *) locktag,
+												locktag,
 												hashcode,
 												HASH_FIND,
 												NULL);
@@ -3141,7 +3141,7 @@ LockRefindAndRelease(LockMethod lockMethodTable, PGPROC *proc,
 	proclock_hashcode = ProcLockHashCode(&proclocktag, hashcode);
 
 	proclock = (PROCLOCK *) hash_search_with_hash_value(LockMethodProcLockHash,
-														(void *) &proclocktag,
+														&proclocktag,
 														proclock_hashcode,
 														HASH_FIND,
 														NULL);
@@ -3255,7 +3255,7 @@ CheckForSessionAndXactLocks(void)
 
 		/* Otherwise, find or make an entry in lockhtab */
 		hentry = (PerLockTagEntry *) hash_search(lockhtab,
-												 (void *) &locallock->tag.lock,
+												 &locallock->tag.lock,
 												 HASH_ENTER, &found);
 		if (!found)				/* initialize, if newly created */
 			hentry->sessLock = hentry->xactLock = false;
@@ -3555,8 +3555,8 @@ PostPrepare_Locks(TransactionId xid)
 			 * given lock with my own proc.
 			 */
 			if (!hash_update_hash_key(LockMethodProcLockHash,
-									  (void *) proclock,
-									  (void *) &proclocktag))
+									  proclock,
+									  &proclocktag))
 				elog(PANIC, "duplicate entry found while reassigning a prepared transaction's locks");
 
 			/* Re-link into the new proc's proclock list */
@@ -4202,7 +4202,7 @@ lock_twophase_recover(TransactionId xid, uint16 info,
 	 * Find or create a lock with this tag.
 	 */
 	lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-												(void *) locktag,
+												locktag,
 												hashcode,
 												HASH_ENTER_NULL,
 												&found);
@@ -4250,7 +4250,7 @@ lock_twophase_recover(TransactionId xid, uint16 info,
 	 * Find or create a proclock entry with this tag
 	 */
 	proclock = (PROCLOCK *) hash_search_with_hash_value(LockMethodProcLockHash,
-														(void *) &proclocktag,
+														&proclocktag,
 														proclock_hashcode,
 														HASH_ENTER_NULL,
 														&found);
@@ -4267,7 +4267,7 @@ lock_twophase_recover(TransactionId xid, uint16 info,
 			 */
 			Assert(dlist_is_empty(&lock->procLocks));
 			if (!hash_search_with_hash_value(LockMethodLockHash,
-											 (void *) &(lock->tag),
+											 &(lock->tag),
 											 hashcode,
 											 HASH_REMOVE,
 											 NULL))
@@ -4679,7 +4679,7 @@ LockWaiterCount(const LOCKTAG *locktag)
 	LWLockAcquire(partitionLock, LW_EXCLUSIVE);
 
 	lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
-												(const void *) locktag,
+												locktag,
 												hashcode,
 												HASH_FIND,
 												&found);
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c
index 80eb6311e7..b2bd749d77 100644
--- a/src/backend/storage/smgr/smgr.c
+++ b/src/backend/storage/smgr/smgr.c
@@ -165,7 +165,7 @@ smgropen(RelFileLocator rlocator, BackendId backend)
 	brlocator.locator = rlocator;
 	brlocator.backend = backend;
 	reln = (SMgrRelation) hash_search(SMgrRelationHash,
-									  (void *) &brlocator,
+									  &brlocator,
 									  HASH_ENTER, &found);
 
 	/* Initialize it if not present before */
@@ -267,7 +267,7 @@ smgrclose(SMgrRelation reln)
 		dlist_delete(&reln->node);
 
 	if (hash_search(SMgrRelationHash,
-					(void *) &(reln->smgr_rlocator),
+					&(reln->smgr_rlocator),
 					HASH_REMOVE, NULL) == NULL)
 		elog(ERROR, "SMgrRelation hashtable corrupted");
 
@@ -352,7 +352,7 @@ smgrcloserellocator(RelFileLocatorBackend rlocator)
 		return;
 
 	reln = (SMgrRelation) hash_search(SMgrRelationHash,
-									  (void *) &rlocator,
+									  &rlocator,
 									  HASH_FIND, NULL);
 	if (reln != NULL)
 		smgrclose(reln);
diff --git a/src/backend/storage/sync/sync.c b/src/backend/storage/sync/sync.c
index 7135150b16..768d1dbfc4 100644
--- a/src/backend/storage/sync/sync.c
+++ b/src/backend/storage/sync/sync.c
@@ -501,7 +501,7 @@ RememberSyncRequest(const FileTag *ftag, SyncRequestType type)
 
 		/* Cancel previously entered request */
 		entry = (PendingFsyncEntry *) hash_search(pendingOps,
-												  (void *) ftag,
+												  ftag,
 												  HASH_FIND,
 												  NULL);
 		if (entry != NULL)
@@ -557,7 +557,7 @@ RememberSyncRequest(const FileTag *ftag, SyncRequestType type)
 		Assert(type == SYNC_REQUEST);
 
 		entry = (PendingFsyncEntry *) hash_search(pendingOps,
-												  (void *) ftag,
+												  ftag,
 												  HASH_ENTER,
 												  &found);
 		/* if new entry, or was previously canceled, initialize it */
diff --git a/src/backend/tsearch/ts_typanalyze.c b/src/backend/tsearch/ts_typanalyze.c
index ae4b5d10f2..75ecd72efe 100644
--- a/src/backend/tsearch/ts_typanalyze.c
+++ b/src/backend/tsearch/ts_typanalyze.c
@@ -254,7 +254,7 @@ compute_tsvector_stats(VacAttrStats *stats,
 
 			/* Lookup current lexeme in hashtable, adding it if new */
 			item = (TrackItem *) hash_search(lexemes_tab,
-											 (const void *) &hash_key,
+											 &hash_key,
 											 HASH_ENTER, &found);
 
 			if (found)
@@ -464,7 +464,7 @@ prune_lexemes_hashtable(HTAB *lexemes_tab, int b_current)
 		{
 			char	   *lexeme = item->key.lexeme;
 
-			if (hash_search(lexemes_tab, (const void *) &item->key,
+			if (hash_search(lexemes_tab, &item->key,
 							HASH_REMOVE, NULL) == NULL)
 				elog(ERROR, "hash table corrupted");
 			pfree(lexeme);
diff --git a/src/backend/utils/adt/array_typanalyze.c b/src/backend/utils/adt/array_typanalyze.c
index 5841d7d6fc..52e160d6bb 100644
--- a/src/backend/utils/adt/array_typanalyze.c
+++ b/src/backend/utils/adt/array_typanalyze.c
@@ -362,7 +362,7 @@ compute_array_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
 			/* Lookup current element in hashtable, adding it if new */
 			elem_value = elem_values[j];
 			item = (TrackItem *) hash_search(elements_tab,
-											 (const void *) &elem_value,
+											 &elem_value,
 											 HASH_ENTER, &found);
 
 			if (found)
@@ -690,7 +690,7 @@ prune_element_hashtable(HTAB *elements_tab, int b_current)
 		{
 			Datum		value = item->key;
 
-			if (hash_search(elements_tab, (const void *) &item->key,
+			if (hash_search(elements_tab, &item->key,
 							HASH_REMOVE, NULL) == NULL)
 				elog(ERROR, "hash table corrupted");
 			/* We should free memory if element is not passed by value */
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 995571ae04..375b17b9f3 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -2129,7 +2129,7 @@ ri_LoadConstraintInfo(Oid constraintOid)
 	 * Find or create a hash entry.  If we find a valid one, just return it.
 	 */
 	riinfo = (RI_ConstraintInfo *) hash_search(ri_constraint_cache,
-											   (void *) &constraintOid,
+											   &constraintOid,
 											   HASH_ENTER, &found);
 	if (!found)
 		riinfo->valid = false;
@@ -2724,7 +2724,7 @@ ri_FetchPreparedPlan(RI_QueryKey *key)
 	 * Lookup for the key
 	 */
 	entry = (RI_QueryHashEntry *) hash_search(ri_query_cache,
-											  (void *) key,
+											  key,
 											  HASH_FIND, NULL);
 	if (entry == NULL)
 		return NULL;
@@ -2777,7 +2777,7 @@ ri_HashPreparedPlan(RI_QueryKey *key, SPIPlanPtr plan)
 	 * invalid by ri_FetchPreparedPlan.
 	 */
 	entry = (RI_QueryHashEntry *) hash_search(ri_query_cache,
-											  (void *) key,
+											  key,
 											  HASH_ENTER, &found);
 	Assert(!found || entry->plan == NULL);
 	entry->plan = plan;
@@ -2927,7 +2927,7 @@ ri_HashCompareOp(Oid eq_opr, Oid typeid)
 	key.eq_opr = eq_opr;
 	key.typeid = typeid;
 	entry = (RI_CompareHashEntry *) hash_search(ri_compare_cache,
-												(void *) &key,
+												&key,
 												HASH_ENTER, &found);
 	if (!found)
 		entry->valid = false;
diff --git a/src/backend/utils/cache/attoptcache.c b/src/backend/utils/cache/attoptcache.c
index 28a99f0fc4..6769d4765b 100644
--- a/src/backend/utils/cache/attoptcache.c
+++ b/src/backend/utils/cache/attoptcache.c
@@ -63,7 +63,7 @@ InvalidateAttoptCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
 		if (attopt->opts)
 			pfree(attopt->opts);
 		if (hash_search(AttoptCacheHash,
-						(void *) &attopt->key,
+						&attopt->key,
 						HASH_REMOVE,
 						NULL) == NULL)
 			elog(ERROR, "hash table corrupted");
@@ -116,7 +116,7 @@ get_attribute_options(Oid attrelid, int attnum)
 	key.attnum = attnum;
 	attopt =
 		(AttoptCacheEntry *) hash_search(AttoptCacheHash,
-										 (void *) &key,
+										 &key,
 										 HASH_FIND,
 										 NULL);
 
@@ -163,7 +163,7 @@ get_attribute_options(Oid attrelid, int attnum)
 		 * pg_attribute, since the read could cause a cache flush.
 		 */
 		attopt = (AttoptCacheEntry *) hash_search(AttoptCacheHash,
-												  (void *) &key,
+												  &key,
 												  HASH_ENTER,
 												  NULL);
 		attopt->opts = opts;
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index d171cfcf2f..dfda0ab7d6 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -210,7 +210,7 @@ static int	EOXactTupleDescArrayLen = 0;
 do { \
 	RelIdCacheEnt *hentry; bool found; \
 	hentry = (RelIdCacheEnt *) hash_search(RelationIdCache, \
-										   (void *) &((RELATION)->rd_id), \
+										   &((RELATION)->rd_id), \
 										   HASH_ENTER, &found); \
 	if (found) \
 	{ \
@@ -232,7 +232,7 @@ do { \
 do { \
 	RelIdCacheEnt *hentry; \
 	hentry = (RelIdCacheEnt *) hash_search(RelationIdCache, \
-										   (void *) &(ID), \
+										   &(ID), \
 										   HASH_FIND, NULL); \
 	if (hentry) \
 		RELATION = hentry->reldesc; \
@@ -244,7 +244,7 @@ do { \
 do { \
 	RelIdCacheEnt *hentry; \
 	hentry = (RelIdCacheEnt *) hash_search(RelationIdCache, \
-										   (void *) &((RELATION)->rd_id), \
+										   &((RELATION)->rd_id), \
 										   HASH_REMOVE, NULL); \
 	if (hentry == NULL) \
 		elog(WARNING, "failed to delete relcache entry for OID %u", \
@@ -1663,7 +1663,7 @@ LookupOpclassInfo(Oid operatorClassOid,
 	}
 
 	opcentry = (OpClassCacheEnt *) hash_search(OpClassCache,
-											   (void *) &operatorClassOid,
+											   &operatorClassOid,
 											   HASH_ENTER, &found);
 
 	if (!found)
@@ -3210,7 +3210,7 @@ AtEOXact_RelationCache(bool isCommit)
 		for (i = 0; i < eoxact_list_len; i++)
 		{
 			idhentry = (RelIdCacheEnt *) hash_search(RelationIdCache,
-													 (void *) &eoxact_list[i],
+													 &eoxact_list[i],
 													 HASH_FIND,
 													 NULL);
 			if (idhentry != NULL)
@@ -3359,7 +3359,7 @@ AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid,
 		for (i = 0; i < eoxact_list_len; i++)
 		{
 			idhentry = (RelIdCacheEnt *) hash_search(RelationIdCache,
-													 (void *) &eoxact_list[i],
+													 &eoxact_list[i],
 													 HASH_FIND,
 													 NULL);
 			if (idhentry != NULL)
diff --git a/src/backend/utils/cache/relfilenumbermap.c b/src/backend/utils/cache/relfilenumbermap.c
index 57c3254795..220f33d43f 100644
--- a/src/backend/utils/cache/relfilenumbermap.c
+++ b/src/backend/utils/cache/relfilenumbermap.c
@@ -72,7 +72,7 @@ RelfilenumberMapInvalidateCallback(Datum arg, Oid relid)
 			entry->relid == relid)	/* individual flushed relation */
 		{
 			if (hash_search(RelfilenumberMapHash,
-							(void *) &entry->key,
+							&entry->key,
 							HASH_REMOVE,
 							NULL) == NULL)
 				elog(ERROR, "hash table corrupted");
@@ -164,7 +164,7 @@ RelidByRelfilenumber(Oid reltablespace, RelFileNumber relfilenumber)
 	 * since querying invalid values isn't supposed to be a frequent thing,
 	 * but it's basically free.
 	 */
-	entry = hash_search(RelfilenumberMapHash, (void *) &key, HASH_FIND, &found);
+	entry = hash_search(RelfilenumberMapHash, &key, HASH_FIND, &found);
 
 	if (found)
 		return entry->relid;
@@ -235,7 +235,7 @@ RelidByRelfilenumber(Oid reltablespace, RelFileNumber relfilenumber)
 	 * caused cache invalidations to be executed which would have deleted a
 	 * new entry if we had entered it above.
 	 */
-	entry = hash_search(RelfilenumberMapHash, (void *) &key, HASH_ENTER, &found);
+	entry = hash_search(RelfilenumberMapHash, &key, HASH_ENTER, &found);
 	if (found)
 		elog(ERROR, "corrupted hashtable");
 	entry->relid = relid;
diff --git a/src/backend/utils/cache/spccache.c b/src/backend/utils/cache/spccache.c
index aabe6ba64b..136fd737d3 100644
--- a/src/backend/utils/cache/spccache.c
+++ b/src/backend/utils/cache/spccache.c
@@ -63,7 +63,7 @@ InvalidateTableSpaceCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
 		if (spc->opts)
 			pfree(spc->opts);
 		if (hash_search(TableSpaceCacheHash,
-						(void *) &spc->oid,
+						&spc->oid,
 						HASH_REMOVE,
 						NULL) == NULL)
 			elog(ERROR, "hash table corrupted");
@@ -121,7 +121,7 @@ get_tablespace(Oid spcid)
 	if (!TableSpaceCacheHash)
 		InitializeTableSpaceCache();
 	spc = (TableSpaceCacheEntry *) hash_search(TableSpaceCacheHash,
-											   (void *) &spcid,
+											   &spcid,
 											   HASH_FIND,
 											   NULL);
 	if (spc)
@@ -163,7 +163,7 @@ get_tablespace(Oid spcid)
 	 * flush.
 	 */
 	spc = (TableSpaceCacheEntry *) hash_search(TableSpaceCacheHash,
-											   (void *) &spcid,
+											   &spcid,
 											   HASH_ENTER,
 											   NULL);
 	spc->opts = opts;
diff --git a/src/backend/utils/cache/ts_cache.c b/src/backend/utils/cache/ts_cache.c
index 519fa9fa73..3f256f9bf9 100644
--- a/src/backend/utils/cache/ts_cache.c
+++ b/src/backend/utils/cache/ts_cache.c
@@ -139,7 +139,7 @@ lookup_ts_parser_cache(Oid prsId)
 
 	/* Try to look up an existing entry */
 	entry = (TSParserCacheEntry *) hash_search(TSParserCacheHash,
-											   (void *) &prsId,
+											   &prsId,
 											   HASH_FIND, NULL);
 	if (entry == NULL || !entry->isvalid)
 	{
@@ -173,7 +173,7 @@ lookup_ts_parser_cache(Oid prsId)
 			/* Now make the cache entry */
 			entry = (TSParserCacheEntry *)
 				hash_search(TSParserCacheHash,
-							(void *) &prsId,
+							&prsId,
 							HASH_ENTER, &found);
 			Assert(!found);		/* it wasn't there a moment ago */
 		}
@@ -238,7 +238,7 @@ lookup_ts_dictionary_cache(Oid dictId)
 
 	/* Try to look up an existing entry */
 	entry = (TSDictionaryCacheEntry *) hash_search(TSDictionaryCacheHash,
-												   (void *) &dictId,
+												   &dictId,
 												   HASH_FIND, NULL);
 	if (entry == NULL || !entry->isvalid)
 	{
@@ -288,7 +288,7 @@ lookup_ts_dictionary_cache(Oid dictId)
 			/* Now make the cache entry */
 			entry = (TSDictionaryCacheEntry *)
 				hash_search(TSDictionaryCacheHash,
-							(void *) &dictId,
+							&dictId,
 							HASH_ENTER, &found);
 			Assert(!found);		/* it wasn't there a moment ago */
 
@@ -401,7 +401,7 @@ lookup_ts_config_cache(Oid cfgId)
 
 	/* Try to look up an existing entry */
 	entry = (TSConfigCacheEntry *) hash_search(TSConfigCacheHash,
-											   (void *) &cfgId,
+											   &cfgId,
 											   HASH_FIND, NULL);
 	if (entry == NULL || !entry->isvalid)
 	{
@@ -441,7 +441,7 @@ lookup_ts_config_cache(Oid cfgId)
 			/* Now make the cache entry */
 			entry = (TSConfigCacheEntry *)
 				hash_search(TSConfigCacheHash,
-							(void *) &cfgId,
+							&cfgId,
 							HASH_ENTER, &found);
 			Assert(!found);		/* it wasn't there a moment ago */
 		}
diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c
index 4a3e0fdb7f..ed6360ce2b 100644
--- a/src/backend/utils/cache/typcache.c
+++ b/src/backend/utils/cache/typcache.c
@@ -364,7 +364,7 @@ lookup_type_cache(Oid type_id, int flags)
 
 	/* Try to look up an existing entry */
 	typentry = (TypeCacheEntry *) hash_search(TypeCacheHash,
-											  (void *) &type_id,
+											  &type_id,
 											  HASH_FIND, NULL);
 	if (typentry == NULL)
 	{
@@ -392,7 +392,7 @@ lookup_type_cache(Oid type_id, int flags)
 
 		/* Now make the typcache entry */
 		typentry = (TypeCacheEntry *) hash_search(TypeCacheHash,
-												  (void *) &type_id,
+												  &type_id,
 												  HASH_ENTER, &found);
 		Assert(!found);			/* it wasn't there a moment ago */
 
@@ -1974,7 +1974,7 @@ assign_record_type_typmod(TupleDesc tupDesc)
 	 * the allocations succeed before we create the new entry.
 	 */
 	recentry = (RecordCacheEntry *) hash_search(RecordCacheHash,
-												(void *) &tupDesc,
+												&tupDesc,
 												HASH_FIND, &found);
 	if (found && recentry->tupdesc != NULL)
 	{
@@ -2012,7 +2012,7 @@ assign_record_type_typmod(TupleDesc tupDesc)
 
 	/* Fully initialized; create the hash table entry */
 	recentry = (RecordCacheEntry *) hash_search(RecordCacheHash,
-												(void *) &tupDesc,
+												&tupDesc,
 												HASH_ENTER, NULL);
 	recentry->tupdesc = entDesc;
 
diff --git a/src/backend/utils/time/combocid.c b/src/backend/utils/time/combocid.c
index c7124d284f..0e94bc93f7 100644
--- a/src/backend/utils/time/combocid.c
+++ b/src/backend/utils/time/combocid.c
@@ -253,7 +253,7 @@ GetComboCommandId(CommandId cmin, CommandId cmax)
 	key.cmin = cmin;
 	key.cmax = cmax;
 	entry = (ComboCidEntry) hash_search(comboHash,
-										(void *) &key,
+										&key,
 										HASH_ENTER,
 										&found);
 
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 8ce4186240..7db912fd18 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -2627,7 +2627,7 @@ plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
 	plpgsql_HashEnt *hentry;
 
 	hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
-											 (void *) func_key,
+											 func_key,
 											 HASH_FIND,
 											 NULL);
 	if (hentry)
@@ -2644,7 +2644,7 @@ plpgsql_HashTableInsert(PLpgSQL_function *function,
 	bool		found;
 
 	hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
-											 (void *) func_key,
+											 func_key,
 											 HASH_ENTER,
 											 &found);
 	if (found)
@@ -2665,7 +2665,7 @@ plpgsql_HashTableDelete(PLpgSQL_function *function)
 		return;
 
 	hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
-											 (void *) function->fn_hashkey,
+											 function->fn_hashkey,
 											 HASH_REMOVE,
 											 NULL);
 	if (hentry == NULL)
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 37da624388..70a002a0f6 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -7775,7 +7775,7 @@ get_cast_hashentry(PLpgSQL_execstate *estate,
 	cast_key.srctypmod = srctypmod;
 	cast_key.dsttypmod = dsttypmod;
 	cast_entry = (plpgsql_CastHashEntry *) hash_search(estate->cast_hash,
-													   (void *) &cast_key,
+													   &cast_key,
 													   HASH_ENTER, &found);
 	if (!found)					/* initialize if new entry */
 		cast_entry->cast_cexpr = NULL;
-- 
2.39.1



  [text/plain] 0002-Remove-useless-casts-to-void-repalloc.patch (7.0K, ../../[email protected]/3-0002-Remove-useless-casts-to-void-repalloc.patch)
  download | inline diff:
From 597d41490d8eda8e3d9361ae39788813828712fc Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:35 +0100
Subject: [PATCH 2/8] Remove useless casts to (void *) (repalloc)

---
 contrib/ltree/ltxtquery_io.c            | 2 +-
 src/backend/access/gist/gistutil.c      | 2 +-
 src/backend/tsearch/spell.c             | 4 ++--
 src/backend/tsearch/ts_parse.c          | 6 +++---
 src/backend/tsearch/ts_utils.c          | 2 +-
 src/backend/utils/adt/tsgistidx.c       | 2 +-
 src/backend/utils/adt/tsquery.c         | 2 +-
 src/backend/utils/adt/tsquery_cleanup.c | 2 +-
 src/backend/utils/adt/tsvector.c        | 4 ++--
 9 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/contrib/ltree/ltxtquery_io.c b/contrib/ltree/ltxtquery_io.c
index d9910e6c99..82d617f1ae 100644
--- a/contrib/ltree/ltxtquery_io.c
+++ b/contrib/ltree/ltxtquery_io.c
@@ -195,7 +195,7 @@ pushval_asis(QPRS_STATE *state, int type, char *strval, int lenval, uint16 flag)
 		int32		tmp = state->curop - state->op;
 
 		state->lenop *= 2;
-		state->op = (char *) repalloc((void *) state->op, state->lenop);
+		state->op = (char *) repalloc(state->op, state->lenop);
 		state->curop = state->op + tmp;
 	}
 	memcpy((void *) state->curop, (void *) strval, lenval);
diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c
index 56451fede1..b4d843a0ff 100644
--- a/src/backend/access/gist/gistutil.c
+++ b/src/backend/access/gist/gistutil.c
@@ -113,7 +113,7 @@ gistextractpage(Page page, int *len /* out */ )
 IndexTuple *
 gistjoinvector(IndexTuple *itvec, int *len, IndexTuple *additvec, int addlen)
 {
-	itvec = (IndexTuple *) repalloc((void *) itvec, sizeof(IndexTuple) * ((*len) + addlen));
+	itvec = (IndexTuple *) repalloc(itvec, sizeof(IndexTuple) * ((*len) + addlen));
 	memmove(&itvec[*len], additvec, sizeof(IndexTuple) * addlen);
 	*len += addlen;
 	return itvec;
diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c
index 83838ab438..c8dfed6178 100644
--- a/src/backend/tsearch/spell.c
+++ b/src/backend/tsearch/spell.c
@@ -695,7 +695,7 @@ NIAddAffix(IspellDict *Conf, const char *flag, char flagflags, const char *mask,
 		if (Conf->maffixes)
 		{
 			Conf->maffixes *= 2;
-			Conf->Affix = (AFFIX *) repalloc((void *) Conf->Affix, Conf->maffixes * sizeof(AFFIX));
+			Conf->Affix = (AFFIX *) repalloc(Conf->Affix, Conf->maffixes * sizeof(AFFIX));
 		}
 		else
 		{
@@ -1116,7 +1116,7 @@ addCompoundAffixFlagValue(IspellDict *Conf, char *s, uint32 val)
 		{
 			Conf->mCompoundAffixFlag *= 2;
 			Conf->CompoundAffixFlags = (CompoundAffixFlag *)
-				repalloc((void *) Conf->CompoundAffixFlags,
+				repalloc(Conf->CompoundAffixFlags,
 						 Conf->mCompoundAffixFlag * sizeof(CompoundAffixFlag));
 		}
 		else
diff --git a/src/backend/tsearch/ts_parse.c b/src/backend/tsearch/ts_parse.c
index 9b6d934958..25d9852778 100644
--- a/src/backend/tsearch/ts_parse.c
+++ b/src/backend/tsearch/ts_parse.c
@@ -410,7 +410,7 @@ parsetext(Oid cfgId, ParsedText *prs, char *buf, int buflen)
 				if (prs->curwords == prs->lenwords)
 				{
 					prs->lenwords *= 2;
-					prs->words = (ParsedWord *) repalloc((void *) prs->words, prs->lenwords * sizeof(ParsedWord));
+					prs->words = (ParsedWord *) repalloc(prs->words, prs->lenwords * sizeof(ParsedWord));
 				}
 
 				if (ptr->flags & TSL_ADDPOS)
@@ -442,7 +442,7 @@ hladdword(HeadlineParsedText *prs, char *buf, int buflen, int type)
 	if (prs->curwords >= prs->lenwords)
 	{
 		prs->lenwords *= 2;
-		prs->words = (HeadlineWordEntry *) repalloc((void *) prs->words, prs->lenwords * sizeof(HeadlineWordEntry));
+		prs->words = (HeadlineWordEntry *) repalloc(prs->words, prs->lenwords * sizeof(HeadlineWordEntry));
 	}
 	memset(&(prs->words[prs->curwords]), 0, sizeof(HeadlineWordEntry));
 	prs->words[prs->curwords].type = (uint8) type;
@@ -470,7 +470,7 @@ hlfinditem(HeadlineParsedText *prs, TSQuery query, int32 pos, char *buf, int buf
 	while (prs->curwords + query->size >= prs->lenwords)
 	{
 		prs->lenwords *= 2;
-		prs->words = (HeadlineWordEntry *) repalloc((void *) prs->words, prs->lenwords * sizeof(HeadlineWordEntry));
+		prs->words = (HeadlineWordEntry *) repalloc(prs->words, prs->lenwords * sizeof(HeadlineWordEntry));
 	}
 
 	word = &(prs->words[prs->curwords - 1]);
diff --git a/src/backend/tsearch/ts_utils.c b/src/backend/tsearch/ts_utils.c
index bb954184d3..c46867d074 100644
--- a/src/backend/tsearch/ts_utils.c
+++ b/src/backend/tsearch/ts_utils.c
@@ -109,7 +109,7 @@ readstoplist(const char *fname, StopList *s, char *(*wordop) (const char *))
 				else
 				{
 					reallen *= 2;
-					stop = (char **) repalloc((void *) stop,
+					stop = (char **) repalloc(stop,
 											  sizeof(char *) * reallen);
 				}
 			}
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
index f0411bf48f..a360b26ee2 100644
--- a/src/backend/utils/adt/tsgistidx.c
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -204,7 +204,7 @@ gtsvector_compress(PG_FUNCTION_ARGS)
 			 * val->size
 			 */
 			len = CALCGTSIZE(ARRKEY, len);
-			res = (SignTSVector *) repalloc((void *) res, len);
+			res = (SignTSVector *) repalloc(res, len);
 			SET_VARSIZE(res, len);
 		}
 
diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
index 25150c6d16..e22a2c20a0 100644
--- a/src/backend/utils/adt/tsquery.c
+++ b/src/backend/utils/adt/tsquery.c
@@ -602,7 +602,7 @@ pushValue(TSQueryParserState state, char *strval, int lenval, int16 weight, bool
 		int			used = state->curop - state->op;
 
 		state->lenop *= 2;
-		state->op = (char *) repalloc((void *) state->op, state->lenop);
+		state->op = (char *) repalloc(state->op, state->lenop);
 		state->curop = state->op + used;
 	}
 	memcpy((void *) state->curop, (void *) strval, lenval);
diff --git a/src/backend/utils/adt/tsquery_cleanup.c b/src/backend/utils/adt/tsquery_cleanup.c
index 59b3e859c3..7b9210c321 100644
--- a/src/backend/utils/adt/tsquery_cleanup.c
+++ b/src/backend/utils/adt/tsquery_cleanup.c
@@ -67,7 +67,7 @@ plainnode(PLAINTREE *state, NODE *node)
 	if (state->cur == state->len)
 	{
 		state->len *= 2;
-		state->ptr = (QueryItem *) repalloc((void *) state->ptr, state->len * sizeof(QueryItem));
+		state->ptr = (QueryItem *) repalloc(state->ptr, state->len * sizeof(QueryItem));
 	}
 	memcpy((void *) &(state->ptr[state->cur]), (void *) node->valnode, sizeof(QueryItem));
 	if (node->valnode->type == QI_VAL)
diff --git a/src/backend/utils/adt/tsvector.c b/src/backend/utils/adt/tsvector.c
index c7e20ce4ec..77673864a2 100644
--- a/src/backend/utils/adt/tsvector.c
+++ b/src/backend/utils/adt/tsvector.c
@@ -232,14 +232,14 @@ tsvectorin(PG_FUNCTION_ARGS)
 		{
 			arrlen *= 2;
 			arr = (WordEntryIN *)
-				repalloc((void *) arr, sizeof(WordEntryIN) * arrlen);
+				repalloc(arr, sizeof(WordEntryIN) * arrlen);
 		}
 		while ((cur - tmpbuf) + toklen >= buflen)
 		{
 			int			dist = cur - tmpbuf;
 
 			buflen *= 2;
-			tmpbuf = (char *) repalloc((void *) tmpbuf, buflen);
+			tmpbuf = (char *) repalloc(tmpbuf, buflen);
 			cur = tmpbuf + dist;
 		}
 		arr[len].entry.len = toklen;
-- 
2.39.1



  [text/plain] 0003-Remove-useless-casts-to-void-memcpy.patch (10.2K, ../../[email protected]/4-0003-Remove-useless-casts-to-void-memcpy.patch)
  download | inline diff:
From 5104fe8d3c2569d74ef77626684d9a38372d36f8 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:34 +0100
Subject: [PATCH 3/8] Remove useless casts to (void *) (memcpy)

---
 contrib/btree_gist/btree_bit.c          | 2 +-
 contrib/btree_gist/btree_interval.c     | 4 ++--
 contrib/btree_gist/btree_utils_num.c    | 6 +++---
 contrib/btree_gist/btree_uuid.c         | 4 ++--
 contrib/ltree/ltxtquery_io.c            | 4 ++--
 contrib/pg_trgm/trgm_gist.c             | 2 +-
 doc/src/sgml/xfunc.sgml                 | 4 ++--
 src/backend/access/gist/gistproc.c      | 4 ++--
 src/backend/storage/ipc/procarray.c     | 4 ++--
 src/backend/utils/adt/tsgistidx.c       | 2 +-
 src/backend/utils/adt/tsquery.c         | 4 ++--
 src/backend/utils/adt/tsquery_cleanup.c | 2 +-
 src/backend/utils/adt/tsvector.c        | 2 +-
 src/tutorial/funcs.c                    | 4 ++--
 14 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/contrib/btree_gist/btree_bit.c b/contrib/btree_gist/btree_bit.c
index 5b246bcde4..6790f22b4b 100644
--- a/contrib/btree_gist/btree_bit.c
+++ b/contrib/btree_gist/btree_bit.c
@@ -84,7 +84,7 @@ gbt_bit_xfrm(bytea *leaf)
 	while (sz < padded_sz)
 		((char *) out)[sz++] = 0;
 	SET_VARSIZE(out, padded_sz);
-	memcpy((void *) VARDATA(out), (void *) VARBITS(leaf), VARBITBYTES(leaf));
+	memcpy(VARDATA(out), VARBITS(leaf), VARBITBYTES(leaf));
 	return out;
 }
 
diff --git a/contrib/btree_gist/btree_interval.c b/contrib/btree_gist/btree_interval.c
index 2c98b330cd..b0afdf02bb 100644
--- a/contrib/btree_gist/btree_interval.c
+++ b/contrib/btree_gist/btree_interval.c
@@ -157,8 +157,8 @@ gbt_intv_compress(PG_FUNCTION_ARGS)
 		{
 			Interval   *key = DatumGetIntervalP(entry->key);
 
-			memcpy((void *) r, (void *) key, INTERVALSIZE);
-			memcpy((void *) (r + INTERVALSIZE), (void *) key, INTERVALSIZE);
+			memcpy(r, key, INTERVALSIZE);
+			memcpy(r + INTERVALSIZE, key, INTERVALSIZE);
 		}
 		else
 		{
diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c
index 05c154afa3..cfbecbea65 100644
--- a/contrib/btree_gist/btree_utils_num.c
+++ b/contrib/btree_gist/btree_utils_num.c
@@ -87,8 +87,8 @@ gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 
 		Assert(tinfo->indexsize >= 2 * tinfo->size);
 
-		memcpy((void *) &r[0], leaf, tinfo->size);
-		memcpy((void *) &r[tinfo->size], leaf, tinfo->size);
+		memcpy(&r[0], leaf, tinfo->size);
+		memcpy(&r[tinfo->size], leaf, tinfo->size);
 		retval = palloc(sizeof(GISTENTRY));
 		gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page,
 					  entry->offset, false);
@@ -184,7 +184,7 @@ gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_nin
 	o.lower = &((GBT_NUMKEY *) out)[0];
 	o.upper = &((GBT_NUMKEY *) out)[tinfo->size];
 
-	memcpy((void *) out, (void *) cur, 2 * tinfo->size);
+	memcpy(out, cur, 2 * tinfo->size);
 
 	for (i = 1; i < numranges; i++)
 	{
diff --git a/contrib/btree_gist/btree_uuid.c b/contrib/btree_gist/btree_uuid.c
index b81875979a..fe8c679cbe 100644
--- a/contrib/btree_gist/btree_uuid.c
+++ b/contrib/btree_gist/btree_uuid.c
@@ -110,8 +110,8 @@ gbt_uuid_compress(PG_FUNCTION_ARGS)
 
 		retval = palloc(sizeof(GISTENTRY));
 
-		memcpy((void *) r, (void *) key, UUID_LEN);
-		memcpy((void *) (r + UUID_LEN), (void *) key, UUID_LEN);
+		memcpy(r, key, UUID_LEN);
+		memcpy(r + UUID_LEN, key, UUID_LEN);
 		gistentryinit(*retval, PointerGetDatum(r),
 					  entry->rel, entry->page,
 					  entry->offset, false);
diff --git a/contrib/ltree/ltxtquery_io.c b/contrib/ltree/ltxtquery_io.c
index 82d617f1ae..0d29e15630 100644
--- a/contrib/ltree/ltxtquery_io.c
+++ b/contrib/ltree/ltxtquery_io.c
@@ -198,7 +198,7 @@ pushval_asis(QPRS_STATE *state, int type, char *strval, int lenval, uint16 flag)
 		state->op = (char *) repalloc(state->op, state->lenop);
 		state->curop = state->op + tmp;
 	}
-	memcpy((void *) state->curop, (void *) strval, lenval);
+	memcpy(state->curop, strval, lenval);
 	state->curop += lenval;
 	*(state->curop) = '\0';
 	state->curop++;
@@ -391,7 +391,7 @@ queryin(char *buf, struct Node *escontext)
 	}
 
 	/* set user-friendly operand view */
-	memcpy((void *) GETOPERAND(query), (void *) state.op, state.sumlen);
+	memcpy(GETOPERAND(query), state.op, state.sumlen);
 	pfree(state.op);
 
 	/* set left operand's position for every operator */
diff --git a/contrib/pg_trgm/trgm_gist.c b/contrib/pg_trgm/trgm_gist.c
index ef5d8cca78..68ebf1767b 100644
--- a/contrib/pg_trgm/trgm_gist.c
+++ b/contrib/pg_trgm/trgm_gist.c
@@ -755,7 +755,7 @@ fillcache(CACHESIGN *item, TRGM *key, BITVECP sign, int siglen)
 	else if (ISALLTRUE(key))
 		item->allistrue = true;
 	else
-		memcpy((void *) item->sign, (void *) GETSIGN(key), siglen);
+		memcpy(item->sign, GETSIGN(key), siglen);
 }
 
 #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index 52e5aa17bf..e2a5496c34 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -2456,8 +2456,8 @@ <title>Version 1 Calling Conventions</title>
      * VARDATA is a pointer to the data region of the new struct.  The source
      * could be a short datum, so retrieve its data through VARDATA_ANY.
      */
-    memcpy((void *) VARDATA(new_t), /* destination */
-           (void *) VARDATA_ANY(t), /* source */
+    memcpy(VARDATA(new_t),          /* destination */
+           VARDATA_ANY(t),          /* source */
            VARSIZE_ANY_EXHDR(t));   /* how many bytes */
     PG_RETURN_TEXT_P(new_t);
 }
diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c
index eb9178d456..4881034069 100644
--- a/src/backend/access/gist/gistproc.c
+++ b/src/backend/access/gist/gistproc.c
@@ -173,7 +173,7 @@ gist_box_union(PG_FUNCTION_ARGS)
 	numranges = entryvec->n;
 	pageunion = (BOX *) palloc(sizeof(BOX));
 	cur = DatumGetBoxP(entryvec->vector[0].key);
-	memcpy((void *) pageunion, (void *) cur, sizeof(BOX));
+	memcpy(pageunion, cur, sizeof(BOX));
 
 	for (i = 1; i < numranges; i++)
 	{
@@ -1043,7 +1043,7 @@ gist_poly_compress(PG_FUNCTION_ARGS)
 		BOX		   *r;
 
 		r = (BOX *) palloc(sizeof(BOX));
-		memcpy((void *) r, (void *) &(in->boundbox), sizeof(BOX));
+		memcpy(r, &(in->boundbox), sizeof(BOX));
 
 		retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
 		gistentryinit(*retval, PointerGetDatum(r),
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 4340bf9641..a7071b2fce 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -2394,7 +2394,7 @@ GetSnapshotData(Snapshot snapshot)
 						pg_read_barrier();	/* pairs with GetNewTransactionId */
 
 						memcpy(snapshot->subxip + subcount,
-							   (void *) proc->subxids.xids,
+							   proc->subxids.xids,
 							   nsubxids * sizeof(TransactionId));
 						subcount += nsubxids;
 					}
@@ -2846,7 +2846,7 @@ GetRunningTransactionData(void)
 				/* barrier not really required, as XidGenLock is held, but ... */
 				pg_read_barrier();	/* pairs with GetNewTransactionId */
 
-				memcpy(&xids[count], (void *) proc->subxids.xids,
+				memcpy(&xids[count], proc->subxids.xids,
 					   nsubxids * sizeof(TransactionId));
 				count += nsubxids;
 				subcount += nsubxids;
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
index a360b26ee2..e27e08d996 100644
--- a/src/backend/utils/adt/tsgistidx.c
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -577,7 +577,7 @@ fillcache(CACHESIGN *item, SignTSVector *key, int siglen)
 	else if (ISALLTRUE(key))
 		item->allistrue = true;
 	else
-		memcpy((void *) item->sign, (void *) GETSIGN(key), siglen);
+		memcpy(item->sign, GETSIGN(key), siglen);
 }
 
 #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
index e22a2c20a0..67ad876a27 100644
--- a/src/backend/utils/adt/tsquery.c
+++ b/src/backend/utils/adt/tsquery.c
@@ -605,7 +605,7 @@ pushValue(TSQueryParserState state, char *strval, int lenval, int16 weight, bool
 		state->op = (char *) repalloc(state->op, state->lenop);
 		state->curop = state->op + used;
 	}
-	memcpy((void *) state->curop, (void *) strval, lenval);
+	memcpy(state->curop, strval, lenval);
 	state->curop += lenval;
 	*(state->curop) = '\0';
 	state->curop++;
@@ -924,7 +924,7 @@ parse_tsquery(char *buf,
 	}
 
 	/* Copy all the operand strings to TSQuery */
-	memcpy((void *) GETOPERAND(query), (void *) state.op, state.sumlen);
+	memcpy(GETOPERAND(query), state.op, state.sumlen);
 	pfree(state.op);
 
 	/*
diff --git a/src/backend/utils/adt/tsquery_cleanup.c b/src/backend/utils/adt/tsquery_cleanup.c
index 7b9210c321..dc31665770 100644
--- a/src/backend/utils/adt/tsquery_cleanup.c
+++ b/src/backend/utils/adt/tsquery_cleanup.c
@@ -69,7 +69,7 @@ plainnode(PLAINTREE *state, NODE *node)
 		state->len *= 2;
 		state->ptr = (QueryItem *) repalloc(state->ptr, state->len * sizeof(QueryItem));
 	}
-	memcpy((void *) &(state->ptr[state->cur]), (void *) node->valnode, sizeof(QueryItem));
+	memcpy(&(state->ptr[state->cur]), node->valnode, sizeof(QueryItem));
 	if (node->valnode->type == QI_VAL)
 		state->cur++;
 	else if (node->valnode->qoperator.oper == OP_NOT)
diff --git a/src/backend/utils/adt/tsvector.c b/src/backend/utils/adt/tsvector.c
index 77673864a2..e5b05960e3 100644
--- a/src/backend/utils/adt/tsvector.c
+++ b/src/backend/utils/adt/tsvector.c
@@ -244,7 +244,7 @@ tsvectorin(PG_FUNCTION_ARGS)
 		}
 		arr[len].entry.len = toklen;
 		arr[len].entry.pos = cur - tmpbuf;
-		memcpy((void *) cur, (void *) token, toklen);
+		memcpy(cur, token, toklen);
 		cur += toklen;
 
 		if (poslen != 0)
diff --git a/src/tutorial/funcs.c b/src/tutorial/funcs.c
index cdd155ebbd..ceffb56835 100644
--- a/src/tutorial/funcs.c
+++ b/src/tutorial/funcs.c
@@ -78,8 +78,8 @@ copytext(PG_FUNCTION_ARGS)
 	 * VARDATA is a pointer to the data region of the new struct.  The source
 	 * could be a short datum, so retrieve its data through VARDATA_ANY.
 	 */
-	memcpy((void *) VARDATA(new_t), /* destination */
-		   (void *) VARDATA_ANY(t), /* source */
+	memcpy(VARDATA(new_t),          /* destination */
+		   VARDATA_ANY(t),          /* source */
 		   VARSIZE_ANY_EXHDR(t));	/* how many bytes */
 	PG_RETURN_TEXT_P(new_t);
 }
-- 
2.39.1



  [text/plain] 0004-Remove-useless-casts-to-void-memset.patch (5.4K, ../../[email protected]/5-0004-Remove-useless-casts-to-void-memset.patch)
  download | inline diff:
From ac0833f8a98d4561c0378fbf98345307b578bcbf Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:34 +0100
Subject: [PATCH 4/8] Remove useless casts to (void *) (memset)

---
 contrib/hstore/hstore_gist.c      | 4 ++--
 contrib/intarray/_intbig_gist.c   | 4 ++--
 contrib/ltree/_ltree_gist.c       | 4 ++--
 contrib/pg_trgm/trgm_gist.c       | 6 +++---
 src/backend/tsearch/ts_utils.c    | 3 +--
 src/backend/utils/adt/tsgistidx.c | 6 +++---
 src/bin/pg_dump/parallel.c        | 2 +-
 7 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/contrib/hstore/hstore_gist.c b/contrib/hstore/hstore_gist.c
index 5d8b806d30..d31da564fe 100644
--- a/contrib/hstore/hstore_gist.c
+++ b/contrib/hstore/hstore_gist.c
@@ -465,7 +465,7 @@ ghstore_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_l) || ISALLTRUE(_j))
 			{
 				if (!ISALLTRUE(datum_l))
-					memset((void *) union_l, 0xff, siglen);
+					memset(union_l, 0xff, siglen);
 			}
 			else
 			{
@@ -481,7 +481,7 @@ ghstore_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_r) || ISALLTRUE(_j))
 			{
 				if (!ISALLTRUE(datum_r))
-					memset((void *) union_r, 0xff, siglen);
+					memset(union_r, 0xff, siglen);
 			}
 			else
 			{
diff --git a/contrib/intarray/_intbig_gist.c b/contrib/intarray/_intbig_gist.c
index dadc18646a..f8fca44ea5 100644
--- a/contrib/intarray/_intbig_gist.c
+++ b/contrib/intarray/_intbig_gist.c
@@ -424,7 +424,7 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_l) || ISALLTRUE(_j))
 			{
 				if (!ISALLTRUE(datum_l))
-					memset((void *) union_l, 0xff, siglen);
+					memset(union_l, 0xff, siglen);
 			}
 			else
 			{
@@ -440,7 +440,7 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_r) || ISALLTRUE(_j))
 			{
 				if (!ISALLTRUE(datum_r))
-					memset((void *) union_r, 0xff, siglen);
+					memset(union_r, 0xff, siglen);
 			}
 			else
 			{
diff --git a/contrib/ltree/_ltree_gist.c b/contrib/ltree/_ltree_gist.c
index 385a10283b..4d9ee53f08 100644
--- a/contrib/ltree/_ltree_gist.c
+++ b/contrib/ltree/_ltree_gist.c
@@ -348,7 +348,7 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
 			if (LTG_ISALLTRUE(datum_l) || LTG_ISALLTRUE(_j))
 			{
 				if (!LTG_ISALLTRUE(datum_l))
-					memset((void *) union_l, 0xff, siglen);
+					memset(union_l, 0xff, siglen);
 			}
 			else
 			{
@@ -364,7 +364,7 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
 			if (LTG_ISALLTRUE(datum_r) || LTG_ISALLTRUE(_j))
 			{
 				if (!LTG_ISALLTRUE(datum_r))
-					memset((void *) union_r, 0xff, siglen);
+					memset(union_r, 0xff, siglen);
 			}
 			else
 			{
diff --git a/contrib/pg_trgm/trgm_gist.c b/contrib/pg_trgm/trgm_gist.c
index 68ebf1767b..ed2b010b93 100644
--- a/contrib/pg_trgm/trgm_gist.c
+++ b/contrib/pg_trgm/trgm_gist.c
@@ -102,7 +102,7 @@ makesign(BITVECP sign, TRGM *a, int siglen)
 	trgm	   *ptr = GETARR(a);
 	int32		tmp = 0;
 
-	MemSet((void *) sign, 0, siglen);
+	MemSet(sign, 0, siglen);
 	SETBIT(sign, SIGLENBIT(siglen));	/* set last unused bit */
 	for (k = 0; k < len; k++)
 	{
@@ -921,7 +921,7 @@ gtrgm_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_l) || cache[j].allistrue)
 			{
 				if (!ISALLTRUE(datum_l))
-					memset((void *) GETSIGN(datum_l), 0xff, siglen);
+					memset(GETSIGN(datum_l), 0xff, siglen);
 			}
 			else
 			{
@@ -937,7 +937,7 @@ gtrgm_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_r) || cache[j].allistrue)
 			{
 				if (!ISALLTRUE(datum_r))
-					memset((void *) GETSIGN(datum_r), 0xff, siglen);
+					memset(GETSIGN(datum_r), 0xff, siglen);
 			}
 			else
 			{
diff --git a/src/backend/tsearch/ts_utils.c b/src/backend/tsearch/ts_utils.c
index c46867d074..7c4c2a9112 100644
--- a/src/backend/tsearch/ts_utils.c
+++ b/src/backend/tsearch/ts_utils.c
@@ -109,8 +109,7 @@ readstoplist(const char *fname, StopList *s, char *(*wordop) (const char *))
 				else
 				{
 					reallen *= 2;
-					stop = (char **) repalloc(stop,
-											  sizeof(char *) * reallen);
+					stop = (char **) repalloc(stop, sizeof(char *) * reallen);
 				}
 			}
 
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
index e27e08d996..ca4563290f 100644
--- a/src/backend/utils/adt/tsgistidx.c
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -143,7 +143,7 @@ makesign(BITVECP sign, SignTSVector *a, int siglen)
 				len = ARRNELEM(a);
 	int32	   *ptr = GETARR(a);
 
-	MemSet((void *) sign, 0, siglen);
+	MemSet(sign, 0, siglen);
 	for (k = 0; k < len; k++)
 		HASH(sign, ptr[k], siglen);
 }
@@ -755,7 +755,7 @@ gtsvector_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_l) || cache[j].allistrue)
 			{
 				if (!ISALLTRUE(datum_l))
-					memset((void *) GETSIGN(datum_l), 0xff, siglen);
+					memset(GETSIGN(datum_l), 0xff, siglen);
 			}
 			else
 			{
@@ -771,7 +771,7 @@ gtsvector_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_r) || cache[j].allistrue)
 			{
 				if (!ISALLTRUE(datum_r))
-					memset((void *) GETSIGN(datum_r), 0xff, siglen);
+					memset(GETSIGN(datum_r), 0xff, siglen);
 			}
 			else
 			{
diff --git a/src/bin/pg_dump/parallel.c b/src/bin/pg_dump/parallel.c
index 9bfb95557a..da0723ad38 100644
--- a/src/bin/pg_dump/parallel.c
+++ b/src/bin/pg_dump/parallel.c
@@ -1736,7 +1736,7 @@ pgpipe(int handles[2])
 		return -1;
 	}
 
-	memset((void *) &serv_addr, 0, sizeof(serv_addr));
+	memset(&serv_addr, 0, sizeof(serv_addr));
 	serv_addr.sin_family = AF_INET;
 	serv_addr.sin_port = pg_hton16(0);
 	serv_addr.sin_addr.s_addr = pg_hton32(INADDR_LOOPBACK);
-- 
2.39.1



  [text/plain] 0005-Remove-useless-casts-to-void-memmove.patch (1.1K, ../../[email protected]/6-0005-Remove-useless-casts-to-void-memmove.patch)
  download | inline diff:
From 7da5b5474a65d5a5a3fd104a624f3e9048f973dd Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:35 +0100
Subject: [PATCH 5/8] Remove useless casts to (void *) (memmove)

---
 contrib/intarray/_int_gist.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/contrib/intarray/_int_gist.c b/contrib/intarray/_int_gist.c
index 331fa25fcf..2d72e7dafb 100644
--- a/contrib/intarray/_int_gist.c
+++ b/contrib/intarray/_int_gist.c
@@ -243,7 +243,7 @@ g_int_compress(PG_FUNCTION_ARGS)
 			/*
 			 * shunt everything down to start at the right place
 			 */
-			memmove((void *) &dr[0], (void *) &dr[2 * j], 2 * (len - j) * sizeof(int32));
+			memmove(&dr[0], &dr[2 * j], 2 * (len - j) * sizeof(int32));
 		}
 
 		/*
@@ -260,7 +260,7 @@ g_int_compress(PG_FUNCTION_ARGS)
 					min = ((int64) dr[i] - (int64) dr[i - 1]);
 					cand = i;
 				}
-			memmove((void *) &dr[cand - 1], (void *) &dr[cand + 1], (len - cand - 1) * sizeof(int32));
+			memmove(&dr[cand - 1], &dr[cand + 1], (len - cand - 1) * sizeof(int32));
 			len -= 2;
 		}
 
-- 
2.39.1



  [text/plain] 0006-Remove-useless-casts-to-void-memcmp.patch (767B, ../../[email protected]/7-0006-Remove-useless-casts-to-void-memcmp.patch)
  download | inline diff:
From 122a9bc37bb9e095665e3b44095f0394983a647a Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:35 +0100
Subject: [PATCH 6/8] Remove useless casts to (void *) (memcmp)

---
 contrib/citext/citext.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/citext/citext.c b/contrib/citext/citext.c
index 976c578e1c..26af935a70 100644
--- a/contrib/citext/citext.c
+++ b/contrib/citext/citext.c
@@ -80,7 +80,7 @@ internal_citext_pattern_cmp(text *left, text *right, Oid collid)
 	llen = strlen(lcstr);
 	rlen = strlen(rcstr);
 
-	result = memcmp((void *) lcstr, (void *) rcstr, Min(llen, rlen));
+	result = memcmp(lcstr, rcstr, Min(llen, rlen));
 	if (result == 0)
 	{
 		if (llen < rlen)
-- 
2.39.1



  [text/plain] 0007-Remove-useless-casts-to-void-qsort.patch (25.8K, ../../[email protected]/8-0007-Remove-useless-casts-to-void-qsort.patch)
  download | inline diff:
From 2b7d664f2f7d475f84ead47eafde28157fcaf061 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:35 +0100
Subject: [PATCH 7/8] Remove useless casts to (void *) (qsort)

---
 contrib/btree_gist/btree_utils_num.c        |  2 +-
 contrib/btree_gist/btree_utils_var.c        |  4 ++--
 contrib/hstore/hstore_gist.c                |  2 +-
 contrib/hstore/hstore_io.c                  |  2 +-
 contrib/intarray/_int_gist.c                |  2 +-
 contrib/intarray/_int_tool.c                |  2 +-
 contrib/intarray/_intbig_gist.c             |  2 +-
 contrib/ltree/_ltree_gist.c                 |  2 +-
 contrib/ltree/ltree_gist.c                  |  2 +-
 contrib/pg_surgery/heap_surgery.c           |  2 +-
 contrib/pg_trgm/trgm_gist.c                 |  2 +-
 contrib/pg_trgm/trgm_op.c                   |  4 ++--
 src/backend/access/brin/brin_minmax_multi.c |  6 +++---
 src/backend/access/gin/ginutil.c            |  2 +-
 src/backend/access/nbtree/nbtutils.c        |  4 ++--
 src/backend/catalog/dependency.c            |  6 +++---
 src/backend/catalog/pg_shdepend.c           |  2 +-
 src/backend/commands/analyze.c              |  8 ++++----
 src/backend/commands/collationcmds.c        |  2 +-
 src/backend/executor/nodeTidscan.c          |  2 +-
 src/backend/nodes/tidbitmap.c               |  8 ++++----
 src/backend/partitioning/partbounds.c       |  4 ++--
 src/backend/statistics/extended_stats.c     |  2 +-
 src/backend/statistics/mcv.c                |  4 ++--
 src/backend/statistics/mvdistinct.c         |  2 +-
 src/backend/tsearch/spell.c                 |  8 ++++----
 src/backend/tsearch/to_tsany.c              |  2 +-
 src/backend/utils/adt/tsgistidx.c           |  2 +-
 src/backend/utils/adt/tsquery_gist.c        |  2 +-
 src/backend/utils/adt/tsquery_util.c        |  2 +-
 src/backend/utils/adt/tsrank.c              |  4 ++--
 src/backend/utils/adt/tsvector.c            | 10 +++++-----
 src/bin/pg_dump/pg_backup_archiver.c        |  2 +-
 src/bin/pg_dump/pg_dump_sort.c              |  2 +-
 src/bin/pg_upgrade/function.c               |  2 +-
 src/bin/pgbench/pgbench.c                   |  2 +-
 36 files changed, 59 insertions(+), 59 deletions(-)

diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c
index cfbecbea65..346ee837d7 100644
--- a/contrib/btree_gist/btree_utils_num.c
+++ b/contrib/btree_gist/btree_utils_num.c
@@ -360,7 +360,7 @@ gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 		arr[i].t = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
 		arr[i].i = i;
 	}
-	qsort_arg((void *) &arr[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1, sizeof(Nsrt), (qsort_arg_comparator) tinfo->f_cmp, (void *) flinfo);
+	qsort_arg(&arr[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1, sizeof(Nsrt), (qsort_arg_comparator) tinfo->f_cmp, flinfo);
 
 	/* We do simply create two parts */
 
diff --git a/contrib/btree_gist/btree_utils_var.c b/contrib/btree_gist/btree_utils_var.c
index 3ef82d0e20..0c0e952f73 100644
--- a/contrib/btree_gist/btree_utils_var.c
+++ b/contrib/btree_gist/btree_utils_var.c
@@ -502,11 +502,11 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 	varg.tinfo = tinfo;
 	varg.collation = collation;
 	varg.flinfo = flinfo;
-	qsort_arg((void *) &arr[FirstOffsetNumber],
+	qsort_arg(&arr[FirstOffsetNumber],
 			  maxoff - FirstOffsetNumber + 1,
 			  sizeof(Vsrt),
 			  gbt_vsrt_cmp,
-			  (void *) &varg);
+			  &varg);
 
 	/* We do simply create two parts */
 
diff --git a/contrib/hstore/hstore_gist.c b/contrib/hstore/hstore_gist.c
index d31da564fe..3df00493e8 100644
--- a/contrib/hstore/hstore_gist.c
+++ b/contrib/hstore/hstore_gist.c
@@ -436,7 +436,7 @@ ghstore_picksplit(PG_FUNCTION_ARGS)
 		size_beta = hemdist(datum_r, _j, siglen);
 		costvector[j - 1].cost = abs(size_alpha - size_beta);
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	union_l = GETSIGN(datum_l);
 	union_r = GETSIGN(datum_r);
diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c
index ae09cede8c..cec7df71a2 100644
--- a/contrib/hstore/hstore_io.c
+++ b/contrib/hstore/hstore_io.c
@@ -365,7 +365,7 @@ hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
 		return l;
 	}
 
-	qsort((void *) a, l, sizeof(Pairs), comparePairs);
+	qsort(a, l, sizeof(Pairs), comparePairs);
 
 	/*
 	 * We can't use qunique here because we have some clean-up code to run on
diff --git a/contrib/intarray/_int_gist.c b/contrib/intarray/_int_gist.c
index 2d72e7dafb..7a48ce624d 100644
--- a/contrib/intarray/_int_gist.c
+++ b/contrib/intarray/_int_gist.c
@@ -542,7 +542,7 @@ g_int_picksplit(PG_FUNCTION_ARGS)
 		pfree(union_d);
 		costvector[i - 1].cost = fabsf((size_alpha - size_l) - (size_beta - size_r));
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	/*
 	 * Now split up the regions between the two seeds.  An important property
diff --git a/contrib/intarray/_int_tool.c b/contrib/intarray/_int_tool.c
index 5ab6eb81e8..68f624e085 100644
--- a/contrib/intarray/_int_tool.c
+++ b/contrib/intarray/_int_tool.c
@@ -212,7 +212,7 @@ isort(int32 *a, int len)
 {
 	bool		r = false;
 
-	qsort_arg(a, len, sizeof(int32), isort_cmp, (void *) &r);
+	qsort_arg(a, len, sizeof(int32), isort_cmp, &r);
 	return r;
 }
 
diff --git a/contrib/intarray/_intbig_gist.c b/contrib/intarray/_intbig_gist.c
index f8fca44ea5..bfba5eef1d 100644
--- a/contrib/intarray/_intbig_gist.c
+++ b/contrib/intarray/_intbig_gist.c
@@ -395,7 +395,7 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 		size_beta = hemdist(datum_r, _j, siglen);
 		costvector[j - 1].cost = abs(size_alpha - size_beta);
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	union_l = GETSIGN(datum_l);
 	union_r = GETSIGN(datum_r);
diff --git a/contrib/ltree/_ltree_gist.c b/contrib/ltree/_ltree_gist.c
index 4d9ee53f08..e89a39a5b5 100644
--- a/contrib/ltree/_ltree_gist.c
+++ b/contrib/ltree/_ltree_gist.c
@@ -319,7 +319,7 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
 		size_beta = hemdist(datum_r, _j, siglen);
 		costvector[j - 1].cost = abs(size_alpha - size_beta);
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	union_l = LTG_SIGN(datum_l);
 	union_r = LTG_SIGN(datum_r);
diff --git a/contrib/ltree/ltree_gist.c b/contrib/ltree/ltree_gist.c
index 5d2db6c62b..3cba2269d8 100644
--- a/contrib/ltree/ltree_gist.c
+++ b/contrib/ltree/ltree_gist.c
@@ -328,7 +328,7 @@ ltree_picksplit(PG_FUNCTION_ARGS)
 		array[j].r = LTG_GETLNODE(lu, siglen);
 	}
 
-	qsort((void *) &array[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1,
+	qsort(&array[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1,
 		  sizeof(RIX), treekey_cmp);
 
 	lu_l = lu_r = ru_l = ru_r = NULL;
diff --git a/contrib/pg_surgery/heap_surgery.c b/contrib/pg_surgery/heap_surgery.c
index 61b184597a..88a40ab7d3 100644
--- a/contrib/pg_surgery/heap_surgery.c
+++ b/contrib/pg_surgery/heap_surgery.c
@@ -131,7 +131,7 @@ heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt)
 	 * array.
 	 */
 	if (ntids > 1)
-		qsort((void *) tids, ntids, sizeof(ItemPointerData), tidcmp);
+		qsort(tids, ntids, sizeof(ItemPointerData), tidcmp);
 
 	curr_start_ptr = next_start_ptr = 0;
 	nblocks = RelationGetNumberOfBlocks(rel);
diff --git a/contrib/pg_trgm/trgm_gist.c b/contrib/pg_trgm/trgm_gist.c
index ed2b010b93..9ef2e38560 100644
--- a/contrib/pg_trgm/trgm_gist.c
+++ b/contrib/pg_trgm/trgm_gist.c
@@ -872,7 +872,7 @@ gtrgm_picksplit(PG_FUNCTION_ARGS)
 		size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]), siglen);
 		costvector[j - 1].cost = abs(size_alpha - size_beta);
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	for (k = 0; k < maxoff; k++)
 	{
diff --git a/contrib/pg_trgm/trgm_op.c b/contrib/pg_trgm/trgm_op.c
index 2c644bc148..49d4497b4f 100644
--- a/contrib/pg_trgm/trgm_op.c
+++ b/contrib/pg_trgm/trgm_op.c
@@ -376,7 +376,7 @@ generate_trgm(char *str, int slen)
 	 */
 	if (len > 1)
 	{
-		qsort((void *) GETARR(trg), len, sizeof(trgm), comp_trgm);
+		qsort(GETARR(trg), len, sizeof(trgm), comp_trgm);
 		len = qunique(GETARR(trg), len, sizeof(trgm), comp_trgm);
 	}
 
@@ -929,7 +929,7 @@ generate_wildcard_trgm(const char *str, int slen)
 	 */
 	if (len > 1)
 	{
-		qsort((void *) GETARR(trg), len, sizeof(trgm), comp_trgm);
+		qsort(GETARR(trg), len, sizeof(trgm), comp_trgm);
 		len = qunique(GETARR(trg), len, sizeof(trgm), comp_trgm);
 	}
 
diff --git a/src/backend/access/brin/brin_minmax_multi.c b/src/backend/access/brin/brin_minmax_multi.c
index ac670fd02d..0ace6035be 100644
--- a/src/backend/access/brin/brin_minmax_multi.c
+++ b/src/backend/access/brin/brin_minmax_multi.c
@@ -543,7 +543,7 @@ range_deduplicate_values(Ranges *range)
 	 */
 	qsort_arg(&range->values[start],
 			  range->nvalues, sizeof(Datum),
-			  compare_values, (void *) &cxt);
+			  compare_values, &cxt);
 
 	n = 1;
 	for (i = 1; i < range->nvalues; i++)
@@ -1197,7 +1197,7 @@ sort_expanded_ranges(FmgrInfo *cmp, Oid colloid,
 	 * some of the points) and do merge sort.
 	 */
 	qsort_arg(eranges, neranges, sizeof(ExpandedRange),
-			  compare_expanded_ranges, (void *) &cxt);
+			  compare_expanded_ranges, &cxt);
 
 	/*
 	 * Deduplicate the ranges - simply compare each range to the preceding
@@ -1535,7 +1535,7 @@ reduce_expanded_ranges(ExpandedRange *eranges, int neranges,
 	 * sorted result.
 	 */
 	qsort_arg(values, nvalues, sizeof(Datum),
-			  compare_values, (void *) &cxt);
+			  compare_values, &cxt);
 
 	/* We have nvalues boundary values, which means nvalues/2 ranges. */
 	for (i = 0; i < (nvalues / 2); i++)
diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
index e7cc452a8a..f05128ecf5 100644
--- a/src/backend/access/gin/ginutil.c
+++ b/src/backend/access/gin/ginutil.c
@@ -560,7 +560,7 @@ ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
 		arg.collation = ginstate->supportCollation[attnum - 1];
 		arg.haveDups = false;
 		qsort_arg(keydata, *nentries, sizeof(keyEntryData),
-				  cmpEntries, (void *) &arg);
+				  cmpEntries, &arg);
 
 		if (arg.haveDups)
 		{
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index 8003583c0a..7da499c4dd 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -488,8 +488,8 @@ _bt_sort_array_elements(IndexScanDesc scan, ScanKey skey,
 	fmgr_info(cmp_proc, &cxt.flinfo);
 	cxt.collation = skey->sk_collation;
 	cxt.reverse = reverse;
-	qsort_arg((void *) elems, nelems, sizeof(Datum),
-			  _bt_compare_array_elements, (void *) &cxt);
+	qsort_arg(elems, nelems, sizeof(Datum),
+			  _bt_compare_array_elements, &cxt);
 
 	/* Now scan the sorted elements and remove duplicates */
 	return qunique_arg(elems, nelems, sizeof(Datum),
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 7acf654bf8..f8a136ba0a 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -967,7 +967,7 @@ findDependentObjects(const ObjectAddress *object,
 	 * first within ObjectAddressAndFlags.
 	 */
 	if (numDependentObjects > 1)
-		qsort((void *) dependentObjects, numDependentObjects,
+		qsort(dependentObjects, numDependentObjects,
 			  sizeof(ObjectAddressAndFlags),
 			  object_address_comparator);
 
@@ -2442,7 +2442,7 @@ eliminate_duplicate_dependencies(ObjectAddresses *addrs)
 		return;					/* nothing to do */
 
 	/* Sort the refs so that duplicates are adjacent */
-	qsort((void *) addrs->refs, addrs->numrefs, sizeof(ObjectAddress),
+	qsort(addrs->refs, addrs->numrefs, sizeof(ObjectAddress),
 		  object_address_comparator);
 
 	/* Remove dups */
@@ -2809,7 +2809,7 @@ void
 sort_object_addresses(ObjectAddresses *addrs)
 {
 	if (addrs->numrefs > 1)
-		qsort((void *) addrs->refs, addrs->numrefs,
+		qsort(addrs->refs, addrs->numrefs,
 			  sizeof(ObjectAddress),
 			  object_address_comparator);
 }
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index 1ce0ba94e3..64d326f073 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -762,7 +762,7 @@ checkSharedDependencies(Oid classId, Oid objectId,
 	 * Sort and report local and shared objects.
 	 */
 	if (numobjects > 1)
-		qsort((void *) objects, numobjects,
+		qsort(objects, numobjects,
 			  sizeof(ShDependObjectInfo), shared_dependency_comparator);
 
 	for (int i = 0; i < numobjects; i++)
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index c86e690980..65750958bb 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -1304,7 +1304,7 @@ acquire_sample_rows(Relation onerel, int elevel,
 	 * tuples are already sorted.
 	 */
 	if (numrows == targrows)
-		qsort_interruptible((void *) rows, numrows, sizeof(HeapTuple),
+		qsort_interruptible(rows, numrows, sizeof(HeapTuple),
 							compare_rows, NULL);
 
 	/*
@@ -2479,8 +2479,8 @@ compute_scalar_stats(VacAttrStatsP stats,
 		/* Sort the collected values */
 		cxt.ssup = &ssup;
 		cxt.tupnoLink = tupnoLink;
-		qsort_interruptible((void *) values, values_cnt, sizeof(ScalarItem),
-							compare_scalars, (void *) &cxt);
+		qsort_interruptible(values, values_cnt, sizeof(ScalarItem),
+							compare_scalars, &cxt);
 
 		/*
 		 * Now scan the values in order, find the most common ones, and also
@@ -2724,7 +2724,7 @@ compute_scalar_stats(VacAttrStatsP stats,
 						deltafrac;
 
 			/* Sort the MCV items into position order to speed next loop */
-			qsort_interruptible((void *) track, num_mcv, sizeof(ScalarMCVItem),
+			qsort_interruptible(track, num_mcv, sizeof(ScalarMCVItem),
 								compare_mcvs, NULL);
 
 			/*
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 6a4311cc63..eb62d285ea 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -878,7 +878,7 @@ pg_import_system_collations(PG_FUNCTION_ARGS)
 		 * created such a pg_collation entry above, and that one will win.)
 		 */
 		if (naliases > 1)
-			qsort((void *) aliases, naliases, sizeof(CollAliasData), cmpaliases);
+			qsort(aliases, naliases, sizeof(CollAliasData), cmpaliases);
 
 		/* Now add aliases, ignoring any that match pre-existing entries */
 		for (i = 0; i < naliases; i++)
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index fe6a964ee1..862bd0330b 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -266,7 +266,7 @@ TidListEval(TidScanState *tidstate)
 		/* CurrentOfExpr could never appear OR'd with something else */
 		Assert(!tidstate->tss_isCurrentOf);
 
-		qsort((void *) tidList, numTids, sizeof(ItemPointerData),
+		qsort(tidList, numTids, sizeof(ItemPointerData),
 			  itemptr_comparator);
 		numTids = qunique(tidList, numTids, sizeof(ItemPointerData),
 						  itemptr_comparator);
diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c
index 8c640ce16a..29a1858441 100644
--- a/src/backend/nodes/tidbitmap.c
+++ b/src/backend/nodes/tidbitmap.c
@@ -853,11 +853,11 @@ tbm_prepare_shared_iterate(TIDBitmap *tbm)
 		if (ptbase != NULL)
 			pg_atomic_init_u32(&ptbase->refcount, 0);
 		if (npages > 1)
-			qsort_arg((void *) (ptpages->index), npages, sizeof(int),
-					  tbm_shared_comparator, (void *) ptbase->ptentry);
+			qsort_arg(ptpages->index, npages, sizeof(int),
+					  tbm_shared_comparator, ptbase->ptentry);
 		if (nchunks > 1)
-			qsort_arg((void *) (ptchunks->index), nchunks, sizeof(int),
-					  tbm_shared_comparator, (void *) ptbase->ptentry);
+			qsort_arg(ptchunks->index, nchunks, sizeof(int),
+					  tbm_shared_comparator, ptbase->ptentry);
 	}
 
 	/*
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index ed880c496a..a69c1d1e77 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -531,7 +531,7 @@ create_list_bounds(PartitionBoundSpec **boundspecs, int nparts,
 	Assert(j == ndatums);
 
 	qsort_arg(all_values, ndatums, sizeof(PartitionListValue),
-			  qsort_partition_list_value_cmp, (void *) key);
+			  qsort_partition_list_value_cmp, key);
 
 	boundinfo->ndatums = ndatums;
 	boundinfo->datums = (Datum **) palloc0(ndatums * sizeof(Datum *));
@@ -737,7 +737,7 @@ create_range_bounds(PartitionBoundSpec **boundspecs, int nparts,
 	qsort_arg(all_bounds, ndatums,
 			  sizeof(PartitionRangeBound *),
 			  qsort_partition_rbound_cmp,
-			  (void *) key);
+			  key);
 
 	/* Save distinct bounds from all_bounds into rbounds. */
 	rbounds = (PartitionRangeBound **)
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index bdc21bb457..572d9b4464 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -1129,7 +1129,7 @@ build_sorted_items(StatsBuildData *data, int *nitems,
 	}
 
 	/* do the sort, using the multi-sort */
-	qsort_interruptible((void *) items, nrows, sizeof(SortItem),
+	qsort_interruptible(items, nrows, sizeof(SortItem),
 						multi_sort_compare, mss);
 
 	return items;
diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c
index 2d2a87d3a6..e21e0e87e4 100644
--- a/src/backend/statistics/mcv.c
+++ b/src/backend/statistics/mcv.c
@@ -457,7 +457,7 @@ build_distinct_groups(int numrows, SortItem *items, MultiSortSupport mss,
 	Assert(j + 1 == ngroups);
 
 	/* Sort the distinct groups by frequency (in descending order). */
-	qsort_interruptible((void *) groups, ngroups, sizeof(SortItem),
+	qsort_interruptible(groups, ngroups, sizeof(SortItem),
 						compare_sort_item_count, NULL);
 
 	*ndistinct = ngroups;
@@ -528,7 +528,7 @@ build_column_frequencies(SortItem *groups, int ngroups,
 		}
 
 		/* sort the values, deduplicate */
-		qsort_interruptible((void *) result[dim], ngroups, sizeof(SortItem),
+		qsort_interruptible(result[dim], ngroups, sizeof(SortItem),
 							sort_item_compare, ssup);
 
 		/*
diff --git a/src/backend/statistics/mvdistinct.c b/src/backend/statistics/mvdistinct.c
index 13301a3157..df5cc3e13a 100644
--- a/src/backend/statistics/mvdistinct.c
+++ b/src/backend/statistics/mvdistinct.c
@@ -489,7 +489,7 @@ ndistinct_for_combination(double totalrows, StatsBuildData *data,
 	}
 
 	/* We can sort the array now ... */
-	qsort_interruptible((void *) items, numrows, sizeof(SortItem),
+	qsort_interruptible(items, numrows, sizeof(SortItem),
 						multi_sort_compare, mss);
 
 	/* ... and count the number of distinct combinations */
diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c
index c8dfed6178..cc04b87164 100644
--- a/src/backend/tsearch/spell.c
+++ b/src/backend/tsearch/spell.c
@@ -1305,7 +1305,7 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
 	tsearch_readline_end(&trst);
 
 	if (Conf->nCompoundAffixFlag > 1)
-		qsort((void *) Conf->CompoundAffixFlags, Conf->nCompoundAffixFlag,
+		qsort(Conf->CompoundAffixFlags, Conf->nCompoundAffixFlag,
 			  sizeof(CompoundAffixFlag), cmpcmdflag);
 
 	if (!tsearch_readline_begin(&trst, filename))
@@ -1789,7 +1789,7 @@ NISortDictionary(IspellDict *Conf)
 	else
 	{
 		/* Count the number of different flags used in the dictionary */
-		qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *),
+		qsort(Conf->Spell, Conf->nspell, sizeof(SPELL *),
 			  cmpspellaffix);
 
 		naffix = 0;
@@ -1827,7 +1827,7 @@ NISortDictionary(IspellDict *Conf)
 	}
 
 	/* Start build a prefix tree */
-	qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspell);
+	qsort(Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspell);
 	Conf->Dictionary = mkSPNode(Conf, 0, Conf->nspell, 0);
 }
 
@@ -2001,7 +2001,7 @@ NISortAffixes(IspellDict *Conf)
 
 	/* Store compound affixes in the Conf->CompoundAffix array */
 	if (Conf->naffixes > 1)
-		qsort((void *) Conf->Affix, Conf->naffixes, sizeof(AFFIX), cmpaffix);
+		qsort(Conf->Affix, Conf->naffixes, sizeof(AFFIX), cmpaffix);
 	Conf->CompoundAffix = ptr = (CMPDAffix *) palloc(sizeof(CMPDAffix) * Conf->naffixes);
 	ptr->affix = NULL;
 
diff --git a/src/backend/tsearch/to_tsany.c b/src/backend/tsearch/to_tsany.c
index f9a87e43ab..3b6d41f9e8 100644
--- a/src/backend/tsearch/to_tsany.c
+++ b/src/backend/tsearch/to_tsany.c
@@ -97,7 +97,7 @@ uniqueWORD(ParsedWord *a, int32 l)
 	/*
 	 * Sort words with its positions
 	 */
-	qsort((void *) a, l, sizeof(ParsedWord), compareWORD);
+	qsort(a, l, sizeof(ParsedWord), compareWORD);
 
 	/*
 	 * Initialize first word and its first position
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
index ca4563290f..f0cd2866ff 100644
--- a/src/backend/utils/adt/tsgistidx.c
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -704,7 +704,7 @@ gtsvector_picksplit(PG_FUNCTION_ARGS)
 		size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]), siglen);
 		costvector[j - 1].cost = abs(size_alpha - size_beta);
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	for (k = 0; k < maxoff; k++)
 	{
diff --git a/src/backend/utils/adt/tsquery_gist.c b/src/backend/utils/adt/tsquery_gist.c
index b7941ffaca..7c99348d44 100644
--- a/src/backend/utils/adt/tsquery_gist.c
+++ b/src/backend/utils/adt/tsquery_gist.c
@@ -222,7 +222,7 @@ gtsquery_picksplit(PG_FUNCTION_ARGS)
 		size_beta = hemdist(GETENTRY(entryvec, seed_2), GETENTRY(entryvec, j));
 		costvector[j - 1].cost = abs(size_alpha - size_beta);
 	}
-	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+	qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
 	for (k = 0; k < maxoff; k++)
 	{
diff --git a/src/backend/utils/adt/tsquery_util.c b/src/backend/utils/adt/tsquery_util.c
index f266b9f067..7b6970a6f8 100644
--- a/src/backend/utils/adt/tsquery_util.c
+++ b/src/backend/utils/adt/tsquery_util.c
@@ -173,7 +173,7 @@ QTNSort(QTNode *in)
 	for (i = 0; i < in->nchild; i++)
 		QTNSort(in->child[i]);
 	if (in->nchild > 1 && in->valnode->qoperator.oper != OP_PHRASE)
-		qsort((void *) in->child, in->nchild, sizeof(QTNode *), cmpQTN);
+		qsort(in->child, in->nchild, sizeof(QTNode *), cmpQTN);
 }
 
 /*
diff --git a/src/backend/utils/adt/tsrank.c b/src/backend/utils/adt/tsrank.c
index 1ae555f7f7..e5b850ea8e 100644
--- a/src/backend/utils/adt/tsrank.c
+++ b/src/backend/utils/adt/tsrank.c
@@ -176,7 +176,7 @@ SortAndUniqItems(TSQuery q, int *size)
 	if (*size < 2)
 		return res;
 
-	qsort_arg(res, *size, sizeof(QueryOperand *), compareQueryOperand, (void *) operand);
+	qsort_arg(res, *size, sizeof(QueryOperand *), compareQueryOperand, operand);
 
 	ptr = res + 1;
 	prevptr = res;
@@ -804,7 +804,7 @@ get_docrep(TSVector txt, QueryRepresentation *qr, int *doclen)
 		/*
 		 * Sort representation in ascending order by pos and entry
 		 */
-		qsort((void *) doc, cur, sizeof(DocRepresentation), compareDocR);
+		qsort(doc, cur, sizeof(DocRepresentation), compareDocR);
 
 		/*
 		 * Join QueryItem per WordEntry and it's position
diff --git a/src/backend/utils/adt/tsvector.c b/src/backend/utils/adt/tsvector.c
index e5b05960e3..03db27194a 100644
--- a/src/backend/utils/adt/tsvector.c
+++ b/src/backend/utils/adt/tsvector.c
@@ -58,7 +58,7 @@ uniquePos(WordEntryPos *a, int l)
 	if (l <= 1)
 		return l;
 
-	qsort((void *) a, l, sizeof(WordEntryPos), compareWordEntryPos);
+	qsort(a, l, sizeof(WordEntryPos), compareWordEntryPos);
 
 	res = a;
 	ptr = a + 1;
@@ -107,8 +107,8 @@ uniqueentry(WordEntryIN *a, int l, char *buf, int *outbuflen)
 	Assert(l >= 1);
 
 	if (l > 1)
-		qsort_arg((void *) a, l, sizeof(WordEntryIN), compareentry,
-				  (void *) buf);
+		qsort_arg(a, l, sizeof(WordEntryIN), compareentry,
+				  buf);
 
 	buflen = 0;
 	res = a;
@@ -552,8 +552,8 @@ tsvectorrecv(PG_FUNCTION_ARGS)
 	SET_VARSIZE(vec, hdrlen + datalen);
 
 	if (needSort)
-		qsort_arg((void *) ARRPTR(vec), vec->size, sizeof(WordEntry),
-				  compareentry, (void *) STRPTR(vec));
+		qsort_arg(ARRPTR(vec), vec->size, sizeof(WordEntry),
+				  compareentry, STRPTR(vec));
 
 	PG_RETURN_TSVECTOR(vec);
 }
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index cb4386f871..71d3bc25fb 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -2363,7 +2363,7 @@ WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
 		}
 
 		if (ntes > 1)
-			qsort((void *) tes, ntes, sizeof(TocEntry *),
+			qsort(tes, ntes, sizeof(TocEntry *),
 				  TocEntrySizeCompare);
 
 		for (int i = 0; i < ntes; i++)
diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c
index f963b9a449..8266c117a3 100644
--- a/src/bin/pg_dump/pg_dump_sort.c
+++ b/src/bin/pg_dump/pg_dump_sort.c
@@ -186,7 +186,7 @@ void
 sortDumpableObjectsByTypeName(DumpableObject **objs, int numObjs)
 {
 	if (numObjs > 1)
-		qsort((void *) objs, numObjs, sizeof(DumpableObject *),
+		qsort(objs, numObjs, sizeof(DumpableObject *),
 			  DOTypeNameCompare);
 }
 
diff --git a/src/bin/pg_upgrade/function.c b/src/bin/pg_upgrade/function.c
index 9ad75446ee..dc8800c7cd 100644
--- a/src/bin/pg_upgrade/function.c
+++ b/src/bin/pg_upgrade/function.c
@@ -136,7 +136,7 @@ check_loadable_libraries(void)
 	 * consistent order, which is important for reproducible behavior if one
 	 * library depends on another.
 	 */
-	qsort((void *) os_info.libraries, os_info.num_libraries,
+	qsort(os_info.libraries, os_info.num_libraries,
 		  sizeof(LibraryInfo), library_name_compare);
 
 	for (libnum = 0; libnum < os_info.num_libraries; libnum++)
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 9c12ffaea9..d2d6431a28 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -1604,7 +1604,7 @@ lookupVariable(Variables *variables, char *name)
 	/* Sort if we have to */
 	if (!variables->vars_sorted)
 	{
-		qsort((void *) variables->vars, variables->nvars, sizeof(Variable),
+		qsort(variables->vars, variables->nvars, sizeof(Variable),
 			  compareVariableNames);
 		variables->vars_sorted = true;
 	}
-- 
2.39.1



  [text/plain] 0008-Remove-useless-casts-to-void-bsearch.patch (2.0K, ../../[email protected]/9-0008-Remove-useless-casts-to-void-bsearch.patch)
  download | inline diff:
From 5ccd209c0fd26625597757cecc5c7acc0f2b7b18 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 2 Feb 2023 23:02:35 +0100
Subject: [PATCH 8/8] Remove useless casts to (void *) (bsearch)

---
 src/backend/commands/vacuum.c | 4 ++--
 src/backend/tsearch/spell.c   | 2 +-
 src/bin/pgbench/pgbench.c     | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 7b1a4b127e..aa79d9de4d 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -2384,8 +2384,8 @@ vac_tid_reaped(ItemPointer itemptr, void *state)
 	if (item < litem || item > ritem)
 		return false;
 
-	res = (ItemPointer) bsearch((void *) itemptr,
-								(void *) dead_items->items,
+	res = (ItemPointer) bsearch(itemptr,
+								dead_items->items,
 								dead_items->num_items,
 								sizeof(ItemPointerData),
 								vac_cmp_itemptr);
diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c
index cc04b87164..8d48cad251 100644
--- a/src/backend/tsearch/spell.c
+++ b/src/backend/tsearch/spell.c
@@ -1158,7 +1158,7 @@ getCompoundAffixFlagValue(IspellDict *Conf, char *s)
 		setCompoundAffixFlagValue(Conf, &key, sflag, 0);
 
 		found = (CompoundAffixFlag *)
-			bsearch(&key, (void *) Conf->CompoundAffixFlags,
+			bsearch(&key, Conf->CompoundAffixFlags,
 					Conf->nCompoundAffixFlag, sizeof(CompoundAffixFlag),
 					cmpcmdflag);
 		if (found != NULL)
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index d2d6431a28..508ed218e8 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -1611,8 +1611,8 @@ lookupVariable(Variables *variables, char *name)
 
 	/* Now we can search */
 	key.name = name;
-	return (Variable *) bsearch((void *) &key,
-								(void *) variables->vars,
+	return (Variable *) bsearch(&key,
+								variables->vars,
 								variables->nvars,
 								sizeof(Variable),
 								compareVariableNames);
-- 
2.39.1



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


end of thread, other threads:[~2023-02-02 22:22 UTC | newest]

Thread overview: 2+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2021-02-05 12:51 [PATCH v24 1/7] Built-in compression method dilipkumar <[email protected]>
2023-02-02 22:22 Remove some useless casts to (void *) Peter Eisentraut <[email protected]>

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