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/elog.h" /* for logging postgres errors */
23 #include "utils/palloc.h"
24 #include "utils/builtins.h" /* where the function declarations go */
26 int like(char *text, char *p);
29 * interface routines called by the function manager
35 a generic fixed length like routine
36 s - the string to match against (not necessarily null-terminated)
38 charlen - the length of the string
41 fixedlen_like(char *s, struct varlena* p, int charlen)
49 /* be sure sterm is null-terminated */
50 sterm = (char *) palloc(charlen + 1);
51 memset(sterm, 0, charlen + 1);
52 strncpy(sterm, s, charlen);
54 /* p is a text = varlena, not a string so we have to make
55 * a string from the vl_data field of the struct. */
57 /* palloc the length of the text + the null character */
58 pterm = (char *) palloc(VARSIZE(p) - VARHDRSZ + 1);
59 memmove(pterm, VARDATA(p), VARSIZE(p) - VARHDRSZ);
60 *(pterm + VARSIZE(p) - VARHDRSZ) = (char)NULL;
62 /* do the regexp matching */
63 result = like(sterm, pterm);
68 return ((bool) result);
72 char2like(uint16 arg1, struct varlena *p)
74 char *s = (char *) &arg1;
75 return (fixedlen_like(s, p, 2));
79 char2nlike(uint16 arg1, struct varlena *p)
81 return (!char2like(arg1, p));
85 char4like(uint32 arg1, struct varlena *p)
87 char *s = (char *) &arg1;
88 return (fixedlen_like(s, p, 4));
92 char4nlike(uint32 arg1, struct varlena *p)
94 return (!char4like(arg1, p));
98 char8like(char *s, struct varlena *p)
100 return (fixedlen_like(s, p, 8));
104 char8nlike(char *s, struct varlena *p)
106 return (!char8like(s, p));
110 char16like(char *s, struct varlena *p)
112 return (fixedlen_like(s, p, 16));
115 char16nlike(char *s, struct varlena *p)
117 return (!char16like(s, p));
121 namelike(NameData *n, struct varlena *p)
123 return (fixedlen_like(n->data, p, NAMEDATALEN));
127 namenlike(NameData *s, struct varlena *p)
129 return (!namelike(s, p));
133 textlike(struct varlena *s, struct varlena *p)
135 return (fixedlen_like(VARDATA(s), p, VARSIZE(s) - VARHDRSZ));
138 bool textnlike(struct varlena *s, struct varlena *p)
140 return (!textlike(s, p));
144 /* $Revision: 1.1.1.1 $
145 ** "like.c" A first attempt at a LIKE operator for Postgres95.
147 ** Originally written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
148 ** Rich $alz is now <rsalz@bbn.com>.
149 ** Special thanks to Lars Mathiesen <thorinn@diku.dk> for the LABORT code.
151 ** This code was shamelessly stolen from the "pql" code by myself and
152 ** slightly modified :)
154 ** All references to the word "star" were replaced by "percent"
155 ** All references to the word "wild" were replaced by "like"
157 ** All the nice shell RE matching stuff was replaced by just "_" and "%"
159 ** As I don't have a copy of the SQL standard handy I wasn't sure whether
160 ** to leave in the '\' escape character handling. (I suspect the standard
161 ** handles "%%" as a single literal percent)
163 ** Keith Parks. <keith@mtcc.demon.co.uk>
165 ** [SQL92 lets you specify the escape character by saying
166 ** LIKE <pattern> ESCAPE <escape character>. We are a small operation
167 ** so we force you to use '\'. - ay 7/95]
173 #define LIKE_ABORT -1
176 ** Match text and p, return LIKE_TRUE, LIKE_FALSE, or LIKE_ABORT.
179 DoMatch(register char *text, register char *p)
181 register int matched;
183 for ( ; *p; text++, p++) {
184 if (*text == '\0' && *p != '%')
188 /* Literal match with following character. */
196 /* Match anything. */
200 /* Consecutive percents act just like one. */
203 /* Trailing percent matches everything. */
206 if ((matched = DoMatch(text++, p)) != LIKE_FALSE)
212 return *text == '\0';
217 ** User-level routine. Returns TRUE or FALSE.
220 like(char *text, char *p)
222 if (p[0] == '%' && p[1] == '\0')
224 return (DoMatch(text, p) == LIKE_TRUE);