OmniSciDB  a5dc49c757
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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:
+ This graph shows which files directly or indirectly include this file:

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)
 
RUNTIME_EXPORT DEVICE bool string_like_simple (const char *str, const int32_t str_len, const char *pattern, const int32_t pat_len, char escape_char)
 
RUNTIME_EXPORT DEVICE bool string_ilike_simple (const char *str, const int32_t str_len, const char *pattern, const int32_t pat_len, char escape_char)
 
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)
 
RUNTIME_EXPORT DEVICE bool string_like (const char *str, const int32_t str_len, const char *pattern, const int32_t pat_len, const char escape_char)
 
RUNTIME_EXPORT DEVICE bool string_ilike (const char *str, const int32_t str_len, const char *pattern, const int32_t pat_len, const char escape_char)
 
RUNTIME_EXPORT DEVICE int32_t StringCompare (const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
 
RUNTIME_EXPORT DEVICE bool string_lt (const char *lhs, const int32_t lhs_len, const char *rhs, const int32_t rhs_len)
 
RUNTIME_EXPORT DEVICE bool string_le (const char *lhs, const int32_t lhs_len, const char *rhs, const int32_t rhs_len)
 
RUNTIME_EXPORT DEVICE bool string_gt (const char *lhs, const int32_t lhs_len, const char *rhs, const int32_t rhs_len)
 
RUNTIME_EXPORT DEVICE bool string_ge (const char *lhs, const int32_t lhs_len, const char *rhs, const int32_t rhs_len)
 
RUNTIME_EXPORT DEVICE bool string_eq (const char *lhs, const int32_t lhs_len, const char *rhs, const int32_t rhs_len)
 
RUNTIME_EXPORT 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.

Definition in file StringLike.cpp.

Macro Definition Documentation

#define STR_CMP_NULLABLE (   base_func)
Value:
extern "C" RUNTIME_EXPORT 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
#define RUNTIME_EXPORT

Definition at line 350 of file StringLike.cpp.

#define STR_LIKE_NULLABLE (   base_func)
Value:
extern "C" RUNTIME_EXPORT 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
#define RUNTIME_EXPORT

Definition at line 290 of file StringLike.cpp.

#define STR_LIKE_SIMPLE_NULLABLE (   base_func)
Value:
extern "C" RUNTIME_EXPORT DEVICE int8_t base_func##_nullable(const char* lhs, \
const int32_t lhs_len, \
const char* rhs, \
const int32_t rhs_len, \
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
#define RUNTIME_EXPORT

Definition at line 78 of file StringLike.cpp.

Enumeration Type Documentation

enum LikeStatus
Enumerator
kLIKE_TRUE 
kLIKE_FALSE 
kLIKE_ABORT 
kLIKE_ERROR 

Definition at line 26 of file StringLike.cpp.

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

Function Documentation

static DEVICE int lowercase ( char  c)
inlinestatic

Definition at line 34 of file StringLike.cpp.

Referenced by string_ilike_simple(), and string_like_match().

34  {
35  if ('A' <= c && c <= 'Z') {
36  return 'a' + (c - 'A');
37  }
38  return c;
39 }

+ Here is the caller graph for this function:

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

Definition at line 336 of file StringLike.cpp.

References StringCompare().

Referenced by StringDictionary::getCompare().

339  {
340  return StringCompare(lhs, lhs_len, rhs, rhs_len) == 0;
341 }
RUNTIME_EXPORT DEVICE int32_t StringCompare(const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
Definition: StringLike.cpp:272

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 329 of file StringLike.cpp.

References StringCompare().

332  {
333  return StringCompare(lhs, lhs_len, rhs, rhs_len) >= 0;
334 }
RUNTIME_EXPORT DEVICE int32_t StringCompare(const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
Definition: StringLike.cpp:272

+ Here is the call graph for this function:

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

Definition at line 322 of file StringLike.cpp.

References StringCompare().

325  {
326  return StringCompare(lhs, lhs_len, rhs, rhs_len) > 0;
327 }
RUNTIME_EXPORT DEVICE int32_t StringCompare(const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
Definition: StringLike.cpp:272

+ Here is the call graph for this function:

RUNTIME_EXPORT 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 261 of file StringLike.cpp.

References kLIKE_TRUE, and string_like_match().

Referenced by StringDictionaryProxy::getLike(), and StringDictionary::getLikeImpl().

265  {
266  // @TODO(wei/alex) add runtime error handling
267  LikeStatus status =
268  string_like_match(str, str_len, pattern, pat_len, escape_char, true);
269  return status == kLIKE_TRUE;
270 }
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:98
LikeStatus
Definition: StringLike.cpp:26

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 61 of file StringLike.cpp.

References lowercase().

Referenced by StringDictionaryProxy::getLike(), and StringDictionary::getLikeImpl().

65  {
66  int i, j;
67  int search_len = str_len - pat_len + 1;
68  for (i = 0; i < search_len; ++i) {
69  for (j = 0; j < pat_len && pattern[j] == lowercase(str[j + i]); ++j) {
70  }
71  if (j >= pat_len) {
72  return true;
73  }
74  }
75  return false;
76 }
static DEVICE int lowercase(char c)
Definition: StringLike.cpp:34

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 315 of file StringLike.cpp.

References StringCompare().

318  {
319  return StringCompare(lhs, lhs_len, rhs, rhs_len) <= 0;
320 }
RUNTIME_EXPORT DEVICE int32_t StringCompare(const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
Definition: StringLike.cpp:272

+ Here is the call graph for this function:

RUNTIME_EXPORT 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 250 of file StringLike.cpp.

References kLIKE_TRUE, and string_like_match().

Referenced by StringDictionaryProxy::getLike(), and StringDictionary::getLikeImpl().

254  {
255  // @TODO(wei/alex) add runtime error handling
256  LikeStatus status =
257  string_like_match(str, str_len, pattern, pat_len, escape_char, false);
258  return status == kLIKE_TRUE;
259 }
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:98
LikeStatus
Definition: StringLike.cpp:26

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 98 of file StringLike.cpp.

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

Referenced by string_ilike(), and string_like().

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 43 of file StringLike.cpp.

Referenced by StringDictionaryProxy::getLike(), and StringDictionary::getLikeImpl().

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

+ Here is the caller graph for this function:

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

Definition at line 308 of file StringLike.cpp.

References StringCompare().

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

311  {
312  return StringCompare(lhs, lhs_len, rhs, rhs_len) < 0;
313 }
RUNTIME_EXPORT DEVICE int32_t StringCompare(const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
Definition: StringLike.cpp:272

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 343 of file StringLike.cpp.

References StringCompare().

346  {
347  return StringCompare(lhs, lhs_len, rhs, rhs_len) != 0;
348 }
RUNTIME_EXPORT DEVICE int32_t StringCompare(const char *s1, const int32_t s1_len, const char *s2, const int32_t s2_len)
Definition: StringLike.cpp:272

+ Here is the call graph for this function:

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

Definition at line 272 of file StringLike.cpp.

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

275  {
276  const char* s1_ = s1;
277  const char* s2_ = s2;
278 
279  while (s1_ < s1 + s1_len && s2_ < s2 + s2_len && *s1_ == *s2_) {
280  s1_++;
281  s2_++;
282  }
283 
284  unsigned char c1 = (s1_ < s1 + s1_len) ? (*(unsigned char*)s1_) : 0;
285  unsigned char c2 = (s2_ < s2 + s2_len) ? (*(unsigned char*)s2_) : 0;
286 
287  return c1 - c2;
288 }

+ Here is the caller graph for this function: