PostgreSQL Source Code  git master
like.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "catalog/pg_collation.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "utils/fmgrprotos.h"
#include "utils/pg_locale.h"
#include "varatt.h"
#include "like_match.c"
Include dependency graph for like.c:

Go to the source code of this file.

Macros

#define LIKE_TRUE   1
 
#define LIKE_FALSE   0
 
#define LIKE_ABORT   (-1)
 
#define NextByte(p, plen)   ((p)++, (plen)--)
 
#define CHAREQ(p1, p2)   wchareq((p1), (p2))
 
#define NextChar(p, plen)    do { int __l = pg_mblen(p); (p) +=__l; (plen) -=__l; } while (0)
 
#define CopyAdvChar(dst, src, srclen)
 
#define MatchText   MB_MatchText
 
#define do_like_escape   MB_do_like_escape
 
#define CHAREQ(p1, p2)   (*(p1) == *(p2))
 
#define NextChar(p, plen)   NextByte((p), (plen))
 
#define CopyAdvChar(dst, src, srclen)   (*(dst)++ = *(src)++, (srclen)--)
 
#define MatchText   SB_MatchText
 
#define do_like_escape   SB_do_like_escape
 
#define MATCH_LOWER(t, locale)   SB_lower_char((unsigned char) (t), locale)
 
#define NextChar(p, plen)   NextByte((p), (plen))
 
#define MatchText   SB_IMatchText
 
#define NextChar(p, plen)    do { (p)++; (plen)--; } while ((plen) > 0 && (*(p) & 0xC0) == 0x80 )
 
#define MatchText   UTF8_MatchText
 

Functions

static int SB_MatchText (const char *t, int tlen, const char *p, int plen, pg_locale_t locale)
 
static textSB_do_like_escape (text *pat, text *esc)
 
static int MB_MatchText (const char *t, int tlen, const char *p, int plen, pg_locale_t locale)
 
static textMB_do_like_escape (text *pat, text *esc)
 
static int UTF8_MatchText (const char *t, int tlen, const char *p, int plen, pg_locale_t locale)
 
static int SB_IMatchText (const char *t, int tlen, const char *p, int plen, pg_locale_t locale)
 
static int GenericMatchText (const char *s, int slen, const char *p, int plen, Oid collation)
 
static int Generic_Text_IC_like (text *str, text *pat, Oid collation)
 
static int wchareq (const char *p1, const char *p2)
 
static char SB_lower_char (unsigned char c, pg_locale_t locale)
 
Datum namelike (PG_FUNCTION_ARGS)
 
Datum namenlike (PG_FUNCTION_ARGS)
 
Datum textlike (PG_FUNCTION_ARGS)
 
Datum textnlike (PG_FUNCTION_ARGS)
 
Datum bytealike (PG_FUNCTION_ARGS)
 
Datum byteanlike (PG_FUNCTION_ARGS)
 
Datum nameiclike (PG_FUNCTION_ARGS)
 
Datum nameicnlike (PG_FUNCTION_ARGS)
 
Datum texticlike (PG_FUNCTION_ARGS)
 
Datum texticnlike (PG_FUNCTION_ARGS)
 
Datum like_escape (PG_FUNCTION_ARGS)
 
Datum like_escape_bytea (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ CHAREQ [1/2]

#define CHAREQ (   p1,
  p2 
)    wchareq((p1), (p2))

Definition at line 122 of file like.c.

◆ CHAREQ [2/2]

#define CHAREQ (   p1,
  p2 
)    (*(p1) == *(p2))

Definition at line 122 of file like.c.

◆ CopyAdvChar [1/2]

#define CopyAdvChar (   dst,
  src,
  srclen 
)
Value:
do { int __l = pg_mblen(src); \
(srclen) -= __l; \
while (__l-- > 0) \
*(dst)++ = *(src)++; \
} while (0)
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1023

Definition at line 124 of file like.c.

◆ CopyAdvChar [2/2]

#define CopyAdvChar (   dst,
  src,
  srclen 
)    (*(dst)++ = *(src)++, (srclen)--)

Definition at line 124 of file like.c.

◆ do_like_escape [1/2]

#define do_like_escape   MB_do_like_escape

Definition at line 127 of file like.c.

◆ do_like_escape [2/2]

#define do_like_escape   SB_do_like_escape

Definition at line 127 of file like.c.

◆ LIKE_ABORT

#define LIKE_ABORT   (-1)

Definition at line 32 of file like.c.

◆ LIKE_FALSE

#define LIKE_FALSE   0

Definition at line 31 of file like.c.

◆ LIKE_TRUE

#define LIKE_TRUE   1

Definition at line 30 of file like.c.

◆ MATCH_LOWER

#define MATCH_LOWER (   t,
  locale 
)    SB_lower_char((unsigned char) (t), locale)

Definition at line 132 of file like.c.

◆ MatchText [1/4]

#define MatchText   MB_MatchText

Definition at line 142 of file like.c.

◆ MatchText [2/4]

#define MatchText   SB_MatchText

Definition at line 142 of file like.c.

◆ MatchText [3/4]

#define MatchText   SB_IMatchText

Definition at line 142 of file like.c.

◆ MatchText [4/4]

#define MatchText   UTF8_MatchText

Definition at line 142 of file like.c.

◆ NextByte

#define NextByte (   p,
  plen 
)    ((p)++, (plen)--)

Definition at line 103 of file like.c.

◆ NextChar [1/4]

#define NextChar (   p,
  plen 
)     do { int __l = pg_mblen(p); (p) +=__l; (plen) -=__l; } while (0)

Definition at line 140 of file like.c.

◆ NextChar [2/4]

#define NextChar (   p,
  plen 
)    NextByte((p), (plen))

Definition at line 140 of file like.c.

◆ NextChar [3/4]

#define NextChar (   p,
  plen 
)    NextByte((p), (plen))

Definition at line 140 of file like.c.

◆ NextChar [4/4]

#define NextChar (   p,
  plen 
)     do { (p)++; (plen)--; } while ((plen) > 0 && (*(p) & 0xC0) == 0x80 )

Definition at line 140 of file like.c.

Function Documentation

◆ bytealike()

Datum bytealike ( PG_FUNCTION_ARGS  )

Definition at line 318 of file like.c.

319 {
321  bytea *pat = PG_GETARG_BYTEA_PP(1);
322  bool result;
323  char *s,
324  *p;
325  int slen,
326  plen;
327 
328  s = VARDATA_ANY(str);
329  slen = VARSIZE_ANY_EXHDR(str);
330  p = VARDATA_ANY(pat);
331  plen = VARSIZE_ANY_EXHDR(pat);
332 
333  result = (SB_MatchText(s, slen, p, plen, 0) == LIKE_TRUE);
334 
335  PG_RETURN_BOOL(result);
336 }
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
const char * str
#define LIKE_TRUE
Definition: like.c:30
static int SB_MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale)
Definition: c.h:678
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317

References LIKE_TRUE, PG_GETARG_BYTEA_PP, PG_RETURN_BOOL, SB_MatchText(), str, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ byteanlike()

Datum byteanlike ( PG_FUNCTION_ARGS  )

Definition at line 339 of file like.c.

340 {
342  bytea *pat = PG_GETARG_BYTEA_PP(1);
343  bool result;
344  char *s,
345  *p;
346  int slen,
347  plen;
348 
349  s = VARDATA_ANY(str);
350  slen = VARSIZE_ANY_EXHDR(str);
351  p = VARDATA_ANY(pat);
352  plen = VARSIZE_ANY_EXHDR(pat);
353 
354  result = (SB_MatchText(s, slen, p, plen, 0) != LIKE_TRUE);
355 
356  PG_RETURN_BOOL(result);
357 }

References LIKE_TRUE, PG_GETARG_BYTEA_PP, PG_RETURN_BOOL, SB_MatchText(), str, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ Generic_Text_IC_like()

static int Generic_Text_IC_like ( text str,
text pat,
Oid  collation 
)
inlinestatic

Definition at line 169 of file like.c.

170 {
171  char *s,
172  *p;
173  int slen,
174  plen;
176 
177  if (!OidIsValid(collation))
178  {
179  /*
180  * This typically means that the parser could not resolve a conflict
181  * of implicit collations, so report it that way.
182  */
183  ereport(ERROR,
184  (errcode(ERRCODE_INDETERMINATE_COLLATION),
185  errmsg("could not determine which collation to use for ILIKE"),
186  errhint("Use the COLLATE clause to set the collation explicitly.")));
187  }
188 
189  locale = pg_newlocale_from_collation(collation);
190 
191  if (!locale->deterministic)
192  ereport(ERROR,
193  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
194  errmsg("nondeterministic collations are not supported for ILIKE")));
195 
196  /*
197  * For efficiency reasons, in the single byte case we don't call lower()
198  * on the pattern and text, but instead call SB_lower_char on each
199  * character. In the multi-byte case we don't have much choice :-(. Also,
200  * ICU does not support single-character case folding, so we go the long
201  * way.
202  */
203 
204  if (pg_database_encoding_max_length() > 1 || (locale->provider == COLLPROVIDER_ICU))
205  {
207  PointerGetDatum(pat)));
208  p = VARDATA_ANY(pat);
209  plen = VARSIZE_ANY_EXHDR(pat);
211  PointerGetDatum(str)));
212  s = VARDATA_ANY(str);
213  slen = VARSIZE_ANY_EXHDR(str);
214  if (GetDatabaseEncoding() == PG_UTF8)
215  return UTF8_MatchText(s, slen, p, plen, 0);
216  else
217  return MB_MatchText(s, slen, p, plen, 0);
218  }
219  else
220  {
221  p = VARDATA_ANY(pat);
222  plen = VARSIZE_ANY_EXHDR(pat);
223  s = VARDATA_ANY(str);
224  slen = VARSIZE_ANY_EXHDR(str);
225  return SB_IMatchText(s, slen, p, plen, locale);
226  }
227 }
#define OidIsValid(objectId)
Definition: c.h:766
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
Datum DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
Definition: fmgr.c:792
#define DatumGetTextPP(X)
Definition: fmgr.h:292
static char * locale
Definition: initdb.c:140
static int UTF8_MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale)
static int MB_MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale)
static int SB_IMatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale)
int GetDatabaseEncoding(void)
Definition: mbutils.c:1261
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1546
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:49
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition: pg_locale.c:1358
@ PG_UTF8
Definition: pg_wchar.h:232
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322

References DatumGetTextPP, DirectFunctionCall1Coll(), ereport, errcode(), errhint(), errmsg(), ERROR, GetDatabaseEncoding(), locale, lower(), MB_MatchText(), OidIsValid, pg_database_encoding_max_length(), pg_newlocale_from_collation(), PG_UTF8, PointerGetDatum(), SB_IMatchText(), str, UTF8_MatchText(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by nameiclike(), nameicnlike(), texticlike(), and texticnlike().

◆ GenericMatchText()

static int GenericMatchText ( const char *  s,
int  slen,
const char *  p,
int  plen,
Oid  collation 
)
inlinestatic

Definition at line 148 of file like.c.

149 {
150  if (collation)
151  {
153 
154  if (!locale->deterministic)
155  ereport(ERROR,
156  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
157  errmsg("nondeterministic collations are not supported for LIKE")));
158  }
159 
161  return SB_MatchText(s, slen, p, plen, 0);
162  else if (GetDatabaseEncoding() == PG_UTF8)
163  return UTF8_MatchText(s, slen, p, plen, 0);
164  else
165  return MB_MatchText(s, slen, p, plen, 0);
166 }

References ereport, errcode(), errmsg(), ERROR, GetDatabaseEncoding(), locale, MB_MatchText(), pg_database_encoding_max_length(), pg_newlocale_from_collation(), PG_UTF8, SB_MatchText(), and UTF8_MatchText().

Referenced by namelike(), namenlike(), textlike(), and textnlike().

◆ like_escape()

Datum like_escape ( PG_FUNCTION_ARGS  )

Definition at line 422 of file like.c.

423 {
424  text *pat = PG_GETARG_TEXT_PP(0);
425  text *esc = PG_GETARG_TEXT_PP(1);
426  text *result;
427 
429  result = SB_do_like_escape(pat, esc);
430  else
431  result = MB_do_like_escape(pat, esc);
432 
433  PG_RETURN_TEXT_P(result);
434 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
static text * SB_do_like_escape(text *pat, text *esc)
static text * MB_do_like_escape(text *pat, text *esc)

References MB_do_like_escape(), pg_database_encoding_max_length(), PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, and SB_do_like_escape().

◆ like_escape_bytea()

Datum like_escape_bytea ( PG_FUNCTION_ARGS  )

Definition at line 441 of file like.c.

442 {
443  bytea *pat = PG_GETARG_BYTEA_PP(0);
444  bytea *esc = PG_GETARG_BYTEA_PP(1);
445  bytea *result = SB_do_like_escape((text *) pat, (text *) esc);
446 
447  PG_RETURN_BYTEA_P((bytea *) result);
448 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371

References PG_GETARG_BYTEA_PP, PG_RETURN_BYTEA_P, and SB_do_like_escape().

◆ MB_do_like_escape()

static text* MB_do_like_escape ( text pat,
text esc 
)
static

Referenced by like_escape().

◆ MB_MatchText()

static int MB_MatchText ( const char *  t,
int  tlen,
const char *  p,
int  plen,
pg_locale_t  locale 
)
static

◆ nameiclike()

Datum nameiclike ( PG_FUNCTION_ARGS  )

Definition at line 364 of file like.c.

365 {
366  Name str = PG_GETARG_NAME(0);
367  text *pat = PG_GETARG_TEXT_PP(1);
368  bool result;
369  text *strtext;
370 
372  NameGetDatum(str)));
373  result = (Generic_Text_IC_like(strtext, pat, PG_GET_COLLATION()) == LIKE_TRUE);
374 
375  PG_RETURN_BOOL(result);
376 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:641
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278
#define PG_GET_COLLATION()
Definition: fmgr.h:198
static int Generic_Text_IC_like(text *str, text *pat, Oid collation)
Definition: like.c:169
static Datum NameGetDatum(const NameData *X)
Definition: postgres.h:373
Definition: c.h:732
Datum name_text(PG_FUNCTION_ARGS)
Definition: varlena.c:3357

References DatumGetTextPP, DirectFunctionCall1, Generic_Text_IC_like(), LIKE_TRUE, name_text(), NameGetDatum(), PG_GET_COLLATION, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and str.

◆ nameicnlike()

Datum nameicnlike ( PG_FUNCTION_ARGS  )

Definition at line 379 of file like.c.

380 {
381  Name str = PG_GETARG_NAME(0);
382  text *pat = PG_GETARG_TEXT_PP(1);
383  bool result;
384  text *strtext;
385 
387  NameGetDatum(str)));
388  result = (Generic_Text_IC_like(strtext, pat, PG_GET_COLLATION()) != LIKE_TRUE);
389 
390  PG_RETURN_BOOL(result);
391 }

References DatumGetTextPP, DirectFunctionCall1, Generic_Text_IC_like(), LIKE_TRUE, name_text(), NameGetDatum(), PG_GET_COLLATION, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and str.

◆ namelike()

Datum namelike ( PG_FUNCTION_ARGS  )

Definition at line 234 of file like.c.

235 {
236  Name str = PG_GETARG_NAME(0);
237  text *pat = PG_GETARG_TEXT_PP(1);
238  bool result;
239  char *s,
240  *p;
241  int slen,
242  plen;
243 
244  s = NameStr(*str);
245  slen = strlen(s);
246  p = VARDATA_ANY(pat);
247  plen = VARSIZE_ANY_EXHDR(pat);
248 
249  result = (GenericMatchText(s, slen, p, plen, PG_GET_COLLATION()) == LIKE_TRUE);
250 
251  PG_RETURN_BOOL(result);
252 }
#define NameStr(name)
Definition: c.h:737
static int GenericMatchText(const char *s, int slen, const char *p, int plen, Oid collation)
Definition: like.c:148

References GenericMatchText(), LIKE_TRUE, NameStr, PG_GET_COLLATION, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, str, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ namenlike()

Datum namenlike ( PG_FUNCTION_ARGS  )

Definition at line 255 of file like.c.

256 {
257  Name str = PG_GETARG_NAME(0);
258  text *pat = PG_GETARG_TEXT_PP(1);
259  bool result;
260  char *s,
261  *p;
262  int slen,
263  plen;
264 
265  s = NameStr(*str);
266  slen = strlen(s);
267  p = VARDATA_ANY(pat);
268  plen = VARSIZE_ANY_EXHDR(pat);
269 
270  result = (GenericMatchText(s, slen, p, plen, PG_GET_COLLATION()) != LIKE_TRUE);
271 
272  PG_RETURN_BOOL(result);
273 }

References GenericMatchText(), LIKE_TRUE, NameStr, PG_GET_COLLATION, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, str, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ SB_do_like_escape()

static text* SB_do_like_escape ( text pat,
text esc 
)
static

Referenced by like_escape(), and like_escape_bytea().

◆ SB_IMatchText()

static int SB_IMatchText ( const char *  t,
int  tlen,
const char *  p,
int  plen,
pg_locale_t  locale 
)
static

Referenced by Generic_Text_IC_like().

◆ SB_lower_char()

static char SB_lower_char ( unsigned char  c,
pg_locale_t  locale 
)
static

Definition at line 94 of file like.c.

95 {
96  if (locale->ctype_is_c)
97  return pg_ascii_tolower(c);
98  else
99  return tolower_l(c, locale->info.lt);
100 }
unsigned char pg_ascii_tolower(unsigned char ch)
Definition: pgstrcasecmp.c:146
char * c
#define tolower_l
Definition: win32_port.h:443

References locale, pg_ascii_tolower(), and tolower_l.

◆ SB_MatchText()

static int SB_MatchText ( const char *  t,
int  tlen,
const char *  p,
int  plen,
pg_locale_t  locale 
)
static

◆ texticlike()

Datum texticlike ( PG_FUNCTION_ARGS  )

Definition at line 394 of file like.c.

395 {
396  text *str = PG_GETARG_TEXT_PP(0);
397  text *pat = PG_GETARG_TEXT_PP(1);
398  bool result;
399 
400  result = (Generic_Text_IC_like(str, pat, PG_GET_COLLATION()) == LIKE_TRUE);
401 
402  PG_RETURN_BOOL(result);
403 }

References Generic_Text_IC_like(), LIKE_TRUE, PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and str.

◆ texticnlike()

Datum texticnlike ( PG_FUNCTION_ARGS  )

Definition at line 406 of file like.c.

407 {
408  text *str = PG_GETARG_TEXT_PP(0);
409  text *pat = PG_GETARG_TEXT_PP(1);
410  bool result;
411 
412  result = (Generic_Text_IC_like(str, pat, PG_GET_COLLATION()) != LIKE_TRUE);
413 
414  PG_RETURN_BOOL(result);
415 }

References Generic_Text_IC_like(), LIKE_TRUE, PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and str.

◆ textlike()

Datum textlike ( PG_FUNCTION_ARGS  )

Definition at line 276 of file like.c.

277 {
278  text *str = PG_GETARG_TEXT_PP(0);
279  text *pat = PG_GETARG_TEXT_PP(1);
280  bool result;
281  char *s,
282  *p;
283  int slen,
284  plen;
285 
286  s = VARDATA_ANY(str);
287  slen = VARSIZE_ANY_EXHDR(str);
288  p = VARDATA_ANY(pat);
289  plen = VARSIZE_ANY_EXHDR(pat);
290 
291  result = (GenericMatchText(s, slen, p, plen, PG_GET_COLLATION()) == LIKE_TRUE);
292 
293  PG_RETURN_BOOL(result);
294 }

References GenericMatchText(), LIKE_TRUE, PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, str, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ textnlike()

Datum textnlike ( PG_FUNCTION_ARGS  )

Definition at line 297 of file like.c.

298 {
299  text *str = PG_GETARG_TEXT_PP(0);
300  text *pat = PG_GETARG_TEXT_PP(1);
301  bool result;
302  char *s,
303  *p;
304  int slen,
305  plen;
306 
307  s = VARDATA_ANY(str);
308  slen = VARSIZE_ANY_EXHDR(str);
309  p = VARDATA_ANY(pat);
310  plen = VARSIZE_ANY_EXHDR(pat);
311 
312  result = (GenericMatchText(s, slen, p, plen, PG_GET_COLLATION()) != LIKE_TRUE);
313 
314  PG_RETURN_BOOL(result);
315 }

References GenericMatchText(), LIKE_TRUE, PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, str, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ UTF8_MatchText()

static int UTF8_MatchText ( const char *  t,
int  tlen,
const char *  p,
int  plen,
pg_locale_t  locale 
)
static

◆ wchareq()

static int wchareq ( const char *  p1,
const char *  p2 
)
inlinestatic

Definition at line 58 of file like.c.

59 {
60  int p1_len;
61 
62  /* Optimization: quickly compare the first byte. */
63  if (*p1 != *p2)
64  return 0;
65 
66  p1_len = pg_mblen(p1);
67  if (pg_mblen(p2) != p1_len)
68  return 0;
69 
70  /* They are the same length */
71  while (p1_len--)
72  {
73  if (*p1++ != *p2++)
74  return 0;
75  }
76  return 1;
77 }

References p2, and pg_mblen().