From e66f9a577730c70a1ec0cd48681969e27a14b1f4 Mon Sep 17 00:00:00 2001 From: Devrim Gunduz Date: Sat, 5 Jul 2025 17:49:30 +0100 Subject: [PATCH] pgpcre: Add a patch to support pcre2. Per https://github.com/petere/pgpcre/pull/9 --- .../main/non-common/pgpcre/EL-10/Makefile | 17 ++ .../pgpcre/EL-10/pgpcre-pcre2.patch | 1 + .../main/non-common/pgpcre/EL-10/pgpcre.spec | 1 + .../non-common/pgpcre/EL-8/pgpcre-pcre2.patch | 1 + .../non-common/pgpcre/EL-9/pgpcre-pcre2.patch | 1 + .../non-common/pgpcre/F-41/pgpcre-pcre2.patch | 1 + .../non-common/pgpcre/F-42/pgpcre-pcre2.patch | 1 + .../pgpcre/SLES-15/pgpcre-pcre2.patch | 1 + .../non-common/pgpcre/main/pgpcre-pcre2.patch | 279 ++++++++++++++++++ .../main/non-common/pgpcre/main/pgpcre.spec | 7 +- 10 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 rpm/redhat/main/non-common/pgpcre/EL-10/Makefile create mode 120000 rpm/redhat/main/non-common/pgpcre/EL-10/pgpcre-pcre2.patch create mode 120000 rpm/redhat/main/non-common/pgpcre/EL-10/pgpcre.spec create mode 120000 rpm/redhat/main/non-common/pgpcre/EL-8/pgpcre-pcre2.patch create mode 120000 rpm/redhat/main/non-common/pgpcre/EL-9/pgpcre-pcre2.patch create mode 120000 rpm/redhat/main/non-common/pgpcre/F-41/pgpcre-pcre2.patch create mode 120000 rpm/redhat/main/non-common/pgpcre/F-42/pgpcre-pcre2.patch create mode 120000 rpm/redhat/main/non-common/pgpcre/SLES-15/pgpcre-pcre2.patch create mode 100644 rpm/redhat/main/non-common/pgpcre/main/pgpcre-pcre2.patch 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 index 000000000..de3d7becf --- /dev/null +++ b/rpm/redhat/main/non-common/pgpcre/EL-10/Makefile @@ -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 index 000000000..5fa346b58 --- /dev/null +++ b/rpm/redhat/main/non-common/pgpcre/EL-10/pgpcre-pcre2.patch @@ -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 index 000000000..99bc86232 --- /dev/null +++ b/rpm/redhat/main/non-common/pgpcre/EL-10/pgpcre.spec @@ -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 index 000000000..5fa346b58 --- /dev/null +++ b/rpm/redhat/main/non-common/pgpcre/EL-8/pgpcre-pcre2.patch @@ -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 index 000000000..5fa346b58 --- /dev/null +++ b/rpm/redhat/main/non-common/pgpcre/EL-9/pgpcre-pcre2.patch @@ -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 index 000000000..5fa346b58 --- /dev/null +++ b/rpm/redhat/main/non-common/pgpcre/F-41/pgpcre-pcre2.patch @@ -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 index 000000000..5fa346b58 --- /dev/null +++ b/rpm/redhat/main/non-common/pgpcre/F-42/pgpcre-pcre2.patch @@ -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 index 000000000..5fa346b58 --- /dev/null +++ b/rpm/redhat/main/non-common/pgpcre/SLES-15/pgpcre-pcre2.patch @@ -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 index 000000000..6e72b886b --- /dev/null +++ b/rpm/redhat/main/non-common/pgpcre/main/pgpcre-pcre2.patch @@ -0,0 +1,279 @@ +From bf69a7118e05958fe1d174847b1ea083a6ce37b1 Mon Sep 17 00:00:00 2001 +From: Yavor Doganov +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 + #include + +-#include ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include + + 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+'; diff --git a/rpm/redhat/main/non-common/pgpcre/main/pgpcre.spec b/rpm/redhat/main/non-common/pgpcre/main/pgpcre.spec index 7a0122b57..27d987375 100644 --- a/rpm/redhat/main/non-common/pgpcre/main/pgpcre.spec +++ b/rpm/redhat/main/non-common/pgpcre/main/pgpcre.spec @@ -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 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 0.20190509-1PGDG - Initial packaging for the PostgreSQL RPM repository -- 2.39.5