pgpcre: Add a patch to support pcre2. Per https://github.com/petere/pgpcre/pull/9
authorDevrim Gunduz <devrim@gunduz.org>
Sat, 5 Jul 2025 16:49:30 +0000 (17:49 +0100)
committerDevrim Gunduz <devrim@gunduz.org>
Sat, 5 Jul 2025 16:49:30 +0000 (17:49 +0100)
rpm/redhat/main/non-common/pgpcre/EL-10/Makefile [new file with mode: 0644]
rpm/redhat/main/non-common/pgpcre/EL-10/pgpcre-pcre2.patch [new symlink]
rpm/redhat/main/non-common/pgpcre/EL-10/pgpcre.spec [new symlink]
rpm/redhat/main/non-common/pgpcre/EL-8/pgpcre-pcre2.patch [new symlink]
rpm/redhat/main/non-common/pgpcre/EL-9/pgpcre-pcre2.patch [new symlink]
rpm/redhat/main/non-common/pgpcre/F-41/pgpcre-pcre2.patch [new symlink]
rpm/redhat/main/non-common/pgpcre/F-42/pgpcre-pcre2.patch [new symlink]
rpm/redhat/main/non-common/pgpcre/SLES-15/pgpcre-pcre2.patch [new symlink]
rpm/redhat/main/non-common/pgpcre/main/pgpcre-pcre2.patch [new file with mode: 0644]
rpm/redhat/main/non-common/pgpcre/main/pgpcre.spec

diff --git a/rpm/redhat/main/non-common/pgpcre/EL-10/Makefile b/rpm/redhat/main/non-common/pgpcre/EL-10/Makefile
new file mode 100644 (file)
index 0000000..de3d7be
--- /dev/null
@@ -0,0 +1,17 @@
+#################################
+# RPM-specific Makefile                #
+# https://yum.postgresql.org   #
+#                              #
+# Devrim Gunduz                        #
+# devrim@gunduz.org            #
+#################################
+
+# Predefined values
+
+ARCH=`rpm --eval "%{_arch}"`
+DIR=`pwd`
+DIST=.rhel10
+SPECFILE="pgpcre.spec"
+
+# Now, include global Makefile
+include ../../../../global/Makefile.global
diff --git a/rpm/redhat/main/non-common/pgpcre/EL-10/pgpcre-pcre2.patch b/rpm/redhat/main/non-common/pgpcre/EL-10/pgpcre-pcre2.patch
new file mode 120000 (symlink)
index 0000000..5fa346b
--- /dev/null
@@ -0,0 +1 @@
+../main/pgpcre-pcre2.patch
\ No newline at end of file
diff --git a/rpm/redhat/main/non-common/pgpcre/EL-10/pgpcre.spec b/rpm/redhat/main/non-common/pgpcre/EL-10/pgpcre.spec
new file mode 120000 (symlink)
index 0000000..99bc862
--- /dev/null
@@ -0,0 +1 @@
+../main/pgpcre.spec
\ No newline at end of file
diff --git a/rpm/redhat/main/non-common/pgpcre/EL-8/pgpcre-pcre2.patch b/rpm/redhat/main/non-common/pgpcre/EL-8/pgpcre-pcre2.patch
new file mode 120000 (symlink)
index 0000000..5fa346b
--- /dev/null
@@ -0,0 +1 @@
+../main/pgpcre-pcre2.patch
\ No newline at end of file
diff --git a/rpm/redhat/main/non-common/pgpcre/EL-9/pgpcre-pcre2.patch b/rpm/redhat/main/non-common/pgpcre/EL-9/pgpcre-pcre2.patch
new file mode 120000 (symlink)
index 0000000..5fa346b
--- /dev/null
@@ -0,0 +1 @@
+../main/pgpcre-pcre2.patch
\ No newline at end of file
diff --git a/rpm/redhat/main/non-common/pgpcre/F-41/pgpcre-pcre2.patch b/rpm/redhat/main/non-common/pgpcre/F-41/pgpcre-pcre2.patch
new file mode 120000 (symlink)
index 0000000..5fa346b
--- /dev/null
@@ -0,0 +1 @@
+../main/pgpcre-pcre2.patch
\ No newline at end of file
diff --git a/rpm/redhat/main/non-common/pgpcre/F-42/pgpcre-pcre2.patch b/rpm/redhat/main/non-common/pgpcre/F-42/pgpcre-pcre2.patch
new file mode 120000 (symlink)
index 0000000..5fa346b
--- /dev/null
@@ -0,0 +1 @@
+../main/pgpcre-pcre2.patch
\ No newline at end of file
diff --git a/rpm/redhat/main/non-common/pgpcre/SLES-15/pgpcre-pcre2.patch b/rpm/redhat/main/non-common/pgpcre/SLES-15/pgpcre-pcre2.patch
new file mode 120000 (symlink)
index 0000000..5fa346b
--- /dev/null
@@ -0,0 +1 @@
+../main/pgpcre-pcre2.patch
\ No newline at end of file
diff --git a/rpm/redhat/main/non-common/pgpcre/main/pgpcre-pcre2.patch b/rpm/redhat/main/non-common/pgpcre/main/pgpcre-pcre2.patch
new file mode 100644 (file)
index 0000000..6e72b88
--- /dev/null
@@ -0,0 +1,279 @@
+From bf69a7118e05958fe1d174847b1ea083a6ce37b1 Mon Sep 17 00:00:00 2001
+From: Yavor Doganov <yavor@gnu.org>
+Date: Sat, 16 Dec 2023 22:49:10 +0200
+Subject: [PATCH] Port to PCRE2
+
+Source: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1000001
+---
+ Makefile               |   6 +--
+ pgpcre.c               | 100 ++++++++++++++++++++---------------------
+ test/expected/test.out |   4 +-
+ 3 files changed, 53 insertions(+), 57 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index dadb1ed..2474572 100644
+--- a/Makefile
++++ b/Makefile
+@@ -6,12 +6,12 @@ MODULE_big = pgpcre
+ OBJS = pgpcre.o
+ DATA = pgpcre--0.sql pgpcre--1.sql pgpcre--0--1.sql
+-ifeq (no,$(shell $(PKG_CONFIG) libpcre || echo no))
++ifeq (no,$(shell $(PKG_CONFIG) libpcre2-8 || echo no))
+ $(warning libpcre not registed with pkg-config, build might fail)
+ endif
+-PG_CPPFLAGS += $(shell $(PKG_CONFIG) --cflags-only-I libpcre)
+-SHLIB_LINK += $(shell $(PKG_CONFIG) --libs libpcre)
++PG_CPPFLAGS += $(shell $(PKG_CONFIG) --cflags-only-I libpcre2-8)
++SHLIB_LINK += $(shell $(PKG_CONFIG) --libs libpcre2-8)
+ REGRESS = init test unicode
+ REGRESS_OPTS = --inputdir=test
+diff --git a/pgpcre.c b/pgpcre.c
+index 97d3b98..79dab5e 100644
+--- a/pgpcre.c
++++ b/pgpcre.c
+@@ -5,7 +5,8 @@
+ #include <utils/array.h>
+ #include <utils/builtins.h>
+-#include <pcre.h>
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ PG_MODULE_MAGIC;
+@@ -57,19 +58,19 @@ Datum
+ pcre_in(PG_FUNCTION_ARGS)
+ {
+       char       *input_string = PG_GETARG_CSTRING(0);
+-      pcre       *pc;
+-      const char *err;
+-      int                     erroffset;
+-      size_t          in_strlen;
+-      int                     rc, total_len, pcsize;
++      pcre2_code *pc;
++      int         err;
++      PCRE2_SIZE              erroffset;
++      size_t          in_strlen, pcsize;
++      int                     rc, total_len;
+       pgpcre     *result;
+       in_strlen = strlen(input_string);
+       if (GetDatabaseEncoding() == PG_UTF8)
+-              pc = pcre_compile(input_string, PCRE_UTF8 | PCRE_UCP, &err, &erroffset, NULL);
++              pc = pcre2_compile((PCRE2_SPTR) input_string, in_strlen, PCRE2_UTF | PCRE2_UCP, &err, &erroffset, NULL);
+       else if (GetDatabaseEncoding() == PG_SQL_ASCII)
+-              pc = pcre_compile(input_string, 0, &err, &erroffset, NULL);
++              pc = pcre2_compile((PCRE2_SPTR) input_string, in_strlen, 0, &err, &erroffset, NULL);
+       else
+       {
+               char *utf8string;
+@@ -78,22 +79,27 @@ pcre_in(PG_FUNCTION_ARGS)
+                                                                                                               in_strlen,
+                                                                                                               GetDatabaseEncoding(),
+                                                                                                               PG_UTF8);
+-              pc = pcre_compile(utf8string, PCRE_UTF8 | PCRE_UCP, &err, &erroffset, NULL);
++              pc = pcre2_compile((PCRE2_SPTR) utf8string, strlen(utf8string), PCRE2_UTF | PCRE2_UCP, &err, &erroffset, NULL);
+               if (utf8string != input_string)
+                       pfree(utf8string);
+       }
+       if (!pc)
+-              elog(ERROR, "PCRE compile error: %s", err);
++      {
++              PCRE2_UCHAR buf[120];
++
++              pcre2_get_error_message(err, buf, sizeof(buf));
++              elog(ERROR, "PCRE compile error: %s", buf);
++        }
+-      rc = pcre_fullinfo(pc, NULL, PCRE_INFO_SIZE, &pcsize);
++      rc = pcre2_pattern_info(pc, PCRE2_INFO_SIZE, &pcsize);
+       if (rc < 0)
+-              elog(ERROR, "pcre_fullinfo/PCRE_INFO_SIZE: %d", rc);
++              elog(ERROR, "pcre2_pattern_info/PCRE2_INFO_SIZE: %d", rc);
+       total_len = offsetof(pgpcre, data) + in_strlen + 1 + pcsize;
+       result = (pgpcre *) palloc0(total_len);
+       SET_VARSIZE(result, total_len);
+-      result->pcre_major = PCRE_MAJOR;
+-      result->pcre_minor = PCRE_MINOR;
++      result->pcre_major = PCRE2_MAJOR;
++      result->pcre_minor = PCRE2_MINOR;
+       result->pattern_strlen = in_strlen;
+       strcpy(result->data, input_string);
+       memcpy(result->data + in_strlen + 1, pc, pcsize);
+@@ -114,50 +120,48 @@ pcre_out(PG_FUNCTION_ARGS)
+ static bool
+ matches_internal(text *subject, pgpcre *pattern, char ***return_matches, int *num_captured)
+ {
+-      pcre       *pc;
++      pcre2_code         *pc;
++      pcre2_match_data   *md;
+       int                     rc;
+-      int                     num_substrings = 0;
+-      int                *ovector;
++      uint32_t                num_substrings = 0;
++      PCRE2_SIZE         *ovector;
+       int                     ovecsize;
+       char       *utf8string;
+       static bool warned = false;
+-      if (!warned && (pattern->pcre_major != PCRE_MAJOR || pattern->pcre_minor != PCRE_MINOR))
++      if (!warned && (pattern->pcre_major != PCRE2_MAJOR || pattern->pcre_minor != PCRE2_MINOR))
+       {
+               ereport(WARNING,
+                               (errmsg("PCRE version mismatch"),
+                                errdetail("The compiled pattern was created by PCRE version %d.%d, the current library is version %d.%d.  According to the PCRE documentation, \"compiling a regular expression with one version of PCRE for use with a different version is not guaranteed to work and may cause crashes.\"  This warning is shown only once per session.",
+                                                  pattern->pcre_major, pattern->pcre_minor,
+-                                                 PCRE_MAJOR, PCRE_MINOR),
++                                                 PCRE2_MAJOR, PCRE2_MINOR),
+                                errhint("You might want to recompile the stored patterns by running something like UPDATE ... SET pcre_col = pcre_col::text::pcre.")));
+               warned = true;
+       }
+-      pc = (pcre *) (pattern->data + pattern->pattern_strlen + 1);
++      pc = (pcre2_code *) (pattern->data + pattern->pattern_strlen + 1);
+       if (num_captured)
+       {
+-              int rc;
+-
+-              if ((rc = pcre_fullinfo(pc, NULL, PCRE_INFO_CAPTURECOUNT, &num_substrings)) != 0)
+-                      elog(ERROR, "pcre_fullinfo error: %d", rc);
++              if ((rc = pcre2_pattern_info(pc, PCRE2_INFO_CAPTURECOUNT, &num_substrings)) != 0)
++                      elog(ERROR, "pcre2_pattern_info error: %d", rc);
+       }
+       if (return_matches)
+       {
+               ovecsize = (num_substrings + 1) * 3;
+-              ovector = palloc(ovecsize * sizeof(*ovector));
++              md = pcre2_match_data_create(ovecsize, NULL);
+       }
+       else
+       {
+-              ovecsize = 0;
+-              ovector = NULL;
++              md = pcre2_match_data_create_from_pattern(pc, NULL);
+       }
+       if (GetDatabaseEncoding() == PG_UTF8 || GetDatabaseEncoding() == PG_SQL_ASCII)
+       {
+               utf8string = VARDATA_ANY(subject);
+-              rc = pcre_exec(pc, NULL, VARDATA_ANY(subject), VARSIZE_ANY_EXHDR(subject), 0, 0, ovector, ovecsize);
++              rc = pcre2_match(pc, (PCRE2_SPTR) VARDATA_ANY(subject), VARSIZE_ANY_EXHDR(subject), 0, 0, md, NULL);
+       }
+       else
+       {
+@@ -165,13 +169,16 @@ matches_internal(text *subject, pgpcre *pattern, char ***return_matches, int *nu
+                                                                                                               VARSIZE_ANY_EXHDR(subject),
+                                                                                                               GetDatabaseEncoding(),
+                                                                                                               PG_UTF8);
+-              rc = pcre_exec(pc, NULL, utf8string, strlen(utf8string), 0, 0, ovector, ovecsize);
++              rc = pcre2_match(pc, (PCRE2_SPTR) utf8string, strlen(utf8string), 0, 0, md, NULL);
+       }
+-      if (rc == PCRE_ERROR_NOMATCH)
++      if (rc == PCRE2_ERROR_NOMATCH)
++      {
++              pcre2_match_data_free(md);
+               return false;
++      }
+       else if (rc < 0)
+-              elog(ERROR, "PCRE exec error: %d", rc);
++              elog(ERROR, "PCRE match error: %d", rc);
+       if (return_matches)
+       {
+@@ -183,32 +190,37 @@ matches_internal(text *subject, pgpcre *pattern, char ***return_matches, int *nu
+                       *num_captured = num_substrings;
+                       matches = palloc(num_substrings * sizeof(*matches));
++                      ovector = pcre2_get_ovector_pointer(md);
+                       for (i = 1; i <= num_substrings; i++)
+                       {
+-                              if (ovector[i * 2] < 0)
++                              if ((int) ovector[i * 2] < 0)
+                                       matches[i - 1] = NULL;
+                               else
+                               {
+-                                      const char *xmatch;
++                                      PCRE2_UCHAR *xmatch;
++                                      PCRE2_SIZE l;
+-                                      pcre_get_substring(utf8string, ovector, rc, i, &xmatch);
++                                      pcre2_substring_get_bynumber(md, i, &xmatch, &l);
+                                       matches[i - 1] = (char *) xmatch;
+                               }
+                       }
+               }
+               else
+               {
+-                      const char *xmatch;
++                      PCRE2_UCHAR *xmatch;
++                      PCRE2_SIZE l;
+                       matches = palloc(1 * sizeof(*matches));
+-                      pcre_get_substring(utf8string, ovector, rc, 0, &xmatch);
++                      pcre2_substring_get_bynumber(md, 0, &xmatch, &l);
+                       matches[0] = (char *) xmatch;
+               }
+               *return_matches = matches;
+       }
++      pcre2_match_data_free(md);
++
+       return true;
+ }
+@@ -307,23 +319,7 @@ pcre_captured_substrings(PG_FUNCTION_ARGS)
+ }
+-static void *
+-pgpcre_malloc(size_t size)
+-{
+-      return palloc(size);
+-}
+-
+-
+-static void
+-pgpcre_free(void *ptr)
+-{
+-      pfree(ptr);
+-}
+-
+-
+ void
+ _PG_init(void)
+ {
+-      pcre_malloc = pgpcre_malloc;
+-      pcre_free = pgpcre_free;
+ }
+diff --git a/test/expected/test.out b/test/expected/test.out
+index 8d59a15..a8a173e 100644
+--- a/test/expected/test.out
++++ b/test/expected/test.out
+@@ -5,7 +5,7 @@ SELECT pcre 'fo+';
+ (1 row)
+ SELECT pcre '+';
+-ERROR:  PCRE compile error: nothing to repeat
++ERROR:  PCRE compile error: quantifier does not follow a repeatable item
+ LINE 1: SELECT pcre '+';
+                     ^
+ SELECT 'foo' =~ 'fo+';
+@@ -21,7 +21,7 @@ SELECT 'bar' =~ 'fo+';
+ (1 row)
+ SELECT 'error' =~ '+';
+-ERROR:  PCRE compile error: nothing to repeat
++ERROR:  PCRE compile error: quantifier does not follow a repeatable item
+ LINE 1: SELECT 'error' =~ '+';
+                           ^
+ SELECT 'foo' ~ pcre 'fo+';
index 7a0122b57377f02fc76b2516f607ea9065ef5a96..27d987375210b0a47fb2e0eeafbaafeb71c7f313 100644 (file)
@@ -4,11 +4,12 @@
 
 Name:          %{sname}_%{pgmajorversion}
 Version:       0.20190509
-Release:       1PGDG%{?dist}
+Release:       2PGDG%{?dist}
 Summary:       PostgreSQL extension that exposes PCRE functionality as functions and operators
 License:       GPLv2
 URL:           https://github.com/petere/%{sname}
 Source0:       https://github.com/petere/%{sname}/archive/refs/tags/%{version}.tar.gz
+Patch0:                %{sname}-pcre2.patch
 
 BuildRequires: postgresql%{pgmajorversion}-devel pcre-devel
 Requires:      postgresql%{pgmajorversion} pcre
@@ -37,6 +38,7 @@ This package provides JIT support for pgpcre
 
 %prep
 %setup -q -n %{sname}-%{version}
+%patch -P 0 -p1
 
 %build
 USE_PGXS=1 PATH=%{pginstdir}/bin:$PATH %{__make} %{?_smp_mflags}
@@ -63,5 +65,8 @@ USE_PGXS=1 PATH=%{pginstdir}/bin:$PATH %{__make} DESTDIR=%{buildroot} install
 %endif
 
 %changelog
+* Sat Jul 5 2025 Devrim Gündüz <devrim@gunduz.org> 0.20190509-2PGDG
+- Add a patch to support pcre2. Per https://github.com/petere/pgpcre/pull/9
+
 * Mon Apr 14 2025 Devrim Gündüz <devrim@gunduz.org> 0.20190509-1PGDG
 - Initial packaging for the PostgreSQL RPM repository