diff options
Diffstat (limited to 'src/backend/utils/adt/like.c')
-rw-r--r-- | src/backend/utils/adt/like.c | 287 |
1 files changed, 149 insertions, 138 deletions
diff --git a/src/backend/utils/adt/like.c b/src/backend/utils/adt/like.c index 50b31514b2a..a3fdbce8855 100644 --- a/src/backend/utils/adt/like.c +++ b/src/backend/utils/adt/like.c @@ -1,225 +1,236 @@ /*------------------------------------------------------------------------- * * like.c-- - * like expression handling code. + * like expression handling code. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * /usr/local/devel/pglite/cvs/src/backend/utils/adt/like.c,v 1.1 1995/07/30 23:55:36 emkxp01 Exp + * /usr/local/devel/pglite/cvs/src/backend/utils/adt/like.c,v 1.1 1995/07/30 23:55:36 emkxp01 Exp * * - * NOTES - * A big hack of the regexp.c code!! Contributed by - * Keith Parks <emkxp01@mtcc.demon.co.uk> (7/95). + * NOTES + * A big hack of the regexp.c code!! Contributed by + * Keith Parks <emkxp01@mtcc.demon.co.uk> (7/95). * * *------------------------------------------------------------------------- */ #include <string.h> -#include "postgres.h" /* postgres system include file */ +#include "postgres.h" /* postgres system include file */ #include "utils/palloc.h" -#include "utils/builtins.h" /* where the function declarations go */ +#include "utils/builtins.h" /* where the function declarations go */ -static int like(char *text, char *p); +static int like(char *text, char *p); /* - * interface routines called by the function manager + * interface routines called by the function manager */ /* fixedlen_like: a generic fixed length like routine - s - the string to match against (not necessarily null-terminated) - p - the pattern - charlen - the length of the string + s - the string to match against (not necessarily null-terminated) + p - the pattern + charlen - the length of the string */ -static bool -fixedlen_like(char *s, struct varlena* p, int charlen) +static bool +fixedlen_like(char *s, struct varlena * p, int charlen) { - char *sterm, *pterm; - int result; - - if (!s || !p) - return FALSE; - - /* be sure sterm is null-terminated */ - sterm = (char *) palloc(charlen + 1); - strNcpy(sterm, s, charlen); - - /* p is a text = varlena, not a string so we have to make - * a string from the vl_data field of the struct. */ - - /* palloc the length of the text + the null character */ - pterm = (char *) palloc(VARSIZE(p) - VARHDRSZ + 1); - memmove(pterm, VARDATA(p), VARSIZE(p) - VARHDRSZ); - *(pterm + VARSIZE(p) - VARHDRSZ) = (char)NULL; - - /* do the regexp matching */ - result = like(sterm, pterm); - - pfree(sterm); - pfree(pterm); - - return ((bool) result); + char *sterm, + *pterm; + int result; + + if (!s || !p) + return FALSE; + + /* be sure sterm is null-terminated */ + sterm = (char *) palloc(charlen + 1); + strNcpy(sterm, s, charlen); + + /* + * p is a text = varlena, not a string so we have to make a string + * from the vl_data field of the struct. + */ + + /* palloc the length of the text + the null character */ + pterm = (char *) palloc(VARSIZE(p) - VARHDRSZ + 1); + memmove(pterm, VARDATA(p), VARSIZE(p) - VARHDRSZ); + *(pterm + VARSIZE(p) - VARHDRSZ) = (char) NULL; + + /* do the regexp matching */ + result = like(sterm, pterm); + + pfree(sterm); + pfree(pterm); + + return ((bool) result); } -bool -char2like(uint16 arg1, struct varlena *p) +bool +char2like(uint16 arg1, struct varlena * p) { - char *s = (char *) &arg1; - return (fixedlen_like(s, p, 2)); -} + char *s = (char *) &arg1; -bool -char2nlike(uint16 arg1, struct varlena *p) + return (fixedlen_like(s, p, 2)); +} + +bool +char2nlike(uint16 arg1, struct varlena * p) { - return (!char2like(arg1, p)); + return (!char2like(arg1, p)); } -bool -char4like(uint32 arg1, struct varlena *p) +bool +char4like(uint32 arg1, struct varlena * p) { - char *s = (char *) &arg1; - return (fixedlen_like(s, p, 4)); + char *s = (char *) &arg1; + + return (fixedlen_like(s, p, 4)); } -bool -char4nlike(uint32 arg1, struct varlena *p) +bool +char4nlike(uint32 arg1, struct varlena * p) { - return (!char4like(arg1, p)); + return (!char4like(arg1, p)); } -bool -char8like(char *s, struct varlena *p) +bool +char8like(char *s, struct varlena * p) { - return (fixedlen_like(s, p, 8)); + return (fixedlen_like(s, p, 8)); } -bool -char8nlike(char *s, struct varlena *p) +bool +char8nlike(char *s, struct varlena * p) { - return (!char8like(s, p)); + return (!char8like(s, p)); } -bool -char16like(char *s, struct varlena *p) +bool +char16like(char *s, struct varlena * p) { - return (fixedlen_like(s, p, 16)); + return (fixedlen_like(s, p, 16)); } -bool -char16nlike(char *s, struct varlena *p) + +bool +char16nlike(char *s, struct varlena * p) { - return (!char16like(s, p)); + return (!char16like(s, p)); } -bool -namelike(NameData *n, struct varlena *p) +bool +namelike(NameData * n, struct varlena * p) { - if (!n) return FALSE; - return (fixedlen_like(n->data, p, NAMEDATALEN)); + if (!n) + return FALSE; + return (fixedlen_like(n->data, p, NAMEDATALEN)); } -bool -namenlike(NameData *s, struct varlena *p) +bool +namenlike(NameData * s, struct varlena * p) { - return (!namelike(s, p)); + return (!namelike(s, p)); } -bool -textlike(struct varlena *s, struct varlena *p) +bool +textlike(struct varlena * s, struct varlena * p) { - if (!s) return FALSE; - return (fixedlen_like(VARDATA(s), p, VARSIZE(s) - VARHDRSZ)); + if (!s) + return FALSE; + return (fixedlen_like(VARDATA(s), p, VARSIZE(s) - VARHDRSZ)); } -bool textnlike(struct varlena *s, struct varlena *p) +bool +textnlike(struct varlena * s, struct varlena * p) { - return (!textlike(s, p)); + return (!textlike(s, p)); } -/* $Revision: 1.6 $ -** "like.c" A first attempt at a LIKE operator for Postgres95. +/* $Revision: 1.7 $ +** "like.c" A first attempt at a LIKE operator for Postgres95. +** +** Originally written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986. +** Rich $alz is now <rsalz@bbn.com>. +** Special thanks to Lars Mathiesen <thorinn@diku.dk> for the LABORT code. +** +** This code was shamelessly stolen from the "pql" code by myself and +** slightly modified :) +** +** All references to the word "star" were replaced by "percent" +** All references to the word "wild" were replaced by "like" +** +** All the nice shell RE matching stuff was replaced by just "_" and "%" ** -** Originally written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986. -** Rich $alz is now <rsalz@bbn.com>. -** Special thanks to Lars Mathiesen <thorinn@diku.dk> for the LABORT code. -** -** This code was shamelessly stolen from the "pql" code by myself and -** slightly modified :) -** -** All references to the word "star" were replaced by "percent" -** All references to the word "wild" were replaced by "like" -** -** All the nice shell RE matching stuff was replaced by just "_" and "%" -** -** As I don't have a copy of the SQL standard handy I wasn't sure whether -** to leave in the '\' escape character handling. (I suspect the standard -** handles "%%" as a single literal percent) +** As I don't have a copy of the SQL standard handy I wasn't sure whether +** to leave in the '\' escape character handling. (I suspect the standard +** handles "%%" as a single literal percent) ** -** Keith Parks. <keith@mtcc.demon.co.uk> +** Keith Parks. <keith@mtcc.demon.co.uk> ** -** [SQL92 lets you specify the escape character by saying -** LIKE <pattern> ESCAPE <escape character>. We are a small operation -** so we force you to use '\'. - ay 7/95] +** [SQL92 lets you specify the escape character by saying +** LIKE <pattern> ESCAPE <escape character>. We are a small operation +** so we force you to use '\'. - ay 7/95] ** */ -#define LIKE_TRUE 1 -#define LIKE_FALSE 0 -#define LIKE_ABORT -1 +#define LIKE_TRUE 1 +#define LIKE_FALSE 0 +#define LIKE_ABORT -1 /* -** Match text and p, return LIKE_TRUE, LIKE_FALSE, or LIKE_ABORT. +** Match text and p, return LIKE_TRUE, LIKE_FALSE, or LIKE_ABORT. */ static int DoMatch(register char *text, register char *p) { - register int matched; - - for ( ; *p; text++, p++) { - if (*text == '\0' && *p != '%') - return LIKE_ABORT; - switch (*p) { - case '\\': - /* Literal match with following character. */ - p++; - /* FALLTHROUGH */ - default: - if (*text != *p) - return LIKE_FALSE; - continue; - case '_': - /* Match anything. */ - continue; - case '%': - while (*++p == '%') - /* Consecutive percents act just like one. */ - continue; - if (*p == '\0') - /* Trailing percent matches everything. */ - return LIKE_TRUE; - while (*text) - if ((matched = DoMatch(text++, p)) != LIKE_FALSE) - return matched; - return LIKE_ABORT; + register int matched; + + for (; *p; text++, p++) + { + if (*text == '\0' && *p != '%') + return LIKE_ABORT; + switch (*p) + { + case '\\': + /* Literal match with following character. */ + p++; + /* FALLTHROUGH */ + default: + if (*text != *p) + return LIKE_FALSE; + continue; + case '_': + /* Match anything. */ + continue; + case '%': + while (*++p == '%') + /* Consecutive percents act just like one. */ + continue; + if (*p == '\0') + /* Trailing percent matches everything. */ + return LIKE_TRUE; + while (*text) + if ((matched = DoMatch(text++, p)) != LIKE_FALSE) + return matched; + return LIKE_ABORT; + } } - } - return *text == '\0'; + return *text == '\0'; } /* -** User-level routine. Returns TRUE or FALSE. +** User-level routine. Returns TRUE or FALSE. */ static int like(char *text, char *p) { - if (p[0] == '%' && p[1] == '\0') - return TRUE; - return (DoMatch(text, p) == LIKE_TRUE); + if (p[0] == '%' && p[1] == '\0') + return TRUE; + return (DoMatch(text, p) == LIKE_TRUE); } |