v1-0001-Add-pg_lfind8_nonzero.patch
application/octet-stream
Filename: v1-0001-Add-pg_lfind8_nonzero.patch
Type: application/octet-stream
Part: 0
Message:
[PATCH] Add pg_lfind8_nonzero()
From ee5da25dbba924c1c9a399568c27db8ac603e2d8 Mon Sep 17 00:00:00 2001
From: ChangAo Chen <cca5507@qq.com>
Date: Sun, 14 Dec 2025 18:13:31 +0800
Subject: [PATCH v1 1/3] Add pg_lfind8_nonzero().
---
src/include/port/pg_lfind.h | 40 +++++++++++++++++++
.../test_lfind/expected/test_lfind.out | 6 +++
.../modules/test_lfind/sql/test_lfind.sql | 1 +
.../modules/test_lfind/test_lfind--1.0.sql | 4 ++
src/test/modules/test_lfind/test_lfind.c | 17 ++++++++
5 files changed, 68 insertions(+)
diff --git a/src/include/port/pg_lfind.h b/src/include/port/pg_lfind.h
index 20f7497dcb7..8dd7b81ebba 100644
--- a/src/include/port/pg_lfind.h
+++ b/src/include/port/pg_lfind.h
@@ -80,6 +80,46 @@ pg_lfind8_le(uint8 key, uint8 *base, uint32 nelem)
return false;
}
+/*
+ * pg_lfind8_nonzero
+ *
+ * Return true if there is an element in 'base' that is not equal to
+ * zero, otherwise return false.
+ */
+static inline bool
+pg_lfind8_nonzero(uint8 *base, uint32 nelem)
+{
+ uint32 i;
+ uint32 tail_idx;
+ uint64 chunk;
+
+ /* Search the array one-by-one if there aren't enough elements. */
+ if (nelem < sizeof(chunk))
+ {
+ for (i = 0; i < nelem; i++)
+ {
+ if (base[i] != 0)
+ return true;
+ }
+ return false;
+ }
+
+ /* Round down to multiple of chunk length. */
+ tail_idx = nelem & ~(sizeof(chunk) - 1);
+
+ for (i = 0; i < tail_idx; i += sizeof(chunk))
+ {
+ /* memcpy() to avoid unaligned access. */
+ memcpy(&chunk, &base[i], sizeof(chunk));
+ if (chunk != 0)
+ return true;
+ }
+
+ /* Process the last chunk in the array. */
+ memcpy(&chunk, &base[nelem - sizeof(chunk)], sizeof(chunk));
+ return chunk != 0;
+}
+
/*
* pg_lfind32_one_by_one_helper
*
diff --git a/src/test/modules/test_lfind/expected/test_lfind.out b/src/test/modules/test_lfind/expected/test_lfind.out
index 1d4b14e7032..4f43a729b51 100644
--- a/src/test/modules/test_lfind/expected/test_lfind.out
+++ b/src/test/modules/test_lfind/expected/test_lfind.out
@@ -16,6 +16,12 @@ SELECT test_lfind8_le();
(1 row)
+SELECT test_lfind8_nonzero();
+ test_lfind8_nonzero
+---------------------
+
+(1 row)
+
SELECT test_lfind32();
test_lfind32
--------------
diff --git a/src/test/modules/test_lfind/sql/test_lfind.sql b/src/test/modules/test_lfind/sql/test_lfind.sql
index 766c640831f..7894fa61e78 100644
--- a/src/test/modules/test_lfind/sql/test_lfind.sql
+++ b/src/test/modules/test_lfind/sql/test_lfind.sql
@@ -7,4 +7,5 @@ CREATE EXTENSION test_lfind;
--
SELECT test_lfind8();
SELECT test_lfind8_le();
+SELECT test_lfind8_nonzero();
SELECT test_lfind32();
diff --git a/src/test/modules/test_lfind/test_lfind--1.0.sql b/src/test/modules/test_lfind/test_lfind--1.0.sql
index 81801926ae8..bb72cc6e56a 100644
--- a/src/test/modules/test_lfind/test_lfind--1.0.sql
+++ b/src/test/modules/test_lfind/test_lfind--1.0.sql
@@ -14,3 +14,7 @@ CREATE FUNCTION test_lfind8()
CREATE FUNCTION test_lfind8_le()
RETURNS pg_catalog.void
AS 'MODULE_PATHNAME' LANGUAGE C;
+
+CREATE FUNCTION test_lfind8_nonzero()
+ RETURNS pg_catalog.void
+ AS 'MODULE_PATHNAME' LANGUAGE C;
diff --git a/src/test/modules/test_lfind/test_lfind.c b/src/test/modules/test_lfind/test_lfind.c
index 8dcaa8f9fda..52ae6783ec9 100644
--- a/src/test/modules/test_lfind/test_lfind.c
+++ b/src/test/modules/test_lfind/test_lfind.c
@@ -115,6 +115,23 @@ test_lfind8_le(PG_FUNCTION_ARGS)
PG_RETURN_VOID();
}
+PG_FUNCTION_INFO_V1(test_lfind8_nonzero);
+Datum
+test_lfind8_nonzero(PG_FUNCTION_ARGS)
+{
+ uint8 charbuf[64] = {0};
+
+ charbuf[32] = 1;
+
+ if (pg_lfind8_nonzero(charbuf, 32))
+ elog(ERROR, "pg_lfind8_nonzero() found nonexistent nonzero");
+
+ if (!pg_lfind8_nonzero(charbuf, 64))
+ elog(ERROR, "pg_lfind8_nonzero() did not find existing nonzero");
+
+ PG_RETURN_VOID();
+}
+
PG_FUNCTION_INFO_V1(test_lfind32);
Datum
test_lfind32(PG_FUNCTION_ARGS)
--
2.52.0