1 /*-------------------------------------------------------------------------
4 * like expression handling code.
6 * Copyright (c) 1994, Regents of the University of California
10 * /usr/local/devel/pglite/cvs/src/backend/utils/adt/like.c,v 1.1 1995/07/30 23:55:36 emkxp01 Exp
14 * A big hack of the regexp.c code!! Contributed by
15 * Keith Parks <emkxp01@mtcc.demon.co.uk> (7/95).
18 *-------------------------------------------------------------------------
21 #include "postgres.h" /* postgres system include file */
22 #include "utils/builtins.h" /* where the function declarations go */
23 #include "mb/pg_wchar.h"
25 static int like(pg_wchar * text, pg_wchar * p);
28 * interface routines called by the function manager
34 a generic fixed length like routine
35 s - the string to match against (not necessarily null-terminated)
37 charlen - the length of the string
40 fixedlen_like(char *s, struct varlena * p, int charlen)
50 /* be sure sterm is null-terminated */
52 sterm = (pg_wchar *) palloc((charlen + 1) * sizeof(pg_wchar));
53 (void) pg_mb2wchar_with_len((unsigned char *) s, sterm, charlen);
55 sterm = (char *) palloc(charlen + 1);
56 StrNCpy(sterm, s, charlen + 1);
60 * p is a text = varlena, not a string so we have to make a string
61 * from the vl_data field of the struct.
64 /* palloc the length of the text + the null character */
65 len = VARSIZE(p) - VARHDRSZ;
67 pterm = (pg_wchar *) palloc((len + 1) * sizeof(pg_wchar));
68 (void) pg_mb2wchar_with_len((unsigned char *) VARDATA(p), pterm, len);
70 pterm = (char *) palloc(len + 1);
71 memmove(pterm, VARDATA(p), len);
72 *(pterm + len) = (char) NULL;
75 /* do the regexp matching */
76 result = like(sterm, pterm);
85 namelike(NameData *n, struct varlena * p)
89 return fixedlen_like(n->data, p, NAMEDATALEN);
93 namenlike(NameData *s, struct varlena * p)
95 return !namelike(s, p);
99 textlike(struct varlena * s, struct varlena * p)
103 return fixedlen_like(VARDATA(s), p, VARSIZE(s) - VARHDRSZ);
107 textnlike(struct varlena * s, struct varlena * p)
109 return !textlike(s, p);
114 ** "like.c" A first attempt at a LIKE operator for Postgres95.
116 ** Originally written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
117 ** Rich $alz is now <rsalz@bbn.com>.
118 ** Special thanks to Lars Mathiesen <thorinn@diku.dk> for the LABORT code.
120 ** This code was shamelessly stolen from the "pql" code by myself and
121 ** slightly modified :)
123 ** All references to the word "star" were replaced by "percent"
124 ** All references to the word "wild" were replaced by "like"
126 ** All the nice shell RE matching stuff was replaced by just "_" and "%"
128 ** As I don't have a copy of the SQL standard handy I wasn't sure whether
129 ** to leave in the '\' escape character handling. (I suspect the standard
130 ** handles "%%" as a single literal percent)
132 ** Keith Parks. <keith@mtcc.demon.co.uk>
134 ** [SQL92 lets you specify the escape character by saying
135 ** LIKE <pattern> ESCAPE <escape character>. We are a small operation
136 ** so we force you to use '\'. - ay 7/95]
142 #define LIKE_ABORT -1
145 ** Match text and p, return LIKE_TRUE, LIKE_FALSE, or LIKE_ABORT.
148 DoMatch(pg_wchar * text, pg_wchar * p)
152 for (; *p && *text; text ++, p++)
157 /* Literal match with following character. */
165 /* Match anything. */
168 /* %% is the same as % according to the SQL standard */
169 /* Advance past all %'s */
173 /* Trailing percent matches everything. */
177 /* Optimization to prevent most recursion */
179 *p == '\\' || *p == '%' || *p == '_') &&
180 (matched = DoMatch(text, p)) != LIKE_FALSE)
192 /* End of input string. Do we have matching string remaining? */
193 while (*p == '%') /* allow multiple %'s at end of pattern */
204 ** User-level routine. Returns TRUE or FALSE.
207 like(pg_wchar * text, pg_wchar * p)
209 if (p[0] == '%' && p[1] == '\0')
211 return DoMatch(text, p) == LIKE_TRUE;