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

