<commit_before>/*-------------------------------------------------------------------------
 *
 * like.c
 *	  like expression handling code.
 *
 *	 NOTES
 *		A big hack of the regexp.c code!! Contributed by
 *		<NAME> <<EMAIL>> (7/95).
 *
 * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	$Header: /cvsroot/pgsql/src/backend/utils/adt/like.c,v 1.42 2000/09/15 18:45:26 tgl Exp $
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include <ctype.h>

#ifdef MULTIBYTE
#include "mb/pg_wchar.h"
#endif
#include "utils/builtins.h"


#define LIKE_TRUE						1
#define LIKE_FALSE						0
#define LIKE_ABORT						(-1)


static int MatchText(unsigned char * t, int tlen,
					 unsigned char * p, int plen);
static int MatchTextIC(unsigned char * t, int tlen,
					   unsigned char * p, int plen);


#ifdef MULTIBYTE
/*--------------------
 * Support routine for MatchText. Compares given multibyte streams
 * as wide characters. If they match, returns 1 otherwise returns 0.
 *--------------------
 */
static int wchareq(unsigned char *p1, unsigned char *p2)
{
	int l;

	l = pg_mblen(p1);
	if (pg_mblen(p2) != l) {
		return(0);
	}
	while (l--) {
		if (*p1++ != *p2++)
			return(0);
	}
	return(1);
}

/*--------------------
 * Support routine for MatchTextIC. Compares given multibyte streams
 * as wide characters ignoring case.
 * If they match, returns 1 otherwise returns 0.
 *--------------------
 */
#define UCHARMAX 0xff

static int iwchareq(unsigned char *p1, unsigned char *p2)
{
	int c1, c2;
	int l;

	/* short cut. if *p1 and *p2 is lower than UCHARMAX, then
	   we assume they are ASCII */
	if (*p1 < UCHARMAX && *p2 < UCHARMAX)
		return(tolower(*p1) == tolower(*p2));

	if (*p1 < UCHARMAX)
		c1 = tolower(*p1);
	else
	{
		l = pg_mblen(p1);
		(void)pg_mb2wchar_with_len(p1, (pg_wchar *)&c1, l);
		c1 = tolower(c1);
	}
	if (*p2 < UCHARMAX)
		c2 = tolower(*p2);
	else
	{
		l = pg_mblen(p2);
		(void)pg_mb2wchar_with_len(p2, (pg_wchar *)&c2, l);
		c2 = tolower(c2);
	}
	return(c1 == c2);
}

#endif

#ifdef MULTIBYTE
#define CHAREQ(p1, p2) wchareq(p1, p2)
#define ICHAREQ(p1, p2) iwchareq(p1, p2)
#define NextChar(p, plen) \
	do { int __l = pg_mblen(p); (p) +=__l; (plen) -=__l; } while (0)
#define CopyAdvChar(dst, src, srclen) \
	do { int __l = pg_mblen(src); \
		 (srclen) -= __l; \
		 while (__l-- > 0) \
			 *(dst)++ = *(src)++; \
	   } while (0)
#else
#define CHAREQ(p1, p2) (*(p1) == *(p2))
#define ICHAREQ(p1, p2) (tolower(*(p1)) == tolower(*(p2)))
#define NextChar(p, plen) ((p)++, (plen)--)
#define CopyAdvChar(dst, src, srclen) (*(dst)++ = *(src)++, (srclen)--)
#endif


/*
 *	interface routines called by the function manager
 */

Datum
namelike(PG_FUNCTION_ARGS)
{
	Name		str = PG_GETARG_NAME(0);<commit_msg>Fix ILIKE bug (only in multi-byte case)<commit_after>/*-------------------------------------------------------------------------
 *
 * like.c
 *	  like expression handling code.
 *
 *	 NOTES
 *		A big hack of the regexp.c code!! Contributed by
 *		<NAME> <<EMAIL>> (7/95).
 *
 * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	$Header: /cvsroot/pgsql/src/backend/utils/adt/like.c,v 1.43 2000/12/11 05:00:18 ishii Exp $
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include <ctype.h>

#ifdef MULTIBYTE
#include "mb/pg_wchar.h"
#endif
#include "utils/builtins.h"


#define LIKE_TRUE						1
#define LIKE_FALSE						0
#define LIKE_ABORT						(-1)


static int MatchText(unsigned char * t, int tlen,
					 unsigned char * p, int plen);
static int MatchTextIC(unsigned char * t, int tlen,
					   unsigned char * p, int plen);


#ifdef MULTIBYTE
/*--------------------
 * Support routine for MatchText. Compares given multibyte streams
 * as wide characters. If they match, returns 1 otherwise returns 0.
 *--------------------
 */
static int wchareq(unsigned char *p1, unsigned char *p2)
{
	int l;

	l = pg_mblen(p1);
	if (pg_mblen(p2) != l) {
		return(0);
	}
	while (l--) {
		if (*p1++ != *p2++)
			return(0);
	}
	return(1);
}

/*--------------------
 * Support routine for MatchTextIC. Compares given multibyte streams
 * as wide characters ignoring case.
 * If they match, returns 1 otherwise returns 0.
 *--------------------
 */
#define CHARMAX 0x80

static int iwchareq(unsigned char *p1, unsigned char *p2)
{
	int c1[2], c2[2];
	int l;

	/* short cut. if *p1 and *p2 is lower than CHARMAX, then
	   we could assume they are ASCII */
	if (*p1 < CHARMAX && *p2 < CHARMAX)
		return(tolower(*p1) == tolower(*p2));

	/* if one of them is an ASCII while the other is not, then
	   they must be different characters
	*/
	else if (*p1 < CHARMAX || *p2 < CHARMAX)
		return(0);

	/* ok, p1 and p2 are both > CHARMAX, then they must be multi-byte
	   characters
	*/
	l = pg_mblen(p1);
	(void)pg_mb2wchar_with_len(p1, (pg_wchar *)c1, l);
	c1[0] = tolower(c1[0]);
	l = pg_mblen(p2);
	(void)pg_mb2wchar_with_len(p2, (pg_wchar *)c2, l);
	c2[0] = tolower(c2[0]);
	return(c1[0] == c2[0]);
}

#endif

#ifdef MULTIBYTE
#define CHAREQ(p1, p2) wchareq(p1, p2)
#define ICHAREQ(p1, p2) iwchareq(p1, p2)
#define NextChar(p, plen) \
	do { int __l = pg_mblen(p); (p) +=__l; (plen) -=__l; } while (0)
#define CopyAdvChar(dst, src, srclen) \
	do { int __l = pg_mblen(src); \
		 (srclen) -= __l; \
		 while (__l-- > 0) \
			 *(dst)++ = *(src)++; \
	   } while (0)
#else
#define CHAREQ(p1, p2) (*(p1) == *(p2))
#define ICHAREQ(p1, p2) (tolower(*(p1)) == tolower(*(p2)))
#define NextChar(p, plen) ((p)++, (plen)--)
#define CopyAdvChar(dst, src, srclen) (*(dst)++ = *(src)++, (srclen)--)
#endif


/*
 *	interface routines called by the function manager
 */

Datum
namelike(PG_FUNCTION_ARGS)
{
	Name		str = PG_GETARG_NAME(0);
{'fraction_non_alphanumeric': 0.22771775827143823, 'fraction_numerical': 0.034942606347062796, 'mean_word_length': 2.5606971153846154, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '95838', 'n_tokens_mistral': 2497, 'n_tokens_neox': 2316, 'n_words': 632}