diff --git a/src/backend/tsearch/regis.c b/src/backend/tsearch/regis.c index 4c35afd18d..0fe0064fd1 100644 --- a/src/backend/tsearch/regis.c +++ b/src/backend/tsearch/regis.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tsearch/regis.c,v 1.3 2008/01/01 19:45:52 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/tsearch/regis.c,v 1.4 2008/01/21 02:46:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -17,27 +17,59 @@ #include "tsearch/dicts/regis.h" #include "tsearch/ts_locale.h" -bool -RS_isRegis(const char *str) -{ - while (str && *str) - { - if (t_isalpha(str) || - t_iseq(str, '[') || - t_iseq(str, ']') || - t_iseq(str, '^')) - str += pg_mblen(str); - else - return false; - } - return true; -} - #define RS_IN_ONEOF 1 #define RS_IN_ONEOF_IN 2 #define RS_IN_NONEOF 3 #define RS_IN_WAIT 4 + +/* + * Test whether a regex is of the subset supported here. + * Keep this in sync with RS_compile! + */ +bool +RS_isRegis(const char *str) +{ + int state = RS_IN_WAIT; + const char *c = str; + + while (*c) + { + if (state == RS_IN_WAIT) + { + if (t_isalpha(c)) + /* okay */ ; + else if (t_iseq(c, '[')) + state = RS_IN_ONEOF; + else + return false; + } + else if (state == RS_IN_ONEOF) + { + if (t_iseq(c, '^')) + state = RS_IN_NONEOF; + else if (t_isalpha(c)) + state = RS_IN_ONEOF_IN; + else + return false; + } + else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF) + { + if (t_isalpha(c)) + /* okay */ ; + else if (t_iseq(c, ']')) + state = RS_IN_WAIT; + else + return false; + } + else + elog(ERROR, "internal error in RS_isRegis: state %d", state); + c += pg_mblen(c); + } + + return (state == RS_IN_WAIT); +} + static RegisNode * newRegisNode(RegisNode *prev, int len) { @@ -50,11 +82,11 @@ newRegisNode(RegisNode *prev, int len) } void -RS_compile(Regis *r, bool issuffix, char *str) +RS_compile(Regis *r, bool issuffix, const char *str) { int len = strlen(str); int state = RS_IN_WAIT; - char *c = (char *) str; + const char *c = str; RegisNode *ptr = NULL; memset(r, 0, sizeof(Regis)); @@ -83,11 +115,8 @@ RS_compile(Regis *r, bool issuffix, char *str) ptr->type = RSF_ONEOF; state = RS_IN_ONEOF; } - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION), - errmsg("invalid regis pattern: \"%s\"", - str))); + else /* shouldn't get here */ + elog(ERROR, "invalid regis pattern: \"%s\"", str); } else if (state == RS_IN_ONEOF) { @@ -102,11 +131,8 @@ RS_compile(Regis *r, bool issuffix, char *str) ptr->len = pg_mblen(c); state = RS_IN_ONEOF_IN; } - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION), - errmsg("invalid regis pattern: \"%s\"", - str))); + else /* shouldn't get here */ + elog(ERROR, "invalid regis pattern: \"%s\"", str); } else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF) { @@ -117,17 +143,17 @@ RS_compile(Regis *r, bool issuffix, char *str) } else if (t_iseq(c, ']')) state = RS_IN_WAIT; - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION), - errmsg("invalid regis pattern: \"%s\"", - str))); + else /* shouldn't get here */ + elog(ERROR, "invalid regis pattern: \"%s\"", str); } else elog(ERROR, "internal error in RS_compile: state %d", state); c += pg_mblen(c); } + if (state != RS_IN_WAIT) /* shouldn't get here */ + elog(ERROR, "invalid regis pattern: \"%s\"", str); + ptr = r->node; while (ptr) { diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c index 00f9d3c477..a2837d1683 100644 --- a/src/backend/tsearch/spell.c +++ b/src/backend/tsearch/spell.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tsearch/spell.c,v 1.10 2008/01/16 13:01:03 teodor Exp $ + * $PostgreSQL: pgsql/src/backend/tsearch/spell.c,v 1.11 2008/01/21 02:46:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -333,7 +333,7 @@ NIAddAffix(IspellDict *Conf, int flag, char flagflags, const char *mask, const c Affix->issimple = 0; Affix->isregis = 1; RS_compile(&(Affix->reg.regis), (type == FF_SUFFIX) ? true : false, - (char *) ((mask && *mask) ? mask : VoidString)); + (mask && *mask) ? mask : VoidString); } else { diff --git a/src/include/tsearch/dicts/regis.h b/src/include/tsearch/dicts/regis.h index b97ec25471..5c3c1794b8 100644 --- a/src/include/tsearch/dicts/regis.h +++ b/src/include/tsearch/dicts/regis.h @@ -6,7 +6,7 @@ * * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/include/tsearch/dicts/regis.h,v 1.4 2008/01/01 19:45:59 momjian Exp $ + * $PostgreSQL: pgsql/src/include/tsearch/dicts/regis.h,v 1.5 2008/01/21 02:46:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -40,7 +40,7 @@ typedef struct Regis bool RS_isRegis(const char *str); -void RS_compile(Regis *r, bool issuffix, char *str); +void RS_compile(Regis *r, bool issuffix, const char *str); void RS_free(Regis *r); /*returns true if matches */