OmniSciDB  c07336695a
StringLike.cpp File Reference

Functions to support the LIKE and ILIKE operator in SQL. Only single-byte character set is supported for now. More...

#include "StringLike.h"
+ Include dependency graph for StringLike.cpp:

Go to the source code of this file.

Macros

#define STR_LIKE_SIMPLE_NULLABLE(base_func)
 
#define STR_LIKE_NULLABLE(base_func)
 
#define STR_CMP_NULLABLE(base_func)
 

Enumerations

enum  LikeStatus { kLIKE_TRUE, kLIKE_FALSE, kLIKE_ABORT, kLIKE_ERROR }
 

Functions

static DEVICE int lowercase (char c)
 
DEVICE bool string_like_simple (const char *str, const int32_t str_len, const char *pattern, const int32_t pat_len)
 
DEVICE bool string_ilike_simple (const char *str, const int32_t str_len, const char *pattern, const int32_t pat_len)
 
static DEVICE LikeStatus string_like_match (const char *str, const int32_t str_len, const char *pattern, const int32_t pat_len, const char escape_char, const bool is_ilike)
 
DEVICE bool string_like (const char *str, const int32_t str_len, const char *pattern, const int32_t pat_len, const char escape_char)
 
DEVICE bool string_ilike (const char *str, const int32_t str_len, const char *pattern, const int32_t pat_len, const char escape_char)
 
DEVICE int32_t StringCompare (const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
 
DEVICE bool string_lt (const char *lhs, const int32_t lhs_len, const char *rhs, const int32_t rhs_len)
 
DEVICE bool string_le (const char *lhs, const int32_t lhs_len, const char *rhs, const int32_t rhs_len)
 
DEVICE bool string_gt (const char *lhs, const int32_t lhs_len, const char *rhs, const int32_t rhs_len)
 
DEVICE bool string_ge (const char *lhs, const int32_t lhs_len, const char *rhs, const int32_t rhs_len)
 
DEVICE bool string_eq (const char *lhs, const int32_t lhs_len, const char *rhs, const int32_t rhs_len)
 
DEVICE bool string_ne (const char *lhs, const int32_t lhs_len, const char *rhs, const int32_t rhs_len)
 

Detailed Description

Functions to support the LIKE and ILIKE operator in SQL. Only single-byte character set is supported for now.

Author
Wei Hong wei@m.nosp@m.apd..nosp@m.com Copyright (c) 2014 MapD Technologies, Inc. All rights reserved.

Definition in file StringLike.cpp.

Macro Definition Documentation

◆ STR_CMP_NULLABLE

#define STR_CMP_NULLABLE (   base_func)
Value:
extern "C" DEVICE int8_t base_func##_nullable(const char* lhs, \
const int32_t lhs_len, \
const char* rhs, \
const int32_t rhs_len, \
const int8_t bool_null) { \
if (!lhs || !rhs) { \
return bool_null; \
} \
return base_func(lhs, lhs_len, rhs, rhs_len) ? 1 : 0; \
}
#define DEVICE

Definition at line 346 of file StringLike.cpp.

◆ STR_LIKE_NULLABLE

#define STR_LIKE_NULLABLE (   base_func)
Value:
extern "C" DEVICE int8_t base_func##_nullable(const char* lhs, \
const int32_t lhs_len, \
const char* rhs, \
const int32_t rhs_len, \
const char escape_char, \
const int8_t bool_null) { \
if (!lhs || !rhs) { \
return bool_null; \
} \
return base_func(lhs, lhs_len, rhs, rhs_len, escape_char) ? 1 : 0; \
}
#define DEVICE

Definition at line 286 of file StringLike.cpp.

◆ STR_LIKE_SIMPLE_NULLABLE

#define STR_LIKE_SIMPLE_NULLABLE (   base_func)
Value:
extern "C" DEVICE int8_t base_func##_nullable(const char* lhs, \
const int32_t lhs_len, \
const char* rhs, \
const int32_t rhs_len, \
const int8_t bool_null) { \
if (!lhs || !rhs) { \
return bool_null; \
} \
return base_func(lhs, lhs_len, rhs, rhs_len) ? 1 : 0; \
}
#define DEVICE

Definition at line 75 of file StringLike.cpp.

Enumeration Type Documentation

◆ LikeStatus

enum LikeStatus
Enumerator
kLIKE_TRUE 
kLIKE_FALSE 
kLIKE_ABORT 
kLIKE_ERROR 

Definition at line 28 of file StringLike.cpp.

28  {
29  kLIKE_TRUE,
31  kLIKE_ABORT, // means we run out of string characters to match against pattern, can
32  // abort early
33  kLIKE_ERROR // error condition
34 };

Function Documentation

◆ lowercase()

static DEVICE int lowercase ( char  c)
inlinestatic

Definition at line 36 of file StringLike.cpp.

References anonymous_namespace{ExecuteTest.cpp}::c().

Referenced by string_ilike_simple(), and string_like_match().

36  {
37  if ('A' <= c && c <= 'Z') {
38  return 'a' + (c - 'A');
39  }
40  return c;
41 }
void c(const std::string &query_string, const ExecutorDeviceType device_type)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ string_eq()

DEVICE bool string_eq ( const char *  lhs,
const int32_t  lhs_len,
const char *  rhs,
const int32_t  rhs_len 
)

Definition at line 332 of file StringLike.cpp.

References StringCompare().

Referenced by StringDictionary::getCompare().

335  {
336  return StringCompare(lhs, lhs_len, rhs, rhs_len) == 0;
337 }
DEVICE int32_t StringCompare(const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
Definition: StringLike.cpp:268
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ string_ge()

DEVICE bool string_ge ( const char *  lhs,
const int32_t  lhs_len,
const char *  rhs,
const int32_t  rhs_len 
)

Definition at line 325 of file StringLike.cpp.

References StringCompare().

328  {
329  return StringCompare(lhs, lhs_len, rhs, rhs_len) >= 0;
330 }
DEVICE int32_t StringCompare(const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
Definition: StringLike.cpp:268
+ Here is the call graph for this function:

◆ string_gt()

DEVICE bool string_gt ( const char *  lhs,
const int32_t  lhs_len,
const char *  rhs,
const int32_t  rhs_len 
)

Definition at line 318 of file StringLike.cpp.

References StringCompare().

321  {
322  return StringCompare(lhs, lhs_len, rhs, rhs_len) > 0;
323 }
DEVICE int32_t StringCompare(const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
Definition: StringLike.cpp:268
+ Here is the call graph for this function:

◆ string_ilike()

DEVICE bool string_ilike ( const char *  str,
const int32_t  str_len,
const char *  pattern,
const int32_t  pat_len,
const char  escape_char 
)

Definition at line 257 of file StringLike.cpp.

References kLIKE_TRUE, and string_like_match().

Referenced by anonymous_namespace{StringDictionaryProxy.cpp}::is_like(), anonymous_namespace{StringDictionary.cpp}::is_like(), and TEST().

261  {
262  // @TODO(wei/alex) add runtime error handling
263  LikeStatus status =
264  string_like_match(str, str_len, pattern, pat_len, escape_char, true);
265  return status == kLIKE_TRUE;
266 }
static DEVICE LikeStatus string_like_match(const char *str, const int32_t str_len, const char *pattern, const int32_t pat_len, const char escape_char, const bool is_ilike)
Definition: StringLike.cpp:94
LikeStatus
Definition: StringLike.cpp:28
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ string_ilike_simple()

DEVICE bool string_ilike_simple ( const char *  str,
const int32_t  str_len,
const char *  pattern,
const int32_t  pat_len 
)

Definition at line 59 of file StringLike.cpp.

References lowercase().

Referenced by anonymous_namespace{StringDictionaryProxy.cpp}::is_like(), and anonymous_namespace{StringDictionary.cpp}::is_like().

62  {
63  int i, j;
64  int search_len = str_len - pat_len + 1;
65  for (i = 0; i < search_len; ++i) {
66  for (j = 0; j < pat_len && pattern[j] == lowercase(str[j + i]); ++j) {
67  }
68  if (j >= pat_len) {
69  return true;
70  }
71  }
72  return false;
73 }
static DEVICE int lowercase(char c)
Definition: StringLike.cpp:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ string_le()

DEVICE bool string_le ( const char *  lhs,
const int32_t  lhs_len,
const char *  rhs,
const int32_t  rhs_len 
)

Definition at line 311 of file StringLike.cpp.

References StringCompare().

314  {
315  return StringCompare(lhs, lhs_len, rhs, rhs_len) <= 0;
316 }
DEVICE int32_t StringCompare(const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
Definition: StringLike.cpp:268
+ Here is the call graph for this function:

◆ string_like()

DEVICE bool string_like ( const char *  str,
const int32_t  str_len,
const char *  pattern,
const int32_t  pat_len,
const char  escape_char 
)

Definition at line 246 of file StringLike.cpp.

References kLIKE_TRUE, and string_like_match().

Referenced by anonymous_namespace{StringDictionaryProxy.cpp}::is_like(), anonymous_namespace{StringDictionary.cpp}::is_like(), and TEST().

250  {
251  // @TODO(wei/alex) add runtime error handling
252  LikeStatus status =
253  string_like_match(str, str_len, pattern, pat_len, escape_char, false);
254  return status == kLIKE_TRUE;
255 }
static DEVICE LikeStatus string_like_match(const char *str, const int32_t str_len, const char *pattern, const int32_t pat_len, const char escape_char, const bool is_ilike)
Definition: StringLike.cpp:94
LikeStatus
Definition: StringLike.cpp:28
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ string_like_match()

static DEVICE LikeStatus string_like_match ( const char *  str,
const int32_t  str_len,
const char *  pattern,
const int32_t  pat_len,
const char  escape_char,
const bool  is_ilike 
)
static

Definition at line 94 of file StringLike.cpp.

References kLIKE_ABORT, kLIKE_ERROR, kLIKE_FALSE, kLIKE_TRUE, and lowercase().

Referenced by string_ilike(), and string_like().

99  {
100  const char* s = str;
101  int slen = str_len;
102  const char* p = pattern;
103  int plen = pat_len;
104 
105  while (slen > 0 && plen > 0) {
106  if (*p == escape_char) {
107  // next pattern char must match literally, whatever it is
108  p++;
109  plen--;
110  if (plen <= 0) {
111  return kLIKE_ERROR;
112  }
113  if ((!is_ilike && *s != *p) || (is_ilike && lowercase(*s) != *p)) {
114  return kLIKE_FALSE;
115  }
116  } else if (*p == '%') {
117  char firstpat;
118  p++;
119  plen--;
120  while (plen > 0) {
121  if (*p == '%') {
122  p++;
123  plen--;
124  } else if (*p == '_') {
125  if (slen <= 0) {
126  return kLIKE_ABORT;
127  }
128  s++;
129  slen--;
130  p++;
131  plen--;
132  } else {
133  break;
134  }
135  }
136  if (plen <= 0) {
137  return kLIKE_TRUE;
138  }
139  if (*p == escape_char) {
140  if (plen < 2) {
141  return kLIKE_ERROR;
142  }
143  firstpat = p[1];
144  } else {
145  firstpat = *p;
146  }
147 
148  while (slen > 0) {
149  bool match = false;
150  if (firstpat == '[' && *p != escape_char) {
151  const char* pp = p + 1;
152  int pplen = plen - 1;
153  while (pplen > 0 && *pp != ']') {
154  if ((!is_ilike && *s == *pp) || (is_ilike && lowercase(*s) == *pp)) {
155  match = true;
156  break;
157  }
158  pp++;
159  pplen--;
160  }
161  if (pplen <= 0) {
162  return kLIKE_ERROR; // malformed
163  }
164  } else if ((!is_ilike && *s == firstpat) ||
165  (is_ilike && lowercase(*s) == firstpat)) {
166  match = true;
167  }
168  if (match) {
169  LikeStatus status = string_like_match(s, slen, p, plen, escape_char, is_ilike);
170  if (status != kLIKE_FALSE) {
171  return status;
172  }
173  }
174  s++;
175  slen--;
176  }
177  return kLIKE_ABORT;
178  } else if (*p == '_') {
179  s++;
180  slen--;
181  p++;
182  plen--;
183  continue;
184  } else if (*p == '[') {
185  const char* pp = p + 1;
186  int pplen = plen - 1;
187  bool match = false;
188  while (pplen > 0 && *pp != ']') {
189  if ((!is_ilike && *s == *pp) || (is_ilike && lowercase(*s) == *pp)) {
190  match = true;
191  break;
192  }
193  pp++;
194  pplen--;
195  }
196  if (match) {
197  s++;
198  slen--;
199  pplen--;
200  const char* x;
201  for (x = pp + 1; *x != ']' && pplen > 0; x++, pplen--) {
202  ;
203  }
204  if (pplen <= 0) {
205  return kLIKE_ERROR; // malformed
206  }
207  plen -= (x - p + 1);
208  p = x + 1;
209  continue;
210  } else {
211  return kLIKE_FALSE;
212  }
213  } else if ((!is_ilike && *s != *p) || (is_ilike && lowercase(*s) != *p)) {
214  return kLIKE_FALSE;
215  }
216  s++;
217  slen--;
218  p++;
219  plen--;
220  }
221  if (slen > 0) {
222  return kLIKE_FALSE;
223  }
224  while (plen > 0 && *p == '%') {
225  p++;
226  plen--;
227  }
228  if (plen <= 0) {
229  return kLIKE_TRUE;
230  }
231  return kLIKE_ABORT;
232 }
static DEVICE LikeStatus string_like_match(const char *str, const int32_t str_len, const char *pattern, const int32_t pat_len, const char escape_char, const bool is_ilike)
Definition: StringLike.cpp:94
static DEVICE int lowercase(char c)
Definition: StringLike.cpp:36
LikeStatus
Definition: StringLike.cpp:28
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ string_like_simple()

DEVICE bool string_like_simple ( const char *  str,
const int32_t  str_len,
const char *  pattern,
const int32_t  pat_len 
)

Definition at line 43 of file StringLike.cpp.

Referenced by anonymous_namespace{StringDictionaryProxy.cpp}::is_like(), and anonymous_namespace{StringDictionary.cpp}::is_like().

46  {
47  int i, j;
48  int search_len = str_len - pat_len + 1;
49  for (i = 0; i < search_len; ++i) {
50  for (j = 0; j < pat_len && pattern[j] == str[j + i]; ++j) {
51  }
52  if (j >= pat_len) {
53  return true;
54  }
55  }
56  return false;
57 }
+ Here is the caller graph for this function:

◆ string_lt()

DEVICE bool string_lt ( const char *  lhs,
const int32_t  lhs_len,
const char *  rhs,
const int32_t  rhs_len 
)

Definition at line 304 of file StringLike.cpp.

References StringCompare().

Referenced by StringDictionary::getCompare(), StringDictionary::mergeSortedCache(), and StringDictionary::sortCache().

307  {
308  return StringCompare(lhs, lhs_len, rhs, rhs_len) < 0;
309 }
DEVICE int32_t StringCompare(const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
Definition: StringLike.cpp:268
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ string_ne()

DEVICE bool string_ne ( const char *  lhs,
const int32_t  lhs_len,
const char *  rhs,
const int32_t  rhs_len 
)

Definition at line 339 of file StringLike.cpp.

References StringCompare().

342  {
343  return StringCompare(lhs, lhs_len, rhs, rhs_len) != 0;
344 }
DEVICE int32_t StringCompare(const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
Definition: StringLike.cpp:268
+ Here is the call graph for this function:

◆ StringCompare()

DEVICE int32_t StringCompare ( const char *  s1,
const int32_t  s1_len,
const char *  s2,
const int32_t  s2_len 
)

Definition at line 268 of file StringLike.cpp.

Referenced by string_eq(), string_ge(), string_gt(), string_le(), string_lt(), and string_ne().

271  {
272  const char* s1_ = s1;
273  const char* s2_ = s2;
274 
275  while (s1_ < s1 + s1_len && s2_ < s2 + s2_len && *s1_ == *s2_) {
276  s1_++;
277  s2_++;
278  }
279 
280  unsigned char c1 = (s1_ < s1 + s1_len) ? (*(unsigned char*)s1_) : 0;
281  unsigned char c2 = (s2_ < s2 + s2_len) ? (*(unsigned char*)s2_) : 0;
282 
283  return c1 - c2;
284 }
+ Here is the caller graph for this function: