OmniSciDB  ca0c39ec8f
 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)
 
RUNTIME_EXPORT 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)
 
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 344 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 284 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, \
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 73 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 330 of file StringLike.cpp.

References StringCompare().

Referenced by StringDictionary::getCompare().

333  {
334  return StringCompare(lhs, lhs_len, rhs, rhs_len) == 0;
335 }
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:266

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

References StringCompare().

326  {
327  return StringCompare(lhs, lhs_len, rhs, rhs_len) >= 0;
328 }
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:266

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

References StringCompare().

319  {
320  return StringCompare(lhs, lhs_len, rhs, rhs_len) > 0;
321 }
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:266

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

References kLIKE_TRUE, and string_like_match().

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

259  {
260  // @TODO(wei/alex) add runtime error handling
261  LikeStatus status =
262  string_like_match(str, str_len, pattern, pat_len, escape_char, true);
263  return status == kLIKE_TRUE;
264 }
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:92
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 
)

Definition at line 57 of file StringLike.cpp.

References lowercase().

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

60  {
61  int i, j;
62  int search_len = str_len - pat_len + 1;
63  for (i = 0; i < search_len; ++i) {
64  for (j = 0; j < pat_len && pattern[j] == lowercase(str[j + i]); ++j) {
65  }
66  if (j >= pat_len) {
67  return true;
68  }
69  }
70  return false;
71 }
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 309 of file StringLike.cpp.

References StringCompare().

312  {
313  return StringCompare(lhs, lhs_len, rhs, rhs_len) <= 0;
314 }
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:266

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

References kLIKE_TRUE, and string_like_match().

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

248  {
249  // @TODO(wei/alex) add runtime error handling
250  LikeStatus status =
251  string_like_match(str, str_len, pattern, pat_len, escape_char, false);
252  return status == kLIKE_TRUE;
253 }
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:92
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 92 of file StringLike.cpp.

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

Referenced by string_ilike(), and string_like().

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

Definition at line 41 of file StringLike.cpp.

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

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

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

References StringCompare().

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

305  {
306  return StringCompare(lhs, lhs_len, rhs, rhs_len) < 0;
307 }
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:266

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

References StringCompare().

340  {
341  return StringCompare(lhs, lhs_len, rhs, rhs_len) != 0;
342 }
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:266

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

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

269  {
270  const char* s1_ = s1;
271  const char* s2_ = s2;
272 
273  while (s1_ < s1 + s1_len && s2_ < s2 + s2_len && *s1_ == *s2_) {
274  s1_++;
275  s2_++;
276  }
277 
278  unsigned char c1 = (s1_ < s1 + s1_len) ? (*(unsigned char*)s1_) : 0;
279  unsigned char c2 = (s2_ < s2 + s2_len) ? (*(unsigned char*)s2_) : 0;
280 
281  return c1 - c2;
282 }

+ Here is the caller graph for this function: