diff --git a/Dockerfile b/Dockerfile
index 1a05f0ea0d41543ed8dd186a6fbda2a9f8f0264b..0feb7bb4599388f06c5c69074dcbe07adcc57647 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -21,7 +21,7 @@
 
 FROM registry.conarx.tech/containers/postgresql/3.19 as tsbuilder-base
 
-ENV POSTGRESQL_VER=15.4
+ENV POSTGRESQL_VER=16.2
 
 # Copy build patches
 COPY patches build/patches
@@ -54,9 +54,9 @@ RUN set -eux; \
 
 
 
-FROM tsbuilder-base as tsbuilder-2.12.2
+FROM tsbuilder-base as tsbuilder-2.14.0
 
-ENV TIMESCALEDB_VER=2.12.2
+ENV TIMESCALEDB_VER=2.14.0
 
 # Checkout the right version
 RUN set -eux; \
@@ -69,9 +69,7 @@ RUN set -eux; \
 	cd build; \
 	cd "timescaledb"; \
 # Patching
-	# TODO: Patch can maybe be removed in future? 2.10.0+
-	patch -p1 < ../patches/disable-partialize_finalize-test.patch; \
-	patch -p1 < ../patches/timescaledb-2.9.3_disable-pg_join-test.patch; \
+	patch -p1 < ../patches/timescaledb-2.14.0-fix-test-output.patch; \
 	mkdir build; \
 	cd build; \
 	\
@@ -106,407 +104,10 @@ RUN set -eux; \
 	cd "timescaledb"; \
 	cd build; \
 	# Test
-	sudo -u pgsqltest make VERBOSE=1 -j1 -l8 installcheck
-
-
-
-FROM tsbuilder-base as tsbuilder-2.12.1
-
-ENV TIMESCALEDB_VER=2.12.1
-
-# Checkout the right version
-RUN set -eux; \
-	cd build; \
-	cd timescaledb; \
-	git checkout "$TIMESCALEDB_VER"
-
-# Build
-RUN set -eux; \
-	cd build; \
-	cd "timescaledb"; \
-# Patching
-	# TODO: Patch can maybe be removed in future? 2.10.0+
-	patch -p1 < ../patches/disable-partialize_finalize-test.patch; \
-	patch -p1 < ../patches/timescaledb-2.9.3_disable-pg_join-test.patch; \
-	mkdir build; \
-	cd build; \
-	\
-	cmake ..; \
-	make VERBOSE=1 -j$(nproc) -l 8; \
-	make DESTDIR="/build/timescaledb-root" install; \
-	# We need to install a second time to run timescaledb tests
-	echo "Size before stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Strip binaries
-RUN set -eux; \
-	cd build/timescaledb-root; \
-	scanelf --recursive --nobanner --osabi --etype "ET_DYN,ET_EXEC" .  | awk '{print $3}' | xargs \
-		strip \
-			--remove-section=.comment \
-			--remove-section=.note \
-			-R .gnu.lto_* -R .gnu.debuglto_* \
-			-N __gnu_lto_slim -N __gnu_lto_v1 \
-			--strip-unneeded; \
-	echo "Size after stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Testing
-RUN set -eux; \
-	# Install TimescaleDB so we can run the installcheck tests below
-	tar -c -C /build/timescaledb-root . | tar -x -C /; \
-	# For testing we need to run the tests as a non-priv user
-	cd build; \
-	adduser -D pgsqltest; \
-	chown -R pgsqltest:pgsqltest "timescaledb"; \
-	cd "timescaledb"; \
-	cd build; \
-	# Test
-	sudo -u pgsqltest make VERBOSE=1 -j1 -l8 installcheck
-
-
-
-
-
-
-FROM tsbuilder-base as tsbuilder-2.12.0
-
-ENV TIMESCALEDB_VER=2.12.0
-
-# Checkout the right version
-RUN set -eux; \
-	cd build; \
-	cd timescaledb; \
-	git checkout "$TIMESCALEDB_VER"
-
-# Build
-RUN set -eux; \
-	cd build; \
-	cd "timescaledb"; \
-# Patching
-	# TODO: Patch can maybe be removed in future? 2.10.0+
-	patch -p1 < ../patches/disable-partialize_finalize-test.patch; \
-	patch -p1 < ../patches/timescaledb-2.9.3_disable-pg_join-test.patch; \
-	mkdir build; \
-	cd build; \
-	\
-	cmake ..; \
-	make VERBOSE=1 -j$(nproc) -l 8; \
-	make DESTDIR="/build/timescaledb-root" install; \
-	# We need to install a second time to run timescaledb tests
-	echo "Size before stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Strip binaries
-RUN set -eux; \
-	cd build/timescaledb-root; \
-	scanelf --recursive --nobanner --osabi --etype "ET_DYN,ET_EXEC" .  | awk '{print $3}' | xargs \
-		strip \
-			--remove-section=.comment \
-			--remove-section=.note \
-			-R .gnu.lto_* -R .gnu.debuglto_* \
-			-N __gnu_lto_slim -N __gnu_lto_v1 \
-			--strip-unneeded; \
-	echo "Size after stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Testing
-RUN set -eux; \
-	# Install TimescaleDB so we can run the installcheck tests below
-	tar -c -C /build/timescaledb-root . | tar -x -C /; \
-	# For testing we need to run the tests as a non-priv user
-	cd build; \
-	adduser -D pgsqltest; \
-	chown -R pgsqltest:pgsqltest "timescaledb"; \
-	cd "timescaledb"; \
-	cd build; \
-	# Test
-	sudo -u pgsqltest make VERBOSE=1 -j1 -l8 installcheck
-
-
-
-
-
-
-FROM tsbuilder-base as tsbuilder-2.11.2
-
-ENV TIMESCALEDB_VER=2.11.2
-
-# Checkout the right version
-RUN set -eux; \
-	cd build; \
-	cd timescaledb; \
-	git checkout "$TIMESCALEDB_VER"
-
-# Build
-RUN set -eux; \
-	cd build; \
-	cd "timescaledb"; \
-# Patching
-	# TODO: Patch can maybe be removed in future? 2.10.0+
-	patch -p1 < ../patches/disable-partialize_finalize-test.patch; \
-	patch -p1 < ../patches/timescaledb-2.9.3_disable-pg_join-test.patch; \
-	mkdir build; \
-	cd build; \
-	\
-	cmake ..; \
-	make VERBOSE=1 -j$(nproc) -l 8; \
-	make DESTDIR="/build/timescaledb-root" install; \
-	# We need to install a second time to run timescaledb tests
-	echo "Size before stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Strip binaries
-RUN set -eux; \
-	cd build/timescaledb-root; \
-	scanelf --recursive --nobanner --osabi --etype "ET_DYN,ET_EXEC" .  | awk '{print $3}' | xargs \
-		strip \
-			--remove-section=.comment \
-			--remove-section=.note \
-			-R .gnu.lto_* -R .gnu.debuglto_* \
-			-N __gnu_lto_slim -N __gnu_lto_v1 \
-			--strip-unneeded; \
-	echo "Size after stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Testing
-RUN set -eux; \
-	# Install TimescaleDB so we can run the installcheck tests below
-	tar -c -C /build/timescaledb-root . | tar -x -C /; \
-	# For testing we need to run the tests as a non-priv user
-	cd build; \
-	adduser -D pgsqltest; \
-	chown -R pgsqltest:pgsqltest "timescaledb"; \
-	cd "timescaledb"; \
-	cd build; \
-	# Test
-	sudo -u pgsqltest make VERBOSE=1 -j1 -l8 installcheck
-
-
-
-FROM tsbuilder-base as tsbuilder-2.11.1
-
-ENV TIMESCALEDB_VER=2.11.1
-
-# Checkout the right version
-RUN set -eux; \
-	cd build; \
-	cd timescaledb; \
-	git checkout "$TIMESCALEDB_VER"
-
-# Build
-RUN set -eux; \
-	cd build; \
-	cd "timescaledb"; \
-# Patching
-	# TODO: Patch can maybe be removed in future? 2.10.0+
-	patch -p1 < ../patches/disable-partialize_finalize-test.patch; \
-	patch -p1 < ../patches/timescaledb-2.9.3_disable-pg_join-test.patch; \
-	mkdir build; \
-	cd build; \
-	\
-	cmake ..; \
-	make VERBOSE=1 -j$(nproc) -l 8; \
-	make DESTDIR="/build/timescaledb-root" install; \
-	# We need to install a second time to run timescaledb tests
-	echo "Size before stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Strip binaries
-RUN set -eux; \
-	cd build/timescaledb-root; \
-	scanelf --recursive --nobanner --osabi --etype "ET_DYN,ET_EXEC" .  | awk '{print $3}' | xargs \
-		strip \
-			--remove-section=.comment \
-			--remove-section=.note \
-			-R .gnu.lto_* -R .gnu.debuglto_* \
-			-N __gnu_lto_slim -N __gnu_lto_v1 \
-			--strip-unneeded; \
-	echo "Size after stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Testing
-RUN set -eux; \
-	# Install TimescaleDB so we can run the installcheck tests below
-	tar -c -C /build/timescaledb-root . | tar -x -C /; \
-	# For testing we need to run the tests as a non-priv user
-	cd build; \
-	adduser -D pgsqltest; \
-	chown -R pgsqltest:pgsqltest "timescaledb"; \
-	cd "timescaledb"; \
-	cd build; \
-	# Test
-	sudo -u pgsqltest make VERBOSE=1 -j1 -l8 installcheck
-
-
-
-FROM tsbuilder-base as tsbuilder-2.10.1
-
-ENV TIMESCALEDB_VER=2.10.1
-
-# Checkout the right version
-RUN set -eux; \
-	cd build; \
-	cd timescaledb; \
-	git checkout "$TIMESCALEDB_VER"
-
-# Build
-RUN set -eux; \
-	cd build; \
-	cd "timescaledb"; \
-# Patching
-	# TODO: Patch can maybe be removed in future? 2.10.0+
-	patch -p1 < ../patches/disable-partialize_finalize-test.patch; \
-	patch -p1 < ../patches/timescaledb-2.9.3_disable-pg_join-test.patch; \
-	mkdir build; \
-	cd build; \
-	\
-	cmake ..; \
-	make VERBOSE=1 -j$(nproc) -l 8; \
-	make DESTDIR="/build/timescaledb-root" install; \
-	# We need to install a second time to run timescaledb tests
-	echo "Size before stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Strip binaries
-RUN set -eux; \
-	cd build/timescaledb-root; \
-	scanelf --recursive --nobanner --osabi --etype "ET_DYN,ET_EXEC" .  | awk '{print $3}' | xargs \
-		strip \
-			--remove-section=.comment \
-			--remove-section=.note \
-			-R .gnu.lto_* -R .gnu.debuglto_* \
-			-N __gnu_lto_slim -N __gnu_lto_v1 \
-			--strip-unneeded; \
-	echo "Size after stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Testing
-RUN set -eux; \
-	# Install TimescaleDB so we can run the installcheck tests below
-	tar -c -C /build/timescaledb-root . | tar -x -C /; \
-	# For testing we need to run the tests as a non-priv user
-	cd build; \
-	adduser -D pgsqltest; \
-	chown -R pgsqltest:pgsqltest "timescaledb"; \
-	cd "timescaledb"; \
-	cd build; \
-	# Test
-	sudo -u pgsqltest make VERBOSE=1 -j1 -l8 installcheck
-
-
-
-
-FROM tsbuilder-base as tsbuilder-2.9.3
-
-ENV TIMESCALEDB_VER=2.9.3
-
-# Checkout the right version
-RUN set -eux; \
-	cd build; \
-	cd timescaledb; \
-	git checkout "$TIMESCALEDB_VER"
-
-# Build
-RUN set -eux; \
-	cd build; \
-	cd "timescaledb"; \
-# Patching
-	# TODO: Patch can maybe be removed in future? 2.10.0+
-	patch -p1 < ../patches/disable-partialize_finalize-test.patch; \
-	patch -p1 < ../patches/timescaledb-2.9.3_disable-pg_join-test.patch; \
-	mkdir build; \
-	cd build; \
-	\
-	cmake ..; \
-	make VERBOSE=1 -j$(nproc) -l 8; \
-	make DESTDIR="/build/timescaledb-root" install; \
-	# We need to install a second time to run timescaledb tests
-	echo "Size before stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Strip binaries
-RUN set -eux; \
-	cd build/timescaledb-root; \
-	scanelf --recursive --nobanner --osabi --etype "ET_DYN,ET_EXEC" .  | awk '{print $3}' | xargs \
-		strip \
-			--remove-section=.comment \
-			--remove-section=.note \
-			-R .gnu.lto_* -R .gnu.debuglto_* \
-			-N __gnu_lto_slim -N __gnu_lto_v1 \
-			--strip-unneeded; \
-	echo "Size after stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Testing
-RUN set -eux; \
-	# Install TimescaleDB so we can run the installcheck tests below
-	tar -c -C /build/timescaledb-root . | tar -x -C /; \
-	# For testing we need to run the tests as a non-priv user
-	cd build; \
-	adduser -D pgsqltest; \
-	chown -R pgsqltest:pgsqltest "timescaledb"; \
-	cd "timescaledb"; \
-	cd build; \
-	# Test
-	sudo -u pgsqltest make VERBOSE=1 -j1 -l8 installcheck
-
-
-
-FROM tsbuilder-base as tsbuilder-2.9.2
-
-ENV TIMESCALEDB_VER=2.9.2
-
-# Checkout the right version
-RUN set -eux; \
-	cd build; \
-	cd timescaledb; \
-	git checkout "$TIMESCALEDB_VER"
-
-# Build
-RUN set -eux; \
-	cd build; \
-	cd "timescaledb"; \
-# Patching
-	# TODO: Patch can maybe be removed in future? 2.10.0+
-	patch -p1 < ../patches/disable-partialize_finalize-test.patch; \
-	patch -p1 < ../patches/timescaledb-2.9.3_disable-pg_join-test.patch; \
-	mkdir build; \
-	cd build; \
-	\
-	cmake ..; \
-	make VERBOSE=1 -j$(nproc) -l 8; \
-	make DESTDIR="/build/timescaledb-root" install; \
-	# We need to install a second time to run timescaledb tests
-	echo "Size before stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Strip binaries
-RUN set -eux; \
-	cd build/timescaledb-root; \
-	scanelf --recursive --nobanner --osabi --etype "ET_DYN,ET_EXEC" .  | awk '{print $3}' | xargs \
-		strip \
-			--remove-section=.comment \
-			--remove-section=.note \
-			-R .gnu.lto_* -R .gnu.debuglto_* \
-			-N __gnu_lto_slim -N __gnu_lto_v1 \
-			--strip-unneeded; \
-	echo "Size after stripping..."; \
-	du -hs /build/timescaledb-root
-
-# Testing
-RUN set -eux; \
-	# Install TimescaleDB so we can run the installcheck tests below
-	tar -c -C /build/timescaledb-root . | tar -x -C /; \
-	# For testing we need to run the tests as a non-priv user
-	cd build; \
-	adduser -D pgsqltest; \
-	chown -R pgsqltest:pgsqltest "timescaledb"; \
-	cd "timescaledb"; \
-	cd build; \
-	# Test
-	sudo -u pgsqltest make VERBOSE=1 -j1 -l8 installcheck
-
+	if ! sudo -u pgsqltest make VERBOSE=1 -j1 -l8 installcheck; then \
+		cat test/regression.diffs; \
+		false; \
+	fi
 
 
 
@@ -514,14 +115,7 @@ FROM registry.conarx.tech/containers/postgresql/3.19
 
 
 # NK: Versions are reverse ordered so newer ones overwrite data from older ones
-COPY --from=tsbuilder-2.9.2 /build/timescaledb-root /
-COPY --from=tsbuilder-2.9.3 /build/timescaledb-root /
-COPY --from=tsbuilder-2.10.1 /build/timescaledb-root /
-COPY --from=tsbuilder-2.11.1 /build/timescaledb-root /
-COPY --from=tsbuilder-2.11.2 /build/timescaledb-root /
-COPY --from=tsbuilder-2.12.0 /build/timescaledb-root /
-COPY --from=tsbuilder-2.12.1 /build/timescaledb-root /
-COPY --from=tsbuilder-2.12.2 /build/timescaledb-root /
+COPY --from=tsbuilder-2.14.0 /build/timescaledb-root /
 
 
 ARG VERSION_INFO=
diff --git a/patches/disable-partialize_finalize-test.patch b/patches/disable-partialize_finalize-test.patch
deleted file mode 100644
index 571578de33a8125bd58238d1c8e88db4e8825dbd..0000000000000000000000000000000000000000
--- a/patches/disable-partialize_finalize-test.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/tsl/test/sql/CMakeLists.txt b/tsl/test/sql/CMakeLists.txt
-index 83a1111..958ebfe 100644
---- a/tsl/test/sql/CMakeLists.txt
-+++ b/tsl/test/sql/CMakeLists.txt
-@@ -22,7 +22,6 @@ set(TEST_FILES
-     exp_cagg_origin.sql
-     exp_cagg_timezone.sql
-     move.sql
--    partialize_finalize.sql
-     reorder.sql
-     skip_scan.sql)
- 
diff --git a/patches/timescaledb-2.14.0-fix-test-output.patch b/patches/timescaledb-2.14.0-fix-test-output.patch
new file mode 100644
index 0000000000000000000000000000000000000000..2fed537234519bbf79071fb6dd82bc6fff38715b
--- /dev/null
+++ b/patches/timescaledb-2.14.0-fix-test-output.patch
@@ -0,0 +1,20 @@
+diff --git a/test/expected/pg_dump_unprivileged.out b/test/expected/pg_dump_unprivileged.out
+index e44df696e..40f533d32 100644
+--- a/test/expected/pg_dump_unprivileged.out
++++ b/test/expected/pg_dump_unprivileged.out
+@@ -9,6 +9,7 @@ CREATE USER dump_unprivileged CREATEDB;
+ \c template1 dump_unprivileged
+ CREATE database dump_unprivileged;
+ \! utils/pg_dump_unprivileged.sh
++Database dumped successfully
+ \c dump_unprivileged :ROLE_SUPERUSER
+ DROP EXTENSION timescaledb;
+ GRANT ALL ON DATABASE dump_unprivileged TO dump_unprivileged;
+@@ -18,6 +19,7 @@ CREATE EXTENSION timescaledb;
+ CREATE TABLE t1 (a int);
+ -- pg_dump currently fails when dumped
+ \! utils/pg_dump_unprivileged.sh
++Database dumped successfully
+ \c template1 :ROLE_SUPERUSER
+ DROP EXTENSION timescaledb;
+ DROP DATABASE dump_unprivileged WITH (FORCE);
diff --git a/patches/timescaledb-2.9.3_disable-pg_join-test.patch b/patches/timescaledb-2.9.3_disable-pg_join-test.patch
deleted file mode 100644
index b33a0a59268aab7449ab7b7ae6e83739b49fd8ca..0000000000000000000000000000000000000000
--- a/patches/timescaledb-2.9.3_disable-pg_join-test.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff --color -ru timescaledb-2.9.3_vanilla/test/sql/CMakeLists.txt timescaledb-2.9.3_disable-pg_join-test/test/sql/CMakeLists.txt
---- timescaledb-2.9.3_vanilla/test/sql/CMakeLists.txt	2023-02-06 11:22:25.000000000 +0000
-+++ timescaledb-2.9.3_disable-pg_join-test/test/sql/CMakeLists.txt	2023-03-08 19:49:02.125092531 +0000
-@@ -34,7 +34,6 @@
-     partition.sql
-     partitioning.sql
-     pg_dump_unprivileged.sql
--    pg_join.sql
-     plain.sql
-     plan_ordered_append.sql
-     relocate_extension.sql