Index: src/backend/utils/adt/regexp.c =================================================================== RCS file: /home/jeremyd/local/postgres/cvsuproot/pgsql/src/backend/utils/adt/regexp.c,v retrieving revision 1.68 diff -c -r1.68 regexp.c *** src/backend/utils/adt/regexp.c 5 Jan 2007 22:19:41 -0000 1.68 --- src/backend/utils/adt/regexp.c 2 Feb 2007 02:45:32 -0000 *************** *** 29,41 **** */ #include "postgres.h" - #include "regex/regex.h" #include "utils/builtins.h" #include "utils/guc.h" /* GUC-settable flavor parameter */ ! static int regex_flavor = REG_ADVANCED; /* --- 29,41 ---- */ #include "postgres.h" #include "utils/builtins.h" #include "utils/guc.h" + #include "utils/regexp.h" /* GUC-settable flavor parameter */ ! int regex_flavor = REG_ADVANCED; /* *************** *** 90,96 **** * Pattern is given in the database encoding. We internally convert to * array of pg_wchar which is what Spencer's regex package wants. */ ! static regex_t * RE_compile_and_cache(text *text_re, int cflags) { int text_re_len = VARSIZE(text_re); --- 90,96 ---- * Pattern is given in the database encoding. We internally convert to * array of pg_wchar which is what Spencer's regex package wants. */ ! regex_t * RE_compile_and_cache(text *text_re, int cflags) { int text_re_len = VARSIZE(text_re); *************** *** 191,238 **** } /* ! * RE_compile_and_execute - compile and execute a RE * * Returns TRUE on match, FALSE on no match * ! * text_re --- the pattern, expressed as an *untoasted* TEXT object ! * dat --- the data to match against (need not be null-terminated) ! * dat_len --- the length of the data string ! * cflags --- compile options for the pattern * nmatch, pmatch --- optional return area for match details * ! * Both pattern and data are given in the database encoding. We internally ! * convert to array of pg_wchar which is what Spencer's regex package wants. */ ! static bool ! RE_compile_and_execute(text *text_re, char *dat, int dat_len, ! int cflags, int nmatch, regmatch_t *pmatch) { - pg_wchar *data; - size_t data_len; int regexec_result; - regex_t *re; char errMsg[100]; - /* Convert data string to wide characters */ - data = (pg_wchar *) palloc((dat_len + 1) * sizeof(pg_wchar)); - data_len = pg_mb2wchar_with_len(dat, data, dat_len); - - /* Compile RE */ - re = RE_compile_and_cache(text_re, cflags); - /* Perform RE match and return result */ regexec_result = pg_regexec(re, data, data_len, ! 0, NULL, /* no details */ nmatch, pmatch, 0); - pfree(data); - if (regexec_result != REG_OKAY && regexec_result != REG_NOMATCH) { /* re failed??? */ --- 191,226 ---- } /* ! * RE_wchar_execute - execute a RE * * Returns TRUE on match, FALSE on no match * ! * re --- the compiled pattern as returned by RE_compile_and_cache ! * data --- the data to match against (need not be null-terminated) ! * data_len --- the length of the data string ! * start_search -- the offset in the data to start searching * nmatch, pmatch --- optional return area for match details * ! * Data is given as array of pg_wchar which is what Spencer's regex package ! * wants. */ ! bool ! RE_wchar_execute(regex_t *re, pg_wchar *data, int data_len, size_t start_search, ! int nmatch, regmatch_t *pmatch) { int regexec_result; char errMsg[100]; /* Perform RE match and return result */ regexec_result = pg_regexec(re, data, data_len, ! start_search, NULL, /* no details */ nmatch, pmatch, 0); if (regexec_result != REG_OKAY && regexec_result != REG_NOMATCH) { /* re failed??? */ *************** *** 245,250 **** --- 233,299 ---- return (regexec_result == REG_OKAY); } + /* + * RE_execute - execute a RE + * + * Returns TRUE on match, FALSE on no match + * + * re --- the compiled pattern as returned by RE_compile_and_cache + * dat --- the data to match against (need not be null-terminated) + * dat_len --- the length of the data string + * nmatch, pmatch --- optional return area for match details + * + * Data is given in the database encoding. We internally + * convert to array of pg_wchar which is what Spencer's regex package wants. + */ + bool + RE_execute(regex_t *re, char *dat, int dat_len, + int nmatch, regmatch_t *pmatch) + { + pg_wchar *data; + size_t data_len; + bool match; + + /* Convert data string to wide characters */ + data = (pg_wchar *) palloc((dat_len + 1) * sizeof(pg_wchar)); + data_len = pg_mb2wchar_with_len(dat, data, dat_len); + + /* Perform RE match and return result */ + match = RE_wchar_execute(re, data, data_len, 0, nmatch, pmatch); + pfree(data); + return match; + } + + /* + * RE_compile_and_execute - compile and execute a RE + * + * Returns TRUE on match, FALSE on no match + * + * text_re --- the pattern, expressed as an *untoasted* TEXT object + * dat --- the data to match against (need not be null-terminated) + * dat_len --- the length of the data string + * cflags --- compile options for the pattern + * nmatch, pmatch --- optional return area for match details + * + * Both pattern and data are given in the database encoding. We internally + * convert to array of pg_wchar which is what Spencer's regex package wants. + */ + bool + RE_compile_and_execute(text *text_re, char *dat, int dat_len, + int cflags, int nmatch, regmatch_t *pmatch) + { + pg_wchar *data; + size_t data_len; + int regexec_result; + regex_t *re; + char errMsg[100]; + + /* Compile RE */ + re = RE_compile_and_cache(text_re, cflags); + + return RE_execute(re, dat, dat_len, nmatch, pmatch); + } + /* * assign_regex_flavor - GUC hook to validate and set REGEX_FLAVOR Index: src/backend/utils/adt/varlena.c =================================================================== RCS file: /home/jeremyd/local/postgres/cvsuproot/pgsql/src/backend/utils/adt/varlena.c,v retrieving revision 1.154 diff -c -r1.154 varlena.c *** src/backend/utils/adt/varlena.c 5 Jan 2007 22:19:42 -0000 1.154 --- src/backend/utils/adt/varlena.c 2 Feb 2007 02:50:31 -0000 *************** *** 23,32 **** #include "libpq/pqformat.h" #include "miscadmin.h" #include "parser/scansup.h" - #include "regex/regex.h" #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/pg_locale.h" typedef struct varlena unknown; --- 23,32 ---- #include "libpq/pqformat.h" #include "miscadmin.h" #include "parser/scansup.h" #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/pg_locale.h" + #include "utils/regexp.h" typedef struct varlena unknown; *************** *** 2355,2386 **** search_start = 0; while (search_start <= data_len) { - int regexec_result; - CHECK_FOR_INTERRUPTS(); ! regexec_result = pg_regexec(re, ! data, ! data_len, ! search_start, ! NULL, /* no details */ ! REGEXP_REPLACE_BACKREF_CNT, ! pmatch, ! 0); ! ! if (regexec_result == REG_NOMATCH) break; - if (regexec_result != REG_OKAY) - { - char errMsg[100]; - - pg_regerror(regexec_result, re, errMsg, sizeof(errMsg)); - ereport(ERROR, - (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION), - errmsg("regular expression failed: %s", errMsg))); - } - /* * Copy the text to the left of the match position. Note we are * given character not byte indexes. --- 2355,2366 ---- search_start = 0; while (search_start <= data_len) { CHECK_FOR_INTERRUPTS(); ! if (!RE_wchar_execute (re, data, data_len, search_start, ! REGEXP_REPLACE_BACKREF_CNT, pmatch)) break; /* * Copy the text to the left of the match position. Note we are * given character not byte indexes. *** ../pgsql-orig/src/include/utils/regexp.h Wed Dec 31 16:00:00 1969 --- src/include/utils/regexp.h Thu Feb 1 18:46:49 2007 *************** *** 0 **** --- 1,29 ---- + /*------------------------------------------------------------------------- + * + * regexp.h + * Header file for regexp connector code. + * + * Copyright (c) 2007, PostgreSQL Global Development Group + * + * $PostgreSQL$ + * + *------------------------------------------------------------------------- + */ + #ifndef REGEXP_H + #define REGEXP_H + + #include "regex/regex.h" + + /* regexp support routines for PostgreSQL-izing regexp code */ + extern regex_t * RE_compile_and_cache(text *text_re, int cflags); + extern bool RE_compile_and_execute(text *text_re, char *dat, int dat_len, + int cflags, int nmatch, regmatch_t *pmatch); + extern bool RE_wchar_execute(regex_t *re, pg_wchar *data, int data_len, + size_t start_search, int nmatch, regmatch_t *pmatch); + extern bool RE_execute(regex_t *re, char *dat, int dat_len, + int nmatch, regmatch_t *pmatch); + + /* regexp flavor GUC variable */ + extern int regex_flavor; + + #endif /* REGEXP_H */