CUBRID Engine  latest
string_opfunc.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * string_opfunc.c - Routines that manipulate arbitrary strings
21  */
22 
23 #ident "$Id$"
24 
25 /* This includes bit strings, character strings, and national character strings
26  */
27 
28 #include "config.h"
29 
30 #include <assert.h>
31 #include <ctype.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <math.h>
35 #include <sys/timeb.h>
36 #include <assert.h>
37 
38 #include "string_opfunc.h"
39 
40 #include "chartype.h"
41 #include "system_parameter.h"
42 #include "intl_support.h"
43 #include "error_manager.h"
44 #include "tz_support.h"
45 #include "db_date.h"
46 #include "misc_string.h"
47 #include "crypt_opfunc.h"
48 #include "base64.h"
49 #include "tz_support.h"
50 #include "object_primitive.h"
51 #include "object_representation.h"
52 #include "dbtype.h"
53 #include "elo.h"
54 #include "es_common.h"
55 #include "db_elo.h"
56 #include "string_regex.hpp"
57 #include "tz_support.h"
58 #include "util_func.h"
59 
60 #include <algorithm>
61 #include <string>
62 #include <locale>
63 
64 #if !defined (SERVER_MODE)
65 #include "parse_tree.h"
66 #include "es_common.h"
67 #endif /* !defined (SERVER_MODE) */
68 
69 #include "dbtype.h"
70 
71 #if defined (SUPPRESS_STRLEN_WARNING)
72 #define strlen(s1) ((int) strlen(s1))
73 #endif /* defined (SUPPRESS_STRLEN_WARNING) */
74 
75 #define BYTE_SIZE (8)
76 #define QSTR_VALUE_PRECISION(value) \
77  ((DB_VALUE_PRECISION(value) == TP_FLOATING_PRECISION_VALUE) \
78  ? db_get_string_length(value) : \
79  DB_VALUE_PRECISION(value))
80 
81 #define QSTR_MAX_PRECISION(str_type) \
82  (QSTR_IS_CHAR(str_type) ? DB_MAX_VARCHAR_PRECISION : \
83  QSTR_IS_NATIONAL_CHAR(str_type) ? DB_MAX_VARNCHAR_PRECISION : \
84  DB_MAX_VARBIT_PRECISION)
85 
86 #define ABS(i) ((i) >= 0 ? (i) : -(i))
87 
88 #define STACK_SIZE 100
89 
90 #define LEAP(y) (((y) % 400 == 0) || ((y) % 100 != 0 && (y) % 4 == 0))
91 
92 #define DBL_MAX_DIGITS ((int)ceil(DBL_MAX_EXP * log10((double) FLT_RADIX)))
93 #define UINT64_MAX_HEX_DIGITS 16
94 #define UINT64_MAX_BIN_DIGITS 64
95 
96 #define LOB_CHUNK_SIZE (128 * 1024)
97 #define DB_GET_UCHAR(dbval) (REINTERPRET_CAST (const unsigned char *, db_get_string ((dbval))))
98 
99 /*
100  * This enumeration type is used to categorize the different
101  * string types into function like groups.
102  *
103  * DB_STRING and DB_CHAR become QSTR_CHAR
104  * DB_NCHAR and DB_VARNCHAR become QSTR_NATIONAL_CHAR
105  * DB_BIT and DB_VARBIT become QSTR_BIT
106  * All others become QSTR_UNKNOWN, although this
107  * categorizations doesn't apply to
108  * any other domain type.
109  */
110 typedef enum
111 {
116 } QSTR_CATEGORY;
117 
118 /* AM/PM position references */
119 enum
122 };
123 
124 /*
125  * Number format
126  */
127 typedef enum
128 {
129  N_END = -2, /* format string end */
130  N_INVALID = -1, /* invalid format */
134 } NUMBER_FORMAT;
135 
136 typedef enum
137 {
138  SDT_DAY = 0,
144 
145 #define WHITE_CHARS " \r\t\n"
146 
147 #define QSTR_DATE_LENGTH 10
148 #define QSTR_TIME_LENGTH 11
149 #define QSTR_TIME_STAMPLENGTH 22
150 #define QSTR_DATETIME_LENGTH 26
151 /* multiplier ratio for TO_CHAR function : estimate result len/size based on
152  * format string len/size : maximum multiplier is given by:
153  * - format element : DAY (3)
154  * - result :Wednesday (9) */
155 #define QSTR_TO_CHAR_LEN_MULTIPLIER_RATIO LOC_PARSE_FRMT_TO_TOKEN_MULT
156 
157 #define MAX_TOKEN_SIZE 16000
158 
159 #define GUID_STANDARD_BYTES_LENGTH 16
160 
161 static int db_string_prefix_compare (const DB_VALUE * string1, const DB_VALUE * string2, DB_VALUE * result);
162 static char db_string_escape_char (char c);
163 static int qstr_trim (MISC_OPERAND tr_operand, const unsigned char *trim, int trim_length, int trim_size,
164  const unsigned char *src_ptr, DB_TYPE src_type, int src_length, int src_size,
165  INTL_CODESET codeset, unsigned char **res, DB_TYPE * res_type, int *res_length, int *res_size);
166 static void trim_leading (const unsigned char *trim_charset_ptr, int trim_charset_size, const unsigned char *src_ptr,
167  DB_TYPE src_type, int src_length, int src_size, INTL_CODESET codeset,
168  unsigned char **lead_trimmed_ptr, int *lead_trimmed_length, int *lead_trimmed_size,
169  bool skip_spaces);
170 static int qstr_pad (MISC_OPERAND pad_operand, int pad_length, const unsigned char *pad_charset_ptr,
171  int pad_charset_length, int pad_charset_size, const unsigned char *src_ptr, DB_TYPE src_type,
172  int src_length, int src_size, INTL_CODESET codeset, unsigned char **result, DB_TYPE * result_type,
173  int *result_length, int *result_size);
174 static int qstr_eval_like (const char *tar, int tar_length, const char *expr, int expr_length, const char *escape,
175  INTL_CODESET codeset, int coll_id);
176 #if defined(ENABLE_UNUSED_FUNCTION)
177 static int kor_cmp (unsigned char *src, unsigned char *dest, int size);
178 #endif
179 static int qstr_replace (const unsigned char *src_buf, int src_len, int src_size, INTL_CODESET codeset, int coll_id,
180  const unsigned char *srch_str_buf, int srch_str_size, const unsigned char *repl_str_buf,
181  int repl_str_size, unsigned char **result_buf, int *result_len, int *result_size);
182 static int qstr_translate (const unsigned char *src_ptr, DB_TYPE src_type, int src_size, INTL_CODESET codeset,
183  const unsigned char *from_str_ptr, int from_str_size, const unsigned char *to_str_ptr,
184  int to_str_size, unsigned char **result_ptr, DB_TYPE * result_type, int *result_len,
185  int *result_size);
186 static QSTR_CATEGORY qstr_get_category (const DB_VALUE * s);
187 #if defined (ENABLE_UNUSED_FUNCTION)
188 static bool is_string (const DB_VALUE * s);
189 #endif /* ENABLE_UNUSED_FUNCTION */
190 static bool is_char_string (const DB_VALUE * s);
191 static bool is_integer (const DB_VALUE * i);
192 static bool is_number (const DB_VALUE * n);
193 static int qstr_grow_string (DB_VALUE * src_string, DB_VALUE * result, int new_size);
194 #if defined (ENABLE_UNUSED_FUNCTION)
195 static int qstr_append (unsigned char *s1, int s1_length, int s1_precision, DB_TYPE s1_type, const unsigned char *s2,
196  int s2_length, int s2_precision, DB_TYPE s2_type, INTL_CODESET codeset, int *result_length,
197  int *result_size, DB_DATA_STATUS * data_status);
198 #endif
199 static int qstr_concatenate (const unsigned char *s1, int s1_length, int s1_precision, DB_TYPE s1_type,
200  const unsigned char *s2, int s2_length, int s2_precision, DB_TYPE s2_type,
201  INTL_CODESET codeset, unsigned char **result, int *result_length, int *result_size,
202  DB_TYPE * result_type, DB_DATA_STATUS * data_status);
203 static int qstr_bit_concatenate (const unsigned char *s1, int s1_length, int s1_precision, DB_TYPE s1_type,
204  const unsigned char *s2, int s2_length, int s2_precision, DB_TYPE s2_type,
205  unsigned char **result, int *result_length, int *result_size, DB_TYPE * result_type,
206  DB_DATA_STATUS * data_status);
207 static bool varchar_truncated (const unsigned char *s, DB_TYPE s_type, int s_length, int used_chars,
208  INTL_CODESET codeset);
209 static bool varbit_truncated (const unsigned char *s, int s_length, int used_bits);
210 static void bit_ncat (unsigned char *r, int offset, const unsigned char *s, int n);
211 static int bstring_fls (const char *s, int n);
212 static int qstr_bit_coerce (const unsigned char *src, int src_length, int src_precision, DB_TYPE src_type,
213  unsigned char **dest, int *dest_length, int dest_precision, DB_TYPE dest_type,
214  DB_DATA_STATUS * data_status);
215 static int qstr_coerce (const unsigned char *src, int src_length, int src_precision, DB_TYPE src_type,
216  INTL_CODESET src_codeset, INTL_CODESET dest_codeset, unsigned char **dest, int *dest_length,
217  int *dest_size, int dest_precision, DB_TYPE dest_type, DB_DATA_STATUS * data_status);
218 static int qstr_position (const char *sub_string, const int sub_size, const int sub_length, const char *src_string,
219  const char *src_end, const char *src_string_bound, int src_length, int coll_id,
220  bool is_forward_search, int *position);
221 static int qstr_bit_position (const unsigned char *sub_string, int sub_length, const unsigned char *src_string,
222  int src_length, int *position);
223 static int shift_left (unsigned char *bit_string, int bit_string_size);
224 static int qstr_substring (const unsigned char *src, int src_length, int start, int length, INTL_CODESET codeset,
225  unsigned char **r, int *r_length, int *r_size);
226 static int qstr_bit_substring (const unsigned char *src, int src_length, int start, int length, unsigned char **r,
227  int *r_length);
228 static void left_nshift (const unsigned char *bit_string, int bit_string_size, int shift_amount, unsigned char *r,
229  int r_size);
230 static int qstr_ffs (int v);
231 static int hextoi (char hex_char);
232 static int adjust_precision (char *data, int precision, int scale);
233 static int date_to_char (const DB_VALUE * src_value, const DB_VALUE * format_str, const DB_VALUE * date_lang,
234  DB_VALUE * result_str, const TP_DOMAIN * domain);
235 static int number_to_char (const DB_VALUE * src_value, const DB_VALUE * format_str, const DB_VALUE * number_lang,
236  DB_VALUE * result_str, const TP_DOMAIN * domain);
237 static int lob_to_bit_char (const DB_VALUE * src_value, DB_VALUE * result_value, DB_TYPE lob_type, int max_length);
238 static int lob_from_file (const char *path, const DB_VALUE * src_value, DB_VALUE * lob_value, DB_TYPE lob_type);
239 static int lob_length (const DB_VALUE * src_value, DB_VALUE * result_value);
240 
241 static int make_number_to_char (const INTL_LANG lang, char *num_string, char *format_str, int *length,
242  DB_CURRENCY currency, char **result_str, INTL_CODESET codeset);
243 static int make_scientific_notation (char *src_string, int cipher);
244 static int roundoff (const INTL_LANG lang, char *src_string, int flag, int *cipher, char *format);
245 static int scientific_to_decimal_string (const INTL_LANG lang, char *src_string, char **scientific_str);
246 static int to_number_next_state (const int previous_state, const int input_char, const INTL_LANG number_lang_id);
247 static int make_number (char *src, char *last_src, INTL_CODESET codeset, char *token, int *token_length, DB_VALUE * r,
248  const int precision, const int scale, const INTL_LANG number_lang_id);
249 static int get_number_token (const INTL_LANG lang, char *fsp, int *length, char *last_position, char **next_fsp,
250  INTL_CODESET codeset);
251 static TIMESTAMP_FORMAT get_next_format (const char *sp, const INTL_CODESET codeset, DB_TYPE str_type,
252  int *format_length, const char **next_pos);
253 static int get_cur_year (void);
254 static int get_cur_month (void);
255 /* utility functions */
256 static int add_and_normalize_date_time (int *years, int *months, int *days, int *hours, int *minutes, int *seconds,
257  int *milliseconds, DB_BIGINT y, DB_BIGINT m, DB_BIGINT d, DB_BIGINT h,
258  DB_BIGINT mi, DB_BIGINT s, DB_BIGINT ms);
259 static int sub_and_normalize_date_time (int *years, int *months, int *days, int *hours, int *minutes, int *seconds,
260  int *milliseconds, DB_BIGINT y, DB_BIGINT m, DB_BIGINT d, DB_BIGINT h,
261  DB_BIGINT mi, DB_BIGINT s, DB_BIGINT ms);
262 static void set_time_argument (struct tm *dest, int year, int month, int day, int hour, int min, int sec);
263 static long calc_unix_timestamp (struct tm *time_argument);
264 #if defined (ENABLE_UNUSED_FUNCTION)
265 static int parse_for_next_int (char **ch, char *output);
266 #endif
267 static int db_str_to_millisec (const char *str);
268 static void copy_and_shift_values (int shift, int n, DB_BIGINT * first, ...);
269 static DB_BIGINT get_single_unit_value (const char *expr, DB_BIGINT int_val);
270 static int db_date_add_sub_interval_expr (DB_VALUE * result, const DB_VALUE * date, const DB_VALUE * expr,
271  const int unit, int is_add);
272 static int db_date_add_sub_interval_days (DB_VALUE * result, const DB_VALUE * date, const DB_VALUE * db_days,
273  bool is_add);
274 static int db_round_dbvalue_to_int (const DB_VALUE * src, int *result);
275 static int db_get_next_like_pattern_character (const char *const pattern, const int length, const INTL_CODESET codeset,
276  const bool has_escape_char, const char *escape_str, int *const position,
277  char **crt_char_p, bool * const is_escaped);
278 static bool is_safe_last_char_for_like_optimization (const char *chr, const bool is_escaped, INTL_CODESET codeset);
279 static int db_check_or_create_null_term_string (const DB_VALUE * str_val, char *pre_alloc_buf, int pre_alloc_buf_size,
280  bool ignore_prec_spaces, bool ignore_trail_spaces, char **str_out,
281  bool * do_alloc);
282 static bool is_str_valid_number (char *num_p, char *str_end, int base, INTL_CODESET codeset);
283 static bool is_valid_ip_slice (const char *ipslice);
284 
285 /* reads cnt digits until non-digit char reached,
286  * returns nr of characters traversed
287  */
288 static int parse_digits (char *s, int *nr, int cnt);
289 static int parse_time_string (const char *timestr, int timestr_size, int *sign, int *h, int *m, int *s, int *ms);
290 static int get_string_date_token_id (const STRING_DATE_TOKEN token_type, const INTL_LANG intl_lang_id, const char *cs,
291  const INTL_CODESET codeset, int *token_id, int *token_size);
292 static int print_string_date_token (const STRING_DATE_TOKEN token_type, const INTL_LANG intl_lang_id,
293  const INTL_CODESET codeset, int token_id, int case_mode, char *buffer,
294  int *token_size);
295 static void convert_locale_number (char *sz, const int size, const INTL_LANG src_locale, const INTL_LANG dst_locale);
296 static int parse_tzd (const char *str, const int max_expect_len);
297 
298 #define TRIM_FORMAT_STRING(sz, n) {if (strlen(sz) > n) sz[n] = 0;}
299 #define WHITESPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
300 #define ALPHABETICAL(c) (((c) >= 'A' && (c) <= 'Z') || \
301  ((c) >= 'a' && (c) <= 'z'))
302 #define DIGIT(c) ((c) >= '0' && (c) <= '9')
303 
304 /* same as characters in get_next_format */
305 #define PUNCTUATIONAL(c) ((c) == '-' || (c) == '/' || (c) == ',' || (c) == '.' \
306  || (c) == ';' || (c) == ':' || (c) == ' ' \
307  || (c) == '\t' || (c) == '\n')
308 
309 /* character that need escaping when making Json String */
310 #define ESCAPE_CHAR(c) (c <= 0x1f || (c) == '"' || (c) == '\\')
311 
312 /* concatenate a char to s */
313 #define STRCHCAT(s, c) \
314  {\
315  char __cch__[2];\
316  __cch__[0] = c;__cch__[1] = 0; strcat(s, __cch__);\
317  }
318 
319 #define SKIP_SPACES(ch, end) do {\
320  while (ch != end && char_isspace(*(ch))) (ch)++; \
321 } while(0)
322 
323 #define TZD_DEFAULT_EXPECTED_LEN 4
324 #define TZD_MAX_EXPECTED_LEN TZ_DS_STRING_SIZE
325 
326 /*
327  * Public Functions for Strings - Bit and Character
328  */
329 
330 /*
331  * db_string_compare () -
332  *
333  * Arguments:
334  * string1: Left side of compare.
335  * string2: Right side of compare
336  * result: Integer result of comparison.
337  *
338  * Returns: int
339  *
340  * Errors:
341  * ER_QSTR_INVALID_DATA_TYPE :
342  * <string1> or <string2> are not character strings.
343  *
344  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
345  * <string1> and <string2> have differing character code sets.
346  *
347  * ER_QSTR_INCOMPATIBLE_COLLATIONS
348  * <string1> and <string2> have incompatible collations.
349  *
350  */
351 
352 int
353 db_string_compare (const DB_VALUE * string1, const DB_VALUE * string2, DB_VALUE * result)
354 {
355  QSTR_CATEGORY string1_category, string2_category;
356  int cmp_result = 0;
357  DB_TYPE str1_type, str2_type;
358 
359  bool ti = true;
360  static bool ignore_trailing_space = prm_get_bool_value (PRM_ID_IGNORE_TRAILING_SPACE);
361 
362  /* Assert that DB_VALUE structures have been allocated. */
363  assert (string1 != (DB_VALUE *) NULL);
364  assert (string2 != (DB_VALUE *) NULL);
365  assert (result != (DB_VALUE *) NULL);
366 
367  /* Categorize the two input parameters and check for errors. Verify that the parameters are both character strings.
368  * Verify that the input strings belong to compatible categories. */
369  string1_category = qstr_get_category (string1);
370  string2_category = qstr_get_category (string2);
371 
372  str1_type = DB_VALUE_DOMAIN_TYPE (string1);
373  str2_type = DB_VALUE_DOMAIN_TYPE (string2);
374 
375  if (!QSTR_IS_ANY_CHAR_OR_BIT (str1_type) || !QSTR_IS_ANY_CHAR_OR_BIT (str2_type))
376  {
379  }
380  if (string1_category != string2_category)
381  {
384  }
385 
386  /* A string which is NULL (not the same as a NULL string) is ordered less than a string which is not NULL. Two
387  * strings which are NULL are ordered equivalently. If both strings are not NULL, then the strings themselves are
388  * compared. */
389  if (DB_IS_NULL (string1) && !DB_IS_NULL (string2))
390  {
391  cmp_result = -1;
392  }
393  else if (!DB_IS_NULL (string1) && DB_IS_NULL (string2))
394  {
395  cmp_result = 1;
396  }
397  else if (DB_IS_NULL (string1) && DB_IS_NULL (string2))
398  {
399  cmp_result = 0;
400  }
401  else if (db_get_string_codeset (string1) != db_get_string_codeset (string2))
402  {
405  }
406  else
407  {
408  int coll_id;
409 
410  switch (string1_category)
411  {
412  case QSTR_CHAR:
413  case QSTR_NATIONAL_CHAR:
414 
415  assert (db_get_string_codeset (string1) == db_get_string_codeset (string2));
416 
418 
419  if (coll_id == -1)
420  {
423  }
424 
425  coll_id = db_get_string_collation (string1);
426  assert (db_get_string_collation (string1) == db_get_string_collation (string2));
427 
428  if (!ignore_trailing_space)
429  {
430  ti = (QSTR_IS_FIXED_LENGTH (str1_type) && QSTR_IS_FIXED_LENGTH (str2_type));
431  }
432  cmp_result = QSTR_COMPARE (coll_id, DB_GET_UCHAR (string1), (int) db_get_string_size (string1),
433  DB_GET_UCHAR (string2), (int) db_get_string_size (string2), ti);
434  break;
435  case QSTR_BIT:
436  cmp_result = varbit_compare (DB_GET_UCHAR (string1), (int) db_get_string_size (string1),
437  DB_GET_UCHAR (string2), (int) db_get_string_size (string2));
438  break;
439  default: /* QSTR_UNKNOWN */
440  assert (false);
441  }
442  }
443 
444  if (cmp_result < 0)
445  {
446  cmp_result = -1;
447  }
448  else if (cmp_result > 0)
449  {
450  cmp_result = 1;
451  }
452  db_make_int (result, cmp_result);
453 
454  return NO_ERROR;
455 }
456 
457 /*
458  * db_string_unique_prefix () -
459  *
460  * Arguments:
461  * string1: (IN) Left side of compare.
462  * string2: (IN) Right side of compare.
463  * result: (OUT) string such that > string1, and <= string2.
464  *
465  * Returns: int
466  *
467  * Errors:
468  * (TBD)
469  *
470  * Note:
471  * The purpose of this routine is to find a prefix that is greater
472  * than or equal to the first string but strictly less than the second
473  * string.
474  *
475  * This routine assumes:
476  * a) The second string is strictly greater than the first
477  * (according to the ANSI SQL string comparison rules).
478  * b) The two strings are both of the same 'type', although one may be
479  * 'fixed' and the other may be 'varying'.
480  * c) No padding is done.
481  *
482  * Assert:
483  *
484  * 1. string1 != (DB_VALUE *)NULL
485  * 2. string2 != (DB_VALUE *)NULL
486  * 3. result != (DB_VALUE *)NULL
487  *
488  */
489 #if 1
490 int
491 db_string_unique_prefix (const DB_VALUE * db_string1, const DB_VALUE * db_string2, DB_VALUE * db_result,
492  TP_DOMAIN * key_domain)
493 {
494  DB_TYPE result_type = (DB_TYPE) 0;
495  int error_status = NO_ERROR;
496  int precision;
497  DB_VALUE tmp_result;
498  int c;
499 
500  bool ti = true;
501  static bool ignore_trailing_space = prm_get_bool_value (PRM_ID_IGNORE_TRAILING_SPACE);
502 
503  /* Assertions */
504  assert (db_string1 != (DB_VALUE *) NULL);
505  assert (db_string2 != (DB_VALUE *) NULL);
506  assert (db_result != (DB_VALUE *) NULL);
507 
508  error_status = db_string_compare (db_string1, db_string2, &tmp_result);
509  if ((error_status != NO_ERROR)
510  || ((c = db_get_int (&tmp_result)) && ((!key_domain->is_desc && c > 0) || (key_domain->is_desc && c < 0))))
511  {
512  db_make_null (db_result);
513 #if defined(CUBRID_DEBUG)
514  if (error_status == ER_QSTR_INVALID_DATA_TYPE)
515  {
516  printf ("db_string_unique_prefix(): non-string type: %s and %s\n",
517  pr_type_name (DB_VALUE_DOMAIN_TYPE (db_string1)), pr_type_name (DB_VALUE_DOMAIN_TYPE (db_string2)));
518  }
519  if (error_status == ER_QSTR_INCOMPATIBLE_CODE_SETS)
520  {
521  printf ("db_string_unique_prefix(): incompatible types: %s and %s\n",
522  pr_type_name (DB_VALUE_DOMAIN_TYPE (db_string1)), pr_type_name (DB_VALUE_DOMAIN_TYPE (db_string2)));
523  }
524  if (db_get_int (&tmp_result) > 0)
525  {
526  printf ("db_string_unique_prefix(): string1 %s, greater than string2 %s\n", db_get_string (db_string1),
527  db_get_string (db_string2));
528  }
529 #endif
530  return ER_GENERIC_ERROR;
531  }
532 
533  precision = DB_VALUE_PRECISION (db_string1);
534  /* Determine the result type */
535  result_type = DB_VALUE_DOMAIN_TYPE (db_string1);
536  if (QSTR_IS_CHAR (result_type))
537  {
538  result_type = DB_TYPE_VARCHAR;
539  }
540  else if (QSTR_IS_NATIONAL_CHAR (result_type))
541  {
542  result_type = DB_TYPE_VARNCHAR;
543  }
544  else if (QSTR_IS_BIT (result_type))
545  {
546  result_type = DB_TYPE_VARBIT;
547  }
548  else
549  {
550  db_make_null (db_result);
551 #if defined(CUBRID_DEBUG)
552  printf ("db_string_unique_prefix(): non-string type: %s and %s\n",
553  pr_type_name (DB_VALUE_DOMAIN_TYPE (db_string1)), pr_type_name (DB_VALUE_DOMAIN_TYPE (db_string2)));
554 #endif
555  return ER_GENERIC_ERROR;
556  }
557 
558  /* A string which is NULL (not the same as a NULL string) is ordered less than a string which is not NULL. Since
559  * string2 is assumed to be strictly > string1, string2 can never be NULL. */
560  if (DB_IS_NULL (db_string1))
561  {
562  db_value_domain_init (db_result, result_type, precision, 0);
563  }
564 
565  /* Find the first byte where the 2 strings differ. Set the result accordingly. */
566  else
567  {
568  int size1, size2, result_size, pad_size = 0;
569  const unsigned char *string1 = NULL, *string2 = NULL, *t = NULL, *key = NULL;
570  unsigned char *result, pad[2];
571  INTL_CODESET codeset;
572  int num_bits = -1;
573  int collation_id;
574  bool bit_use_str2_size = false;
575 
576  string1 = DB_GET_UCHAR (db_string1);
577  size1 = (int) db_get_string_size (db_string1);
578  string2 = DB_GET_UCHAR (db_string2);
579  size2 = (int) db_get_string_size (db_string2);
580  codeset = db_get_string_codeset (db_string1);
581  collation_id = db_get_string_collation (db_string1);
582 
583  assert (collation_id == db_get_string_collation (db_string2));
584 
585  if (result_type == DB_TYPE_VARBIT)
586  {
587  collation_id = LANG_COLL_ISO_BINARY;
588  }
589 
590  if (string1 == NULL || string2 == NULL)
591  {
594  }
595 
596  intl_pad_char (codeset, pad, &pad_size);
597 
598  trim_again:
599  /* We need to implicitly trim both strings since we don't want padding for the result (its of varying type) and
600  * since padding can mask the logical end of both of the strings. Trimming depends on codeset. */
601 
602  if (pad_size == 1)
603  {
604  for (t = string1 + (size1 - 1); t >= string1 && *t == pad[0]; t--, size1--)
605  {
606  ;
607  }
608  for (t = string2 + (size2 - 1); t >= string2 && *t == pad[0]; t--, size2--)
609  {
610  ;
611  }
612  }
613  else
614  {
615  assert (pad_size == 2);
616 
617  for (t = string1 + (size1 - 2); t >= string1 && *t == pad[0] && *(t + 1) == pad[1];
618  t--, t--, size1--, size1--)
619  {
620  ;
621  }
622 
623  for (t = string2 + (size2 - 2); t >= string2 && *t == pad[0] && *(t + 1) == pad[1];
624  t--, t--, size2--, size2--)
625  {
626  ;
627  }
628 
629  if (codeset == INTL_CODESET_KSC5601_EUC)
630  {
631  /* trim also ASCII space */
632  intl_pad_char (INTL_CODESET_ISO88591, pad, &pad_size);
633  goto trim_again;
634  }
635  }
636 
637  if (result_type == DB_TYPE_VARBIT)
638  {
639  int size;
640  const unsigned char *t2;
641 
642  for (size = 1, t = string1, t2 = string2; size <= size1 && size <= size2; size++, t++, t2++)
643  {
644  if (*t != *t2)
645  {
646  size++;
647  break;
648  }
649  }
650 
651  if (!(key_domain->is_desc))
652  { /* normal index */
653  key = string2;
654 
655  /* search until non-zero differentiating byte */
656  t2++;
657  size++;
658 
659  bit_use_str2_size = false;
660  if (size >= size2)
661  {
662  size = size2;
663  bit_use_str2_size = true;
664  }
665  }
666  else
667  {
668  /* reverse index */
669  assert (key_domain->is_desc);
670 
671  t++;
672  size++;
673 
674  if (size >= size1)
675  {
676  /* str1 exhaused or at last byte, we use string2 as key */
677  key = string2;
678  size = size2;
679  bit_use_str2_size = true;
680  }
681  else
682  {
683  /* pos is already at the next diffentiating byte */
684  assert (size < size1);
685  key = string1;
686  bit_use_str2_size = false;
687  }
688  }
689 
690  num_bits = bit_use_str2_size ? (db_string2->data.ch.medium.size) : (size * BYTE_SIZE);
691 
692  result_size = (num_bits + 7) / 8;
693  }
694  else
695  {
696  if (!ignore_trailing_space)
697  {
698  ti = (db_string1->domain.char_info.type == DB_TYPE_CHAR
699  || db_string1->domain.char_info.type == DB_TYPE_NCHAR);
700  }
701  error_status = QSTR_SPLIT_KEY (collation_id, key_domain->is_desc, string1, size1, string2, size2, &key,
702  &result_size, ti);
703  }
704  assert (error_status == NO_ERROR);
705 
706  assert (key != NULL);
707 
708  result = (unsigned char *) db_private_alloc (NULL, result_size + 1);
709  if (result)
710  {
711  if (result_size)
712  {
713  (void) memcpy (result, key, result_size);
714  }
715  result[result_size] = 0;
716  db_value_domain_init (db_result, result_type, precision, 0);
717  error_status = db_make_db_char (db_result, codeset, collation_id, REINTERPRET_CAST (char *, result),
718  (result_type == DB_TYPE_VARBIT ? num_bits : result_size));
719  db_result->need_clear = true;
720  }
721  else
722  {
723  /* will already be set by memory mgr */
724  assert (er_errid () != NO_ERROR);
725  error_status = er_errid ();
726  }
727  }
728 
729 #if !defined(NDEBUG)
730  if (error_status == NO_ERROR)
731  {
732  int err_status2 = NO_ERROR;
733  int c1 = 1, c2 = -1;
734 
735  err_status2 = db_string_prefix_compare (db_string1, db_result, &tmp_result);
736  if (err_status2 == NO_ERROR)
737  {
738  c1 = db_get_int (&tmp_result);
739  }
740  err_status2 = db_string_prefix_compare (db_result, db_string2, &tmp_result);
741  if (err_status2 == NO_ERROR)
742  {
743  c2 = db_get_int (&tmp_result);
744  }
745 
746  if (!key_domain->is_desc)
747  {
748  assert (c1 < 0 && c2 <= 0);
749  }
750  else
751  {
752  assert (c1 > 0 && c2 >= 0);
753  }
754  }
755 #endif
756 
757  return (error_status);
758 }
759 #else
760 int
761 db_string_unique_prefix (const DB_VALUE * db_string1, const DB_VALUE * db_string2, DB_VALUE * db_result)
762 {
763  DB_TYPE result_type = 0;
764  int error_status = NO_ERROR;
765  int precision, num_bits = -1;
766  DB_TYPE string_type;
767 
768  /* Assertions */
769  assert (db_string1 != (DB_VALUE *) NULL);
770  assert (db_string2 != (DB_VALUE *) NULL);
771  assert (db_result != (DB_VALUE *) NULL);
772 
773  precision = DB_VALUE_PRECISION (db_string1);
774  string_type = DB_VALUE_DOMAIN_TYPE (db_string1);
775 
776  /* Determine the result type */
777  if (QSTR_IS_CHAR (string_type))
778  {
779  result_type = DB_TYPE_VARCHAR;
780  }
781  else if (QSTR_IS_NATIONAL_CHAR (string_type))
782  {
783  result_type = DB_TYPE_VARNCHAR;
784  }
785  else if (QSTR_IS_BIT (string_type))
786  {
787  result_type = DB_TYPE_VARBIT;
788  }
789  else
790  {
791  result_type = DB_TYPE_NULL;
792  db_make_null (db_result);
793 #if defined(CUBRID_DEBUG)
794  printf ("db_string_unique_prefix called with non-string type: %s\n", pr_type_name (string_type));
795 #endif
796  return ER_GENERIC_ERROR;
797  }
798 
799  /*
800  * A string which is NULL (not the same as a NULL string) is
801  * ordered less than a string which is not NULL. Since string2 is
802  * assumed to be strictly > string1, string2 can never be NULL.
803  */
804  if (DB_IS_NULL (db_string1))
805  {
806  db_value_domain_init (db_result, result_type, precision, 0);
807  }
808  /*
809  * Find the first byte where the 2 strings differ. Set the result
810  * accordingly.
811  */
812  else
813  {
814  int string1_size = db_get_string_size (db_string1);
815  int string2_size = db_get_string_size (db_string2);
816  const unsigned char *string1 = (const unsigned char *) db_get_string (db_string1);
817  const unsigned char *string2 = (const unsigned char *) db_get_string (db_string2);
818  unsigned char *result;
819  const unsigned char *key;
820  int result_size;
821  INTL_CODESET codeset = db_get_string_codeset ((DB_VALUE *) db_string1);
822 
823  /* We need to implicitly trim both strings since we don't want padding for the result (its of varying type) and
824  * since padding can mask the logical end of both of the strings. We need to be careful how the trimming is
825  * done. Char and varchar can do the normal trim, nchar and varnchar need to worry about codeset and pad chars,
826  * and bit and varbit don't want to trim at all. */
827  if (result_type == DB_TYPE_VARCHAR)
828  {
829  for (; string1_size && string1[string1_size - 1] == ' '; string1_size--)
830  {
831  ; /* do nothing */
832  }
833  for (; string2_size && string2[string2_size - 1] == ' '; string2_size--)
834  {
835  ; /* do nothing */
836  }
837  }
838  else if (result_type == DB_TYPE_VARNCHAR)
839  {
840  /* This is going to look a lot like qstr_trim_trailing. We don't call qstr_trim_trailing because he works on
841  * length of characters and we need to work on length of bytes. We could calculate the length in characters,
842  * but that requires a full scan of the strings which is not necessary. */
843  int i, pad_size, trim_length, cmp_flag, prev_size;
844  unsigned char *prev_ptr, *current_ptr, pad[2];
845 
846  intl_pad_char (codeset, pad, &pad_size);
847 
848  trim_length = string1_size;
849  current_ptr = (unsigned char *) (string1 + string1_size);
850  for (i = 0, cmp_flag = 0; (i < string1_size) && (cmp_flag == 0); i++)
851  {
852  prev_ptr = qstr_prev_char (current_ptr, codeset, &prev_size);
853  if (pad_size == prev_size)
854  {
855  cmp_flag = memcmp ((char *) prev_ptr, (char *) pad, pad_size);
856 
857  if (cmp_flag == 0)
858  {
859  trim_length -= pad_size;
860  }
861  }
862  else
863  {
864  cmp_flag = 1;
865  }
866 
867  current_ptr = prev_ptr;
868  }
869  string1_size = trim_length;
870 
871  trim_length = string2_size;
872  current_ptr = (unsigned char *) (string2 + string2_size);
873  for (i = 0, cmp_flag = 0; (i < string2_size) && (cmp_flag == 0); i++)
874  {
875  prev_ptr = qstr_prev_char (current_ptr, codeset, &prev_size);
876  if (pad_size == prev_size)
877  {
878  cmp_flag = memcmp ((char *) prev_ptr, (char *) pad, pad_size);
879 
880  if (cmp_flag == 0)
881  {
882  trim_length -= pad_size;
883  }
884  }
885  else
886  {
887  cmp_flag = 1;
888  }
889 
890  current_ptr = prev_ptr;
891  }
892  string2_size = trim_length;
893 
894  }
895 
896  /* now find the first byte where the strings differ */
897  for (result_size = 0;
898  result_size < string1_size && result_size < string2_size && string1[result_size] == string2[result_size];
899  result_size++)
900  {
901  ; /* do nothing */
902  }
903 
904  /* Check for string2 < string1. This check can only be done when we haven't exhausted one of the strings. If
905  * string2 is exhausted it is an error. */
906  if ((result_size != string1_size)
907  && ((result_size == string2_size) || (string2[result_size] < string1[result_size])))
908  {
909 #if defined(CUBRID_DEBUG)
910  printf ("db_string_unique_prefix called with ");
911  printf ("string1: %s, greater than string2: %s\n", string1, string2);
912 #endif
913  error_status = ER_GENERIC_ERROR;
914  }
915  else
916  {
917 
918  if (result_size == string1_size || result_size == string2_size - 1)
919  {
920  key = string1;
921  result_size = string1_size;
922  /* if we have bits, we need all the string1 bits. Remember that you may not use all of the bits in the
923  * last byte. */
924  if (result_type == DB_TYPE_VARBIT)
925  {
926  num_bits = db_string1->data.ch.medium.size;
927  }
928  }
929  else
930  {
931  result_size += 1;
932  key = string2;
933  /* if we have bits, we will take all the bits for the differentiating byte. This is fine since in this
934  * branch we are guaranteed not to be at the end of either string. */
935  if (result_type == DB_TYPE_VARBIT)
936  {
937  num_bits = result_size * BYTE_SIZE;
938  }
939  }
940 
941  result = db_private_alloc (NULL, result_size + 1);
942  if (result)
943  {
944  if (result_size)
945  {
946  memcpy (result, key, result_size);
947  }
948  result[result_size] = 0;
949  db_value_domain_init (db_result, result_type, precision, 0);
950  if (result_type == DB_TYPE_VARBIT)
951  {
952  error_status = db_make_db_char (db_result, codeset, (const char *) result, num_bits);
953  }
954  else
955  {
956  error_status = db_make_db_char (db_result, codeset, (const char *) result, result_size);
957  }
958 
959  db_result->need_clear = true;
960  }
961  else
962  {
963  /* will already be set by memory mgr */
964  assert (er_errid () != NO_ERROR);
965  error_status = er_errid ();
966  }
967  }
968  }
969 
970  return (error_status);
971 }
972 #endif
973 
974 /*
975  * db_string_concatenate () -
976  *
977  * Arguments:
978  * string1: Left string to concatenate.
979  * string2: Right string to concatenate.
980  * result: Result of concatenation of both strings.
981  * data_status: DB_DATA_STATUS which indicates if truncation occurred.
982  *
983  * Returns: int
984  *
985  * Errors:
986  * ER_QSTR_INVALID_DATA_TYPE :
987  * <string1> or <string2> not string types.
988  *
989  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
990  * <string1> or <string2> have different character code sets
991  * or are not all bit strings.
992  *
993  */
994 
995 int
996 db_string_concatenate (const DB_VALUE * string1, const DB_VALUE * string2, DB_VALUE * result,
997  DB_DATA_STATUS * data_status)
998 {
999  QSTR_CATEGORY string1_code_set, string2_code_set;
1000  int error_status = NO_ERROR;
1001  DB_TYPE string_type1, string_type2;
1002  bool is_inplace_concat;
1003 
1004  /*
1005  * Initialize status value
1006  */
1007  *data_status = DATA_STATUS_OK;
1008 
1009  /*
1010  * Assert that DB_VALUE structures have been allocated.
1011  */
1012  assert (string1 != (DB_VALUE *) NULL);
1013  assert (string2 != (DB_VALUE *) NULL);
1014  assert (result != (DB_VALUE *) NULL);
1015 
1016  is_inplace_concat = false; /* init */
1017 
1018  /* check iff is in-place update */
1019  if (string1 == result || string2 == result)
1020  {
1021  is_inplace_concat = true;
1022  }
1023 
1024  /*
1025  * Categorize the parameters into respective code sets.
1026  * Verify that the parameters are both character strings.
1027  * Verify that the input strings belong to compatible code sets.
1028  */
1029  string1_code_set = qstr_get_category (string1);
1030  string2_code_set = qstr_get_category (string2);
1031 
1032  string_type1 = DB_VALUE_DOMAIN_TYPE (string1);
1033  string_type2 = DB_VALUE_DOMAIN_TYPE (string2);
1034 
1035  if (!QSTR_IS_ANY_CHAR_OR_BIT (string_type1) || !QSTR_IS_ANY_CHAR_OR_BIT (string_type2))
1036  {
1037  /* ORACLE7 ServerSQL Language Reference Manual 3-4; Although ORACLE treats zero-length character strings as
1038  * nulls, concatenating a zero-length character string with another operand always results in the other operand,
1039  * rather than a null. However, this may not continue to be true in future versions of ORACLE. To concatenate an
1040  * expression that might be null, use the NVL function to explicitly convert the expression to a zero-length
1041  * string. */
1043  {
1044  if (DB_IS_NULL (string1) && QSTR_IS_ANY_CHAR_OR_BIT (string_type2))
1045  {
1046  pr_clone_value ((DB_VALUE *) string2, result);
1047  }
1048  else if (DB_IS_NULL (string2) && QSTR_IS_ANY_CHAR_OR_BIT (string_type1))
1049  {
1050  pr_clone_value ((DB_VALUE *) string1, result);
1051  }
1052  else
1053  {
1054  error_status = ER_QSTR_INVALID_DATA_TYPE;
1055  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
1056  }
1057  }
1058  else
1059  {
1060  error_status = ER_QSTR_INVALID_DATA_TYPE;
1061  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
1062  }
1063  }
1064  else if ((string1_code_set != string2_code_set))
1065  {
1066  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
1067  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
1068  }
1069  else if (DB_IS_NULL (string1) || DB_IS_NULL (string2))
1070  {
1071  bool check_empty_string;
1072 
1073  /* ORACLE7 ServerSQL Language Reference Manual 3-4; Although ORACLE treats zero-length character strings as
1074  * nulls, concatenating a zero-length character string with another operand always results in the other operand,
1075  * rather than a null. However, this may not continue to be true in future versions of ORACLE. To concatenate an
1076  * expression that might be null, use the NVL function to explicitly convert the expression to a zero-length
1077  * string. */
1078  check_empty_string = prm_get_bool_value (PRM_ID_ORACLE_STYLE_EMPTY_STRING) ? true : false;
1079 
1080  if (check_empty_string && DB_IS_NULL (string1) && QSTR_IS_ANY_CHAR_OR_BIT (string_type2))
1081  {
1082  pr_clone_value ((DB_VALUE *) string2, result);
1083  }
1084  else if (check_empty_string && DB_IS_NULL (string2) && QSTR_IS_ANY_CHAR_OR_BIT (string_type1))
1085  {
1086  pr_clone_value ((DB_VALUE *) string1, result);
1087  }
1088  else
1089  {
1090  if (QSTR_IS_CHAR (string_type1))
1091  {
1092  if (string_type1 == DB_TYPE_VARCHAR || string_type2 == DB_TYPE_VARCHAR)
1093  {
1095  }
1096  else
1097  {
1099  }
1100  }
1101  else if (QSTR_IS_NATIONAL_CHAR (string_type1))
1102  {
1103  if (string_type1 == DB_TYPE_VARNCHAR || string_type2 == DB_TYPE_VARNCHAR)
1104  {
1106  }
1107  else
1108  {
1110  }
1111  }
1112  else
1113  {
1114  if (string_type1 == DB_TYPE_VARBIT || string_type2 == DB_TYPE_VARBIT)
1115  {
1117  }
1118  else
1119  {
1121  }
1122  }
1123  }
1124  }
1125  else
1126  {
1127  unsigned char *r;
1128  int r_length, r_size;
1129  DB_TYPE r_type;
1130 
1131  if (string1_code_set == QSTR_BIT)
1132  {
1133  int result_domain_length;
1134 
1135  error_status = qstr_bit_concatenate (DB_GET_UCHAR (string1), (int) db_get_string_length (string1),
1136  (int) QSTR_VALUE_PRECISION (string1), DB_VALUE_DOMAIN_TYPE (string1),
1137  DB_GET_UCHAR (string2), (int) db_get_string_length (string2),
1138  (int) QSTR_VALUE_PRECISION (string2), DB_VALUE_DOMAIN_TYPE (string2),
1139  &r, &r_length, &r_size, &r_type, data_status);
1140 
1141  if (error_status == NO_ERROR)
1142  {
1145  {
1146  result_domain_length = TP_FLOATING_PRECISION_VALUE;
1147  }
1148  else
1149  {
1150  result_domain_length =
1151  MIN (DB_MAX_BIT_LENGTH, DB_VALUE_PRECISION (string1) + DB_VALUE_PRECISION (string2));
1152  }
1153 
1154  qstr_make_typed_string (r_type, result, result_domain_length, (char *) r, r_length,
1155  db_get_string_codeset (string1), db_get_string_collation (string1));
1156  result->need_clear = true;
1157  }
1158  }
1159  else
1160  {
1161  DB_VALUE temp;
1162  int result_domain_length;
1163  int common_coll;
1164  INTL_CODESET codeset = db_get_string_codeset (string1);
1165 
1166  db_make_null (&temp);
1167 
1168  LANG_RT_COMMON_COLL (db_get_string_collation (string1), db_get_string_collation (string2), common_coll);
1169  if (common_coll == -1)
1170  {
1173  }
1174 
1175  if (db_get_string_codeset (string1) != db_get_string_codeset (string2))
1176  {
1177  DB_DATA_STATUS data_status;
1178 
1179  codeset = lang_get_collation (common_coll)->codeset;
1180 
1181  if (db_get_string_codeset (string1) != codeset)
1182  {
1183  db_value_domain_init (&temp, string_type1, (int) QSTR_VALUE_PRECISION (string1), 0);
1184 
1185  db_string_put_cs_and_collation (&temp, codeset, common_coll);
1186  error_status = db_char_string_coerce (string1, &temp, &data_status);
1187 
1188  if (error_status != NO_ERROR)
1189  {
1190  pr_clear_value (&temp);
1191  return error_status;
1192  }
1193 
1194  assert (data_status == DATA_STATUS_OK);
1195 
1196  string1 = &temp;
1197  }
1198  else
1199  {
1200  assert (db_get_string_codeset (string2) != codeset);
1201 
1202  db_value_domain_init (&temp, string_type2, (int) QSTR_VALUE_PRECISION (string2), 0);
1203 
1204  db_string_put_cs_and_collation (&temp, codeset, common_coll);
1205  error_status = db_char_string_coerce (string2, &temp, &data_status);
1206 
1207  if (error_status != NO_ERROR)
1208  {
1209  pr_clear_value (&temp);
1210  return error_status;
1211  }
1212 
1213  assert (data_status == DATA_STATUS_OK);
1214 
1215  string2 = &temp;
1216  }
1217  }
1218 
1219  error_status = qstr_concatenate (DB_GET_UCHAR (string1), (int) db_get_string_length (string1),
1220  (int) QSTR_VALUE_PRECISION (string1), DB_VALUE_DOMAIN_TYPE (string1),
1221  DB_GET_UCHAR (string2), (int) db_get_string_length (string2),
1222  (int) QSTR_VALUE_PRECISION (string2), DB_VALUE_DOMAIN_TYPE (string2),
1223  codeset, &r, &r_length, &r_size, &r_type, data_status);
1224 
1225  pr_clear_value (&temp);
1226 
1227  if (error_status == NO_ERROR && r != NULL)
1228  {
1231  {
1232  result_domain_length = TP_FLOATING_PRECISION_VALUE;
1233  }
1234  else
1235  {
1236  result_domain_length =
1237  MIN (QSTR_MAX_PRECISION (r_type), DB_VALUE_PRECISION (string1) + DB_VALUE_PRECISION (string2));
1238  }
1239 
1240  if (is_inplace_concat)
1241  {
1242  /* clear value before in-place update */
1243  (void) pr_clear_value (result);
1244  }
1245 
1246  qstr_make_typed_string (r_type, result, result_domain_length, (char *) r, r_size, codeset, common_coll);
1247  r[r_size] = 0;
1248  result->need_clear = true;
1249  }
1250  }
1251  }
1252 
1253  return error_status;
1254 }
1255 
1256 /*
1257  * db_string_chr () - take character of db_value
1258  * return: NO_ERROR, or ER_code
1259  * res(OUT) : resultant db_value node
1260  * dbval1(IN) : first db_value node
1261  * dbval2(IN) : charset name to use
1262  */
1263 
1264 int
1265 db_string_chr (DB_VALUE * res, DB_VALUE * dbval1, DB_VALUE * dbval2)
1266 {
1267  DB_TYPE arg_type;
1268  DB_BIGINT temp_bigint = 0;
1269  unsigned int temp_arg = 0, uint_arg = 0;
1270  int itmp = 0;
1271 
1272  DB_BIGINT bi = 0;
1273 
1274  double dtmp = 0;
1275 
1276  char *num_as_bytes = NULL;
1277  char *invalid_pos = NULL;
1278  int num_byte_count = 0;
1279  int i, codeset = -1, collation = -1;
1280  int err_status = NO_ERROR;
1281 
1282  arg_type = DB_VALUE_DOMAIN_TYPE (dbval1);
1283 
1284  assert (dbval1 != NULL && dbval2 != NULL);
1285 
1286  if (arg_type == DB_TYPE_NULL || DB_IS_NULL (dbval1))
1287  {
1288  goto exit;
1289  }
1290 
1292 
1293  codeset = db_get_int (dbval2);
1294  if (codeset != INTL_CODESET_UTF8 && codeset != INTL_CODESET_ISO88591 && codeset != INTL_CODESET_KSC5601_EUC
1295  && codeset != INTL_CODESET_BINARY)
1296  {
1298  err_status = ER_OBJ_INVALID_ARGUMENTS;
1299  goto exit;
1300  }
1301 
1302  /* Get value according to DB_TYPE */
1303  switch (arg_type)
1304  {
1305  case DB_TYPE_SHORT:
1306  itmp = db_get_short (dbval1);
1307  break;
1308  case DB_TYPE_INTEGER:
1309  itmp = db_get_int (dbval1);
1310  break;
1311  case DB_TYPE_BIGINT:
1312  bi = db_get_bigint (dbval1);
1313  break;
1314  case DB_TYPE_FLOAT:
1315  dtmp = db_get_float (dbval1);
1316  break;
1317  case DB_TYPE_DOUBLE:
1318  dtmp = db_get_double (dbval1);
1319  break;
1320  case DB_TYPE_NUMERIC:
1322  break;
1323  case DB_TYPE_MONETARY:
1324  dtmp = (db_get_monetary (dbval1))->amount;
1325  break;
1326  default:
1327  assert (false);
1329  err_status = ER_GENERIC_ERROR;
1330  goto exit;
1331  } /* switch */
1332 
1333  /* bi, dtmp and itmp have the default value set to 0, so temp_bigint will hold the numeric representation of the
1334  * first argument, regardless of its type. */
1335  temp_bigint = bi + (DB_BIGINT) round (fmod (dtmp, 0x100000000)) + itmp;
1336 
1337  if (temp_bigint >= 0)
1338  {
1339  temp_arg = DB_UINT32_MAX & temp_bigint;
1340  }
1341  else
1342  {
1343  temp_arg = DB_UINT32_MAX & (-temp_bigint);
1344  temp_arg = DB_UINT32_MAX - temp_arg + 1;
1345  }
1346  uint_arg = temp_arg;
1347 
1348  if (temp_arg == 0)
1349  {
1350  num_byte_count = 1;
1351  }
1352  else
1353  {
1354  while (temp_arg > 0)
1355  {
1356  num_byte_count++;
1357  temp_arg >>= 8;
1358  }
1359  }
1360 
1361  num_as_bytes = (char *) db_private_alloc (NULL, (1 + num_byte_count) * sizeof (char));
1362  if (num_as_bytes == NULL)
1363  {
1364  err_status = ER_OUT_OF_VIRTUAL_MEMORY;
1365  goto exit;
1366  }
1367  temp_arg = uint_arg;
1368 
1369  for (i = num_byte_count - 1; i >= 0; i--)
1370  {
1371  num_as_bytes[i] = (char) (temp_arg & 0xFF);
1372  temp_arg >>= 8;
1373  }
1374  num_as_bytes[num_byte_count] = '\0';
1375 
1376  if ((codeset == INTL_CODESET_UTF8
1377  && intl_check_utf8 ((const unsigned char *) num_as_bytes, num_byte_count, &invalid_pos) != INTL_UTF8_VALID)
1378  || (codeset == INTL_CODESET_KSC5601_EUC
1379  && intl_check_euckr ((const unsigned char *) num_as_bytes, num_byte_count, &invalid_pos) != INTL_UTF8_VALID))
1380  {
1381  db_make_null (res);
1382  db_private_free (NULL, num_as_bytes);
1383 
1385  {
1386  er_clear ();
1387  err_status = NO_ERROR;
1388  }
1389  else
1390  {
1392  err_status = ER_OBJ_INVALID_ARGUMENTS;
1393  }
1394  goto exit;
1395  }
1396 
1397  collation = LANG_GET_BINARY_COLLATION (codeset);
1398 
1399  db_make_varchar (res, DB_DEFAULT_PRECISION, num_as_bytes, num_byte_count, codeset, collation);
1400  res->need_clear = true;
1401 
1402 exit:
1403  return err_status;
1404 }
1405 
1406 /*
1407  * db_string_instr () -
1408  *
1409  * Arguments:
1410  * sub_string: String fragment to search for within <src_string>.
1411  * src_string: String to be searched.
1412  * result: Character or bit position of the first <sub_string>
1413  * occurance.
1414  *
1415  * Returns: int
1416  *
1417  * Errors:
1418  * ER_QSTR_INVALID_DATA_TYPE :
1419  * <sub_string> or <src_string> are not a character strings.
1420  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
1421  * <sub_string> and <src_string> have different character
1422  * code sets, or are not both bit strings.
1423  *
1424  */
1425 
1426 int
1427 db_string_instr (const DB_VALUE * src_string, const DB_VALUE * sub_string, const DB_VALUE * start_pos,
1428  DB_VALUE * result)
1429 {
1430  int error_status = NO_ERROR;
1431  DB_TYPE str1_type, str2_type;
1432  DB_TYPE arg3_type;
1433 
1434  /*
1435  * Assert that DB_VALUE structures have been allocated.
1436  */
1437  assert (src_string != (DB_VALUE *) NULL);
1438  assert (sub_string != (DB_VALUE *) NULL);
1439  assert (start_pos != (DB_VALUE *) NULL);
1440  assert (result != (DB_VALUE *) NULL);
1441 
1442  /*
1443  * Categorize the parameters into respective code sets.
1444  * Verify that the parameters are both character strings.
1445  * Verify that the input strings belong to compatible code sets.
1446  */
1447  str1_type = DB_VALUE_DOMAIN_TYPE (src_string);
1448  str2_type = DB_VALUE_DOMAIN_TYPE (sub_string);
1449  arg3_type = DB_VALUE_DOMAIN_TYPE (start_pos);
1450 
1451  if (DB_IS_NULL (src_string) || DB_IS_NULL (sub_string) || DB_IS_NULL (start_pos))
1452  {
1453  db_make_null (result);
1454  }
1455  else
1456  {
1457  if ((str1_type != DB_TYPE_STRING && str1_type != DB_TYPE_CHAR && str1_type != DB_TYPE_VARCHAR
1458  && str1_type != DB_TYPE_NCHAR && str1_type != DB_TYPE_VARNCHAR)
1459  || (str2_type != DB_TYPE_STRING && str2_type != DB_TYPE_CHAR && str2_type != DB_TYPE_VARCHAR
1460  && str2_type != DB_TYPE_NCHAR && str2_type != DB_TYPE_VARNCHAR)
1461  || (arg3_type != DB_TYPE_INTEGER && arg3_type != DB_TYPE_SHORT && arg3_type != DB_TYPE_BIGINT))
1462  {
1463  error_status = ER_QSTR_INVALID_DATA_TYPE;
1464  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
1465  }
1466  else if (qstr_get_category (src_string) != qstr_get_category (sub_string)
1467  || (db_get_string_codeset (src_string) != db_get_string_codeset (sub_string)))
1468  {
1469  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
1470  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
1471  }
1472  else
1473  {
1474  int position = 0;
1475  int src_str_len;
1476  int sub_str_len;
1477  int offset = db_get_int (start_pos);
1478  INTL_CODESET codeset = (INTL_CODESET) db_get_string_codeset (src_string);
1479  const char *search_from, *src_buf, *sub_str;
1480  int coll_id;
1481  int sub_str_size = db_get_string_size (sub_string);
1482  int from_byte_offset;
1483  int src_size = db_get_string_size (src_string);
1484 
1485  LANG_RT_COMMON_COLL (db_get_string_collation (src_string), db_get_string_collation (sub_string), coll_id);
1486  if (coll_id == -1)
1487  {
1490  }
1491 
1492  src_str_len = db_get_string_length (src_string);
1493  sub_str_len = db_get_string_length (sub_string);
1494 
1495  src_buf = db_get_string (src_string);
1496  if (src_size < 0)
1497  {
1498  src_size = strlen (src_buf);
1499  }
1500 
1501  sub_str = db_get_string (sub_string);
1502  if (sub_str_size < 0)
1503  {
1504  sub_str_size = strlen (sub_str);
1505  }
1506 
1507  if (offset > 0)
1508  {
1509  offset--;
1510  if (offset + sub_str_len > src_str_len)
1511  { /* out of bound */
1512  position = 0;
1513  }
1514  else
1515  {
1516  search_from = src_buf;
1517 
1518  intl_char_size ((unsigned char *) search_from, offset, codeset, &from_byte_offset);
1519  search_from += from_byte_offset;
1520 
1521  intl_char_count ((unsigned char *) search_from, src_size - from_byte_offset, codeset, &src_str_len);
1522 
1523  /* forward search */
1524  error_status =
1525  qstr_position (sub_str, sub_str_size, sub_str_len, search_from, src_buf + src_size,
1526  src_buf + src_size, src_str_len, coll_id, true, &position);
1527  position += (position != 0) ? offset : 0;
1528  }
1529  }
1530  else if (offset < 0)
1531  {
1532  if (src_str_len + offset + 1 < sub_str_len)
1533  {
1534  position = 0;
1535  }
1536  else
1537  {
1538  int real_offset = src_str_len + offset - (sub_str_len - 1);
1539 
1540  search_from = src_buf;
1541 
1542  intl_char_size ((unsigned char *) search_from, real_offset, codeset, &from_byte_offset);
1543 
1544  search_from += from_byte_offset;
1545 
1546  /* backward search */
1547  error_status =
1548  qstr_position (sub_str, sub_str_size, sub_str_len, search_from, src_buf + src_size, src_buf,
1549  src_str_len + offset + 1, coll_id, false, &position);
1550  if (position != 0)
1551  {
1552  position = src_str_len - (-offset - 1) - (position - 1) - (sub_str_len - 1);
1553  }
1554  }
1555  }
1556  else
1557  {
1558  /* offset == 0 */
1559  position = 0;
1560  }
1561 
1562  if (error_status == NO_ERROR)
1563  {
1564  db_make_int (result, position);
1565  }
1566  }
1567  }
1568 
1569  return error_status;
1570 }
1571 
1572 /*
1573  * db_string_space () -
1574  * returns a VARCHAR string consisting of a number of space characters equals
1575  * to the given argument
1576  *
1577  * Arguments:
1578  * count: number of space characters in the returned string
1579  *
1580  * Returns: int
1581  *
1582  * Errors:
1583  * ER_QSTR_INVALID_DATA_TYPE: count is not a discrete numeric type (integer)
1584  * .... ...
1585  */
1586 
1587 int
1589 {
1590  assert (count != (DB_VALUE *) NULL);
1591  assert (result != (DB_VALUE *) NULL);
1592 
1593  if (DB_IS_NULL (count))
1594  {
1595  db_make_null (result);
1596  return NO_ERROR;
1597  }
1598  else
1599  {
1600  int len = 0;
1601  char *space_string_p = NULL;
1602 
1603  switch (DB_VALUE_DOMAIN_TYPE (count))
1604  {
1605  case DB_TYPE_SMALLINT:
1606  len = db_get_short (count);
1607  break;
1608  case DB_TYPE_INTEGER:
1609  len = db_get_int (count);
1610  break;
1611  case DB_TYPE_BIGINT:
1612  len = (int) db_get_bigint (count);
1613  break;
1614  default:
1616  }
1617 
1618  if (len < 0)
1619  {
1620  len = 0;
1621  }
1622 
1624  {
1627  db_make_null (result);
1628  return NO_ERROR;
1629  }
1630 
1631  space_string_p = (char *) db_private_alloc (NULL, len + 1);
1632 
1633  if (space_string_p)
1634  {
1635  if (len > 64)
1636  {
1637  /* if string is longer than 64 chars use memset to initialize it */
1638  memset (space_string_p, ' ', len);
1639  }
1640  else
1641  {
1642  int i = 0;
1643 
1644  while (i < len)
1645  space_string_p[i++] = ' ';
1646  }
1647  space_string_p[len] = '\0';
1648 
1649  qstr_make_typed_string (DB_TYPE_VARCHAR, result, len, space_string_p, len, LANG_COERCIBLE_CODESET,
1651  result->need_clear = true;
1652  return NO_ERROR;
1653  }
1654  else
1655  {
1656  assert (er_errid () != NO_ERROR);
1657  return er_errid ();
1658  }
1659  }
1660 }
1661 
1662 /*
1663  * db_string_position () -
1664  *
1665  * Arguments:
1666  * sub_string: String fragment to search for within <src_string>.
1667  * src_string: String to be searched.
1668  * result: Character or bit position of the first <sub_string>
1669  * occurance.
1670  *
1671  * Returns: int
1672  *
1673  * Errors:
1674  * ER_QSTR_INVALID_DATA_TYPE :
1675  * <sub_string> or <src_string> are not a character strings.
1676  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
1677  * <sub_string> and <src_string> have different character
1678  * code sets, or are not both bit strings.
1679  *
1680  */
1681 
1682 int
1683 db_string_position (const DB_VALUE * sub_string, const DB_VALUE * src_string, DB_VALUE * result)
1684 {
1685  int error_status = NO_ERROR;
1686  DB_TYPE str1_type, str2_type;
1687 
1688  /*
1689  * Assert that DB_VALUE structures have been allocated.
1690  */
1691  assert (sub_string != (DB_VALUE *) NULL);
1692  assert (src_string != (DB_VALUE *) NULL);
1693  assert (result != (DB_VALUE *) NULL);
1694 
1695 
1696  /*
1697  * Categorize the parameters into respective code sets.
1698  * Verify that the parameters are both character strings.
1699  * Verify that the input strings belong to compatible code sets.
1700  */
1701  str1_type = DB_VALUE_DOMAIN_TYPE (sub_string);
1702  str2_type = DB_VALUE_DOMAIN_TYPE (src_string);
1703 
1704  if (DB_IS_NULL (sub_string) || DB_IS_NULL (src_string))
1705  {
1706  db_make_null (result);
1707  }
1708  else if (!QSTR_IS_ANY_CHAR_OR_BIT (str1_type) || !QSTR_IS_ANY_CHAR_OR_BIT (str2_type))
1709  {
1710  error_status = ER_QSTR_INVALID_DATA_TYPE;
1711  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
1712  }
1713  else if ((qstr_get_category (sub_string) != qstr_get_category (src_string))
1714  || (db_get_string_codeset (src_string) != db_get_string_codeset (sub_string)))
1715  {
1716  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
1717  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
1718  }
1719  else
1720  {
1721  int position;
1722  DB_TYPE src_type = DB_VALUE_DOMAIN_TYPE (src_string);
1723 
1724  if (QSTR_IS_CHAR (src_type) || QSTR_IS_NATIONAL_CHAR (src_type))
1725  {
1726  const char *src_str = db_get_string (src_string);
1727  int src_size = db_get_string_size (src_string);
1728  const char *sub_str = db_get_string (sub_string);
1729  int sub_size = db_get_string_size (sub_string);
1730  int coll_id;
1731 
1732  LANG_RT_COMMON_COLL (db_get_string_collation (src_string), db_get_string_collation (sub_string), coll_id);
1733  if (coll_id == -1)
1734  {
1737  }
1738 
1739  if (src_size < 0)
1740  {
1741  src_size = strlen (src_str);
1742  }
1743 
1744  if (sub_size < 0)
1745  {
1746  sub_size = strlen (sub_str);
1747  }
1748 
1749  error_status = qstr_position (sub_str, sub_size, db_get_string_length (sub_string), src_str,
1750  src_str + src_size, src_str + src_size, db_get_string_length (src_string),
1751  coll_id, true, &position);
1752  }
1753  else
1754  {
1755  error_status = qstr_bit_position (DB_GET_UCHAR (sub_string), db_get_string_length (sub_string),
1756  DB_GET_UCHAR (src_string), db_get_string_length (src_string), &position);
1757  }
1758 
1759  if (error_status == NO_ERROR)
1760  {
1761  db_make_int (result, position);
1762  }
1763  }
1764 
1765  return error_status;
1766 }
1767 
1768 /*
1769  * db_string_substring
1770  *
1771  * Arguments:
1772  * src_string: String from which extraction will occur.
1773  * start_pos: Character position to begin extraction from.
1774  * extraction_length: Number of characters to extract (Optional).
1775  * sub_string: Extracted subtring is returned here.
1776  *
1777  * Returns: int
1778  *
1779  * Errors:
1780  * ER_QSTR_INVALID_DATA_TYPE :
1781  * <src_string> is not a string type,
1782  * <start_pos> or <extraction_length> is not an integer type
1783  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
1784  * <src_string> have different character
1785  * code sets or are not both bit strings.
1786  *
1787  */
1788 
1789 int
1790 db_string_substring (const MISC_OPERAND substr_operand, const DB_VALUE * src_string, const DB_VALUE * start_position,
1791  const DB_VALUE * extraction_length, DB_VALUE * sub_string)
1792 {
1793  int error_status = NO_ERROR;
1794  int extraction_length_is_null = false;
1795  DB_TYPE result_type;
1796  DB_TYPE src_type;
1797 
1798  /*
1799  * Assert that DB_VALUE structures have been allocated.
1800  */
1801  assert (src_string != (DB_VALUE *) NULL);
1802  assert (start_position != (DB_VALUE *) NULL);
1803  assert (sub_string != (DB_VALUE *) NULL);
1804 
1805  src_type = DB_VALUE_DOMAIN_TYPE (src_string);
1806 
1807  if ((extraction_length == NULL) || DB_IS_NULL (extraction_length))
1808  {
1809  extraction_length_is_null = true;
1810  }
1811 
1812  if (QSTR_IS_CHAR (src_type))
1813  {
1814  result_type = DB_TYPE_VARCHAR;
1815  }
1816  else if (QSTR_IS_NATIONAL_CHAR (src_type))
1817  {
1818  result_type = DB_TYPE_VARNCHAR;
1819  }
1820  else
1821  {
1822  result_type = DB_TYPE_VARBIT;
1823  }
1824 
1825  if (DB_IS_NULL (src_string) || DB_IS_NULL (start_position))
1826  {
1827 #if defined(SERVER_MODE)
1828  assert (DB_IS_NULL (sub_string));
1829 #endif
1830  db_make_null (sub_string);
1831  }
1832  else
1833  {
1834  if (!QSTR_IS_ANY_CHAR_OR_BIT (src_type) || !is_integer (start_position)
1835  || (!extraction_length_is_null && !is_integer (extraction_length)))
1836  {
1837  error_status = ER_QSTR_INVALID_DATA_TYPE;
1838  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
1839  }
1840  else
1841  {
1842  unsigned char *sub;
1843  int sub_length;
1844 
1845  int extract_nchars = -1;
1846 
1847  if (!extraction_length_is_null)
1848  {
1849  extract_nchars = (int) db_get_int (extraction_length);
1850  }
1851 
1852  /* Initialize the memory manager of the substring */
1853  if (QSTR_IS_CHAR (src_type) || QSTR_IS_NATIONAL_CHAR (src_type))
1854  {
1855  int sub_size = 0;
1856 
1857  const unsigned char *string = DB_GET_UCHAR (src_string);
1858  int start_offset = db_get_int (start_position);
1859  int string_len = db_get_string_length (src_string);
1860 
1861  if (extraction_length_is_null)
1862  {
1863  extract_nchars = string_len;
1864  }
1865 
1866  if (substr_operand == SUBSTR)
1867  {
1868  if (extract_nchars < 0 || string_len < ABS (start_offset))
1869  {
1870  return error_status;
1871  }
1872 
1873  if (start_offset < 0)
1874  {
1875  int byte_pos;
1876  (void) intl_char_size (string, string_len + start_offset, db_get_string_codeset (src_string),
1877  &byte_pos);
1878  string += byte_pos;
1879  string_len = -start_offset;
1880  }
1881  }
1882 
1883  error_status = qstr_substring (string, string_len, start_offset, extract_nchars,
1884  db_get_string_codeset (src_string), &sub, &sub_length, &sub_size);
1885  if (error_status == NO_ERROR && sub != NULL)
1886  {
1887  qstr_make_typed_string (result_type, sub_string, DB_VALUE_PRECISION (src_string), (char *) sub,
1888  sub_size, db_get_string_codeset (src_string),
1889  db_get_string_collation (src_string));
1890  sub[sub_size] = 0;
1891  sub_string->need_clear = true;
1892  }
1893  }
1894  else
1895  {
1896  error_status = qstr_bit_substring (DB_GET_UCHAR (src_string), (int) db_get_string_length (src_string),
1897  (int) db_get_int (start_position), extract_nchars, &sub, &sub_length);
1898  if (error_status == NO_ERROR)
1899  {
1900  qstr_make_typed_string (result_type, sub_string, DB_VALUE_PRECISION (src_string), (char *) sub,
1901  sub_length, db_get_string_codeset (src_string),
1902  db_get_string_collation (src_string));
1903  sub_string->need_clear = true;
1904  }
1905  }
1906  }
1907  }
1908 
1909  return error_status;
1910 }
1911 
1912 static char
1914 {
1915  switch (c)
1916  {
1917  case '\b':
1918  return 'b';
1919  case '\f':
1920  return 'f';
1921  case '\n':
1922  return 'n';
1923  case '\r':
1924  return 'r';
1925  case '\t':
1926  return 't';
1927  default:
1928  return c;
1929  }
1930 }
1931 
1932 int
1933 db_string_escape_str (const char *src_str, size_t src_size, char **res_string, size_t * dest_size)
1934 {
1935  size_t dest_crt_pos;
1936  size_t src_last_pos;
1937 
1938  // *INDENT-OFF*
1939  std::vector<size_t> special_idx;
1940  // *INDENT-ON*
1941  for (size_t i = 0; i < src_size; ++i)
1942  {
1943  unsigned char uc = (unsigned char) src_str[i];
1944  if (ESCAPE_CHAR (uc))
1945  {
1946  special_idx.push_back (i);
1947  }
1948  }
1949  *dest_size = src_size + special_idx.size () + 2 /* quotes */ + 1 /* string terminator */ ;
1950  char *result = (char *) db_private_alloc (NULL, *dest_size);
1951  if (result == NULL)
1952  {
1953  return ER_OUT_OF_VIRTUAL_MEMORY;
1954  }
1955 
1956  result[0] = '"';
1957  dest_crt_pos = 1;
1958  src_last_pos = 0;
1959  for (size_t i = 0; i < special_idx.size (); ++i)
1960  {
1961  size_t len = special_idx[i] - src_last_pos;
1962  if (len > 0)
1963  {
1964  memcpy (&result[dest_crt_pos], &src_str[src_last_pos], len);
1965  result[dest_crt_pos] = db_string_escape_char (result[dest_crt_pos]);
1966  dest_crt_pos += len;
1967  }
1968  result[dest_crt_pos] = '\\';
1969  ++dest_crt_pos;
1970  src_last_pos = special_idx[i];
1971  }
1972 
1973  memcpy (&result[dest_crt_pos], &src_str[src_last_pos], src_size - src_last_pos);
1974  result[dest_crt_pos] = db_string_escape_char (result[dest_crt_pos]);
1975  result[*dest_size - 2] = '"';
1976  result[*dest_size - 1] = '\0';
1977 
1978  *res_string = result;
1979  return NO_ERROR;
1980 }
1981 
1982 
1983 /*
1984  * db_string_quote - escape a string and surround it with quotes
1985  * return: If success, return 0.
1986  * src(in): str
1987  * res(out): quoted string
1988  * Note:
1989  */
1990 int
1991 db_string_quote (const DB_VALUE * str, DB_VALUE * res)
1992 {
1993  if (DB_IS_NULL (str))
1994  {
1995  return db_make_null (res);
1996  }
1997  else
1998  {
1999  char *escaped_string = NULL;
2000  size_t escaped_string_size;
2001  int error_code =
2002  db_string_escape_str (db_get_string (str), db_get_string_size (str), &escaped_string, &escaped_string_size);
2003  if (error_code)
2004  {
2005  return error_code;
2006  }
2007 
2008  db_make_null (res);
2009  DB_TYPE result_type = DB_TYPE_VARCHAR;
2010  qstr_make_typed_string (result_type, res, TP_FLOATING_PRECISION_VALUE, escaped_string,
2011  (int) escaped_string_size - 1, db_get_string_codeset (str),
2012  db_get_string_collation (str));
2013 
2014  res->need_clear = true;
2015  return NO_ERROR;
2016  }
2017 }
2018 
2019 /*
2020  * db_string_repeat
2021  *
2022  * Arguments:
2023  * src_string: String which repeats itself.
2024  * count: Number of repetitions.
2025  * result: string containing the repeated original.
2026  *
2027  * Returns: int
2028  *
2029  * Errors:
2030  * ER_QSTR_INVALID_DATA_TYPE :
2031  * <src_string> is not a string type,
2032  * <start_pos> or <extraction_length> is not an integer type
2033  *
2034  */
2035 
2036 int
2037 db_string_repeat (const DB_VALUE * src_string, const DB_VALUE * count, DB_VALUE * result)
2038 {
2039  int error_status = NO_ERROR;
2040  int src_length, count_i = 0, src_size = 0;
2041  DB_TYPE result_type = DB_TYPE_NULL;
2042  DB_TYPE src_type;
2043  INTL_CODESET codeset;
2044 
2045  /*
2046  * Assert that DB_VALUE structures have been allocated.
2047  */
2048  assert (src_string != (DB_VALUE *) NULL);
2049  assert (count != (DB_VALUE *) NULL);
2050  assert (result != (DB_VALUE *) NULL);
2051 
2052  assert (!DB_IS_NULL (src_string) && !DB_IS_NULL (count));
2053 
2054  src_type = DB_VALUE_DOMAIN_TYPE (src_string);
2055  src_length = (int) db_get_string_length (src_string);
2056  count_i = db_get_int (count);
2057  codeset = db_get_string_codeset (src_string);
2058 
2059  if (QSTR_IS_CHAR (src_type))
2060  {
2061  result_type = DB_TYPE_VARCHAR;
2062  }
2063  else if (QSTR_IS_NATIONAL_CHAR (src_type))
2064  {
2065  result_type = DB_TYPE_VARNCHAR;
2066  }
2067 
2068  src_size = db_get_string_size (src_string);
2069  if (src_size < 0)
2070  {
2071  intl_char_size (DB_GET_UCHAR (result), src_length, codeset, &src_size);
2072  }
2073 
2074  if (!QSTR_IS_ANY_CHAR (src_type) || !is_integer (count))
2075  {
2076  error_status = ER_QSTR_INVALID_DATA_TYPE;
2077  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
2078  }
2079  else if (count_i <= 0 || src_length <= 0)
2080  {
2081  error_status =
2082  db_string_make_empty_typed_string (result, result_type, src_length, db_get_string_codeset (src_string),
2083  db_get_string_collation (src_string));
2084  if (error_status != NO_ERROR)
2085  {
2086  return error_status;
2087  }
2088  }
2089  else
2090  {
2091  DB_VALUE dummy;
2092  char *res_ptr;
2093  const char *src_ptr;
2094  DB_BIGINT new_length, expected_size;
2095 
2096  /* init dummy */
2097  db_make_null (&dummy);
2098  /* create an empy string for result */
2099 
2100  new_length = (DB_BIGINT) src_length *count_i;
2101  if (OR_CHECK_INT_OVERFLOW (new_length))
2102  {
2104  return ER_PRECISION_OVERFLOW;
2105  }
2106 
2107  error_status =
2108  db_string_make_empty_typed_string (&dummy, result_type, (int) new_length,
2109  db_get_string_codeset (src_string), db_get_string_collation (src_string));
2110  if (error_status != NO_ERROR)
2111  {
2112  return error_status;
2113  }
2114 
2117  {
2118  /* intermediate value : clear is_null flag */
2119  dummy.domain.general_info.is_null = 0;
2120  }
2121 
2122  expected_size = src_size * count_i;
2123  if (OR_CHECK_INT_OVERFLOW (expected_size))
2124  {
2128  }
2129 
2130  error_status = qstr_grow_string (&dummy, result, (int) expected_size);
2131  if (error_status < 0)
2132  {
2133  pr_clear_value (&dummy);
2134  return error_status;
2135  }
2136  /* qstr_grow_string may return DB_NULL if size too big */
2137  if (DB_IS_NULL (result))
2138  {
2139  pr_clear_value (&dummy);
2140  return NO_ERROR;
2141  }
2142 
2143  pr_clear_value (&dummy);
2144 
2145  res_ptr = CONST_CAST (char *, db_get_string (result));
2146  src_ptr = db_get_string (src_string);
2147 
2148  while (count_i--)
2149  {
2150  memcpy (res_ptr, src_ptr, src_size);
2151  res_ptr += src_size;
2152  }
2153 
2154  /* update size of string */
2155  qstr_make_typed_string (result_type, result, DB_VALUE_PRECISION (result), db_get_string (result),
2156  (int) expected_size, db_get_string_codeset (src_string),
2157  db_get_string_collation (src_string));
2158  result->need_clear = true;
2159 
2160  }
2161 
2162  return error_status;
2163 }
2164 
2165 /*
2166  * db_string_substring_index - returns the substring from a string before
2167  * count occurences of delimeter
2168  *
2169  * Arguments:
2170  * src_string: String to search in.
2171  * delim_string: String delimiter
2172  * count: Number of occurences.
2173  * result: string containing reminder.
2174  *
2175  * Returns: int
2176  *
2177  * Errors:
2178  * ER_QSTR_INVALID_DATA_TYPE :
2179  * <str_string> or <delim_string> is not a string type,
2180  * <count> is not an integer type
2181  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
2182  * <str_string> or <delim_string> are not compatible
2183  *
2184  */
2185 
2186 int
2187 db_string_substring_index (DB_VALUE * src_string, DB_VALUE * delim_string, const DB_VALUE * count, DB_VALUE * result)
2188 {
2189  QSTR_CATEGORY src_categ, delim_categ;
2190  int error_status = NO_ERROR, count_i = 0;
2191  DB_TYPE src_type, delim_type;
2192  DB_VALUE empty_string1, empty_string2;
2193  INTL_CODESET src_cs, delim_cs;
2194  int src_coll, delim_coll;
2195 
2196  /*
2197  * Initialize status value
2198  */
2199  db_make_null (result);
2200  db_make_null (&empty_string1);
2201  db_make_null (&empty_string2);
2202 
2203  /*
2204  * Assert that DB_VALUE structures have been allocated.
2205  */
2206  assert (src_string != (DB_VALUE *) NULL);
2207  assert (delim_string != (DB_VALUE *) NULL);
2208  assert (count != (DB_VALUE *) NULL);
2209  assert (result != (DB_VALUE *) NULL);
2210 
2211  if (DB_IS_NULL (count))
2212  {
2213  db_make_null (result);
2214 
2215  return NO_ERROR;
2216  }
2217  count_i = db_get_int (count);
2218 
2219  /*
2220  * Categorize the parameters into respective code sets.
2221  * Verify that the parameters are both character strings.
2222  * Verify that the input strings belong to compatible code sets.
2223  */
2224  src_categ = qstr_get_category (src_string);
2225  delim_categ = qstr_get_category (delim_string);
2226 
2227  src_type = DB_VALUE_DOMAIN_TYPE (src_string);
2228  delim_type = DB_VALUE_DOMAIN_TYPE (delim_string);
2229 
2230  src_cs = DB_IS_NULL (src_string) ? LANG_SYS_CODESET : db_get_string_codeset (src_string);
2231  src_coll = DB_IS_NULL (src_string) ? LANG_SYS_COLLATION : db_get_string_collation (src_string);
2232 
2233  delim_cs = DB_IS_NULL (delim_string) ? LANG_SYS_CODESET : db_get_string_codeset (delim_string);
2234  delim_coll = DB_IS_NULL (delim_string) ? LANG_SYS_COLLATION : db_get_string_collation (delim_string);
2235 
2237  {
2238  if (DB_IS_NULL (src_string))
2239  {
2240  if (DB_IS_NULL (delim_string))
2241  {
2242  /* both strings are NULL (or empty): result is DB_TYPE_NULL */
2243  assert (error_status == NO_ERROR);
2244  goto empty_string;
2245  }
2246  /* convert to empty string */
2247  src_string = &empty_string1;
2248 
2249  src_type = delim_type;
2250  src_categ = delim_categ;
2251 
2252  error_status =
2253  db_string_make_empty_typed_string (src_string, src_type, TP_FLOATING_PRECISION_VALUE, delim_cs, delim_coll);
2254 
2255  if (error_status != NO_ERROR)
2256  {
2257  goto exit;
2258  }
2259 
2260  /* intermediate value : clear is_null flag */
2261  if (QSTR_IS_ANY_CHAR_OR_BIT (DB_VALUE_DOMAIN_TYPE (src_string)))
2262  {
2263  src_string->domain.general_info.is_null = 0;
2264  }
2265  }
2266 
2267  if (DB_IS_NULL (delim_string))
2268  {
2269  /* convert to empty string */
2270  delim_string = &empty_string2;
2271 
2272  delim_type = src_type;
2273  delim_categ = src_categ;
2274 
2275  error_status =
2276  db_string_make_empty_typed_string (delim_string, delim_type, TP_FLOATING_PRECISION_VALUE, src_cs, src_coll);
2277  if (error_status != NO_ERROR)
2278  {
2279  goto exit;
2280  }
2281 
2282  /* intermediate value : clear is_null flag */
2283  if (QSTR_IS_ANY_CHAR_OR_BIT (DB_VALUE_DOMAIN_TYPE (delim_string)))
2284  {
2285  delim_string->domain.general_info.is_null = 0;
2286  }
2287  }
2288  }
2289  else if (DB_IS_NULL (src_string) || DB_IS_NULL (delim_string))
2290  {
2291  goto exit;
2292  }
2293 
2294  if (!QSTR_IS_ANY_CHAR (src_type) || !QSTR_IS_ANY_CHAR (delim_type))
2295  {
2296  error_status = ER_QSTR_INVALID_DATA_TYPE;
2297  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
2298  }
2299  else if ((src_categ != delim_categ) || (src_cs != delim_cs))
2300  {
2301  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
2302  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
2303  }
2304  else if (count_i == 0)
2305  {
2306  /* return an empty string */
2307  goto empty_string;
2308  }
2309  else
2310  {
2311  DB_VALUE offset_val, interm_pos;
2312  int offset = 1, initial_count = 0;
2313  bool count_from_start;
2314  const int src_length = db_get_string_length (src_string);
2315  const int delim_length = db_get_string_length (delim_string);
2316 
2317  db_make_null (&interm_pos);
2318  initial_count = count_i;
2319  count_from_start = (count_i > 0) ? true : false;
2320  count_i = abs (count_i);
2321 
2322  assert (src_cs == delim_cs);
2323 
2324  if (count_from_start)
2325  {
2326  while (count_i > 0)
2327  {
2328  db_make_int (&offset_val, offset);
2329  error_status = db_string_instr (src_string, delim_string, &offset_val, &interm_pos);
2330  if (error_status < 0)
2331  {
2332  goto exit;
2333  }
2334  offset = db_get_int (&interm_pos);
2335  if (offset != 0)
2336  {
2337  offset += delim_length;
2338  db_make_int (&offset_val, offset);
2339  }
2340  else
2341  {
2342  break;
2343  }
2344  count_i--;
2345  }
2346 
2347  }
2348  else
2349  {
2350  while (count_i > 0)
2351  {
2352  /* search from end */
2353  db_make_int (&offset_val, -offset);
2354  error_status = db_string_instr (src_string, delim_string, &offset_val, &interm_pos);
2355  if (error_status < 0)
2356  {
2357  goto exit;
2358  }
2359  offset = db_get_int (&interm_pos);
2360  if (offset != 0)
2361  {
2362  /* adjust offset to indicate position relative to end */
2363  offset = src_length - offset + 2;
2364  db_make_int (&offset_val, offset);
2365  }
2366  else
2367  {
2368  break;
2369  }
2370  count_i--;
2371  }
2372  }
2373 
2374  assert (count_i >= 0);
2375 
2376  if (count_i == 0)
2377  {
2378  /* found count occurences , return the string */
2379  DB_VALUE start_val, len_val;
2380  int start_pos = 1, end_pos = 0;
2381 
2382  if (count_from_start)
2383  {
2384  start_pos = 1;
2385  end_pos = offset - delim_length - 1;
2386  }
2387  else
2388  {
2389  start_pos = src_length - offset + 2 + delim_length;
2390  end_pos = src_length;
2391  }
2392 
2393  if (start_pos > end_pos || start_pos < 1 || end_pos > src_length)
2394  {
2395  /* empty string */
2396  goto empty_string;
2397  }
2398  else
2399  {
2400  db_make_int (&start_val, start_pos);
2401  db_make_int (&len_val, end_pos - start_pos + 1);
2402 
2403  error_status = db_string_substring (SUBSTRING, src_string, &start_val, &len_val, result);
2404 
2405  result->need_clear = true;
2406  if (error_status < 0)
2407  {
2408  goto exit;
2409  }
2410  }
2411  }
2412  else
2413  {
2414  assert (count_i > 0);
2415  /* not found at all or not enough number of occurences */
2416  /* return the entire source string */
2417 
2418  error_status = pr_clone_value ((DB_VALUE *) src_string, result);
2419  if (src_type == DB_TYPE_CHAR || src_type == DB_TYPE_NCHAR)
2420  {
2421  /* convert CHARACTER(N) to CHARACTER VARYING(N) */
2423  DB_VALUE_PRECISION (result), db_get_string (result), db_get_string_size (result),
2424  src_cs, src_coll);
2425  result->need_clear = true;
2426  }
2427 
2428  if (error_status < 0)
2429  {
2430  goto exit;
2431  }
2432  }
2433  }
2434 
2435  pr_clear_value (&empty_string1);
2436  pr_clear_value (&empty_string2);
2437 
2438  return error_status;
2439 
2440 empty_string:
2441  /* the result should always be varying type string */
2442  if (src_type == DB_TYPE_CHAR)
2443  {
2444  src_type = DB_TYPE_VARCHAR;
2445  }
2446  else if (src_type == DB_TYPE_NCHAR)
2447  {
2448  src_type = DB_TYPE_VARNCHAR;
2449  }
2450  error_status = db_string_make_empty_typed_string (result, src_type, TP_FLOATING_PRECISION_VALUE, src_cs, src_coll);
2451  pr_clear_value (&empty_string1);
2452  pr_clear_value (&empty_string2);
2453 
2454  return error_status;
2455 
2456 exit:
2457  pr_clear_value (&empty_string1);
2458  pr_clear_value (&empty_string2);
2459 
2460  return error_status;
2461 }
2462 
2463 /*
2464  * db_string_shaone - sha1 encrypt function
2465  * return: If success, return 0.
2466  * src(in): source string
2467  * result(out): the encrypted data.
2468  * Note:
2469  */
2470 int
2471 db_string_sha_one (DB_VALUE const *src, DB_VALUE * result)
2472 {
2473  int error_status = NO_ERROR;
2474  char *result_strp = NULL;
2475  int result_len = 0;
2476 
2477  assert (src != (DB_VALUE *) NULL);
2478  assert (result != (DB_VALUE *) NULL);
2479 
2480  if (DB_IS_NULL (src))
2481  {
2482  db_make_null (result); /* SH1(NULL) returns NULL */
2483  return error_status;
2484  }
2485  else
2486  {
2487  DB_TYPE val_type = DB_VALUE_DOMAIN_TYPE (src);
2488 
2489  if (QSTR_IS_ANY_CHAR (val_type))
2490  {
2491  error_status = crypt_sha_one (NULL, db_get_string (src), db_get_string_size (src), &result_strp, &result_len);
2492  if (error_status != NO_ERROR)
2493  {
2494  goto error;
2495  }
2496 
2497  qstr_make_typed_string (DB_TYPE_CHAR, result, result_len, result_strp, result_len,
2499  result->need_clear = true;
2500  }
2501  else
2502  {
2503  error_status = ER_QSTR_INVALID_DATA_TYPE;
2504  goto error;
2505  }
2506  }
2507 
2508  return error_status;
2509 
2510 error:
2511  db_make_null (result);
2513  {
2514  er_clear ();
2515  return NO_ERROR;
2516  }
2517  else
2518  {
2519  if (er_errid () == NO_ERROR)
2520  {
2521  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
2522  }
2523  return error_status;
2524  }
2525 }
2526 
2527 /*
2528  * db_string_shatwo - sha2 encrypt function
2529  * return: If success, return 0.
2530  * src(in): source string
2531  * hash_len(in): the hash length
2532  * result(out): the encrypted data.
2533  * Note:
2534  */
2535 int
2536 db_string_sha_two (DB_VALUE const *src, DB_VALUE const *hash_len, DB_VALUE * result)
2537 {
2538  int error_status = NO_ERROR;
2539 
2540  DB_TYPE src_type = DB_VALUE_DOMAIN_TYPE (src);
2541  DB_TYPE hash_len_type = DB_VALUE_DOMAIN_TYPE (hash_len);
2542  char *result_strp = NULL;
2543  int result_len = 0;
2544  int len = 0;
2545 
2546  assert (src != (DB_VALUE *) NULL);
2547  assert (hash_len != (DB_VALUE *) NULL);
2548  assert (result != (DB_VALUE *) NULL);
2549 
2550  if (DB_IS_NULL (src) || DB_IS_NULL (hash_len))
2551  {
2552  db_make_null (result); /* sha2(NULL, ...) or sha2(..., NULL) returns NULL */
2553  return error_status;
2554  }
2555 
2556  switch (hash_len_type)
2557  {
2558  case DB_TYPE_SHORT:
2559  len = db_get_short (hash_len);
2560  break;
2561  case DB_TYPE_INTEGER:
2562  len = db_get_int (hash_len);
2563  break;
2564  case DB_TYPE_BIGINT:
2565  len = (int) db_get_bigint (hash_len);
2566  break;
2567  default:
2569  }
2570 
2571  if (QSTR_IS_ANY_CHAR (src_type))
2572  {
2573  error_status =
2574  crypt_sha_two (NULL, db_get_string (src), db_get_string_length (src), len, &result_strp, &result_len);
2575  if (error_status != NO_ERROR)
2576  {
2577  goto error;
2578  }
2579 
2580  /* It means that the hash_len is wrong. */
2581  if (result_strp == NULL)
2582  {
2583  db_make_null (result);
2584  return error_status;
2585  }
2586 
2587  qstr_make_typed_string (DB_TYPE_VARCHAR, result, result_len, result_strp, result_len, db_get_string_codeset (src),
2588  db_get_string_collation (src));
2589  result->need_clear = true;
2590  }
2591  else
2592  {
2593  error_status = ER_QSTR_INVALID_DATA_TYPE;
2594  goto error;
2595  }
2596 
2597  return error_status;
2598 
2599 error:
2600  db_make_null (result);
2602  {
2603  er_clear ();
2604  return NO_ERROR;
2605  }
2606  else
2607  {
2608  if (er_errid () == NO_ERROR)
2609  {
2610  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
2611  }
2612  return error_status;
2613  }
2614 }
2615 
2616 /*
2617  * db_string_aes_encrypt - aes encrypt function
2618  * return: If success, return 0.
2619  * src(in): source string
2620  * key(in): the encrypt key
2621  * result(out): the encrypted data.
2622  * Note:
2623  */
2624 int
2625 db_string_aes_encrypt (DB_VALUE const *src, DB_VALUE const *key, DB_VALUE * result)
2626 {
2627  int error_status = NO_ERROR;
2628 
2629  DB_TYPE src_type = DB_VALUE_DOMAIN_TYPE (src);
2630  DB_TYPE key_type = DB_VALUE_DOMAIN_TYPE (key);
2631  char *result_strp = NULL;
2632  int result_len = 0;
2633 
2634  assert (src != (DB_VALUE *) NULL);
2635  assert (key != (DB_VALUE *) NULL);
2636  assert (result != (DB_VALUE *) NULL);
2637 
2638  if (DB_IS_NULL (src) || DB_IS_NULL (key))
2639  {
2640  /* aes_encypt(NULL, ...) or aes_encypt(..., NULL) returns NULL */
2641  db_make_null (result);
2642  return error_status;
2643  }
2644 
2645  if (QSTR_IS_ANY_CHAR (src_type) && QSTR_IS_ANY_CHAR (key_type))
2646  {
2647  error_status =
2649  db_get_string_length (key), &result_strp, &result_len, AES_128_ECB);
2650  if (error_status != NO_ERROR)
2651  {
2652  goto error;
2653  }
2654 
2655  qstr_make_typed_string (DB_TYPE_VARCHAR, result, result_len, result_strp, result_len, db_get_string_codeset (src),
2656  db_get_string_collation (src));
2657  result->need_clear = true;
2658  }
2659  else
2660  {
2661  error_status = ER_QSTR_INVALID_DATA_TYPE;
2662  goto error;
2663  }
2664 
2665  return error_status;
2666 
2667 error:
2668  db_make_null (result);
2670  {
2671  er_clear ();
2672  return NO_ERROR;
2673  }
2674  else
2675  {
2676  if (er_errid () == NO_ERROR)
2677  {
2678  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
2679  }
2680  return error_status;
2681  }
2682 }
2683 
2684 /*
2685  * db_string_aes_decrypt - aes decrypt function
2686  * return: If success, return 0.
2687  * src(in): source string
2688  * key(in): the encrypt key
2689  * result(out): the decrypted data.
2690  * Note:
2691  */
2692 int
2693 db_string_aes_decrypt (DB_VALUE const *src, DB_VALUE const *key, DB_VALUE * result)
2694 {
2695  int error_status = NO_ERROR;
2696 
2697  DB_TYPE src_type = DB_VALUE_DOMAIN_TYPE (src);
2698  DB_TYPE key_type = DB_VALUE_DOMAIN_TYPE (key);
2699  char *result_strp = NULL;
2700  int result_len = 0;
2701 
2702  assert (src != (DB_VALUE *) NULL);
2703  assert (key != (DB_VALUE *) NULL);
2704  assert (result != (DB_VALUE *) NULL);
2705 
2706  if (DB_IS_NULL (src) || DB_IS_NULL (key))
2707  {
2708  /* aes_decypt(NULL, ...) or aes_decypt(..., NULL) returns NULL */
2709  db_make_null (result);
2710  return error_status;
2711  }
2712 
2713  if (QSTR_IS_ANY_CHAR (src_type) && QSTR_IS_ANY_CHAR (key_type))
2714  {
2715  error_status =
2717  db_get_string_length (key), &result_strp, &result_len, AES_128_ECB);
2718  if (error_status != NO_ERROR)
2719  {
2720  goto error;
2721  }
2722 
2723  if (result_strp == NULL)
2724  {
2725  /* it means the src isn't aes_encrypted string, we return NULL like mysql */
2726  db_make_null (result);
2727  return error_status;
2728  }
2729 
2730  qstr_make_typed_string (DB_TYPE_VARCHAR, result, result_len, result_strp, result_len, db_get_string_codeset (src),
2731  db_get_string_collation (src));
2732  result->need_clear = true;
2733  }
2734  else
2735  {
2736  error_status = ER_QSTR_INVALID_DATA_TYPE;
2737  goto error;
2738  }
2739 
2740  return error_status;
2741 
2742 error:
2743  db_make_null (result);
2745  {
2746  er_clear ();
2747  return NO_ERROR;
2748  }
2749  else
2750  {
2751  if (er_errid () == NO_ERROR)
2752  {
2753  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
2754  }
2755  return error_status;
2756  }
2757 }
2758 
2759 
2760 /*
2761  * MD5('str')
2762  * Arguments
2763  * val: string to compute the MD5 (message digest) for
2764  * result: DB_VALUE to receive the computed MD5 from the val argument
2765  */
2766 int
2767 db_string_md5 (DB_VALUE const *val, DB_VALUE * result)
2768 {
2769  int error_status = NO_ERROR;
2770 
2771  assert (val != (DB_VALUE *) NULL);
2772  assert (result != (DB_VALUE *) NULL);
2773 
2774  if (DB_IS_NULL (val))
2775  {
2776  db_make_null (result); /* MD5(NULL) returns NULL */
2777  return error_status;
2778  }
2779  else
2780  {
2781  DB_TYPE val_type = DB_VALUE_DOMAIN_TYPE (val);
2782 
2783  if (QSTR_IS_ANY_CHAR (val_type))
2784  {
2785  /* MD5 hash string buffer */
2786  char hashString[32 + 1] = { '\0' };
2787 
2788  DB_VALUE hash_string;
2789 
2790  db_make_null (&hash_string);
2791 
2792  error_status = crypt_md5_buffer_hex (db_get_string (val), db_get_string_length (val), hashString);
2793  if (error_status != NO_ERROR)
2794  {
2795  return error_status;
2796  }
2797 
2798  /* dump result as hex string */
2799  qstr_make_typed_string (DB_TYPE_CHAR, &hash_string, 32, hashString, 32, db_get_string_codeset (val),
2800  db_get_string_collation (val));
2801  hash_string.need_clear = false;
2802  pr_clone_value (&hash_string, result);
2803  }
2804  else
2805  {
2806  error_status = ER_QSTR_INVALID_DATA_TYPE;
2807  }
2808  }
2809 
2810  return error_status;
2811 }
2812 
2813 /*
2814  * db_string_insert_substring - insert a substring into a string replacing
2815  * "length" characters starting at "position"
2816  *
2817  * Arguments:
2818  * src_string: string to insert into. Its value will not be
2819  * modified as the output is the "result" parameter
2820  * position: starting position
2821  * length: number of character to replace
2822  * sub_string: string to be inserted
2823  * result: string containing result.
2824  *
2825  * Returns: int
2826  *
2827  * Errors:
2828  * ER_QSTR_INVALID_DATA_TYPE :
2829  * <str_string> or <delim_string> is not a string type,
2830  * <count> is not an integer type
2831  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
2832  * <str_string> or <delim_string> are not compatible
2833  *
2834  */
2835 
2836 int
2837 db_string_insert_substring (DB_VALUE * src_string, const DB_VALUE * position, const DB_VALUE * length,
2838  DB_VALUE * sub_string, DB_VALUE * result)
2839 {
2840  QSTR_CATEGORY src_categ, substr_categ;
2841  int error_status = NO_ERROR, position_i = 0, length_i = 0;
2842  DB_TYPE src_type, substr_type;
2843  DB_VALUE string1, string2;
2844  int src_length = 0;
2845  int result_size = 0;
2846  DB_VALUE empty_string1, empty_string2;
2847  DB_VALUE partial_result;
2848  INTL_CODESET src_cs, substr_cs;
2849  int src_coll, substr_coll;
2850 
2851  /*
2852  * Assert that DB_VALUE structures have been allocated.
2853  */
2854  assert (src_string != (DB_VALUE *) NULL);
2855  assert (sub_string != (DB_VALUE *) NULL);
2856  assert (position != (DB_VALUE *) NULL);
2857  assert (length != (DB_VALUE *) NULL);
2858  assert (result != (DB_VALUE *) NULL);
2859 
2860  /*
2861  * Initialize values
2862  */
2863  db_make_null (result);
2864  db_make_null (&string1);
2865  db_make_null (&string2);
2866  db_make_null (&empty_string1);
2867  db_make_null (&empty_string2);
2868  db_make_null (&partial_result);
2869 
2870  /*
2871  * Categorize the parameters into respective code sets.
2872  * Verify that the parameters are both character strings.
2873  * Verify that the input strings belong to compatible code sets.
2874  */
2875  src_categ = qstr_get_category (src_string);
2876  substr_categ = qstr_get_category (sub_string);
2877 
2878  src_type = DB_VALUE_DOMAIN_TYPE (src_string);
2879  substr_type = DB_VALUE_DOMAIN_TYPE (sub_string);
2880 
2881  src_cs = DB_IS_NULL (src_string) ? LANG_SYS_CODESET : db_get_string_codeset (src_string);
2882  src_coll = DB_IS_NULL (src_string) ? LANG_SYS_COLLATION : db_get_string_collation (src_string);
2883 
2884  substr_cs = DB_IS_NULL (sub_string) ? LANG_SYS_CODESET : db_get_string_codeset (sub_string);
2885  substr_coll = DB_IS_NULL (sub_string) ? LANG_SYS_COLLATION : db_get_string_collation (sub_string);
2886 
2888  {
2889  if (DB_IS_NULL (src_string))
2890  {
2891  if (DB_IS_NULL (sub_string))
2892  {
2893  /* both strings are NULL (or empty): result is DB_TYPE_NULL */
2894  assert (error_status == NO_ERROR);
2895  goto exit;
2896  }
2897  /* convert to empty string */
2898  src_string = &empty_string1;
2899 
2900  src_type = substr_type;
2901  src_categ = substr_categ;
2902 
2903  error_status =
2904  db_string_make_empty_typed_string (src_string, src_type, TP_FLOATING_PRECISION_VALUE, substr_cs,
2905  substr_coll);
2906  if (error_status != NO_ERROR)
2907  {
2908  goto exit;
2909  }
2910 
2911  /* intermediate value : clear is_null flag */
2912  if (QSTR_IS_ANY_CHAR_OR_BIT (DB_VALUE_DOMAIN_TYPE (src_string)))
2913  {
2914  src_string->domain.general_info.is_null = 0;
2915  }
2916  }
2917 
2918  if (DB_IS_NULL (sub_string))
2919  {
2920  /* convert to empty string */
2921  sub_string = &empty_string2;
2922 
2923  substr_type = src_type;
2924  substr_categ = src_categ;
2925 
2926  error_status =
2927  db_string_make_empty_typed_string (sub_string, substr_type, TP_FLOATING_PRECISION_VALUE, src_cs, src_coll);
2928  if (error_status != NO_ERROR)
2929  {
2930  goto exit;
2931  }
2932 
2933  /* intermediate value : clear is_null flag */
2934  if (QSTR_IS_ANY_CHAR_OR_BIT (DB_VALUE_DOMAIN_TYPE (sub_string)))
2935  {
2936  sub_string->domain.general_info.is_null = 0;
2937  }
2938  }
2939  }
2940  else if (DB_IS_NULL (src_string) || DB_IS_NULL (sub_string))
2941  {
2942  /* result is DB_TYPE_NULL */
2943  assert (error_status == NO_ERROR);
2944  goto exit;
2945  }
2946 
2947  if (DB_IS_NULL (position) || DB_IS_NULL (length))
2948  {
2949  /* result is DB_TYPE_NULL */
2950  assert (error_status == NO_ERROR);
2951  goto exit;
2952  }
2953  if (!QSTR_IS_ANY_CHAR_OR_BIT (src_type) || !QSTR_IS_ANY_CHAR_OR_BIT (substr_type))
2954  {
2955  error_status = ER_QSTR_INVALID_DATA_TYPE;
2956  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
2957  goto exit;
2958  }
2959  if (src_categ != substr_categ)
2960  {
2961  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
2962  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
2963  goto exit;
2964  }
2965 
2966  position_i = db_get_int (position);
2967  length_i = db_get_int (length);
2968  src_length = db_get_string_length (src_string);
2969 
2970  if (position_i <= 0 || position_i > src_length + 1)
2971  {
2972  /* return the source string */
2973  error_status = pr_clone_value ((DB_VALUE *) src_string, result);
2974  result_size = db_get_string_size (src_string);
2975  }
2976  else
2977  {
2978  DB_DATA_STATUS data_status;
2979 
2980  /* result = string1 + substring + string2 */
2981 
2982  /* string1 = left(string,position) */
2983 
2984  if (position_i > 1)
2985  {
2986  DB_VALUE start_val, len_val;
2987 
2988  db_make_int (&start_val, 1);
2989  db_make_int (&len_val, position_i - 1);
2990 
2991  error_status = db_string_substring (SUBSTRING, src_string, &start_val, &len_val, &string1);
2992  if (error_status != NO_ERROR)
2993  {
2994  goto exit;
2995  }
2996  }
2997 
2998  if (DB_IS_NULL (&string1)) /* make dummy for concat */
2999  {
3000  error_status =
3001  db_string_make_empty_typed_string (&string1, src_type, TP_FLOATING_PRECISION_VALUE, src_cs, src_coll);
3002  if (error_status != NO_ERROR)
3003  {
3004  goto exit;
3005  }
3006 
3009  {
3010  /* intermediate value : clear is_null flag */
3011  string1.domain.general_info.is_null = 0;
3012  }
3013  }
3014 
3015  /* string2 = susbtring(string,position+len) */
3016 
3017  /* get string2 if the conditions are fullfilled : 1. length_i >= 0 - compatibility with MySql (if len is
3018  * negative, no remainder is concatenated) 2. (position_i + length_i) <= src_length - check the start boundary
3019  * for substring */
3020  if ((length_i >= 0) && ((position_i + length_i) <= src_length))
3021  {
3022  DB_VALUE start_val, len_val;
3023 
3024  db_make_int (&start_val, position_i + length_i);
3025  db_make_int (&len_val, src_length - (position_i + length_i) + 1);
3026 
3027  error_status = db_string_substring (SUBSTRING, src_string, &start_val, &len_val, &string2);
3028  if (error_status != NO_ERROR)
3029  {
3030  goto exit;
3031  }
3032  }
3033 
3034  if (DB_IS_NULL (&string2)) /* make dummy for concat */
3035  {
3036  error_status =
3037  db_string_make_empty_typed_string (&string2, src_type, TP_FLOATING_PRECISION_VALUE, src_cs, src_coll);
3038  if (error_status != NO_ERROR)
3039  {
3040  goto exit;
3041  }
3042 
3045  {
3046  /* intermediate value : clear is_null flag */
3047  string2.domain.general_info.is_null = 0;
3048  }
3049  }
3050 
3051  /* partial_result = concat(string1,substring) */
3052  error_status = db_string_concatenate (&string1, sub_string, &partial_result, &data_status);
3053  if (error_status != NO_ERROR)
3054  {
3055  goto exit;
3056  }
3057  if (data_status != DATA_STATUS_OK)
3058  {
3059  /* This should never happen as the partial_result is a VAR[N]CHAR */
3060  assert (false);
3061  error_status = ER_FAILED;
3062  goto exit;
3063  }
3064 
3065  /* result = concat(partial_result,string2) */
3066  error_status = db_string_concatenate (&partial_result, &string2, result, &data_status);
3067  if (error_status != NO_ERROR)
3068  {
3069  goto exit;
3070  }
3071 
3072  if (data_status != DATA_STATUS_OK)
3073  {
3074  /* This should never happen as the result is a VAR[N]CHAR */
3075  assert (false);
3076  error_status = ER_FAILED;
3077  goto exit;
3078  }
3079 
3080  result_size = db_get_string_size (result);
3081  }
3082 
3083  /* force type to variable string */
3084  if (src_type == DB_TYPE_CHAR || src_type == DB_TYPE_NCHAR)
3085  {
3086  /* convert CHARACTER(N) to CHARACTER VARYING(N) */
3088  TP_FLOATING_PRECISION_VALUE, db_get_string (result), result_size, src_cs, src_coll);
3089  }
3090  else if (src_type == DB_TYPE_BIT)
3091  {
3092  /* convert BIT to BIT VARYING */
3094  src_cs, src_coll);
3095  }
3096 
3097  result->need_clear = true;
3098 
3099 exit:
3100  pr_clear_value (&string1);
3101  pr_clear_value (&string2);
3102  pr_clear_value (&empty_string1);
3103  pr_clear_value (&empty_string2);
3104  pr_clear_value (&partial_result);
3105 
3106  return error_status;
3107 }
3108 
3109 /*
3110  ELT(index, arg1, arg2, arg3, ...)
3111 
3112  Clones into result the argument with the index given by the first
3113  argument.
3114 
3115  Returns: NO_ERROR or an error code
3116 */
3117 int
3118 db_string_elt (DB_VALUE * result, DB_VALUE * arg[], int const num_args)
3119 {
3120  DB_TYPE index_type = DB_VALUE_DOMAIN_TYPE (arg[0]);
3121  DB_BIGINT index = 0;
3122 
3123  if (num_args <= 0)
3124  {
3125  db_make_null (result);
3126  return NO_ERROR;
3127  }
3128 
3129  if (DB_IS_NULL (arg[0]))
3130  {
3131  db_make_null (result);
3132  return NO_ERROR;
3133  }
3134 
3135  switch (index_type)
3136  {
3137  case DB_TYPE_BIGINT:
3138  index = db_get_bigint (arg[0]);
3139  break;
3140  case DB_TYPE_INTEGER:
3141  index = db_get_int (arg[0]);
3142  break;
3143  case DB_TYPE_SMALLINT:
3144  index = db_get_short (arg[0]);
3145  break;
3146  default:
3149  }
3150 
3151  if (index > 0 && index < num_args)
3152  {
3153  pr_clone_value (arg[index], result);
3154  }
3155  else
3156  {
3157  db_make_null (result);
3158  }
3159 
3160  return NO_ERROR;
3161 }
3162 
3163 #if defined (ENABLE_UNUSED_FUNCTION)
3164 /*
3165  * db_string_byte_length
3166  *
3167  * Arguments:
3168  * string: (IN) Input string of which the byte count is desired.
3169  * byte_count: (OUT) The number of bytes in string.
3170  *
3171  * Returns: int
3172  *
3173  * Errors:
3174  * ER_QSTR_INVALID_DATA_TYPE:
3175  * <string> is not a string type
3176  *
3177  * Note:
3178  * This function returns the number of bytes in <string>.
3179  *
3180  * If the NULL flag is set for <string>, then the NULL flag
3181  * for the <byte_count> is set.
3182  *
3183  * Assert:
3184  * 1. string != (DB_VALUE *) NULL
3185  * 2. byte_count != (DB_VALUE *) NULL
3186  *
3187  */
3188 
3189 int
3190 db_string_byte_length (const DB_VALUE * string, DB_VALUE * byte_count)
3191 {
3192  int error_status = NO_ERROR;
3193  DB_TYPE str_type;
3194 
3195  /*
3196  * Assert that DB_VALUE structures have been allocated.
3197  */
3198  assert (string != (DB_VALUE *) NULL);
3199  assert (byte_count != (DB_VALUE *) NULL);
3200 
3201  /*
3202  * Verify that the input string is a valid character
3203  * string. Bit strings are not allowed.
3204  *
3205  * If the input string is a NULL, then set
3206  * the output null flag.
3207  *
3208  * Otherwise, calculte the byte size.
3209  */
3210 
3211  str_type = DB_VALUE_DOMAIN_TYPE (string);
3212  if (!QSTR_IS_ANY_CHAR_OR_BIT (str_type))
3213  {
3214  error_status = ER_QSTR_INVALID_DATA_TYPE;
3215  }
3216  else if (DB_IS_NULL (string))
3217  {
3219  }
3220  else
3221  {
3222  db_make_int (byte_count, db_get_string_size (string));
3223  }
3224 
3225  return error_status;
3226 }
3227 #endif /* ENABLE_UNUSED_FUNCTION */
3228 
3229 /*
3230  * db_string_bit_length () -
3231  *
3232  * Arguments:
3233  * string: Inpute string of which the bit length is desired.
3234  * bit_count: Bit count of string.
3235  *
3236  * Returns: int
3237  *
3238  * Errors:
3239  * ER_QSTR_INVALID_DATA_TYPE:
3240  * <string> is not a string type
3241  *
3242  * Note:
3243  * This function returns the number of bits in <string>.
3244  *
3245  * If the NULL flag is set for <string>, then the NULL flag
3246  * for the <bit_count> is set.
3247  *
3248  * Assert:
3249  * 1. string != (DB_VALUE *) NULL
3250  * 2. bit_count != (DB_VALUE *) NULL
3251  *
3252  */
3253 
3254 int
3255 db_string_bit_length (const DB_VALUE * string, DB_VALUE * bit_count)
3256 {
3257  int error_status = NO_ERROR;
3258  DB_TYPE str_type;
3259 
3260  /*
3261  * Assert that DB_VALUE structures have been allocated.
3262  */
3263  assert (string != (DB_VALUE *) NULL);
3264  assert (bit_count != (DB_VALUE *) NULL);
3265 
3266  /*
3267  * Verify that the input string is a valid character string.
3268  * Bit strings are not allowed.
3269  *
3270  * If the input string is a NULL, then set the output null flag.
3271  *
3272  * If the input parameter is valid, then extract the byte length
3273  * of the string.
3274  */
3275 
3276  str_type = DB_VALUE_DOMAIN_TYPE (string);
3277  if (!QSTR_IS_ANY_CHAR_OR_BIT (str_type))
3278  {
3279  error_status = ER_QSTR_INVALID_DATA_TYPE;
3280  }
3281  else if (DB_IS_NULL (string))
3282  {
3284  }
3285  else
3286  {
3287  if (qstr_get_category (string) == QSTR_BIT)
3288  {
3289  db_make_int (bit_count, db_get_string_length (string));
3290  }
3291  else
3292  {
3293  db_make_int (bit_count, (db_get_string_size (string) * BYTE_SIZE));
3294  }
3295  }
3296 
3297  return error_status;
3298 }
3299 
3300 /*
3301  * db_string_char_length () -
3302  *
3303  * Arguments:
3304  * string: String for which the number of characters is desired.
3305  * char_count: Number of characters in string.
3306  *
3307  * Returns: int
3308  *
3309  * Errors:
3310  * ER_QSTR_INVALID_DATA_TYPE:
3311  * <string> is not a character string
3312  *
3313  * Note:
3314  * This function returns the number of characters in <string>.
3315  *
3316  * If the NULL flag is set for <string>, then the NULL flag
3317  * for the <char_count> is set.
3318  *
3319  * Assert:
3320  * 1. string != (DB_VALUE *) NULL
3321  * 2. char_count != (DB_VALUE *) NULL
3322  *
3323  */
3324 
3325 int
3326 db_string_char_length (const DB_VALUE * string, DB_VALUE * char_count)
3327 {
3328  int error_status = NO_ERROR;
3329 
3330  /*
3331  * Assert that DB_VALUE structures have been allocated.
3332  */
3333  assert (string != (DB_VALUE *) NULL);
3334  assert (char_count != (DB_VALUE *) NULL);
3335 
3336 
3337  /*
3338  * Verify that the input string is a valid character
3339  * string. Bit strings are not allowed.
3340  *
3341  * If the input string is a NULL, then set the output null flag.
3342  *
3343  * If the input parameter is valid, then extract the character
3344  * length of the string.
3345  */
3346  if (!is_char_string (string))
3347  {
3348  error_status = ER_QSTR_INVALID_DATA_TYPE;
3349  }
3350  else if (DB_IS_NULL (string))
3351  {
3353  }
3354  else
3355  {
3356  db_make_int (char_count, db_get_string_length (string));
3357  }
3358 
3359  return error_status;
3360 }
3361 
3362 /*
3363  * db_string_lower () -
3364  *
3365  * Arguments:
3366  * string: Input string that will be converted to lower case.
3367  * lower_string: Output converted string.
3368  *
3369  * Returns: int
3370  *
3371  * Errors:
3372  * ER_QSTR_INVALID_DATA_TYPE :
3373  * <string> is not a character string.
3374  *
3375  * Note:
3376  * This function returns a string with all uppercase ASCII
3377  * and LATIN alphabetic characters converted to lowercase.
3378  *
3379  * If the NULL flag is set for <string>, then the NULL flag
3380  * for the <lower_string> is set.
3381  *
3382  * The <lower_string> value structure will be cloned from <string>.
3383  * <lower_string> should be cleared with pr_clone_value() if it has
3384  * already been initialized or db_make_null if it has not been
3385  * previously used by the system.
3386  *
3387  * Assert:
3388  *
3389  * 1. string != (DB_VALUE *) NULL
3390  * 2. lower_string != (DB_VALUE *) NULL
3391  *
3392  */
3393 
3394 int
3395 db_string_lower (const DB_VALUE * string, DB_VALUE * lower_string)
3396 {
3397  int error_status = NO_ERROR;
3398  DB_TYPE str_type;
3399 
3400  /*
3401  * Assert that DB_VALUE structures have been allocated.
3402  */
3403  assert (string != (DB_VALUE *) NULL);
3404  assert (lower_string != (DB_VALUE *) NULL);
3405 
3406  /*
3407  * Categorize the two input parameters and check for errors.
3408  * Verify that the parameters are both character strings.
3409  */
3410 
3411  str_type = DB_VALUE_DOMAIN_TYPE (string);
3412  if (DB_IS_NULL (string))
3413  {
3414  db_make_null (lower_string);
3415  }
3416  else if (!QSTR_IS_ANY_CHAR (str_type))
3417  {
3418  error_status = ER_QSTR_INVALID_DATA_TYPE;
3419  }
3420  /*
3421  * If the input parameters have been properly validated, then
3422  * we are ready to operate.
3423  */
3424  else
3425  {
3426  unsigned char *lower_str;
3427  int lower_size;
3428  int src_length;
3430 
3431  src_length = db_get_string_length (string);
3432  lower_size = intl_lower_string_size (alphabet, DB_GET_UCHAR (string), db_get_string_size (string), src_length);
3433 
3434  lower_str = (unsigned char *) db_private_alloc (NULL, lower_size + 1);
3435  if (!lower_str)
3436  {
3437  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
3438  }
3439  else
3440  {
3441  int lower_length = TP_FLOATING_PRECISION_VALUE;
3442  intl_lower_string (alphabet, DB_GET_UCHAR (string), lower_str, src_length);
3443  lower_str[lower_size] = 0;
3444 
3446  {
3447  intl_char_count (lower_str, lower_size, db_get_string_codeset (string), &lower_length);
3448  }
3449  qstr_make_typed_string (str_type, lower_string, lower_length, (char *) lower_str, lower_size,
3450  db_get_string_codeset (string), db_get_string_collation (string));
3451  lower_string->need_clear = true;
3452  }
3453  }
3454 
3455  return error_status;
3456 }
3457 
3458 /*
3459  * db_string_upper () -
3460  *
3461  * Arguments:
3462  * string: Input string that will be converted to upper case.
3463  * lower_string: Output converted string.
3464  *
3465  * Returns: int
3466  *
3467  * Errors:
3468  * ER_QSTR_INVALID_DATA_TYPE :
3469  * <string> is not a character string.
3470  *
3471  * Note:
3472  *
3473  * This function returns a string with all lowercase ASCII
3474  * and LATIN alphabetic characters converted to uppercase.
3475  *
3476  * If the NULL flag is set for <string>, then the NULL flag
3477  * for the <upper_string> is set.
3478  *
3479  * The <upper_string> value structure will be cloned from <string>.
3480  * <upper_string> should be cleared with pr_clone_value() if it has
3481  * already been initialized or db_make_null if it has not been
3482  * previously used by the system.
3483  *
3484  * Assert:
3485  *
3486  * 1. string != (DB_VALUE *) NULL
3487  * 2. upper_string != (DB_VALUE *) NULL
3488  *
3489  */
3490 
3491 int
3492 db_string_upper (const DB_VALUE * string, DB_VALUE * upper_string)
3493 {
3494  int error_status = NO_ERROR;
3495  DB_TYPE str_type;
3496 
3497  /*
3498  * Assert that DB_VALUE structures have been allocated.
3499  */
3500  assert (string != (DB_VALUE *) NULL);
3501  assert (upper_string != (DB_VALUE *) NULL);
3502 
3503  /*
3504  * Categorize the two input parameters and check for errors.
3505  * Verify that the parameters are both character strings.
3506  */
3507 
3508  str_type = DB_VALUE_DOMAIN_TYPE (string);
3509  if (DB_IS_NULL (string))
3510  {
3511  db_make_null (upper_string);
3512  }
3513  else if (!QSTR_IS_ANY_CHAR (str_type))
3514  {
3515  error_status = ER_QSTR_INVALID_DATA_TYPE;
3516  }
3517  /*
3518  * If the input parameters have been properly validated, then
3519  * we are ready to operate.
3520  */
3521  else
3522  {
3523  unsigned char *upper_str;
3524  int upper_size, src_length;
3526 
3527  src_length = db_get_string_length (string);
3528  upper_size = intl_upper_string_size (alphabet, DB_GET_UCHAR (string), db_get_string_size (string), src_length);
3529 
3530  upper_str = (unsigned char *) db_private_alloc (NULL, upper_size + 1);
3531  if (!upper_str)
3532  {
3533  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
3534  }
3535  else
3536  {
3537  int upper_length = TP_FLOATING_PRECISION_VALUE;
3538  intl_upper_string (alphabet, DB_GET_UCHAR (string), upper_str, src_length);
3539 
3540  upper_str[upper_size] = 0;
3542  {
3543  intl_char_count (upper_str, upper_size, db_get_string_codeset (string), &upper_length);
3544  }
3545  qstr_make_typed_string (str_type, upper_string, upper_length, (char *) upper_str, upper_size,
3546  db_get_string_codeset (string), db_get_string_collation (string));
3547  upper_string->need_clear = true;
3548  }
3549  }
3550 
3551  return error_status;
3552 }
3553 
3554 /*
3555  * db_string_trim () -
3556  *
3557  * Arguments:
3558  * trim_operand: Specifies whether the character to be trimmed is
3559  * removed from the beginning, ending or both ends
3560  * of the string.
3561  * trim_charset: (Optional) The characters to be removed.
3562  * src_string: String to remove trim character from.
3563  * trimmed_string: Resultant trimmed string.
3564  *
3565  * Returns: int
3566  *
3567  * Errors:
3568  * ER_QSTR_INVALID_DATA_TYPE : <trim_char> or <src_string> are
3569  * not character strings.
3570  * ER_QSTR_INVALID_TRIM_OPERAND : <trim_char> has char length > 1.
3571  * ER_QSTR_INCOMPATIBLE_CODE_SETS: <trim_char>, <src_string> and
3572  * <trimmed_string> have different
3573  * character code sets.
3574  *
3575  */
3576 
3577 int
3578 db_string_trim (const MISC_OPERAND tr_operand, const DB_VALUE * trim_charset, const DB_VALUE * src_string,
3579  DB_VALUE * trimmed_string)
3580 {
3581  int error_status = NO_ERROR;
3582  int is_trim_charset_omitted = false;
3583 
3584  unsigned char *result;
3585  int result_length, result_size = 0, result_domain_length;
3586  DB_TYPE result_type = DB_TYPE_NULL;
3587 
3588  const unsigned char *trim_charset_ptr = NULL;
3589  int trim_charset_length = 0;
3590  int trim_charset_size = 0;
3591  DB_TYPE src_type, trim_type;
3592 
3593  /*
3594  * Assert DB_VALUE structures have been allocated
3595  */
3596 
3597  assert (src_string != (DB_VALUE *) NULL);
3598  assert (trimmed_string != (DB_VALUE *) NULL);
3599 
3600  /* if source is NULL, return NULL */
3601  if (DB_IS_NULL (src_string))
3602  {
3603  if (QSTR_IS_CHAR (DB_VALUE_DOMAIN_TYPE (src_string)))
3604  {
3606  }
3607  else
3608  {
3610  }
3611  return error_status;
3612  }
3613 
3614  if (trim_charset == NULL)
3615  {
3616  is_trim_charset_omitted = true;
3617  }
3618  else
3619  {
3620  is_trim_charset_omitted = false;
3621  trim_type = DB_VALUE_DOMAIN_TYPE (trim_charset);
3622 
3623  if (DB_IS_NULL (trim_charset))
3624  {
3625  if (QSTR_IS_CHAR (DB_VALUE_DOMAIN_TYPE (src_string)))
3626  {
3628  }
3629  else
3630  {
3632  }
3633  return error_status;
3634  }
3635  }
3636 
3637  /*
3638  * Verify input parameters are all char strings and are compatible
3639  */
3640 
3641  src_type = DB_VALUE_DOMAIN_TYPE (src_string);
3642  if (!QSTR_IS_ANY_CHAR (src_type) || (!is_trim_charset_omitted && !QSTR_IS_ANY_CHAR (trim_type)))
3643  {
3644  error_status = ER_QSTR_INVALID_DATA_TYPE;
3646  return error_status;
3647  }
3648 
3649  if (!is_trim_charset_omitted
3650  && (qstr_get_category (src_string) != qstr_get_category (trim_charset)
3651  || db_get_string_codeset (src_string) != db_get_string_codeset (trim_charset)))
3652  {
3653  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
3655  return error_status;
3656  }
3657 
3658  /*
3659  * begin of main codes
3660  */
3661  if (!is_trim_charset_omitted)
3662  {
3663  trim_charset_ptr = DB_GET_UCHAR (trim_charset);
3664  trim_charset_length = db_get_string_length (trim_charset);
3665  trim_charset_size = db_get_string_size (trim_charset);
3666  }
3667 
3668  error_status = qstr_trim (tr_operand, trim_charset_ptr, trim_charset_length, trim_charset_size,
3669  DB_GET_UCHAR (src_string), DB_VALUE_DOMAIN_TYPE (src_string),
3670  db_get_string_length (src_string), db_get_string_size (src_string),
3671  db_get_string_codeset (src_string), &result, &result_type, &result_length, &result_size);
3672 
3673  if (error_status == NO_ERROR && result != NULL)
3674  {
3675  result_domain_length = MIN (QSTR_MAX_PRECISION (result_type), DB_VALUE_PRECISION (src_string));
3676  qstr_make_typed_string (result_type, trimmed_string, result_domain_length, (char *) result, result_size,
3677  db_get_string_codeset (src_string), db_get_string_collation (src_string));
3678  result[result_size] = 0;
3679  trimmed_string->need_clear = true;
3680  }
3681 
3682  return error_status;
3683 }
3684 
3685 /*
3686  * db_string_prefix_compare () - this function is similar with db_string_compare.
3687  * but if one of 2 string arguments is char-type
3688  * they are compared by the ignore-trailing-space rule.
3689  * Arguments:
3690  * string1: Left side of compare.
3691  * string2: Right side of compare
3692  * result: Integer result of comparison.
3693  *
3694  * Returns: int
3695  *
3696  * Errors:
3697  * ER_QSTR_INVALID_DATA_TYPE :
3698  * <string1> or <string2> are not character strings.
3699  *
3700  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
3701  * <string1> and <string2> have differing character code sets.
3702  *
3703  * ER_QSTR_INCOMPATIBLE_COLLATIONS
3704  * <string1> and <string2> have incompatible collations.
3705  */
3706 static int
3707 db_string_prefix_compare (const DB_VALUE * string1, const DB_VALUE * string2, DB_VALUE * result)
3708 {
3709  QSTR_CATEGORY string1_category, string2_category;
3710  int cmp_result = 0;
3711  DB_TYPE str1_type, str2_type;
3712 
3713  bool ti = true;
3714  static bool ignore_trailing_space = prm_get_bool_value (PRM_ID_IGNORE_TRAILING_SPACE);
3715 
3716  /* Assert that DB_VALUE structures have been allocated. */
3717  assert (string1 != (DB_VALUE *) NULL);
3718  assert (string2 != (DB_VALUE *) NULL);
3719  assert (result != (DB_VALUE *) NULL);
3720 
3721  /* Categorize the two input parameters and check for errors. Verify that the parameters are both character strings.
3722  * Verify that the input strings belong to compatible categories. */
3723  string1_category = qstr_get_category (string1);
3724  string2_category = qstr_get_category (string2);
3725 
3726  str1_type = DB_VALUE_DOMAIN_TYPE (string1);
3727  str2_type = DB_VALUE_DOMAIN_TYPE (string2);
3728 
3729  if (!QSTR_IS_ANY_CHAR_OR_BIT (str1_type) || !QSTR_IS_ANY_CHAR_OR_BIT (str2_type))
3730  {
3733  }
3734  if (string1_category != string2_category)
3735  {
3738  }
3739 
3740  /* A string which is NULL (not the same as a NULL string) is ordered less than a string which is not NULL. Two
3741  * strings which are NULL are ordered equivalently. If both strings are not NULL, then the strings themselves are
3742  * compared. */
3743  if (DB_IS_NULL (string1) && !DB_IS_NULL (string2))
3744  {
3745  cmp_result = -1;
3746  }
3747  else if (!DB_IS_NULL (string1) && DB_IS_NULL (string2))
3748  {
3749  cmp_result = 1;
3750  }
3751  else if (DB_IS_NULL (string1) && DB_IS_NULL (string2))
3752  {
3753  cmp_result = 0;
3754  }
3755  else if (db_get_string_codeset (string1) != db_get_string_codeset (string2))
3756  {
3759  }
3760  else
3761  {
3762  int coll_id;
3763 
3764  switch (string1_category)
3765  {
3766  case QSTR_CHAR:
3767  case QSTR_NATIONAL_CHAR:
3768 
3769  assert (db_get_string_codeset (string1) == db_get_string_codeset (string2));
3770 
3772 
3773  if (coll_id == -1)
3774  {
3777  }
3778 
3779  coll_id = db_get_string_collation (string1);
3780  assert (db_get_string_collation (string1) == db_get_string_collation (string2));
3781 
3782  if (!ignore_trailing_space)
3783  {
3784  ti = (QSTR_IS_FIXED_LENGTH (str1_type) || QSTR_IS_FIXED_LENGTH (str2_type));
3785  }
3786  cmp_result = QSTR_COMPARE (coll_id, DB_GET_UCHAR (string1), (int) db_get_string_size (string1),
3787  DB_GET_UCHAR (string2), (int) db_get_string_size (string2), ti);
3788  break;
3789  case QSTR_BIT:
3790  cmp_result = varbit_compare (DB_GET_UCHAR (string1), (int) db_get_string_size (string1),
3791  DB_GET_UCHAR (string2), (int) db_get_string_size (string2));
3792  break;
3793  default: /* QSTR_UNKNOWN */
3794  assert (false);
3795  }
3796  }
3797 
3798  if (cmp_result < 0)
3799  {
3800  cmp_result = -1;
3801  }
3802  else if (cmp_result > 0)
3803  {
3804  cmp_result = 1;
3805  }
3806  db_make_int (result, cmp_result);
3807 
3808  return NO_ERROR;
3809 }
3810 
3811 /* qstr_trim () -
3812 */
3813 static int
3814 qstr_trim (MISC_OPERAND trim_operand, const unsigned char *trim_charset, int trim_charset_length, int trim_charset_size,
3815  const unsigned char *src_ptr, DB_TYPE src_type, int src_length, int src_size, INTL_CODESET codeset,
3816  unsigned char **result, DB_TYPE * result_type, int *result_length, int *result_size)
3817 {
3818  unsigned char pad_char[2], *lead_trimmed_ptr, *trail_trimmed_ptr;
3819  int lead_trimmed_length, trail_trimmed_length;
3820  int lead_trimmed_size, trail_trimmed_size, pad_char_size = 0;
3821  int error_status = NO_ERROR;
3822  bool trim_ascii_spaces = false;
3823 
3824  /* default case */
3825  intl_pad_char (codeset, pad_char, &pad_char_size);
3826  if (trim_charset_length == 0)
3827  {
3828  trim_charset = pad_char;
3829  trim_charset_length = 1;
3830  trim_charset_size = pad_char_size;
3831  trim_ascii_spaces = true;
3832  }
3833 
3834  /* trim from front */
3835  lead_trimmed_ptr = (unsigned char *) src_ptr;
3836  lead_trimmed_length = src_length;
3837  lead_trimmed_size = src_size;
3838 
3839  if (trim_operand == LEADING || trim_operand == BOTH)
3840  {
3841  trim_leading (trim_charset, trim_charset_size, src_ptr, src_type, src_length, src_size, codeset,
3842  &lead_trimmed_ptr, &lead_trimmed_length, &lead_trimmed_size, trim_ascii_spaces);
3843  }
3844 
3845  trail_trimmed_ptr = lead_trimmed_ptr;
3846  trail_trimmed_length = lead_trimmed_length;
3847  trail_trimmed_size = lead_trimmed_size;
3848 
3849  if (trim_operand == TRAILING || trim_operand == BOTH)
3850  {
3851  qstr_trim_trailing (trim_charset, trim_charset_size, lead_trimmed_ptr, src_type, lead_trimmed_length,
3852  lead_trimmed_size, codeset, &trail_trimmed_length, &trail_trimmed_size, trim_ascii_spaces);
3853  }
3854 
3855  /* setup result */
3856  *result = (unsigned char *) db_private_alloc (NULL, (size_t) trail_trimmed_size + 1);
3857  if (*result == NULL)
3858  {
3859  assert (er_errid () != NO_ERROR);
3860  error_status = er_errid ();
3861  return error_status;
3862  }
3863 
3864  (void) memcpy ((char *) (*result), (char *) trail_trimmed_ptr, trail_trimmed_size);
3865  (*result)[trail_trimmed_size] = '\0';
3866 
3867  if (QSTR_IS_NATIONAL_CHAR (src_type))
3868  {
3869  *result_type = DB_TYPE_VARNCHAR;
3870  }
3871  else
3872  {
3873  *result_type = DB_TYPE_VARCHAR;
3874  }
3875  *result_length = trail_trimmed_length;
3876  *result_size = trail_trimmed_size;
3877 
3878  return error_status;
3879 }
3880 
3881 /*
3882  * trim_leading () -
3883  *
3884  * Arguments:
3885  * trim_charset_ptr: (in) Single character trim string.
3886  * trim_charset_size: (in) Size of trim string.
3887  * src_string_ptr: (in) Source string to be trimmed.
3888  * src_string_length: (in) Length of source string.
3889  * codeset: (in) International codeset of source string.
3890  * lead_trimmed_ptr: (out) Pointer to start of trimmed string.
3891  * lead_trimmed_length: (out) Length of trimmed string.
3892  * trim_ascii_spaces: (in) Option to trim normal spaces also.
3893  *
3894  * Returns: nothing
3895  *
3896  * Errors:
3897  *
3898  * Note:
3899  * Remove trim character from the front of the source string. No
3900  * characters are actually removed. Instead, the function returns
3901  * a pointer to the beginning of the source string after the trim
3902  * characters and the resultant length of the string.
3903  *
3904  */
3905 static void
3906 trim_leading (const unsigned char *trim_charset_ptr, int trim_charset_size, const unsigned char *src_ptr,
3907  DB_TYPE src_type, int src_length, int src_size, INTL_CODESET codeset, unsigned char **lead_trimmed_ptr,
3908  int *lead_trimmed_length, int *lead_trimmed_size, bool trim_ascii_spaces)
3909 {
3910  int cur_src_char_size, cur_trim_char_size;
3911  unsigned char *cur_src_char_ptr, *cur_trim_char_ptr;
3912 
3913  int cmp_flag = 0;
3914 
3915  *lead_trimmed_ptr = (unsigned char *) src_ptr;
3916  *lead_trimmed_length = src_length;
3917  *lead_trimmed_size = src_size;
3918 
3919  /* iterate for source string */
3920  for (cur_src_char_ptr = (unsigned char *) src_ptr; cur_src_char_ptr < src_ptr + src_size;)
3921  {
3922  if (trim_ascii_spaces && *cur_src_char_ptr == ' ')
3923  {
3924  cur_src_char_ptr += 1;
3925  *lead_trimmed_length -= 1;
3926  *lead_trimmed_size -= 1;
3927  *lead_trimmed_ptr += 1;
3928  continue;
3929  }
3930  for (cur_trim_char_ptr = (unsigned char *) trim_charset_ptr;
3931  cur_src_char_ptr < (src_ptr + src_size) && (cur_trim_char_ptr < trim_charset_ptr + trim_charset_size);)
3932  {
3933  intl_char_size (cur_src_char_ptr, 1, codeset, &cur_src_char_size);
3934  intl_char_size (cur_trim_char_ptr, 1, codeset, &cur_trim_char_size);
3935 
3936  if (cur_src_char_size != cur_trim_char_size)
3937  {
3938  return;
3939  }
3940 
3941  cmp_flag = memcmp ((char *) cur_src_char_ptr, (char *) cur_trim_char_ptr, cur_trim_char_size);
3942  if (cmp_flag != 0)
3943  {
3944  return;
3945  }
3946 
3947  cur_src_char_ptr += cur_src_char_size;
3948  cur_trim_char_ptr += cur_trim_char_size;
3949  }
3950 
3951  if (cur_trim_char_ptr >= trim_charset_ptr + trim_charset_size)
3952  { /* all string matched */
3953  *lead_trimmed_length -= trim_charset_size;
3954  *lead_trimmed_size -= trim_charset_size;
3955  *lead_trimmed_ptr += trim_charset_size;
3956  }
3957  }
3958 }
3959 
3960 /*
3961  * qstr_trim_trailing () -
3962  *
3963  * Arguments:
3964  * trim_charset_ptr: (in) Single character trim string.
3965  * trim_charset_size: (in) Size of trim string.
3966  * src_ptr: (in) Source string to be trimmed.
3967  * src_length: (in) Length of source string.
3968  * codeset: (in) International codeset of source string.
3969  * trail_trimmed_length: (out) Length of trimmed string.
3970  * trim_ascii_spaces: (in) Option to trim normal spaces also.
3971  *
3972  * Returns: nothing
3973  *
3974  * Errors:
3975  *
3976  * Note:
3977  * Remove trim character from the end of the source string. No
3978  * characters are actually removed. Instead, the function returns
3979  * a pointer to the beginning of the source string after the trim
3980  * characters and the resultant length of the string.
3981  *
3982  */
3983 void
3984 qstr_trim_trailing (const unsigned char *trim_charset_ptr, int trim_charset_size, const unsigned char *src_ptr,
3985  DB_TYPE src_type, int src_length, int src_size, INTL_CODESET codeset, int *trail_trimmed_length,
3986  int *trail_trimmed_size, bool trim_ascii_spaces)
3987 {
3988  int prev_src_char_size, prev_trim_char_size;
3989  const unsigned char *cur_src_char_ptr, *cur_trim_char_ptr;
3990  const unsigned char *prev_src_char_ptr, *prev_trim_char_ptr;
3991  int cmp_flag = 0;
3992 
3993  *trail_trimmed_length = src_length;
3994  *trail_trimmed_size = src_size;
3995 
3996  /* iterate for source string */
3997  for (cur_src_char_ptr = (unsigned char *) src_ptr + src_size; cur_src_char_ptr > src_ptr;)
3998  {
3999  if (trim_ascii_spaces && *(cur_src_char_ptr - 1) == ' ')
4000  {
4001  cur_src_char_ptr -= 1;
4002  *trail_trimmed_length -= 1;
4003  *trail_trimmed_size -= 1;
4004  continue;
4005  }
4006  for (cur_trim_char_ptr = (unsigned char *) trim_charset_ptr + trim_charset_size;
4007  cur_trim_char_ptr > trim_charset_ptr && cur_src_char_ptr > src_ptr;)
4008  {
4009  /* get previous letter */
4010  prev_src_char_ptr = intl_prev_char (cur_src_char_ptr, src_ptr, codeset, &prev_src_char_size);
4011  prev_trim_char_ptr = intl_prev_char (cur_trim_char_ptr, trim_charset_ptr, codeset, &prev_trim_char_size);
4012 
4013  if (prev_trim_char_size != prev_src_char_size)
4014  {
4015  return;
4016  }
4017 
4018  cmp_flag = memcmp ((char *) prev_src_char_ptr, (char *) prev_trim_char_ptr, prev_trim_char_size);
4019  if (cmp_flag != 0)
4020  {
4021  return;
4022  }
4023 
4024  cur_src_char_ptr -= prev_src_char_size;
4025  cur_trim_char_ptr -= prev_trim_char_size;
4026  }
4027 
4028  if (cur_trim_char_ptr <= trim_charset_ptr)
4029  {
4030  *trail_trimmed_length -= trim_charset_size;
4031  *trail_trimmed_size -= trim_charset_size;
4032  }
4033  }
4034 }
4035 
4036 /*
4037  * db_string_pad () -
4038  *
4039  * Arguments:
4040  * pad_operand: (in) Left or Right padding?
4041  * src_string: (in) Source string to be padded.
4042  * pad_length: (in) Length of padded string
4043  * pad_charset: (in) Padding char set
4044  * padded_string: (out) Padded string
4045  *
4046  * Returns: nothing
4047  */
4048 int
4049 db_string_pad (const MISC_OPERAND pad_operand, const DB_VALUE * src_string, const DB_VALUE * pad_length,
4050  const DB_VALUE * pad_charset, DB_VALUE * padded_string)
4051 {
4052  int error_status = NO_ERROR;
4053  int total_length;
4054 
4055  unsigned char *result;
4056  int result_length = 0, result_size = 0;
4057  DB_TYPE result_type;
4058 
4059  const unsigned char *pad_charset_ptr = NULL;
4060  int pad_charset_length = 0;
4061  int pad_charset_size = 0;
4062  DB_TYPE src_type;
4063  bool is_pad_charset_omitted = false;
4064 
4065  assert (src_string != (DB_VALUE *) NULL);
4066  assert (padded_string != (DB_VALUE *) NULL);
4067 
4068  if (QSTR_IS_CHAR (DB_VALUE_DOMAIN_TYPE (src_string)))
4069  {
4071  }
4072  else
4073  {
4075  }
4076 
4077  /* if source is NULL, return NULL */
4078  if (DB_IS_NULL (src_string))
4079  {
4080  return NO_ERROR;
4081  }
4082 
4083  if (pad_charset == NULL)
4084  {
4085  is_pad_charset_omitted = true;
4086  }
4087  else if (DB_IS_NULL (pad_charset))
4088  {
4089  return NO_ERROR;
4090  }
4091 
4092  if (DB_IS_NULL (pad_length) || (total_length = db_get_int (pad_length)) <= 0)
4093  {
4094  /* error_status = ER_QPROC_INVALID_PARAMETER; */// why is this commented??
4095  return error_status; // this is NO_ERROR
4096  }
4097 
4098  src_type = DB_VALUE_DOMAIN_TYPE (src_string);
4099  if (!QSTR_IS_ANY_CHAR (src_type) || (!is_pad_charset_omitted && !is_char_string (pad_charset)))
4100  {
4101  error_status = ER_QSTR_INVALID_DATA_TYPE;
4103  return error_status;
4104  }
4105 
4106  if (!is_pad_charset_omitted
4107  && (qstr_get_category (src_string) != qstr_get_category (pad_charset)
4108  || db_get_string_codeset (src_string) != db_get_string_codeset (pad_charset)))
4109  {
4110  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
4112  return error_status;
4113  }
4114 
4115  if (!is_pad_charset_omitted)
4116  {
4117  pad_charset_ptr = DB_GET_UCHAR (pad_charset);
4118  pad_charset_length = db_get_string_length (pad_charset);
4119  pad_charset_size = db_get_string_size (pad_charset);
4120  }
4121 
4122  error_status = qstr_pad (pad_operand, total_length, pad_charset_ptr, pad_charset_length, pad_charset_size,
4123  DB_GET_UCHAR (src_string), DB_VALUE_DOMAIN_TYPE (src_string),
4124  db_get_string_length (src_string), db_get_string_size (src_string),
4125  db_get_string_codeset (src_string), &result, &result_type, &result_length, &result_size);
4126 
4127  if (error_status != NO_ERROR)
4128  {
4129  assert (result == NULL);
4130  ASSERT_ERROR ();
4131  return error_status;
4132  }
4133 
4134  if (result == NULL)
4135  {
4136  // null result
4137  return NO_ERROR;
4138  }
4139 
4140  // check length/size
4141  if (result_length > QSTR_MAX_PRECISION (DB_VALUE_DOMAIN_TYPE (src_string)))
4142  {
4144  QSTR_MAX_PRECISION (DB_VALUE_DOMAIN_TYPE (src_string)));
4145  db_private_free_and_init (NULL, result);
4146  return ER_PRECISION_OVERFLOW;
4147  }
4148  if ((UINT64) result_size > prm_get_bigint_value (PRM_ID_STRING_MAX_SIZE_BYTES))
4149  {
4152  db_private_free_and_init (NULL, result);
4154  }
4155  qstr_make_typed_string (result_type, padded_string, result_length, (char *) result, result_size,
4156  db_get_string_codeset (src_string), db_get_string_collation (src_string));
4157  result[result_size] = 0;
4158  padded_string->need_clear = true;
4159  return NO_ERROR;
4160 }
4161 
4162 /*
4163  * qstr_pad () -
4164  */
4165 static int
4166 qstr_pad (MISC_OPERAND pad_operand, int pad_length, const unsigned char *pad_charset_ptr, int pad_charset_length,
4167  int pad_charset_size, const unsigned char *src_ptr, DB_TYPE src_type, int src_length, int src_size,
4168  INTL_CODESET codeset, unsigned char **result, DB_TYPE * result_type, int *result_length, int *result_size)
4169 {
4170  unsigned char def_pad_char[2];
4171  unsigned char *cur_pad_char_ptr;
4172  int def_pad_char_size = 0; /* default padding char */
4173  int truncate_size, pad_size, alloc_size, cnt;
4174  int length_to_be_padded; /* length that will be really padded */
4175  int remain_length_to_be_padded; /* remained length that will be padded */
4176  int pad_full_size = 0;
4177  int pad_reminder_size = 0;
4178  int error_status = NO_ERROR;
4179 
4180  if (codeset == INTL_CODESET_KSC5601_EUC)
4181  {
4182  def_pad_char[0] = ' ';
4183  def_pad_char_size = 1;
4184  }
4185  else
4186  {
4187  intl_pad_char (codeset, def_pad_char, &def_pad_char_size);
4188  }
4189 
4190  if (pad_charset_length == 0)
4191  {
4192  pad_charset_ptr = def_pad_char;
4193  pad_charset_length = 1;
4194  pad_charset_size = def_pad_char_size;
4195  }
4196 
4197  assert (pad_charset_length > 0);
4198 
4199  if (src_length >= pad_length)
4200  {
4201  alloc_size = src_size;
4202  }
4203  else
4204  {
4205  pad_full_size = ((pad_length - src_length) / pad_charset_length) * pad_charset_size;
4206  intl_char_size ((unsigned char *) pad_charset_ptr, (pad_length - src_length) % pad_charset_length, codeset,
4207  &pad_reminder_size);
4208  alloc_size = src_size + pad_full_size + pad_reminder_size;
4209  }
4210 
4211  if (QSTR_IS_NATIONAL_CHAR (src_type))
4212  {
4213  *result_type = DB_TYPE_VARNCHAR;
4214  }
4215  else
4216  {
4217  *result_type = DB_TYPE_VARCHAR;
4218  }
4219 
4220  *result = (unsigned char *) db_private_alloc (NULL, (size_t) alloc_size + 1);
4221  if (*result == NULL)
4222  {
4223  assert (er_errid () != NO_ERROR);
4224  error_status = er_errid ();
4225  return error_status;
4226  }
4227 
4228  /*
4229  * now start padding
4230  */
4231 
4232  /* if source length is greater than pad_length */
4233  if (src_length >= pad_length)
4234  {
4235  truncate_size = 0; /* SIZE to be cut */
4236  intl_char_size ((unsigned char *) src_ptr, pad_length, codeset, &truncate_size);
4237  memcpy ((char *) (*result), (char *) src_ptr, truncate_size);
4238 
4239  *result_length = pad_length;
4240  *result_size = truncate_size;
4241 
4242  return error_status;
4243  }
4244 
4245  /*
4246  * Get real length to be paded
4247  * if source length is greater than pad_length
4248  */
4249 
4250  length_to_be_padded = pad_length - src_length;
4251 
4252  /* pad heading first */
4253 
4254  cnt = 0; /* how many times copy pad_char_set */
4255  pad_size = 0; /* SIZE of padded char */
4256  remain_length_to_be_padded = 0;
4257 
4258  for (; cnt < (length_to_be_padded / pad_charset_length); cnt++)
4259  {
4260  (void) memcpy ((char *) (*result) + pad_charset_size * cnt, (char *) pad_charset_ptr, pad_charset_size);
4261  }
4262  pad_size = pad_charset_size * cnt;
4263  remain_length_to_be_padded = (pad_length - src_length) % pad_charset_length;
4264 
4265  if (remain_length_to_be_padded != 0)
4266  {
4267  int remain_size_to_be_padded = 0;
4268 
4269  assert (remain_length_to_be_padded > 0);
4270 
4271  cur_pad_char_ptr = (unsigned char *) pad_charset_ptr;
4272 
4273  intl_char_size (cur_pad_char_ptr, remain_length_to_be_padded, codeset, &remain_size_to_be_padded);
4274  (void) memcpy ((char *) (*result) + pad_size, (char *) cur_pad_char_ptr, remain_size_to_be_padded);
4275  cur_pad_char_ptr += remain_size_to_be_padded;
4276  pad_size += remain_size_to_be_padded;
4277  }
4278 
4279  memcpy ((char *) (*result) + pad_size, src_ptr, src_size);
4280 
4281  if (pad_operand == TRAILING)
4282  { /* switch source and padded string */
4283  memmove ((char *) (*result) + src_size, (char *) (*result), pad_size);
4284  memcpy ((char *) (*result), src_ptr, src_size);
4285  }
4286 
4287  pad_size += src_size;
4288 
4289  *result_length = pad_length;
4290  *result_size = pad_size;
4291 
4292  return error_status;
4293 }
4294 
4295 /*
4296  * db_string_like () -
4297  *
4298  * Arguments:
4299  * src_string: (IN) Source string.
4300  * pattern: (IN) Pattern string which can contain % and _
4301  * characters.
4302  * esc_char: (IN) Optional escape character.
4303  * result: (OUT) Integer result.
4304  *
4305  * Returns: int
4306  *
4307  * Errors:
4308  * ER_QSTR_INVALID_DATA_TYPE:
4309  * <src_string>, <pattern>, or <esc_char> (if it's not NULL)
4310  * is not a character string.
4311  *
4312  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
4313  * <src_string>, <pattern>, and <esc_char> (if it's not NULL)
4314  * have different character code sets.
4315  *
4316  * ER_QSTR_INVALID_ESCAPE_SEQUENCE:
4317  * An illegal pattern is specified.
4318  *
4319  * ER_QSTR_INVALID_ESCAPE_CHARACTER:
4320  * If <esc_char> is not NULL and the length of E is > 1.
4321  *
4322  */
4323 /* TODO ER_QSTR_INVALID_ESCAPE_CHARACTER is not checked for, although it
4324  probably should be (the escape sequence string should contain a single
4325  character)
4326 */
4327 
4328 int
4329 db_string_like (const DB_VALUE * src_string, const DB_VALUE * pattern, const DB_VALUE * esc_char, int *result)
4330 {
4331  QSTR_CATEGORY src_category = QSTR_UNKNOWN;
4332  QSTR_CATEGORY pattern_category = QSTR_UNKNOWN;
4333  int error_status = NO_ERROR;
4334  DB_TYPE src_type = DB_TYPE_UNKNOWN;
4335  DB_TYPE pattern_type = DB_TYPE_UNKNOWN;
4336  const char *src_char_string_p = NULL;
4337  const char *pattern_char_string_p = NULL;
4338  const char *esc_char_p = NULL;
4339  int src_length = 0, pattern_length = 0;
4340  int coll_id;
4341 
4342  /*
4343  * Assert that DB_VALUE structures have been allocated.
4344  */
4345  assert (src_string != NULL);
4346  assert (pattern != NULL);
4347 
4348  src_category = qstr_get_category (src_string);
4349  pattern_category = qstr_get_category (pattern);
4350 
4351  src_type = DB_VALUE_DOMAIN_TYPE (src_string);
4352  pattern_type = DB_VALUE_DOMAIN_TYPE (pattern);
4353 
4354  if (!QSTR_IS_ANY_CHAR (src_type) || !QSTR_IS_ANY_CHAR (pattern_type))
4355  {
4356  error_status = ER_QSTR_INVALID_DATA_TYPE;
4358  *result = V_ERROR;
4359  return error_status;
4360  }
4361 
4362  if (src_category != pattern_category || (db_get_string_codeset (src_string) != db_get_string_codeset (pattern)))
4363  {
4364  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
4365  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4366  *result = V_ERROR;
4367  return error_status;
4368  }
4369 
4370  if (DB_IS_NULL (src_string))
4371  {
4372  *result = V_UNKNOWN;
4373  return error_status;
4374  }
4375 
4376  if (DB_IS_NULL (pattern))
4377  {
4378  *result = V_FALSE;
4379  return error_status;
4380  }
4381 
4382  LANG_RT_COMMON_COLL (db_get_string_collation (src_string), db_get_string_collation (pattern), coll_id);
4383  if (coll_id == -1)
4384  {
4385  error_status = ER_QSTR_INCOMPATIBLE_COLLATIONS;
4386  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4387  *result = V_ERROR;
4388  return error_status;
4389  }
4390 
4391  if (esc_char)
4392  {
4393  if (DB_IS_NULL (esc_char))
4394  {
4395  /* The implicit escape character ('\\') is used if (a LIKE b ESCAPE NULL) is given in the syntax */
4396  esc_char_p = "\\";
4397  }
4398  else
4399  {
4400  QSTR_CATEGORY esc_category = qstr_get_category (esc_char);
4401  DB_TYPE esc_type = DB_VALUE_DOMAIN_TYPE (esc_char);
4402  int esc_char_len, esc_char_size;
4403 
4404  if (QSTR_IS_ANY_CHAR (esc_type))
4405  {
4406  if (src_category == esc_category)
4407  {
4408  esc_char_p = db_get_string (esc_char);
4409  esc_char_size = db_get_string_size (esc_char);
4410 
4411  intl_char_count ((unsigned char *) esc_char_p, esc_char_size, db_get_string_codeset (esc_char),
4412  &esc_char_len);
4413 
4414  assert (esc_char_p != NULL);
4415  if (esc_char_len != 1)
4416  {
4417  error_status = ER_QSTR_INVALID_ESCAPE_SEQUENCE;
4418  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4419  *result = V_ERROR;
4420  return error_status;
4421  }
4422  }
4423  else
4424  {
4425  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
4426  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4427  *result = V_ERROR;
4428  return error_status;
4429  }
4430  }
4431  else
4432  {
4433  error_status = ER_QSTR_INVALID_DATA_TYPE;
4435  *result = V_ERROR;
4436  return error_status;
4437  }
4438  }
4439  }
4440 
4441  src_char_string_p = db_get_string (src_string);
4442  src_length = db_get_string_size (src_string);
4443 
4444  pattern_char_string_p = db_get_string (pattern);
4445  pattern_length = db_get_string_size (pattern);
4446 
4447  *result =
4448  qstr_eval_like (src_char_string_p, src_length, pattern_char_string_p, pattern_length,
4449  (esc_char ? esc_char_p : NULL), db_get_string_codeset (src_string), coll_id);
4450 
4451  if (*result == V_ERROR)
4452  {
4454  }
4455 
4456  return ((*result == V_ERROR) ? ER_QSTR_INVALID_ESCAPE_SEQUENCE : error_status);
4457 }
4458 
4459 /*
4460  * db_string_rlike () - check for match between string and regex
4461  *
4462  * Arguments:
4463  * src: (IN) Source string.
4464  * pattern: (IN) Regular expression.
4465  * case_sensitive: (IN) Perform case sensitive matching when 1
4466  * comp_regex: (IN/OUT) Compiled regex object
4467  * comp_pattern: (IN/OUT) Compiled regex pattern
4468  * result: (OUT) Integer result.
4469  *
4470  * Returns: int
4471  *
4472  * Errors:
4473  * ER_QSTR_INVALID_DATA_TYPE:
4474  * <src>, <pattern> (if it's not NULL)
4475  * is not a character string.
4476  *
4477  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
4478  * <src>, <pattern> (if it's not NULL)
4479  * have different character code sets.
4480  *
4481  * ER_QSTR_INVALID_ESCAPE_SEQUENCE:
4482  * An illegal pattern is specified.
4483  *
4484  */
4485 int
4486 db_string_rlike (const DB_VALUE * src, const DB_VALUE * pattern, const DB_VALUE * case_sensitive,
4487  cub_regex_object ** comp_regex, char **comp_pattern, int *result)
4488 {
4489  int error_status = NO_ERROR;
4490  *result = V_FALSE;
4491 
4492  /* get compiled pattern and regex object */
4493  char *rx_compiled_pattern = (comp_pattern != NULL) ? *comp_pattern : NULL;
4494  cub_regex_object *rx_compiled_regex = (comp_regex != NULL) ? *comp_regex : NULL;
4495 
4496  {
4497  /* check for allocated DB values */
4498  assert (src != NULL);
4499  assert (pattern != NULL);
4500  assert (case_sensitive != NULL);
4501 
4502  /* check type */
4503  QSTR_CATEGORY src_category = qstr_get_category (src);
4504  QSTR_CATEGORY pattern_category = qstr_get_category (pattern);
4505 
4506  DB_TYPE src_type = DB_VALUE_DOMAIN_TYPE (src);
4507  DB_TYPE pattern_type = DB_VALUE_DOMAIN_TYPE (pattern);
4508  DB_TYPE case_sens_type = DB_VALUE_DOMAIN_TYPE (case_sensitive);
4509 
4510  if (!QSTR_IS_ANY_CHAR (src_type) || !QSTR_IS_ANY_CHAR (pattern_type))
4511  {
4512  error_status = ER_QSTR_INVALID_DATA_TYPE;
4513  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4514  goto cleanup;
4515  }
4516 
4517  if (DB_IS_NULL (src) || DB_IS_NULL (pattern))
4518  {
4519  goto cleanup;
4520  }
4521 
4522  if (DB_IS_NULL (case_sensitive) || case_sens_type != DB_TYPE_INTEGER)
4523  {
4524  error_status = ER_QPROC_INVALID_PARAMETER;
4525  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4526  goto cleanup;
4527  }
4528 
4529  INTL_CODESET src_codeset = db_get_string_codeset (src);
4530  INTL_CODESET pattern_codeset = db_get_string_codeset (pattern);
4531 
4532  /* check codeset compatible */
4533  if ((src_category != pattern_category) || (src_codeset != pattern_codeset))
4534  {
4535  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
4536  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4537  *result = V_ERROR;
4538  goto cleanup;
4539  }
4540 
4541  /* collation compatible check */
4542  int coll_id = -1;
4544  if (coll_id == -1)
4545  {
4546  error_status = ER_QSTR_INCOMPATIBLE_COLLATIONS;
4547  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4548  *result = V_ERROR;
4549  goto cleanup;
4550  }
4551 
4552  if (db_get_string_size (pattern) == 0)
4553  {
4554  goto cleanup;
4555  }
4556 
4557 // *INDENT-OFF*
4558  /* extract case sensitivity */
4559  bool is_case_sensitive = (case_sensitive->data.i != 0);
4560 
4561  std::regex_constants::syntax_option_type reg_flags = std::regex_constants::ECMAScript;
4562  reg_flags |= std::regex_constants::nosubs;
4563  if (!is_case_sensitive)
4564  {
4565  reg_flags |= std::regex_constants::icase;
4566  }
4567 
4568  LANG_COLLATION *collation = lang_get_collation (coll_id);
4569  assert (collation != NULL);
4570 
4571  /* compile pattern if needed */
4572  std::string pattern_string (db_get_string (pattern), db_get_string_size (pattern));
4573  if (cubregex::check_should_recompile (rx_compiled_regex, rx_compiled_pattern, pattern_string, reg_flags) == true)
4574  {
4575  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
4576  int pattern_length = pattern_string.size ();
4577  rx_compiled_pattern = (char *) db_private_alloc (NULL, pattern_length + 1);
4578  if (rx_compiled_pattern == NULL)
4579  {
4580  /* out of memory */
4581  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
4582  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4583  goto cleanup;
4584  }
4585  memcpy (rx_compiled_pattern, pattern_string.c_str (), pattern_length);
4586  rx_compiled_pattern[pattern_length] = '\0';
4587 
4588  error_status = cubregex::compile (rx_compiled_regex, rx_compiled_pattern, reg_flags, collation);
4589  if (error_status != NO_ERROR)
4590  {
4591  error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
4592  goto cleanup;
4593  }
4594  }
4595 
4596  std::string src_string (db_get_string (src), db_get_string_size (src));
4597  error_status = cubregex::search (*result, *rx_compiled_regex, src_string, collation->codeset);
4598  if (error_status != NO_ERROR)
4599  {
4600  error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
4601  goto cleanup;
4602  }
4603 // *INDENT-ON*
4604  }
4605 
4606 cleanup:
4607  if (error_status != NO_ERROR)
4608  {
4609  *result = V_ERROR;
4610  // *INDENT-OFF*
4611  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
4612  // *INDENT-ON*
4614  {
4615  /* we must not return an error code */
4616  *result = V_UNKNOWN;
4617  er_clear ();
4618  error_status = NO_ERROR;
4619  }
4620  }
4621 
4622  if (comp_regex == NULL || comp_pattern == NULL)
4623  {
4624  /* free memory if this function is invoked in constant folding */
4625  // *INDENT-OFF*
4626  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
4627  // *INDENT-ON*
4628  }
4629  else
4630  {
4631  /* pass compiled regex object and compiled pattern out to reuse them */
4632  *comp_regex = rx_compiled_regex;
4633  *comp_pattern = rx_compiled_pattern;
4634  }
4635 
4636  return error_status;
4637 }
4638 
4639 /*
4640  * db_string_regexp_count () returns the number of times that regex pattern matched in a given string.
4641  *
4642  * Arguments:
4643  * result: (IN) Result String
4644  * args: (IN) Array of Arguments
4645  * num_args: (IN) # of Arguments
4646  * comp_regex: (IN/OUT) Compiled regex object
4647  * comp_pattern: (IN/OUT) Compiled regex pattern
4648  *
4649  * Returns: int
4650  *
4651  * Errors:
4652  * ER_QSTR_INVALID_DATA_TYPE:
4653  * <src>, <pattern> (if it's not NULL)
4654  * is not a character string.
4655  *
4656  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
4657  * <src_string>, <pattern> (if it's not NULL)
4658  * have different character code sets.
4659  *
4660  * ER_QSTR_INCOMPATIBLE_COLLATIONS:
4661  * <src_string>, <pattern> (if it's not NULL)
4662  * are incompatible collations.
4663  *
4664  * ER_REGEX_COMPILE_ERROR:
4665  * An illegal regex pattern is specified.
4666  *
4667  * ER_REGEX_EXEC_ERROR:
4668  * An regex pattern is too complex or insufficient memory while executing regex matching
4669  *
4670  * ER_QPROC_INVALID_PARAMETER:
4671  * Invalid parameter exists
4672  *
4673  */
4674 int
4675 db_string_regexp_count (DB_VALUE * result, DB_VALUE * args[], int const num_args,
4676  cub_regex_object ** comp_regex, char **comp_pattern)
4677 {
4678  int error_status = NO_ERROR;
4679  db_make_int (result, 0);
4680 
4681  /* get compiled pattern and regex object */
4682  char *rx_compiled_pattern = (comp_pattern != NULL) ? *comp_pattern : NULL;
4683  cub_regex_object *rx_compiled_regex = (comp_regex != NULL) ? *comp_regex : NULL;
4684 
4685  {
4686  for (int i = 0; i < num_args; i++)
4687  {
4688  DB_VALUE *arg = args[i];
4689  /* check for allocated DB value */
4690  assert (arg != (DB_VALUE *) NULL);
4691 
4692  /* if any argument is NULL, return NULL */
4693  if (DB_IS_NULL (arg))
4694  {
4695  db_make_null (result);
4696  goto exit;
4697  }
4698  }
4699 
4700  const DB_VALUE *src = args[0];
4701  const DB_VALUE *pattern = args[1];
4702  const DB_VALUE *position = (num_args >= 3) ? args[2] : NULL;
4703  const DB_VALUE *match_type = (num_args == 4) ? args[3] : NULL;
4704 
4705  /* check type */
4706  if (!is_char_string (src) || !is_char_string (pattern))
4707  {
4708  error_status = ER_QSTR_INVALID_DATA_TYPE;
4709  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4710  goto exit;
4711  }
4712 
4713  if (position && !is_integer (position))
4714  {
4715  error_status = ER_QSTR_INVALID_DATA_TYPE;
4716  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4717  goto exit;
4718  }
4719 
4720  if (match_type && !is_char_string (match_type))
4721  {
4722  error_status = ER_QSTR_INVALID_DATA_TYPE;
4723  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4724  goto exit;
4725  }
4726 
4727  /* check codeset compatible */
4728  if (qstr_get_category (src) != qstr_get_category (pattern)
4729  || db_get_string_codeset (src) != db_get_string_codeset (pattern))
4730  {
4731  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
4732  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4733  goto exit;
4734  }
4735 
4736  /* check collation compatible */
4737  int coll_id = -1;
4739  if (coll_id == -1)
4740  {
4741  error_status = ER_QSTR_INCOMPATIBLE_COLLATIONS;
4742  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4743  goto exit;
4744  }
4745 
4746  /* check position argument */
4747  int position_value = (position != NULL) ? db_get_int (position) - 1 : 0;
4748  if (position_value < 0)
4749  {
4750  error_status = ER_QPROC_INVALID_PARAMETER;
4751  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4752  goto exit;
4753  }
4754 
4755  // *INDENT-OFF*
4756  /* match_type argument check */
4757  std::regex_constants::syntax_option_type reg_flags = std::regex_constants::ECMAScript | std::regex_constants::icase;
4758  if (match_type)
4759  {
4760  std::string match_type_str (db_get_string (match_type), db_get_string_size (match_type));
4761  error_status = cubregex::parse_match_type (reg_flags, match_type_str);
4762  if (error_status != NO_ERROR)
4763  {
4764  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4765  goto exit;
4766  }
4767  }
4768  // *INDENT-ON*
4769 
4770  /* check pattern string */
4771  if (db_get_string_size (pattern) == 0 || position_value >= db_get_string_size (src))
4772  {
4773  goto exit;
4774  }
4775 
4776  LANG_COLLATION *collation = lang_get_collation (coll_id);
4777  assert (collation != NULL);
4778 
4779  // *INDENT-OFF*
4780  /* compile pattern if needed */
4781  std::string pattern_string (db_get_string (pattern), db_get_string_size (pattern));
4782  if (cubregex::check_should_recompile (rx_compiled_regex, rx_compiled_pattern, pattern_string, reg_flags) == true)
4783  {
4784  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
4785  int pattern_length = pattern_string.size ();
4786  rx_compiled_pattern = (char *) db_private_alloc (NULL, pattern_length + 1);
4787  if (rx_compiled_pattern == NULL)
4788  {
4789  /* out of memory */
4790  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
4791  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4792  goto exit;
4793  }
4794  memcpy (rx_compiled_pattern, pattern_string.c_str (), pattern_length);
4795  rx_compiled_pattern[pattern_length] = '\0';
4796 
4797  error_status = cubregex::compile (rx_compiled_regex, rx_compiled_pattern, reg_flags, collation);
4798  if (error_status != NO_ERROR)
4799  {
4800  error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
4801  goto exit;
4802  }
4803  }
4804 
4805  /* perform regular expression according to the position and occurence value */
4806  int result_value = 0;
4807  std::string src_string (db_get_string (src), db_get_string_size (src));
4808  error_status = cubregex::count (result_value, *rx_compiled_regex, src_string, position_value, collation->codeset);
4809  if (error_status != NO_ERROR)
4810  {
4811  /* regex execution error */
4812  error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
4813  goto exit;
4814  }
4815  // *INDENT-ON*
4816 
4817  /* make result */
4818  db_make_int (result, result_value);
4819  goto exit;
4820  }
4821 
4822 exit:
4823  if (error_status != NO_ERROR)
4824  {
4825  db_make_int (result, 0);
4826  // *INDENT-OFF*
4827  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
4828  // *INDENT-ON*
4830  {
4831  /* we must not return an error code */
4832  er_clear ();
4833  error_status = NO_ERROR;
4834  }
4835  }
4836 
4837  if (comp_regex == NULL || comp_pattern == NULL)
4838  {
4839  /* free memory if this function is invoked in constant folding */
4840  // *INDENT-OFF*
4841  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
4842  // *INDENT-ON*
4843  }
4844  else
4845  {
4846  /* pass compiled regex object and compiled pattern out to reuse them */
4847  *comp_regex = rx_compiled_regex;
4848  *comp_pattern = rx_compiled_pattern;
4849  }
4850 
4851  return error_status;
4852 }
4853 
4854 /*
4855  * db_string_regexp_instr () returns an integer indicating the position of searched sub-string by regex pattern
4856  *
4857  * Arguments:
4858  * result: (IN) Result String
4859  * args: (IN) Array of Arguments
4860  * num_args: (IN) # of Arguments
4861  * comp_regex: (IN/OUT) Compiled regex object
4862  * comp_pattern: (IN/OUT) Compiled regex pattern
4863  *
4864  * Returns: int
4865  *
4866  * Errors:
4867  * ER_QSTR_INVALID_DATA_TYPE:
4868  * <src>, <pattern>, <replace> (if it's not NULL)
4869  * is not a character string.
4870  *
4871  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
4872  * <src>, <pattern> (if it's not NULL)
4873  * have different character code sets.
4874  *
4875  * ER_QSTR_INCOMPATIBLE_COLLATIONS:
4876  * <src>, <pattern>, <replace> (if it's not NULL)
4877  * are incompatible collations.
4878  *
4879  * ER_REGEX_COMPILE_ERROR:
4880  * An illegal regex pattern is specified.
4881  *
4882  * ER_REGEX_EXEC_ERROR:
4883  * An regex pattern is too complex or insufficient memory while executing regex matching
4884  *
4885  * ER_QPROC_INVALID_PARAMETER:
4886  * Invalid parameter exists
4887  *
4888  */
4889 int
4890 db_string_regexp_instr (DB_VALUE * result, DB_VALUE * args[], int const num_args,
4891  cub_regex_object ** comp_regex, char **comp_pattern)
4892 {
4893  int error_status = NO_ERROR;
4894  db_make_int (result, 0);
4895 
4896  /* get compiled pattern and regex object */
4897  char *rx_compiled_pattern = (comp_pattern != NULL) ? *comp_pattern : NULL;
4898  cub_regex_object *rx_compiled_regex = (comp_regex != NULL) ? *comp_regex : NULL;
4899 
4900  {
4901  for (int i = 0; i < num_args; i++)
4902  {
4903  DB_VALUE *arg = args[i];
4904  /* check for allocated DB value */
4905  assert (arg != (DB_VALUE *) NULL);
4906 
4907  /* if any argument is NULL, return NULL */
4908  if (DB_IS_NULL (arg))
4909  {
4910  db_make_null (result);
4911  goto exit;
4912  }
4913  }
4914 
4915  const DB_VALUE *src = args[0];
4916  const DB_VALUE *pattern = args[1];
4917  const DB_VALUE *position = (num_args >= 3) ? args[2] : NULL;
4918  const DB_VALUE *occurrence = (num_args >= 4) ? args[3] : NULL;
4919  const DB_VALUE *return_opt = (num_args >= 5) ? args[4] : NULL;
4920  const DB_VALUE *match_type = (num_args == 6) ? args[5] : NULL;
4921 
4922  /* check type */
4923  if (!is_char_string (src) || !is_char_string (pattern))
4924  {
4925  error_status = ER_QSTR_INVALID_DATA_TYPE;
4926  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4927  goto exit;
4928  }
4929 
4930  if (position && !is_integer (position))
4931  {
4932  error_status = ER_QSTR_INVALID_DATA_TYPE;
4933  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4934  goto exit;
4935  }
4936 
4937  if (occurrence && !is_integer (occurrence))
4938  {
4939  error_status = ER_QSTR_INVALID_DATA_TYPE;
4940  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4941  goto exit;
4942  }
4943 
4944  if (return_opt && !is_integer (return_opt))
4945  {
4946  error_status = ER_QSTR_INVALID_DATA_TYPE;
4947  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4948  goto exit;
4949  }
4950 
4951  if (match_type && !is_char_string (match_type))
4952  {
4953  error_status = ER_QSTR_INVALID_DATA_TYPE;
4954  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4955  goto exit;
4956  }
4957 
4958  /* check codeset compatible */
4959  if (qstr_get_category (src) != qstr_get_category (pattern)
4960  || db_get_string_codeset (src) != db_get_string_codeset (pattern))
4961  {
4962  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
4963  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4964  goto exit;
4965  }
4966 
4967  /* check collation compatible */
4968  int coll_id = -1;
4970  if (coll_id == -1)
4971  {
4972  error_status = ER_QSTR_INCOMPATIBLE_COLLATIONS;
4973  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4974  goto exit;
4975  }
4976 
4977  /* check position argument */
4978  int position_value = (position != NULL) ? db_get_int (position) - 1 : 0;
4979  if (position_value < 0)
4980  {
4981  error_status = ER_QPROC_INVALID_PARAMETER;
4982  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4983  goto exit;
4984  }
4985 
4986  /* check occurrence argument */
4987  int occurrence_value = (occurrence != NULL) ? db_get_int (occurrence) : 1;
4988  if (occurrence_value < 1)
4989  {
4990  error_status = ER_QPROC_INVALID_PARAMETER;
4991  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
4992  goto exit;
4993  }
4994 
4995  /* check return_opt argument */
4996  int return_opt_value = (return_opt != NULL) ? db_get_int (return_opt) : 0;
4997  if (return_opt_value != 0 && return_opt_value != 1)
4998  {
4999  error_status = ER_QPROC_INVALID_PARAMETER;
5000  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5001  goto exit;
5002  }
5003 
5004  // *INDENT-OFF*
5005  /* match_type argument check */
5006  std::regex_constants::syntax_option_type reg_flags = std::regex_constants::ECMAScript | std::regex_constants::icase;
5007  if (match_type)
5008  {
5009  std::string match_type_str (db_get_string (match_type), db_get_string_size (match_type));
5010  error_status = cubregex::parse_match_type (reg_flags, match_type_str);
5011  if (error_status != NO_ERROR)
5012  {
5013  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5014  goto exit;
5015  }
5016  }
5017  // *INDENT-ON*
5018 
5019  /* check pattern string */
5020  if (db_get_string_size (pattern) == 0 || position_value >= db_get_string_size (src))
5021  {
5022  goto exit;
5023  }
5024 
5025  LANG_COLLATION *collation = lang_get_collation (coll_id);
5026  assert (collation != NULL);
5027 
5028  // *INDENT-OFF*
5029  /* compile pattern if needed */
5030  std::string pattern_string (db_get_string (pattern), db_get_string_size (pattern));
5031  if (cubregex::check_should_recompile (rx_compiled_regex, rx_compiled_pattern, pattern_string, reg_flags) == true)
5032  {
5033  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
5034  int pattern_length = pattern_string.size ();
5035  rx_compiled_pattern = (char *) db_private_alloc (NULL, pattern_length + 1);
5036  if (rx_compiled_pattern == NULL)
5037  {
5038  /* out of memory */
5039  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
5040  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5041  goto exit;
5042  }
5043  memcpy (rx_compiled_pattern, pattern_string.c_str (), pattern_length);
5044  rx_compiled_pattern[pattern_length] = '\0';
5045 
5046  error_status = cubregex::compile (rx_compiled_regex, rx_compiled_pattern, reg_flags, collation);
5047  if (error_status != NO_ERROR)
5048  {
5049  error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
5050  goto exit;
5051  }
5052  }
5053 
5054  /* perform regular expression according to the position and occurence value */
5055  int result_value = 0;
5056  std::string src_string (db_get_string (src), db_get_string_size (src));
5057  error_status = cubregex::instr (result_value, *rx_compiled_regex, src_string, position_value,
5058  occurrence_value, return_opt_value, collation->codeset);
5059  if (error_status != NO_ERROR)
5060  {
5061  /* regex execution error */
5062  error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
5063  goto exit;
5064  }
5065  // *INDENT-ON*
5066 
5067  /* make result */
5068  db_make_int (result, result_value);
5069  goto exit;
5070  }
5071 
5072 exit:
5073  if (error_status != NO_ERROR)
5074  {
5075  db_make_null (result);
5076  // *INDENT-OFF*
5077  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
5078  // *INDENT-ON*
5080  {
5081  /* we must not return an error code */
5082  er_clear ();
5083  error_status = NO_ERROR;
5084  }
5085  }
5086 
5087  if (comp_regex == NULL || comp_pattern == NULL)
5088  {
5089  /* free memory if this function is invoked in constant folding */
5090  // *INDENT-OFF*
5091  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
5092  // *INDENT-ON*
5093  }
5094  else
5095  {
5096  /* pass compiled regex object and compiled pattern out to reuse them */
5097  *comp_regex = rx_compiled_regex;
5098  *comp_pattern = rx_compiled_pattern;
5099  }
5100 
5101  return error_status;
5102 }
5103 
5104 /*
5105  * db_string_regexp_like () checks for match between string and regex
5106  *
5107  * Arguments:
5108  * result: (IN) Result String
5109  * args: (IN) Array of Arguments
5110  * num_args: (IN) # of Arguments
5111  * comp_regex: (IN/OUT) Compiled regex object
5112  * comp_pattern: (IN/OUT) Compiled regex pattern
5113  *
5114  * Returns: int
5115  *
5116  * Errors:
5117  * ER_QSTR_INVALID_DATA_TYPE:
5118  * <src>, <pattern>, <replace> (if it's not NULL)
5119  * is not a character string.
5120  *
5121  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
5122  * <src>, <pattern> (if it's not NULL)
5123  * have different character code sets.
5124  *
5125  * ER_QSTR_INCOMPATIBLE_COLLATIONS:
5126  * <src>, <pattern>, <replace> (if it's not NULL)
5127  * are incompatible collations.
5128  *
5129  * ER_REGEX_COMPILE_ERROR:
5130  * An illegal regex pattern is specified.
5131  *
5132  * ER_REGEX_EXEC_ERROR:
5133  * An regex pattern is too complex or insufficient memory while executing regex matching
5134  *
5135  * ER_QPROC_INVALID_PARAMETER:
5136  * Invalid parameter exists
5137  *
5138  */
5139 int
5140 db_string_regexp_like (DB_VALUE * result, DB_VALUE * args[], int const num_args,
5141  cub_regex_object ** comp_regex, char **comp_pattern)
5142 {
5143  int error_status = NO_ERROR;
5144  db_make_null (result);
5145 
5146  /* get compiled pattern and regex object */
5147  char *rx_compiled_pattern = (comp_pattern != NULL) ? *comp_pattern : NULL;
5148  cub_regex_object *rx_compiled_regex = (comp_regex != NULL) ? *comp_regex : NULL;
5149 
5150  {
5151  for (int i = 0; i < num_args; i++)
5152  {
5153  DB_VALUE *arg = args[i];
5154  /* check for allocated DB value */
5155  assert (arg != (DB_VALUE *) NULL);
5156 
5157  /* if any argument is NULL, return NULL */
5158  if (DB_IS_NULL (arg))
5159  {
5160  goto exit;
5161  }
5162  }
5163 
5164  const DB_VALUE *src = args[0];
5165  const DB_VALUE *pattern = args[1];
5166  const DB_VALUE *match_type = (num_args == 3) ? args[2] : NULL;
5167 
5168  /* check type */
5169  if (!is_char_string (src) || !is_char_string (pattern))
5170  {
5171  error_status = ER_QSTR_INVALID_DATA_TYPE;
5172  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5173  goto exit;
5174  }
5175 
5176  if (match_type && !is_char_string (match_type))
5177  {
5178  error_status = ER_QSTR_INVALID_DATA_TYPE;
5179  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5180  goto exit;
5181  }
5182 
5183  /* check codeset compatible */
5184  if (qstr_get_category (src) != qstr_get_category (pattern)
5185  || db_get_string_codeset (src) != db_get_string_codeset (pattern))
5186  {
5187  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
5188  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5189  goto exit;
5190  }
5191 
5192  /* check collation compatible */
5193  int coll_id = -1;
5195  if (coll_id == -1)
5196  {
5197  error_status = ER_QSTR_INCOMPATIBLE_COLLATIONS;
5198  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5199  goto exit;
5200  }
5201 
5202  // *INDENT-OFF*
5203  /* match_type argument check */
5204  std::regex_constants::syntax_option_type reg_flags = std::regex_constants::ECMAScript | std::regex_constants::icase;
5205  if (match_type)
5206  {
5207  std::string match_type_str (db_get_string (match_type), db_get_string_size (match_type));
5208  error_status = cubregex::parse_match_type (reg_flags, match_type_str);
5209  if (error_status != NO_ERROR)
5210  {
5211  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5212  goto exit;
5213  }
5214  }
5215  // *INDENT-ON*
5216 
5217  /* check pattern string */
5218  if (db_get_string_size (pattern) == 0)
5219  {
5220  db_make_int (result, 0);
5221  goto exit;
5222  }
5223 
5224  LANG_COLLATION *collation = lang_get_collation (coll_id);
5225  assert (collation != NULL);
5226 
5227  // *INDENT-OFF*
5228  /* compile pattern if needed */
5229  std::string pattern_string (db_get_string (pattern), db_get_string_size (pattern));
5230  if (cubregex::check_should_recompile (rx_compiled_regex, rx_compiled_pattern, pattern_string, reg_flags) == true)
5231  {
5232  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
5233  int pattern_length = pattern_string.size ();
5234  rx_compiled_pattern = (char *) db_private_alloc (NULL, pattern_length + 1);
5235  if (rx_compiled_pattern == NULL)
5236  {
5237  /* out of memory */
5238  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
5239  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5240  goto exit;
5241  }
5242  memcpy (rx_compiled_pattern, pattern_string.c_str (), pattern_length);
5243  rx_compiled_pattern[pattern_length] = '\0';
5244 
5245  error_status = cubregex::compile (rx_compiled_regex, rx_compiled_pattern, reg_flags, collation);
5246  if (error_status != NO_ERROR)
5247  {
5248  error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
5249  goto exit;
5250  }
5251  }
5252 
5253  /* perform regular expression according to the position and occurence value */
5254  int result_value = 0;
5255  std::string src_string (db_get_string (src), db_get_string_size (src));
5256  error_status = cubregex::search (result_value, *rx_compiled_regex, src_string, collation->codeset);
5257  if (error_status != NO_ERROR)
5258  {
5259  /* regex execution error */
5260  error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
5261  goto exit;
5262  }
5263  // *INDENT-ON*
5264 
5265  /* make result */
5266  db_make_int (result, result_value);
5267  goto exit;
5268  }
5269 
5270 exit:
5271  if (error_status != NO_ERROR)
5272  {
5273  db_make_null (result);
5274  // *INDENT-OFF*
5275  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
5276  // *INDENT-ON*
5278  {
5279  /* we must not return an error code */
5280  er_clear ();
5281  error_status = NO_ERROR;
5282  }
5283  }
5284 
5285  if (comp_regex == NULL || comp_pattern == NULL)
5286  {
5287  /* free memory if this function is invoked in constant folding */
5288  // *INDENT-OFF*
5289  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
5290  // *INDENT-ON*
5291  }
5292  else
5293  {
5294  /* pass compiled regex object and compiled pattern out to reuse them */
5295  *comp_regex = rx_compiled_regex;
5296  *comp_pattern = rx_compiled_pattern;
5297  }
5298 
5299  return error_status;
5300 }
5301 
5302 /*
5303  * db_string_regexp_replace () returns replaced string by regex pattern
5304  *
5305  * Arguments:
5306  * result: (IN) Result String
5307  * args: (IN) Array of Arguments
5308  * num_args: (IN) # of Arguments
5309  * comp_regex: (IN/OUT) Compiled regex object
5310  * comp_pattern: (IN/OUT) Compiled regex pattern
5311  *
5312  * Returns: int
5313  *
5314  * Errors:
5315  * ER_QSTR_INVALID_DATA_TYPE:
5316  * <src>, <pattern>, <replace> (if it's not NULL)
5317  * is not a character string.
5318  *
5319  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
5320  * <src>, <pattern> (if it's not NULL)
5321  * have different character code sets.
5322  *
5323  * ER_QSTR_INCOMPATIBLE_COLLATIONS:
5324  * <src>, <pattern>, <replace> (if it's not NULL)
5325  * are incompatible collations.
5326  *
5327  * ER_REGEX_COMPILE_ERROR:
5328  * An illegal regex pattern is specified.
5329  *
5330  * ER_REGEX_EXEC_ERROR:
5331  * An regex pattern is too complex or insufficient memory while executing regex matching
5332  *
5333  * ER_QPROC_INVALID_PARAMETER:
5334  * Invalid parameter exists
5335  *
5336  */
5337 int
5338 db_string_regexp_replace (DB_VALUE * result, DB_VALUE * args[], int const num_args,
5339  cub_regex_object ** comp_regex, char **comp_pattern)
5340 {
5341  int error_status = NO_ERROR;
5342  db_make_null (result);
5343 
5344  /* get compiled pattern and regex object */
5345  char *rx_compiled_pattern = (comp_pattern != NULL) ? *comp_pattern : NULL;
5346  cub_regex_object *rx_compiled_regex = (comp_regex != NULL) ? *comp_regex : NULL;
5347 
5348  {
5349  for (int i = 0; i < num_args; i++)
5350  {
5351  DB_VALUE *arg = args[i];
5352  /* check for allocated DB value */
5353  assert (arg != (DB_VALUE *) NULL);
5354 
5355  /* if any argument is NULL, return NULL */
5356  if (DB_IS_NULL (arg))
5357  {
5358  goto exit;
5359  }
5360  }
5361 
5362  const DB_VALUE *src = args[0];
5363  const DB_VALUE *pattern = args[1];
5364  const DB_VALUE *replace = args[2];
5365  const DB_VALUE *position = (num_args >= 4) ? args[3] : NULL;
5366  const DB_VALUE *occurrence = (num_args >= 5) ? args[4] : NULL;
5367  const DB_VALUE *match_type = (num_args == 6) ? args[5] : NULL;
5368 
5369  /* check type */
5370  if (!is_char_string (src) || !is_char_string (pattern) || !is_char_string (replace))
5371  {
5372  error_status = ER_QSTR_INVALID_DATA_TYPE;
5373  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5374  goto exit;
5375  }
5376 
5377  if (position && !is_integer (position))
5378  {
5379  error_status = ER_QSTR_INVALID_DATA_TYPE;
5380  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5381  goto exit;
5382  }
5383 
5384  if (occurrence && !is_integer (occurrence))
5385  {
5386  error_status = ER_QSTR_INVALID_DATA_TYPE;
5387  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5388  goto exit;
5389  }
5390 
5391  if (match_type && !is_char_string (match_type))
5392  {
5393  error_status = ER_QSTR_INVALID_DATA_TYPE;
5394  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5395  goto exit;
5396  }
5397 
5398  /* check codeset compatible */
5399  QSTR_CATEGORY category = qstr_get_category (src);
5400  INTL_CODESET codeset = db_get_string_codeset (src);
5401 
5402  if (category != qstr_get_category (pattern) || codeset != db_get_string_codeset (pattern))
5403  {
5404  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
5405  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5406  goto exit;
5407  }
5408 
5409  if (category != qstr_get_category (replace) || codeset != db_get_string_codeset (replace))
5410  {
5411  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
5412  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5413  goto exit;
5414  }
5415 
5416  /* check collation compatible */
5417  int coll_id_tmp = -1, coll_id = -1;
5419  if (coll_id_tmp == -1)
5420  {
5421  error_status = ER_QSTR_INCOMPATIBLE_COLLATIONS;
5422  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5423  goto exit;
5424  }
5425 
5426  LANG_RT_COMMON_COLL (coll_id_tmp, db_get_string_collation (replace), coll_id);
5427  if (coll_id == -1)
5428  {
5429  error_status = ER_QSTR_INCOMPATIBLE_COLLATIONS;
5430  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5431  goto exit;
5432  }
5433 
5434  /* check position argument */
5435  int position_value = (position != NULL) ? db_get_int (position) - 1 : 0;
5436  if (position_value < 0)
5437  {
5438  error_status = ER_QPROC_INVALID_PARAMETER;
5439  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5440  goto exit;
5441  }
5442 
5443  /* check occurrence argument */
5444  int occurrence_value = (occurrence != NULL) ? db_get_int (occurrence) : 0;
5445  if (occurrence_value < 0)
5446  {
5447  error_status = ER_QPROC_INVALID_PARAMETER;
5448  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5449  goto exit;
5450  }
5451 
5452  // *INDENT-OFF*
5453  /* match_type argument check */
5454  std::regex_constants::syntax_option_type reg_flags = std::regex_constants::ECMAScript | std::regex_constants::icase;
5455  if (match_type)
5456  {
5457  std::string match_type_str (db_get_string (match_type), db_get_string_size (match_type));
5458  error_status = cubregex::parse_match_type (reg_flags, match_type_str);
5459  if (error_status != NO_ERROR)
5460  {
5461  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5462  goto exit;
5463  }
5464  }
5465  // *INDENT-ON*
5466 
5467  /* check pattern string */
5468  if (db_get_string_size (pattern) == 0 || position_value >= db_get_string_size (src))
5469  {
5470  goto exit_copy;
5471  }
5472 
5473  LANG_COLLATION *collation = lang_get_collation (coll_id);
5474  assert (collation != NULL);
5475 
5476  // *INDENT-OFF*
5477  /* compile pattern if needed */
5478  std::string pattern_string (db_get_string (pattern), db_get_string_size (pattern));
5479  if (cubregex::check_should_recompile (rx_compiled_regex, rx_compiled_pattern, pattern_string, reg_flags) == true)
5480  {
5481  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
5482  int pattern_length = pattern_string.size ();
5483  rx_compiled_pattern = (char *) db_private_alloc (NULL, pattern_length + 1);
5484  if (rx_compiled_pattern == NULL)
5485  {
5486  /* out of memory */
5487  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
5488  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5489  goto exit;
5490  }
5491  memcpy (rx_compiled_pattern, pattern_string.c_str (), pattern_length);
5492  rx_compiled_pattern[pattern_length] = '\0';
5493 
5494  error_status = cubregex::compile (rx_compiled_regex, rx_compiled_pattern, reg_flags, collation);
5495  if (error_status != NO_ERROR)
5496  {
5497  if (error_status == ER_QSTR_BAD_SRC_CODESET)
5498  {
5499  goto exit_copy;
5500  }
5501  else
5502  {
5503  goto exit;
5504  }
5505  }
5506  }
5507 
5508  /* perform regular expression according to the position and occurence value */
5509  std::string result_string;
5510  std::string src_string (db_get_string (src), db_get_string_size (src));
5511  std::string repl_string (db_get_string (replace), db_get_string_size (replace));
5512  error_status = cubregex::replace (result_string, *rx_compiled_regex, src_string, repl_string, position_value,
5513  occurrence_value, collation->codeset);
5514  if (error_status != NO_ERROR)
5515  {
5516  /* regex execution error */
5517  if (error_status == ER_QSTR_BAD_SRC_CODESET)
5518  {
5519  goto exit_copy;
5520  }
5521  else
5522  {
5523  goto exit;
5524  }
5525  }
5526  // *INDENT-ON*
5527 
5528  /* make result */
5529  int result_char_size = result_string.size ();
5530  char *result_char_string = (char *) db_private_alloc (NULL, result_char_size + 1);
5531  if (result_char_string == NULL)
5532  {
5533  /* out of memory */
5534  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
5535  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5536  goto exit;
5537  }
5538  memcpy (result_char_string, result_string.c_str (), result_char_size);
5539  result_char_string[result_char_size] = '\0';
5540 
5542  result_char_size, result_char_string, result_char_size,
5543  db_get_string_codeset (src), coll_id);
5544  result->need_clear = true;
5545  goto exit;
5546  }
5547 
5548 exit_copy:
5549  {
5550  /* clear error status */
5551  error_status = NO_ERROR;
5552 
5553  const DB_VALUE *src = args[0];
5554  pr_clone_value ((DB_VALUE *) src, result);
5555  DB_TYPE src_type = DB_VALUE_DOMAIN_TYPE (src);
5556  if (src_type == DB_TYPE_CHAR || src_type == DB_TYPE_NCHAR)
5557  {
5558  /* convert CHARACTER(N) to CHARACTER VARYING(N) */
5560  DB_VALUE_PRECISION (result), db_get_string (result), db_get_string_size (result),
5562  }
5563  result->need_clear = true;
5564  }
5565 
5566 exit:
5567  if (error_status != NO_ERROR)
5568  {
5569  db_make_null (result);
5570  // *INDENT-OFF*
5571  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
5572  // *INDENT-ON*
5574  {
5575  /* we must not return an error code */
5576  er_clear ();
5577  error_status = NO_ERROR;
5578  }
5579  }
5580 
5581  if (comp_regex == NULL || comp_pattern == NULL)
5582  {
5583  /* free memory if this function is invoked in constant folding */
5584  // *INDENT-OFF*
5585  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
5586  // *INDENT-ON*
5587  }
5588  else
5589  {
5590  /* pass compiled regex object and compiled pattern out to reuse them */
5591  *comp_regex = rx_compiled_regex;
5592  *comp_pattern = rx_compiled_pattern;
5593  }
5594 
5595  return error_status;
5596 }
5597 
5598 /*
5599  * db_string_regexp_substr () returns searched sub-string by regex pattern
5600  *
5601  * Arguments:
5602  * result: (IN) Result String
5603  * args: (IN) Array of Arguments
5604  * num_args: (IN) # of Arguments
5605  * comp_regex: (IN/OUT) Compiled regex object
5606  * comp_pattern: (IN/OUT) Compiled regex pattern
5607  *
5608  * Returns: int
5609  *
5610  * Errors:
5611  * ER_QSTR_INVALID_DATA_TYPE:
5612  * <src>, <pattern> (if it's not NULL)
5613  * is not a character string.
5614  *
5615  * ER_QSTR_INCOMPATIBLE_CODE_SETS:
5616  * <src_string>, <pattern> (if it's not NULL)
5617  * have different character code sets.
5618  *
5619  * ER_QSTR_INCOMPATIBLE_COLLATIONS:
5620  * <src_string>, <pattern> (if it's not NULL)
5621  * are incompatible collations.
5622  *
5623  * ER_REGEX_COMPILE_ERROR:
5624  * An illegal regex pattern is specified.
5625  *
5626  * ER_REGEX_EXEC_ERROR:
5627  * An regex pattern is too complex or insufficient memory while executing regex matching
5628  *
5629  * ER_QPROC_INVALID_PARAMETER:
5630  * Invalid parameter exists
5631  *
5632  */
5633 int
5634 db_string_regexp_substr (DB_VALUE * result, DB_VALUE * args[], int const num_args,
5635  cub_regex_object ** comp_regex, char **comp_pattern)
5636 {
5637  int error_status = NO_ERROR;
5638  db_make_null (result);
5639 
5640  /* get compiled pattern and regex object */
5641  char *rx_compiled_pattern = (comp_pattern != NULL) ? *comp_pattern : NULL;
5642  cub_regex_object *rx_compiled_regex = (comp_regex != NULL) ? *comp_regex : NULL;
5643 
5644  {
5645  for (int i = 0; i < num_args; i++)
5646  {
5647  DB_VALUE *arg = args[i];
5648  /* check for allocated DB value */
5649  assert (arg != (DB_VALUE *) NULL);
5650 
5651  /* if any argument is NULL, return NULL */
5652  if (DB_IS_NULL (arg))
5653  {
5654  goto exit;
5655  }
5656  }
5657 
5658  const DB_VALUE *src = args[0];
5659  const DB_VALUE *pattern = args[1];
5660  const DB_VALUE *position = (num_args >= 3) ? args[2] : NULL;
5661  const DB_VALUE *occurrence = (num_args >= 4) ? args[3] : NULL;
5662  const DB_VALUE *match_type = (num_args == 5) ? args[4] : NULL;
5663 
5664  /* check type */
5665  if (!is_char_string (src) || !is_char_string (pattern))
5666  {
5667  error_status = ER_QSTR_INVALID_DATA_TYPE;
5668  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5669  goto exit;
5670  }
5671 
5672  if (position && !is_integer (position))
5673  {
5674  error_status = ER_QSTR_INVALID_DATA_TYPE;
5675  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5676  goto exit;
5677  }
5678 
5679  if (occurrence && !is_integer (occurrence))
5680  {
5681  error_status = ER_QSTR_INVALID_DATA_TYPE;
5682  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5683  goto exit;
5684  }
5685 
5686  if (match_type && !is_char_string (match_type))
5687  {
5688  error_status = ER_QSTR_INVALID_DATA_TYPE;
5689  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5690  goto exit;
5691  }
5692 
5693  /* check codeset compatible */
5694  if (qstr_get_category (src) != qstr_get_category (pattern)
5695  || db_get_string_codeset (src) != db_get_string_codeset (pattern))
5696  {
5697  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
5698  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5699  goto exit;
5700  }
5701 
5702  /* check collation compatible */
5703  int coll_id = -1;
5705  if (coll_id == -1)
5706  {
5707  error_status = ER_QSTR_INCOMPATIBLE_COLLATIONS;
5708  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5709  goto exit;
5710  }
5711 
5712  /* check position argument */
5713  int position_value = (position != NULL) ? db_get_int (position) - 1 : 0;
5714  if (position_value < 0)
5715  {
5716  error_status = ER_QPROC_INVALID_PARAMETER;
5717  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5718  goto exit;
5719  }
5720 
5721  /* check occurrence argument */
5722  int occurrence_value = (occurrence != NULL) ? db_get_int (occurrence) : 1;
5723  if (occurrence_value < 1)
5724  {
5725  error_status = ER_QPROC_INVALID_PARAMETER;
5726  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5727  goto exit;
5728  }
5729 
5730  // *INDENT-OFF*
5731  /* match_type argument check */
5732  std::regex_constants::syntax_option_type reg_flags = std::regex_constants::ECMAScript | std::regex_constants::icase;
5733  if (match_type)
5734  {
5735  std::string match_type_str (db_get_string (match_type), db_get_string_size (match_type));
5736  error_status = cubregex::parse_match_type (reg_flags, match_type_str);
5737  if (error_status != NO_ERROR)
5738  {
5739  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5740  goto exit;
5741  }
5742  }
5743  // *INDENT-ON*
5744 
5745  /* check pattern string */
5746  if (db_get_string_size (pattern) == 0 || position_value >= db_get_string_size (src))
5747  {
5748  goto exit;
5749  }
5750 
5751  LANG_COLLATION *collation = lang_get_collation (coll_id);
5752  assert (collation != NULL);
5753 
5754  // *INDENT-OFF*
5755  /* compile pattern if needed */
5756  std::string pattern_string (db_get_string (pattern), db_get_string_size (pattern));
5757  if (cubregex::check_should_recompile (rx_compiled_regex, rx_compiled_pattern, pattern_string, reg_flags) == true)
5758  {
5759  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
5760  int pattern_length = pattern_string.size ();
5761  rx_compiled_pattern = (char *) db_private_alloc (NULL, pattern_length + 1);
5762  if (rx_compiled_pattern == NULL)
5763  {
5764  /* out of memory */
5765  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
5766  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5767  goto exit;
5768  }
5769  memcpy (rx_compiled_pattern, pattern_string.c_str (), pattern_length);
5770  rx_compiled_pattern[pattern_length] = '\0';
5771 
5772  error_status = cubregex::compile (rx_compiled_regex, rx_compiled_pattern, reg_flags, collation);
5773  if (error_status != NO_ERROR)
5774  {
5775  error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
5776  goto exit;
5777  }
5778  }
5779 
5780  /* perform regular expression according to the position and occurence value */
5781  std::string result_string;
5782  bool is_matched = false;
5783  std::string src_string (db_get_string (src), db_get_string_size (src));
5784  error_status = cubregex::substr (result_string, is_matched, *rx_compiled_regex, src_string, position_value,
5785  occurrence_value, collation->codeset);
5786  if (error_status != NO_ERROR)
5787  {
5788  /* regex execution error */
5789  error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
5790  goto exit;
5791  }
5792  // *INDENT-ON*
5793 
5794  if (is_matched)
5795  {
5796  /* make result */
5797  int result_char_size = result_string.size ();
5798  char *result_char_string = (char *) db_private_alloc (NULL, result_char_size + 1);
5799  if (result_char_string == NULL)
5800  {
5801  /* out of memory */
5802  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
5803  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
5804  goto exit;
5805  }
5806  memcpy (result_char_string, result_string.c_str (), result_char_size);
5807  result_char_string[result_char_size] = '\0';
5808 
5810  result, result_char_size, result_char_string, result_char_size,
5811  db_get_string_codeset (src), coll_id);
5812  result->need_clear = true;
5813  }
5814  }
5815 
5816 exit:
5817  if (error_status != NO_ERROR)
5818  {
5819  db_make_null (result);
5820  // *INDENT-OFF*
5821  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
5822  // *INDENT-ON*
5824  {
5825  /* we must not return an error code */
5826  er_clear ();
5827  error_status = NO_ERROR;
5828  }
5829  }
5830 
5831  if (comp_regex == NULL || comp_pattern == NULL)
5832  {
5833  /* free memory if this function is invoked in constant folding */
5834  // *INDENT-OFF*
5835  cubregex::clear (rx_compiled_regex, rx_compiled_pattern);
5836  // *INDENT-ON*
5837  }
5838  else
5839  {
5840  /* pass compiled regex object and compiled pattern out to reuse them */
5841  *comp_regex = rx_compiled_regex;
5842  *comp_pattern = rx_compiled_pattern;
5843  }
5844 
5845  return error_status;
5846 }
5847 
5848 /*
5849  * db_string_limit_size_string () - limits the size of a string. It limits
5850  * the size of value, but in case of fixed
5851  * length values, it limits also the domain
5852  * precision.
5853  *
5854  * Arguments:
5855  * src: (IN) String variable.
5856  * result: (OUT) Variable with new size
5857  * new_size: (IN) New size for the string (in bytes).
5858  * spare_bytes: (OUT) the number of bytes that could fit from last
5859  * truncated character
5860  *
5861  * Returns:
5862  *
5863  * Errors:
5864  * ER_QSTR_INVALID_DATA_TYPE:
5865  * <src_string> is not CHAR, NCHAR, VARCHAR, VARNCHAR, BIT or
5866  * VARBIT
5867  *
5868  * Note : result variable must already be created
5869  * operates directly on memory buffer
5870  * if the new size is greater than the source, it clones the input
5871  * The truncation of domain size in case of fixed domain argument
5872  * is needed in context of GROUP_CONCAT, when the result needs to be
5873  * truncated.
5874  * The full-char adjusting code in this function is specific to
5875  * GROUP_CONCAT.
5876  */
5877 int
5878 db_string_limit_size_string (DB_VALUE * src_string, DB_VALUE * result, const int new_size, int *spare_bytes)
5879 {
5880  int result_size = 0, src_size = 0, src_domain_precision = 0;
5881  unsigned char *r;
5882  int error_status = NO_ERROR;
5883  DB_TYPE src_type;
5884  int char_count = 0, adj_char_size = 0;
5885 
5886  assert (src_string != (DB_VALUE *) NULL);
5887  assert (result != (DB_VALUE *) NULL);
5888  assert (new_size >= 0);
5889  assert (spare_bytes != NULL);
5890 
5891  src_type = DB_VALUE_DOMAIN_TYPE (src_string);
5892 
5893  if (!QSTR_IS_ANY_CHAR_OR_BIT (src_type))
5894  {
5896  }
5897 
5898  src_size = db_get_string_size (src_string);
5899  src_domain_precision = DB_VALUE_PRECISION (src_string);
5900 
5901  if (new_size < 0)
5902  {
5904  }
5905 
5906  *spare_bytes = 0;
5907 
5908  if (src_size <= 0 || new_size >= src_size)
5909  {
5910  assert (error_status == NO_ERROR);
5911  goto exit_copy;
5912  }
5913 
5914  result_size = new_size;
5915 
5916  /* Adjust size to a full character. */
5917  if (DB_VALUE_DOMAIN_TYPE (src_string) == DB_TYPE_VARBIT || DB_VALUE_DOMAIN_TYPE (src_string) == DB_TYPE_BIT)
5918  {
5919  char_count = result_size;
5920  adj_char_size = result_size;
5921  }
5922  else
5923  {
5924  intl_char_count (DB_GET_UCHAR (src_string), result_size, db_get_string_codeset (src_string), &char_count);
5925  intl_char_size (DB_GET_UCHAR (src_string), char_count, db_get_string_codeset (src_string), &adj_char_size);
5926  }
5927 
5928  assert (adj_char_size <= result_size);
5929 
5930  /* Allocate storage for the result string */
5931  r = (unsigned char *) db_private_alloc (NULL, (size_t) result_size + 1);
5932  if (r == NULL)
5933  {
5934  goto mem_error;
5935  }
5936  memset (r, 0, (size_t) result_size + 1);
5937 
5938  if (adj_char_size > 0)
5939  {
5940  memcpy (r, db_get_string (src_string), adj_char_size);
5941  }
5942  /* adjust also domain precision in case of fixed length types */
5943  if (QSTR_IS_FIXED_LENGTH (src_type))
5944  {
5945  src_domain_precision = MIN (src_domain_precision, char_count);
5946  }
5947  qstr_make_typed_string (src_type, result, src_domain_precision, (char *) r, adj_char_size,
5948  db_get_string_codeset (src_string), db_get_string_collation (src_string));
5949  result->need_clear = true;
5950 
5951  *spare_bytes = result_size - adj_char_size;
5952 
5953  assert (error_status == NO_ERROR);
5954  return error_status;
5955 
5956 mem_error:
5957  assert (er_errid () != NO_ERROR);
5958  error_status = er_errid ();
5959  return error_status;
5960 
5961 exit_copy:
5962  assert (error_status == NO_ERROR);
5963  error_status = pr_clone_value (src_string, result);
5964  return error_status;
5965 }
5966 
5967 /*
5968  * db_string_fix_string_size () - fixes the size of a string according to its
5969  * content (NULL terminator)
5970  *
5971  * Arguments:
5972  * src: (IN/OUT) String variable.
5973  *
5974  * Returns:
5975  *
5976  * Errors:
5977  * ER_QSTR_INVALID_DATA_TYPE:
5978  * <src_string> is not CHAR, NCHAR, VARCHAR, VARNCHAR
5979  *
5980  * Note : Used in context of GROUP_CONCAT. It is complementary to
5981  * 'db_string_limit_size_string' function
5982  */
5983 int
5985 {
5986  int val_size = 0;
5987  int string_size = 0;
5988  int error_status = NO_ERROR;
5989  DB_TYPE src_type;
5990  bool save_need_clear;
5991 
5992  assert (src_string != (DB_VALUE *) NULL);
5993 
5994  src_type = DB_VALUE_DOMAIN_TYPE (src_string);
5995 
5996  if (!QSTR_IS_ANY_CHAR (src_type))
5997  {
5999  }
6000 
6001  val_size = db_get_string_size (src_string);
6002  /* this is a system generated string; it must have the null terminator */
6003  string_size = strlen (db_get_string (src_string));
6004  assert (val_size >= string_size);
6005 
6006  save_need_clear = src_string->need_clear;
6007  qstr_make_typed_string (src_type, src_string, DB_VALUE_PRECISION (src_string), db_get_string (src_string),
6008  string_size, db_get_string_codeset (src_string), db_get_string_collation (src_string));
6009  src_string->need_clear = save_need_clear;
6010 
6011  return error_status;
6012 }
6013 
6014 /*
6015  * qstr_eval_like () -
6016  */
6017 /* TODO this function should be modified to not rely on the special value 1
6018  in the situation of no escape character. With the current
6019  implementation it will incorrectly process strings containing
6020  character 1.
6021 */
6022 static int
6023 qstr_eval_like (const char *tar, int tar_length, const char *expr, int expr_length, const char *escape,
6024  INTL_CODESET codeset, int coll_id)
6025 {
6026  const int IN_CHECK = 0;
6027  const int IN_PERCENT = 1;
6028 
6029  int status = IN_CHECK;
6030  const unsigned char *tarstack[STACK_SIZE], *exprstack[STACK_SIZE];
6031  int stackp = -1;
6032 
6033  const unsigned char *tar_ptr, *end_tar;
6034  const unsigned char *expr_ptr, *end_expr;
6035  bool escape_is_match_one = ((escape != NULL) && *escape == LIKE_WILDCARD_MATCH_ONE);
6036  bool escape_is_match_many = ((escape != NULL) && *escape == LIKE_WILDCARD_MATCH_MANY);
6037  unsigned char pad_char[2];
6038 
6039 
6040  LANG_COLLATION *current_collation;
6041 
6042  int pad_char_size;
6043 
6044  current_collation = lang_get_collation (coll_id);
6045  intl_pad_char (codeset, pad_char, &pad_char_size);
6046 
6047  tar_ptr = REINTERPRET_CAST (const unsigned char *, tar);
6048  expr_ptr = REINTERPRET_CAST (const unsigned char *, expr);
6049  end_tar = tar_ptr + tar_length;
6050  end_expr = expr_ptr + expr_length;
6051 
6052  while (1)
6053  {
6054  int dummy = 1;
6055 
6056  if (status == IN_CHECK)
6057  {
6058  bool go_back = true;
6059  if (expr_ptr == end_expr)
6060  {
6061  go_back = false;
6062 
6063  if (codeset != INTL_CODESET_KSC5601_EUC)
6064  {
6065  while (tar_ptr < end_tar && *tar_ptr == ' ')
6066  {
6067  tar_ptr++;
6068  }
6069  }
6070  else
6071  {
6072  while (tar_ptr < end_tar)
6073  {
6074  /* EUC-KR : both ASCII space and EUC-KR padding char are ignored */
6075  if (*tar_ptr == ' ')
6076  {
6077  tar_ptr++;
6078  }
6079  else if (tar_ptr + pad_char_size <= end_tar && memcmp (tar_ptr, pad_char, pad_char_size) == 0)
6080  {
6081  tar_ptr += pad_char_size;
6082  }
6083  else
6084  {
6085  break;
6086  }
6087  }
6088  }
6089 
6090  if (tar_ptr == end_tar)
6091  {
6092  return V_TRUE;
6093  }
6094  else
6095  {
6096  if (stackp >= 0 && stackp < STACK_SIZE)
6097  {
6098  tar_ptr = tarstack[stackp];
6099  INTL_NEXT_CHAR (tar_ptr, tar_ptr, codeset, &dummy);
6100  expr_ptr = exprstack[stackp--];
6101  }
6102  else
6103  {
6104  return V_FALSE;
6105  }
6106  }
6107  }
6108  else if (!escape_is_match_many && expr_ptr < end_expr && *expr_ptr == LIKE_WILDCARD_MATCH_MANY)
6109  {
6110  go_back = false;
6111  status = IN_PERCENT;
6112  while ((expr_ptr + 1 < end_expr) && *(expr_ptr + 1) == LIKE_WILDCARD_MATCH_MANY)
6113  {
6114  expr_ptr++;
6115  }
6116  }
6117  else if (tar_ptr < end_tar && expr_ptr < end_expr)
6118  {
6119  if (!escape_is_match_one && *expr_ptr == LIKE_WILDCARD_MATCH_ONE)
6120  {
6121  INTL_NEXT_CHAR (tar_ptr, tar_ptr, codeset, &dummy);
6122  expr_ptr++;
6123  go_back = false;
6124  }
6125  else
6126  {
6127  const unsigned char *expr_seq_end = expr_ptr;
6128  int cmp;
6129  int tar_matched_size;
6130  unsigned char *match_escape = NULL;
6131  bool inescape = false;
6132  bool has_last_escape = false;
6133 
6134  /* build sequence to check (until wildcard) */
6135  do
6136  {
6137  if (!inescape
6138  && (((!escape_is_match_many && *expr_seq_end == LIKE_WILDCARD_MATCH_MANY)
6139  || (!escape_is_match_one && *expr_seq_end == LIKE_WILDCARD_MATCH_ONE))))
6140  {
6141  break;
6142  }
6143 
6144  /* set escape for match: if remains NULL, we don't check for escape in matching function */
6145  if (!inescape && escape != NULL
6146  && intl_cmp_char (expr_seq_end, (unsigned char *) escape, codeset, &dummy) == 0)
6147  {
6148  /* last escape character is not considered escape, but normal character */
6149  if (expr_seq_end + 1 >= end_expr)
6150  {
6151  has_last_escape = true;
6152  inescape = false;
6153  }
6154  else
6155  {
6156  inescape = true;
6157  match_escape = (unsigned char *) escape;
6158  }
6159  }
6160  else
6161  {
6162  inescape = false;
6163  }
6164  INTL_NEXT_CHAR (expr_seq_end, expr_seq_end, codeset, &dummy);
6165  }
6166  while (expr_seq_end < end_expr);
6167 
6168  assert (end_tar - tar_ptr > 0);
6169  assert (expr_seq_end - expr_ptr > 0);
6170 
6171  /* match using collation */
6172  cmp =
6173  current_collation->strmatch (current_collation, true, tar_ptr, CAST_BUFLEN (end_tar - tar_ptr),
6174  expr_ptr, CAST_BUFLEN (expr_seq_end - expr_ptr), match_escape,
6175  has_last_escape, &tar_matched_size, false);
6176 
6177  if (cmp == 0)
6178  {
6179  tar_ptr += tar_matched_size;
6180  expr_ptr = expr_seq_end;
6181  go_back = false;
6182  }
6183 
6184  assert (tar_ptr <= end_tar);
6185  assert (expr_ptr <= end_expr);
6186  }
6187  }
6188 
6189  if (go_back)
6190  {
6191  if (stackp >= 0 && stackp < STACK_SIZE)
6192  {
6193  tar_ptr = tarstack[stackp];
6194  INTL_NEXT_CHAR (tar_ptr, tar_ptr, codeset, &dummy);
6195  expr_ptr = exprstack[stackp--];
6196  }
6197  else if (stackp > STACK_SIZE)
6198  {
6199  return V_ERROR;
6200  }
6201  else
6202  {
6203  return V_FALSE;
6204  }
6205  }
6206  }
6207  else
6208  {
6209  const unsigned char *next_expr_ptr;
6210  INTL_NEXT_CHAR (next_expr_ptr, expr_ptr, codeset, &dummy);
6211 
6212  assert (status == IN_PERCENT);
6213  if ((next_expr_ptr < end_expr) && (!escape_is_match_one || escape == NULL)
6214  && *next_expr_ptr == LIKE_WILDCARD_MATCH_ONE)
6215  {
6216  if (stackp >= STACK_SIZE - 1)
6217  {
6218  return V_ERROR;
6219  }
6220  tarstack[++stackp] = tar_ptr;
6221  exprstack[stackp] = expr_ptr;
6222  expr_ptr = next_expr_ptr;
6223  INTL_NEXT_CHAR (next_expr_ptr, expr_ptr, codeset, &dummy);
6224 
6225  if (stackp > STACK_SIZE)
6226  {
6227  return V_ERROR;
6228  }
6229  status = IN_CHECK;
6230  continue;
6231  }
6232 
6233  if (next_expr_ptr == end_expr)
6234  {
6235  return V_TRUE;
6236  }
6237 
6238  if (tar_ptr < end_tar && next_expr_ptr < end_expr)
6239  {
6240  const unsigned char *expr_seq_end = next_expr_ptr;
6241  int cmp;
6242  int tar_matched_size;
6243  unsigned char *match_escape = NULL;
6244  bool inescape = false;
6245  bool has_last_escape = false;
6246 
6247  /* build sequence to check (until wildcard) */
6248  do
6249  {
6250  if (!inescape
6251  && (((!escape_is_match_many && *expr_seq_end == LIKE_WILDCARD_MATCH_MANY)
6252  || (!escape_is_match_one && *expr_seq_end == LIKE_WILDCARD_MATCH_ONE))))
6253  {
6254  break;
6255  }
6256 
6257  /* set escape for match: if remains NULL, we don't check for escape in matching function */
6258  if (!inescape && escape != NULL
6259  && intl_cmp_char (expr_seq_end, (unsigned char *) escape, codeset, &dummy) == 0)
6260  {
6261  /* last escape character is not considered escape, but normal character */
6262  if (expr_seq_end + 1 >= end_expr)
6263  {
6264  has_last_escape = true;
6265  inescape = false;
6266  }
6267  else
6268  {
6269  inescape = true;
6270  match_escape = (unsigned char *) escape;
6271  }
6272  }
6273  else
6274  {
6275  inescape = false;
6276  }
6277 
6278  INTL_NEXT_CHAR (expr_seq_end, expr_seq_end, codeset, &dummy);
6279  }
6280  while (expr_seq_end < end_expr);
6281 
6282  assert (end_tar - tar_ptr > 0);
6283  assert (expr_seq_end - next_expr_ptr > 0);
6284 
6285  do
6286  {
6287  /* match using collation */
6288  cmp =
6289  current_collation->strmatch (current_collation, true, tar_ptr, CAST_BUFLEN (end_tar - tar_ptr),
6290  next_expr_ptr, CAST_BUFLEN (expr_seq_end - next_expr_ptr),
6291  match_escape, has_last_escape, &tar_matched_size, false);
6292  if (cmp == 0)
6293  {
6294  if (stackp >= STACK_SIZE - 1)
6295  {
6296  return V_ERROR;
6297  }
6298  tarstack[++stackp] = tar_ptr;
6299  tar_ptr += tar_matched_size;
6300 
6301  exprstack[stackp] = expr_ptr;
6302  expr_ptr = expr_seq_end;
6303 
6304  if (stackp > STACK_SIZE)
6305  {
6306  return V_ERROR;
6307  }
6308  status = IN_CHECK;
6309  break;
6310  }
6311  else
6312  {
6313  /* check starting from next char */
6314  INTL_NEXT_CHAR (tar_ptr, tar_ptr, codeset, &dummy);
6315  }
6316  }
6317  while (tar_ptr < end_tar);
6318  }
6319  }
6320 
6321  if (tar_ptr == end_tar)
6322  {
6323  while (expr_ptr < end_expr && *expr_ptr == LIKE_WILDCARD_MATCH_MANY)
6324  {
6325  expr_ptr++;
6326  }
6327 
6328  if (expr_ptr == end_expr)
6329  {
6330  return V_TRUE;
6331  }
6332  else
6333  {
6334  return V_FALSE;
6335  }
6336  }
6337  else if (tar_ptr > end_tar)
6338  {
6339  return V_FALSE;
6340  }
6341  }
6342 }
6343 
6344 /*
6345  * db_string_replace () -
6346  */
6347 int
6348 db_string_replace (const DB_VALUE * src_string, const DB_VALUE * srch_string, const DB_VALUE * repl_string,
6349  DB_VALUE * replaced_string)
6350 {
6351  int error_status = NO_ERROR;
6352  unsigned char *result_ptr = NULL;
6353  int result_length = 0, result_size = 0;
6354  DB_TYPE result_type = DB_TYPE_NULL;
6355  int coll_id, coll_id_tmp;
6356  DB_VALUE dummy_string;
6357  int is_repl_string_omitted = false;
6358  const unsigned char *repl_string_ptr = NULL;
6359  int repl_string_size = 0;
6360 
6361  assert (src_string != (DB_VALUE *) NULL);
6362  assert (replaced_string != (DB_VALUE *) NULL);
6363 
6364  db_make_null (&dummy_string);
6365 
6366  if (repl_string == NULL)
6367  {
6368  is_repl_string_omitted = true;
6369  }
6370 
6371  if (DB_IS_NULL (src_string) || DB_IS_NULL (srch_string) || (!is_repl_string_omitted && DB_IS_NULL (repl_string)))
6372  {
6373  if (prm_get_bool_value (PRM_ID_ORACLE_STYLE_EMPTY_STRING) == true && !DB_IS_NULL (src_string)
6374  && is_char_string (src_string))
6375  /* srch_string or repl_string is null */
6376  {
6377  error_status =
6378  db_string_make_empty_typed_string (&dummy_string, DB_VALUE_DOMAIN_TYPE (src_string),
6380  db_get_string_collation (src_string));
6381  if (error_status != NO_ERROR)
6382  {
6383  goto exit;
6384  }
6385 
6386  if (DB_IS_NULL (srch_string))
6387  {
6388  srch_string = &dummy_string;
6389  }
6390  if (!is_repl_string_omitted && DB_IS_NULL (repl_string))
6391  {
6392  repl_string = &dummy_string;
6393  }
6394  }
6395  else
6396  {
6397  if (QSTR_IS_CHAR (DB_VALUE_DOMAIN_TYPE (src_string)))
6398  {
6399  error_status =
6401  }
6402  else
6403  {
6404  error_status =
6406  }
6407  goto exit;
6408  }
6409  }
6410 
6411  if (!is_char_string (srch_string) || (!is_repl_string_omitted && !is_char_string (repl_string))
6412  || !is_char_string (src_string))
6413  {
6414  error_status = ER_QSTR_INVALID_DATA_TYPE;
6416  goto exit;
6417  }
6418 
6419  if ((qstr_get_category (src_string) != qstr_get_category (srch_string))
6420  || (!is_repl_string_omitted && (qstr_get_category (src_string) != qstr_get_category (repl_string)))
6421  || (!is_repl_string_omitted && (qstr_get_category (srch_string) != qstr_get_category (repl_string)))
6422  || ((db_get_string_codeset (src_string) != db_get_string_codeset (srch_string)))
6423  || (!is_repl_string_omitted && (db_get_string_codeset (src_string) != db_get_string_codeset (repl_string))))
6424  {
6425  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
6427  goto exit;
6428  }
6429 
6430  LANG_RT_COMMON_COLL (db_get_string_collation (src_string), db_get_string_collation (srch_string), coll_id_tmp);
6431  if (coll_id_tmp == -1)
6432  {
6433  error_status = ER_QSTR_INCOMPATIBLE_COLLATIONS;
6434  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
6435  goto exit;
6436  }
6437 
6438  if (!is_repl_string_omitted)
6439  {
6440  LANG_RT_COMMON_COLL (coll_id_tmp, db_get_string_collation (repl_string), coll_id);
6441  if (coll_id == -1)
6442  {
6443  error_status = ER_QSTR_INCOMPATIBLE_COLLATIONS;
6444  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
6445  goto exit;
6446  }
6447  }
6448  else
6449  {
6450  coll_id = coll_id_tmp;
6451  }
6452 
6454 
6455  if (!is_repl_string_omitted)
6456  {
6457  repl_string_ptr = DB_GET_UCHAR (repl_string);
6458  repl_string_size = db_get_string_size (repl_string);
6459  }
6460  error_status = qstr_replace (DB_GET_UCHAR (src_string), db_get_string_length (src_string),
6461  db_get_string_size (src_string), db_get_string_codeset (src_string), coll_id,
6462  DB_GET_UCHAR (srch_string), db_get_string_size (srch_string), repl_string_ptr,
6463  repl_string_size, &result_ptr, &result_length, &result_size);
6464 
6465  if (error_status == NO_ERROR && result_ptr != NULL)
6466  {
6467  if (result_length == 0)
6468  {
6469  qstr_make_typed_string (result_type, replaced_string,
6470  (db_get_string_length (src_string) == 0) ? 1 : db_get_string_length (src_string),
6471  (char *) result_ptr, result_size, db_get_string_codeset (src_string), coll_id);
6472  }
6473  else
6474  {
6475  qstr_make_typed_string (result_type, replaced_string, result_length, (char *) result_ptr, result_size,
6476  db_get_string_codeset (src_string), coll_id);
6477  }
6478  result_ptr[result_size] = 0;
6479  replaced_string->need_clear = true;
6480  }
6481 
6482 exit:
6483  pr_clear_value (&dummy_string);
6484 
6485  return error_status;
6486 }
6487 
6488 /* qstr_replace () -
6489  */
6490 static int
6491 qstr_replace (const unsigned char *src_buf, int src_len, int src_size, INTL_CODESET codeset, int coll_id,
6492  const unsigned char *srch_str_buf, int srch_str_size, const unsigned char *repl_str_buf,
6493  int repl_str_size, unsigned char **result_buf, int *result_len, int *result_size)
6494 {
6495 #define REPL_POS_ARRAY_EXTENT 32
6496 
6497  int error_status = NO_ERROR;
6498  int char_size, i;
6499  const unsigned char *matched_ptr, *matched_ptr_end;
6500  unsigned char *target;
6501  int *repl_pos_array = NULL;
6502  int repl_pos_array_size;
6503  int repl_pos_array_cnt;
6504  const unsigned char *src_ptr;
6505  int repl_str_len;
6506 
6507  assert (result_buf != NULL);
6508 
6509  *result_buf = NULL;
6510 
6511  /*
6512  * if search string is NULL or is longer than source string
6513  * copy source string as a result
6514  */
6515  if (srch_str_buf == NULL || src_size < srch_str_size)
6516  {
6517  *result_buf = (unsigned char *) db_private_alloc (NULL, (size_t) src_size + 1);
6518  if (*result_buf == NULL)
6519  {
6520  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
6521  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 1, (size_t) src_size);
6522  goto exit;
6523  }
6524 
6525  (void) memcpy ((char *) (*result_buf), (char *) src_buf, src_size);
6526  *result_len = src_len;
6527  *result_size = src_size;
6528  goto exit;
6529  }
6530 
6531  if (repl_str_buf == NULL)
6532  {
6533  repl_str_buf = (unsigned char *) "";
6534  }
6535 
6536  repl_pos_array_size = REPL_POS_ARRAY_EXTENT;
6537  repl_pos_array = (int *) db_private_alloc (NULL, 2 * sizeof (int) * repl_pos_array_size);
6538  if (repl_pos_array == NULL)
6539  {
6540  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
6541  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 1, 2 * sizeof (int) * repl_pos_array_size);
6542  goto exit;
6543  }
6544 
6545  intl_char_count (repl_str_buf, repl_str_size, codeset, &repl_str_len);
6546 
6547  repl_pos_array_cnt = 0;
6548  for (*result_size = 0, *result_len = 0, src_ptr = src_buf;
6549  src_size > 0 && srch_str_size > 0 && src_ptr < src_buf + src_size;)
6550  {
6551  int matched_size;
6552 
6553  if (QSTR_MATCH (coll_id, src_ptr, CAST_BUFLEN (src_buf - src_ptr) + src_size, srch_str_buf, srch_str_size, NULL,
6554  false, &matched_size) == 0)
6555  {
6556  /* store byte position and size of matched string */
6557  if (repl_pos_array_cnt >= repl_pos_array_size)
6558  {
6559  repl_pos_array_size += REPL_POS_ARRAY_EXTENT;
6560  repl_pos_array =
6561  (int *) db_private_realloc (NULL, repl_pos_array, 2 * sizeof (int) * repl_pos_array_size);
6562  if (repl_pos_array == NULL)
6563  {
6564  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
6565  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 1, 2 * sizeof (int) * repl_pos_array_size);
6566  goto exit;
6567  }
6568  }
6569  repl_pos_array[repl_pos_array_cnt * 2] = CAST_BUFLEN (src_ptr - src_buf);
6570  repl_pos_array[repl_pos_array_cnt * 2 + 1] = matched_size;
6571  src_ptr += matched_size;
6572  repl_pos_array_cnt++;
6573  *result_size += repl_str_size;
6574  *result_len += repl_str_len;
6575  }
6576  else
6577  {
6578  INTL_NEXT_CHAR (src_ptr, src_ptr, codeset, &char_size);
6579  *result_size += char_size;
6580  *result_len += 1;
6581  }
6582  }
6583 
6584  if (repl_pos_array_cnt == 0)
6585  {
6586  *result_size = src_size;
6587  }
6588 
6589  *result_buf = (unsigned char *) db_private_alloc (NULL, (size_t) (*result_size) + 1);
6590  if (*result_buf == NULL)
6591  {
6592  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
6593  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 1, (size_t) (*result_size + 1));
6594  goto exit;
6595  }
6596 
6597  matched_ptr = matched_ptr_end = src_buf;
6598  target = *result_buf;
6599  for (i = 0; i < repl_pos_array_cnt; i++)
6600  {
6601  /* first, copy non matched original string preceeding matched part */
6602  matched_ptr = src_buf + repl_pos_array[2 * i];
6603  if ((matched_ptr - matched_ptr_end) > 0)
6604  {
6605  (void) memcpy (target, matched_ptr_end, matched_ptr - matched_ptr_end);
6606  target += matched_ptr - matched_ptr_end;
6607  }
6608 
6609  /* second, copy replacing string */
6610  (void) memcpy (target, repl_str_buf, repl_str_size);
6611  target += repl_str_size;
6612  matched_ptr_end = matched_ptr + repl_pos_array[2 * i + 1];
6613  }
6614 
6615  /* append any trailing string (after last matched part) */
6616  if (matched_ptr_end < src_buf + src_size)
6617  {
6618  (void) memcpy (target, matched_ptr_end, src_buf + src_size - matched_ptr_end);
6619  target += src_buf + src_size - matched_ptr_end;
6620  }
6621 
6622  assert (target - *result_buf == *result_size);
6623 
6624 exit:
6625  if (repl_pos_array != NULL)
6626  {
6627  db_private_free (NULL, repl_pos_array);
6628  }
6629 
6630  return error_status;
6631 
6632 #undef REPL_POS_ARRAY_EXTENT
6633 }
6634 
6635 /*
6636  * db_string_translate () -
6637  */
6638 int
6639 db_string_translate (const DB_VALUE * src_string, const DB_VALUE * from_string, const DB_VALUE * to_string,
6640  DB_VALUE * transed_string)
6641 {
6642  int error_status = NO_ERROR;
6643  unsigned char *result_ptr = NULL;
6644  int result_length = 0, result_size = 0;
6645  DB_TYPE result_type = DB_TYPE_NULL;
6646 
6647  assert (src_string != (DB_VALUE *) NULL);
6648  assert (transed_string != (DB_VALUE *) NULL);
6649 
6650  if (DB_IS_NULL (src_string) || DB_IS_NULL (from_string) || DB_IS_NULL (to_string))
6651  {
6652  if (QSTR_IS_CHAR (DB_VALUE_DOMAIN_TYPE (src_string)))
6653  {
6655  }
6656  else
6657  {
6658  error_status =
6660  }
6661  return error_status;
6662  }
6663 
6664  if (!is_char_string (from_string) || !is_char_string (to_string) || !is_char_string (src_string))
6665  {
6666  error_status = ER_QSTR_INVALID_DATA_TYPE;
6667  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
6668  return error_status;
6669  }
6670 
6671  if ((qstr_get_category (src_string) != qstr_get_category (from_string))
6672  || (qstr_get_category (src_string) != qstr_get_category (to_string))
6673  || (qstr_get_category (from_string) != qstr_get_category (to_string))
6674  || (db_get_string_codeset (src_string) != db_get_string_codeset (from_string))
6675  || (db_get_string_codeset (src_string) != db_get_string_codeset (to_string)))
6676  {
6677  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
6678  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
6679  return error_status;
6680  }
6681 
6682  error_status = qstr_translate (DB_GET_UCHAR (src_string), DB_VALUE_DOMAIN_TYPE (src_string),
6683  db_get_string_size (src_string), db_get_string_codeset (src_string),
6684  DB_GET_UCHAR (from_string), db_get_string_size (from_string),
6685  DB_GET_UCHAR (to_string), db_get_string_size (to_string), &result_ptr,
6686  &result_type, &result_length, &result_size);
6687 
6688  if (error_status == NO_ERROR && result_ptr != NULL)
6689  {
6690  if (result_length == 0)
6691  {
6692  qstr_make_typed_string (result_type, transed_string,
6693  (db_get_string_length (src_string) == 0) ? 1 : db_get_string_length (src_string),
6694  (char *) result_ptr, result_size, db_get_string_codeset (src_string),
6695  db_get_string_collation (src_string));
6696  }
6697  else
6698  {
6699  qstr_make_typed_string (result_type, transed_string, result_length, (char *) result_ptr, result_size,
6700  db_get_string_codeset (src_string), db_get_string_collation (src_string));
6701  }
6702  result_ptr[result_size] = 0;
6703  transed_string->need_clear = true;
6704  }
6705 
6706  return error_status;
6707 }
6708 
6709 /*
6710  * qstr_translate () -
6711  */
6712 static int
6713 qstr_translate (const unsigned char *src_ptr, DB_TYPE src_type, int src_size, INTL_CODESET codeset,
6714  const unsigned char *from_str_ptr, int from_str_size, const unsigned char *to_str_ptr, int to_str_size,
6715  unsigned char **result_ptr, DB_TYPE * result_type, int *result_len, int *result_size)
6716 {
6717  int error_status = NO_ERROR;
6718  int j, offset, offset1, offset2;
6719  int from_char_loc, to_char_cnt, to_char_loc;
6720  const unsigned char *srcp, *fromp;
6721  unsigned char *target = NULL;
6722  int matched = 0, phase = 0;
6723 
6724  if ((from_str_ptr == NULL && to_str_ptr != NULL))
6725  {
6726  error_status = ER_QPROC_INVALID_PARAMETER;
6727  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
6728  return error_status;
6729  }
6730 
6731  if (to_str_ptr == NULL)
6732  {
6733  to_str_ptr = (unsigned char *) "";
6734  }
6735 
6736  /* check from, to string */
6737  to_char_cnt = 0;
6738  for (j = 0; j < to_str_size;)
6739  {
6740  intl_char_size (to_str_ptr + j, 1, codeset, &offset2);
6741  j += offset2;
6742  to_char_cnt++;
6743  }
6744 
6745  /* calculate total length */
6746  *result_size = 0;
6747  phase = 0;
6748 
6749 loop:
6750  srcp = src_ptr;
6751  for (srcp = src_ptr; srcp < src_ptr + src_size;)
6752  {
6753  intl_char_size (srcp, 1, codeset, &offset);
6754 
6755  matched = 0;
6756  from_char_loc = 0;
6757  for (fromp = from_str_ptr; fromp != NULL && fromp < from_str_ptr + from_str_size; from_char_loc++)
6758  {
6759  intl_char_size (fromp, 1, codeset, &offset1);
6760 
6761  /* if source and from char are matched, translate */
6762  if ((offset == offset1) && (memcmp (srcp, fromp, offset) == 0))
6763  {
6764  matched = 1;
6765  to_char_loc = 0;
6766  for (j = 0; j < to_str_size;)
6767  {
6768  intl_char_size (to_str_ptr + j, 1, codeset, &offset2);
6769 
6770  if (to_char_loc == from_char_loc)
6771  { /* if matched char exist, replace */
6772  if (phase == 0)
6773  {
6774  *result_size += offset2;
6775  }
6776  else
6777  {
6778  memcpy (target, to_str_ptr + j, offset2);
6779  target += offset2;
6780  }
6781  break;
6782  }
6783  j += offset2;
6784  to_char_loc++;
6785  }
6786  break;
6787  }
6788  fromp += offset1;
6789  }
6790  if (!matched)
6791  { /* preserve source char */
6792  if (phase == 0)
6793  {
6794  *result_size += offset;
6795  }
6796  else
6797  {
6798  memcpy (target, srcp, offset);
6799  target += offset;
6800  }
6801  }
6802  srcp += offset;
6803  }
6804 
6805  if (phase == 1)
6806  {
6807  return error_status;
6808  }
6809 
6810  /* evaluate result string length */
6811  *result_type = QSTR_IS_NATIONAL_CHAR (src_type) ? DB_TYPE_VARNCHAR : DB_TYPE_VARCHAR;
6812  *result_ptr = (unsigned char *) db_private_alloc (NULL, (size_t) * result_size + 1);
6813  if (*result_ptr == NULL)
6814  {
6815  assert (er_errid () != NO_ERROR);
6816  error_status = er_errid ();
6817  return error_status;
6818  }
6819  if (phase == 0)
6820  {
6821  phase = 1;
6822  target = *result_ptr;
6823  *result_len = *result_size;
6824  goto loop;
6825  }
6826 
6827  return error_status;
6828 }
6829 
6830 /*
6831  * db_bit_string_coerce () -
6832  *
6833  * Arguments:
6834  * src_string: (In) Source string
6835  * dest_string: (Out) Coerced string
6836  * data_status: (Out) Data status
6837  *
6838  * Returns: int
6839  *
6840  * Errors:
6841  * ER_QSTR_INVALID_DATA_TYPE
6842  * <src_string> is not a bit string
6843  * ER_QSTR_INCOMPATIBLE_CODE_SETS
6844  * <dest_domain> is not a compatible domain type
6845  *
6846  * Note:
6847  *
6848  * This function coerces a bit string from one domain to another.
6849  * A new DB_VALUE is created making use of the memory manager and
6850  * domain information stored in <dest_value>, and coercing the
6851  * data portion of <src_string>.
6852  *
6853  * If any loss of data due to truncation occurs, <data_status>
6854  * is set to DATA_STATUS_TRUNCATED.
6855  *
6856  * The destination container should have the memory manager, precision
6857  * and domain type initialized.
6858  *
6859  * Assert:
6860  *
6861  * 1. src_string != (DB_VALUE *) NULL
6862  * 2. dest_value != (DB_VALUE *) NULL
6863  * 3. data_status != (DB_DATA_STATUS *) NULL
6864  *
6865  */
6866 
6867 int
6868 db_bit_string_coerce (const DB_VALUE * src_string, DB_VALUE * dest_string, DB_DATA_STATUS * data_status)
6869 {
6870  DB_TYPE src_type, dest_type;
6871 
6872  int error_status = NO_ERROR;
6873 
6874  /* Assert that DB_VALUE structures have been allocated. */
6875  assert (src_string != (DB_VALUE *) NULL);
6876  assert (dest_string != (DB_VALUE *) NULL);
6877  assert (data_status != (DB_DATA_STATUS *) NULL);
6878 
6879  /* Initialize status value */
6880  *data_status = DATA_STATUS_OK;
6881 
6882  /* Categorize the two input parameters and check for errors. Verify that the parameters are both character strings. */
6883  src_type = DB_VALUE_DOMAIN_TYPE (src_string);
6884  dest_type = DB_VALUE_DOMAIN_TYPE (dest_string);
6885 
6886  if (!QSTR_IS_BIT (src_type) || !QSTR_IS_BIT (dest_type))
6887  {
6888  error_status = ER_QSTR_INVALID_DATA_TYPE;
6889  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
6890  }
6891  else if (qstr_get_category (src_string) != qstr_get_category (dest_string))
6892  {
6893  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
6894  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
6895  }
6896  else if (DB_IS_NULL (src_string))
6897  {
6899  }
6900  else
6901  {
6902  unsigned char *dest;
6903  int dest_prec;
6904  int dest_length;
6905 
6906  if (DB_VALUE_PRECISION (dest_string) == TP_FLOATING_PRECISION_VALUE)
6907  {
6908  dest_prec = db_get_string_length (src_string);
6909  }
6910  else
6911  {
6912  dest_prec = DB_VALUE_PRECISION (dest_string);
6913  }
6914 
6915  error_status = qstr_bit_coerce (DB_GET_UCHAR (src_string), db_get_string_length (src_string),
6916  QSTR_VALUE_PRECISION (src_string), src_type, &dest, &dest_length, dest_prec,
6917  dest_type, data_status);
6918 
6919  if (error_status == NO_ERROR)
6920  {
6921  qstr_make_typed_string (dest_type, dest_string, DB_VALUE_PRECISION (dest_string), (char *) dest, dest_length,
6923  dest_string->need_clear = true;
6924  }
6925  }
6926 
6927  return error_status;
6928 }
6929 
6930 /*
6931  * db_char_string_coerce () -
6932  *
6933  * Arguments:
6934  * src_string: (In) Source string
6935  * dest_string: (Out) Coerced string
6936  * data_status: (Out) Data status
6937  *
6938  * Returns: int
6939  *
6940  * Errors:
6941  * ER_QSTR_INVALID_DATA_TYPE
6942  * <src_string> and <dest_string> are not both char strings
6943  * ER_QSTR_INCOMPATIBLE_CODE_SETS
6944  * <dest_domain> is not a compatible domain type
6945  *
6946  * Note:
6947  *
6948  * This function coerces a char string from one domain to
6949  * another. A new DB_VALUE is created making use of the
6950  * memory manager and domain information stored in
6951  * <dest_value>, and coercing the data portion of
6952  * <src_string>.
6953  *
6954  * If any loss of data due to truncation occurs, <data_status>
6955  * is set to DATA_STATUS_TRUNCATED.
6956  *
6957  * Assert:
6958  *
6959  * 1. src_string != (DB_VALUE *) NULL
6960  * 2. dest_value != (DB_VALUE *) NULL
6961  * 3. data_status != (DB_DATA_STATUS *) NULL
6962  *
6963  */
6964 
6965 int
6966 db_char_string_coerce (const DB_VALUE * src_string, DB_VALUE * dest_string, DB_DATA_STATUS * data_status)
6967 {
6968  int error_status = NO_ERROR;
6969 
6970  /* Assert that DB_VALUE structures have been allocated. */
6971  assert (src_string != (DB_VALUE *) NULL);
6972  assert (dest_string != (DB_VALUE *) NULL);
6973  assert (data_status != (DB_DATA_STATUS *) NULL);
6974 
6975  /* Initialize status value */
6976  *data_status = DATA_STATUS_OK;
6977 
6978  /*
6979  * Categorize the two input parameters and check for errors.
6980  * Verify that the parameters are both character strings.
6981  * Verify that the source and destination strings are of
6982  * the same character code set.
6983  * Verify that the source string is not NULL.
6984  * Otherwise, coerce.
6985  */
6986  if (!is_char_string (src_string) || !is_char_string (dest_string))
6987  {
6988  error_status = ER_QSTR_INVALID_DATA_TYPE;
6989  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
6990  }
6991  else if (qstr_get_category (src_string) != qstr_get_category (dest_string))
6992  {
6993  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
6994  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
6995  }
6996  else if (DB_IS_NULL (src_string))
6997  {
6999  }
7000  else
7001  {
7002  unsigned char *dest;
7003  int dest_prec;
7004  int dest_length;
7005  int dest_size;
7006  INTL_CODESET src_codeset = db_get_string_codeset (src_string);
7007  INTL_CODESET dest_codeset = db_get_string_codeset (dest_string);
7008 
7009  if (!INTL_CAN_COERCE_CS (src_codeset, dest_codeset))
7010  {
7011  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
7012  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
7013  return error_status;
7014  }
7015 
7016  /* Initialize the memory manager of the destination */
7017  if (DB_VALUE_PRECISION (dest_string) == TP_FLOATING_PRECISION_VALUE)
7018  {
7019  dest_prec = db_get_string_length (src_string);
7020  }
7021  else
7022  {
7023  dest_prec = DB_VALUE_PRECISION (dest_string);
7024  }
7025 
7026  error_status = qstr_coerce (DB_GET_UCHAR (src_string), db_get_string_length (src_string),
7027  QSTR_VALUE_PRECISION (src_string), DB_VALUE_DOMAIN_TYPE (src_string), src_codeset,
7028  dest_codeset, &dest, &dest_length, &dest_size, dest_prec,
7029  DB_VALUE_DOMAIN_TYPE (dest_string), data_status);
7030 
7031  if (error_status == NO_ERROR && dest != NULL)
7032  {
7033  qstr_make_typed_string (DB_VALUE_DOMAIN_TYPE (dest_string), dest_string, DB_VALUE_PRECISION (dest_string),
7034  (char *) dest, dest_size, db_get_string_codeset (dest_string),
7035  db_get_string_collation (dest_string));
7036  dest[dest_size] = 0;
7037  dest_string->need_clear = true;
7038  }
7039  }
7040 
7041  return error_status;
7042 }
7043 
7044 /*
7045  * db_string_make_empty_typed_string() -
7046  *
7047  * Arguments:
7048  * db_val : (In/Out) value to make
7049  * db_type : (In) Type of string (char,nchar,bit)
7050  * precision : (In)
7051  * codeset : (In)
7052  * collation_id : (In)
7053  *
7054  * Returns: int
7055  *
7056  * Errors:
7057  * ER_QSTR_INVALID_DATA_TYPE
7058  * <type> is not one of (char,nchar,bit)
7059  * ER_OUT_OF_VIRTUAL_MEMORY
7060  * out of memory
7061  *
7062  */
7063 int
7064 db_string_make_empty_typed_string (DB_VALUE * db_val, const DB_TYPE db_type, int precision, int codeset,
7065  int collation_id)
7066 {
7067  int status = NO_ERROR;
7068  char *buf = NULL;
7069 
7070  /* handle bad cases */
7071  assert (db_val != NULL);
7072  assert (precision >= DB_DEFAULT_PRECISION);
7073 
7074  if (db_type != DB_TYPE_BIT && db_type != DB_TYPE_VARBIT && db_type != DB_TYPE_CHAR && db_type != DB_TYPE_VARCHAR
7075  && db_type != DB_TYPE_NCHAR && db_type != DB_TYPE_VARNCHAR)
7076  {
7078  }
7079 
7080  if (db_val == NULL)
7081  {
7083  }
7084 
7085  if (DB_IS_NULL (db_val))
7086  {
7087  db_value_domain_init (db_val, db_type, precision, 0);
7088  }
7089  precision = ((precision < DB_DEFAULT_PRECISION) ? DB_DEFAULT_PRECISION : precision);
7090 
7091  /* create an empty string DB VALUE */
7092  buf = (char *) db_private_alloc (NULL, 1);
7093  if (buf == NULL)
7094  {
7095  return ER_OUT_OF_VIRTUAL_MEMORY;
7096  }
7097  *buf = '\0';
7098 
7099  /* We are sure it's a string type value. */
7100  db_make_db_char (db_val, (INTL_CODESET) (codeset), collation_id, buf, 0);
7101  db_val->need_clear = true;
7102 
7103  return status;
7104 }
7105 
7106 /*
7107  * db_find_string_in_in_set () - find the position of a string token in
7108  * a string containing comma separated tokens
7109  * return : error code or NO_ERROR
7110  * needle (in) : the token to look for
7111  * stack (in) : the set of tokens
7112  * result (in/out) : will hold the position of the token
7113  */
7114 int
7115 db_find_string_in_in_set (const DB_VALUE * needle, const DB_VALUE * stack, DB_VALUE * result)
7116 {
7117  int err = NO_ERROR;
7118  DB_TYPE needle_type, stack_type;
7119  int position = 1;
7120  int stack_size = 0, needle_size = 0;
7121  const char *stack_str = NULL;
7122  const char *needle_str = NULL;
7123  int cmp, coll_id, matched_stack_size;
7124  const char *stack_ptr, *stack_end, *elem_start;
7125 
7126  if (DB_IS_NULL (needle) || DB_IS_NULL (stack))
7127  {
7128  db_make_null (result);
7129  return NO_ERROR;
7130  }
7131 
7132  /*
7133  * Categorize the parameters into respective code sets.
7134  * Verify that the parameters are both character strings.
7135  * Verify that the input strings belong to compatible code sets.
7136  */
7137  needle_type = DB_VALUE_DOMAIN_TYPE (needle);
7138  stack_type = DB_VALUE_DOMAIN_TYPE (stack);
7139 
7140  if (!QSTR_IS_ANY_CHAR_OR_BIT (needle_type) || !QSTR_IS_ANY_CHAR_OR_BIT (stack_type))
7141  {
7142  assert (false);
7145  goto error_return;
7146  }
7147 
7148  if (qstr_get_category (needle) != qstr_get_category (stack)
7149  || db_get_string_codeset (needle) != db_get_string_codeset (stack))
7150  {
7153  goto error_return;
7154  }
7155 
7157  if (coll_id == -1)
7158  {
7161  goto error_return;
7162  }
7163 
7164  stack_str = db_get_string (stack);
7165  stack_size = db_get_string_size (stack);
7166 
7167  needle_str = db_get_string (needle);
7168  needle_size = db_get_string_size (needle);
7169 
7170  if (stack_size == 0 && needle_size == 0)
7171  {
7172  /* if both are empty string, no match */
7173  goto match_not_found;
7174  }
7175 
7176  for (elem_start = stack_ptr = stack_str, stack_end = stack_str + stack_size; stack_ptr <= stack_end; ++stack_ptr)
7177  {
7178  if (stack_ptr == stack_end || *stack_ptr == ',')
7179  {
7180  if (stack_ptr == elem_start)
7181  {
7182  if (needle_size == 0)
7183  {
7184  db_make_int (result, position);
7185  return NO_ERROR;
7186  }
7187  }
7188  else
7189  {
7190  assert (stack_ptr > elem_start);
7191  /* check using collation */
7192  if (needle_size > 0)
7193  {
7194  cmp = QSTR_MATCH (coll_id, (const unsigned char *) elem_start, CAST_BUFLEN (stack_ptr - elem_start),
7195  (const unsigned char *) needle_str, needle_size, NULL, false, &matched_stack_size);
7196  if (cmp == 0 && matched_stack_size == CAST_BUFLEN (stack_ptr - elem_start))
7197  {
7198  db_make_int (result, position);
7199  return NO_ERROR;
7200  }
7201  }
7202  }
7203 
7204  position++;
7205  elem_start = stack_ptr + 1;
7206  }
7207  }
7208 
7209 match_not_found:
7210  /* if we didn't find it in the loop above, then there is no match */
7211  db_make_int (result, 0);
7212  return NO_ERROR;
7213 
7214 error_return:
7215  db_make_null (result);
7217  {
7218  er_clear ();
7219  return NO_ERROR;
7220  }
7221  return err;
7222 }
7223 
7224 /*
7225  * db_bigint_to_binary_string () - compute the string representation of a
7226  * binary a value
7227  * return : error code or NO_ERROR
7228  * src_bigint (in) : the binary value
7229  * result (out) : the string representation of the binary value
7230  */
7231 int
7232 db_bigint_to_binary_string (const DB_VALUE * src_bigint, DB_VALUE * result)
7233 {
7234  int error = NO_ERROR;
7235  int i = 0;
7236  DB_BIGINT bigint_val = 0;
7237  int digits_count = 0;
7238  char *binary_form = NULL;
7239 
7240  if (DB_IS_NULL (src_bigint))
7241  {
7242  db_make_null (result);
7243  return NO_ERROR;
7244  }
7245 
7246  if (DB_VALUE_TYPE (src_bigint) != DB_TYPE_BIGINT)
7247  {
7248  assert (false);
7250  error = ER_QSTR_INVALID_DATA_TYPE;
7251  goto error_return;
7252  }
7253 
7254  bigint_val = db_get_bigint (src_bigint);
7255 
7256  /* count the number of digits in bigint_val */
7257  if (bigint_val < (DB_BIGINT) 0)
7258  {
7259  /* MSB is the sign bit */
7260  digits_count = sizeof (DB_BIGINT) * 8;
7261  }
7262  else if (bigint_val == 0)
7263  {
7264  digits_count = 1;
7265  }
7266  else
7267  {
7268  i = 0;
7269  /* positive numbers have at most 8 * sizeof(DB_BIGINT) - 1 digits */
7270  while ((DB_BIGINT) 1 << i <= bigint_val && i < (int) sizeof (DB_BIGINT) * 8 - 1)
7271  {
7272  i++;
7273  }
7274  digits_count = i;
7275  }
7276 
7277  binary_form = (char *) db_private_alloc (NULL, digits_count + 1);
7278  if (binary_form == NULL)
7279  {
7280  error = ER_OUT_OF_VIRTUAL_MEMORY;
7281  goto error_return;
7282  }
7283  memset (binary_form, 0, digits_count + 1);
7284 
7285  for (i = 0; i < digits_count; i++)
7286  {
7287  binary_form[digits_count - i - 1] = ((DB_BIGINT) 1 << i) & bigint_val ? '1' : '0';
7288  }
7289 
7290  db_make_varchar (result, digits_count, binary_form, digits_count, LANG_COERCIBLE_CODESET, LANG_COERCIBLE_COLL);
7291  result->need_clear = true;
7292  return error;
7293 
7294 error_return:
7295  if (binary_form != NULL)
7296  {
7297  db_private_free (NULL, binary_form);
7298  }
7299  pr_clear_value (result);
7300  db_make_null (result);
7302  {
7303  er_clear ();
7304  return NO_ERROR;
7305  }
7306  return error;
7307 }
7308 
7309 /*
7310  * db_add_time () - add the time represented by right to the value left
7311  * return : error code or NO_ERROR
7312  * left (in) : left operand
7313  * right (in) : right operand
7314  * result (out) : result
7315  * domain (in) : the domain of the return type
7316  */
7317 int
7318 db_add_time (const DB_VALUE * left, const DB_VALUE * right, DB_VALUE * result, const TP_DOMAIN * domain)
7319 {
7320  int error = NO_ERROR;
7321  DB_DATETIME ldatetime = { 0, 0 };
7322  DB_DATETIME result_datetime = { 0, 0 };
7323  bool left_is_datetime = false;
7324  int month = 0, day = 0, year = 0;
7325  int lsecond = 0, lminute = 0, lhour = 0, lms = 0;
7326  bool is_time_decoded = false;
7327  bool is_datetime_decoded = false;
7328  int rsecond = 0, rminute = 0, rhour = 0, rms = 0;
7329  DB_TIME ltime = 0, rtime = 0;
7330  char *res_s = NULL;
7331  DB_TYPE result_type = DB_TYPE_NULL;
7332  INTL_CODESET codeset;
7333  int collation_id;
7334  TZ_ID tz_id = 0;
7335  DB_DATETIMETZ ldatetimetz;
7336 
7337  if (DB_IS_NULL (left) || DB_IS_NULL (right))
7338  {
7339  db_make_null (result);
7340  return NO_ERROR;
7341  }
7342 
7343  switch (DB_VALUE_TYPE (left))
7344  {
7345  case DB_TYPE_CHAR:
7346  case DB_TYPE_VARCHAR:
7347  case DB_TYPE_NCHAR:
7348  case DB_TYPE_VARNCHAR:
7349  {
7350  bool has_zone = false;
7351  bool is_explicit_time = false;
7352 
7353  error = db_string_to_datetimetz_ex (db_get_string (left), db_get_string_size (left), &ldatetimetz, &has_zone);
7354  if (error == NO_ERROR && has_zone == true)
7355  {
7356  tz_id = ldatetimetz.tz_id;
7357  ldatetime = ldatetimetz.datetime;
7358  result_type = DB_TYPE_DATETIMETZ;
7359  left_is_datetime = true;
7360  break;
7361  }
7362 
7363  error = db_date_parse_time (db_get_string (left), db_get_string_size (left), &ltime, &lms);
7364  if (error != NO_ERROR)
7365  {
7366  /* left may be a date string, try it here */
7367  error =
7369  &is_explicit_time, NULL, NULL, NULL);
7370  if (error != NO_ERROR)
7371  {
7373  error = ER_TIME_CONVERSION;
7374  goto error_return;
7375  }
7376 
7377  left_is_datetime = true;
7378  if (has_zone == true)
7379  {
7380  result_type = DB_TYPE_DATETIMETZ;
7381  }
7382  else
7383  {
7384  result_type = DB_TYPE_VARCHAR;
7385  }
7386  break;
7387  }
7388 
7389  db_time_decode (&ltime, &lhour, &lminute, &lsecond);
7390  is_time_decoded = true;
7391 
7392  error =
7393  db_date_parse_datetime_parts (db_get_string (left), db_get_string_size (left), &ldatetime, &is_explicit_time,
7394  NULL, NULL, NULL);
7395  if (error != NO_ERROR || !is_explicit_time)
7396  {
7397  left_is_datetime = false;
7398  }
7399  else
7400  {
7401  int lsecond2 = 0, lminute2 = 0, lhour2 = 0, lms2 = 0;
7402  left_is_datetime = true;
7403  db_datetime_decode (&ldatetime, &month, &day, &year, &lhour2, &lminute2, &lsecond2, &lms2);
7404  is_datetime_decoded = true;
7405  if (lhour2 != lhour || lminute2 != lminute || lsecond2 != lsecond || lms2 != lms)
7406  {
7407  month = 0;
7408  day = 0;
7409  year = 0;
7410  left_is_datetime = false;
7411  }
7412  }
7413  result_type = DB_TYPE_VARCHAR;
7414  break;
7415  }
7416 
7417  case DB_TYPE_DATETIME:
7418  case DB_TYPE_DATETIMELTZ:
7419  ldatetime = *(db_get_datetime (left));
7420  left_is_datetime = true;
7421 
7422  if (DB_VALUE_TYPE (left) == DB_TYPE_DATETIME)
7423  {
7424  result_type = DB_TYPE_DATETIME;
7425  }
7426  else
7427  {
7428  result_type = DB_TYPE_DATETIMELTZ;
7429  }
7430  break;
7431 
7432  case DB_TYPE_DATETIMETZ:
7433  {
7434  DB_DATETIMETZ *dt_tz_p;
7435 
7436  dt_tz_p = db_get_datetimetz (left);
7437  ldatetime = dt_tz_p->datetime;
7438  tz_id = dt_tz_p->tz_id;
7439  left_is_datetime = true;
7440  result_type = DB_TYPE_DATETIMETZ;
7441  break;
7442  }
7443  case DB_TYPE_TIMESTAMP:
7444  case DB_TYPE_TIMESTAMPLTZ:
7445  db_timestamp_decode_utc (db_get_timestamp (left), &ldatetime.date, &ltime);
7446  ldatetime.time = ltime * 1000;
7447  left_is_datetime = true;
7448  if (DB_VALUE_TYPE (left) == DB_TYPE_TIMESTAMP)
7449  {
7450  result_type = DB_TYPE_DATETIME;
7451  }
7452  else
7453  {
7454  result_type = DB_TYPE_DATETIMELTZ;
7455  }
7456  break;
7457 
7458  case DB_TYPE_TIMESTAMPTZ:
7459  {
7460  DB_TIMESTAMPTZ *ts_tz_p;
7461 
7462  ts_tz_p = db_get_timestamptz (left);
7463  db_timestamp_decode_utc (&ts_tz_p->timestamp, &ldatetime.date, &ltime);
7464 
7465  ldatetime.time = ltime * 1000;
7466  left_is_datetime = true;
7467  tz_id = ts_tz_p->tz_id;
7468  result_type = DB_TYPE_DATETIMETZ;
7469  break;
7470  }
7471 
7472  case DB_TYPE_DATE:
7473  ldatetime.date = *(db_get_date (left));
7474  left_is_datetime = true;
7475  result_type = DB_TYPE_DATETIME;
7476  break;
7477 
7478  case DB_TYPE_TIME:
7479  ltime = *(db_get_time (left));
7480  left_is_datetime = false;
7481  result_type = DB_TYPE_TIME;
7482  break;
7483 
7484  default:
7486  error = ER_QSTR_INVALID_DATA_TYPE;
7487  goto error_return;
7488  break;
7489  }
7490 
7491  if (db_get_time_from_dbvalue (right, &rhour, &rminute, &rsecond, &rms) != NO_ERROR)
7492  {
7494  error = ER_QSTR_INVALID_DATA_TYPE;
7495  goto error_return;
7496  }
7497 
7498  if (left_is_datetime)
7499  {
7500  /* add a datetime to a time */
7501  if (!is_datetime_decoded)
7502  {
7503  db_datetime_decode (&ldatetime, &month, &day, &year, &lhour, &lminute, &lsecond, &lms);
7504  }
7505 
7506  if (month == 0 && day == 0 && year == 0 && lhour == 0 && lminute == 0 && lsecond == 0 && lms == 0)
7507  {
7510  goto error_return;
7511  }
7512 
7513  error =
7514  add_and_normalize_date_time (&year, &month, &day, &lhour, &lminute, &lsecond, &lms, 0, 0, 0, rhour, rminute,
7515  rsecond, 0);
7516  if (error != NO_ERROR)
7517  {
7519  error = ER_DATE_CONVERSION;
7520  goto error_return;
7521  }
7522 
7523  if (result_type != DB_TYPE_DATETIMETZ)
7524  {
7525  db_datetime_encode (&result_datetime, month, day, year, lhour, lminute, lsecond, lms);
7526  }
7527  }
7528  else
7529  {
7530  /* add two time values */
7531  int seconds = 0;
7532  if (!is_time_decoded)
7533  {
7534  db_time_decode (&ltime, &lhour, &lminute, &lsecond);
7535  }
7536  seconds = (lhour + rhour) * 3600 + (lminute + rminute) * 60 + lsecond + rsecond;
7537  rhour = seconds / 3600;
7538  if (rhour > 23)
7539  {
7541  error = ER_TIME_CONVERSION;
7542  goto error_return;
7543  }
7544  rminute = (seconds - rhour * 3600) / 60;
7545  rsecond = seconds % 60;
7546  }
7547 
7548  /* depending on the first argument, the result is either result_date or result_time */
7549 
7550  if (domain != NULL)
7551  {
7552  assert (TP_DOMAIN_TYPE (domain) == result_type);
7553  }
7554 
7555  switch (result_type)
7556  {
7557  case DB_TYPE_DATETIME:
7558  if (!left_is_datetime)
7559  {
7560  /* the result type can be DATETIME only if the first argument is a DATE or a DATETIME */
7561  assert (false);
7562  db_make_null (result);
7563  }
7564 
7565  if (DB_VALUE_TYPE (left) == DB_TYPE_TIMESTAMP)
7566  {
7567  DB_DATETIME dt_local;
7568 
7569  error = tz_datetimeltz_to_local (&result_datetime, &dt_local);
7570  if (error != NO_ERROR)
7571  {
7572  goto error_return;
7573  }
7574  result_datetime = dt_local;
7575  }
7576 
7577  db_make_datetime (result, &result_datetime);
7578  break;
7579 
7580  case DB_TYPE_DATETIMELTZ:
7581  {
7582  if (!left_is_datetime)
7583  {
7584  /* the result type can be DATETIME only if the first argument is a DATE or a DATETIME */
7585  assert (false);
7586  db_make_null (result);
7587  }
7588 
7589  db_make_datetimeltz (result, &result_datetime);
7590  break;
7591  }
7592 
7593  case DB_TYPE_DATETIMETZ:
7594  {
7595  DB_DATETIMETZ dt_tz;
7596 
7597  if (!left_is_datetime)
7598  {
7599  /* the result type can be DATETIME only if the first argument is a DATE or a DATETIME */
7600  assert (false);
7601  db_make_null (result);
7602  }
7603 
7604  error = tz_create_datetimetz_from_parts (month, day, year, lhour, lminute, lsecond, lms, &tz_id, &dt_tz);
7605  if (error != NO_ERROR)
7606  {
7607  goto error_return;
7608  }
7609  db_make_datetimetz (result, &dt_tz);
7610  break;
7611  }
7612 
7613  case DB_TYPE_TIME:
7614  if (left_is_datetime)
7615  {
7616  /* the result type can be DATETIME only if the first argument is a TIME */
7617  assert (false);
7618  db_make_null (result);
7619  }
7620  db_make_time (result, rhour, rminute, rsecond);
7621  break;
7622 
7623  case DB_TYPE_VARCHAR:
7624  codeset = TP_DOMAIN_CODESET (domain);
7625  collation_id = TP_DOMAIN_COLLATION (domain);
7626 
7627  if (left_is_datetime)
7628  {
7629  res_s = (char *) db_private_alloc (NULL, QSTR_DATETIME_LENGTH + 1);
7630  if (res_s == NULL)
7631  {
7632  error = ER_DATE_CONVERSION;
7633  goto error_return;
7634  }
7635 
7636  db_datetime_to_string (res_s, QSTR_DATETIME_LENGTH + 1, &result_datetime);
7637  db_make_varchar (result, strlen (res_s), res_s, strlen (res_s), codeset, collation_id);
7638  }
7639  else
7640  {
7641  res_s = (char *) db_private_alloc (NULL, QSTR_TIME_LENGTH + 1);
7642  if (res_s == NULL)
7643  {
7644  error = ER_TIME_CONVERSION;
7645  goto error_return;
7646  }
7647  db_time_encode (&rtime, rhour, rminute, rsecond);
7648  db_time_to_string (res_s, QSTR_TIME_LENGTH + 1, &rtime);
7649  db_make_varchar (result, strlen (res_s), res_s, strlen (res_s), codeset, collation_id);
7650  }
7651  result->need_clear = true;
7652  break;
7653  default:
7654  assert (false);
7655  db_make_null (result);
7656  break;
7657  }
7658 
7659  return NO_ERROR;
7660 
7661 error_return:
7662  if (res_s != NULL)
7663  {
7664  db_private_free (NULL, res_s);
7665  }
7666  db_make_null (result);
7668  {
7669  /* clear error and return NULL */
7670  er_clear ();
7671  return NO_ERROR;
7672  }
7673  return error;
7674 }
7675 
7676 int
7678 {
7679  assert (dbval != NULL && DB_IS_STRING (dbval));
7680  DB_VALUE coerced_str;
7682  {
7683  return NO_ERROR;
7684  }
7685  int error_code = db_string_convert_to (dbval, &coerced_str, INTL_CODESET_UTF8, LANG_COLL_UTF8_BINARY);
7686  if (error_code != NO_ERROR)
7687  {
7688  return error_code;
7689  }
7690 
7691  std::swap (coerced_str, *dbval);
7692  pr_clear_value (&coerced_str);
7693  return NO_ERROR;
7694 }
7695 
7696 int
7697 db_json_copy_and_convert_to_utf8 (const DB_VALUE * src_dbval, DB_VALUE * dest_dbval, const DB_VALUE ** json_str_dbval)
7698 {
7699  assert (src_dbval != NULL && dest_dbval != NULL && json_str_dbval != NULL);
7700  if (db_get_string_codeset (src_dbval) == INTL_CODESET_UTF8)
7701  {
7702  *json_str_dbval = src_dbval;
7703  db_make_null (dest_dbval);
7704  }
7705  else
7706  {
7707  *json_str_dbval = dest_dbval;
7708  int error_code = db_string_convert_to (src_dbval, dest_dbval, INTL_CODESET_UTF8, LANG_COLL_UTF8_BINARY);
7709  if (error_code != NO_ERROR)
7710  {
7711  ASSERT_ERROR ();
7712  return error_code;
7713  }
7714  }
7715 
7716  return NO_ERROR;
7717 }
7718 
7719 int
7720 db_string_convert_to (const DB_VALUE * src_str_dbval, DB_VALUE * dest_str_dbval, INTL_CODESET dest_codeset,
7721  int dest_col)
7722 {
7723  assert (src_str_dbval != NULL && dest_str_dbval != NULL);
7724 
7725  DB_TYPE src_str_type = (DB_TYPE) src_str_dbval->domain.general_info.type;
7726 
7727  int dest_precision = QSTR_VALUE_PRECISION (src_str_dbval);
7728 
7729  db_value_domain_init (dest_str_dbval, src_str_type, dest_precision, 0);
7730  db_string_put_cs_and_collation (dest_str_dbval, dest_codeset, dest_col);
7731 
7732  DB_DATA_STATUS data_status;
7733  int error_code = db_char_string_coerce (src_str_dbval, dest_str_dbval, &data_status);
7734  if (error_code != NO_ERROR)
7735  {
7736  pr_clear_value (dest_str_dbval);
7737  ASSERT_ERROR ();
7738  return error_code;
7739  }
7740  assert (data_status == DATA_STATUS_OK);
7741 
7742  return NO_ERROR;
7743 }
7744 
7745 #if defined(ENABLE_UNUSED_FUNCTION)
7746 /*
7747  * db_string_convert () -
7748  *
7749  * Arguments:
7750  * src_string: (In) Source string
7751  * dest_string: (Out) Converted string
7752  * data_status: (Out) Data status
7753  *
7754  * Returns: int
7755  *
7756  * Errors:
7757  * ER_QSTR_INVALID_DATA_TYPE
7758  * <src_string> and <dest_string> are not both national char strings
7759  * ER_QSTR_INCOMPATIBLE_CODE_SETS
7760  * Conversion not supported between code sets of <src_string>
7761  * and <dest_string>
7762  *
7763  * Note:
7764  * This function converts a national character string from one
7765  * set encoding to another.
7766  *
7767  * A new DB_VALUE is created making use of the code set and
7768  * memory manager stored in <dest_string>, and converting
7769  * the characters in the data portion of <src_string>.
7770  *
7771  * If the source string is fixed-length, the destination will be
7772  * fixed-length with pad characters. If the source string is
7773  * variable-length, the result will also be variable length.
7774  *
7775  * Assert:
7776  *
7777  * 1. src_string != (DB_VALUE *) NULL
7778  * 2. dest_value != (DB_VALUE *) NULL
7779  * 3. data_status != (DB_DATA_STATUS *) NULL
7780  *
7781  */
7782 
7783 int
7784 db_string_convert (const DB_VALUE * src_string, DB_VALUE * dest_string)
7785 {
7786  DB_TYPE src_type, dest_type;
7787  int error_status = NO_ERROR;
7788 
7789  /*
7790  * Assert that DB_VALUE structures have been allocated.
7791  */
7792  assert (src_string != (DB_VALUE *) NULL);
7793  assert (dest_string != (DB_VALUE *) NULL);
7794 
7795  /*
7796  * Categorize the two input parameters and check for errors.
7797  * Verify that the parameters are both character strings.
7798  */
7799  src_type = DB_VALUE_DOMAIN_TYPE (src_string);
7800  dest_type = DB_VALUE_DOMAIN_TYPE (dest_string);
7801 
7802  if (!QSTR_IS_NATIONAL_CHAR (src_type) || !QSTR_IS_NATIONAL_CHAR (dest_type))
7803  {
7804  error_status = ER_QSTR_INVALID_DATA_TYPE;
7805  }
7806 
7807  else if (DB_IS_NULL (src_string))
7808  {
7809  db_value_domain_init (dest_string, DB_VALUE_DOMAIN_TYPE (src_string), 0, 0);
7810  }
7811  else
7812  {
7813  unsigned char *src, *dest;
7814  int src_length = 0, src_precision;
7815  INTL_CODESET src_codeset, dest_codeset;
7816  int convert_status;
7817  int num_unconverted, cnv_size;
7818 
7819 
7820  src = (unsigned char *) db_get_nchar (src_string, &src_length);
7821  src_precision = QSTR_VALUE_PRECISION (src_string);
7822 
7823  src_codeset = db_get_string_codeset (src_string);
7824  dest_codeset = db_get_string_codeset (dest_string);
7825 
7826  /* Fixed-length strings */
7827 
7828  if (QSTR_IS_FIXED_LENGTH (src_type))
7829  {
7830  /* Allocate enough room for a fully padded string */
7831  dest = (unsigned char *) db_private_alloc (NULL, (size_t) (2 * src_precision) + 1);
7832  if (dest == NULL)
7833  {
7834  goto mem_error;
7835  }
7836 
7837  /* Convert the string codeset */
7838  convert_status = intl_convert_charset (src, src_length, src_codeset, dest, dest_codeset, &num_unconverted);
7839 
7840  /* Pad the result */
7841  if (convert_status == NO_ERROR)
7842  {
7843  intl_char_size (dest, (src_length - num_unconverted), dest_codeset, &cnv_size);
7844  qstr_pad_string ((unsigned char *) &dest[cnv_size], (src_precision - src_length + num_unconverted),
7845  dest_codeset);
7846  dest[src_precision] = 0;
7847  db_make_nchar (dest_string, src_precision, (char *) dest, src_precision);
7848  dest_string->need_clear = true;
7849  }
7850  else
7851  {
7853  }
7854  }
7855 
7856  /* Variable-length strings */
7857  else
7858  {
7859  /* Allocate enough room for the string */
7860  dest = (unsigned char *) db_private_alloc (NULL, (size_t) (2 * src_length) + 1);
7861  if (dest == NULL)
7862  {
7863  goto mem_error;
7864  }
7865 
7866  /* Convert the string codeset */
7867  convert_status = intl_convert_charset (src, src_length, src_codeset, dest, dest_codeset, &num_unconverted);
7868 
7869  if (convert_status == NO_ERROR)
7870  {
7871  dest[src_length - num_unconverted] = 0;
7872  db_make_varnchar (dest_string, src_precision, (char *) dest, (src_length - num_unconverted));
7873  dest_string->need_clear = true;
7874  }
7875  else
7876  {
7878  }
7879  }
7880 
7881  /*
7882  * If intl_convert_charset() returned an error, map
7883  * to an ER_QSTR_INCOMPATIBLE_CODE_SETS error.
7884  */
7885  if (convert_status != NO_ERROR)
7886  {
7887  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
7888  }
7889  }
7890 
7891  return error_status;
7892 
7893  /*
7894  * Error handling
7895  */
7896 mem_error:
7897  assert (er_errid () != NO_ERROR);
7898  error_status = er_errid ();
7899  return error_status;
7900 }
7901 #endif
7902 
7903 /*
7904  * qstr_pad_string () -
7905  *
7906  * Arguments:
7907  * s: (IN OUT) Pointer to input string.
7908  * length: (IN) Size of input string.
7909  * codeset: (IN) International codeset of input string.
7910  *
7911  * Returns: unsigned char
7912  *
7913  * Errors:
7914  *
7915  * Note:
7916  * This is a convenience function which will copy pad characters into
7917  * the input string. It is assumed that the pad character will consist
7918  * of one or two bytes (this is currently true).
7919  *
7920  * The address immediately after the padded string is returned. Thus,
7921  * If a NULL terminated string was desired, then a call could be made:
7922  *
7923  * ptr = qstr_pad_string();
7924  * *ptr = '\0';
7925  *
7926  */
7927 
7928 unsigned char *
7929 qstr_pad_string (unsigned char *s, int length, INTL_CODESET codeset)
7930 {
7931  unsigned char pad[2];
7932  int i, j, pad_size = 0;
7933 
7934  if (length == 0)
7935  {
7936  return s;
7937  }
7938 
7939  assert (length > 0);
7940 
7941  intl_pad_char (codeset, pad, &pad_size);
7942 
7943  if (pad_size == 1)
7944  {
7945  (void) memset ((char *) s, (int) pad[0], length);
7946  s = s + length;
7947  }
7948  else
7949  {
7950  for (i = 0; i < length; i++)
7951  {
7952  for (j = 0; j < pad_size; j++)
7953  {
7954  *(s++) = pad[j];
7955  }
7956  }
7957  }
7958 
7959  return s;
7960 }
7961 
7962 /*
7963  * qstr_bin_to_hex () -
7964  *
7965  * arguments:
7966  * dest: Pointer to destination hex buffer area
7967  * dest_size: Size of destination buffer area in bytes
7968  * src: Pointer to source binary buffer area
7969  * src_size: Size of source buffer area in bytes
7970  *
7971  * returns/side-effects: int
7972  * The number of converted source bytes is returned. This value will
7973  * equal src_size if (dest_size >= 2*src_size) and less otherwise.
7974  *
7975  * description:
7976  * Convert the binary data in the source buffer to ASCII hex characters
7977  * in the destination buffer. The destination buffer should be at
7978  * least 2 * src_size. If not, as much of the source string is processed
7979  * as possible. The number of ASCII Hex characters in dest will
7980  * equal two times the returned value.
7981  *
7982  */
7983 
7984 int
7985 qstr_bin_to_hex (char *dest, int dest_size, const char *src, int src_size)
7986 {
7987  int i, copy_size;
7988 
7989  if (dest_size >= (2 * src_size))
7990  {
7991  copy_size = src_size;
7992  }
7993  else
7994  {
7995  copy_size = dest_size / 2;
7996  }
7997 
7998  for (i = 0; i < copy_size; i++)
7999  {
8000  sprintf (&(dest[2 * i]), "%02x", (unsigned char) (src[i]));
8001  }
8002 
8003  return copy_size;
8004 }
8005 
8006 /*
8007  * qstr_hex_to_bin () -
8008  *
8009  * arguments:
8010  * dest: Pointer to destination hex buffer area
8011  * dest_size: Size of destination buffer area in bytes
8012  * src: Pointer to source binary buffer area
8013  * src_size: Size of source buffer area in bytes
8014  *
8015  * returns/side-effects: int
8016  * The number of converted hex characters is returned.
8017  *
8018  * description:
8019  * Convert the string of hex characters to decimal values. For each two
8020  * characters, one unsigned character value is produced. If the number
8021  * of characters is odd, then the second nibble of the last byte will
8022  * be 0 padded. If the destination buffer is not large enough to hold
8023  * the converted data, as much data is converted as possible.
8024  *
8025  */
8026 
8027 int
8028 qstr_hex_to_bin (char *dest, int dest_size, const char *src, int src_size)
8029 {
8030  int i, copy_size, src_index, required_size;
8031 
8032  required_size = (src_size + 1) / 2;
8033 
8034  if (dest_size >= required_size)
8035  {
8036  copy_size = required_size;
8037  }
8038  else
8039  {
8040  copy_size = dest_size;
8041  }
8042 
8043  src_index = 0;
8044  for (i = 0; i < copy_size; i++)
8045  {
8046  int hex_digit;
8047 
8048  hex_digit = hextoi (src[src_index++]);
8049  if (hex_digit < 0)
8050  {
8051  return -1;
8052  }
8053  else
8054  {
8055  dest[i] = hex_digit << 4;
8056  if (src_index < src_size)
8057  {
8058  hex_digit = hextoi (src[src_index++]);
8059  if (hex_digit < 0)
8060  {
8061  return -1;
8062  }
8063  else
8064  {
8065  dest[i] += hex_digit;
8066  }
8067  }
8068  }
8069  }
8070 
8071  return src_index;
8072 }
8073 
8074 /*
8075  * qstr_bit_to_bin () -
8076  *
8077  * arguments:
8078  * dest: Pointer to destination buffer area
8079  * dest_size: Size of destination buffer area in bytes
8080  * src: Pointer to source binary buffer area
8081  * src_size: Size of source buffer area in bytes
8082  *
8083  * returns/side-effects: int
8084  * The number of converted binary characters is returned.
8085  *
8086  * description:
8087  * Convert the string of '0's and '1's to decimal values. For each 8
8088  * characters, one unsigned character value is produced. If the number
8089  * of characters is not a multiple of 8, the result will assume trailing
8090  * 0 padding. If the destination buffer is not large enough to hold
8091  * the converted data, as much data is converted as possible.
8092  *
8093  */
8094 
8095 int
8096 qstr_bit_to_bin (char *dest, int dest_size, const char *src, int src_size)
8097 {
8098  int dest_byte, copy_size, src_index, required_size;
8099 
8100  required_size = (src_size + 7) / 8;
8101 
8102  if (dest_size >= required_size)
8103  {
8104  copy_size = required_size;
8105  }
8106  else
8107  {
8108  copy_size = dest_size;
8109  }
8110 
8111  src_index = 0;
8112  for (dest_byte = 0; dest_byte < copy_size; dest_byte++)
8113  {
8114  int bit_count;
8115 
8116  dest[dest_byte] = 0;
8117  for (bit_count = 0; bit_count < 8; bit_count++)
8118  {
8119  dest[dest_byte] = dest[dest_byte] << 1;
8120  if (src_index < src_size)
8121  {
8122  if (src[src_index] == '1')
8123  {
8124  dest[dest_byte]++;
8125  }
8126  else if (src[src_index] != '0')
8127  {
8128  return -1; /* Illegal digit */
8129  }
8130  src_index++;
8131  }
8132  }
8133  }
8134 
8135  return src_index;
8136 }
8137 
8138 /*
8139  * qstr_bit_to_hex_coerce () -
8140  *
8141  * arguments:
8142  * buffer: Pointer to destination buffer area
8143  * buffer_size: Size of destination buffer area (in bytes, *including* null
8144  * terminator)
8145  * src: Pointer to source buffer area
8146  * src_length: Length of source buffer area in bits
8147  * pad_flag: TRUE if the buffer should be padded and FALSE otherwise
8148  * copy_size: Number of bytes transfered from the src string to the dst
8149  * buffer
8150  * truncation: pointer to a int field. *outlen will equal 0 if no
8151  * truncation occurred and will equal the size of the dst buffer
8152  * in bytes needed to avoid truncation (not including the
8153  * terminating NULL), otherwise.
8154  *
8155  * returns/side-effects: void
8156  *
8157  * description:
8158  * Transfers at most buffer_size bytes to the region pointed at by dst.
8159  * If pad_flag is TRUE, strings shorter than buffer_size will be
8160  * blank-padded out to buffer_size-1 bytes. All strings will be
8161  * null-terminated. If truncation is necessary (i.e., if buffer_size is
8162  * less than or equal to src_length), *truncation is set to src_length;
8163  * if truncation is is not necessary, *truncation is set to 0.
8164  *
8165  */
8166 
8167 void
8168 qstr_bit_to_hex_coerce (char *buffer, int buffer_size, const char *src, int src_length, int pad_flag, int *copy_size,
8169  int *truncation)
8170 {
8171  int src_size = QSTR_NUM_BYTES (src_length);
8172 
8173  if (src == NULL)
8174  {
8175  buffer[0] = '\0';
8176  return;
8177  }
8178 
8179  if (buffer_size > (2 * src_size))
8180  {
8181  /*
8182  * No truncation; copy the data and blank pad if necessary.
8183  */
8184  qstr_bin_to_hex (buffer, buffer_size, src, src_size);
8185 /*
8186  for (i=0; i<src_size; i++)
8187  sprintf(&(buffer[2*i]), "%02x", (unsigned char)(src[i]));
8188 */
8189  if (pad_flag != 0)
8190  {
8191  memset (&(buffer[2 * src_size]), '0', (buffer_size - (2 * src_size)));
8192  *copy_size = buffer_size - 1;
8193  }
8194  else
8195  {
8196  *copy_size = 2 * src_size;
8197  }
8198  buffer[*copy_size] = '\0';
8199  *truncation = 0;
8200  }
8201  else
8202  {
8203  /*
8204  * Truncation is necessary; put as many bytes as possible into
8205  * the receiving buffer and null-terminate it (i.e., it receives
8206  * at most dstsize-1 bytes). If there is not outlen indicator by
8207  * which we can indicate truncation, this is an error.
8208  *
8209  */
8210  if (buffer_size % 2)
8211  {
8212  src_size = buffer_size / 2;
8213  }
8214  else
8215  {
8216  src_size = (buffer_size - 1) / 2;
8217  }
8218 
8219  qstr_bin_to_hex (buffer, buffer_size, src, src_size);
8220 /*
8221  for (i=0; i<src_size; i++)
8222  sprintf(&(buffer[2*i]), "%02x", (unsigned char)(src[i]));
8223 */
8224  *copy_size = 2 * src_size;
8225  buffer[*copy_size] = '\0';
8226 
8227  *truncation = src_size;
8228  }
8229 }
8230 
8231 /*
8232  * db_get_string_length
8233  *
8234  * Arguments:
8235  * value: Value container
8236  *
8237  * Returns: int
8238  *
8239  * Errors:
8240  *
8241  * Note:
8242  * Returns the character length of the string in the container.
8243  *
8244  */
8245 
8246 int
8248 {
8249  DB_CONST_C_CHAR str;
8250  int size;
8251  INTL_CODESET codeset;
8252  int length = 0;
8253 
8254 #if 0
8255  /* Currently, only the medium model is used */
8256 
8257  switch (value->data.ch.info.style)
8258  {
8259  case SMALL_STRING:
8260  str = value->data.ch.small.buf;
8261  length = size = value->data.ch.small.size;
8262  codeset = value->data.ch.small.codeset;
8263  break;
8264 
8265  case MEDIUM_STRING:
8266  str = value->data.ch.medium.buf;
8267  length = size = value->data.ch.medium.size;
8268  codeset = value->data.ch.medium.codeset;
8269  break;
8270 
8271  case LARGE_STRING:
8272  str = NULL;
8273  size = 0;
8274  break;
8275 
8276  default:
8277  break;
8278  }
8279 #endif
8280 
8281  str = value->data.ch.medium.buf;
8282  length = size = value->data.ch.medium.size;
8283  codeset = (INTL_CODESET) value->data.ch.medium.codeset;
8284 
8286  {
8287  intl_char_count ((unsigned char *) str, size, codeset, &length);
8288  }
8289 
8290  return length;
8291 }
8292 
8293 /*
8294  * qstr_make_typed_string () -
8295  *
8296  * Arguments:
8297  * db_type: value type for the result.
8298  * value: Value container for the result.
8299  * precision: Length of the string precision.
8300  * src: Pointer to string.
8301  * s_unit: Size of the string.
8302  * codeset: codeset
8303  * collation_id: collation
8304  *
8305  * Returns: void
8306  *
8307  * Errors:
8308  *
8309  * Note:
8310  * Make a value container from the string of the given domain.
8311  * This is a convenience function which allows for all string
8312  * types given the proper domain type.
8313  *
8314  */
8315 
8316 void
8317 qstr_make_typed_string (const DB_TYPE db_type, DB_VALUE * value, const int precision, DB_CONST_C_CHAR src,
8318  const int s_unit, const int codeset, const int collation_id)
8319 {
8320  int error = NO_ERROR;
8321  switch (db_type)
8322  {
8323  case DB_TYPE_CHAR:
8324  error = db_make_char (value, precision, src, s_unit, codeset, collation_id);
8325  break;
8326 
8327  case DB_TYPE_VARCHAR:
8328  error = db_make_varchar (value, precision, src, s_unit, codeset, collation_id);
8329  break;
8330 
8331  case DB_TYPE_NCHAR:
8332  error = db_make_nchar (value, precision, src, s_unit, codeset, collation_id);
8333  break;
8334 
8335  case DB_TYPE_VARNCHAR:
8336  error = db_make_varnchar (value, precision, src, s_unit, codeset, collation_id);
8337  break;
8338 
8339  case DB_TYPE_BIT:
8340  error = db_make_bit (value, precision, src, s_unit);
8341  break;
8342 
8343  case DB_TYPE_VARBIT:
8344  error = db_make_varbit (value, precision, src, s_unit);
8345  break;
8346 
8347  default:
8348  assert (false);
8349  db_make_null (value);
8350  break;
8351  }
8352  assert (error == NO_ERROR);
8353 }
8354 
8355 /*
8356  * Private Functions
8357  */
8358 
8359 /*
8360  * qstr_get_category
8361  *
8362  * Arguments:
8363  * s: DB_VALUE representation of a string.
8364  *
8365  * Returns: QSTR_CATEGORY
8366  *
8367  * Errors:
8368  *
8369  * Note:
8370  * Returns the character code set of the string "s." The character code
8371  * set of strings is:
8372  *
8373  * QSTR_CHAR, QSTR_NATIONAL_CHAR, QSTR_BIT
8374  *
8375  * as defined in type QSTR_CATEGORY. A value of QSTR_UNKNOWN is defined
8376  * if the string does not fit into one of these categories. This should
8377  * never happen if is_string() returns TRUE.
8378  *
8379  */
8380 
8381 static QSTR_CATEGORY
8383 {
8384  QSTR_CATEGORY code_set;
8385 
8386  switch (DB_VALUE_DOMAIN_TYPE (s))
8387  {
8388 
8389  case DB_TYPE_VARCHAR:
8390  case DB_TYPE_CHAR:
8391  code_set = QSTR_CHAR;
8392  break;
8393 
8394  case DB_TYPE_NCHAR:
8395  case DB_TYPE_VARNCHAR:
8396  code_set = QSTR_NATIONAL_CHAR;
8397  break;
8398 
8399  case DB_TYPE_BIT:
8400  case DB_TYPE_VARBIT:
8401  code_set = QSTR_BIT;
8402  break;
8403 
8404  default:
8405  code_set = QSTR_UNKNOWN;
8406  break;
8407  }
8408 
8409  return code_set;
8410 }
8411 
8412 #if defined (ENABLE_UNUSED_FUNCTION)
8413 /*
8414  * is_string () -
8415  *
8416  * Arguments:
8417  * s: (IN) DB_VALUE variable.
8418  *
8419  * Returns: bool
8420  *
8421  * Errors:
8422  *
8423  * Note:
8424  * Verifies that the value is a string. Returns TRUE if the
8425  * domain type is one of:
8426  *
8427  * DB_TYPE_STRING
8428  * DB_TYPE_CHAR
8429  * DB_TYPE_VARCHAR
8430  * DB_TYPE_NCHAR
8431  * DB_TYPE_VARNCHAR
8432  * DB_TYPE_BIT
8433  * DB_TYPE_VARBIT
8434  *
8435  * Returns FALSE otherwise.
8436  *
8437  * This function supports the older type DB_TYPE_STRING which
8438  * has been replaced by DB_TYPE_VARCHAR.
8439  *
8440  */
8441 
8442 static bool
8443 is_string (const DB_VALUE * s)
8444 {
8445  DB_TYPE domain_type = DB_VALUE_DOMAIN_TYPE (s);
8446 
8447  return QSTR_IS_ANY_CHAR_OR_BIT (domain_type);
8448 }
8449 #endif /* ENABLE_UNUSED_FUNCTION */
8450 
8451 /*
8452  * is_char_string () -
8453  *
8454  * Arguments:
8455  * s: DB_VALUE variable.
8456  *
8457  * Returns: bool
8458  *
8459  * Errors:
8460  *
8461  * Note:
8462  * Verifies that the value is a character string. Returns TRUE if the
8463  * value is of domain type is one of:
8464  *
8465  * DB_TYPE_STRING
8466  * DB_TYPE_VARCHAR
8467  * DB_TYPE_CHAR
8468  * DB_TYPE_NCHAR
8469  * DB_TYPE_VARNCHAR
8470  *
8471  * Returns FALSE otherwise.
8472  *
8473  * This function supports the older type DB_TYPE_STRING which
8474  * has been replaced by DB_TYPE_VARCHAR.
8475  *
8476  */
8477 
8478 static bool
8480 {
8481  DB_TYPE domain_type = DB_VALUE_DOMAIN_TYPE (s);
8482 
8483  return (QSTR_IS_ANY_CHAR (domain_type));
8484 }
8485 
8486 /*
8487  * is_integer () -
8488  *
8489  * Arguments:
8490  * i: (IN) DB_VALUE variable.
8491  *
8492  * Returns: bool
8493  *
8494  * Errors:
8495  *
8496  * Note:
8497  * Verifies that the value is an integer. Returns TRUE if the
8498  * value is of domain type is one of:
8499  *
8500  * DB_TYPE_INTEGER
8501  *
8502  * Returns FALSE otherwise.
8503  *
8504  */
8505 
8506 static bool
8508 {
8509  return (DB_VALUE_DOMAIN_TYPE (i) == DB_TYPE_INTEGER);
8510 }
8511 
8512 /*
8513  * is_number () -
8514  *
8515  * Arguments:
8516  * n: (IN) DB_VALUE variable.
8517  *
8518  * Returns: bool
8519  *
8520  * Errors:
8521  *
8522  * Note:
8523  * Verifies that the value is an number. Returns TRUE if the
8524  * value is of domain type is one of:
8525  *
8526  * DB_TYPE_NUMERIC
8527  * DB_TYPE_INTEGER
8528  * DB_TYPE_SMALLINT
8529  * DB_TYPE_DOUBLE
8530  * DB_TYPE_FLOAT
8531  *
8532  * Returns FALSE otherwise.
8533  *
8534  */
8535 
8536 static bool
8537 is_number (const DB_VALUE * n)
8538 {
8539  DB_TYPE domain_type = DB_VALUE_DOMAIN_TYPE (n);
8540 
8541  return ((domain_type == DB_TYPE_NUMERIC) || (domain_type == DB_TYPE_INTEGER) || (domain_type == DB_TYPE_SMALLINT)
8542  || (domain_type == DB_TYPE_BIGINT) || (domain_type == DB_TYPE_DOUBLE) || (domain_type == DB_TYPE_FLOAT)
8543  || (domain_type == DB_TYPE_MONETARY));
8544 }
8545 
8546 /*
8547 * is_str_find_all () -
8548 *
8549 * Arguments:
8550 * val: (IN) DB_VALUE variable. Assumed string
8551 * find_all: (OUT) whether all/one
8552 *
8553 * Returns: error
8554 *
8555 * Errors:
8556 * ER_QSTR_INVALID_DATA_TYPE
8557 *
8558 * Note:
8559 * find_all becomes TRUE if val's lower-cased string is 'all', FALSE if it is 'one'
8560 *
8561 * Returns ER_QSTR_INVALID_DATA_TYPE otherwise.
8562 *
8563 */
8564 
8565 
8566 
8567 #if defined (ENABLE_UNUSED_FUNCTION)
8568 /*
8569  * qstr_compare () - compare two character strings of DB_TYPE_STRING(tp_String)
8570  *
8571  * Arguments:
8572  * string1: 1st character string
8573  * size1: size of 1st string
8574  * string2: 2nd character string
8575  * size2: size of 2nd string
8576  *
8577  * Returns:
8578  * Greater than 0 if string1 > string2
8579  * Equal to 0 if string1 = string2
8580  * Less than 0 if string1 < string2
8581  *
8582  * Errors:
8583  *
8584  * Note:
8585  * This function is similar to strcmp(3) or bcmp(3). It is designed to
8586  * follow SQL_TEXT character set collation. Padding character(space ' ') is
8587  * the smallest character in the set. (e.g.) "ab z" < "ab\t1"
8588  *
8589  */
8590 
8591 int
8592 qstr_compare (const unsigned char *string1, int size1, const unsigned char *string2, int size2)
8593 {
8594  int n, i, cmp;
8595  unsigned char c1, c2;
8596 
8597 #define PAD ' ' /* str_pad_char(INTL_CODESET_ISO88591, pad, &pad_size) */
8598 #define SPACE PAD /* smallest character in the collation sequence */
8599 #define ZERO '\0' /* space is treated as zero */
8600 
8601  n = size1 < size2 ? size1 : size2;
8602  for (i = 0, cmp = 0; i < n && cmp == 0; i++)
8603  {
8604  c1 = *string1++;
8605  if (c1 == SPACE)
8606  {
8607  c1 = ZERO;
8608  }
8609  c2 = *string2++;
8610  if (c2 == SPACE)
8611  {
8612  c2 = ZERO;
8613  }
8614  cmp = c1 - c2;
8615  }
8616  if (cmp != 0)
8617  {
8618  return cmp;
8619  }
8620  if (size1 == size2)
8621  {
8622  return cmp;
8623  }
8624 
8625  c1 = c2 = ZERO;
8626  if (size1 < size2)
8627  {
8628  n = size2 - size1;
8629  for (i = 0; i < n && cmp == 0; i++)
8630  {
8631  c2 = *string2++;
8632  if (c2 == PAD)
8633  {
8634  c2 = ZERO;
8635  }
8636  cmp = c1 - c2;
8637  }
8638  }
8639  else
8640  {
8641  n = size1 - size2;
8642  for (i = 0; i < n && cmp == 0; i++)
8643  {
8644  c1 = *string1++;
8645  if (c1 == PAD)
8646  {
8647  c1 = ZERO;
8648  }
8649  cmp = c1 - c2;
8650  }
8651  }
8652  return cmp;
8653 
8654 #undef PAD
8655 #undef SPACE
8656 #undef ZERO
8657 } /* qstr_compare() */
8658 
8659 /*
8660  * char_compare () - compare two character strings of DB_TYPE_CHAR(tp_Char)
8661  *
8662  * Arguments:
8663  * string1: 1st character string
8664  * size1: size of 1st string
8665  * string2: 2nd character string
8666  * size2: size of 2nd string
8667  *
8668  * Returns:
8669  * Greater than 0 if string1 > string2
8670  * Equal to 0 if string1 = string2
8671  * Less than 0 if string1 < string2
8672  *
8673  * Errors:
8674  *
8675  * Note:
8676  * This function is identical to qstr_compare().
8677  *
8678  */
8679 
8680 int
8681 char_compare (const unsigned char *string1, int size1, const unsigned char *string2, int size2)
8682 {
8683  int n, i, cmp;
8684  unsigned char c1, c2;
8685 
8686  assert (size1 >= 0 && size2 >= 0);
8687 
8688 #define PAD ' ' /* str_pad_char(INTL_CODESET_ISO88591, pad, &pad_size) */
8689 #define SPACE PAD /* smallest character in the collation sequence */
8690 #define ZERO '\0' /* space is treated as zero */
8691 
8692  n = size1 < size2 ? size1 : size2;
8693  for (i = 0, cmp = 0; i < n && cmp == 0; i++)
8694  {
8695  c1 = *string1++;
8696  if (c1 == SPACE)
8697  {
8698  c1 = ZERO;
8699  }
8700  c2 = *string2++;
8701  if (c2 == SPACE)
8702  {
8703  c2 = ZERO;
8704  }
8705  cmp = c1 - c2;
8706  }
8707  if (cmp != 0)
8708  {
8709  return cmp;
8710  }
8711  if (size1 == size2)
8712  {
8713  return cmp;
8714  }
8715 
8716  c1 = c2 = ZERO;
8717  if (size1 < size2)
8718  {
8719  n = size2 - size1;
8720  for (i = 0; i < n && cmp == 0; i++)
8721  {
8722  c2 = *string2++;
8723  if (c2 == PAD)
8724  {
8725  c2 = ZERO;
8726  }
8727  cmp = c1 - c2;
8728  }
8729  }
8730  else
8731  {
8732  n = size1 - size2;
8733  for (i = 0; i < n && cmp == 0; i++)
8734  {
8735  c1 = *string1++;
8736  if (c1 == PAD)
8737  {
8738  c1 = ZERO;
8739  }
8740  cmp = c1 - c2;
8741  }
8742  }
8743  return cmp;
8744 
8745 #undef PAD
8746 #undef SPACE
8747 #undef ZERO
8748 } /* char_compare() */
8749 
8750 /*
8751  * varnchar_compare () - compare two national character strings of
8752  * DB_TYPE_VARNCHAR(tp_VarNChar)
8753  *
8754  * Arguments:
8755  * string1: 1st national character string
8756  * size1: size of 1st string
8757  * string2: 2nd national character string
8758  * size2: size of 2nd string
8759  * codeset: codeset of strings
8760  *
8761  * Returns:
8762  * Greater than 0 if string1 > string2
8763  * Equal to 0 if string1 = string2
8764  * Less than 0 if string1 < string2
8765  *
8766  * Errors:
8767  *
8768  * Note:
8769  * This function is identical to qstr_compare() except that it awares
8770  * of the codeset.
8771  *
8772  */
8773 
8774 int
8775 varnchar_compare (const unsigned char *string1, int size1, const unsigned char *string2, int size2,
8776  INTL_CODESET codeset)
8777 {
8778  int n, i, cmp, pad_size = 0;
8779  unsigned char c1, c2, pad[2];
8780 
8781  intl_pad_char (codeset, pad, &pad_size);
8782 #define PAD pad[i % pad_size]
8783 #define SPACE PAD /* smallest character in the collation sequence */
8784 #define ZERO '\0' /* space is treated as zero */
8785  n = size1 < size2 ? size1 : size2;
8786  for (i = 0, cmp = 0; i < n && cmp == 0; i++)
8787  {
8788  c1 = *string1++;
8789  if (c1 == SPACE)
8790  {
8791  c1 = ZERO;
8792  }
8793  c2 = *string2++;
8794  if (c2 == SPACE)
8795  {
8796  c2 = ZERO;
8797  }
8798  cmp = c1 - c2;
8799  }
8800  if (cmp != 0)
8801  {
8802  return cmp;
8803  }
8804  if (size1 == size2)
8805  {
8806  return cmp;
8807  }
8808 
8809  c1 = c2 = ZERO;
8810  if (size1 < size2)
8811  {
8812  n = size2 - size1;
8813  for (i = 0; i < n && cmp == 0; i++)
8814  {
8815  c2 = *string2++;
8816  if (c2 == PAD)
8817  {
8818  c2 = ZERO;
8819  }
8820  cmp = c1 - c2;
8821  }
8822  }
8823  else
8824  {
8825  n = size1 - size2;
8826  for (i = 0; i < n && cmp == 0; i++)
8827  {
8828  c1 = *string1++;
8829  if (c1 == PAD)
8830  {
8831  c1 = ZERO;
8832  }
8833  cmp = c1 - c2;
8834  }
8835  }
8836  return cmp;
8837 #undef SPACE
8838 #undef ZERO
8839 #undef PAD
8840 } /* varnchar_compare() */
8841 
8842 /*
8843  * nchar_compare () - compare two national character strings of
8844  * DB_TYPE_NCHAR(tp_NChar)
8845  *
8846  * Arguments:
8847  * string1: 1st national character string
8848  * size1: size of 1st string
8849  * string2: 2nd national character string
8850  * size2: size of 2nd string
8851  * codeset: codeset of strings
8852  *
8853  * Returns:
8854  * Greater than 0 if string1 > string2
8855  * Equal to 0 if string1 = string2
8856  * Less than 0 if string1 < string2
8857  *
8858  * Errors:
8859  *
8860  * Note:
8861  * This function is identical to qstr_compare() except that it awares
8862  * of the codeset.
8863  *
8864  */
8865 
8866 int
8867 nchar_compare (const unsigned char *string1, int size1, const unsigned char *string2, int size2, INTL_CODESET codeset)
8868 {
8869  int n, i, cmp, pad_size = 0;
8870  unsigned char c1, c2, pad[2];
8871 
8872  assert (size1 >= 0 && size2 >= 0);
8873 
8874  intl_pad_char (codeset, pad, &pad_size);
8875 #define PAD pad[i % pad_size]
8876 #define SPACE PAD /* smallest character in the collation sequence */
8877 #define ZERO '\0' /* space is treated as zero */
8878  n = size1 < size2 ? size1 : size2;
8879  for (i = 0, cmp = 0; i < n && cmp == 0; i++)
8880  {
8881  c1 = *string1++;
8882  if (c1 == SPACE)
8883  {
8884  c1 = ZERO;
8885  }
8886  c2 = *string2++;
8887  if (c2 == SPACE)
8888  {
8889  c2 = ZERO;
8890  }
8891  cmp = c1 - c2;
8892  }
8893  if (cmp != 0)
8894  {
8895  return cmp;
8896  }
8897  if (size1 == size2)
8898  {
8899  return cmp;
8900  }
8901 
8902  c1 = c2 = ZERO;
8903  if (size1 < size2)
8904  {
8905  n = size2 - size1;
8906  for (i = 0; i < n && cmp == 0; i++)
8907  {
8908  c2 = *string2++;
8909  if (c2 == PAD)
8910  {
8911  c2 = ZERO;
8912  }
8913  cmp = c1 - c2;
8914  }
8915  }
8916  else
8917  {
8918  n = size1 - size2;
8919  for (i = 0; i < n && cmp == 0; i++)
8920  {
8921  c1 = *string1++;
8922  if (c1 == PAD)
8923  {
8924  c1 = ZERO;
8925  }
8926  cmp = c1 - c2;
8927  }
8928  }
8929  return cmp;
8930 #undef SPACE
8931 #undef ZERO
8932 #undef PAD
8933 } /* nchar_compare() */
8934 #endif /* ENABLE_UNUSED_FUNCTION */
8935 /*
8936  * bit_compare () - compare two bit strings of DB_TYPE_BIT(tp_Bit)
8937  *
8938  * Arguments:
8939  * string1: 1st bit string
8940  * size1: size of 1st string
8941  * string2: 2nd bit string
8942  * size2: size of 2nd string
8943  * codeset: codeset of strings
8944  *
8945  * Returns:
8946  * Greater than 0 if string1 > string2
8947  * Equal to 0 if string1 = string2
8948  * Less than 0 if string1 < string2
8949  *
8950  * Errors:
8951  *
8952  * Note:
8953  * This function is identical to qstr_compare().
8954  *
8955  */
8956 
8957 int
8958 bit_compare (const unsigned char *string1, int size1, const unsigned char *string2, int size2)
8959 {
8960  int n, i, cmp;
8961 
8962  assert (size1 >= 0 && size2 >= 0);
8963 
8964 #define PAD '\0' /* str_pad_char(INTL_CODESET_RAW_BITS, pad, &pad_size) */
8965  n = size1 < size2 ? size1 : size2;
8966  for (i = 0, cmp = 0; i < n && cmp == 0; i++)
8967  {
8968  cmp = (*string1++ - *string2++);
8969  }
8970  if (cmp != 0)
8971  {
8972  return cmp;
8973  }
8974  cmp = size1 - size2;
8975  return cmp;
8976 #undef PAD
8977 } /* bit_compare() */
8978 
8979 /*
8980  * varbit_compare () - compare two bit strings of DB_TYPE_VARBIT(tp_VarBit)
8981  *
8982  * Arguments:
8983  * string1: 1st bit string
8984  * size1: size of 1st string
8985  * string2: 2nd bit string
8986  * size2: size of 2nd string
8987  * codeset: codeset of strings
8988  *
8989  * Returns:
8990  * Greater than 0 if string1 > string2
8991  * Equal to 0 if string1 = string2
8992  * Less than 0 if string1 < string2
8993  *
8994  * Errors:
8995  *
8996  * Note:
8997  * This function is identical to qstr_compare().
8998  *
8999  */
9000 
9001 int
9002 varbit_compare (const unsigned char *string1, int size1, const unsigned char *string2, int size2)
9003 {
9004  int n, i, cmp;
9005 
9006 #define PAD '\0' /* str_pad_char(INTL_CODESET_RAW_BITS, pad, &pad_size) */
9007  n = size1 < size2 ? size1 : size2;
9008  for (i = 0, cmp = 0; i < n && cmp == 0; i++)
9009  {
9010  cmp = (*string1++ - *string2++);
9011  }
9012  if (cmp != 0)
9013  {
9014  return cmp;
9015  }
9016  cmp = size1 - size2;
9017  return cmp;
9018 #undef PAD
9019 } /* varbit_compare() */
9020 
9021 
9022 /*
9023  * qstr_grow_string () - grows the memory buffer of string value
9024  *
9025  * Arguments:
9026  * src: (IN) String variable.
9027  * result: (IN/OUT) value with new size, or DB_NULL if requested size
9028  * exceeds PRM_STRING_MAX_SIZE_BYTES system parameter
9029  * new_size: (IN) New size to be reserved for the string (in bytes).
9030  *
9031  * Returns:
9032  *
9033  * Errors:
9034  * ER_QSTR_INVALID_DATA_TYPE:
9035  * <src_string> is not CHAR, NCHAR, VARCHAR or VARNCHAR
9036  *
9037  * Note : src buffer is not freed, caller should be aware of this;
9038  * Result DB_VALUE must already be created.
9039  * It doesn't operate on BIT strings;
9040  * if requested size is larger than PRM_STRING_MAX_SIZE_BYTES,
9041  * DB_VALUE_NULL is returned
9042  */
9043 
9044 static int
9045 qstr_grow_string (DB_VALUE * src_string, DB_VALUE * result, int new_size)
9046 {
9047  int result_size = 0, src_length = 0, result_domain_length = 0, src_size = 0;
9048  char *r = NULL;
9049  int error_status = NO_ERROR;
9050  DB_TYPE src_type, result_type;
9051  INTL_CODESET codeset;
9052 
9053  assert (src_string != (DB_VALUE *) NULL);
9054  assert (result != (DB_VALUE *) NULL);
9055 
9056  src_type = DB_VALUE_DOMAIN_TYPE (src_string);
9057  src_length = (int) db_get_string_length (src_string);
9058  result_domain_length = DB_VALUE_PRECISION (src_string);
9059 
9060  if (!QSTR_IS_ANY_CHAR (src_type) || DB_IS_NULL (src_string))
9061  {
9063  }
9064  if (QSTR_IS_NATIONAL_CHAR (src_type))
9065  {
9066  result_type = DB_TYPE_NCHAR;
9067  }
9068  else
9069  {
9070  result_type = DB_TYPE_CHAR;
9071  }
9072 
9073  codeset = db_get_string_codeset (src_string);
9074 
9075  result_size = src_length * INTL_CODESET_MULT (codeset);
9076 
9077  src_size = db_get_string_size (src_string);
9078 
9079  assert (new_size >= result_size);
9080  assert (new_size >= src_size);
9081 
9082  result_size = MAX (result_size, new_size);
9083  result_size = MAX (result_size, src_size);
9084 
9085  if (result_size > (int) prm_get_bigint_value (PRM_ID_STRING_MAX_SIZE_BYTES))
9086  {
9089 
9090  db_make_null (result);
9091  return NO_ERROR;
9092  }
9093  /* Allocate storage for the result string */
9094  r = (char *) db_private_alloc (NULL, (size_t) result_size + 1);
9095  if (r == NULL)
9096  {
9097  assert (er_errid () != NO_ERROR);
9098  return er_errid ();
9099  }
9100  memset (r, 0, (size_t) result_size + 1);
9101 
9102  if (src_size > 0)
9103  {
9104  memcpy (r, db_get_string (src_string), src_size);
9105  }
9106  qstr_make_typed_string (result_type, result, result_domain_length, r, (int) MIN (result_size, src_size),
9107  codeset, db_get_string_collation (src_string));
9108 
9111  {
9112  /* intermediate value : clear is_null flag */
9113  result->domain.general_info.is_null = 0;
9114  }
9115  result->need_clear = true;
9116  return error_status;
9117 }
9118 
9119 #if defined (ENABLE_UNUSED_FUNCTION)
9120 /*
9121  * qstr_append () - appends a string to another string. Doesn't operate on BIT
9122  *
9123  * Arguments:
9124  * s1: (IN/OUT) First string pointer.
9125  * s1_length: (IN) Character length of <s1>.
9126  * s1_precision: (IN) Max character length of <s1>.
9127  * s1_type: (IN) Domain type of <s1>.
9128  * s2: (IN) Second string pointer.
9129  * s2_length: (IN) Character length of <s2>.
9130  * s2_precision: (IN) Max character length of <s2>.
9131  * s2_type: (IN) Domain type of <s2>.
9132  * codeset: (IN) international codeset.
9133  * result_length: (OUT) Character length of <result>.
9134  * result_size: (OUT) Byte size of <result>.
9135  * data_status: (OUT) status of truncation
9136  *
9137  * Returns:
9138  * ER_QSTR_INVALID_DATA_TYPE:
9139  * <s1> and <s2> are not CHAR, NCHAR, VARCHAR or VARNCHAR
9140  *
9141  * Errors:
9142  *
9143  */
9144 
9145 static int
9146 qstr_append (unsigned char *s1, int s1_length, int s1_precision, DB_TYPE s1_type, const unsigned char *s2,
9147  int s2_length, int s2_precision, DB_TYPE s2_type, INTL_CODESET codeset, int *result_length,
9148  int *result_size, DB_DATA_STATUS * data_status)
9149 {
9150  int copy_length, copy_size;
9151  int pad1_length, pad2_length;
9152  int length_left, cat_length, cat_size;
9153  int s1_logical_length, s2_logical_length;
9154  unsigned char *cat_ptr;
9155  int error_status = NO_ERROR;
9156 
9157  *data_status = DATA_STATUS_OK;
9158 
9159  /* Note : append logic is similar to concatenate, except the s1 string is already copied into the result. However,
9160  * the concatenate logic is preserved in order to have the same type limits checking and padding. */
9161  /* functions qstr_append & qstr_concatenate are kept separately because of different signatures and different
9162  * purpose. However, a refactoring may be necessary for the shared code */
9163  if (!QSTR_IS_ANY_CHAR (s1_type) || !QSTR_IS_ANY_CHAR (s2_type))
9164  {
9166  }
9167  /*
9168  * Categorize the source string into fixed and variable
9169  * length. Variable length strings are simple. Fixed
9170  * length strings have to be handled special since the
9171  * strings may not have all of their pad character allocated
9172  * yet. We have to account for this and act as if all of the
9173  * characters are present. They all will be by the time
9174  * we are through.
9175  */
9176 
9177  if (QSTR_IS_FIXED_LENGTH (s1_type))
9178  {
9179  s1_logical_length = s1_precision;
9180  }
9181  else
9182  {
9183  s1_logical_length = s1_length;
9184  }
9185 
9186 
9187  if (QSTR_IS_FIXED_LENGTH (s2_type))
9188  {
9189  s2_logical_length = s2_precision;
9190  }
9191  else
9192  {
9193  s2_logical_length = s2_length;
9194  }
9195 
9196  /*
9197  * If both source strings are fixed-length, the concatenated
9198  * result will be fixed-length.
9199  */
9200  if (QSTR_IS_FIXED_LENGTH (s1_type) && QSTR_IS_FIXED_LENGTH (s2_type))
9201  {
9202  /*
9203  * The result will be a chararacter string of length =
9204  * string1_precision + string2_precision. If the result
9205  * length is greater than the maximum allowed for a fixed
9206  * length string, the TRUNCATED exception is raised and
9207  * the string is shortened appropriately.
9208  */
9209  *result_length = s1_logical_length + s2_logical_length;
9210  if (*result_length > QSTR_MAX_PRECISION (s1_type))
9211  {
9212  *result_length = QSTR_MAX_PRECISION (s1_type);
9213  *data_status = DATA_STATUS_TRUNCATED;
9214  }
9215 
9216  if (QSTR_IS_NATIONAL_CHAR (s1_type))
9217  {
9218  *result_size = *result_length * 2;
9219  }
9220  else
9221  {
9222  *result_size = *result_length;
9223  }
9224 
9225  /*
9226  * Determine how much of s1 is already copied.
9227  * Remember that this may or may not include needed padding.
9228  * Then determine how much padding must be added to each
9229  * source string.
9230  */
9231  copy_length = MIN (s1_length, *result_length);
9232  intl_char_size ((unsigned char *) s1, copy_length, codeset, &copy_size);
9233 
9234  pad1_length = MIN (s1_logical_length, *result_length) - copy_length;
9235  length_left = *result_length - copy_length - pad1_length;
9236 
9237  /*
9238  * Determine how much of string2 can be concatenated after
9239  * string1. Remember that string2 is concatentated after
9240  * the full length of string1 including any necessary pad
9241  * characters.
9242  */
9243  cat_length = MIN (s2_length, length_left);
9244  intl_char_size ((unsigned char *) s2, cat_length, codeset, &cat_size);
9245 
9246  pad2_length = length_left - cat_length;
9247 
9248  /*
9249  * Pad string s1, Copy the s2 string after the s1 string
9250  */
9251  cat_ptr = qstr_pad_string ((unsigned char *) &(s1[copy_size]), pad1_length, codeset);
9252 
9253  memcpy ((char *) cat_ptr, (char *) s2, cat_size);
9254  (void) qstr_pad_string ((unsigned char *) &cat_ptr[cat_size], pad2_length, codeset);
9255  }
9256  /*
9257  * If either source string is variable-length, the concatenated
9258  * result will be variable-length.
9259  */
9260  else
9261  {
9262  /*
9263  * The result length will be the sum of the lengths of
9264  * the two source strings. If this is greater than the
9265  * maximum length of a variable length string, then the
9266  * result length is adjusted appropriately. This does
9267  * not necessarily indicate a truncation condition.
9268  */
9269  *result_length = MIN ((s1_logical_length + s2_logical_length), QSTR_MAX_PRECISION (s1_type));
9270 
9271  if ((s1_type == DB_TYPE_NCHAR) || (s1_type == DB_TYPE_VARNCHAR))
9272  {
9273  *result_size = *result_length * 2;
9274  }
9275  else
9276  {
9277  *result_size = *result_length;
9278  }
9279 
9280  /*
9281  * Calculate the number of characters from string1 that are already
9282  * into the result. If s1 string is larger than the expected entire
9283  * string and if the portion of the string s1 contained anything but
9284  * pad characters, then raise a truncation exception.
9285  */
9286  copy_length = s1_length;
9287  if (copy_length > *result_length)
9288  {
9289  copy_length = *result_length;
9290 
9291  if (varchar_truncated ((unsigned char *) s1, s1_type, s1_length, copy_length, codeset))
9292  {
9293  *data_status = DATA_STATUS_TRUNCATED;
9294  }
9295  }
9296  intl_char_size ((unsigned char *) s1, copy_length, codeset, &copy_size);
9297 
9298  pad1_length = MIN (s1_logical_length, *result_length) - copy_length;
9299  length_left = *result_length - copy_length - pad1_length;
9300 
9301  /*
9302  * Processess string2 as we did for string1.
9303  */
9304  cat_length = s2_length;
9305  if (cat_length > (*result_length - copy_length))
9306  {
9307  cat_length = *result_length - copy_length;
9308 
9309  if (varchar_truncated ((unsigned char *) s2, s2_type, s2_length, cat_length, codeset))
9310  {
9311  *data_status = DATA_STATUS_TRUNCATED;
9312  }
9313  }
9314  intl_char_size ((unsigned char *) s2, cat_length, codeset, &cat_size);
9315 
9316  pad2_length = length_left - cat_length;
9317 
9318  /*
9319  * Actually perform the copy operation.
9320  */
9321  cat_ptr = qstr_pad_string ((unsigned char *) &(s1[copy_size]), pad1_length, codeset);
9322 
9323  memcpy ((char *) cat_ptr, (char *) s2, cat_size);
9324  (void) qstr_pad_string ((unsigned char *) &cat_ptr[cat_size], pad2_length, codeset);
9325  }
9326 
9327  intl_char_size (s1, *result_length, codeset, result_size);
9328 
9329  return error_status;
9330 }
9331 #endif
9332 /*
9333  * qstr_concatenate () -
9334  *
9335  * Arguments:
9336  * s1: (IN) First string pointer.
9337  * s1_length: (IN) Character length of <s1>.
9338  * s1_precision: (IN) Max character length of <s1>.
9339  * s1_type: (IN) Domain type of <s1>.
9340  * s2: (IN) Second string pointer.
9341  * s2_length: (IN) Character length of <s2>.
9342  * s2_precision: (IN) Max character length of <s2>.
9343  * s2_type: (IN) Domain type of <s2>.
9344  * codeset: (IN) international codeset.
9345  * result: (OUT) Concatenated string pointer.
9346  * result_length: (OUT) Character length of <result>.
9347  * result_size: (OUT) Byte size of <result>.
9348  * result_type: (OUT) Domain type of <result>
9349  *
9350  * Returns:
9351  *
9352  * Errors:
9353  *
9354  */
9355 
9356 static int
9357 qstr_concatenate (const unsigned char *s1, int s1_length, int s1_precision, DB_TYPE s1_type, const unsigned char *s2,
9358  int s2_length, int s2_precision, DB_TYPE s2_type, INTL_CODESET codeset, unsigned char **result,
9359  int *result_length, int *result_size, DB_TYPE * result_type, DB_DATA_STATUS * data_status)
9360 {
9361  int copy_length, copy_size;
9362  int pad1_length, pad2_length;
9363  int length_left, cat_length, cat_size;
9364  int s1_logical_length, s2_logical_length;
9365  int s1_size, s2_size;
9366  unsigned char *cat_ptr;
9367  int error_status = NO_ERROR;
9368 
9369  *data_status = DATA_STATUS_OK;
9370 
9371  /*
9372  * Categorize the source string into fixed and variable
9373  * length. Variable length strings are simple. Fixed
9374  * length strings have to be handled special since the
9375  * strings may not have all of their pad character allocated
9376  * yet. We have to account for this and act as if all of the
9377  * characters are present. They all will be by the time
9378  * we are through.
9379  */
9380  if (QSTR_IS_FIXED_LENGTH (s1_type))
9381  {
9382  s1_logical_length = s1_precision;
9383  }
9384  else
9385  {
9386  s1_logical_length = s1_length;
9387  }
9388 
9389 
9390  if (QSTR_IS_FIXED_LENGTH (s2_type))
9391  {
9392  s2_logical_length = s2_precision;
9393  }
9394  else
9395  {
9396  s2_logical_length = s2_length;
9397  }
9398 
9399  /*
9400  * If both source strings are fixed-length, the concatenated
9401  * result will be fixed-length.
9402  */
9403  if (QSTR_IS_FIXED_LENGTH (s1_type) && QSTR_IS_FIXED_LENGTH (s2_type))
9404  {
9405  /*
9406  * The result will be a chararacter string of length =
9407  * string1_precision + string2_precision. If the result
9408  * length is greater than the maximum allowed for a fixed
9409  * length string, the TRUNCATED exception is raised and
9410  * the string is shortened appropriately.
9411  */
9412  *result_length = s1_logical_length + s2_logical_length;
9413  if (*result_length > QSTR_MAX_PRECISION (s1_type))
9414  {
9415  *result_length = QSTR_MAX_PRECISION (s1_type);
9416  *data_status = DATA_STATUS_TRUNCATED;
9417  }
9418 
9419  intl_char_size ((unsigned char *) s1, s1_logical_length, codeset, &s1_size);
9420  intl_char_size ((unsigned char *) s2, s2_logical_length, codeset, &s2_size);
9421 
9422  if (s1_size == 0)
9423  {
9424  s1_size = s1_logical_length;
9425  }
9426  if (s2_size == 0)
9427  {
9428  s2_size = s2_logical_length;
9429  }
9430 
9431  *result_size = s1_size + s2_size;
9432 
9433  if (QSTR_IS_NATIONAL_CHAR (s1_type))
9434  {
9435  *result_type = DB_TYPE_VARNCHAR;
9436  }
9437  else
9438  {
9439  *result_type = DB_TYPE_VARCHAR;
9440  }
9441 
9442  if (*result_size > (int) prm_get_bigint_value (PRM_ID_STRING_MAX_SIZE_BYTES))
9443  {
9444  goto size_error;
9445  }
9446  /* Allocate storage for the result string */
9447  *result = (unsigned char *) db_private_alloc (NULL, (size_t) * result_size + 1);
9448  if (*result == NULL)
9449  {
9450  goto mem_error;
9451  }
9452 
9453  /*
9454  * Determine how much of string1 needs to be copied.
9455  * Remember that this may or may not include needed padding.
9456  * Then determine how much padding must be added to each
9457  * source string.
9458  */
9459  copy_length = MIN (s1_length, *result_length);
9460  intl_char_size ((unsigned char *) s1, copy_length, codeset, &copy_size);
9461 
9462  pad1_length = MIN (s1_logical_length, *result_length) - copy_length;
9463  length_left = *result_length - copy_length - pad1_length;
9464 
9465  /*
9466  * Determine how much of string2 can be concatenated after
9467  * string1. Remember that string2 is concatentated after
9468  * the full length of string1 including any necessary pad
9469  * characters.
9470  */
9471  cat_length = MIN (s2_length, length_left);
9472  intl_char_size ((unsigned char *) s2, cat_length, codeset, &cat_size);
9473 
9474  pad2_length = length_left - cat_length;
9475 
9476  /*
9477  * Copy the source strings into the result string
9478  */
9479  memcpy ((char *) *result, (char *) s1, copy_size);
9480  cat_ptr = qstr_pad_string ((unsigned char *) &((*result)[copy_size]), pad1_length, codeset);
9481 
9482  memcpy ((char *) cat_ptr, (char *) s2, cat_size);
9483  (void) qstr_pad_string ((unsigned char *) &cat_ptr[cat_size], pad2_length, codeset);
9484  }
9485  /*
9486  * If either source string is variable-length, the concatenated
9487  * result will be variable-length.
9488  */
9489  else
9490  {
9491  /*
9492  * The result length will be the sum of the lengths of
9493  * the two source strings. If this is greater than the
9494  * maximum length of a variable length string, then the
9495  * result length is adjusted appropriately. This does
9496  * not necessarily indicate a truncation condition.
9497  */
9498  *result_length = MIN ((s1_logical_length + s2_logical_length), QSTR_MAX_PRECISION (s1_type));
9499 
9500  if ((s1_type == DB_TYPE_NCHAR) || (s1_type == DB_TYPE_VARNCHAR))
9501  {
9502  *result_type = DB_TYPE_VARNCHAR;
9503  }
9504  else
9505  {
9506  *result_type = DB_TYPE_VARCHAR;
9507  }
9508 
9509  intl_char_size ((unsigned char *) s1, s1_logical_length, codeset, &s1_size);
9510  intl_char_size ((unsigned char *) s2, s2_logical_length, codeset, &s2_size);
9511 
9512  if (s1_size == 0)
9513  {
9514  s1_size = s1_logical_length;
9515  }
9516  if (s2_size == 0)
9517  {
9518  s2_size = s2_logical_length;
9519  }
9520 
9521  *result_size = s1_size + s2_size;
9522 
9523  if (*result_size > (int) prm_get_bigint_value (PRM_ID_STRING_MAX_SIZE_BYTES))
9524  {
9525  goto size_error;
9526  }
9527 
9528  /* Allocate the result string */
9529  *result = (unsigned char *) db_private_alloc (NULL, (size_t) * result_size + 1);
9530  if (*result == NULL)
9531  {
9532  goto mem_error;
9533  }
9534 
9535 
9536  /*
9537  * Calculate the number of characters from string1 that can
9538  * be copied to the result. If we cannot copy the entire
9539  * string and if the portion of the string which was not
9540  * copied contained anything but pad characters, then raise
9541  * a truncation exception.
9542  */
9543  copy_length = s1_length;
9544  if (copy_length > *result_length)
9545  {
9546  copy_length = *result_length;
9547 
9548  if (varchar_truncated ((unsigned char *) s1, s1_type, s1_length, copy_length, codeset))
9549  {
9550  *data_status = DATA_STATUS_TRUNCATED;
9551  }
9552  }
9553  intl_char_size ((unsigned char *) s1, copy_length, codeset, &copy_size);
9554 
9555  pad1_length = MIN (s1_logical_length, *result_length) - copy_length;
9556  length_left = *result_length - copy_length - pad1_length;
9557 
9558  /*
9559  * Processess string2 as we did for string1.
9560  */
9561  cat_length = s2_length;
9562  if (cat_length > (*result_length - copy_length))
9563  {
9564  cat_length = *result_length - copy_length;
9565 
9566  if (varchar_truncated ((unsigned char *) s2, s2_type, s2_length, cat_length, codeset))
9567  {
9568  *data_status = DATA_STATUS_TRUNCATED;
9569  }
9570  }
9571  intl_char_size ((unsigned char *) s2, cat_length, codeset, &cat_size);
9572 
9573  pad2_length = length_left - cat_length;
9574 
9575  /*
9576  * Actually perform the copy operations.
9577  */
9578  memcpy ((char *) *result, (char *) s1, copy_size);
9579  cat_ptr = qstr_pad_string ((unsigned char *) &((*result)[copy_size]), pad1_length, codeset);
9580 
9581  memcpy ((char *) cat_ptr, (char *) s2, cat_size);
9582  (void) qstr_pad_string ((unsigned char *) &cat_ptr[cat_size], pad2_length, codeset);
9583  }
9584 
9585  intl_char_size (*result, *result_length, codeset, result_size);
9586 
9587  return error_status;
9588 
9589 size_error:
9590  error_status = ER_QPROC_STRING_SIZE_TOO_BIG;
9591  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 2, *result_size,
9593  return error_status;
9594  /*
9595  * Error handler
9596  */
9597 mem_error:
9598  assert (er_errid () != NO_ERROR);
9599  error_status = er_errid ();
9600  return error_status;
9601 }
9602 
9603 /*
9604  * qstr_bit_concatenate () -
9605  *
9606  * Arguments:
9607  * s1: (IN) First string pointer.
9608  * s1_length: (IN) Character length of <s1>.
9609  * s1_precision: (IN) Max character length of <s1>.
9610  * s1_type: (IN) Domain type of <s1>.
9611  * s2: (IN) Second string pointer.
9612  * s2_length: (IN) Character length of <s2>.
9613  * s2_precision: (IN) Max character length of <s2>.
9614  * s2_type: (IN) Domain type of <s2>.
9615  * result: (OUT) Concatenated string pointer.
9616  * result_length: (OUT) Character length of <result>.
9617  * result_size: (OUT) Byte size of <result>.
9618  * result_type: (OUT) Domain type of <result>
9619  *
9620  * Returns:
9621  *
9622  * Errors:
9623  *
9624  */
9625 
9626 static int
9627 qstr_bit_concatenate (const unsigned char *s1, int s1_length, int s1_precision, DB_TYPE s1_type,
9628  const unsigned char *s2, int s2_length, int s2_precision, DB_TYPE s2_type, unsigned char **result,
9629  int *result_length, int *result_size, DB_TYPE * result_type, DB_DATA_STATUS * data_status)
9630 {
9631  int s1_size, s2_size;
9632  int copy_length, cat_length;
9633  int s1_logical_length, s2_logical_length;
9634  int error_status = NO_ERROR;
9635 
9636  *data_status = DATA_STATUS_OK;
9637 
9638  /*
9639  * Calculate the byte size of the strings.
9640  * Calculate the bit length and byte size needed to concatenate
9641  * the two strings without truncation.
9642  */
9643  s1_size = QSTR_NUM_BYTES (s1_length);
9644  s2_size = QSTR_NUM_BYTES (s2_length);
9645 
9646 
9647  /*
9648  * Categorize the source string into fixed and variable
9649  * length. Variable length strings are simple. Fixed
9650  * length strings have to be handled special since the
9651  * strings may not have all of their pad character allocated
9652  * yet. We have to account for this and act as if all of the
9653  * characters are present. They all will be by the time
9654  * we are through.
9655  */
9656  if ((s1_type == DB_TYPE_CHAR) || (s1_type == DB_TYPE_NCHAR))
9657  {
9658  s1_logical_length = s1_precision;
9659  }
9660  else
9661  {
9662  s1_logical_length = s1_length;
9663  }
9664 
9665 
9666  if ((s2_type == DB_TYPE_CHAR) || (s2_type == DB_TYPE_NCHAR))
9667  {
9668  s2_logical_length = s2_precision;
9669  }
9670  else
9671  {
9672  s2_logical_length = s2_length;
9673  }
9674 
9675 
9676  if ((s1_type == DB_TYPE_BIT) && (s2_type == DB_TYPE_BIT))
9677  {
9678  /*
9679  * The result will be a bit string of length =
9680  * string1_precision + string2_precision. If the result
9681  * length is greater than the maximum allowed for a fixed
9682  * length string, the TRUNCATED exception is raised and
9683  * the string is shortened appropriately.
9684  */
9685  *result_type = DB_TYPE_BIT;
9686  *result_length = s1_logical_length + s2_logical_length;
9687 
9688  if (*result_length > DB_MAX_BIT_LENGTH)
9689  {
9690  *result_length = DB_MAX_BIT_LENGTH;
9691  *data_status = DATA_STATUS_TRUNCATED;
9692  }
9693  *result_size = QSTR_NUM_BYTES (*result_length);
9694 
9695 
9696  if (*result_size > (int) prm_get_bigint_value (PRM_ID_STRING_MAX_SIZE_BYTES))
9697  {
9698  goto size_error;
9699  }
9700 
9701  /* Allocate the result string */
9702  *result = (unsigned char *) db_private_alloc (NULL, (size_t) * result_size + 1);
9703  if (*result == NULL)
9704  {
9705  goto mem_error;
9706  }
9707 
9708  /*
9709  * The source strings may not be fully padded, so
9710  * we pre-pad the result string.
9711  */
9712  (void) memset ((char *) *result, (int) 0, (int) *result_size);
9713 
9714  /*
9715  * Determine how much of string1 needs to be copied.
9716  * Remember that this may or may not include needed padding
9717  */
9718  copy_length = s1_length;
9719  if (copy_length > *result_length)
9720  {
9721  copy_length = *result_length;
9722  }
9723 
9724  /*
9725  * Determine how much of string2 can be concatenated after
9726  * string1. Remember that string2 is concatentated after
9727  * the full length of string1 including any necessary pad
9728  * characters.
9729  */
9730  cat_length = s2_length;
9731  if (cat_length > (*result_length - s1_logical_length))
9732  {
9733  cat_length = *result_length - s1_logical_length;
9734  }
9735 
9736 
9737  /*
9738  * Copy the source strings into the result string.
9739  * We are being a bit sloppy here by performing a byte
9740  * copy as opposed to a bit copy. But this should be OK
9741  * since the bit strings should be bit padded with 0' s */
9742  bit_ncat (*result, 0, (unsigned char *) s1, copy_length);
9743  bit_ncat (*result, s1_logical_length, (unsigned char *) s2, cat_length);
9744  }
9745 
9746  else /* Assume DB_TYPE_VARBIT */
9747  {
9748  /*
9749  * The result length will be the sum of the lengths of
9750  * the two source strings. If this is greater than the
9751  * maximum length of a variable length string, then the
9752  * result length is adjusted appropriately. This does
9753  * not necessarily indicate a truncation condition.
9754  */
9755  *result_type = DB_TYPE_VARBIT;
9756  *result_length = s1_logical_length + s2_logical_length;
9757  if (*result_length > DB_MAX_BIT_LENGTH)
9758  *result_length = DB_MAX_BIT_LENGTH;
9759 
9760  *result_size = QSTR_NUM_BYTES (*result_length);
9761 
9762  if (*result_size > (int) prm_get_bigint_value (PRM_ID_STRING_MAX_SIZE_BYTES))
9763  {
9764  goto size_error;
9765  }
9766  /* Allocate storage for the result string */
9767  *result = (unsigned char *) db_private_alloc (NULL, (size_t) * result_size + 1);
9768  if (*result == NULL)
9769  {
9770  goto mem_error;
9771  }
9772 
9773  /*
9774  * The source strings may not be fully padded, so
9775  * we pre-pad the result string.
9776  */
9777  (void) memset ((char *) *result, (int) 0, (int) *result_size);
9778 
9779  /*
9780  * Calculate the number of bits from string1 that can
9781  * be copied to the result. If we cannot copy the entire
9782  * string and if the portion of the string which was not
9783  * copied contained anything but 0's, then raise a
9784  * truncation exception.
9785  */
9786  copy_length = s1_length;
9787  if (copy_length > *result_length)
9788  {
9789  copy_length = *result_length;
9790  if (varbit_truncated (s1, s1_length, copy_length))
9791  {
9792  *data_status = DATA_STATUS_TRUNCATED;
9793  }
9794  }
9795 
9796  /* Processess string2 as we did for string1. */
9797  cat_length = s2_length;
9798  if (cat_length > (*result_length - copy_length))
9799  {
9800  cat_length = *result_length - copy_length;
9801  if (varbit_truncated (s2, s2_length, cat_length))
9802  {
9803  *data_status = DATA_STATUS_TRUNCATED;
9804  }
9805  }
9806 
9807 
9808  /*
9809  * Actually perform the copy operations and
9810  * place the result string in a container.
9811  */
9812  bit_ncat (*result, 0, (unsigned char *) s1, copy_length);
9813  bit_ncat (*result, copy_length, s2, cat_length);
9814  }
9815 
9816  return error_status;
9817 
9818 size_error:
9819  error_status = ER_QPROC_STRING_SIZE_TOO_BIG;
9820  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 2, *result_size,
9822  return error_status;
9823 
9824  /*
9825  * Error handling
9826  */
9827 mem_error:
9828  assert (er_errid () != NO_ERROR);
9829  error_status = er_errid ();
9830  return error_status;
9831 }
9832 
9833 /*
9834  * varchar_truncated () -
9835  *
9836  * Arguments:
9837  * s: (IN) Pointer to input string.
9838  * s_length: (IN) Length of input string.
9839  * used_chars: (IN) Number of characters which were used by caller.
9840  * 0 <= <used_chars> <= <s_length>
9841  * codeset: (IN) international codeset of input string.
9842  *
9843  * Returns: bool
9844  *
9845  * Errors:
9846  *
9847  * Note:
9848  * This is a convenience function which is used by the concatenation
9849  * function to determine if a variable length string has been
9850  * truncated. When concatenating variable length strings, the string
9851  * is not considered truncated if only pad characters were omitted.
9852  *
9853  * This function accepts a string <s>, its length <s_length>, and
9854  * a count of characters <used_chars>. If the remaining characters
9855  * are all pad characters, then the function returns true value.
9856  * A False value is returned otherwise.
9857  *
9858  */
9859 
9860 static bool
9861 varchar_truncated (const unsigned char *s, DB_TYPE s_type, int s_length, int used_chars, INTL_CODESET codeset)
9862 {
9863  unsigned char pad[2];
9864  int pad_size = 0, trim_length, trim_size;
9865  int s_size;
9866 
9867  bool truncated = false;
9868 
9869  intl_pad_char (codeset, pad, &pad_size);
9870  intl_char_size ((unsigned char *) s, s_length, codeset, &s_size);
9871 
9872  qstr_trim_trailing (pad, pad_size, s, s_type, s_length, s_size, codeset, &trim_length, &trim_size, true);
9873 
9874  if (trim_length > used_chars)
9875  {
9876  truncated = true;
9877  }
9878 
9879  return truncated;
9880 }
9881 
9882 /*
9883  * varbit_truncated () -
9884  *
9885  * Arguments:
9886  * s: (IN) Pointer to input string.
9887  * s_length: (IN) Length of input string.
9888  * used_bits: (IN) Number of characters which were used by caller.
9889  * 0 <= <used_chars> <= <s_length>
9890  *
9891  * Returns:
9892  *
9893  * Errors:
9894  *
9895  * Note:
9896  * This is a convenience function which is used by the concatenation
9897  * function to determine if a variable length string has been
9898  * truncated. When concatenating variable length strings, the bit
9899  * string is not considered truncated if only 0's were omitted.
9900  *
9901  * This function accepts a string <s>, its length <s_length>, and
9902  * a count of characters <used_chars>. If the remaining characters
9903  * are all 0's, then the function returns true value. A False value
9904  * is returned otherwise.
9905  *
9906  */
9907 
9908 static bool
9909 varbit_truncated (const unsigned char *s, int s_length, int used_bits)
9910 {
9911  int last_set_bit;
9912  bool truncated = false;
9913 
9914 
9915  last_set_bit = bstring_fls ((char *) s, QSTR_NUM_BYTES (s_length));
9916 
9917  if (last_set_bit > used_bits)
9918  {
9919  truncated = true;
9920  }
9921 
9922  return truncated;
9923 }
9924 
9925 /*
9926  * bit_ncat () -
9927  *
9928  * Arguments:
9929  * r: Pointer to bit string 1
9930  * offset: Number of bits in string1
9931  * s: Pointer to bit string 2
9932  * n: Number of bits in string 2
9933  *
9934  * Returns: void
9935  *
9936  * Errors:
9937  *
9938  * Note:
9939  * Shift the bits of <s> onto the end of <r>. This is a helper
9940  * function to str_bit_concatenate. This function shifts
9941  * (concatenates) exactly the number of bits specified into the result
9942  * buffer which must be preallocated to the correct size.
9943  *
9944  */
9945 
9946 static void
9947 bit_ncat (unsigned char *r, int offset, const unsigned char *s, int n)
9948 {
9949  int i, copy_size, cat_size, total_size;
9950  unsigned int remainder, shift_amount;
9951  unsigned short tmp_shifted;
9952  unsigned char mask;
9953 
9954  copy_size = QSTR_NUM_BYTES (offset);
9955  cat_size = QSTR_NUM_BYTES (n);
9956  total_size = QSTR_NUM_BYTES (offset + n);
9957 
9958  remainder = offset % BYTE_SIZE;
9959 
9960  if (remainder == 0)
9961  {
9962  memcpy ((char *) &r[copy_size], (char *) s, cat_size);
9963  }
9964  else
9965  {
9966  int start_byte = copy_size - 1;
9967 
9968  shift_amount = BYTE_SIZE - remainder;
9969  mask = 0xff << shift_amount;
9970 
9971  /*
9972  * tmp_shifted is loaded with a byte from the source
9973  * string and shifted into poition. The upper byte is
9974  * used for the current destination location, while the
9975  * lower byte is used by the next destination location.
9976  */
9977  for (i = start_byte; i < total_size; i++)
9978  {
9979  tmp_shifted = (unsigned short) (s[i - start_byte]);
9980  tmp_shifted = tmp_shifted << shift_amount;
9981  r[i] = (r[i] & mask) | (tmp_shifted >> BYTE_SIZE);
9982 
9983  if (i < (total_size - 1))
9984  {
9985  r[i + 1] = (unsigned char) (tmp_shifted & (unsigned short) 0xff);
9986  }
9987  }
9988  }
9989 
9990  /* Mask out the unused bits */
9991  mask = 0xff << (BYTE_SIZE - ((offset + n) % BYTE_SIZE));
9992  if (mask != 0)
9993  {
9994  r[total_size - 1] &= mask;
9995  }
9996 }
9997 
9998 /*
9999  * bstring_fls () -
10000  *
10001  * Arguments:
10002  * s: Pointer to source bit string
10003  * n: Number of bits in string1
10004  *
10005  * Returns: int
10006  *
10007  * Errors:
10008  *
10009  * Note:
10010  * Find the last set bit in the bit string. The bits are numbered left
10011  * to right starting at 1. A value of 0 indicates that no set bits were
10012  * found in the string.
10013  *
10014  */
10015 
10016 static int
10017 bstring_fls (const char *s, int n)
10018 {
10019  int byte_num, bit_num, inter_bit_num;
10020 
10021 
10022  /*
10023  * We are looking for the first non-zero byte (starting at the end).
10024  */
10025  byte_num = n - 1;
10026  while ((byte_num >= 0) && ((int) (s[byte_num]) == 0))
10027  {
10028  byte_num--;
10029  }
10030 
10031  /*
10032  * If byte_num is < 0, then the string is all 0's.
10033  * Othersize, byte_num is the index for the first byte which has
10034  * some bits set (from the end).
10035  */
10036  if (byte_num < 0)
10037  {
10038  bit_num = 0;
10039  }
10040  else
10041  {
10042  inter_bit_num = (int) qstr_ffs ((int) (s[byte_num]));
10043  bit_num = (byte_num * BYTE_SIZE) + (BYTE_SIZE - inter_bit_num + 1);
10044  }
10045 
10046  return bit_num;
10047 }
10048 
10049 /*
10050  * qstr_bit_coerce () -
10051  *
10052  * Arguments:
10053  * src_string: (In) Source string
10054  * dest_string: (Out) Coerced string
10055  *
10056  * Returns: DB_DATA_STATUS
10057  *
10058  * Errors:
10059  *
10060  * Note:
10061  * This is a helper function which performs the actual coercion for
10062  * bit strings. It is called from db_bit_string_coerce().
10063  *
10064  * If any loss of data due to truncation occurs DATA_STATUS_TRUNCATED
10065  * is returned.
10066  *
10067  */
10068 
10069 static int
10070 qstr_bit_coerce (const unsigned char *src, int src_length, int src_precision, DB_TYPE src_type, unsigned char **dest,
10071  int *dest_length, int dest_precision, DB_TYPE dest_type, DB_DATA_STATUS * data_status)
10072 {
10073  int src_padded_length, copy_size, dest_size, copy_length;
10074  int error_status = NO_ERROR;
10075 
10076  *data_status = DATA_STATUS_OK;
10077 
10078  /*
10079  * <src_padded_length> is the length of the fully padded
10080  * source string.
10081  */
10082  if (QSTR_IS_FIXED_LENGTH (src_type))
10083  {
10084  src_padded_length = src_precision;
10085  }
10086  else
10087  {
10088  src_padded_length = src_length;
10089  }
10090 
10091  /*
10092  * If there is not enough precision in the destination string,
10093  * then some bits will be omited from the source string.
10094  */
10095  if (src_padded_length > dest_precision)
10096  {
10097  int i, n = 0;
10098  i = dest_precision / 8;
10099  if (src[i] & (0x80 >> (dest_precision % 8)) || ((src[i] << (dest_precision % 8)) & 0xff))
10100  {
10101  *data_status = DATA_STATUS_TRUNCATED;
10102  }
10103  else
10104  {
10105  i++; /* for check reamin trailing bits */
10106  for (; i < (src_padded_length + 4) / 8; i++)
10107  {
10108  if (src[i])
10109  {
10110  *data_status = DATA_STATUS_TRUNCATED;
10111  break;
10112  }
10113  }
10114  }
10115  src_padded_length = dest_precision;
10116  }
10117 
10118  copy_length = MIN (src_length, src_padded_length);
10119  copy_size = QSTR_NUM_BYTES (copy_length);
10120 
10121  /*
10122  * For fixed-length destination strings...
10123  * Allocate the destination precision size, copy the source
10124  * string and pad the rest.
10125  *
10126  * For variable-length destination strings...
10127  * Allocate enough for a fully padded source string, copy
10128  * the source string and pad the rest.
10129  */
10130  if (QSTR_IS_FIXED_LENGTH (dest_type))
10131  {
10132  *dest_length = dest_precision;
10133  }
10134  else
10135  {
10136  *dest_length = MIN (src_padded_length, dest_precision);
10137  }
10138 
10139  dest_size = QSTR_NUM_BYTES (*dest_length);
10140 
10141  *dest = (unsigned char *) db_private_alloc (NULL, dest_size + 1);
10142  if (*dest == NULL)
10143  {
10144  assert (er_errid () != NO_ERROR);
10145  error_status = er_errid ();
10146  }
10147  else
10148  {
10149  bit_ncat (*dest, 0, src, copy_length);
10150  (void) memset ((char *) &((*dest)[copy_size]), (int) 0, (dest_size - copy_size));
10151  }
10152 
10153  return error_status;
10154 }
10155 
10156 /*
10157  * qstr_coerce () -
10158  *
10159  * Arguments:
10160  * src_string: (In) Source string
10161  * dest_string: (Out) Coerced string
10162  *
10163  * Returns: DB_DATA_STATUS
10164  *
10165  * Errors:
10166  *
10167  * Note:
10168  * This is a helper function which performs the actual coercion for
10169  * character strings. It is called from db_char_string_coerce().
10170  *
10171  * If any loss of data due to truncation occurs DATA_STATUS_TRUNCATED
10172  * is returned.
10173  *
10174  */
10175 
10176 static int
10177 qstr_coerce (const unsigned char *src, int src_length, int src_precision, DB_TYPE src_type, INTL_CODESET src_codeset,
10178  INTL_CODESET dest_codeset, unsigned char **dest, int *dest_length, int *dest_size, int dest_precision,
10179  DB_TYPE dest_type, DB_DATA_STATUS * data_status)
10180 {
10181  int src_padded_length, copy_length, copy_size;
10182  int alloc_size;
10183  unsigned char *end_of_string;
10184  int error_status = NO_ERROR;
10185 
10186  *data_status = DATA_STATUS_OK;
10187  *dest_size = 0;
10188 
10189  /*
10190  * <src_padded_length> is the length of the fully padded
10191  * source string.
10192  */
10193  if (QSTR_IS_FIXED_LENGTH (src_type))
10194  {
10195  src_padded_length = src_precision;
10196  }
10197  else
10198  {
10199  src_padded_length = src_length;
10200  }
10201 
10202  /*
10203  * Some characters will be truncated if there is not enough
10204  * precision in the destination string. If any of the
10205  * truncated characters are non-pad characters, a truncation
10206  * exception is raised.
10207  */
10208  if (src_padded_length > dest_precision)
10209  {
10210  src_padded_length = dest_precision;
10211  if ((src_length > src_padded_length)
10212  && (varchar_truncated (src, src_type, src_length, src_padded_length, src_codeset)))
10213  {
10214  *data_status = DATA_STATUS_TRUNCATED;
10215  }
10216  }
10217 
10218  copy_length = MIN (src_length, src_padded_length);
10219 
10220  /*
10221  * For fixed-length destination strings...
10222  * Allocate the destination precision size, copy the source
10223  * string and pad the rest.
10224  *
10225  * For variable-length destination strings...
10226  * Allocate enough for a fully padded source string, copy
10227  * the source string and pad the rest.
10228  */
10229  if (QSTR_IS_FIXED_LENGTH (dest_type))
10230  {
10231  *dest_length = dest_precision;
10232  }
10233  else
10234  {
10235  *dest_length = src_padded_length;
10236  }
10237 
10238  if (dest_codeset == INTL_CODESET_RAW_BYTES)
10239  {
10240  /* when coercing multibyte to binary charset, we just reinterpret each byte as one character */
10241  if (INTL_CODESET_MULT (src_codeset) > 1)
10242  {
10243  assert (dest_precision != TP_FLOATING_PRECISION_VALUE);
10244 
10245  intl_char_size ((unsigned char *) src, copy_length, src_codeset, &copy_size);
10246  if (copy_size > dest_precision)
10247  {
10248  *data_status = DATA_STATUS_TRUNCATED;
10249  copy_size = dest_precision;
10250  }
10251  copy_length = copy_size;
10252  if (QSTR_IS_VARIABLE_LENGTH (dest_type))
10253  {
10254  *dest_length = copy_length;
10255  }
10256  }
10257  else
10258  {
10259  copy_size = copy_length;
10260  }
10261  }
10262  else
10263  {
10264  /* copy_length = number of characters, count the bytes according to source codeset */
10265  intl_char_size ((unsigned char *) src, copy_length, src_codeset, &copy_size);
10266  }
10267 
10268  alloc_size = INTL_CODESET_MULT (dest_codeset) * (*dest_length);
10269 
10270  /* fix allocation size enough to fit copy size plus pad size */
10271  {
10272  unsigned char pad[2];
10273  int pad_size = 0;
10274 
10275  intl_pad_char (dest_codeset, pad, &pad_size);
10276  alloc_size = MAX (alloc_size, copy_size + (*dest_length - copy_length) * pad_size);
10277  }
10278 
10279  if (!alloc_size)
10280  {
10281  alloc_size = 1;
10282  }
10283 
10284  *dest = (unsigned char *) db_private_alloc (NULL, alloc_size + 1);
10285  if (*dest == NULL)
10286  {
10287  assert (er_errid () != NO_ERROR);
10288  error_status = er_errid ();
10289  }
10290  else
10291  {
10292  int conv_status = 0;
10293 
10294  assert (copy_size >= 0);
10295  if (copy_size == 0)
10296  {
10297  assert (alloc_size > 0);
10298  **dest = '\0';
10299  }
10300  else if (src_codeset == INTL_CODESET_ISO88591 && dest_codeset == INTL_CODESET_UTF8)
10301  {
10302  int conv_size = 0;
10303 
10304  assert (copy_size > 0);
10305  conv_status = intl_fast_iso88591_to_utf8 (src, copy_size, dest, &conv_size);
10306  copy_size = conv_size;
10307  }
10308  else if (src_codeset == INTL_CODESET_KSC5601_EUC && dest_codeset == INTL_CODESET_UTF8)
10309  {
10310  int conv_size = 0;
10311 
10312  assert (copy_size > 0);
10313  conv_status = intl_euckr_to_utf8 (src, copy_size, dest, &conv_size);
10314  copy_size = conv_size;
10315  }
10316  else if (src_codeset == INTL_CODESET_UTF8 && dest_codeset == INTL_CODESET_KSC5601_EUC)
10317  {
10318  int conv_size = 0;
10319 
10320  assert (copy_size > 0);
10321  conv_status = intl_utf8_to_euckr (src, copy_size, dest, &conv_size);
10322  copy_size = conv_size;
10323  }
10324  else if (src_codeset == INTL_CODESET_ISO88591 && dest_codeset == INTL_CODESET_KSC5601_EUC)
10325  {
10326  int conv_size = 0;
10327 
10328  assert (copy_size > 0);
10329  conv_status = intl_iso88591_to_euckr (src, copy_size, dest, &conv_size);
10330  copy_size = conv_size;
10331  }
10332  else if (src_codeset == INTL_CODESET_UTF8 && dest_codeset == INTL_CODESET_ISO88591)
10333  {
10334  int conv_size = 0;
10335 
10336  assert (copy_size > 0);
10337  conv_status = intl_utf8_to_iso88591 (src, copy_size, dest, &conv_size);
10338  copy_size = conv_size;
10339  }
10340  else if (src_codeset == INTL_CODESET_KSC5601_EUC && dest_codeset == INTL_CODESET_ISO88591)
10341  {
10342  int conv_size = 0;
10343 
10344  assert (copy_size > 0);
10345  conv_status = intl_euckr_to_iso88591 (src, copy_size, dest, &conv_size);
10346  copy_size = conv_size;
10347  }
10348  else
10349  {
10350  assert (copy_size <= alloc_size);
10351 
10352  if (src_codeset == INTL_CODESET_RAW_BYTES && (INTL_CODESET_MULT (dest_codeset) > 1))
10353  {
10354  int conv_size = 0;
10355 
10356  if (dest_codeset == INTL_CODESET_UTF8)
10357  {
10358  intl_binary_to_utf8 (src, copy_size, dest, &conv_size);
10359  }
10360  else
10361  {
10362  assert (dest_codeset == INTL_CODESET_KSC5601_EUC);
10363  intl_binary_to_euckr (src, copy_size, dest, &conv_size);
10364  }
10365  copy_size = conv_size;
10366  }
10367  else
10368  {
10369  (void) memcpy ((char *) *dest, (char *) src, (int) copy_size);
10370  }
10371  }
10372 
10373  end_of_string =
10374  qstr_pad_string ((unsigned char *) &((*dest)[copy_size]), (*dest_length - copy_length), dest_codeset);
10375  *dest_size = CAST_STRLEN (end_of_string - (*dest));
10376 
10377  if (conv_status != 0)
10378  {
10379  /* conversion error occured, re-count characters so that we comply to computed precision */
10380  (void) intl_char_size (*dest, *dest_length, dest_codeset, dest_size);
10381  end_of_string = (*dest) + *dest_size;
10382  *end_of_string = '\0';
10383  }
10384 
10385  assert (*dest_size <= alloc_size);
10386  }
10387 
10388  return error_status;
10389 }
10390 
10391 /*
10392  * qstr_position () -
10393  *
10394  * Arguments:
10395  * sub_string: String fragment to search for within <src_string>.
10396  * sub_length: Number of characters in sub_string.
10397  * src_string: String to be searched.
10398  * src_string_bound: Bound of string buffer:
10399  * end of string buffer, if 'is_forward_search == true'
10400  * start of string buffer, if 'is_forward_search == false'
10401  * src_length: Number of characters in src_string.
10402  * is_forward_search: forward search or backward search.
10403  * codeset: Codeset of strings.
10404  *
10405  * Returns: int
10406  *
10407  * Errors:
10408  *
10409  * Note:
10410  * This function accepts a source string <src_sring> and a string
10411  * string fragment <sub_string> and returns the character position
10412  * corresponding to the first occurrence of <sub_string> within
10413  * <src_string>.
10414  *
10415  * This function works with National character strings.
10416  *
10417  */
10418 
10419 static int
10420 qstr_position (const char *sub_string, const int sub_size, const int sub_length, const char *src_string,
10421  const char *src_end, const char *src_string_bound, int src_length, int coll_id, bool is_forward_search,
10422  int *position)
10423 {
10424  int error_status = NO_ERROR;
10425  int dummy;
10426 
10427  *position = 0;
10428 
10429  if (sub_length == 0)
10430  {
10431  *position = 1;
10432  }
10433  else
10434  {
10435  int i, num_searches, current_position, result;
10436  const unsigned char *ptr;
10437  int char_size;
10438  LANG_COLLATION *lc;
10439  INTL_CODESET codeset;
10440 
10441  lc = lang_get_collation (coll_id);
10442  assert (lc != NULL);
10443 
10444  codeset = lc->codeset;
10445 
10446  /*
10447  * Since the entire sub-string must be matched, a reduced
10448  * number of compares <num_searches> are needed. A collation-based
10449  * comparison will be used.
10450  */
10451  if (lc->coll.uca_exp_num > 1 || lc->coll.count_contr > 0)
10452  {
10453  /* characters may not match one-by-one */
10454  num_searches = src_length;
10455  }
10456  else
10457  {
10458  num_searches = src_length - sub_length + 1;
10459  if (sub_length > src_length)
10460  {
10461  *position = 0;
10462  return error_status;
10463  }
10464  }
10465 
10466  /*
10467  * Starting at the first position of the string, match the
10468  * sub-string to the source string. If a match is not found,
10469  * then increment into the source string by one character and
10470  * try again. This is repeated until a match is found, or
10471  * there are no more comparisons to be made.
10472  */
10473  const unsigned char *usub_string = REINTERPRET_CAST (const unsigned char *, sub_string);
10474  const unsigned char *usrc_end = REINTERPRET_CAST (const unsigned char *, src_end);
10475  const unsigned char *usrc_string = REINTERPRET_CAST (const unsigned char *, src_string);
10476  const unsigned char *usrc_string_bound = REINTERPRET_CAST (const unsigned char *, src_string_bound);
10477 
10478  ptr = usrc_string;
10479  current_position = 0;
10480  result = 1;
10481 
10482  for (i = 0; i < num_searches; i++)
10483  {
10484  result = QSTR_MATCH (coll_id, ptr, CAST_BUFLEN (usrc_end - ptr), usub_string, sub_size, NULL, false, &dummy);
10485  current_position++;
10486  if (result == 0)
10487  {
10488  break;
10489  }
10490 
10491  if (is_forward_search)
10492  {
10493  if (ptr >= usrc_string_bound)
10494  {
10495  break;
10496  }
10497 
10498  INTL_NEXT_CHAR (ptr, ptr, codeset, &char_size);
10499  }
10500  else
10501  {
10502  /* backward */
10503  if (ptr > usrc_string_bound)
10504  {
10505  ptr = intl_prev_char (ptr, usrc_string_bound, codeset, &char_size);
10506  }
10507  else
10508  {
10509  break;
10510  }
10511  }
10512  }
10513 
10514  /*
10515  * Return the position of the match, if found.
10516  */
10517  if (result == 0)
10518  {
10519  *position = current_position;
10520  }
10521  }
10522 
10523  return error_status;
10524 }
10525 
10526 /*
10527  * qstr_bit_position () -
10528  *
10529  * Arguments:
10530  * sub_string: String fragment to search for within <src_string>.
10531  * sub_length: Number of characters in sub_string.
10532  * src_string: String to be searched.
10533  * src_length: Number of characters in src_string.
10534  *
10535  * Returns: int
10536  *
10537  * Errors:
10538  *
10539  * Note:
10540  * This function accepts a source string <src_sring> and a string
10541  * string fragment <sub_string> and returns the bit position
10542  * corresponding to the first occurance of <sub_string> within
10543  * <src_string>.
10544  *
10545  */
10546 
10547 static int
10548 qstr_bit_position (const unsigned char *sub_string, int sub_length, const unsigned char *src_string, int src_length,
10549  int *position)
10550 {
10551  int error_status = NO_ERROR;
10552 
10553  *position = 0;
10554 
10555  if (sub_length == 0)
10556  {
10557  *position = 1;
10558  }
10559 
10560  else if (sub_length > src_length)
10561  {
10562  *position = 0;
10563  }
10564 
10565  else
10566  {
10567  int i, num_searches, result;
10568  int sub_size, sub_remainder, shift_amount;
10569  unsigned char *ptr, *tmp_string, tmp_byte, mask;
10570 
10571  num_searches = src_length - sub_length + 1;
10572  sub_size = QSTR_NUM_BYTES (sub_length);
10573 
10574  sub_remainder = sub_length % BYTE_SIZE;
10575  shift_amount = BYTE_SIZE - sub_remainder;
10576  mask = 0xff << shift_amount;
10577 
10578  /*
10579  * We will be manipulating the source string prior to
10580  * comparison. So that we do not corrupt the source string,
10581  * we'll allocate a storage area so that we can make a copy
10582  * of the string. This copy need only be he length of the
10583  * sub-string since that is the limit of the comparison.
10584  */
10585  tmp_string = (unsigned char *) db_private_alloc (NULL, (size_t) sub_size + 1);
10586  if (tmp_string == NULL)
10587  {
10588  assert (er_errid () != NO_ERROR);
10589  error_status = er_errid ();
10590  }
10591  else
10592  {
10593  ptr = (unsigned char *) src_string;
10594 
10595  /*
10596  * Make a copy of the source string.
10597  * Initialize the bit index.
10598  */
10599  (void) memcpy ((char *) tmp_string, (char *) ptr, sub_size);
10600  i = 0;
10601  result = 1;
10602 
10603  while ((i < num_searches) && (result != 0))
10604  {
10605  /* Pad the irrelevant bits of the source string with 0's */
10606  tmp_byte = tmp_string[sub_size - 1];
10607  tmp_string[sub_size - 1] &= mask;
10608 
10609  /* Compare the source string with the sub-string */
10610  result = memcmp (sub_string, tmp_string, sub_size);
10611 
10612  /* Restore the padded byte to its original value */
10613  tmp_string[sub_size - 1] = tmp_byte;
10614 
10615  /* Shift the copied source string left one bit */
10616  (void) shift_left (tmp_string, sub_size);
10617 
10618  i++;
10619 
10620  /*
10621  * Every time we hit a byte boundary,
10622  * Move on to the next byte of the source string.
10623  */
10624  if ((i % BYTE_SIZE) == 0)
10625  {
10626  ptr++;
10627  memcpy (tmp_string, ptr, sub_size);
10628  }
10629  }
10630 
10631 
10632  db_private_free_and_init (NULL, tmp_string);
10633 
10634  /*
10635  * If a match was found, then return the position
10636  * of the match.
10637  */
10638  if (result == 0)
10639  {
10640  *position = i;
10641  }
10642  }
10643  }
10644 
10645  return error_status;
10646 }
10647 
10648 /*
10649  * shift_left () -
10650  *
10651  * Arguments:
10652  * bit_string: Byte array representing a bit string.
10653  * bit_string_size: Number of bytes in the array.
10654  *
10655  * Returns: int
10656  *
10657  * Errors:
10658  *
10659  * Note:
10660  * Shift the bit string left one bit. The left most bit is shifted out
10661  * and returned. A 0 is inserted into the rightmost bit position.
10662  * The entire array is shifted regardless of the number of significant
10663  * bits in the array.
10664  *
10665  */
10666 
10667 static int
10668 shift_left (unsigned char *bit_string, int bit_string_size)
10669 {
10670  int i, highest_bit;
10671 
10672 
10673  highest_bit = ((bit_string[0] & 0x80) != 0);
10674  bit_string[0] = bit_string[0] << 1;
10675 
10676  for (i = 1; i < bit_string_size; i++)
10677  {
10678  if (bit_string[i] & 0x80)
10679  {
10680  bit_string[i - 1] |= 0x01;
10681  }
10682 
10683  bit_string[i] = bit_string[i] << 1;
10684  }
10685 
10686  return highest_bit;
10687 }
10688 
10689 /*
10690  * qstr_substring () -
10691  *
10692  * Arguments:
10693  * src_string: Source string.
10694  * start_position: Starting character position of sub-string.
10695  * extraction_length: Length of sub-string.
10696  * sub_string: Returned sub-string.
10697  *
10698  * Returns: void
10699  *
10700  * Errors:
10701  *
10702  * Note:
10703  * Extract the sub-string from the source string. The sub-string is
10704  * specified by a starting position and length.
10705  *
10706  * This functions works on character and national character strings.
10707  *
10708  */
10709 
10710 static int
10711 qstr_substring (const unsigned char *src, int src_length, int start, int length, INTL_CODESET codeset,
10712  unsigned char **r, int *r_length, int *r_size)
10713 {
10714  int error_status = NO_ERROR;
10715  const unsigned char *sub;
10716  int src_size, leading_bytes;
10717  *r_size = 0;
10718 
10719  /* Get the size of the source string. */
10720  intl_char_size ((unsigned char *) src, src_length, codeset, &src_size);
10721 
10722  /*
10723  * Perform some error chaecking.
10724  * If the starting position is < 1, then set it to 1.
10725  * If the starting position is after the end of the source string,
10726  * then set the sub-string length to 0.
10727  * If the sub-string length will extend beyond the end of the source string,
10728  * then shorten the sub-string length to fit.
10729  */
10730  if (start < 1)
10731  {
10732  start = 1;
10733  }
10734 
10735  if (start > src_length)
10736  {
10737  start = 1;
10738  length = 0;
10739  }
10740 
10741  if ((length < 0) || ((start + length - 1) > src_length))
10742  {
10743  length = src_length - start + 1;
10744  }
10745 
10746  *r_length = length;
10747 
10748  /*
10749  * Get a pointer to the start of the sub-string and the
10750  * size of the sub-string.
10751  *
10752  * Compute the starting byte of the sub-string.
10753  * Compute the length of the sub-string in bytes.
10754  */
10755  intl_char_size ((unsigned char *) src, (start - 1), codeset, &leading_bytes);
10756  sub = &(src[leading_bytes]);
10757  intl_char_size ((unsigned char *) sub, *r_length, codeset, r_size);
10758 
10759  *r = (unsigned char *) db_private_alloc (NULL, (size_t) ((*r_size) + 1));
10760  if (*r == NULL)
10761  {
10762  assert (er_errid () != NO_ERROR);
10763  error_status = er_errid ();
10764  }
10765  else
10766  {
10767  (void) memcpy (*r, sub, *r_size);
10768  }
10769 
10770  return error_status;
10771 }
10772 
10773 /*
10774  * qstr_bit_substring () -
10775  *
10776  * Arguments:
10777  * src_string: Source string.
10778  * start_position: Starting character position of sub-string.
10779  * extraction_length: Length of sub-string.
10780  * sub_string: Returned sub-string.
10781  *
10782  * Returns: void
10783  *
10784  * Errors:
10785  *
10786  * Note:
10787  * Extract the sub-string from the source string. The sub-string is
10788  * specified by a starting position and length.
10789  *
10790  * This functions works on bit strings.
10791  *
10792  */
10793 
10794 static int
10795 qstr_bit_substring (const unsigned char *src, int src_length, int start, int length, unsigned char **r, int *r_length)
10796 {
10797  int src_size, sub_size, rem;
10798  unsigned char trailing_mask;
10799  int error_status = NO_ERROR;
10800 
10801  src_size = QSTR_NUM_BYTES (src_length);
10802 
10803  /*
10804  * Perform some error checking.
10805  * If the starting position is < 1, then set it to 1.
10806  * If the starting position is after the end of the source
10807  * string, then set the sub-string length to 0.
10808  * If the sub-string length will extend beyond the end of the
10809  * source string, then shorten the sub-string length to fit.
10810  */
10811  if (start < 1)
10812  {
10813  start = 1;
10814  }
10815 
10816  if (start > src_length)
10817  {
10818  start = 1;
10819  length = 0;
10820  }
10821 
10822  if ((length < 0) || ((start + length - 1) > src_length))
10823  {
10824  length = src_length - start + 1;
10825  }
10826 
10827  sub_size = QSTR_NUM_BYTES (length);
10828  *r_length = length;
10829 
10830  rem = length % BYTE_SIZE;
10831  if (rem == 0)
10832  {
10833  trailing_mask = 0xff;
10834  }
10835  else
10836  {
10837  trailing_mask = 0xff << (BYTE_SIZE - rem);
10838  }
10839 
10840  /*
10841  * Allocate storage for the sub-string.
10842  * Copy the sub-string.
10843  */
10844  *r = (unsigned char *) db_private_alloc (NULL, (size_t) sub_size + 1);
10845  if (*r == NULL)
10846  {
10847  assert (er_errid () != NO_ERROR);
10848  error_status = er_errid ();
10849  }
10850  else
10851  {
10852  left_nshift (src, src_size, (start - 1), *r, sub_size);
10853  (*r)[sub_size - 1] &= trailing_mask;
10854  }
10855 
10856  return error_status;
10857 }
10858 
10859 /*
10860  * left_nshift () -
10861  *
10862  * Arguments:
10863  * bit_string: Byte array containing the bit string.
10864  * bit_string_size: Size of the bit array in bytes.
10865  * shift_amount: Number of bit positions to shift by.
10866  * range: 0 <= shift_amount
10867  * r: Pointer to result buffer where the shifted bit
10868  * array will be stored.
10869  * r_size: Size of the result array in bytes.
10870  *
10871  * Returns: void
10872  *
10873  * Errors:
10874  *
10875  * Note:
10876  * Shift the bit string left <shift_amount> bits. The left most bits
10877  * are shifted out. 0's are inserted into the rightmost bit positions.
10878  * The entire array is shifted regardless of the number of significant
10879  * bits in the array.
10880  *
10881  */
10882 
10883 static void
10884 left_nshift (const unsigned char *bit_string, int bit_string_size, int shift_amount, unsigned char *r, int r_size)
10885 {
10886  int i, shift_bytes, shift_bits, adj_bit_string_size;
10887  const unsigned char *ptr;
10888 
10889  shift_bytes = shift_amount / BYTE_SIZE;
10890  shift_bits = shift_amount % BYTE_SIZE;
10891  ptr = &(bit_string[shift_bytes]);
10892 
10893  adj_bit_string_size = bit_string_size - shift_bytes;
10894 
10895  for (i = 0; i < r_size; i++)
10896  {
10897  if (i < (adj_bit_string_size - 1))
10898  {
10899  r[i] = ((ptr[i] << shift_bits) | (ptr[i + 1] >> (BYTE_SIZE - shift_bits)));
10900  }
10901  else if (i == (adj_bit_string_size - 1))
10902  {
10903  r[i] = (ptr[i] << shift_bits);
10904  }
10905  else
10906  {
10907  r[i] = 0;
10908  }
10909  }
10910 }
10911 
10912 /*
10913  * The version below handles multibyte character sets by promoting all
10914  * characters to two bytes each. Unfortunately, the current implementation
10915  * of the regular expression package has some limitations with characters
10916  * that are not char sized. The above version works with char sized
10917  * sets only and therefore will not work with national character sets.
10918  */
10919 
10920 /*
10921  * qstr_ffs () -
10922  * Returns: int
10923  * v: (IN) Source string.
10924  *
10925  *
10926  * Errors:
10927  *
10928  * Note:
10929  * Finds the first bit set in the passed argument and returns
10930  * the index of that bit. Bits are numbered starting at 1
10931  * from the right. A return value of 0 indicates that the value
10932  * passed is zero.
10933  *
10934  */
10935 
10936 static int
10937 qstr_ffs (int v)
10938 {
10939  int nbits;
10940 
10941  int i = 0;
10942  int position = 0;
10943  unsigned int uv = (unsigned int) v;
10944 
10945  nbits = sizeof (int) * 8;
10946 
10947  if (uv != 0)
10948  {
10949  while ((i < nbits) && (position == 0))
10950  {
10951  if (uv & 0x01)
10952  {
10953  position = i + 1;
10954  }
10955 
10956  i++;
10957  uv >>= 1;
10958  }
10959  }
10960 
10961  return position;
10962 }
10963 
10964 /*
10965  * hextoi () -
10966  *
10967  * Arguments:
10968  * hex_char: (IN) Character containing ASCII hex character
10969  *
10970  * Returns: int
10971  *
10972  * Errors:
10973  *
10974  * Note:
10975  * Returns the decimal value associated with the ASCII hex character.
10976  * Will return a -1 if hex_char is not a hexadecimal ASCII character.
10977  *
10978  */
10979 
10980 static int
10981 hextoi (char hex_char)
10982 {
10983  if ((hex_char >= '0') && (hex_char <= '9'))
10984  {
10985  return (hex_char - '0');
10986  }
10987  else if ((hex_char >= 'A') && (hex_char <= 'F'))
10988  {
10989  return (hex_char - 'A' + 10);
10990  }
10991  else if ((hex_char >= 'a') && (hex_char <= 'f'))
10992  {
10993  return (hex_char - 'a' + 10);
10994  }
10995  else
10996  {
10997  return (-1);
10998  }
10999 }
11000 
11001 /*
11002  * set_time_argument() - construct struct tm
11003  * return:
11004  * dest(out):
11005  * year(in):
11006  * month(in):
11007  * day(in):
11008  * hour(in):
11009  * min(in):
11010  * sec(in):
11011  */
11012 static void
11013 set_time_argument (struct tm *dest, int year, int month, int day, int hour, int min, int sec)
11014 {
11015  if (year >= 1900)
11016  {
11017  dest->tm_year = year - 1900;
11018  }
11019  else
11020  {
11021  dest->tm_year = -1;
11022  }
11023  dest->tm_mon = month - 1;
11024  dest->tm_mday = day;
11025  dest->tm_hour = hour;
11026  dest->tm_min = min;
11027  dest->tm_sec = sec;
11028  dest->tm_isdst = -1;
11029 }
11030 
11031 /*
11032  * calc_unix_timestamp() - calculates UNIX timestamp
11033  * return:
11034  * time_argument(in):
11035  */
11036 static long
11037 calc_unix_timestamp (struct tm *time_argument)
11038 {
11039  time_t result;
11040 
11041  if (time_argument != NULL)
11042  {
11043  /* validation for tm fields in order to cover for mktime conversion's like 40th of Sept equals 10th of Oct */
11044  if (time_argument->tm_year < 0 || time_argument->tm_year > 9999 || time_argument->tm_mon < 0
11045  || time_argument->tm_mon > 11 || time_argument->tm_mday < 1 || time_argument->tm_mday > 31
11046  || time_argument->tm_hour < 0 || time_argument->tm_hour > 23 || time_argument->tm_min < 0
11047  || time_argument->tm_min > 59 || time_argument->tm_sec < 0 || time_argument->tm_sec > 59)
11048  {
11049  return -1L;
11050  }
11051  result = mktime (time_argument);
11052  }
11053  else
11054  {
11055  result = time (NULL);
11056  }
11057 
11058  if (result < (time_t) 0)
11059  {
11060  return -1L;
11061  }
11062  return (long) result;
11063 }
11064 
11065 #if defined (ENABLE_UNUSED_FUNCTION)
11066 /*
11067  * parse_for_next_int () -
11068  *
11069  * Arguments:
11070  * ch: char position from which we start parsing
11071  * output: integer read
11072  *
11073  * Returns: -1 if error, 0 if success
11074  *
11075  * Note:
11076  * parses a string for integers while skipping non-alpha delimitators
11077  */
11078 static int
11079 parse_for_next_int (char **ch, char *output)
11080 {
11081  int i;
11082  /* we need in fact only 6 (upper bound for the integers we want) */
11083  char buf[16];
11084 
11085  i = 0;
11086  memset (buf, 0, sizeof (buf));
11087 
11088  /* trailing zeroes - accept only 2 (for year 00 which is short for 2000) */
11089  while (**ch == '0')
11090  {
11091  if (i < 2)
11092  {
11093  buf[i++] = **ch;
11094  }
11095  (*ch)++;
11096  }
11097 
11098  while (i < 6 && char_isdigit (**ch) && **ch != 0)
11099  {
11100  buf[i++] = **ch;
11101  (*ch)++;
11102  }
11103  if (i > 6)
11104  {
11105  return -1;
11106  }
11107  strcpy (output, buf);
11108 
11109  /* skip all delimitators */
11110  while (**ch != 0 && !char_isalpha (**ch) && !char_isdigit (**ch))
11111  {
11112  (*ch)++;
11113  }
11114  return 0;
11115 }
11116 #endif
11117 /*
11118  * db_unix_timestamp () -
11119  *
11120  * Arguments:
11121  * src_date: datetime from which we calculate timestamp
11122  *
11123  * Returns: int
11124  *
11125  * Errors:
11126  *
11127  * Note:
11128  * Returns a Unix timestamp (seconds since '1970-01-01 00:00:00' UTC)
11129  */
11130 int
11131 db_unix_timestamp (const DB_VALUE * src_date, DB_VALUE * result_timestamp)
11132 {
11133  DB_TYPE type = DB_TYPE_UNKNOWN;
11134  int error_status = NO_ERROR;
11135  time_t ts = 0;
11136 
11137  if (DB_IS_NULL (src_date))
11138  {
11139  db_make_null (result_timestamp);
11140  return error_status;
11141  }
11142 
11143  type = DB_VALUE_DOMAIN_TYPE (src_date);
11144  switch (type)
11145  {
11146  case DB_TYPE_VARCHAR:
11147  case DB_TYPE_VARNCHAR:
11148  case DB_TYPE_CHAR:
11149  case DB_TYPE_NCHAR:
11150  case DB_TYPE_DATETIME:
11151  case DB_TYPE_DATE:
11152  {
11153  DB_VALUE *dt_tz_p;
11154  DB_VALUE dt;
11155  TP_DOMAIN *tp_datetime;
11156  TP_DOMAIN *tp_datetimetz;
11157  DB_DATETIME datetime;
11158  DB_TIMESTAMP timestamp;
11159  DB_DATE date;
11160 
11161  dt_tz_p = &dt;
11162  if (type != DB_TYPE_DATETIME && type != DB_TYPE_DATE)
11163  {
11164  tp_datetimetz = db_type_to_db_domain (DB_TYPE_DATETIMETZ);
11165 
11166  if (tp_value_cast (src_date, dt_tz_p, tp_datetimetz, false) == DOMAIN_COMPATIBLE)
11167  {
11168  type = DB_TYPE_DATETIMETZ;
11169  }
11170  else
11171  {
11172  tp_datetime = db_type_to_db_domain (DB_TYPE_DATETIME);
11173 
11174  if (tp_value_cast (src_date, dt_tz_p, tp_datetime, false) == DOMAIN_COMPATIBLE)
11175  {
11176  type = DB_TYPE_DATETIME;
11177  /* Clear error from cast to DB_TYPE_DATETIMETZ. */
11178  er_clear ();
11179  }
11180  else
11181  {
11182  error_status = ER_OBJ_INVALID_ARGUMENTS;
11183  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
11184  db_make_null (result_timestamp);
11185  return ER_FAILED;
11186  }
11187  }
11188 
11189  assert (DB_VALUE_TYPE (dt_tz_p) == type);
11190  }
11191  else
11192  {
11193  dt_tz_p = (DB_VALUE *) src_date;
11194  }
11195 
11196  /* The supported datetime range is '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC */
11197 
11198  if (type == DB_TYPE_DATETIMETZ)
11199  {
11200  DB_DATETIMETZ *datetimetz;
11201 
11202  datetimetz = db_get_datetimetz (dt_tz_p);
11203  datetime = datetimetz->datetime;
11204  datetime.time /= 1000;
11205  }
11206  else if (type == DB_TYPE_DATETIME)
11207  {
11208  datetime = *db_get_datetime (dt_tz_p);
11209  datetime.time /= 1000;
11210  }
11211  else
11212  {
11213  assert (type == DB_TYPE_DATE);
11214  date = *db_get_date (dt_tz_p);
11215  datetime.date = date;
11216  datetime.time = 0;
11217  }
11218 
11219  if (type == DB_TYPE_DATE || type == DB_TYPE_DATETIME)
11220  {
11221  error_status = db_timestamp_encode (&timestamp, &datetime.date, &datetime.time);
11222  if (error_status != NO_ERROR)
11223  {
11224  return error_status;
11225  }
11226  }
11227  else
11228  {
11229  assert (type == DB_TYPE_DATETIMETZ);
11230  error_status = db_timestamp_encode_utc (&datetime.date, &datetime.time, &timestamp);
11231  if (error_status != NO_ERROR)
11232  {
11233  return error_status;
11234  }
11235  }
11236 
11237  db_make_int (result_timestamp, timestamp);
11238  return NO_ERROR;
11239  }
11240 
11241  case DB_TYPE_DATETIMETZ:
11242  case DB_TYPE_DATETIMELTZ:
11243  {
11244  DB_DATETIMETZ *datetimetz;
11245  DB_DATETIME datetime;
11246  DB_TIMESTAMP timestamp;
11247 
11248  if (type == DB_TYPE_DATETIMETZ)
11249  {
11250  datetimetz = db_get_datetimetz (src_date);
11251  datetime = datetimetz->datetime;
11252  }
11253  else
11254  {
11255  datetime = *db_get_datetime (src_date);
11256  }
11257 
11258  datetime.time /= 1000;
11259  error_status = db_timestamp_encode_utc (&datetime.date, &datetime.time, &timestamp);
11260  if (error_status != NO_ERROR)
11261  {
11262  return error_status;
11263  }
11264  db_make_int (result_timestamp, timestamp);
11265 
11266  return NO_ERROR;
11267  }
11268 
11269  /* a TIMESTAMP format */
11270  case DB_TYPE_TIMESTAMP:
11271  case DB_TYPE_TIMESTAMPLTZ:
11272  /* The supported timestamp range is '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC */
11273  ts = *db_get_timestamp (src_date);
11274  /* supplementary conversion from long to int will be needed on 64 bit platforms. */
11275  db_make_int (result_timestamp, (int) ts);
11276  return NO_ERROR;
11277 
11278  case DB_TYPE_TIMESTAMPTZ:
11279  {
11280  DB_TIMESTAMPTZ *timestamp_tz;
11281  timestamp_tz = db_get_timestamptz (src_date);
11282  ts = timestamp_tz->timestamp;
11283  db_make_int (result_timestamp, (int) ts);
11284  return NO_ERROR;
11285  }
11286 
11287  default:
11288  db_make_null (result_timestamp);
11290  return ER_FAILED;
11291  }
11292 
11293  db_make_null (result_timestamp);
11295  return ER_FAILED;
11296 }
11297 
11298 /*
11299  * db_datetime_to_timestamp () - create a timestamp DB_VALUE from a datetime
11300  * DB_VALUE
11301  *
11302  * src_datetime(in):
11303  * result_timestamp(in):
11304  * return: ERROR_CODE
11305  */
11306 int
11307 db_datetime_to_timestamp (const DB_VALUE * src_datetime, DB_VALUE * result_timestamp)
11308 {
11309  DB_DATETIME *tmp_datetime;
11310  DB_DATE tmp_date;
11311  DB_TIME tmp_time;
11312  DB_TIMESTAMP tmp_timestamp;
11313  int error;
11314  DB_VALUE temp, *temp_p;
11315  bool same_argument = (src_datetime == result_timestamp);
11316 
11317  if (DB_IS_NULL (src_datetime))
11318  {
11319  db_make_null (result_timestamp);
11320 
11321  return NO_ERROR;
11322  }
11323 
11324  if (same_argument)
11325  {
11326  /* if the result argument is the same with the source argument, then use a temporary value for creating the
11327  * timestamp */
11328  temp_p = &temp;
11329  }
11330  else
11331  {
11332  /* the result_timestamp value can be used and no other temporary values are needed */
11333  temp_p = result_timestamp;
11334  }
11335 
11337  if (error != NO_ERROR)
11338  {
11339  /* error message has been set */
11340  return error;
11341  }
11342 
11343  tmp_datetime = db_get_datetime (src_datetime);
11344  tmp_date = tmp_datetime->date;
11345  tmp_time = tmp_datetime->time / 1000;
11346  error = db_timestamp_encode_ses (&tmp_date, &tmp_time, &tmp_timestamp, NULL);
11347  if (error != NO_ERROR)
11348  {
11349  /* error message has been set */
11350  return error;
11351  }
11352  db_make_timestamp (temp_p, tmp_timestamp);
11353 
11354  if (same_argument)
11355  {
11356  /* if src_datetime was the same with result_timestamp, copy the result from temp, and release the temporary value */
11357  pr_clone_value (temp_p, result_timestamp);
11358  }
11359 
11360  return NO_ERROR;
11361 }
11362 
11363 /*
11364  * db_get_date_dayofyear () - compute day of year from a date type value
11365  *
11366  * Arguments:
11367  * src_date: datetime from which to compute the day of year
11368  *
11369  * Returns: int
11370  */
11371 int
11372 db_get_date_dayofyear (const DB_VALUE * src_date, DB_VALUE * result)
11373 {
11374  int error_status = NO_ERROR;
11375  int month = 0, day = 0, year = 0;
11376  int second = 0, minute = 0, hour = 0;
11377  int ms = 0;
11378  int day_of_year = 0;
11379 
11380  if (DB_IS_NULL (src_date))
11381  {
11382  db_make_null (result);
11383  return NO_ERROR;
11384  }
11385 
11386  /* get the date/time information from src_date */
11387  error_status = db_get_datetime_from_dbvalue (src_date, &year, &month, &day, &hour, &minute, &second, &ms, NULL);
11388  if (error_status != NO_ERROR)
11389  {
11390  error_status = ER_DATE_CONVERSION;
11391  goto error_exit;
11392  }
11393 
11394  if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0 && ms == 0)
11395  {
11396  error_status = ER_ATTEMPT_TO_USE_ZERODATE;
11397  goto error_exit;
11398  }
11399 
11400  day_of_year = db_get_day_of_year (year, month, day);
11401  db_make_int (result, day_of_year);
11402 
11403  return NO_ERROR;
11404 
11405 error_exit:
11406  /* This function should return NULL if src_date is an invalid parameter or Zero date. Clear the error generated by
11407  * the function call and return null. */
11408  er_clear ();
11409  db_make_null (result);
11411  {
11412  return NO_ERROR;
11413  }
11414 
11415  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
11416  return error_status;
11417 }
11418 
11419 #if !defined (SERVER_MODE)
11420 /*
11421  * db_get_date_weekday () - compute day of week from a date type value
11422  *
11423  * Arguments:
11424  * src_date: datetime from which to compute the week day
11425  * mode : the mode in which week days are numbered
11426  * 0 = Monday, ..., 6 = Sunday or
11427  * 1 = Sunday, ..., 7 = Saturday
11428  *
11429  * Returns: int
11430  */
11431 int
11432 db_get_date_weekday (const DB_VALUE * src_date, const int mode, DB_VALUE * result)
11433 {
11434  int error_status = NO_ERROR;
11435  int month = 0, day = 0, year = 0;
11436  int second = 0, minute = 0, hour = 0;
11437  int ms = 0;
11438  int day_of_week = 0;
11439 
11440  if (DB_IS_NULL (src_date))
11441  {
11442  db_make_null (result);
11443  return NO_ERROR;
11444  }
11445 
11446  /* get the date/time information from src_date */
11447  error_status = db_get_datetime_from_dbvalue (src_date, &year, &month, &day, &hour, &minute, &second, &ms, NULL);
11448  if (error_status != NO_ERROR)
11449  {
11450  error_status = ER_DATE_CONVERSION;
11451  goto error_exit;
11452  }
11453 
11454  if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0 && ms == 0)
11455  {
11456  error_status = ER_ATTEMPT_TO_USE_ZERODATE;
11457  goto error_exit;
11458  }
11459 
11460  /* 0 = Sunday, 1 = Monday, etc */
11461  day_of_week = db_get_day_of_week (year, month, day);
11462 
11463  switch (mode)
11464  {
11465  case PT_WEEKDAY:
11466  /* 0 = Monday, 1 = Tuesday, ..., 6 = Sunday */
11467  if (day_of_week == 0)
11468  {
11469  day_of_week = 6;
11470  }
11471  else
11472  {
11473  day_of_week--;
11474  }
11475  db_make_int (result, day_of_week);
11476  break;
11477 
11478  case PT_DAYOFWEEK:
11479  /* 1 = Sunday, 2 = Monday, ..., 7 = Saturday */
11480  day_of_week++;
11481  db_make_int (result, day_of_week);
11482  break;
11483 
11484  default:
11485  assert (false);
11486  db_make_null (result);
11487  break;
11488  }
11489 
11490  return NO_ERROR;
11491 
11492 error_exit:
11493  /* This function should return NULL if src_date is an invalid parameter or zero date. Clear the error generated by
11494  * the function call and return null. */
11495  er_clear ();
11496  db_make_null (result);
11498  {
11499  return NO_ERROR;
11500  }
11501 
11502  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
11503  return error_status;
11504 }
11505 #endif /* !defined (SERVER_MODE) */
11506 
11507 /*
11508  * db_get_date_quarter () - compute quarter from a date type value
11509  *
11510  * Arguments:
11511  * src_date: datetime from which to compute the quarter
11512  *
11513  * Returns: int
11514  */
11515 int
11516 db_get_date_quarter (const DB_VALUE * src_date, DB_VALUE * result)
11517 {
11518  int month = 0, day = 0, year = 0;
11519  int second = 0, minute = 0, hour = 0;
11520  int ms = 0;
11521  char const *endp = NULL;
11522  int retval;
11523 
11524  if (DB_IS_NULL (src_date))
11525  {
11526  db_make_null (result);
11527  return NO_ERROR;
11528  }
11529  /* get the date/time information from src_date */
11530  retval = db_get_datetime_from_dbvalue (src_date, &year, &month, &day, &hour, &minute, &second, &ms, &endp);
11531  if (retval != NO_ERROR || (endp && *endp && !char_isspace (*endp)))
11532  {
11533  er_clear ();
11534  db_make_null (result);
11536  {
11537  return NO_ERROR;
11538  }
11540  return ER_DATE_CONVERSION;
11541  }
11542 
11543  if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0 && ms == 0)
11544  {
11545  /* This function should return 0 if src_date is zero date */
11546  db_make_int (result, 0);
11547  }
11548  /* db_datetime_decode returned NO_ERROR so we can calculate the quarter */
11549  else if (month == 0)
11550  {
11551  assert (false);
11552  db_make_int (result, 0);
11553  }
11554  else if (month < 0 || month > 12)
11555  {
11556  assert (false);
11557  db_make_null (result);
11558  }
11559  else
11560  {
11561  const int quarter = (month - 1) / 3 + 1;
11562  db_make_int (result, quarter);
11563  }
11564 
11565  return NO_ERROR;
11566 }
11567 
11568 /*
11569  * db_get_date_totaldays () - compute the number of days from the date 0 AD
11570  * until the day represented by src_date
11571  *
11572  * Arguments:
11573  * src_date: datetime from which to compute the number of days
11574  *
11575  * Returns: int
11576  */
11577 int
11578 db_get_date_totaldays (const DB_VALUE * src_date, DB_VALUE * result)
11579 {
11580  int error_status = NO_ERROR;
11581  int month = 0, day = 0, year = 0;
11582  int second = 0, minute = 0, hour = 0;
11583  int ms = 0;
11584  int leap_years = 0, total_days = 0, days_this_year = 0;
11585 
11586  if (DB_IS_NULL (src_date))
11587  {
11588  db_make_null (result);
11589  return NO_ERROR;
11590  }
11591 
11592  /* get the date/time information from src_date */
11593  error_status = db_get_datetime_from_dbvalue (src_date, &year, &month, &day, &hour, &minute, &second, &ms, NULL);
11594  if (error_status != NO_ERROR)
11595  {
11596  error_status = ER_DATE_CONVERSION;
11597  goto error_exit;
11598  }
11599 
11600  if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0 && ms == 0)
11601  {
11602  error_status = ER_ATTEMPT_TO_USE_ZERODATE;
11603  goto error_exit;
11604  }
11605 
11606  leap_years = count_leap_years_up_to (year - 1);
11607  days_this_year = db_get_day_of_year (year, month, day);
11608  total_days = year * 365 + leap_years + days_this_year;
11609  db_make_int (result, total_days);
11610 
11611  return NO_ERROR;
11612 
11613 error_exit:
11614  er_clear ();
11615  db_make_null (result);
11617  {
11618  return NO_ERROR;
11619  }
11620 
11621  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
11622  return error_status;
11623 }
11624 
11625 /*
11626  * db_get_date_from_days () - computes a date by adding the number of days
11627  * represented by src to the year 0 AD
11628  *
11629  * Arguments:
11630  * src: number from which to compute the date
11631  *
11632  * Returns: date
11633  */
11634 int
11635 db_get_date_from_days (const DB_VALUE * src, DB_VALUE * result)
11636 {
11637  int year = 0;
11638  int month = 0;
11639  int day = 0;
11640  int week = 0;
11641  int int_value = 0;
11642  int julian_day = 0;
11643 
11644  if (DB_IS_NULL (src))
11645  {
11646  db_make_null (result);
11647  return NO_ERROR;
11648  }
11649 
11650  if (db_round_dbvalue_to_int (src, &int_value) != NO_ERROR)
11651  {
11652  int_value = 0;
11653  }
11654 
11655  /* The count should start from day 0001-01-01. Because year 0 is considered special, this function should return
11656  * 0000-00-00 for less than 366 days */
11657  if (int_value < 366)
11658  {
11659  db_make_date (result, 0, 0, 0);
11660  return NO_ERROR;
11661  }
11662 
11663  julian_day = julian_encode (1, 1, 1);
11664 
11665  /* Subtract 364 from the Julian Day to start counting from 0001-01-01 */
11666  julian_day += int_value - 364;
11667 
11668  julian_decode (julian_day, &month, &day, &year, &week);
11669 
11670  if (year > 9999)
11671  {
11672  db_make_date (result, 0, 0, 0);
11673  return NO_ERROR;
11674  }
11675 
11676  db_make_date (result, month, day, year);
11677  return NO_ERROR;
11678 }
11679 
11680 /*
11681  * db_add_days_to_year () - computes a date by adding the number of days
11682  * contained in src_days to the date 01/01/src_year
11683  *
11684  * Arguments:
11685  * src_year: the year to add days to
11686  * src_days: the number of days to add
11687  *
11688  * Returns: date
11689  */
11690 int
11691 db_add_days_to_year (const DB_VALUE * src_year, const DB_VALUE * src_days, DB_VALUE * result)
11692 {
11693  int year_value = 0;
11694  int days_value = 0;
11695  int julian_day = 0;
11696  int year = 0, month = 0, day = 0, week = 0;
11697 
11698  if (DB_IS_NULL (src_year) || DB_IS_NULL (src_days))
11699  {
11700  db_make_null (result);
11701  return NO_ERROR;
11702  }
11703 
11704  if (db_round_dbvalue_to_int (src_year, &year_value) != NO_ERROR)
11705  {
11706  goto error;
11707  }
11708 
11709  if (db_round_dbvalue_to_int (src_days, &days_value) != NO_ERROR)
11710  {
11711  goto error;
11712  }
11713 
11714  /* days<=0 or year_value <0 are invalid values */
11715  if (days_value <= 0 || year_value < 0)
11716  {
11717  goto error;
11718  }
11719 
11720  /* correct the year value by applying the following rules: - if 0 <= year <= 69 then consider year as 20yy (e.g.: 33
11721  * is 2033) - if 70 <= year <= 99 then consider year as 19yy (e.g.: 71 is 1971) */
11722  if (year_value < 70)
11723  {
11724  year_value += 2000;
11725  }
11726  else if (year_value >= 70 && year_value < 100)
11727  {
11728  year_value += 1900;
11729  }
11730 
11731  julian_day = julian_encode (1, 1, year_value);
11732  julian_day += days_value - 1;
11733  julian_decode (julian_day, &month, &day, &year, &week);
11734 
11735  if (year > 9999)
11736  {
11737  goto error;
11738  }
11739 
11740  db_make_date (result, month, day, year);
11741  return NO_ERROR;
11742 
11743 error:
11744  db_make_null (result);
11745 
11747  {
11748  er_clear ();
11749  return NO_ERROR;
11750  }
11751 
11753  return ER_DATE_CONVERSION;
11754 }
11755 
11756 /*
11757  * db_convert_to_time () - creates a time value from the given hour, minute,
11758  * second
11759  *
11760  * Arguments:
11761  * src_hour: the hour
11762  * src_minute: the minute
11763  * src_second: the second
11764  *
11765  * Returns: date
11766  */
11767 int
11768 db_convert_to_time (const DB_VALUE * src_hour, const DB_VALUE * src_minute, const DB_VALUE * src_second,
11769  DB_VALUE * result)
11770 {
11771  int hour = 0, minute = 0, second = 0;
11772 
11773  if (DB_IS_NULL (src_hour) || DB_IS_NULL (src_minute) || DB_IS_NULL (src_second))
11774  {
11775  db_make_null (result);
11776  return NO_ERROR;
11777  }
11778 
11779  if (db_round_dbvalue_to_int (src_hour, &hour) != NO_ERROR || db_round_dbvalue_to_int (src_minute, &minute) != NO_ERROR
11780  || db_round_dbvalue_to_int (src_second, &second) != NO_ERROR)
11781  {
11782  goto error;
11783  }
11784 
11785  if (minute >= 60 || minute < 0 || second >= 60 || second < 0 || hour >= 24 || hour < 0)
11786  {
11787  goto error;
11788  }
11789 
11790  db_make_time (result, hour, minute, second);
11791  return NO_ERROR;
11792 
11793 error:
11794  db_make_null (result);
11795 
11797  {
11798  er_clear ();
11799  return NO_ERROR;
11800  }
11801 
11803  return ER_TIME_CONVERSION;
11804 }
11805 
11806 /*
11807  * db_convert_sec_to_time() - convert a value that represents a number of
11808  * seconds into a time value
11809  * (hours:minutes:seconds)
11810  *
11811  * Arguments:
11812  * src : value to be converted to the time value
11813  *
11814  * Returns: int
11815  *
11816  * Note:
11817  * This function returns values in the interval 00:00:00, 23:59:59. If the
11818  * value passed as argument does not fall in this interval then this function
11819  * returns the nearest interval limit.
11820  *
11821  */
11822 int
11824 {
11825  int hours = 0;
11826  int minutes = 0;
11827  int seconds = 0;
11828  int int_value = 0;
11829  int err;
11830 
11831  if (DB_IS_NULL (src))
11832  {
11833  db_make_null (result);
11834  return NO_ERROR;
11835  }
11836 
11837  err = db_round_dbvalue_to_int (src, &int_value);
11838  if (err != NO_ERROR)
11839  {
11840  int_value = 0;
11841  }
11842 
11843  if (int_value < 0 || err == ER_OUT_OF_VIRTUAL_MEMORY)
11844  {
11845  goto error;
11846  }
11847 
11848  hours = int_value / 3600;
11849  minutes = (int_value - hours * 3600) / 60;
11850  seconds = int_value % 60;
11851 
11852  if (hours > 23)
11853  {
11854  goto error;
11855  }
11856 
11857  db_make_time (result, hours, minutes, seconds);
11858  return NO_ERROR;
11859 
11860 error:
11861  db_make_null (result);
11862 
11864  {
11865  er_clear ();
11866  return NO_ERROR;
11867  }
11868 
11870  return ER_TIME_CONVERSION;
11871 }
11872 
11873 /*
11874  * db_convert_time_to_sec () - compute the number of seconds that have elapsed
11875  * since 00:00:00 to a given time
11876  *
11877  * Arguments:
11878  * src_date: time from which to compute the number of seconds
11879  *
11880  * Returns: int
11881  */
11882 int
11883 db_convert_time_to_sec (const DB_VALUE * src_date, DB_VALUE * result)
11884 {
11885  int error_status = NO_ERROR;
11886  int second = 0, minute = 0, hour = 0, millisecond = 0;
11887  int total_seconds = 0;
11888 
11889  if (DB_IS_NULL (src_date))
11890  {
11891  db_make_null (result);
11892  return NO_ERROR;
11893  }
11894 
11895  error_status = db_get_time_from_dbvalue (src_date, &hour, &minute, &second, &millisecond);
11896  if (error_status != NO_ERROR)
11897  {
11898  er_clear ();
11899  db_make_null (result);
11900 
11902  {
11903  return NO_ERROR;
11904  }
11906  return ER_TIME_CONVERSION;
11907  }
11908 
11909  total_seconds = hour * 3600 + minute * 60 + second;
11910  db_make_int (result, total_seconds);
11911 
11912  return NO_ERROR;
11913 }
11914 
11915 /*
11916  * db_round_dbvalue_to_int() - converts a db value to an integer rounding the
11917  * value to the nearest integer
11918  *
11919  * Arguments:
11920  * src : value to be converted to int
11921  * Return: NO_ERROR or error code.
11922  * Note: for string source values the function will return the converted
11923  * number or 0 otherwise.
11924  */
11925 static int
11926 db_round_dbvalue_to_int (const DB_VALUE * src, int *result)
11927 {
11928  DB_TYPE src_type = DB_VALUE_DOMAIN_TYPE (src);
11929 
11930  switch (src_type)
11931  {
11932  case DB_TYPE_SMALLINT:
11933  *result = db_get_short (src);
11934  return NO_ERROR;
11935 
11936  case DB_TYPE_INTEGER:
11937  *result = db_get_int (src);
11938  return NO_ERROR;
11939 
11940  case DB_TYPE_FLOAT:
11941  {
11942  float x = db_get_float (src);
11943  *result = (int) ((x) > 0 ? ((x) + .5) : ((x) - .5));
11944  return NO_ERROR;
11945  }
11946 
11947  case DB_TYPE_DOUBLE:
11948  {
11949  double x = db_get_double (src);
11950  *result = (int) ((x) > 0 ? ((x) + .5) : ((x) - .5));
11951  return NO_ERROR;
11952  }
11953 
11954  case DB_TYPE_NUMERIC:
11955  {
11956  double x = 0;
11958  *result = (int) ((x) > 0 ? ((x) + .5) : ((x) - .5));
11959  return NO_ERROR;
11960  }
11961 
11962  case DB_TYPE_BIGINT:
11963  *result = (int) db_get_bigint (src);
11964  return NO_ERROR;
11965 
11966  case DB_TYPE_MONETARY:
11967  {
11968  double x = (db_get_monetary (src))->amount;
11969  *result = (int) ((x) > 0 ? ((x) + .5) : ((x) - .5));
11970  return NO_ERROR;
11971  }
11972 
11973  case DB_TYPE_STRING:
11974  case DB_TYPE_CHAR:
11975  case DB_TYPE_VARNCHAR:
11976  case DB_TYPE_NCHAR:
11977  {
11978  double x;
11979  DB_VALUE val;
11980  int error_status = tp_value_string_to_double (src, &val);
11981 
11982  if (error_status != NO_ERROR)
11983  {
11984  return error_status;
11985  }
11986 
11987  x = db_get_double (&val);
11988  *result = (int) ((x) > 0 ? ((x) + .5) : ((x) - .5));
11989  return NO_ERROR;
11990  }
11991 
11992  case DB_TYPE_DATE:
11993  {
11994  /* convert the date to yyyymmdd as integer */
11995  int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
11996  int ms = 0;
11997  if (db_get_datetime_from_dbvalue (src, &year, &month, &day, &hour, &second, &minute, &ms, NULL) != NO_ERROR)
11998  {
11999  er_clear ();
12000  *result = 0;
12001  }
12002  else
12003  {
12004  *result = (int) (year * 10000 * month * 100 * day);
12005  }
12006  return NO_ERROR;
12007  }
12008  case DB_TYPE_DATETIME:
12009  case DB_TYPE_TIMESTAMP:
12010  {
12011  /* convert the date to yyyymmddhhmmss as integer */
12012  int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
12013  int ms = 0;
12014 
12015  if (db_get_datetime_from_dbvalue (src, &year, &month, &day, &hour, &second, &minute, &ms, NULL) != NO_ERROR)
12016  {
12017  er_clear ();
12018  *result = 0;
12019  return ER_FAILED;
12020  }
12021 
12022  *result = (int) (year * 10000000000 + month * 100000000 + day * 1000000 + hour * 10000 + minute * 100 + second);
12023  return NO_ERROR;
12024  }
12025 
12026  case DB_TYPE_TIME:
12027  {
12028  int hour = 0, minute = 0, second = 0, millisecond = 0;
12029  if (db_get_time_from_dbvalue (src, &hour, &minute, &second, &millisecond) != NO_ERROR)
12030  {
12031  er_clear ();
12032  *result = 0;
12033  return ER_FAILED;
12034  }
12035 
12036  *result = hour * 10000 + minute * 100 + second;
12037  return NO_ERROR;
12038  }
12039 
12040  default:
12041  *result = 0;
12042  return ER_FAILED;
12043  }
12044 
12045  *result = 0;
12046  return ER_FAILED;
12047 }
12048 
12049 /*
12050  * db_get_date_week () - compute the week number of a given date time
12051  *
12052  * Arguments:
12053  * src_date: datetime from which to compute the week number
12054  * mode: specifies the mode in which to count the weeks
12055  *
12056  * Returns: int
12057  */
12058 int
12059 db_get_date_week (const DB_VALUE * src_date, const DB_VALUE * mode, DB_VALUE * result)
12060 {
12061  int error_status = NO_ERROR;
12062  int month = 0, day = 0, year = 0;
12063  int second = 0, minute = 0, hour = 0;
12064  int ms = 0;
12066  int week_number = 0;
12067 
12068  if (DB_IS_NULL (src_date))
12069  {
12070  db_make_null (result);
12071  return NO_ERROR;
12072  }
12073 
12074  /* get the date/time information from src_date */
12075  error_status = db_get_datetime_from_dbvalue (src_date, &year, &month, &day, &hour, &minute, &second, &ms, NULL);
12076  if (error_status != NO_ERROR)
12077  {
12078  error_status = ER_DATE_CONVERSION;
12079  goto error_exit;
12080  }
12081 
12082  if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0 && ms == 0)
12083  {
12084  error_status = ER_ATTEMPT_TO_USE_ZERODATE;
12085  goto error_exit;
12086  }
12087 
12088  if (DB_IS_NULL (mode))
12089  {
12091  }
12092  else
12093  {
12094  error_status = db_round_dbvalue_to_int (mode, &calc_mode);
12095  if (error_status != NO_ERROR)
12096  {
12097  error_status = ER_DATE_CONVERSION;
12098  goto error_exit;
12099  }
12100  }
12101  /* check boundaries for calc_mode */
12102  if (calc_mode < 0 || calc_mode > 7)
12103  {
12104  error_status = ER_DATE_CONVERSION;
12105  goto error_exit;
12106  }
12107 
12108  week_number = db_get_week_of_year (year, month, day, calc_mode);
12109 
12110  db_make_int (result, week_number);
12111  return NO_ERROR;
12112 
12113 error_exit:
12114  er_clear ();
12115  db_make_null (result);
12117  {
12118  return NO_ERROR;
12119  }
12120 
12121  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
12122  return error_status;
12123 }
12124 
12125 #if !defined (SERVER_MODE)
12126 /*
12127  * db_get_date_item () - compute an item from a datetime value
12128  *
12129  * Arguments:
12130  * src_date: datetime from which to calculate the item
12131  * item_type: one of year, month, day
12132  *
12133  * Returns: int
12134  */
12135 int
12136 db_get_date_item (const DB_VALUE * src_date, const int item_type, DB_VALUE * result)
12137 {
12138  int month = 0, day = 0, year = 0;
12139  int second = 0, minute = 0, hour = 0;
12140  int ms = 0;
12141 
12142  if (DB_IS_NULL (src_date))
12143  {
12144  db_make_null (result);
12145  return NO_ERROR;
12146  }
12147 
12148  /* get the date/time information from src_date */
12149  if (db_get_datetime_from_dbvalue (src_date, &year, &month, &day, &hour, &minute, &second, &ms, NULL) != NO_ERROR)
12150  {
12151  /* This function should return NULL if src_date is an invalid parameter. Clear the error generated by the
12152  * function call and return null. */
12153  er_clear ();
12154  db_make_null (result);
12156  {
12157  return NO_ERROR;
12158  }
12159  /* set ER_DATE_CONVERSION */
12161  return ER_DATE_CONVERSION;
12162  }
12163 
12164  switch (item_type)
12165  {
12166  case PT_YEARF:
12167  db_make_int (result, year);
12168  break;
12169  case PT_MONTHF:
12170  db_make_int (result, month);
12171  break;
12172  case PT_DAYF:
12173  db_make_int (result, day);
12174  break;
12175  default:
12176  assert (false);
12177  db_make_null (result);
12178  break;
12179  }
12180 
12181  return NO_ERROR;
12182 }
12183 
12184 /*
12185  * db_get_time_item () - compute an item from a datetime value
12186  *
12187  * Arguments:
12188  * src_date: datetime from which to calculate the item
12189  * item_type: one of hour, minute, second
12190  *
12191  * Returns: int
12192  */
12193 int
12194 db_get_time_item (const DB_VALUE * src_date, const int item_type, DB_VALUE * result)
12195 {
12196  int second = 0, minute = 0, hour = 0, millisecond = 0;
12197 
12198  if (DB_IS_NULL (src_date))
12199  {
12200  db_make_null (result);
12201  return NO_ERROR;
12202  }
12203 
12204  if (db_get_time_from_dbvalue (src_date, &hour, &minute, &second, &millisecond) != NO_ERROR)
12205  {
12206  er_clear ();
12207  db_make_null (result);
12209  {
12210  return NO_ERROR;
12211  }
12213  return ER_TIME_CONVERSION;
12214  }
12215 
12216  switch (item_type)
12217  {
12218  case PT_HOURF:
12219  db_make_int (result, hour);
12220  break;
12221  case PT_MINUTEF:
12222  db_make_int (result, minute);
12223  break;
12224  case PT_SECONDF:
12225  db_make_int (result, second);
12226  break;
12227  default:
12228  assert (false);
12229  db_make_null (result);
12230  break;
12231  }
12232 
12233  return NO_ERROR;
12234 }
12235 #endif /* !defined (SERVER_MODE) */
12236 
12237 /*
12238  * db_time_format ()
12239  *
12240  * Arguments:
12241  * time_value: time from which we get the informations
12242  * format: format specifiers string
12243  * result: output string
12244  * domain: domain of result
12245  *
12246  * Returns: int
12247  *
12248  * Errors:
12249  *
12250  * Note:
12251  * This is used like the DATE_FORMAT() function, but the format
12252  * string may contain format specifiers only for hours, minutes, seconds, and
12253  * milliseconds. Other specifiers produce a NULL value or 0.
12254  */
12255 int
12256 db_time_format (const DB_VALUE * src_value, const DB_VALUE * format, const DB_VALUE * date_lang, DB_VALUE * result,
12257  const TP_DOMAIN * domain)
12258 {
12259  DB_TIME db_time, *t_p;
12260  DB_TIMESTAMP *ts_p;
12261  DB_DATETIME *dt_p;
12262  DB_DATE db_date;
12263  DB_TYPE res_type, format_type;
12264  const char *format_s, *strend;
12265  char *res, *res2;
12266  int format_s_len;
12267  int error_status = NO_ERROR, len;
12268  int h, mi, s, ms, year, month, day;
12269  char format_specifiers[256][64];
12270  int is_date, is_datetime, is_timestamp, is_time;
12271  char och = -1, ch;
12272  INTL_LANG date_lang_id;
12273  const LANG_LOCALE_DATA *lld;
12274  bool dummy;
12275  INTL_CODESET codeset;
12276  int res_collation;
12277  char tzr[TZR_SIZE + 1], tzd[TZ_DS_STRING_SIZE + 1];
12278  char hours_or_minutes[4];
12279  int tzh = 0, tzm = 0;
12280  bool is_valid_tz = false;
12281  DB_VALUE new_time_value;
12282  const DB_VALUE *time_value = src_value;
12283  const TP_DOMAIN *new_domain = tp_domain_resolve_default (DB_TYPE_VARCHAR);
12284  TP_DOMAIN_STATUS status;
12285 
12286  is_date = is_datetime = is_timestamp = is_time = 0;
12287  h = mi = s = ms = 0;
12288  tzr[0] = '\0';
12289  tzd[0] = '\0';
12290  memset (hours_or_minutes, 0, sizeof (hours_or_minutes));
12291  memset (format_specifiers, 0, sizeof (format_specifiers));
12292 
12293  res = NULL;
12294  res2 = NULL;
12295 
12296  db_make_null (&new_time_value);
12297 
12298  if (time_value == NULL || format == NULL || DB_IS_NULL (time_value) || DB_IS_NULL (format))
12299  {
12300  db_make_null (result);
12301  goto error;
12302  }
12303 
12304  assert (DB_VALUE_TYPE (date_lang) == DB_TYPE_INTEGER);
12305  date_lang_id = lang_get_lang_id_from_flag (db_get_int (date_lang), &dummy, &dummy);
12306  if (domain != NULL && domain->collation_flag != TP_DOMAIN_COLL_LEAVE)
12307  {
12308  codeset = TP_DOMAIN_CODESET (domain);
12309  res_collation = TP_DOMAIN_COLLATION (domain);
12310  }
12311  else
12312  {
12313  codeset = db_get_string_codeset (format);
12314  res_collation = db_get_string_collation (format);
12315  }
12316 
12317  lld = lang_get_specific_locale (date_lang_id, codeset);
12318  if (lld == NULL)
12319  {
12320  error_status = ER_LANG_CODESET_NOT_AVAILABLE;
12321  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 2, lang_get_lang_name_from_id (date_lang_id),
12322  lang_charset_name (codeset));
12323  goto error;
12324  }
12325 
12326  res_type = DB_VALUE_DOMAIN_TYPE (time_value);
12327 
12328  if ((res_type == DB_TYPE_DATE) || !(TP_IS_DATE_OR_TIME_TYPE (res_type) || TP_IS_CHAR_TYPE (res_type)))
12329  {
12330  status = tp_value_auto_cast (time_value, &new_time_value, new_domain);
12331  if (status != DOMAIN_COMPATIBLE)
12332  {
12333  error_status = ER_QSTR_INVALID_DATA_TYPE;
12334  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
12335  goto error;
12336  }
12337  time_value = &new_time_value;
12338  }
12339 
12340  res_type = DB_VALUE_DOMAIN_TYPE (time_value);
12341 
12342  /* 1. Get date values */
12343  switch (res_type)
12344  {
12345  case DB_TYPE_TIMESTAMP:
12346  {
12347  TZ_ID tz_id;
12348 
12349  ts_p = db_get_timestamp (time_value);
12350  error_status = tz_create_session_tzid_for_timestamp (ts_p, &tz_id);
12351  if (error_status != NO_ERROR)
12352  {
12353  goto error;
12354  }
12355 
12356  (void) db_timestamp_decode_ses (ts_p, &db_date, &db_time);
12357  db_time_decode (&db_time, &h, &mi, &s);
12358 
12359  error_status = tz_explain_tz_id (&tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
12360  if (error_status != NO_ERROR)
12361  {
12362  goto error;
12363  }
12364  is_valid_tz = true;
12365  }
12366  break;
12367 
12368  case DB_TYPE_TIMESTAMPTZ:
12369  {
12370  DB_TIMESTAMPTZ *tsmp_tz;
12371  DB_DATE date;
12372  DB_TIME time;
12373 
12374  tsmp_tz = db_get_timestamptz (time_value);
12375  error_status = db_timestamp_decode_w_tz_id (&tsmp_tz->timestamp, &tsmp_tz->tz_id, &date, &time);
12376  if (error_status != NO_ERROR)
12377  {
12378  goto error;
12379  }
12380 
12381  db_time_decode (&time, &h, &mi, &s);
12382  error_status = tz_explain_tz_id (&tsmp_tz->tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
12383  if (error_status != NO_ERROR)
12384  {
12385  goto error;
12386  }
12387  is_valid_tz = true;
12388  }
12389  break;
12390 
12391  case DB_TYPE_TIMESTAMPLTZ:
12392  {
12393  DB_TIMESTAMP *tsmp;
12394  DB_DATE date;
12395  DB_TIME time;
12396  TZ_ID tz_id;
12397 
12398  tsmp = db_get_timestamp (time_value);
12399  error_status = tz_create_session_tzid_for_timestamp (tsmp, &tz_id);
12400 
12401  if (error_status != NO_ERROR)
12402  {
12403  goto error;
12404  }
12405  error_status = db_timestamp_decode_w_tz_id (tsmp, &tz_id, &date, &time);
12406  if (error_status != NO_ERROR)
12407  {
12408  goto error;
12409  }
12410 
12411  db_time_decode (&time, &h, &mi, &s);
12412  error_status = tz_explain_tz_id (&tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
12413  if (error_status != NO_ERROR)
12414  {
12415  goto error;
12416  }
12417  is_valid_tz = true;
12418  }
12419  break;
12420 
12421  case DB_TYPE_DATETIME:
12422  {
12423  TZ_ID tz_id;
12424 
12425  dt_p = db_get_datetime (time_value);
12426  error_status = tz_create_session_tzid_for_datetime (dt_p, true, &tz_id);
12427  if (error_status != NO_ERROR)
12428  {
12429  goto error;
12430  }
12431  db_datetime_decode (dt_p, &month, &day, &year, &h, &mi, &s, &ms);
12432  error_status = tz_explain_tz_id (&tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
12433  if (error_status != NO_ERROR)
12434  {
12435  goto error;
12436  }
12437  is_valid_tz = true;
12438  }
12439  break;
12440 
12441  case DB_TYPE_DATETIMETZ:
12442  {
12443  DB_DATETIME dt_local;
12444  DB_DATETIMETZ *dt_tz;
12445 
12446  dt_tz = db_get_datetimetz (time_value);
12447  error_status = tz_utc_datetimetz_to_local (&dt_tz->datetime, &dt_tz->tz_id, &dt_local);
12448  if (error_status != NO_ERROR)
12449  {
12450  goto error;
12451  }
12452  db_datetime_decode (&dt_local, &month, &day, &year, &h, &mi, &s, &ms);
12453 
12454  error_status = tz_explain_tz_id (&dt_tz->tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
12455  if (error_status != NO_ERROR)
12456  {
12457  goto error;
12458  }
12459  is_valid_tz = true;
12460  }
12461  break;
12462 
12463  case DB_TYPE_DATETIMELTZ:
12464  {
12465  DB_DATETIME *dt, dt_local;
12466  TZ_ID tz_id;
12467 
12468  dt = db_get_datetime (time_value);
12469  error_status = tz_create_session_tzid_for_datetime (dt, true, &tz_id);
12470  if (error_status != NO_ERROR)
12471  {
12472  goto error;
12473  }
12474 
12475  error_status = tz_utc_datetimetz_to_local (dt, &tz_id, &dt_local);
12476  if (error_status != NO_ERROR)
12477  {
12478  goto error;
12479  }
12480  db_datetime_decode (&dt_local, &month, &day, &year, &h, &mi, &s, &ms);
12481 
12482  error_status = tz_explain_tz_id (&tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
12483  if (error_status != NO_ERROR)
12484  {
12485  goto error;
12486  }
12487 
12488  is_valid_tz = true;
12489  }
12490  break;
12491 
12492 
12493  case DB_TYPE_TIME:
12494  {
12495  TZ_ID tz_id;
12496 
12497  t_p = db_get_time (time_value);
12498 
12499  error_status = tz_create_session_tzid_for_time (t_p, true, &tz_id);
12500  if (error_status != NO_ERROR)
12501  {
12502  goto error;
12503  }
12504 
12505  db_time_decode (t_p, &h, &mi, &s);
12506  error_status = tz_explain_tz_id (&tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
12507  if (error_status != NO_ERROR)
12508  {
12509  goto error;
12510  }
12511  is_valid_tz = true;
12512  }
12513  break;
12514 
12515  case DB_TYPE_STRING:
12516  case DB_TYPE_VARNCHAR:
12517  case DB_TYPE_CHAR:
12518  case DB_TYPE_NCHAR:
12519  {
12520  DB_VALUE tm;
12522  bool is_time = false;
12523 
12524  if (tp_value_cast (time_value, &tm, tp_time, false) == DOMAIN_COMPATIBLE)
12525  {
12526  db_time_decode (db_get_time (&tm), &h, &mi, &s);
12527  is_time = true;
12528  }
12529 
12530  if (is_time == false)
12531  {
12532  error_status = ER_QSTR_INVALID_DATA_TYPE;
12533  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
12534  goto error;
12535  }
12536  }
12537  break;
12538 
12539  default:
12540  error_status = ER_QSTR_INVALID_DATA_TYPE;
12541  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
12542  goto error;
12543  }
12544 
12545  pr_clear_value (&new_time_value);
12546 
12547  /* 2. Compute the value for each format specifier */
12548  if (mi < 0)
12549  {
12550  mi = -mi;
12551  }
12552  if (s < 0)
12553  {
12554  s = -s;
12555  }
12556  if (ms < 0)
12557  {
12558  ms = -ms;
12559  }
12560 
12561  /* %f Milliseconds (000..999) */
12562  sprintf (format_specifiers['f'], "%03d", ms);
12563 
12564  /* %H Hour (00..23) */
12565  if (h < 0)
12566  {
12567  sprintf (format_specifiers['H'], "-%02d", -h);
12568  }
12569  else
12570  {
12571  sprintf (format_specifiers['H'], "%02d", h);
12572  }
12573  if (h < 0)
12574  {
12575  h = -h;
12576  }
12577 
12578  /* %h Hour (01..12) */
12579  sprintf (format_specifiers['h'], "%02d", (h % 12 == 0) ? 12 : (h % 12));
12580 
12581  /* %I Hour (01..12) */
12582  sprintf (format_specifiers['I'], "%02d", (h % 12 == 0) ? 12 : (h % 12));
12583 
12584  /* %i Minutes, numeric (00..59) */
12585  sprintf (format_specifiers['i'], "%02d", mi);
12586 
12587  /* %k Hour (0..23) */
12588  sprintf (format_specifiers['k'], "%d", h);
12589 
12590  /* %l Hour (1..12) */
12591  sprintf (format_specifiers['l'], "%d", (h % 12 == 0) ? 12 : (h % 12));
12592 
12593  /* %p AM or PM */
12594  strcpy (format_specifiers['p'], (h > 11) ? lld->am_pm[PM_NAME] : lld->am_pm[AM_NAME]);
12595 
12596  /* %r Time, 12-hour (hh:mm:ss followed by AM or PM) */
12597  sprintf (format_specifiers['r'], "%02d:%02d:%02d %s", (h % 12 == 0) ? 12 : (h % 12), mi, s,
12598  (h > 11) ? lld->am_pm[PM_NAME] : lld->am_pm[AM_NAME]);
12599 
12600  /* %S Seconds (00..59) */
12601  sprintf (format_specifiers['S'], "%02d", s);
12602 
12603  /* %s Seconds (00..59) */
12604  sprintf (format_specifiers['s'], "%02d", s);
12605 
12606  /* %T Time, 24-hour (hh:mm:ss) */
12607  sprintf (format_specifiers['T'], "%02d:%02d:%02d", h, mi, s);
12608 
12609  /* 3. Generate the output according to the format and the values */
12610  format_type = DB_VALUE_DOMAIN_TYPE (format);
12611  switch (format_type)
12612  {
12613  case DB_TYPE_STRING:
12614  case DB_TYPE_VARNCHAR:
12615  case DB_TYPE_CHAR:
12616  case DB_TYPE_NCHAR:
12617  format_s = db_get_string (format);
12618  format_s_len = db_get_string_size (format);
12619  break;
12620 
12621  default:
12622  /* we should not get a nonstring format */
12623  assert (false);
12624  error_status = ER_FAILED;
12625  goto error;
12626  }
12627 
12628  len = 1024;
12629  res = (char *) db_private_alloc (NULL, len);
12630  if (!res)
12631  {
12632  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
12633  goto error;
12634  }
12635  memset (res, 0, len);
12636 
12637  ch = *format_s;
12638  strend = format_s + format_s_len;
12639 
12640  while (format_s < strend)
12641  {
12642  format_s++;
12643  och = ch;
12644  ch = *format_s;
12645 
12646  if (och == '%' /* && (res[strlen(res) - 1] != '%') */ )
12647  {
12648  if (ch == '%')
12649  {
12650  STRCHCAT (res, '%');
12651 
12652  /* jump a character */
12653  format_s++;
12654  och = ch;
12655  ch = *format_s;
12656 
12657  continue;
12658  }
12659 
12660  if (ch == 'T' && format_s + 2 < strend && *(format_s + 1) == 'Z'
12661  && (*(format_s + 2) == 'R' || *(format_s + 2) == 'D' || *(format_s + 2) == 'H' || *(format_s + 2) == 'M'))
12662  {
12663  if (is_valid_tz == false)
12664  {
12665  if (er_errid () != ER_TZ_LOAD_ERROR)
12666  {
12667  error_status = ER_QSTR_INVALID_DATA_TYPE;
12668  }
12669  er_clear ();
12670  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
12671  goto error;
12672  }
12673  switch (*(format_s + 2))
12674  {
12675  case 'R':
12676  strcat (res, tzr);
12677  break;
12678  case 'D':
12679  strcat (res, tzd);
12680  break;
12681  case 'H':
12682  if (tzh >= 0)
12683  {
12684  sprintf (hours_or_minutes, "%02d", tzh);
12685  }
12686  else
12687  {
12688  sprintf (hours_or_minutes, "%c%02d", '-', -tzh);
12689  }
12690  strcat (res, hours_or_minutes);
12691  break;
12692  case 'M':
12693  if (tzm >= 0)
12694  {
12695  sprintf (hours_or_minutes, "%02d", tzm);
12696  }
12697  else
12698  {
12699  sprintf (hours_or_minutes, "%c%02d", '-', -tzm);
12700  }
12701  strcat (res, hours_or_minutes);
12702  break;
12703  }
12704  format_s += 2;
12705  }
12706  /* parse the character */
12707  else if (strlen (format_specifiers[(unsigned char) ch]) == 0)
12708  {
12709  /* append the character itself */
12710  STRCHCAT (res, ch);
12711  }
12712  else
12713  {
12714  strcat (res, format_specifiers[(unsigned char) ch]);
12715  }
12716 
12717  /* jump a character */
12718  format_s++;
12719  och = ch;
12720  ch = *format_s;
12721  }
12722  else
12723  {
12724  STRCHCAT (res, och);
12725  }
12726 
12727  /* chance of overflow ? */
12728  /* assume we can't add at a time mode than 16 chars */
12729  if (strlen (res) + 16 > len)
12730  {
12731  /* realloc - copy temporary in res2 */
12732  res2 = (char *) db_private_alloc (NULL, len);
12733  if (!res2)
12734  {
12735  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
12736  goto error;
12737  }
12738  memset (res2, 0, len);
12739  strcpy (res2, res);
12741 
12742  len += 1024;
12743  res = (char *) db_private_alloc (NULL, len);
12744  if (!res)
12745  {
12746  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
12747  goto error;
12748  }
12749  memset (res, 0, len);
12750  strcpy (res, res2);
12752  }
12753  }
12754  /* finished string */
12755 
12756  /* 4. */
12757 
12758  db_make_string (result, res);
12759  db_string_put_cs_and_collation (result, codeset, res_collation);
12760 
12761  result->need_clear = true;
12762 
12763  return error_status;
12764 
12765 error:
12766  pr_clear_value (&new_time_value);
12767 
12768  if (res != NULL)
12769  {
12771  }
12772 
12773  if (res2 != NULL)
12774  {
12776  }
12777 
12778  return error_status;
12779 }
12780 
12781 /*
12782  * db_timestamp() -
12783  *
12784  * Arguments:
12785  * src_datetime1: date or datetime expression
12786  * src_time2: time expression
12787  *
12788  * Returns: int
12789  *
12790  * Errors:
12791  *
12792  * Note:
12793  * This function is used in the function TIMESTAMP().
12794  * It returns the date or datetime expression expr as a datetime value.
12795  * With both arguments, it adds the time expression src_time2 to the date or
12796  * datetime expression src_datetime1 and returns the result as a datetime value.
12797  */
12798 int
12799 db_timestamp (const DB_VALUE * src_datetime1, const DB_VALUE * src_time2, DB_VALUE * result_datetime)
12800 {
12801  int error_status = NO_ERROR;
12802  int year, month, day, hour, minute, second, millisecond;
12803  int h = 0, mi = 0, s = 0, ms = 0;
12804  DB_BIGINT amount = 0;
12805  double amount_d = 0;
12806  DB_TYPE type;
12807  DB_DATETIME datetime, calculated_datetime;
12808  /* if sign is 1 then we perform a subtraction */
12809  int sign = 0;
12810 
12811  if (result_datetime == (DB_VALUE *) NULL)
12812  {
12815  }
12816 
12818 
12819  /* Return NULL if NULL is explicitly given as the second argument. If no second argument is given, we consider it as
12820  * 0. */
12821  if (DB_IS_NULL (src_datetime1) || (src_time2 && DB_IS_NULL (src_time2)))
12822  {
12823  db_make_null (result_datetime);
12824  return NO_ERROR;
12825  }
12826 
12827  year = month = day = hour = minute = second = millisecond = 0;
12828 
12829  error_status =
12830  db_get_datetime_from_dbvalue (src_datetime1, &year, &month, &day, &hour, &minute, &second, &millisecond, NULL);
12831  if (error_status != NO_ERROR)
12832  {
12833  return error_status;
12834  }
12835  /* If no second argument is given, just encode the first argument. */
12836  if (src_time2 == NULL)
12837  {
12838  goto encode_result;
12839  }
12840 
12841  type = DB_VALUE_DOMAIN_TYPE (src_time2);
12842  switch (type)
12843  {
12844  case DB_TYPE_CHAR:
12845  case DB_TYPE_VARCHAR:
12846  parse_time_string (db_get_string (src_time2), db_get_string_size (src_time2), &sign, &h, &mi, &s, &ms);
12847  break;
12848 
12849  case DB_TYPE_TIME:
12850  db_time_decode (db_get_time (src_time2), &h, &mi, &s);
12851  break;
12852 
12853  case DB_TYPE_SMALLINT:
12854  amount = (DB_BIGINT) db_get_short (src_time2);
12855  break;
12856 
12857  case DB_TYPE_INTEGER:
12858  amount = (DB_BIGINT) db_get_int (src_time2);
12859  break;
12860 
12861  case DB_TYPE_BIGINT:
12862  amount = db_get_bigint (src_time2);
12863  break;
12864 
12865  case DB_TYPE_FLOAT:
12866  amount_d = db_get_float (src_time2);
12867  break;
12868 
12869  case DB_TYPE_DOUBLE:
12870  amount_d = db_get_double (src_time2);
12871  break;
12872 
12873  case DB_TYPE_MONETARY:
12874  amount_d = db_value_get_monetary_amount_as_double (src_time2);
12875  break;
12876 
12877  case DB_TYPE_NUMERIC:
12879  &amount_d);
12880  break;
12881 
12882  default:
12885  }
12886 
12887  if (type == DB_TYPE_DOUBLE || type == DB_TYPE_FLOAT || type == DB_TYPE_MONETARY || type == DB_TYPE_NUMERIC)
12888  {
12889  amount = (DB_BIGINT) amount_d;
12890  ms = ((long) (amount_d * 1000.0)) % 1000;
12891  }
12892 
12893  if (type != DB_TYPE_VARCHAR && type != DB_TYPE_CHAR && type != DB_TYPE_TIME)
12894  {
12895  if (amount < 0)
12896  {
12897  amount = -amount;
12898  ms = -ms;
12899  sign = 1;
12900  }
12901  s = (int) ((DB_BIGINT) amount % 100);
12902  amount /= 100;
12903  mi = (int) ((DB_BIGINT) amount % 100);
12904  amount /= 100;
12905  h = (int) amount;
12906  }
12907 
12908  /* validation of minute and second */
12909  if ((mi < 0 || mi > 59) || (s < 0 || s > 59))
12910  {
12913  }
12914 
12915  /* Convert time to milliseconds. */
12916  amount = ((DB_BIGINT) h * 60 * 60 * 1000) + ((DB_BIGINT) mi * 60 * 1000) + ((DB_BIGINT) s * 1000) + (DB_BIGINT) ms;
12917 
12918 encode_result:
12919 
12920  db_datetime_encode (&datetime, month, day, year, hour, minute, second, millisecond);
12921  if (amount > 0)
12922  {
12923  if (sign == 0)
12924  {
12925  error_status = db_add_int_to_datetime (&datetime, amount, &calculated_datetime);
12926  }
12927  else
12928  {
12929  error_status = db_subtract_int_from_datetime (&datetime, amount, &calculated_datetime);
12930  }
12931  if (error_status != NO_ERROR)
12932  {
12933  return error_status;
12934  }
12935 
12936  db_make_datetime (result_datetime, &calculated_datetime);
12937  }
12938  else
12939  {
12940  db_make_datetime (result_datetime, &datetime);
12941  }
12942 
12943  return error_status;
12944 }
12945 
12946 /*
12947  * db_add_months () -
12948  */
12949 int
12950 db_add_months (const DB_VALUE * src_date, const DB_VALUE * nmonth, DB_VALUE * result_date)
12951 {
12952  int error_status = NO_ERROR;
12953  int n;
12954  int month, day, year;
12955  int old_month, old_year;
12956  DB_DATE *date_p;
12957 
12958  assert (src_date != (DB_VALUE *) NULL);
12959  assert (nmonth != (DB_VALUE *) NULL);
12960  assert (result_date != (DB_VALUE *) NULL);
12961 
12963 
12964  if (DB_IS_NULL (src_date) || DB_IS_NULL (nmonth))
12965  {
12966  db_make_null (result_date);
12967  return error_status;
12968  }
12969 
12970  assert (DB_VALUE_TYPE (nmonth) == DB_TYPE_INTEGER);
12971  n = db_get_int (nmonth);
12972 
12973  assert (DB_VALUE_TYPE (src_date) == DB_TYPE_DATE);
12974  date_p = db_get_date (src_date);
12975 
12976  db_date_decode (date_p, &month, &day, &year);
12977 
12978  old_month = month;
12979  old_year = year;
12980 
12981  if ((month + n) >= 0) /* Calculate month,year */
12982  {
12983  year = year + (month + n) / 12;
12984  month = (month + n) % 12;
12985  year = (month == 0) ? year - 1 : year;
12986  month = (month == 0) ? 12 : month;
12987  }
12988  else
12989  {
12990  year = year + (month + n - 12) / 12;
12991  month = 12 + (month + n) % 12;
12992  }
12993  /* Check last day of month */
12994  if (day == get_last_day (old_month, old_year) || day > get_last_day (month, year))
12995  {
12996  day = get_last_day (month, year);
12997  }
12998 
12999  if (0 < year && year < 10000)
13000  {
13001  db_make_date (result_date, month, day, year);
13002  }
13003  else
13004  {
13005  error_status = ER_DATE_EXCEED_LIMIT;
13006  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13007  return error_status;
13008  }
13009  return error_status;
13010 }
13011 
13012 /*
13013  * db_last_day () -
13014  */
13015 int
13016 db_last_day (const DB_VALUE * src_date, DB_VALUE * result_day)
13017 {
13018  int error_status = NO_ERROR;
13019  int month, day, year;
13020  int lastday;
13021 
13022  assert (src_date != (DB_VALUE *) NULL);
13023  assert (result_day != (DB_VALUE *) NULL);
13024 
13025  if (DB_IS_NULL (src_date))
13026  {
13027  db_make_null (result_day);
13028  return error_status;
13029  }
13030 
13031  db_date_decode ((DB_DATE *) (&src_date->data.date), &month, &day, &year);
13032 
13033  if (month == 0 && day == 0 && year == 0)
13034  {
13035  db_make_null (result_day);
13036  er_clear ();
13038  {
13039  return NO_ERROR;
13040  }
13043  }
13044 
13045  lastday = get_last_day (month, year);
13046 
13047  db_make_date (result_day, month, lastday, year);
13048 
13049  return error_status;
13050 }
13051 
13052 /*
13053  * db_months_between () -
13054  */
13055 int
13056 db_months_between (const DB_VALUE * start_mon, const DB_VALUE * end_mon, DB_VALUE * result_mon)
13057 {
13058  int error_status = NO_ERROR;
13059  double result_double;
13060  int start_month, start_day, start_year;
13061  int end_month, end_day, end_year;
13062  DB_DATE *start_date, *end_date;
13063 
13064  assert (start_mon != (DB_VALUE *) NULL);
13065  assert (end_mon != (DB_VALUE *) NULL);
13066  assert (result_mon != (DB_VALUE *) NULL);
13067 
13068  /* now return null */
13069 
13070  if (DB_IS_NULL (start_mon) || DB_IS_NULL (end_mon))
13071  {
13072  db_make_null (result_mon);
13073  return error_status;
13074  }
13075 
13076  assert (DB_VALUE_TYPE (start_mon) == DB_TYPE_DATE);
13077  assert (DB_VALUE_TYPE (end_mon) == DB_TYPE_DATE);
13078 
13079  start_date = db_get_date (start_mon);
13080  end_date = db_get_date (end_mon);
13081 
13082  db_date_decode (start_date, &start_month, &start_day, &start_year);
13083  db_date_decode (end_date, &end_month, &end_day, &end_year);
13084 
13085  if (start_day == end_day
13086  || (start_day == get_last_day (start_month, start_year) && end_day == get_last_day (end_month, end_year)))
13087  {
13088  result_double = (double) (start_year * 12 + start_month - end_year * 12 - end_month);
13089  }
13090  else
13091  {
13092  result_double =
13093  (double) ((start_year - end_year) * 12.0) + (double) (start_month - end_month) +
13094  (double) ((start_day - end_day) / 31.0);
13095  }
13096 
13097  db_make_double (result_mon, result_double);
13098 
13099  return error_status;
13100 }
13101 
13102 /*
13103  * db_sys_date () -
13104  */
13105 int
13106 db_sys_date (DB_VALUE * result_date)
13107 {
13108  int error_status = NO_ERROR;
13109  time_t tloc;
13110  struct tm *c_time_struct, tm_val;
13111 
13112  assert (result_date != (DB_VALUE *) NULL);
13113 
13114  /* now return null */
13116 
13117  /* Need checking error */
13118 
13119  if (time (&tloc) == -1)
13120  {
13121  error_status = ER_SYSTEM_DATE;
13122  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13123  return error_status;
13124  }
13125 
13126  c_time_struct = localtime_r (&tloc, &tm_val);
13127  if (c_time_struct == NULL)
13128  {
13129  error_status = ER_SYSTEM_DATE;
13130  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13131  return error_status;
13132  }
13133 
13134  db_make_date (result_date, c_time_struct->tm_mon + 1, c_time_struct->tm_mday, c_time_struct->tm_year + 1900);
13135 
13136  return error_status;
13137 }
13138 
13139 /*
13140  * db_sys_time () -
13141  */
13142 int
13143 db_sys_time (DB_VALUE * result_time)
13144 {
13145  int error_status = NO_ERROR;
13146  time_t tloc;
13147  struct tm *c_time_struct, tm_val;
13148 
13149  assert (result_time != (DB_VALUE *) NULL);
13150 
13151  /* now return null */
13153 
13154  /* Need checking error */
13155 
13156  if (time (&tloc) == -1)
13157  {
13158  error_status = ER_SYSTEM_DATE;
13159  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13160  return error_status;
13161  }
13162 
13163  c_time_struct = localtime_r (&tloc, &tm_val);
13164  if (c_time_struct == NULL)
13165  {
13166  error_status = ER_SYSTEM_DATE;
13167  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13168  return error_status;
13169  }
13170  db_make_time (result_time, c_time_struct->tm_hour, c_time_struct->tm_min, c_time_struct->tm_sec);
13171 
13172  return error_status;
13173 }
13174 
13175 /*
13176  * db_sys_timestamp () -
13177  */
13178 int
13179 db_sys_timestamp (DB_VALUE * result_timestamp)
13180 {
13181  int error_status = NO_ERROR;
13182  time_t tloc;
13183 
13184  assert (result_timestamp != (DB_VALUE *) NULL);
13185 
13186  /* now return null */
13188 
13189  if (time (&tloc) == -1 || OR_CHECK_INT_OVERFLOW (tloc))
13190  {
13191  error_status = ER_SYSTEM_DATE;
13192  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13193  return error_status;
13194  }
13195 
13196  db_make_timestamp (result_timestamp, (DB_TIMESTAMP) tloc);
13197 
13198  return error_status;
13199 }
13200 
13201 /*
13202  * db_sys_datetime () -
13203  */
13204 int
13205 db_sys_datetime (DB_VALUE * result_datetime)
13206 {
13207  int error_status = NO_ERROR;
13208  DB_DATETIME datetime;
13209 
13210  time_t sec;
13211  int millisec;
13212  struct tm *c_time_struct, tm_val;
13213 
13214  assert (result_datetime != (DB_VALUE *) NULL);
13215 
13216  /* now return null */
13218 
13219  util_get_second_and_ms_since_epoch (&sec, &millisec);
13220 
13221  c_time_struct = localtime_r (&sec, &tm_val);
13222  if (c_time_struct == NULL)
13223  {
13224  error_status = ER_SYSTEM_DATE;
13225  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13226  return error_status;
13227  }
13228 
13229  db_datetime_encode (&datetime, c_time_struct->tm_mon + 1, c_time_struct->tm_mday, c_time_struct->tm_year + 1900,
13230  c_time_struct->tm_hour, c_time_struct->tm_min, c_time_struct->tm_sec, millisec);
13231  db_make_datetime (result_datetime, &datetime);
13232 
13233  return error_status;
13234 }
13235 
13236 /*
13237  * db_sys_date_and_epoch_time () - This function returns current
13238  * datetime and timestamp.
13239  *
13240  * return: status of the error
13241  *
13242  * dt_dbval(out): datetime
13243  * ts_dbval(out): timestamp
13244  */
13245 
13246 int
13248 {
13249  int error_status = NO_ERROR;
13250  DB_DATETIME datetime;
13251  time_t sec;
13252  int millisec;
13253  struct tm *c_time_struct, tm_val;
13254 
13255  assert (dt_dbval != NULL);
13256  assert (ts_dbval != NULL);
13257 
13258  util_get_second_and_ms_since_epoch (&sec, &millisec);
13259 
13260  c_time_struct = localtime_r (&sec, &tm_val);
13261  if (c_time_struct == NULL)
13262  {
13263  error_status = ER_SYSTEM_DATE;
13264  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13265  return error_status;
13266  }
13267 
13268  db_datetime_encode (&datetime, c_time_struct->tm_mon + 1, c_time_struct->tm_mday, c_time_struct->tm_year + 1900,
13269  c_time_struct->tm_hour, c_time_struct->tm_min, c_time_struct->tm_sec, millisec);
13270 
13271  db_make_datetime (dt_dbval, &datetime);
13272  db_make_timestamp (ts_dbval, (DB_TIMESTAMP) sec);
13273 
13274  return error_status;
13275 }
13276 
13277 /*
13278  * This function return the current timezone , as an integer representing
13279  * the minutes away from GMT
13280  */
13281 int
13282 db_sys_timezone (DB_VALUE * result_timezone)
13283 {
13284  assert (result_timezone != (DB_VALUE *) NULL);
13285 
13286  /* now return null */
13288 
13289  db_make_int (result_timezone, tz_get_offset_in_mins ());
13290  return NO_ERROR;
13291 }
13292 
13293 /*
13294  * get_last_day () -
13295  */
13296 int
13297 get_last_day (int month, int year)
13298 {
13299  int lastday = 0;
13300 
13301  if (year >= 1700)
13302  {
13303  switch (month)
13304  {
13305  case 1:
13306  case 3:
13307  case 5:
13308  case 7:
13309  case 8:
13310  case 10:
13311  case 12:
13312  lastday = 31;
13313  break;
13314  case 4:
13315  case 6:
13316  case 9:
13317  case 11:
13318  lastday = 30;
13319  break;
13320  case 2:
13321  if (year % 4 == 0)
13322  {
13323  if (year % 100 == 0)
13324  {
13325  if (year % 400 == 0)
13326  {
13327  lastday = 29;
13328  }
13329  else
13330  {
13331  lastday = 28;
13332  }
13333  }
13334  else
13335  {
13336  lastday = 29;
13337  }
13338  }
13339  else
13340  {
13341  lastday = 28;
13342  }
13343  break;
13344  default:
13345  break; /* Need Error Checking */
13346  }
13347  }
13348  else
13349  {
13350  switch (month)
13351  {
13352  case 1:
13353  case 3:
13354  case 5:
13355  case 7:
13356  case 8:
13357  case 10:
13358  case 12:
13359  lastday = 31;
13360  break;
13361  case 4:
13362  case 6:
13363  case 9:
13364  case 11:
13365  lastday = 30;
13366  break;
13367  case 2:
13368  if (year % 4 == 0)
13369  {
13370  lastday = 29;
13371  }
13372  else
13373  {
13374  lastday = 28;
13375  }
13376  break;
13377  default:
13378  break; /* Need Error Checking */
13379  }
13380  }
13381  return lastday;
13382 }
13383 
13384 /*
13385  * db_to_char () -
13386  */
13387 int
13388 db_to_char (const DB_VALUE * src_value, const DB_VALUE * format_or_length, const DB_VALUE * lang_str,
13389  DB_VALUE * result_str, const TP_DOMAIN * domain)
13390 {
13391  int error_status = NO_ERROR;
13392  DB_TYPE type;
13393 
13394  type = DB_VALUE_DOMAIN_TYPE (src_value);
13395  if (type == DB_TYPE_NULL || is_number (src_value))
13396  {
13397  return number_to_char (src_value, format_or_length, lang_str, result_str, domain);
13398  }
13399  else if (TP_IS_DATE_OR_TIME_TYPE (type))
13400  {
13401  return date_to_char (src_value, format_or_length, lang_str, result_str, domain);
13402  }
13403  else if (TP_IS_CHAR_TYPE (type))
13404  {
13405  if (domain == NULL)
13406  {
13407  error_status = pr_clone_value (src_value, result_str);
13408  if (error_status != NO_ERROR)
13409  {
13410  return error_status;
13411  }
13413  }
13414  else
13415  {
13416  error_status = db_value_coerce (src_value, result_str, domain);
13417  }
13418 
13419  return error_status;
13420  }
13421  else
13422  {
13423  error_status = ER_QSTR_INVALID_DATA_TYPE;
13424  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13425 
13426  return error_status;
13427  }
13428 }
13429 
13430 #define MAX_STRING_DATE_TOKEN_LEN LOC_DATA_MONTH_WIDE_SIZE
13431 const char *Month_name_ISO[][12] = {
13432  {"January", "February", "March", "April",
13433  "May", "June", "July", "August", "September", "October",
13434  "November", "December"}, /* US */
13435  {"1wol",
13436  "2wol",
13437  "3wol",
13438  "4wol",
13439  "5wol",
13440  "6wol",
13441  "7wol",
13442  "8wol",
13443  "9wol",
13444  "10wol",
13445  "11wol",
13446  "12wol"}, /* KR */
13447  {"Ocak",
13448  "Subat",
13449  "Mart",
13450  "Nisan",
13451  "Mayis",
13452  "Haziran",
13453  "Temmuz",
13454  "Agustos",
13455  "Eylul",
13456  "Ekim",
13457  "Kasim",
13458  "Aralik"} /* TR */
13459 };
13460 
13461 const char *Month_name_UTF8[][12] = {
13462  {"January", "February", "March", "April",
13463  "May", "June", "July", "August", "September", "October",
13464  "November", "December"}, /* US */
13465  {"1\xec\x9b\x94",
13466  "2\xec\x9b\x94",
13467  "3\xec\x9b\x94",
13468  "4\xec\x9b\x94",
13469  "5\xec\x9b\x94",
13470  "6\xec\x9b\x94",
13471  "7\xec\x9b\x94",
13472  "8\xec\x9b\x94",
13473  "9\xec\x9b\x94",
13474  "10\xec\x9b\x94",
13475  "11\xec\x9b\x94",
13476  "12\xec\x9b\x94"}, /* KR */
13477  {"Ocak",
13478  "\xc5\x9e" "ubat",
13479  "Mart",
13480  "Nisan",
13481  "May" "\xc4\xb1" "s",
13482  "Haziran",
13483  "Temmuz",
13484  "A" "\xc4\x9f" "ustos",
13485  "Eyl" "\xc3\xbc" "l",
13486  "Ekim",
13487  "Kas" "\xc4\xb1" "m",
13488  "Aral" "\xc4\xb1" "k"} /* TR */
13489 };
13490 
13491 const char *Month_name_EUCKR[][12] = {
13492  {"January", "February", "March", "April",
13493  "May", "June", "July", "August", "September", "October",
13494  "November", "December"}, /* US */
13495  {"1\xbf\xf9",
13496  "2\xbf\xf9",
13497  "3\xbf\xf9",
13498  "4\xbf\xf9",
13499  "5\xbf\xf9",
13500  "6\xbf\xf9",
13501  "7\xbf\xf9",
13502  "8\xbf\xf9",
13503  "9\xbf\xf9",
13504  "10\xbf\xf9",
13505  "11\xbf\xf9",
13506  "12\xbf\xf9"}, /* KR */
13507  {"Ocak",
13508  "Subat",
13509  "Mart",
13510  "Nisan",
13511  "Mayis",
13512  "Haziran",
13513  "Temmuz",
13514  "Agustos",
13515  "Eylul",
13516  "Ekim",
13517  "Kasim",
13518  "Aralik"} /* TR */
13519 };
13520 
13521 const char Month_name_parse_order[][12] = {
13522  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
13523  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
13524  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
13525 };
13526 
13527 const char *Day_name_ISO[][7] = {
13528  {"Sunday", "Monday", "Tuesday", "Wednesday",
13529  "Thursday", "Friday", "Saturday"}, /* US */
13530  {"Iryoil",
13531  "Woryoil",
13532  "Hwayoil",
13533  "Suyoil",
13534  "Mogyoil",
13535  "Geumyoil",
13536  "Toyoil"}, /* KR */
13537  {"Pazar", "Pazartesi", "Sali",
13538  "Carsamba",
13539  "Persembe", "Cuma",
13540  "Cumartesi"} /* TR */
13541 };
13542 
13543 const char *Day_name_UTF8[][7] = {
13544  {"Sunday", "Monday", "Tuesday", "Wednesday",
13545  "Thursday", "Friday", "Saturday"}, /* US */
13546  {"\xec\x9d\xbc\xec\x9a\x94\xec\x9d\xbc",
13547  "\xec\x9b\x94\xec\x9a\x94\xec\x9d\xbc",
13548  "\xed\x99\x94\xec\x9a\x94\xec\x9d\xbc",
13549  "\xec\x88\x98\xec\x9a\x94\xec\x9d\xbc",
13550  "\xeb\xaa\xa9\xec\x9a\x94\xec\x9d\xbc",
13551  "\xea\xb8\x88\xec\x9a\x94\xec\x9d\xbc",
13552  "\xed\x86\xa0\xec\x9a\x94\xec\x9d\xbc"}, /* KR */
13553  {"Pazar", "Pazartesi", "Sal\xc4\xb1",
13554  "\xc3\x87" "ar" "\xc5\x9f" "amba",
13555  "Per" "\xc5\x9f" "embe", "Cuma",
13556  "Cumartesi"} /* TR */
13557 };
13558 
13559 const char *Day_name_EUCKR[][7] = {
13560  {"Sunday", "Monday", "Tuesday", "Wednesday",
13561  "Thursday", "Friday", "Saturday"}, /* US */
13562  {"\xc0\xcf\xbf\xe4\xc0\xcf",
13563  "\xbf\xf9\xbf\xe4\xc0\xcf",
13564  "\xc8\xad\xbf\xe4\xc0\xcf",
13565  "\xbc\xf6\xbf\xe4\xc0\xcf",
13566  "\xb8\xf1\xbf\xe4\xc0\xcf",
13567  "\xb1\xdd\xbf\xe4\xc0\xcf",
13568  "\xc5\xe4\xbf\xe4\xc0\xcf"}, /* KR */
13569  {"Pazar", "Pazartesi", "Sali",
13570  "Carsamba",
13571  "Persembe", "Cuma",
13572  "Cumartesi"} /* TR */
13573 };
13574 
13575 const char Day_name_parse_order[][7] = {
13576  {0, 1, 2, 3, 4, 5, 6},
13577  {0, 1, 2, 3, 4, 5, 6},
13578  {1, 0, 2, 3, 4, 6, 5}
13579 };
13580 
13581 const char *Short_Month_name_ISO[][12] = {
13582  {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
13583  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}, /* US */
13584  {"1wol",
13585  "2wol",
13586  "3wol",
13587  "4wol",
13588  "5wol",
13589  "6wol",
13590  "7wol",
13591  "8wol",
13592  "9wol",
13593  "10wol",
13594  "11wol",
13595  "12wol"}, /* KR */
13596  {"Ock",
13597  "Sbt",
13598  "Mrt",
13599  "Nsn",
13600  "Mys",
13601  "Hzr",
13602  "Tmz",
13603  "Ags",
13604  "Eyl",
13605  "Ekm",
13606  "Ksm",
13607  "Arl"} /* TR */
13608 };
13609 
13610 const char *Short_Month_name_UTF8[][12] = {
13611  {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
13612  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}, /* US */
13613  {"1\xec\x9b\x94",
13614  "2\xec\x9b\x94",
13615  "3\xec\x9b\x94",
13616  "4\xec\x9b\x94",
13617  "5\xec\x9b\x94",
13618  "6\xec\x9b\x94",
13619  "7\xec\x9b\x94",
13620  "8\xec\x9b\x94",
13621  "9\xec\x9b\x94",
13622  "10\xec\x9b\x94",
13623  "11\xec\x9b\x94",
13624  "12\xec\x9b\x94"}, /* KR */
13625  {"Ock",
13626  "\xc5\x9e" "bt",
13627  "Mrt",
13628  "Nsn",
13629  "Mys",
13630  "Hzr",
13631  "Tmz",
13632  "A" "\xc4\x9f" "s",
13633  "Eyl",
13634  "Ekm",
13635  "Ksm",
13636  "Arl"} /* TR */
13637 };
13638 
13639 const char *Short_Month_name_EUCKR[][12] = {
13640  {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
13641  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}, /* US */
13642  {"1\xbf\xf9",
13643  "2\xbf\xf9",
13644  "3\xbf\xf9",
13645  "4\xbf\xf9",
13646  "5\xbf\xf9",
13647  "6\xbf\xf9",
13648  "7\xbf\xf9",
13649  "8\xbf\xf9",
13650  "9\xbf\xf9",
13651  "10\xbf\xf9",
13652  "11\xbf\xf9",
13653  "12\xbf\xf9"}, /* KR */
13654  {"Ock",
13655  "Sbt",
13656  "Mrt",
13657  "Nsn",
13658  "Mys",
13659  "Hzr",
13660  "Tmz",
13661  "Ags",
13662  "Eyl",
13663  "Ekm",
13664  "Ksm",
13665  "Arl"} /* TR */
13666 };
13667 
13668 const char Short_Month_name_parse_order[][12] = {
13669  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
13670  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
13671  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
13672 };
13673 
13674 const char *Short_Day_name_ISO[][7] = {
13675  {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}, /* US */
13676  {"Il",
13677  "Wol",
13678  "Hwa",
13679  "Su",
13680  "Mok",
13681  "Geum",
13682  "To"}, /* KR */
13683  {"Pz", "Pt", "Sa",
13684  "Ca",
13685  "Pe", "Cu", "Ct"} /* TR */
13686 };
13687 
13688 const char *Short_Day_name_UTF8[][7] = {
13689  {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}, /* US */
13690  {"\xec\x9d\xbc",
13691  "\xec\x9b\x94",
13692  "\xed\x99\x94",
13693  "\xec\x88\x98",
13694  "\xeb\xaa\xa9",
13695  "\xea\xb8\x88",
13696  "\xed\x86\xa0"}, /* KR */
13697  {"Pz", "Pt", "Sa",
13698  "\xc3\x87" "a",
13699  "Pe", "Cu", "Ct"} /* TR */
13700 };
13701 
13702 const char *Short_Day_name_EUCKR[][7] = {
13703  {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}, /* US */
13704  {"\xc0\xcf",
13705  "\xbf\xf9",
13706  "\xc8\xad",
13707  "\xbc\xf6",
13708  "\xb8\xf1",
13709  "\xb1\xdd",
13710  "\xc5\xe4"}, /* KR */
13711  {"Pz", "Pt", "Sa",
13712  "Ca",
13713  "Pe", "Cu", "Ct"} /* TR */
13714 };
13715 
13716 const char Short_Day_name_parse_order[][7] = {
13717  {0, 1, 2, 3, 4, 5, 6},
13718  {0, 1, 2, 3, 4, 5, 6},
13719  {0, 1, 2, 3, 4, 5, 6}
13720 };
13721 
13722 #define AM_NAME_KR "ojeon"
13723 #define PM_NAME_KR "ohu"
13724 
13725 #define AM_NAME_KR_EUC "\xbf\xc0\xc0\xfc"
13726 #define PM_NAME_KR_EUC "\xbf\xc0\xc8\xc4"
13727 
13728 #define AM_NAME_KR_UTF8 "\xec\x98\xa4\xec\xa0\x84"
13729 #define PM_NAME_KR_UTF8 "\xec\x98\xa4\xed\x9b\x84"
13730 
13731 const char AM_PM_parse_order[][12] = {
13732  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
13733  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
13734  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
13735 };
13736 
13737 
13738 
13739 const char *Am_Pm_name_ISO[][12] = {
13740  {"am", "pm", "Am", "Pm", "AM", "PM",
13741  "a.m.", "p.m.", "A.m.", "P.m.", "A.M.", "P.M."}, /* US */
13744  /* KR */
13745  {"am", "pm", "Am", "Pm", "AM", "PM",
13746  "a.m.", "p.m.", "A.m.", "P.m.", "A.M.", "P.M."}, /* TR */
13747 };
13748 
13749 const char *Am_Pm_name_UTF8[][12] = {
13750  {"am", "pm", "Am", "Pm", "AM", "PM",
13751  "a.m.", "p.m.", "A.m.", "P.m.", "A.M.", "P.M."}, /* US */
13755  PM_NAME_KR_UTF8, AM_NAME_KR_UTF8, PM_NAME_KR_UTF8},
13756  /* KR */
13757  {"am", "pm", "Am", "Pm", "AM", "PM",
13758  "a.m.", "p.m.", "A.m.", "P.m.", "A.M.", "P.M."}, /* TR */
13759 };
13760 
13761 const char *Am_Pm_name_EUCKR[][12] = {
13762  {"am", "pm", "Am", "Pm", "AM", "PM",
13763  "a.m.", "p.m.", "A.m.", "P.m.", "A.M.", "P.M."}, /* US */
13767  PM_NAME_KR_EUC, AM_NAME_KR_EUC, PM_NAME_KR_EUC},
13768  /* KR */
13769  {"am", "pm", "Am", "Pm", "AM", "PM",
13770  "a.m.", "p.m.", "A.m.", "P.m.", "A.M.", "P.M."}, /* TR */
13771 };
13772 
13773 /*
13774  * db_to_date () -
13775  */
13776 int
13777 db_to_date (const DB_VALUE * src_str, const DB_VALUE * format_str, const DB_VALUE * date_lang, DB_VALUE * result_date)
13778 {
13779  int error_status = NO_ERROR;
13780  const char *cur_format_str_ptr, *next_format_str_ptr;
13781  char *cs; /* current source string pointer */
13782  const char *last_src, *last_format;
13783 
13784  TIMESTAMP_FORMAT cur_format;
13785 
13786  int cur_format_size;
13787 
13788  int month = 0, day = 0, year = 0, day_of_the_week = 0, week = -1;
13789  int monthcount = 0, daycount = 0, yearcount = 0, day_of_the_weekcount = 0;
13790 
13791  int i;
13792  bool no_user_format;
13793  INTL_LANG date_lang_id;
13794  INTL_CODESET codeset;
13795  INTL_CODESET frmt_codeset;
13796  char stack_buf_str[64], stack_buf_format[64];
13797  char *initial_buf_str = NULL, *initial_buf_format = NULL;
13798  bool do_free_buf_str = false, do_free_buf_format = false;
13799  DB_VALUE default_format;
13800  bool has_user_format = false;
13801  bool dummy;
13802 
13803  assert (src_str != (DB_VALUE *) NULL);
13804  assert (result_date != (DB_VALUE *) NULL);
13805  assert (date_lang != (DB_VALUE *) NULL);
13806 
13807  db_make_null (&default_format);
13808 
13809  if (DB_IS_NULL (src_str))
13810  {
13811  db_make_null (result_date);
13812  return error_status;
13813  }
13814 
13815  assert (DB_VALUE_TYPE (date_lang) == DB_TYPE_INTEGER);
13816  date_lang_id = lang_get_lang_id_from_flag (db_get_int (date_lang), &has_user_format, &dummy);
13817 
13818  if (false == is_char_string (src_str))
13819  {
13820  error_status = ER_QSTR_INVALID_DATA_TYPE;
13821  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13822  return error_status;
13823  }
13824 
13825  if (db_get_string_size (src_str) == 0)
13826  {
13827  error_status = ER_QSTR_EMPTY_STRING;
13828  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13829  return error_status;
13830  }
13831 
13832  if (db_get_string_size (src_str) > MAX_TOKEN_SIZE)
13833  {
13834  error_status = ER_QSTR_SRC_TOO_LONG;
13835  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13836  return error_status;
13837  }
13838 
13839  codeset = db_get_string_codeset (src_str);
13840  if (lang_get_specific_locale (date_lang_id, codeset) == NULL)
13841  {
13842  error_status = ER_LANG_CODESET_NOT_AVAILABLE;
13843  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 2, lang_get_lang_name_from_id (date_lang_id),
13844  lang_charset_name (codeset));
13845  return error_status;
13846  }
13847 
13848  error_status =
13849  db_check_or_create_null_term_string (src_str, stack_buf_str, sizeof (stack_buf_str), true, true, &initial_buf_str,
13850  &do_free_buf_str);
13851  if (error_status != NO_ERROR)
13852  {
13853  goto exit;
13854  }
13855 
13856  cs = initial_buf_str;
13857  last_src = cs + strlen (cs);
13858 
13859  last_src = (char *) intl_backskip_spaces (cs, last_src - 1, codeset);
13860  last_src = last_src + 1;
13861 
13862  no_user_format = (format_str == NULL) || (!has_user_format);
13863 
13864  if (no_user_format)
13865  {
13866  DB_DATE date_tmp;
13867  const char *default_format_str;
13868 
13869  /* try default CUBRID format first */
13870  if (NO_ERROR == db_string_to_date_ex ((char *) cs, CAST_BUFLEN (last_src - cs), &date_tmp))
13871  {
13872  db_value_put_encoded_date (result_date, &date_tmp);
13873  goto exit;
13874  }
13875 
13876  /* error parsing CUBRID default format, try the locale format, if any */
13877  default_format_str = lang_date_format_parse (date_lang_id, codeset, DB_TYPE_DATE, &frmt_codeset);
13878  if (default_format_str == NULL)
13879  {
13880  error_status = ER_DATE_CONVERSION;
13881  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13882  goto exit;
13883  }
13884 
13885  db_make_char (&default_format, strlen (default_format_str), default_format_str,
13886  strlen (default_format_str), frmt_codeset, LANG_GET_BINARY_COLLATION (frmt_codeset));
13887  format_str = &default_format;
13888  }
13889 
13890  if (DB_IS_NULL (format_str))
13891  {
13892  db_make_null (result_date);
13893  goto exit;
13894  }
13895 
13896  if (false == is_char_string (format_str))
13897  {
13898  error_status = ER_QSTR_INVALID_DATA_TYPE;
13899  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13900  goto exit;
13901  }
13902 
13903  if (db_get_string_size (format_str) > MAX_TOKEN_SIZE)
13904  {
13905  error_status = ER_QSTR_FORMAT_TOO_LONG;
13906  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13907  goto exit;
13908  }
13909 
13910  if (db_get_string_size (format_str) == 0)
13911  {
13912  error_status = ER_QSTR_EMPTY_STRING;
13913  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13914  goto exit;
13915  }
13916 
13917  frmt_codeset = db_get_string_codeset (format_str);
13918 
13919  error_status =
13920  db_check_or_create_null_term_string (format_str, stack_buf_format, sizeof (stack_buf_format), true, true,
13921  &initial_buf_format, &do_free_buf_format);
13922  if (error_status != NO_ERROR)
13923  {
13924  goto exit;
13925  }
13926 
13927  cur_format_str_ptr = initial_buf_format;
13928  last_format = cur_format_str_ptr + strlen (cur_format_str_ptr);
13929 
13930  /* Skip space, tab, CR */
13931  while (cs < last_src && strchr (WHITE_CHARS, *cs))
13932  {
13933  cs++;
13934  }
13935 
13936  /* Skip space, tab, CR */
13937  while (cur_format_str_ptr < last_format && strchr (WHITE_CHARS, *cur_format_str_ptr))
13938  {
13939  cur_format_str_ptr++;
13940  }
13941 
13942  while (cs < last_src)
13943  {
13944  int token_size, cmp, cs_byte_size;
13945  int k;
13946 
13947  cur_format =
13948  get_next_format (cur_format_str_ptr, frmt_codeset, DB_TYPE_DATE, &cur_format_size, &next_format_str_ptr);
13949  switch (cur_format)
13950  {
13951  case DT_YYYY:
13952  if (yearcount != 0)
13953  {
13954  error_status = ER_QSTR_FORMAT_DUPLICATION;
13955  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13956  goto exit;
13957  }
13958  else
13959  {
13960  yearcount++;
13961  }
13962 
13963  k = parse_digits (cs, &year, 4);
13964  if (k <= 0)
13965  {
13966  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
13967  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13968  goto exit;
13969  }
13970 
13971  cs += k;
13972  break;
13973 
13974  case DT_YY:
13975  if (yearcount != 0)
13976  {
13977  error_status = ER_QSTR_FORMAT_DUPLICATION;
13978  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13979  goto exit;
13980  }
13981  else
13982  {
13983  yearcount++;
13984  }
13985 
13986  k = parse_digits (cs, &year, 2);
13987  if (k <= 0)
13988  {
13989  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
13990  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
13991  goto exit;
13992  }
13993 
13994  cs += k;
13995 
13996  i = get_cur_year ();
13997  if (i == -1)
13998  {
13999  error_status = ER_SYSTEM_DATE;
14000  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14001  goto exit;
14002  }
14003 
14004  year += (i / 100) * 100;
14005  break;
14006 
14007  case DT_MM:
14008  if (monthcount != 0)
14009  {
14010  error_status = ER_QSTR_FORMAT_DUPLICATION;
14011  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14012  goto exit;
14013  }
14014  else
14015  {
14016  monthcount++;
14017  }
14018 
14019  k = parse_digits (cs, &month, 2);
14020  if (k <= 0)
14021  {
14022  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
14023  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14024  goto exit;
14025  }
14026 
14027  cs += k;
14028 
14029  if (month < 1 || month > 12)
14030  {
14031  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
14032  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14033  goto exit;
14034  }
14035  break;
14036 
14037  case DT_MONTH:
14038  if (monthcount != 0)
14039  {
14040  error_status = ER_QSTR_FORMAT_DUPLICATION;
14041  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14042  goto exit;
14043  }
14044  else
14045  {
14046  monthcount++;
14047  }
14048 
14049  error_status = get_string_date_token_id (SDT_MONTH, date_lang_id, cs, codeset, &month, &token_size);
14050  if (error_status != NO_ERROR)
14051  {
14052  goto exit;
14053  }
14054 
14055  cs += token_size;
14056 
14057  if (month == 0)
14058  {
14059  error_status = ER_DATE_CONVERSION;
14060  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14061  goto exit;
14062  }
14063  break;
14064 
14065  case DT_MON:
14066  if (monthcount != 0)
14067  {
14068  error_status = ER_QSTR_FORMAT_DUPLICATION;
14069  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14070  goto exit;
14071  }
14072  else
14073  {
14074  monthcount++;
14075  }
14076 
14077  month = 0;
14078 
14079 
14080  error_status = get_string_date_token_id (SDT_MONTH_SHORT, date_lang_id, cs, codeset, &month, &token_size);
14081  if (error_status != NO_ERROR)
14082  {
14083  goto exit;
14084  }
14085  cs += token_size;
14086 
14087 
14088  if (month == 0)
14089  {
14090  error_status = ER_DATE_CONVERSION;
14091  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14092  goto exit;
14093  }
14094  break;
14095 
14096  case DT_DD:
14097  if (daycount != 0)
14098  {
14099  error_status = ER_QSTR_FORMAT_DUPLICATION;
14100  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14101  goto exit;
14102  }
14103  else
14104  {
14105  daycount++;
14106  }
14107 
14108  k = parse_digits (cs, &day, 2);
14109  if (k <= 0)
14110  {
14111  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
14112  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14113  goto exit;
14114  }
14115 
14116  cs += k;
14117 
14118  if (day < 0 || day > 31)
14119  {
14120  error_status = ER_DATE_CONVERSION;
14121  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14122  goto exit;
14123  }
14124  break;
14125 
14126  case DT_TEXT:
14127  if (codeset != frmt_codeset)
14128  {
14129  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
14130  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14131  goto exit;
14132  }
14133  cmp = intl_case_match_tok (date_lang_id, codeset, (unsigned char *) (cur_format_str_ptr + 1),
14134  (unsigned char *) cs, cur_format_size - 2, strlen (cs), &cs_byte_size);
14135 
14136  if (cmp != 0)
14137  {
14138  error_status = ER_QSTR_INVALID_FORMAT;
14139  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14140  goto exit;
14141  }
14142 
14143  cs += cs_byte_size;
14144  break;
14145 
14146  case DT_PUNCTUATION:
14147  if (strncasecmp ((const char *) cur_format_str_ptr, (const char *) cs, cur_format_size) != 0)
14148  {
14149  error_status = ER_QSTR_INVALID_FORMAT;
14150  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14151  goto exit;
14152  }
14153 
14154  cs += cur_format_size;
14155  break;
14156 
14157  case DT_CC:
14158  case DT_Q:
14159  error_status = ER_QSTR_INVALID_FORMAT;
14160  /* Does it need error message? */
14161  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14162  goto exit;
14163 
14164  case DT_DAY:
14165  if (day_of_the_weekcount != 0)
14166  {
14167  error_status = ER_QSTR_FORMAT_DUPLICATION;
14168  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14169  goto exit;
14170  }
14171  else
14172  {
14173  day_of_the_weekcount++;
14174  }
14175 
14176  error_status = get_string_date_token_id (SDT_DAY, date_lang_id, cs, codeset, &day_of_the_week, &token_size);
14177  if (error_status != NO_ERROR)
14178  {
14179  goto exit;
14180  }
14181  cs += token_size;
14182 
14183  if (day_of_the_week == 0)
14184  {
14185  error_status = ER_DATE_CONVERSION;
14186  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14187  goto exit;
14188  }
14189  break;
14190 
14191  case DT_DY:
14192  if (day_of_the_weekcount != 0)
14193  {
14194  error_status = ER_QSTR_FORMAT_DUPLICATION;
14195  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14196  goto exit;
14197  }
14198  else
14199  {
14200  day_of_the_weekcount++;
14201  }
14202 
14203  error_status =
14204  get_string_date_token_id (SDT_DAY_SHORT, date_lang_id, cs, codeset, &day_of_the_week, &token_size);
14205  if (error_status != NO_ERROR)
14206  {
14207  goto exit;
14208  }
14209 
14210  cs += token_size;
14211 
14212  if (day_of_the_week == 0)
14213  {
14214  error_status = ER_DATE_CONVERSION;
14215  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14216  goto exit;
14217  }
14218  break;
14219 
14220  case DT_D:
14221  if (day_of_the_weekcount != 0)
14222  {
14223  error_status = ER_QSTR_FORMAT_DUPLICATION;
14224  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14225  goto exit;
14226  }
14227  else
14228  {
14229  day_of_the_weekcount++;
14230  }
14231 
14232  k = parse_digits (cs, &day_of_the_week, 1);
14233  if (k <= 0)
14234  {
14235  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
14236  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14237  goto exit;
14238  }
14239 
14240  cs += k;
14241 
14242  if (day_of_the_week < 1 || day_of_the_week > 7)
14243  {
14244  error_status = ER_DATE_CONVERSION;
14245  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14246  goto exit;
14247  }
14248  break;
14249 
14250  case DT_INVALID:
14251  case DT_NORMAL:
14252  error_status = ER_QSTR_INVALID_FORMAT;
14253  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14254  goto exit;
14255  default:
14256  break;
14257  }
14258 
14259  /* Skip space, tab, CR */
14260  while (cs < last_src && strchr (WHITE_CHARS, *cs))
14261  {
14262  cs++;
14263  }
14264 
14265  cur_format_str_ptr = next_format_str_ptr;
14266 
14267  /* Skip space, tab, CR */
14268  while (cur_format_str_ptr < last_format && strchr (WHITE_CHARS, *cur_format_str_ptr))
14269  {
14270  cur_format_str_ptr++;
14271  }
14272 
14273  if (last_format == next_format_str_ptr)
14274  {
14275  while (cs < last_src && strchr (WHITE_CHARS, *cs))
14276  {
14277  cs++;
14278  }
14279 
14280  if (cs != last_src)
14281  {
14282  error_status = ER_QSTR_INVALID_FORMAT;
14283  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14284  goto exit;
14285  }
14286  break;
14287  }
14288  }
14289 
14290 
14291  /* Both format and src should end at same time */
14292  if (cs != last_src || cur_format_str_ptr != last_format)
14293  {
14294  error_status = ER_QSTR_INVALID_FORMAT;
14295  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14296  goto exit;
14297  }
14298 
14299  year = (yearcount == 0) ? get_cur_year () : year;
14300  month = (monthcount == 0) ? get_cur_month () : month;
14301  day = (daycount == 0) ? 1 : day;
14302  week = (day_of_the_weekcount == 0) ? -1 : day_of_the_week - 1;
14303 
14304  if (week != -1 && week != db_get_day_of_week (year, month, day))
14305  {
14306  error_status = ER_DATE_CONVERSION;
14307  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14308  goto exit;
14309  }
14310 
14311  db_make_date (result_date, month, day, year);
14312 
14313  if (*(db_get_date (result_date)) == 0)
14314  {
14315  error_status = ER_DATE_CONVERSION;
14316  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14317  }
14318 
14319 exit:
14320  if (do_free_buf_str)
14321  {
14322  assert (initial_buf_str != NULL);
14323  db_private_free (NULL, initial_buf_str);
14324  }
14325  if (do_free_buf_format)
14326  {
14327  assert (initial_buf_format != NULL);
14328  db_private_free (NULL, initial_buf_format);
14329  }
14330 
14331  return error_status;
14332 }
14333 
14334 /*
14335  * db_to_time () -
14336  */
14337 int
14338 db_to_time (const DB_VALUE * src_str, const DB_VALUE * format_str, const DB_VALUE * date_lang, const DB_TYPE type,
14339  DB_VALUE * result_time)
14340 {
14341  int error_status = NO_ERROR;
14342 
14343  const char *cur_format_str_ptr, *next_format_str_ptr;
14344  char *cs; /* current source string pointer */
14345  const char *last_format, *last_src;
14346 
14347  TIMESTAMP_FORMAT cur_format;
14348 
14349  int cur_format_size;
14350 
14351  int second = 0, minute = 0, hour = 0;
14352  int time_count = 0;
14353  int mil_time_count = 0;
14354  int am = false;
14355  int pm = false;
14356 
14357  bool no_user_format;
14358  INTL_LANG date_lang_id;
14359  INTL_CODESET codeset;
14360  INTL_CODESET frmt_codeset;
14361  char stack_buf_str[64], stack_buf_format[64];
14362  char *initial_buf_str = NULL, *initial_buf_format = NULL;
14363  bool do_free_buf_str = false, do_free_buf_format = false;
14364  DB_VALUE default_format;
14365  bool has_user_format = false;
14366  bool dummy;
14367  int tzh = 0, tzm = 0;
14368  bool set_tzh = false, set_tzm = false;
14369  int start_tzr = -1, start_tzd = -1;
14370  int len_tzr = -1, len_tzd = -1;
14371  int zone_id = -1;
14372  bool is_negative_tzd = false;
14373 
14374  assert (src_str != (DB_VALUE *) NULL);
14375  assert (result_time != (DB_VALUE *) NULL);
14376  assert (date_lang != (DB_VALUE *) NULL);
14377  assert (type == DB_TYPE_TIME);
14378 
14379  if (DB_IS_NULL (src_str))
14380  {
14381  db_make_null (result_time);
14382  return error_status;
14383  }
14384 
14385  assert (DB_VALUE_TYPE (date_lang) == DB_TYPE_INTEGER);
14386  date_lang_id = lang_get_lang_id_from_flag (db_get_int (date_lang), &has_user_format, &dummy);
14387 
14388  /* now return null */
14389  if (false == is_char_string (src_str))
14390  {
14391  error_status = ER_QSTR_INVALID_DATA_TYPE;
14392  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14393  return error_status;
14394  }
14395 
14396  if (db_get_string_size (src_str) == 0)
14397  {
14398  error_status = ER_QSTR_EMPTY_STRING;
14399  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14400  return error_status;
14401  }
14402 
14403  if (db_get_string_size (src_str) > MAX_TOKEN_SIZE)
14404  {
14405  error_status = ER_QSTR_SRC_TOO_LONG;
14406  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14407  return error_status;
14408  }
14409 
14410  codeset = db_get_string_codeset (src_str);
14411  if (lang_get_specific_locale (date_lang_id, codeset) == NULL)
14412  {
14413  error_status = ER_LANG_CODESET_NOT_AVAILABLE;
14414  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 2, lang_get_lang_name_from_id (date_lang_id),
14415  lang_charset_name (codeset));
14416  return error_status;
14417  }
14418  error_status =
14419  db_check_or_create_null_term_string (src_str, stack_buf_str, sizeof (stack_buf_str), true, true, &initial_buf_str,
14420  &do_free_buf_str);
14421  if (error_status != NO_ERROR)
14422  {
14423  goto exit;
14424  }
14425 
14426  cs = initial_buf_str;
14427  last_src = cs + strlen (cs);
14428 
14429  last_src = (char *) intl_backskip_spaces (cs, last_src - 1, codeset);
14430  last_src = last_src + 1;
14431 
14432  no_user_format = (format_str == NULL) || (!has_user_format);
14433 
14434  if (no_user_format)
14435  {
14436  DB_TIME time_tmp;
14437  const char *default_format_str;
14438 
14439  /* try default CUBRID format first */
14440  assert (type == DB_TYPE_TIME);
14441 
14442  if (NO_ERROR == db_string_to_time_ex ((const char *) cs, CAST_BUFLEN (last_src - cs), &time_tmp))
14443  {
14444  db_value_put_encoded_time (result_time, &time_tmp);
14445  goto exit;
14446  }
14447 
14448  /* error parsing CUBRID default format, try the locale format, if any */
14449  default_format_str = lang_date_format_parse (date_lang_id, codeset, type, &frmt_codeset);
14450  if (default_format_str == NULL)
14451  {
14452  error_status = ER_TIME_CONVERSION;
14453  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14454  goto exit;
14455  }
14456  db_make_char (&default_format, strlen (default_format_str), default_format_str,
14457  strlen (default_format_str), frmt_codeset, LANG_GET_BINARY_COLLATION (frmt_codeset));
14458  format_str = &default_format;
14459  }
14460 
14461  if (DB_IS_NULL (format_str))
14462  {
14463  db_make_null (result_time);
14464  goto exit;
14465  }
14466 
14467  if (false == is_char_string (format_str))
14468  {
14469  error_status = ER_QSTR_INVALID_DATA_TYPE;
14470  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14471  goto exit;
14472  }
14473 
14474  if (db_get_string_size (format_str) > MAX_TOKEN_SIZE)
14475  {
14476  error_status = ER_QSTR_FORMAT_TOO_LONG;
14477  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14478  goto exit;
14479  }
14480 
14481  if (db_get_string_size (format_str) == 0)
14482  {
14483  error_status = ER_QSTR_EMPTY_STRING;
14484  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14485  goto exit;
14486  }
14487 
14488  frmt_codeset = db_get_string_codeset (format_str);
14489 
14490  error_status =
14491  db_check_or_create_null_term_string (format_str, stack_buf_format, sizeof (stack_buf_format), true, true,
14492  &initial_buf_format, &do_free_buf_format);
14493  if (error_status != NO_ERROR)
14494  {
14495  goto exit;
14496  }
14497 
14498  cur_format_str_ptr = initial_buf_format;
14499  last_format = cur_format_str_ptr + strlen (cur_format_str_ptr);
14500 
14501  /* Skip space, tab, CR */
14502  while (cs < last_src && strchr (WHITE_CHARS, *cs))
14503  {
14504  cs++;
14505  }
14506 
14507  /* Skip space, tab, CR */
14508  while (cur_format_str_ptr < last_format && strchr (WHITE_CHARS, *cur_format_str_ptr))
14509  {
14510  cur_format_str_ptr++;
14511  }
14512 
14513  while (cs < last_src)
14514  {
14515  int cmp, cs_byte_size, token_size;
14516  int am_pm_id;
14517  int k;
14518 
14519  cur_format = get_next_format (cur_format_str_ptr, frmt_codeset, type, &cur_format_size, &next_format_str_ptr);
14520  switch (cur_format)
14521  {
14522  case DT_AM:
14523  case DT_A_M:
14524  case DT_PM:
14525  case DT_P_M:
14526  if (mil_time_count != 0)
14527  {
14528  error_status = ER_QSTR_FORMAT_DUPLICATION;
14529  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14530  goto exit;
14531  }
14532  else
14533  {
14534  mil_time_count++;
14535  }
14536 
14537  error_status = get_string_date_token_id (SDT_AM_PM, date_lang_id, cs, codeset, &am_pm_id, &token_size);
14538  if (error_status != NO_ERROR)
14539  {
14540  goto exit;
14541  }
14542 
14543  if (am_pm_id > 0)
14544  {
14545  if (am_pm_id % 2)
14546  {
14547  am = true;
14548  }
14549  else
14550  {
14551  pm = true;
14552  }
14553  }
14554  else
14555  {
14556  error_status = ER_QSTR_INVALID_FORMAT;
14557  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14558  goto exit;
14559  }
14560 
14561  cs += token_size;
14562  break;
14563 
14564  case DT_HH:
14565  case DT_HH12:
14566  if (time_count != 0)
14567  {
14568  error_status = ER_QSTR_FORMAT_DUPLICATION;
14569  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14570  goto exit;
14571  }
14572  else
14573  {
14574  time_count++;
14575  }
14576 
14577  k = parse_digits (cs, &hour, 2);
14578  if (k <= 0)
14579  {
14580  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
14581  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14582  goto exit;
14583  }
14584  cs += k;
14585 
14586  if (hour < 1 || hour > 12)
14587  {
14588  error_status = ER_DATE_CONVERSION;
14589  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14590  goto exit;
14591  }
14592  break;
14593 
14594  case DT_HH24:
14595  if (time_count != 0)
14596  {
14597  error_status = ER_QSTR_FORMAT_DUPLICATION;
14598  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14599  goto exit;
14600  }
14601  else
14602  {
14603  time_count++;
14604  }
14605 
14606  if (mil_time_count != 0)
14607  {
14608  error_status = ER_QSTR_FORMAT_DUPLICATION;
14609  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14610  goto exit;
14611  }
14612  else
14613  {
14614  mil_time_count++;
14615  }
14616 
14617  k = parse_digits (cs, &hour, 2);
14618  if (k <= 0)
14619  {
14620  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
14621  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14622  goto exit;
14623  }
14624  cs += k;
14625 
14626  if (hour < 0 || hour > 23)
14627  {
14628  error_status = ER_TIME_CONVERSION;
14629  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14630  goto exit;
14631  }
14632  break;
14633 
14634  case DT_MI:
14635  k = parse_digits (cs, &minute, 2);
14636  if (k <= 0)
14637  {
14638  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
14639  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14640  goto exit;
14641  }
14642  cs += k;
14643 
14644  if (minute < 0 || minute > 59)
14645  {
14646  error_status = ER_TIME_CONVERSION;
14647  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14648  goto exit;
14649  }
14650  break;
14651 
14652  case DT_SS:
14653  k = parse_digits (cs, &second, 2);
14654  if (k <= 0)
14655  {
14656  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
14657  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14658  goto exit;
14659  }
14660  cs += k;
14661 
14662  if (second < 0 || second > 59)
14663  {
14664  error_status = ER_TIME_CONVERSION;
14665  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14666  goto exit;
14667  }
14668  break;
14669 
14670  case DT_TEXT:
14671  if (codeset != frmt_codeset)
14672  {
14673  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
14674  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14675  goto exit;
14676  }
14677  cmp = intl_case_match_tok (date_lang_id, codeset, (unsigned char *) (cur_format_str_ptr + 1),
14678  (unsigned char *) cs, cur_format_size - 2, strlen (cs), &cs_byte_size);
14679 
14680  if (cmp != 0)
14681  {
14682  error_status = ER_TIME_CONVERSION;
14683  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14684  goto exit;
14685  }
14686 
14687  cs += cs_byte_size;
14688  break;
14689 
14690  case DT_PUNCTUATION:
14691  if (strncasecmp ((const char *) cur_format_str_ptr, (const char *) cs, cur_format_size) != 0)
14692  {
14693  error_status = ER_TIME_CONVERSION;
14694  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14695  goto exit;
14696  }
14697 
14698  cs += cur_format_size;
14699  break;
14700 
14701  case DT_TZR:
14702  {
14703  if (type == DB_TYPE_TIME)
14704  {
14705  error_status = ER_QSTR_INVALID_FORMAT;
14706  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14707  goto exit;
14708  }
14709  start_tzr = CAST_BUFLEN (cs - initial_buf_str);
14710  zone_id = tz_get_best_match_zone (cs, &len_tzr);
14711  if (zone_id < 0)
14712  {
14713  error_status = ER_OBJ_INVALID_ARGUMENTS;
14714  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14715  goto exit;
14716  }
14717  cs += len_tzr;
14718  }
14719  break;
14720 
14721  case DT_TZD:
14722  {
14723  if (type == DB_TYPE_TIME)
14724  {
14725  error_status = ER_QSTR_INVALID_FORMAT;
14726  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14727  goto exit;
14728  }
14729 
14730  start_tzd = CAST_BUFLEN (cs - initial_buf_str);
14731  len_tzd = parse_tzd (cs, TZD_MAX_EXPECTED_LEN);
14732  if (len_tzd < 0)
14733  {
14734  error_status = ER_OBJ_INVALID_ARGUMENTS;
14735  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14736  goto exit;
14737  }
14738  cs += len_tzd;
14739  }
14740  break;
14741 
14742  case DT_TZH:
14743  case DT_TZM:
14744  {
14745  int *p = NULL;
14746 
14747  if (type == DB_TYPE_TIME)
14748  {
14749  error_status = ER_QSTR_INVALID_FORMAT;
14750  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14751  goto exit;
14752  }
14753 
14754  if (cur_format == DT_TZH)
14755  {
14756  p = &tzh;
14757  set_tzh = true;
14758  }
14759  else
14760  {
14761  p = &tzm;
14762  set_tzm = true;
14763  }
14764 
14765  /* Get the timezone hour offset */
14766  if (*cs == '+' || *cs == '-')
14767  {
14768  if (cur_format == DT_TZM)
14769  {
14770  error_status = ER_OBJ_INVALID_ARGUMENTS;
14771  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14772  goto exit;
14773  }
14774  if (*cs == '-')
14775  {
14776  is_negative_tzd = true;
14777  }
14778  else
14779  {
14780  is_negative_tzd = false;
14781  }
14782  cs++;
14783  }
14784 
14785  k = parse_digits (cs, p, 2);
14786  if (k <= 0)
14787  {
14788  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
14789  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14790  goto exit;
14791  }
14792  cs += k;
14793  }
14794  break;
14795 
14796  case DT_INVALID:
14797  error_status = ER_TIME_CONVERSION;
14798  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14799  goto exit;
14800  default:
14801  break;
14802  }
14803 
14804  /* Skip space, tab, CR */
14805  while (cs < last_src && strchr (WHITE_CHARS, *cs))
14806  {
14807  cs++;
14808  }
14809 
14810  cur_format_str_ptr = next_format_str_ptr;
14811 
14812  /* Skip space, tab, CR */
14813  while (cur_format_str_ptr < last_format && strchr (WHITE_CHARS, *cur_format_str_ptr))
14814  {
14815  cur_format_str_ptr++;
14816  }
14817 
14818  if (last_format == next_format_str_ptr)
14819  {
14820  while (cs < last_src && strchr (WHITE_CHARS, *cs))
14821  {
14822  cs++;
14823  }
14824 
14825  if (cs != last_src)
14826  {
14827  error_status = ER_QSTR_INVALID_FORMAT;
14828  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14829  goto exit;
14830  }
14831  break;
14832  }
14833  }
14834 
14835  /* 2. Validations */
14836  if (len_tzd > 0 || len_tzr > 0)
14837  {
14838  if (set_tzh == true || set_tzm == true)
14839  {
14840  error_status = ER_OBJ_INVALID_ARGUMENTS;
14841  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14842  goto exit;
14843  }
14844  }
14845 
14846  if (is_negative_tzd)
14847  {
14848  tzh = -tzh;
14849  tzm = -tzm;
14850  }
14851 
14852  /* Both format and src should end at same time */
14853  if (cs != last_src || cur_format_str_ptr != last_format)
14854  {
14855  error_status = ER_TIME_CONVERSION;
14856  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14857  goto exit;
14858  }
14859 
14860  if (am != 0 && pm == 0 && hour <= 12)
14861  { /* If A.M. */
14862  hour = (hour == 12) ? 0 : hour;
14863  }
14864  else if (am == 0 && pm != 0 && hour <= 12)
14865  { /* If P.M. */
14866  hour = (hour == 12) ? hour : hour + 12;
14867  }
14868  else if (am == 0 && pm == 0)
14869  { /* If military time */
14870  ;
14871  }
14872  else
14873  {
14874  error_status = ER_TIME_CONVERSION;
14875  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14876  goto exit;
14877  }
14878 
14879  db_make_time (result_time, hour, minute, second);
14880 
14881 exit:
14882  if (do_free_buf_str)
14883  {
14884  assert (initial_buf_str != NULL);
14885  db_private_free (NULL, initial_buf_str);
14886  }
14887  if (do_free_buf_format)
14888  {
14889  assert (initial_buf_format != NULL);
14890  db_private_free (NULL, initial_buf_format);
14891  }
14892 
14893  return error_status;
14894 }
14895 
14896 /*
14897  * db_to_timestamp () -
14898  */
14899 int
14900 db_to_timestamp (const DB_VALUE * src_str, const DB_VALUE * format_str, const DB_VALUE * date_lang, const DB_TYPE type,
14901  DB_VALUE * result_timestamp)
14902 {
14903  int error_status = NO_ERROR;
14904 
14905  DB_DATE tmp_date;
14906  DB_TIME tmp_time;
14907  DB_TIMESTAMP tmp_timestamp;
14908 
14909  const char *cur_format_str_ptr, *next_format_str_ptr;
14910  char *cs; /* current source string pointer */
14911  const char *last_format, *last_src;
14912 
14913  int cur_format_size;
14914  TIMESTAMP_FORMAT cur_format;
14915 
14916  int month = 0, day = 0, year = 0, day_of_the_week = 0, week = -1;
14917  int monthcount = 0, daycount = 0, yearcount = 0, day_of_the_weekcount = 0;
14918 
14919  int second = 0, minute = 0, hour = 0;
14920  int time_count = 0;
14921  int mil_time_count = 0;
14922  int am = false;
14923  int pm = false;
14924 
14925  int i;
14926  bool no_user_format;
14927  INTL_LANG date_lang_id;
14928  INTL_CODESET codeset;
14929  INTL_CODESET frmt_codeset;
14930  char stack_buf_str[64], stack_buf_format[64];
14931  char *initial_buf_str = NULL, *initial_buf_format = NULL;
14932  bool do_free_buf_str = false, do_free_buf_format = false;
14933  DB_VALUE default_format;
14934  bool has_user_format = false;
14935  bool dummy;
14936  int tzh = 0, tzm = 0;
14937  bool set_tzh = false, set_tzm = false;
14938  int start_tzr = -1, start_tzd = -1;
14939  int len_tzr = -1, len_tzd = -1;
14940  int zone_id = -1;
14941  bool is_negative_tzd = false;
14942 
14943  assert (src_str != (DB_VALUE *) NULL);
14944  assert (result_timestamp != (DB_VALUE *) NULL);
14945  assert (date_lang != (DB_VALUE *) NULL);
14946  assert (type == DB_TYPE_TIMESTAMP || type == DB_TYPE_TIMESTAMPTZ);
14947 
14948  db_make_null (&default_format);
14949 
14950  if (DB_IS_NULL (src_str))
14951  {
14952  db_make_null (result_timestamp);
14953  return error_status;
14954  }
14955 
14956  assert (DB_VALUE_TYPE (date_lang) == DB_TYPE_INTEGER);
14957  date_lang_id = lang_get_lang_id_from_flag (db_get_int (date_lang), &has_user_format, &dummy);
14958 
14959  if (false == is_char_string (src_str))
14960  {
14961  error_status = ER_QSTR_INVALID_DATA_TYPE;
14962  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14963  return error_status;
14964  }
14965 
14966  if (db_get_string_size (src_str) == 0)
14967  {
14968  error_status = ER_QSTR_EMPTY_STRING;
14969  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14970  return error_status;
14971  }
14972 
14973  if (db_get_string_size (src_str) > MAX_TOKEN_SIZE)
14974  {
14975  error_status = ER_QSTR_SRC_TOO_LONG;
14976  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
14977  return error_status;
14978  }
14979 
14980  codeset = db_get_string_codeset (src_str);
14981  if (lang_get_specific_locale (date_lang_id, codeset) == NULL)
14982  {
14983  error_status = ER_LANG_CODESET_NOT_AVAILABLE;
14984  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 2, lang_get_lang_name_from_id (date_lang_id),
14985  lang_charset_name (codeset));
14986  return error_status;
14987  }
14988 
14989  error_status =
14990  db_check_or_create_null_term_string (src_str, stack_buf_str, sizeof (stack_buf_str), true, true, &initial_buf_str,
14991  &do_free_buf_str);
14992  if (error_status != NO_ERROR)
14993  {
14994  goto exit;
14995  }
14996 
14997  cs = initial_buf_str;
14998  last_src = cs + strlen (cs);
14999 
15000  last_src = (char *) intl_backskip_spaces (cs, last_src - 1, codeset);
15001  last_src = last_src + 1;
15002 
15003  no_user_format = (format_str == NULL) || (!has_user_format);
15004 
15005  if (no_user_format)
15006  {
15007  DB_TIMESTAMP timestamp_tmp;
15008  DB_TIMESTAMPTZ timestamptz_tmp;
15009  const char *default_format_str;
15010 
15011  /* try default CUBRID format first */
15012  if (type == DB_TYPE_TIMESTAMP)
15013  {
15014  if (db_string_to_timestamp_ex ((const char *) cs, CAST_BUFLEN (last_src - cs), &timestamp_tmp) == NO_ERROR)
15015  {
15016  db_make_timestamp (result_timestamp, timestamp_tmp);
15017  goto exit;
15018  }
15019  }
15020  else
15021  {
15022  bool has_zone;
15023  if (db_string_to_timestamptz_ex ((const char *) cs, CAST_BUFLEN (last_src - cs), &timestamptz_tmp, &has_zone,
15024  false) == NO_ERROR)
15025  {
15026  db_make_timestamptz (result_timestamp, &timestamptz_tmp);
15027  goto exit;
15028  }
15029  }
15030 
15031  default_format_str = lang_date_format_parse (date_lang_id, codeset, type, &frmt_codeset);
15032  if (default_format_str == NULL)
15033  {
15034  error_status = ER_TIMESTAMP_CONVERSION;
15035  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15036  goto exit;
15037  }
15038 
15039  db_make_char (&default_format, strlen (default_format_str), default_format_str,
15040  strlen (default_format_str), frmt_codeset, LANG_GET_BINARY_COLLATION (frmt_codeset));
15041  format_str = &default_format;
15042  }
15043 
15044  if (DB_IS_NULL (format_str))
15045  {
15046  db_make_null (result_timestamp);
15047  goto exit;
15048  }
15049 
15050  if (false == is_char_string (format_str))
15051  {
15052  error_status = ER_QSTR_INVALID_DATA_TYPE;
15053  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15054  goto exit;
15055  }
15056 
15057  if (db_get_string_size (format_str) > MAX_TOKEN_SIZE)
15058  {
15059  error_status = ER_QSTR_FORMAT_TOO_LONG;
15060  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15061  goto exit;
15062  }
15063 
15064  if (db_get_string_size (format_str) == 0)
15065  {
15066  error_status = ER_QSTR_EMPTY_STRING;
15067  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15068  goto exit;
15069  }
15070 
15071  frmt_codeset = db_get_string_codeset (format_str);
15072 
15073  error_status =
15074  db_check_or_create_null_term_string (format_str, stack_buf_format, sizeof (stack_buf_format), true, true,
15075  &initial_buf_format, &do_free_buf_format);
15076  if (error_status != NO_ERROR)
15077  {
15078  goto exit;
15079  }
15080 
15081  cur_format_str_ptr = initial_buf_format;
15082  last_format = cur_format_str_ptr + strlen (cur_format_str_ptr);
15083 
15084  /* Skip space, tab, CR */
15085  while (cs < last_src && strchr (WHITE_CHARS, *cs))
15086  {
15087  cs++;
15088  }
15089 
15090  /* Skip space, tab, CR */
15091  while (cur_format_str_ptr < last_format && strchr (WHITE_CHARS, *cur_format_str_ptr))
15092  {
15093  cur_format_str_ptr++;
15094  }
15095 
15096  while (cs < last_src)
15097  {
15098  int token_size, cmp, cs_byte_size;
15099  int am_pm_id;
15100  int k;
15101 
15102  cur_format = get_next_format (cur_format_str_ptr, frmt_codeset, type, &cur_format_size, &next_format_str_ptr);
15103  switch (cur_format)
15104  {
15105  case DT_YYYY:
15106  if (yearcount != 0)
15107  {
15108  error_status = ER_QSTR_FORMAT_DUPLICATION;
15109  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15110  goto exit;
15111  }
15112  else
15113  {
15114  yearcount++;
15115  }
15116 
15117  k = parse_digits (cs, &year, 4);
15118  if (k <= 0)
15119  {
15120  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
15121  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15122  goto exit;
15123  }
15124  cs += k;
15125  break;
15126 
15127  case DT_YY:
15128  if (yearcount != 0)
15129  {
15130  error_status = ER_QSTR_FORMAT_DUPLICATION;
15131  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15132  goto exit;
15133  }
15134  else
15135  {
15136  yearcount++;
15137  }
15138 
15139  k = parse_digits (cs, &year, 2);
15140  if (k <= 0)
15141  {
15142  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
15143  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15144  goto exit;
15145  }
15146  cs += k;
15147 
15148  i = get_cur_year ();
15149  if (i == -1)
15150  {
15151  error_status = ER_SYSTEM_DATE;
15152  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15153  goto exit;
15154  }
15155 
15156  year += (i / 100) * 100;
15157  break;
15158 
15159  case DT_MM:
15160  if (monthcount != 0)
15161  {
15162  error_status = ER_QSTR_FORMAT_DUPLICATION;
15163  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15164  goto exit;
15165  }
15166  else
15167  {
15168  monthcount++;
15169  }
15170 
15171  k = parse_digits (cs, &month, 2);
15172  if (k <= 0)
15173  {
15174  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
15175  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15176  goto exit;
15177  }
15178  cs += k;
15179 
15180  if (month < 1 || month > 12)
15181  {
15182  error_status = ER_DATE_CONVERSION;
15183  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15184  goto exit;
15185  }
15186  break;
15187 
15188  case DT_MONTH:
15189  if (monthcount != 0)
15190  {
15191  error_status = ER_QSTR_FORMAT_DUPLICATION;
15192  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15193  goto exit;
15194  }
15195  else
15196  {
15197  monthcount++;
15198  }
15199 
15200  error_status = get_string_date_token_id (SDT_MONTH, date_lang_id, cs, codeset, &month, &token_size);
15201  if (error_status != NO_ERROR)
15202  {
15203  goto exit;
15204  }
15205 
15206  cs += token_size;
15207 
15208  if (month == 0)
15209  {
15210  error_status = ER_DATE_CONVERSION;
15211  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15212  goto exit;
15213  }
15214  break;
15215 
15216  case DT_MON:
15217  if (monthcount != 0)
15218  {
15219  error_status = ER_QSTR_FORMAT_DUPLICATION;
15220  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15221  goto exit;
15222  }
15223  else
15224  {
15225  monthcount++;
15226  }
15227 
15228  month = 0;
15229 
15230  error_status = get_string_date_token_id (SDT_MONTH_SHORT, date_lang_id, cs, codeset, &month, &token_size);
15231  if (error_status != NO_ERROR)
15232  {
15233  goto exit;
15234  }
15235 
15236  cs += token_size;
15237 
15238  if (month == 0)
15239  {
15240  error_status = ER_DATE_CONVERSION;
15241  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15242  goto exit;
15243  }
15244  break;
15245 
15246  case DT_DD:
15247  if (daycount != 0)
15248  {
15249  error_status = ER_QSTR_FORMAT_DUPLICATION;
15250  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15251  goto exit;
15252  }
15253  else
15254  {
15255  daycount++;
15256  }
15257 
15258  k = parse_digits (cs, &day, 2);
15259  if (k <= 0)
15260  {
15261  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
15262  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15263  goto exit;
15264  }
15265  cs += k;
15266 
15267  if (day < 0 || day > 31)
15268  {
15269  error_status = ER_DATE_CONVERSION;
15270  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15271  goto exit;
15272  }
15273  break;
15274 
15275  case DT_AM:
15276  case DT_A_M:
15277  case DT_PM:
15278  case DT_P_M:
15279  if (mil_time_count != 0)
15280  {
15281  error_status = ER_QSTR_FORMAT_DUPLICATION;
15282  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15283  goto exit;
15284  }
15285  else
15286  {
15287  mil_time_count++;
15288  }
15289 
15290  error_status = get_string_date_token_id (SDT_AM_PM, date_lang_id, cs, codeset, &am_pm_id, &token_size);
15291  if (error_status != NO_ERROR)
15292  {
15293  goto exit;
15294  }
15295 
15296  if (am_pm_id > 0)
15297  {
15298  if (am_pm_id % 2)
15299  {
15300  am = true;
15301  }
15302  else
15303  {
15304  pm = true;
15305  }
15306  }
15307  else
15308  {
15309  error_status = ER_QSTR_INVALID_FORMAT;
15310  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15311  goto exit;
15312  }
15313 
15314  cs += token_size;
15315  break;
15316 
15317  case DT_HH:
15318  case DT_HH12:
15319  if (time_count != 0)
15320  {
15321  error_status = ER_QSTR_FORMAT_DUPLICATION;
15322  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15323  goto exit;
15324  }
15325  else
15326  {
15327  time_count++;
15328  }
15329 
15330  k = parse_digits (cs, &hour, 2);
15331  if (k <= 0)
15332  {
15333  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
15334  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15335  goto exit;
15336  }
15337  cs += k;
15338 
15339  if (hour < 1 || hour > 12)
15340  {
15341  error_status = ER_TIME_CONVERSION;
15342  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15343  goto exit;
15344  }
15345  break;
15346 
15347  case DT_HH24:
15348  if (time_count != 0)
15349  {
15350  error_status = ER_QSTR_FORMAT_DUPLICATION;
15351  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15352  goto exit;
15353  }
15354  else
15355  {
15356  time_count++;
15357  }
15358 
15359  if (mil_time_count != 0)
15360  {
15361  error_status = ER_QSTR_FORMAT_DUPLICATION;
15362  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15363  goto exit;
15364  }
15365  else
15366  {
15367  mil_time_count++;
15368  }
15369 
15370  k = parse_digits (cs, &hour, 2);
15371  if (k <= 0)
15372  {
15373  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
15374  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15375  goto exit;
15376  }
15377  cs += k;
15378 
15379  if (hour < 0 || hour > 23)
15380  {
15381  error_status = ER_TIME_CONVERSION;
15382  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15383  goto exit;
15384  }
15385  break;
15386 
15387  case DT_MI:
15388  k = parse_digits (cs, &minute, 2);
15389  if (k <= 0)
15390  {
15391  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
15392  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15393  goto exit;
15394  }
15395  cs += k;
15396 
15397  if (minute < 0 || minute > 59)
15398  {
15399  error_status = ER_TIME_CONVERSION;
15400  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15401  goto exit;
15402  }
15403  break;
15404 
15405  case DT_SS:
15406  k = parse_digits (cs, &second, 2);
15407  if (k <= 0)
15408  {
15409  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
15410  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15411  goto exit;
15412  }
15413  cs += k;
15414 
15415  if (second < 0 || second > 59)
15416  {
15417  error_status = ER_TIME_CONVERSION;
15418  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15419  goto exit;
15420  }
15421  break;
15422 
15423  case DT_TEXT:
15424  if (codeset != frmt_codeset)
15425  {
15426  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
15427  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15428  goto exit;
15429  }
15430 
15431  cmp = intl_case_match_tok (date_lang_id, codeset, (unsigned char *) (cur_format_str_ptr + 1),
15432  (unsigned char *) cs, cur_format_size - 2, strlen (cs), &cs_byte_size);
15433 
15434  if (cmp != 0)
15435  {
15436  error_status = ER_QSTR_INVALID_FORMAT;
15437  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15438  goto exit;
15439  }
15440 
15441  cs += cs_byte_size;
15442  break;
15443 
15444  case DT_PUNCTUATION:
15445  if (strncasecmp ((const char *) (void *) cur_format_str_ptr, (const char *) cs, cur_format_size) != 0)
15446  {
15447  error_status = ER_QSTR_INVALID_FORMAT;
15448  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15449  goto exit;
15450  }
15451  cs += cur_format_size;
15452  break;
15453 
15454  case DT_CC:
15455  case DT_Q:
15456  error_status = ER_QSTR_INVALID_FORMAT;
15457  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15458  goto exit;
15459 
15460  case DT_DAY:
15461  if (day_of_the_weekcount != 0)
15462  {
15463  error_status = ER_QSTR_FORMAT_DUPLICATION;
15464  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15465  goto exit;
15466  }
15467  else
15468  {
15469  day_of_the_weekcount++;
15470  }
15471 
15472  error_status = get_string_date_token_id (SDT_DAY, date_lang_id, cs, codeset, &day_of_the_week, &token_size);
15473  if (error_status != NO_ERROR)
15474  {
15475  goto exit;
15476  }
15477 
15478  cs += token_size;
15479 
15480  if (day_of_the_week == 0)
15481  {
15482  error_status = ER_DATE_CONVERSION;
15483  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15484  goto exit;
15485  }
15486  break;
15487 
15488  case DT_DY:
15489  if (day_of_the_weekcount != 0)
15490  {
15491  error_status = ER_QSTR_FORMAT_DUPLICATION;
15492  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15493  goto exit;
15494  }
15495  else
15496  {
15497  day_of_the_weekcount++;
15498  }
15499 
15500  error_status =
15501  get_string_date_token_id (SDT_DAY_SHORT, date_lang_id, cs, codeset, &day_of_the_week, &token_size);
15502  if (error_status != NO_ERROR)
15503  {
15504  goto exit;
15505  }
15506 
15507  cs += token_size;
15508 
15509  if (day_of_the_week == 0)
15510  {
15511  error_status = ER_DATE_CONVERSION;
15512  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15513  goto exit;
15514  }
15515  break;
15516 
15517  case DT_D:
15518  if (day_of_the_weekcount != 0)
15519  {
15520  error_status = ER_QSTR_FORMAT_DUPLICATION;
15521  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15522  goto exit;
15523  }
15524  else
15525  {
15526  day_of_the_weekcount++;
15527  }
15528 
15529  k = parse_digits (cs, &day_of_the_week, 1);
15530  if (k <= 0)
15531  {
15532  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
15533  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15534  goto exit;
15535  }
15536  cs += k;
15537 
15538  if (day_of_the_week < 1 || day_of_the_week > 7)
15539  {
15540  error_status = ER_DATE_CONVERSION;
15541  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15542  goto exit;
15543  }
15544  break;
15545 
15546  case DT_TZR:
15547  {
15548  if (type == DB_TYPE_TIMESTAMP)
15549  {
15550  error_status = ER_QSTR_INVALID_FORMAT;
15551  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15552  goto exit;
15553  }
15554  start_tzr = CAST_BUFLEN (cs - initial_buf_str);
15555  zone_id = tz_get_best_match_zone (cs, &len_tzr);
15556  if (zone_id < 0)
15557  {
15558  error_status = ER_OBJ_INVALID_ARGUMENTS;
15559  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15560  goto exit;
15561  }
15562  cs += len_tzr;
15563  }
15564  break;
15565 
15566  case DT_TZD:
15567  {
15568  if (type == DB_TYPE_TIMESTAMP)
15569  {
15570  error_status = ER_QSTR_INVALID_FORMAT;
15571  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15572  goto exit;
15573  }
15574 
15575  start_tzd = CAST_BUFLEN (cs - initial_buf_str);
15576  len_tzd = parse_tzd (cs, TZD_MAX_EXPECTED_LEN);
15577  if (len_tzd < 0)
15578  {
15579  error_status = ER_OBJ_INVALID_ARGUMENTS;
15580  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15581  goto exit;
15582  }
15583  cs += len_tzd;
15584  }
15585  break;
15586 
15587  case DT_TZH:
15588  case DT_TZM:
15589  {
15590  int *p = NULL;
15591 
15592  if (type == DB_TYPE_TIMESTAMP)
15593  {
15594  error_status = ER_QSTR_INVALID_FORMAT;
15595  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15596  goto exit;
15597  }
15598 
15599  if (cur_format == DT_TZH)
15600  {
15601  p = &tzh;
15602  set_tzh = true;
15603  }
15604  else
15605  {
15606  p = &tzm;
15607  set_tzm = true;
15608  }
15609 
15610  /* Get the timezone hour offset */
15611  if (*cs == '+' || *cs == '-')
15612  {
15613  if (cur_format == DT_TZM)
15614  {
15615  error_status = ER_OBJ_INVALID_ARGUMENTS;
15616  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15617  goto exit;
15618  }
15619  if (*cs == '-')
15620  {
15621  is_negative_tzd = true;
15622  }
15623  else
15624  {
15625  is_negative_tzd = false;
15626  }
15627  cs++;
15628  }
15629 
15630  k = parse_digits (cs, p, 2);
15631  if (k <= 0)
15632  {
15633  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
15634  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15635  goto exit;
15636  }
15637  cs += k;
15638  }
15639  break;
15640 
15641  case DT_NORMAL:
15642  case DT_INVALID:
15643  error_status = ER_QSTR_INVALID_FORMAT;
15644  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15645  goto exit;
15646  default:
15647  break;
15648  }
15649 
15650  /* Skip space, tab, CR */
15651  while (cs < last_src && strchr (WHITE_CHARS, *cs))
15652  {
15653  cs++;
15654  }
15655 
15656  cur_format_str_ptr = next_format_str_ptr;
15657 
15658  /* Skip space, tab, CR */
15659  while (cur_format_str_ptr < last_format && strchr (WHITE_CHARS, *cur_format_str_ptr))
15660  {
15661  cur_format_str_ptr++;
15662  }
15663 
15664  if (last_format == next_format_str_ptr)
15665  {
15666  while (cs < last_src && strchr (WHITE_CHARS, *cs))
15667  {
15668  cs++;
15669  }
15670 
15671  if (cs != last_src)
15672  {
15673  error_status = ER_QSTR_INVALID_FORMAT;
15674  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15675  goto exit;
15676  }
15677  break;
15678  }
15679  }
15680 
15681  /* 2. Validations */
15682  if (len_tzd > 0 || len_tzr > 0)
15683  {
15684  if (set_tzh == true || set_tzm == true)
15685  {
15686  error_status = ER_OBJ_INVALID_ARGUMENTS;
15687  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15688  goto exit;
15689  }
15690  }
15691  if (is_negative_tzd)
15692  {
15693  tzh = -tzh;
15694  tzm = -tzm;
15695  }
15696 
15697  /* Both format and src should end at same time */
15698  if (cs != last_src || cur_format_str_ptr != last_format)
15699  {
15700  error_status = ER_QSTR_INVALID_FORMAT;
15701  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15702  goto exit;
15703  }
15704 
15705  /************** Check DATE ****************/
15706  year = (yearcount == 0) ? get_cur_year () : year;
15707  month = (monthcount == 0) ? get_cur_month () : month;
15708  day = (daycount == 0) ? 1 : day;
15709  week = (day_of_the_weekcount == 0) ? -1 : day_of_the_week - 1;
15710 
15711  if (week != -1 && week != db_get_day_of_week (year, month, day))
15712  {
15713  error_status = ER_DATE_CONVERSION;
15714  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15715  goto exit;
15716  }
15717 
15718  if (db_date_encode (&tmp_date, month, day, year) != NO_ERROR)
15719  {
15720  error_status = ER_DATE_CONVERSION;
15721  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15722  goto exit;
15723  }
15724 
15725  /************** Check TIME ****************/
15726  if (am != 0 && pm == 0 && hour <= 12)
15727  { /* If A.M. */
15728  hour = (hour == 12) ? 0 : hour;
15729  }
15730  else if (am == 0 && pm != 0 && hour <= 12)
15731  { /* If P.M. */
15732  hour = (hour == 12) ? hour : hour + 12;
15733  }
15734  else if (am == 0 && pm == 0)
15735  { /* If military time */
15736  ;
15737  }
15738  else
15739  {
15740  error_status = ER_DATE_CONVERSION;
15741  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15742  goto exit;
15743  }
15744 
15745  db_time_encode (&tmp_time, hour, minute, second);
15746 
15747  if (type == DB_TYPE_TIMESTAMP)
15748  {
15749  if (db_timestamp_encode_ses (&tmp_date, &tmp_time, &tmp_timestamp, NULL) != NO_ERROR)
15750  {
15751  error_status = ER_DATE_CONVERSION;
15752  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15753  goto exit;
15754  }
15755  db_make_timestamp (result_timestamp, tmp_timestamp);
15756  }
15757  else
15758  {
15760  if (set_tzh == true || set_tzm == true)
15761  {
15762  error_status = tz_create_timestamptz_from_offset (&tmp_date, &tmp_time, tzh, tzm, &db_timestamptz);
15763 
15764  if (error_status != NO_ERROR)
15765  {
15766  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15767  goto exit;
15768  }
15769  }
15770  else
15771  {
15772  TZ_REGION session_tz_region;
15773  const char *dst = NULL;
15774 
15775  if (len_tzd > 0)
15776  {
15777  assert (start_tzd >= 0);
15778  dst = initial_buf_str + start_tzd;
15779  }
15780  tz_get_session_tz_region (&session_tz_region);
15781  error_status =
15782  tz_create_timestamptz_from_zoneid_and_tzd (&tmp_date, &tmp_time, &session_tz_region, zone_id, dst, len_tzd,
15783  &db_timestamptz);
15784 
15785  if (error_status != NO_ERROR)
15786  {
15787  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15788  goto exit;
15789  }
15790  }
15791  db_make_timestamptz (result_timestamp, &db_timestamptz);
15792  }
15793 
15794 exit:
15795  if (do_free_buf_str)
15796  {
15797  assert (initial_buf_str != NULL);
15798  db_private_free (NULL, initial_buf_str);
15799  }
15800  if (do_free_buf_format)
15801  {
15802  assert (initial_buf_format != NULL);
15803  db_private_free (NULL, initial_buf_format);
15804  }
15805 
15806  return error_status;
15807 }
15808 
15809 /*
15810  * db_to_datetime () -
15811  */
15812 int
15813 db_to_datetime (const DB_VALUE * src_str, const DB_VALUE * format_str, const DB_VALUE * date_lang, const DB_TYPE type,
15814  DB_VALUE * result_datetime)
15815 {
15816  int error_status = NO_ERROR;
15817 
15818  DB_DATETIME tmp_datetime;
15819 
15820  const char *cur_format_str_ptr, *next_format_str_ptr;
15821  char *cs; /* current source string pointer */
15822  const char *last_format, *last_src;
15823 
15824  int cur_format_size;
15825  TIMESTAMP_FORMAT cur_format;
15826 
15827  int month = 0, day = 0, year = 0, day_of_the_week = 0, week = -1;
15828  int monthcount = 0, daycount = 0, yearcount = 0, day_of_the_weekcount = 0;
15829 
15830  double fraction;
15831  int millisecond = 0, second = 0, minute = 0, hour = 0;
15832  int time_count = 0;
15833  int mil_time_count = 0;
15834  int am = false;
15835  int pm = false;
15836 
15837  int i;
15838  bool no_user_format;
15839  INTL_LANG date_lang_id;
15840  INTL_CODESET codeset;
15841  INTL_CODESET frmt_codeset;
15842  char stack_buf_str[64], stack_buf_format[64];
15843  char *initial_buf_str = NULL, *initial_buf_format = NULL;
15844  bool do_free_buf_str = false, do_free_buf_format = false;
15845  DB_VALUE default_format;
15846  bool has_user_format = false;
15847  bool dummy;
15848  int tzh = 0, tzm = 0;
15849  bool set_tzh = false, set_tzm = false;
15850  int start_tzr = -1, start_tzd = -1;
15851  int len_tzr = -1, len_tzd = -1;
15852  int zone_id = -1;
15853  bool is_negative_tzd = false;
15854 
15855  assert (src_str != (DB_VALUE *) NULL);
15856  assert (result_datetime != (DB_VALUE *) NULL);
15857  assert (type == DB_TYPE_DATETIME || type == DB_TYPE_DATETIMETZ);
15858 
15859  db_make_null (&default_format);
15860 
15861  if (DB_IS_NULL (src_str))
15862  {
15863  db_make_null (result_datetime);
15864  return error_status;
15865  }
15866 
15867  assert (DB_VALUE_TYPE (date_lang) == DB_TYPE_INTEGER);
15868  date_lang_id = lang_get_lang_id_from_flag (db_get_int (date_lang), &has_user_format, &dummy);
15869 
15870  if (false == is_char_string (src_str))
15871  {
15872  error_status = ER_QSTR_INVALID_DATA_TYPE;
15873  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15874  return error_status;
15875  }
15876 
15877  if (db_get_string_size (src_str) == 0)
15878  {
15879  error_status = ER_QSTR_EMPTY_STRING;
15880  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15881  return error_status;
15882  }
15883 
15884  if (db_get_string_size (src_str) > MAX_TOKEN_SIZE)
15885  {
15886  error_status = ER_QSTR_SRC_TOO_LONG;
15887  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15888  return error_status;
15889  }
15890 
15891  codeset = db_get_string_codeset (src_str);
15892  if (lang_get_specific_locale (date_lang_id, codeset) == NULL)
15893  {
15894  error_status = ER_LANG_CODESET_NOT_AVAILABLE;
15895  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 2, lang_get_lang_name_from_id (date_lang_id),
15896  lang_charset_name (codeset));
15897  return error_status;
15898  }
15899 
15900  error_status =
15901  db_check_or_create_null_term_string (src_str, stack_buf_str, sizeof (stack_buf_str), true, true, &initial_buf_str,
15902  &do_free_buf_str);
15903  if (error_status != NO_ERROR)
15904  {
15905  goto exit;
15906  }
15907 
15908  cs = initial_buf_str;
15909  last_src = cs + strlen (cs);
15910 
15911  last_src = (char *) intl_backskip_spaces (cs, last_src - 1, codeset);
15912  last_src = last_src + 1;
15913 
15914  no_user_format = (format_str == NULL) || (!has_user_format);
15915 
15916  if (no_user_format)
15917  {
15918  DB_DATETIME datetime_tmp;
15919  DB_DATETIMETZ datetimetz_tmp;
15920  const char *default_format_str;
15921 
15922  /* try default CUBRID format first */
15923  if (type == DB_TYPE_DATETIME)
15924  {
15925  if (db_string_to_datetime_ex ((const char *) cs, CAST_BUFLEN (last_src - cs), &datetime_tmp) == NO_ERROR)
15926  {
15927  db_make_datetime (result_datetime, &datetime_tmp);
15928  goto exit;
15929  }
15930  }
15931  else
15932  {
15933  bool has_zone;
15934  if (db_string_to_datetimetz_ex ((const char *) cs, CAST_BUFLEN (last_src - cs), &datetimetz_tmp, &has_zone)
15935  == NO_ERROR)
15936  {
15937  db_make_datetimetz (result_datetime, &datetimetz_tmp);
15938  goto exit;
15939  }
15940  }
15941 
15942  default_format_str = lang_date_format_parse (date_lang_id, codeset, type, &frmt_codeset);
15943  if (default_format_str == NULL)
15944  {
15945  error_status = ER_TIMESTAMP_CONVERSION;
15946  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15947  goto exit;
15948  }
15949 
15950  db_make_char (&default_format, strlen (default_format_str), default_format_str,
15951  strlen (default_format_str), frmt_codeset, LANG_GET_BINARY_COLLATION (frmt_codeset));
15952  format_str = &default_format;
15953  }
15954  if (DB_IS_NULL (format_str))
15955  {
15956  db_make_null (result_datetime);
15957  goto exit;
15958  }
15959 
15960  if (false == is_char_string (format_str))
15961  {
15962  error_status = ER_QSTR_INVALID_DATA_TYPE;
15963  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15964  goto exit;
15965  }
15966 
15967  if (db_get_string_size (format_str) > MAX_TOKEN_SIZE)
15968  {
15969  error_status = ER_QSTR_FORMAT_TOO_LONG;
15970  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15971  goto exit;
15972  }
15973 
15974  if (db_get_string_size (format_str) == 0)
15975  {
15976  error_status = ER_QSTR_EMPTY_STRING;
15977  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
15978  goto exit;
15979  }
15980 
15981  frmt_codeset = db_get_string_codeset (format_str);
15982 
15983  error_status =
15984  db_check_or_create_null_term_string (format_str, stack_buf_format, sizeof (stack_buf_format), true, true,
15985  &initial_buf_format, &do_free_buf_format);
15986  if (error_status != NO_ERROR)
15987  {
15988  goto exit;
15989  }
15990 
15991  cur_format_str_ptr = initial_buf_format;
15992  last_format = cur_format_str_ptr + strlen (cur_format_str_ptr);
15993 
15994  /* Skip space, tab, CR */
15995  while (cs < last_src && strchr (WHITE_CHARS, *cs))
15996  {
15997  cs++;
15998  }
15999 
16000  /* Skip space, tab, CR */
16001  while (cur_format_str_ptr < last_format && strchr (WHITE_CHARS, *cur_format_str_ptr))
16002  {
16003  cur_format_str_ptr++;
16004  }
16005 
16006  while (cs < last_src)
16007  {
16008  int token_size, cmp, cs_byte_size;
16009  int am_pm_id;
16010  int k;
16011 
16012  cur_format = get_next_format (cur_format_str_ptr, frmt_codeset, type, &cur_format_size, &next_format_str_ptr);
16013  switch (cur_format)
16014  {
16015  case DT_YYYY:
16016  if (yearcount != 0)
16017  {
16018  error_status = ER_QSTR_FORMAT_DUPLICATION;
16019  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16020  goto exit;
16021  }
16022  else
16023  {
16024  yearcount++;
16025  }
16026 
16027  k = parse_digits (cs, &year, 4);
16028  if (k <= 0)
16029  {
16030  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
16031  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16032  goto exit;
16033  }
16034  cs += k;
16035  break;
16036 
16037  case DT_YY:
16038  if (yearcount != 0)
16039  {
16040  error_status = ER_QSTR_FORMAT_DUPLICATION;
16041  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16042  goto exit;
16043  }
16044  else
16045  {
16046  yearcount++;
16047  }
16048 
16049  k = parse_digits (cs, &year, 2);
16050  if (k <= 0)
16051  {
16052  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
16053  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16054  goto exit;
16055  }
16056  cs += k;
16057 
16058  i = get_cur_year ();
16059  if (i == -1)
16060  {
16061  error_status = ER_SYSTEM_DATE;
16062  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16063  goto exit;
16064  }
16065 
16066  year += (i / 100) * 100;
16067  break;
16068 
16069  case DT_MM:
16070  if (monthcount != 0)
16071  {
16072  error_status = ER_QSTR_FORMAT_DUPLICATION;
16073  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16074  goto exit;
16075  }
16076  else
16077  {
16078  monthcount++;
16079  }
16080 
16081  k = parse_digits (cs, &month, 2);
16082  if (k <= 0)
16083  {
16084  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
16085  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16086  goto exit;
16087  }
16088  cs += k;
16089 
16090  if (month < 1 || month > 12)
16091  {
16092  error_status = ER_DATE_CONVERSION;
16093  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16094  goto exit;
16095  }
16096  break;
16097 
16098  case DT_MONTH:
16099  if (monthcount != 0)
16100  {
16101  error_status = ER_QSTR_FORMAT_DUPLICATION;
16102  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16103  goto exit;
16104  }
16105  else
16106  {
16107  monthcount++;
16108  }
16109 
16110  error_status = get_string_date_token_id (SDT_MONTH, date_lang_id, cs, codeset, &month, &token_size);
16111  if (error_status != NO_ERROR)
16112  {
16113  goto exit;
16114  }
16115 
16116  cs += token_size;
16117 
16118  if (month == 0)
16119  {
16120  error_status = ER_DATE_CONVERSION;
16121  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16122  goto exit;
16123  }
16124  break;
16125 
16126  case DT_MON:
16127  if (monthcount != 0)
16128  {
16129  error_status = ER_QSTR_FORMAT_DUPLICATION;
16130  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16131  goto exit;
16132  }
16133  else
16134  {
16135  monthcount++;
16136  }
16137 
16138  month = 0;
16139 
16140  error_status = get_string_date_token_id (SDT_MONTH_SHORT, date_lang_id, cs, codeset, &month, &token_size);
16141  if (error_status != NO_ERROR)
16142  {
16143  goto exit;
16144  }
16145 
16146  cs += token_size;
16147 
16148  if (month == 0)
16149  {
16150  error_status = ER_DATE_CONVERSION;
16151  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16152  goto exit;
16153  }
16154  break;
16155 
16156  case DT_DD:
16157  if (daycount != 0)
16158  {
16159  error_status = ER_QSTR_FORMAT_DUPLICATION;
16160  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16161  goto exit;
16162  }
16163  else
16164  {
16165  daycount++;
16166  }
16167 
16168  k = parse_digits (cs, &day, 2);
16169  if (k <= 0)
16170  {
16171  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
16172  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16173  goto exit;
16174  }
16175  cs += k;
16176 
16177  if (day < 0 || day > 31)
16178  {
16179  error_status = ER_DATE_CONVERSION;
16180  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16181  goto exit;
16182  }
16183  break;
16184 
16185  case DT_AM:
16186  case DT_A_M:
16187  case DT_PM:
16188  case DT_P_M:
16189  if (mil_time_count != 0)
16190  {
16191  error_status = ER_QSTR_FORMAT_DUPLICATION;
16192  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16193  goto exit;
16194  }
16195  else
16196  {
16197  mil_time_count++;
16198  }
16199 
16200  error_status = get_string_date_token_id (SDT_AM_PM, date_lang_id, cs, codeset, &am_pm_id, &token_size);
16201  if (error_status != NO_ERROR)
16202  {
16203  goto exit;
16204  }
16205 
16206  if (am_pm_id > 0)
16207  {
16208  if (am_pm_id % 2)
16209  {
16210  am = true;
16211  }
16212  else
16213  {
16214  pm = true;
16215  }
16216  }
16217  else
16218  {
16219  error_status = ER_QSTR_INVALID_FORMAT;
16220  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16221  goto exit;
16222  }
16223 
16224  cs += token_size;
16225  break;
16226 
16227  case DT_H:
16228  if (time_count != 0)
16229  {
16230  error_status = ER_QSTR_FORMAT_DUPLICATION;
16231  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16232  goto exit;
16233  }
16234  else
16235  {
16236  time_count++;
16237  }
16238 
16239  k = parse_digits (cs, &hour, 1);
16240  if (k <= 0)
16241  {
16242  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
16243  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16244  goto exit;
16245  }
16246  cs += k;
16247  if (hour < 1 || hour > 12)
16248  {
16249  error_status = ER_TIME_CONVERSION;
16250  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16251  goto exit;
16252  }
16253  break;
16254 
16255  case DT_HH:
16256  case DT_HH12:
16257  if (time_count != 0)
16258  {
16259  error_status = ER_QSTR_FORMAT_DUPLICATION;
16260  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16261  goto exit;
16262  }
16263  else
16264  {
16265  time_count++;
16266  }
16267 
16268  k = parse_digits (cs, &hour, 2);
16269  if (k <= 0)
16270  {
16271  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
16272  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16273  goto exit;
16274  }
16275  cs += k;
16276 
16277  if (hour < 1 || hour > 12)
16278  {
16279  error_status = ER_TIME_CONVERSION;
16280  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16281  goto exit;
16282  }
16283  break;
16284 
16285  case DT_HH24:
16286  if (time_count != 0)
16287  {
16288  error_status = ER_QSTR_FORMAT_DUPLICATION;
16289  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16290  goto exit;
16291  }
16292  else
16293  {
16294  time_count++;
16295  }
16296 
16297  if (mil_time_count != 0)
16298  {
16299  error_status = ER_QSTR_FORMAT_DUPLICATION;
16300  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16301  goto exit;
16302  }
16303  else
16304  {
16305  mil_time_count++;
16306  }
16307 
16308  k = parse_digits (cs, &hour, 2);
16309  if (k <= 0)
16310  {
16311  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
16312  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16313  goto exit;
16314  }
16315  cs += k;
16316 
16317  if (hour < 0 || hour > 23)
16318  {
16319  error_status = ER_TIME_CONVERSION;
16320  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16321  goto exit;
16322  }
16323  break;
16324 
16325  case DT_MI:
16326  k = parse_digits (cs, &minute, 2);
16327  if (k <= 0)
16328  {
16329  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
16330  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16331  goto exit;
16332  }
16333  cs += k;
16334 
16335  if (minute < 0 || minute > 59)
16336  {
16337  error_status = ER_TIME_CONVERSION;
16338  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16339  goto exit;
16340  }
16341  break;
16342 
16343  case DT_SS:
16344  k = parse_digits (cs, &second, 2);
16345  if (k <= 0)
16346  {
16347  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
16348  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16349  goto exit;
16350  }
16351  cs += k;
16352 
16353  if (second < 0 || second > 59)
16354  {
16355  error_status = ER_TIME_CONVERSION;
16356  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16357  goto exit;
16358  }
16359  break;
16360 
16361  case DT_MS:
16362  if (!char_isdigit (*cs))
16363  {
16364  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
16365  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16366  goto exit;
16367  }
16368 
16369  for (i = 0, fraction = 100; char_isdigit (*cs); cs++, i++)
16370  {
16371  millisecond += (int) ((*cs - '0') * fraction + 0.5);
16372  fraction /= 10;
16373  }
16374 
16375  if (millisecond < 0 || millisecond > 999)
16376  {
16377  error_status = ER_TIME_CONVERSION;
16378  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16379  goto exit;
16380  }
16381  break;
16382 
16383  case DT_TEXT:
16384  if (codeset != frmt_codeset)
16385  {
16386  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
16387  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16388  goto exit;
16389  }
16390  cmp = intl_case_match_tok (date_lang_id, codeset, (unsigned char *) (cur_format_str_ptr + 1),
16391  (unsigned char *) cs, cur_format_size - 2, strlen (cs), &cs_byte_size);
16392 
16393  if (cmp != 0)
16394  {
16395  error_status = ER_QSTR_INVALID_FORMAT;
16396  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16397  goto exit;
16398  }
16399 
16400  cs += cs_byte_size;
16401  break;
16402 
16403  case DT_PUNCTUATION:
16404  if (strncasecmp ((const char *) (void *) cur_format_str_ptr, (const char *) cs, cur_format_size) != 0)
16405  {
16406  error_status = ER_QSTR_INVALID_FORMAT;
16407  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16408  goto exit;
16409  }
16410 
16411  cs += cur_format_size;
16412  break;
16413 
16414  case DT_CC:
16415  case DT_Q:
16416  error_status = ER_QSTR_INVALID_FORMAT;
16417  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16418  goto exit;
16419 
16420  case DT_DAY:
16421  if (day_of_the_weekcount != 0)
16422  {
16423  error_status = ER_QSTR_FORMAT_DUPLICATION;
16424  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16425  goto exit;
16426  }
16427  else
16428  {
16429  day_of_the_weekcount++;
16430  }
16431 
16432  error_status = get_string_date_token_id (SDT_DAY, date_lang_id, cs, codeset, &day_of_the_week, &token_size);
16433  if (error_status != NO_ERROR)
16434  {
16435  goto exit;
16436  }
16437 
16438  cs += token_size;
16439 
16440  if (day_of_the_week == 0)
16441  {
16442  error_status = ER_DATE_CONVERSION;
16443  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16444  goto exit;
16445  }
16446  break;
16447 
16448  case DT_DY:
16449  if (day_of_the_weekcount != 0)
16450  {
16451  error_status = ER_QSTR_FORMAT_DUPLICATION;
16452  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16453  goto exit;
16454  }
16455  else
16456  {
16457  day_of_the_weekcount++;
16458  }
16459 
16460  error_status =
16461  get_string_date_token_id (SDT_DAY_SHORT, date_lang_id, cs, codeset, &day_of_the_week, &token_size);
16462  if (error_status != NO_ERROR)
16463  {
16464  goto exit;
16465  }
16466 
16467  cs += token_size;
16468 
16469  if (day_of_the_week == 0)
16470  {
16471  error_status = ER_DATE_CONVERSION;
16472  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16473  goto exit;
16474  }
16475  break;
16476 
16477  case DT_D:
16478  if (day_of_the_weekcount != 0)
16479  {
16480  error_status = ER_QSTR_FORMAT_DUPLICATION;
16481  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16482  goto exit;
16483  }
16484  else
16485  {
16486  day_of_the_weekcount++;
16487  }
16488 
16489  k = parse_digits (cs, &day_of_the_week, 1);
16490  if (k <= 0)
16491  {
16492  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
16493  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16494  goto exit;
16495  }
16496  cs += k;
16497 
16498  if (day_of_the_week < 1 || day_of_the_week > 7)
16499  {
16500  error_status = ER_DATE_CONVERSION;
16501  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16502  goto exit;
16503  }
16504  break;
16505 
16506  case DT_TZR:
16507  {
16508  if (type == DB_TYPE_DATETIME)
16509  {
16510  error_status = ER_QSTR_INVALID_FORMAT;
16511  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16512  goto exit;
16513  }
16514  start_tzr = CAST_BUFLEN (cs - initial_buf_str);
16515  zone_id = tz_get_best_match_zone (cs, &len_tzr);
16516  if (zone_id < 0)
16517  {
16518  error_status = ER_OBJ_INVALID_ARGUMENTS;
16519  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16520  goto exit;
16521  }
16522  cs += len_tzr;
16523  }
16524  break;
16525 
16526  case DT_TZD:
16527  {
16528  if (type == DB_TYPE_DATETIME)
16529  {
16530  error_status = ER_QSTR_INVALID_FORMAT;
16531  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16532  goto exit;
16533  }
16534 
16535  start_tzd = CAST_BUFLEN (cs - initial_buf_str);
16536  len_tzd = parse_tzd (cs, TZD_MAX_EXPECTED_LEN);
16537  if (len_tzd < 0)
16538  {
16539  error_status = ER_OBJ_INVALID_ARGUMENTS;
16540  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16541  goto exit;
16542  }
16543  cs += len_tzd;
16544  }
16545  break;
16546 
16547  case DT_TZH:
16548  case DT_TZM:
16549  {
16550  int *p = NULL;
16551 
16552  if (type == DB_TYPE_DATETIME)
16553  {
16554  error_status = ER_QSTR_INVALID_FORMAT;
16555  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16556  goto exit;
16557  }
16558 
16559  if (cur_format == DT_TZH)
16560  {
16561  p = &tzh;
16562  set_tzh = true;
16563  }
16564  else
16565  {
16566  p = &tzm;
16567  set_tzm = true;
16568  }
16569 
16570  /* Get the timezone hour offset */
16571  if (*cs == '+' || *cs == '-')
16572  {
16573  if (cur_format == DT_TZM)
16574  {
16575  error_status = ER_OBJ_INVALID_ARGUMENTS;
16576  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16577  goto exit;
16578  }
16579  if (*cs == '-')
16580  {
16581  is_negative_tzd = true;
16582  }
16583  else
16584  {
16585  is_negative_tzd = false;
16586  }
16587  cs++;
16588  }
16589 
16590  k = parse_digits (cs, p, 2);
16591  if (k <= 0)
16592  {
16593  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
16594  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16595  goto exit;
16596  }
16597  cs += k;
16598  }
16599  break;
16600 
16601  case DT_NORMAL:
16602  case DT_INVALID:
16603  error_status = ER_QSTR_INVALID_FORMAT;
16604  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16605  goto exit;
16606  default:
16607  break;
16608  }
16609 
16610  while (cs < last_src && strchr (WHITE_CHARS, *cs))
16611  {
16612  cs++;
16613  }
16614 
16615  cur_format_str_ptr = next_format_str_ptr;
16616 
16617  /* Skip space, tab, CR */
16618  while (cur_format_str_ptr < last_format && strchr (WHITE_CHARS, *cur_format_str_ptr))
16619  {
16620  cur_format_str_ptr++;
16621  }
16622 
16623  if (last_format == next_format_str_ptr)
16624  {
16625  while (cs < last_src && strchr (WHITE_CHARS, *cs))
16626  {
16627  cs++;
16628  }
16629 
16630  if (cs != last_src)
16631  {
16632  error_status = ER_QSTR_INVALID_FORMAT;
16633  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16634  goto exit;
16635  }
16636  break;
16637  }
16638  }
16639 
16640  /* 2. Validations */
16641  if (len_tzd > 0 || len_tzr > 0)
16642  {
16643  if (set_tzh == true || set_tzm == true)
16644  {
16645  error_status = ER_OBJ_INVALID_ARGUMENTS;
16646  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16647  goto exit;
16648  }
16649  }
16650  if (is_negative_tzd)
16651  {
16652  tzh = -tzh;
16653  tzm = -tzm;
16654  }
16655 
16656  /* Both format and src should end at same time */
16657  if (cs != last_src || cur_format_str_ptr != last_format)
16658  {
16659  error_status = ER_QSTR_INVALID_FORMAT;
16660  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16661  goto exit;
16662  }
16663 
16664  /************** Check DATE ****************/
16665  year = (yearcount == 0) ? get_cur_year () : year;
16666  month = (monthcount == 0) ? get_cur_month () : month;
16667  day = (daycount == 0) ? 1 : day;
16668  week = (day_of_the_weekcount == 0) ? -1 : day_of_the_week - 1;
16669 
16670  if (week != -1 && week != db_get_day_of_week (year, month, day))
16671  {
16672  error_status = ER_DATE_CONVERSION;
16673  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16674  goto exit;
16675  }
16676 
16677  /************** Check TIME ****************/
16678  if (am != 0 && pm == 0 && hour <= 12)
16679  { /* If A.M. */
16680  hour = (hour == 12) ? 0 : hour;
16681  }
16682  else if (am == 0 && pm != 0 && hour <= 12)
16683  { /* If P.M. */
16684  hour = (hour == 12) ? hour : hour + 12;
16685  }
16686  else if (am == 0 && pm == 0)
16687  { /* If military time */
16688  ;
16689  }
16690  else
16691  {
16692  error_status = ER_DATE_CONVERSION;
16693  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16694  goto exit;
16695  }
16696 
16697  /************* Make DATETIME *****************/
16698  error_status = db_datetime_encode (&tmp_datetime, month, day, year, hour, minute, second, millisecond);
16699  if (error_status != NO_ERROR)
16700  {
16701  goto exit;
16702  }
16703 
16704  if (type == DB_TYPE_DATETIME)
16705  {
16706  if (db_make_datetime (result_datetime, &tmp_datetime) != NO_ERROR)
16707  {
16708  error_status = ER_DATE_CONVERSION;
16709  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16710  goto exit;
16711  }
16712  }
16713  else
16714  {
16716  if (set_tzh == true || set_tzm == true)
16717  {
16718  error_status = tz_create_datetimetz_from_offset (&tmp_datetime, tzh, tzm, &db_datetimetz);
16719 
16720  if (error_status != NO_ERROR)
16721  {
16722  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16723  goto exit;
16724  }
16725  }
16726  else
16727  {
16728  TZ_REGION session_tz_region;
16729  const char *dst = NULL;
16730 
16731  tz_get_session_tz_region (&session_tz_region);
16732  if (len_tzd > 0)
16733  {
16734  assert (start_tzd >= 0);
16735  dst = initial_buf_str + start_tzd;
16736  }
16737  error_status =
16738  tz_create_datetimetz_from_zoneid_and_tzd (&tmp_datetime, &session_tz_region, zone_id, dst, len_tzd, false,
16739  &db_datetimetz);
16740 
16741  if (error_status != NO_ERROR)
16742  {
16743  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16744  goto exit;
16745  }
16746  }
16747  db_make_datetimetz (result_datetime, &db_datetimetz);
16748  }
16749 
16750 exit:
16751  if (do_free_buf_str)
16752  {
16753  assert (initial_buf_str != NULL);
16754  db_private_free (NULL, initial_buf_str);
16755  }
16756  if (do_free_buf_format)
16757  {
16758  assert (initial_buf_format != NULL);
16759  db_private_free (NULL, initial_buf_format);
16760  }
16761 
16762  return error_status;
16763 }
16764 
16765 
16766 /*
16767  * adjust_precision () - Change representation of 'data' as of
16768  * 'precision' and 'scale'.
16769  * When data has invalid format, just return
16770  * return : DOMAIN_INCOMPATIBLE, DOMAIN_OVERFLOW, NO_ERROR
16771  *
16772  * Note : This function is not localized in relation to fractional and digit
16773  * grouping symbols. It assumes the default symbols ('.' for fraction
16774  * symbol and ',' for digit grouping symbol)
16775  */
16776 static int
16777 adjust_precision (char *data, int precision, int scale)
16778 {
16779  char tmp_data[DB_MAX_NUMERIC_PRECISION * 2 + 1];
16780  int scale_counter = 0;
16781  int i = 0;
16782  int before_dec_point = 0;
16783  int after_dec_point = 0;
16784  int space_started = false;
16785 
16786  if (data == NULL || precision < 0 || precision > DB_MAX_NUMERIC_PRECISION || scale < 0
16787  || scale > DB_MAX_NUMERIC_PRECISION)
16788  {
16789  return DOMAIN_INCOMPATIBLE;
16790  }
16791 
16792  if (*data == '-')
16793  {
16794  tmp_data[0] = '-';
16795  i++;
16796  }
16797  else if (*data == '+')
16798  {
16799  i++;
16800  }
16801 
16802  for (; i < DB_MAX_NUMERIC_PRECISION && *(data + i) != '\0' && *(data + i) != '.'; i++)
16803  {
16804  if (char_isdigit (*(data + i)))
16805  {
16806  tmp_data[i] = *(data + i);
16807  before_dec_point++;
16808  }
16809  else if (char_isspace (*(data + i)))
16810  {
16811  space_started = true;
16812  break;
16813  }
16814  else
16815  {
16816  return DOMAIN_INCOMPATIBLE;
16817  }
16818  }
16819 
16820  if (space_started != 0)
16821  {
16822  int j = i;
16823  while (char_isspace (*(data + j)))
16824  {
16825  j++;
16826  }
16827 
16828  if (*(data + j) != '\0')
16829  {
16830  return DOMAIN_INCOMPATIBLE;
16831  }
16832  }
16833 
16834  if (*(data + i) == '.')
16835  {
16836  tmp_data[i] = '.';
16837  i++;
16838  while (*(data + i) != '\0' && scale_counter < scale)
16839  {
16840  if (char_isdigit (*(data + i)))
16841  {
16842  tmp_data[i] = *(data + i);
16843  after_dec_point++;
16844  }
16845  else if (char_isspace (*(data + i)))
16846  {
16847  space_started = true;
16848  break;
16849  }
16850  else
16851  {
16852  return DOMAIN_INCOMPATIBLE;
16853  }
16854  scale_counter++;
16855  i++;
16856  }
16857 
16858  if (space_started != 0)
16859  {
16860  int j = i;
16861  while (char_isspace (*(data + j)))
16862  {
16863  j++;
16864  }
16865 
16866  if (*(data + j) != '\0')
16867  {
16868  return DOMAIN_INCOMPATIBLE;
16869  }
16870  }
16871 
16872  while (scale_counter < scale)
16873  {
16874  tmp_data[i] = '0';
16875  scale_counter++;
16876  i++;
16877  }
16878 
16879  }
16880  else if (*(data + i) == '\0')
16881  {
16882  tmp_data[i] = '.';
16883  i++;
16884  while (scale_counter < scale)
16885  {
16886  tmp_data[i] = '0';
16887  scale_counter++;
16888  i++;
16889  }
16890 
16891  }
16892  else
16893  {
16894  return DOMAIN_COMPATIBLE;
16895  }
16896 
16897  if (before_dec_point + after_dec_point > DB_MAX_NUMERIC_PRECISION || after_dec_point > DB_DEFAULT_NUMERIC_PRECISION
16898  || before_dec_point > precision - scale)
16899  {
16900  return DOMAIN_OVERFLOW;
16901  }
16902 
16903  tmp_data[i] = '\0';
16904  strcpy (data, tmp_data);
16905  return NO_ERROR;
16906 }
16907 
16908 /*
16909  * db_to_number () -
16910  *
16911  * Note : This function is localized in relation to fractional and digit
16912  * grouping symbols.
16913  */
16914 int
16915 db_to_number (const DB_VALUE * src_str, const DB_VALUE * format_str, const DB_VALUE * number_lang,
16916  DB_VALUE * result_num)
16917 {
16918 #define DB_NUMERIC_E38_MAX "99999999999999999999999999999999999999"
16919  /* default precision and scale is (38, 0) */
16920  /* it is more profitable that the definition of this value is located in some header file */
16921  const char *dflt_format_str = DB_NUMERIC_E38_MAX;
16922 
16923  int error_status = NO_ERROR;
16924 
16925  char *cs; /* current source string pointer */
16926  char *last_cs;
16927  char *format_str_ptr;
16928  char *last_format;
16929  char *next_fsp; /* next format string pointer */
16930  int token_length;
16931  int count_format = 0;
16932  int cur_format;
16933 
16934  int precision = 0; /* retain precision of format_str */
16935  int scale = 0;
16936  int loopvar, met_decptr = 0;
16937  int use_default_precision = 0;
16938 
16939  char *first_cs_for_error, *first_format_str_for_error;
16940 
16941  char stack_buf_str[64], stack_buf_format[64];
16942  char *initial_buf_str = NULL, *initial_buf_format = NULL;
16943  bool do_free_buf_str = false, do_free_buf_format = false;
16944  char digit_grouping_symbol;
16945  char fraction_symbol;
16946  bool has_user_format;
16947  bool dummy;
16948  int number_lang_id;
16949  TP_DOMAIN *domain;
16950  INTL_CODESET format_codeset = INTL_CODESET_NONE;
16951 
16952  assert (src_str != (DB_VALUE *) NULL);
16953  assert (result_num != (DB_VALUE *) NULL);
16954  assert (number_lang != NULL);
16955  assert (format_str != NULL);
16956 
16957  if (DB_IS_NULL (src_str))
16958  {
16959  db_make_null (result_num);
16960  return error_status;
16961  }
16962 
16963  if (false == is_char_string (src_str))
16964  {
16965  error_status = ER_QSTR_INVALID_DATA_TYPE;
16966  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16967  return error_status;
16968  }
16969 
16970  if (db_get_string_size (src_str) == 0)
16971  {
16972  error_status = ER_QSTR_EMPTY_STRING;
16973  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16974  return error_status;
16975  }
16976 
16977  if (db_get_string_size (src_str) > MAX_TOKEN_SIZE)
16978  {
16979  error_status = ER_QSTR_SRC_TOO_LONG;
16980  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
16981  return error_status;
16982  }
16983 
16984  assert (DB_VALUE_TYPE (number_lang) == DB_TYPE_INTEGER);
16985  number_lang_id = lang_get_lang_id_from_flag (db_get_int (number_lang), &has_user_format, &dummy);
16986  digit_grouping_symbol = lang_digit_grouping_symbol (number_lang_id);
16987  fraction_symbol = lang_digit_fractional_symbol (number_lang_id);
16988 
16989  error_status =
16990  db_check_or_create_null_term_string (src_str, stack_buf_str, sizeof (stack_buf_str), true, false, &initial_buf_str,
16991  &do_free_buf_str);
16992  if (error_status != NO_ERROR)
16993  {
16994  goto exit;
16995  }
16996 
16997  cs = initial_buf_str;
16998  last_cs = cs + strlen (cs);
16999 
17000  /* If there is no format */
17001  if (!has_user_format)
17002  {
17003  format_str_ptr = (char *) dflt_format_str;
17004  last_format = format_str_ptr + strlen (dflt_format_str);
17005  }
17006  else /* format_str != NULL */
17007  {
17008  /* Format string type checking */
17009  if (is_char_string (format_str))
17010  {
17011  if (db_get_string_size (format_str) > MAX_TOKEN_SIZE)
17012  {
17013  error_status = ER_QSTR_FORMAT_TOO_LONG;
17014  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17015  goto exit;
17016  }
17017 
17018  error_status =
17019  db_check_or_create_null_term_string (format_str, stack_buf_format, sizeof (stack_buf_format), true, false,
17020  &initial_buf_format, &do_free_buf_format);
17021 
17022  if (error_status != NO_ERROR)
17023  {
17024  goto exit;
17025  }
17026  format_str_ptr = initial_buf_format;
17027  last_format = format_str_ptr + strlen (format_str_ptr);
17028  format_codeset = db_get_string_codeset (format_str);
17029  }
17030  else
17031  {
17032  error_status = ER_QSTR_INVALID_DATA_TYPE;
17033  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17034  goto exit;
17035  }
17036 
17037  if (db_get_string_size (format_str) == 0)
17038  {
17039  error_status = ER_QSTR_EMPTY_STRING;
17040  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17041  goto exit;
17042  }
17043  }
17044 
17045  last_cs = (char *) intl_backskip_spaces (cs, last_cs - 1, db_get_string_codeset (src_str));
17046  last_cs = last_cs + 1;
17047 
17048  /* Skip space, tab, CR */
17049  while (cs < last_cs && strchr (WHITE_CHARS, *cs))
17050  {
17051  cs++;
17052  }
17053  while (format_str_ptr < last_format && strchr (WHITE_CHARS, *format_str_ptr))
17054  {
17055  format_str_ptr++;
17056  }
17057  first_cs_for_error = cs;
17058  first_format_str_for_error = format_str_ptr;
17059 
17060  /* get precision and scale of format_str */
17061  for (loopvar = 0; format_str_ptr + loopvar < last_format; loopvar++)
17062  {
17063  switch (*(format_str_ptr + loopvar))
17064  {
17065  case '9':
17066  case '0':
17067  precision++;
17068  if (met_decptr > 0)
17069  {
17070  scale++;
17071  }
17072  break;
17073 
17074  case 'c':
17075  case 'C':
17076  case 's':
17077  case 'S':
17078  break;
17079 
17080  default:
17081  if (*(format_str_ptr + loopvar) == digit_grouping_symbol)
17082  {
17083  break;
17084  }
17085  else if (*(format_str_ptr + loopvar) == fraction_symbol)
17086  {
17087  met_decptr++;
17088  break;
17089  }
17090  precision = 0;
17091  scale = 0;
17092  use_default_precision = 1;
17093  }
17094 
17095  if (precision + scale > DB_MAX_NUMERIC_PRECISION)
17096  {
17099  error_status = ER_IT_DATA_OVERFLOW;
17100  goto exit;
17101  }
17102 
17103  if (use_default_precision == 1)
17104  {
17105  /* scientific notation */
17106  precision = DB_MAX_NUMERIC_PRECISION;
17108  break;
17109  }
17110  }
17111 
17112  /* Skip space, tab, CR */
17113  while (cs < last_cs)
17114  {
17115  cur_format =
17116  get_number_token (number_lang_id, format_str_ptr, &token_length, last_format, &next_fsp, format_codeset);
17117  switch (cur_format)
17118  {
17119  case N_FORMAT:
17120  if (count_format != 0)
17121  {
17122  error_status = ER_QSTR_INVALID_FORMAT;
17123  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17124  goto exit;
17125  }
17126 
17127  error_status =
17128  make_number (cs, last_cs, db_get_string_codeset (src_str), format_str_ptr, &token_length, result_num,
17129  precision, scale, number_lang_id);
17130  if (error_status == NO_ERROR)
17131  {
17132  count_format++;
17133  cs += token_length;
17134  }
17135  else if (error_status == ER_IT_DATA_OVERFLOW)
17136  {
17138  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 1, pr_type_name (TP_DOMAIN_TYPE (domain)));
17139  goto exit;
17140  }
17141  else
17142  {
17143  goto format_mismatch;
17144  }
17145 
17146  break;
17147 
17148  case N_SPACE:
17149  if (!strchr (WHITE_CHARS, *cs))
17150  {
17151  goto format_mismatch;
17152  }
17153 
17154  while (cs < last_cs && strchr (WHITE_CHARS, *cs))
17155  {
17156  cs++;
17157  }
17158  break;
17159 
17160  case N_TEXT:
17161  if (strncasecmp ((format_str_ptr + 1), cs, token_length - 2) != 0)
17162  {
17163  goto format_mismatch;
17164  }
17165  cs += token_length - 2;
17166  break;
17167 
17168  case N_INVALID:
17169  error_status = ER_QSTR_INVALID_FORMAT;
17170  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17171  goto exit;
17172 
17173  case N_END:
17174  /* Skip space, tab, CR */
17175  while (cs < last_cs && strchr (WHITE_CHARS, *cs))
17176  {
17177  cs++;
17178  }
17179 
17180  if (cs != last_cs)
17181  {
17182  goto format_mismatch;
17183  }
17184  break;
17185  }
17186 
17187  while (cs < last_cs && strchr (WHITE_CHARS, *cs))
17188  {
17189  cs++;
17190  }
17191 
17192  format_str_ptr = next_fsp;
17193 
17194  /* Skip space, tab, CR */
17195  while (format_str_ptr < last_format && strchr (WHITE_CHARS, *format_str_ptr))
17196  {
17197  format_str_ptr++;
17198  }
17199  }
17200 
17201  /* Both format and src should end at same time */
17202  if (cs != last_cs || format_str_ptr != last_format)
17203  {
17204  goto format_mismatch;
17205  }
17206 
17207  result_num->domain.numeric_info.precision = precision;
17208  result_num->domain.numeric_info.scale = scale;
17209 
17210  if (do_free_buf_str)
17211  {
17212  assert (initial_buf_str != NULL);
17213  db_private_free (NULL, initial_buf_str);
17214  }
17215  if (do_free_buf_format)
17216  {
17217  assert (initial_buf_format != NULL);
17218  db_private_free (NULL, initial_buf_format);
17219  }
17220 
17221  return error_status;
17222 
17223 format_mismatch:
17224  while (strchr (WHITE_CHARS, *(last_cs - 1)))
17225  {
17226  last_cs--;
17227  }
17228  *last_cs = '\0';
17229 
17230  error_status = ER_QSTR_TONUM_FORMAT_MISMATCH;
17231  if (first_format_str_for_error == dflt_format_str)
17232  {
17233  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 2, first_cs_for_error, "default");
17234  }
17235  else
17236  {
17237  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 2, first_cs_for_error, first_format_str_for_error);
17238  }
17239 
17240 exit:
17241  if (do_free_buf_str)
17242  {
17243  assert (initial_buf_str != NULL);
17244  db_private_free (NULL, initial_buf_str);
17245  }
17246  if (do_free_buf_format)
17247  {
17248  assert (initial_buf_format != NULL);
17249  db_private_free (NULL, initial_buf_format);
17250  }
17251 
17252  return error_status;
17253 #undef DB_NUMERIC_E38_MAX
17254 }
17255 
17256 /*
17257  * date_to_char () -
17258  */
17259 static int
17260 date_to_char (const DB_VALUE * src_value, const DB_VALUE * format_str, const DB_VALUE * date_lang,
17261  DB_VALUE * result_str, const TP_DOMAIN * domain)
17262 {
17263  int error_status = NO_ERROR;
17264  DB_TYPE src_type;
17265  const char *cur_format_str_ptr, *next_format_str_ptr;
17266  const char *last_format_str_ptr;
17267 
17268  int cur_format_size;
17269  TIMESTAMP_FORMAT cur_format;
17270 
17271  char *result_buf = NULL;
17272  int result_len = 0;
17273  int result_size = 0;
17274 
17275  int month = 0, day = 0, year = 0;
17276  int second = 0, minute = 0, hour = 0, millisecond = 0;
17277 
17278  int i;
17279 
17280  unsigned int tmp_int;
17281  DB_DATE tmp_date;
17282  DB_TIME tmp_time;
17283 
17284  bool no_user_format;
17285  INTL_LANG date_lang_id;
17286 
17287  char stack_buf_format[64];
17288  char *initial_buf_format = NULL;
17289  bool do_free_buf_format = false;
17290  const INTL_CODESET codeset = TP_DOMAIN_CODESET (domain);
17291  const int collation_id = TP_DOMAIN_COLLATION (domain);
17292  bool has_user_format = false;
17293  bool dummy;
17294 
17295  assert (src_value != (DB_VALUE *) NULL);
17296  assert (result_str != (DB_VALUE *) NULL);
17297  assert (date_lang != (DB_VALUE *) NULL);
17298 
17299  if (DB_IS_NULL (src_value))
17300  {
17301  db_make_null (result_str);
17302  return error_status;
17303  }
17304 
17305  src_type = DB_VALUE_DOMAIN_TYPE (src_value);
17306 
17307  if (TP_IS_DATE_OR_TIME_TYPE (src_type) != true)
17308  {
17309  error_status = ER_QSTR_INVALID_DATA_TYPE;
17310  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17311  return error_status;
17312  }
17313 
17314  if (date_lang == NULL || DB_IS_NULL (date_lang))
17315  {
17316  error_status = ER_OBJ_INVALID_ARGUMENTS;
17317  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17318  return error_status;
17319  }
17320 
17321  assert (DB_VALUE_TYPE (date_lang) == DB_TYPE_INTEGER);
17322  date_lang_id = lang_get_lang_id_from_flag (db_get_int (date_lang), &has_user_format, &dummy);
17323 
17324  no_user_format = (format_str == NULL) || (!has_user_format);
17325 
17326  if (no_user_format)
17327  {
17328  int retval = 0;
17329 
17330  switch (src_type)
17331  {
17332  case DB_TYPE_DATE:
17333  result_buf = (char *) db_private_alloc (NULL, QSTR_DATE_LENGTH + 1);
17334  if (result_buf == NULL)
17335  {
17336  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
17337  return error_status;
17338  }
17339  result_len = QSTR_DATE_LENGTH;
17340  retval = db_date_to_string (result_buf, QSTR_DATE_LENGTH + 1, db_get_date (src_value));
17341  break;
17342 
17343  case DB_TYPE_TIME:
17344  result_buf = (char *) db_private_alloc (NULL, QSTR_TIME_LENGTH + 1);
17345  if (result_buf == NULL)
17346  {
17347  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
17348  return error_status;
17349  }
17350  result_len = QSTR_TIME_LENGTH;
17351  retval = db_time_to_string (result_buf, QSTR_TIME_LENGTH + 1, db_get_time (src_value));
17352  break;
17353 
17354  case DB_TYPE_TIMESTAMP:
17355  result_buf = (char *) db_private_alloc (NULL, QSTR_TIME_STAMPLENGTH + 1);
17356  if (result_buf == NULL)
17357  {
17358  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
17359  return error_status;
17360  }
17361  result_len = QSTR_TIME_STAMPLENGTH;
17362  retval = db_timestamp_to_string (result_buf, QSTR_TIME_STAMPLENGTH + 1, db_get_timestamp (src_value));
17363  break;
17364 
17365  case DB_TYPE_DATETIME:
17366  result_buf = (char *) db_private_alloc (NULL, QSTR_DATETIME_LENGTH + 1);
17367  if (result_buf == NULL)
17368  {
17369  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
17370  return error_status;
17371  }
17372  result_len = QSTR_DATETIME_LENGTH;
17373  retval = db_datetime_to_string (result_buf, QSTR_DATETIME_LENGTH + 1, db_get_datetime (src_value));
17374  break;
17375 
17376  case DB_TYPE_DATETIMETZ:
17377  {
17378  DB_DATETIMETZ dtz;
17379  result_buf = (char *) db_private_alloc (NULL, DATETIMETZ_BUF_SIZE);
17380  if (result_buf == NULL)
17381  {
17382  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
17383  return error_status;
17384  }
17385  dtz = *db_get_datetimetz (src_value);
17386  retval = db_datetimetz_to_string (result_buf, DATETIMETZ_BUF_SIZE, &dtz.datetime, &dtz.tz_id);
17387  result_len = retval;
17388  }
17389  break;
17390 
17391  case DB_TYPE_DATETIMELTZ:
17392  result_buf = (char *) db_private_alloc (NULL, DATETIMETZ_BUF_SIZE);
17393  if (result_buf == NULL)
17394  {
17395  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
17396  return error_status;
17397  }
17398  retval = db_datetimeltz_to_string (result_buf, DATETIMETZ_BUF_SIZE, db_get_datetime (src_value));
17399  result_len = retval;
17400  break;
17401 
17402  case DB_TYPE_TIMESTAMPTZ:
17403  {
17404  DB_TIMESTAMPTZ tsmp_tz;
17405  result_buf = (char *) db_private_alloc (NULL, TIMESTAMPTZ_BUF_SIZE);
17406 
17407  if (result_buf == NULL)
17408  {
17409  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
17410  return error_status;
17411  }
17412  tsmp_tz = *db_get_timestamptz (src_value);
17413  retval = db_timestamptz_to_string (result_buf, TIMESTAMPTZ_BUF_SIZE, &tsmp_tz.timestamp, &tsmp_tz.tz_id);
17414  result_len = retval;
17415  }
17416  break;
17417 
17418  case DB_TYPE_TIMESTAMPLTZ:
17419  result_buf = (char *) db_private_alloc (NULL, TIMESTAMPTZ_BUF_SIZE);
17420 
17421  if (result_buf == NULL)
17422  {
17423  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
17424  return error_status;
17425  }
17426  retval = db_timestampltz_to_string (result_buf, TIMESTAMPTZ_BUF_SIZE, db_get_timestamp (src_value));
17427  result_len = retval;
17428  break;
17429 
17430  default:
17431  break;
17432  }
17433 
17434  if (retval == 0)
17435  {
17436  error_status = ER_QSTR_INVALID_DATA_TYPE;
17437  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17438  db_private_free_and_init (NULL, result_buf);
17439  return error_status;
17440  }
17441 
17442  db_make_varchar (result_str, result_len, result_buf, result_len, codeset, collation_id);
17443  }
17444  else
17445  {
17446  INTL_CODESET frmt_codeset;
17447  char tzr[TZR_SIZE + 1], tzd[TZ_DS_STRING_SIZE + 1];
17448  int tzh, tzm;
17449  int ntzr = 0, ntzd = 0;
17450  int len_tzr = 0, len_tzd = 0;
17451  bool has_tzh = false, has_tzm = false;
17452  TZ_ID tz_id;
17453 
17454  tzr[0] = '\0';
17455  tzd[0] = '\0';
17456  assert (!DB_IS_NULL (date_lang));
17457 
17458  if (DB_IS_NULL (format_str))
17459  {
17460  db_make_null (result_str);
17461  goto exit;
17462  }
17463 
17464  /* compute allocation size : trade-off exact size (and small mem usage) vs speed */
17465  result_len = (db_get_string_length (format_str) * QSTR_TO_CHAR_LEN_MULTIPLIER_RATIO);
17466 
17467  if (db_get_string_size (format_str) == 0)
17468  {
17469  error_status = ER_QSTR_EMPTY_STRING;
17470  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17471  goto exit;
17472  }
17473 
17474  frmt_codeset = db_get_string_codeset (format_str);
17475 
17476  error_status =
17477  db_check_or_create_null_term_string (format_str, stack_buf_format, sizeof (stack_buf_format), true, false,
17478  &initial_buf_format, &do_free_buf_format);
17479  if (error_status != NO_ERROR)
17480  {
17481  goto exit;
17482  }
17483 
17484  cur_format_str_ptr = initial_buf_format;
17485  last_format_str_ptr = cur_format_str_ptr + strlen (cur_format_str_ptr);
17486 
17487  /* First compute the number of TZR and TZD tokens if any */
17488  cur_format = DT_NORMAL;
17489  for (;;)
17490  {
17491  cur_format =
17492  get_next_format (cur_format_str_ptr, frmt_codeset, src_type, &cur_format_size, &next_format_str_ptr);
17493  switch (cur_format)
17494  {
17495  case DT_TZR:
17496  ntzr++;
17497  break;
17498 
17499  case DT_TZD:
17500  ntzd++;
17501  break;
17502 
17503  case DT_TZH:
17504  has_tzh = true;
17505  break;
17506 
17507  case DT_TZM:
17508  has_tzm = true;
17509  break;
17510 
17511  case DT_INVALID:
17512  error_status = ER_QSTR_INVALID_FORMAT;
17513  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17514  goto exit;
17515 
17516  default:
17517  break;
17518  }
17519 
17520  cur_format_str_ptr = next_format_str_ptr;
17521  if (next_format_str_ptr == last_format_str_ptr)
17522  {
17523  break;
17524  }
17525  }
17526 
17527  switch (src_type)
17528  {
17529  case DB_TYPE_DATE:
17530  db_date_decode (db_get_date (src_value), &month, &day, &year);
17531  break;
17532  case DB_TYPE_TIME:
17533  {
17534  DB_TIME *tm;
17535 
17536  tm = db_get_time (src_value);
17537  if (ntzr != 0 || ntzd != 0 || has_tzh == true || has_tzm == true)
17538  {
17539  error_status = tz_create_session_tzid_for_time (tm, true, &tz_id);
17540  if (error_status != NO_ERROR)
17541  {
17542  goto exit;
17543  }
17544  }
17545  db_time_decode (tm, &hour, &minute, &second);
17546  }
17547  break;
17548  case DB_TYPE_TIMESTAMP:
17549  {
17550  DB_TIMESTAMP *tsmp;
17551 
17552  tsmp = db_get_timestamp (src_value);
17553  if (ntzr != 0 || ntzd != 0 || has_tzh == true || has_tzm == true)
17554  {
17555  error_status = tz_create_session_tzid_for_timestamp (tsmp, &tz_id);
17556  if (error_status != NO_ERROR)
17557  {
17558  goto exit;
17559  }
17560  }
17561  (void) db_timestamp_decode_ses (tsmp, &tmp_date, &tmp_time);
17562  db_date_decode (&tmp_date, &month, &day, &year);
17563  db_time_decode (&tmp_time, &hour, &minute, &second);
17564  }
17565  break;
17566  case DB_TYPE_DATETIME:
17567  {
17568  DB_DATETIME *dt;
17569 
17570  dt = db_get_datetime (src_value);
17571  if (ntzr != 0 || ntzd != 0 || has_tzh == true || has_tzm == true)
17572  {
17573  error_status = tz_create_session_tzid_for_datetime (dt, true, &tz_id);
17574  if (error_status != NO_ERROR)
17575  {
17576  goto exit;
17577  }
17578  }
17579  db_datetime_decode (dt, &month, &day, &year, &hour, &minute, &second, &millisecond);
17580  }
17581  break;
17582  case DB_TYPE_DATETIMETZ:
17583  {
17584  DB_DATETIMETZ dtz;
17585  DB_DATETIME dt_local;
17586 
17587  dtz = *db_get_datetimetz (src_value);
17588  tz_id = dtz.tz_id;
17589  error_status = tz_utc_datetimetz_to_local (&dtz.datetime, &dtz.tz_id, &dt_local);
17590  if (error_status != NO_ERROR)
17591  {
17592  goto exit;
17593  }
17594  db_datetime_decode (&dt_local, &month, &day, &year, &hour, &minute, &second, &millisecond);
17595  }
17596  break;
17597  case DB_TYPE_DATETIMELTZ:
17598  {
17599  DB_DATETIME *dt, dt_local;
17600 
17601  dt = db_get_datetime (src_value);
17602  error_status = tz_create_session_tzid_for_datetime (dt, true, &tz_id);
17603  if (error_status != NO_ERROR)
17604  {
17605  goto exit;
17606  }
17607 
17608  error_status = tz_utc_datetimetz_to_local (dt, &tz_id, &dt_local);
17609  if (error_status != NO_ERROR)
17610  {
17611  goto exit;
17612  }
17613  db_datetime_decode (&dt_local, &month, &day, &year, &hour, &minute, &second, &millisecond);
17614  }
17615  break;
17616  case DB_TYPE_TIMESTAMPTZ:
17617  {
17618  DB_TIMESTAMPTZ tsmp_tz;
17619  DB_DATE date;
17620  DB_TIME time;
17621 
17622  tsmp_tz = *db_get_timestamptz (src_value);
17623  tz_id = tsmp_tz.tz_id;
17624  error_status = db_timestamp_decode_w_tz_id (&tsmp_tz.timestamp, &tsmp_tz.tz_id, &date, &time);
17625  if (error_status != NO_ERROR)
17626  {
17627  goto exit;
17628  }
17629  db_date_decode (&date, &month, &day, &year);
17630  db_time_decode (&time, &hour, &minute, &second);
17631  }
17632  break;
17633  case DB_TYPE_TIMESTAMPLTZ:
17634  {
17635  DB_TIMESTAMP *tsmp;
17636  DB_DATE date;
17637  DB_TIME time;
17638 
17639  tsmp = db_get_timestamp (src_value);
17640  error_status = tz_create_session_tzid_for_timestamp (tsmp, &tz_id);
17641  if (error_status != NO_ERROR)
17642  {
17643  goto exit;
17644  }
17645 
17646  error_status = db_timestamp_decode_w_tz_id (tsmp, &tz_id, &date, &time);
17647  if (error_status != NO_ERROR)
17648  {
17649  goto exit;
17650  }
17651  db_date_decode (&date, &month, &day, &year);
17652  db_time_decode (&time, &hour, &minute, &second);
17653  }
17654  break;
17655  default:
17656  break;
17657  }
17658 
17659  if (ntzr != 0 || ntzd != 0 || has_tzh == true || has_tzm == true)
17660  {
17661  int len = db_get_string_length (format_str);
17662  int left;
17663 
17664  error_status = tz_explain_tz_id (&tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
17665  if (error_status != NO_ERROR)
17666  {
17667  goto exit;
17668  }
17669  left = len - 3 * ntzr - 3 * ntzd;
17670  len_tzr = strlen (tzr);
17671  len_tzd = strlen (tzd);
17672  result_len = left * QSTR_TO_CHAR_LEN_MULTIPLIER_RATIO + len_tzr * ntzr + len_tzd * ntzd;
17673  }
17674 
17675  result_size = result_len * INTL_CODESET_MULT (codeset);
17676  if (result_size > MAX_TOKEN_SIZE)
17677  {
17678  error_status = ER_QSTR_FORMAT_TOO_LONG;
17679  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17680  goto exit;
17681  }
17682  result_buf = (char *) db_private_alloc (NULL, result_size + 1);
17683  if (result_buf == NULL)
17684  {
17685  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
17686  goto exit;
17687  }
17688 
17689  i = 0;
17690  cur_format = DT_NORMAL;
17691  cur_format_str_ptr = initial_buf_format;
17692 
17693  while (i < result_size)
17694  {
17695  int token_case_mode;
17696  int token_size;
17697 
17698  cur_format =
17699  get_next_format (cur_format_str_ptr, frmt_codeset, src_type, &cur_format_size, &next_format_str_ptr);
17700  switch (cur_format)
17701  {
17702  case DT_CC:
17703  if (month == 0 && day == 0 && year == 0)
17704  {
17705  goto zerodate_exit;
17706  }
17707 
17708  tmp_int = (year / 100) + 1;
17709  sprintf (&result_buf[i], "%02d\n", tmp_int);
17710  i += 2;
17711  cur_format_str_ptr += 2;
17712  break;
17713 
17714  case DT_YYYY:
17715  sprintf (&result_buf[i], "%04d\n", year);
17716  i += 4;
17717  break;
17718 
17719  case DT_YY:
17720  tmp_int = year - (year / 100) * 100;
17721  sprintf (&result_buf[i], "%02d\n", tmp_int);
17722  i += 2;
17723  break;
17724 
17725  case DT_MM:
17726  sprintf (&result_buf[i], "%02d\n", month);
17727  i += 2;
17728  break;
17729 
17730  case DT_MONTH:
17731  case DT_MON:
17732  if (month == 0 && day == 0 && year == 0)
17733  {
17734  goto zerodate_exit;
17735  }
17736 
17737  if (*cur_format_str_ptr == 'm')
17738  {
17739  token_case_mode = 1;
17740  }
17741  else if (*(cur_format_str_ptr + 1) == 'O')
17742  {
17743  token_case_mode = 2;
17744  }
17745  else
17746  {
17747  token_case_mode = 0;
17748  }
17749 
17750  if (cur_format == DT_MONTH)
17751  {
17752  error_status =
17753  print_string_date_token (SDT_MONTH, date_lang_id, codeset, month - 1, token_case_mode,
17754  &result_buf[i], &token_size);
17755  }
17756  else /* cur_format == DT_MON */
17757  {
17758  error_status =
17759  print_string_date_token (SDT_MONTH_SHORT, date_lang_id, codeset, month - 1, token_case_mode,
17760  &result_buf[i], &token_size);
17761  }
17762 
17763  if (error_status != NO_ERROR)
17764  {
17765  db_private_free_and_init (NULL, result_buf);
17766  goto exit;
17767  }
17768 
17769  i += token_size;
17770  break;
17771 
17772  case DT_Q:
17773  if (month == 0 && day == 0 && year == 0)
17774  {
17775  goto zerodate_exit;
17776  }
17777 
17778  result_buf[i] = '1' + ((month - 1) / 3);
17779  i++;
17780  break;
17781 
17782  case DT_DD:
17783  sprintf (&result_buf[i], "%02d\n", day);
17784  i += 2;
17785  break;
17786 
17787  case DT_DAY:
17788  case DT_DY:
17789  if (month == 0 && day == 0 && year == 0)
17790  {
17791  goto zerodate_exit;
17792  }
17793 
17794  tmp_int = get_day (month, day, year);
17795 
17796  if (*cur_format_str_ptr == 'd')
17797  {
17798  token_case_mode = 1;
17799  }
17800  else if (*(cur_format_str_ptr + 1) == 'A') /* "DAY" */
17801  {
17802  token_case_mode = 2;
17803  }
17804  else if (*(cur_format_str_ptr + 1) == 'Y') /* "DY" */
17805  {
17806  token_case_mode = 2;
17807  }
17808  else
17809  {
17810  token_case_mode = 0;
17811  }
17812 
17813  if (cur_format == DT_DAY)
17814  {
17815  error_status =
17816  print_string_date_token (SDT_DAY, date_lang_id, codeset, tmp_int, token_case_mode, &result_buf[i],
17817  &token_size);
17818  }
17819  else /* cur_format == DT_DY */
17820  {
17821  error_status =
17822  print_string_date_token (SDT_DAY_SHORT, date_lang_id, codeset, tmp_int, token_case_mode,
17823  &result_buf[i], &token_size);
17824  }
17825 
17826  if (error_status != NO_ERROR)
17827  {
17828  db_private_free_and_init (NULL, result_buf);
17829  goto exit;
17830  }
17831 
17832  i += token_size;
17833  break;
17834 
17835  case DT_D:
17836  if (month == 0 && day == 0 && year == 0)
17837  {
17838  goto zerodate_exit;
17839  }
17840 
17841  tmp_int = get_day (month, day, year);
17842  result_buf[i] = '0' + tmp_int + 1; /* sun=1 */
17843  i += 1;
17844  break;
17845 
17846  case DT_AM:
17847  case DT_PM:
17848  {
17849  int am_pm_id = -1;
17850  int am_pm_len = 0;
17851 
17852  if (0 <= hour && hour <= 11)
17853  {
17854  if (*cur_format_str_ptr == 'a' || *cur_format_str_ptr == 'p')
17855  {
17856  am_pm_id = (int) am_NAME;
17857  }
17858  else if (*(cur_format_str_ptr + 1) == 'm')
17859  {
17860  am_pm_id = (int) Am_NAME;
17861  }
17862  else
17863  {
17864  am_pm_id = (int) AM_NAME;
17865  }
17866  }
17867  else if (12 <= hour && hour <= 23)
17868  {
17869  if (*cur_format_str_ptr == 'p' || *cur_format_str_ptr == 'a')
17870  {
17871  am_pm_id = (int) pm_NAME;
17872  }
17873  else if (*(cur_format_str_ptr + 1) == 'm')
17874  {
17875  am_pm_id = (int) Pm_NAME;
17876  }
17877  else
17878  {
17879  am_pm_id = (int) PM_NAME;
17880  }
17881  }
17882  else
17883  {
17884  error_status = ER_QSTR_INVALID_FORMAT;
17885  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17886  db_private_free_and_init (NULL, result_buf);
17887  goto exit;
17888  }
17889 
17890  assert (am_pm_id >= (int) am_NAME && am_pm_id <= (int) P_M_NAME);
17891 
17892  error_status =
17893  print_string_date_token (SDT_AM_PM, date_lang_id, codeset, am_pm_id, 0, &result_buf[i], &am_pm_len);
17894 
17895  if (error_status != NO_ERROR)
17896  {
17897  db_private_free_and_init (NULL, result_buf);
17898  goto exit;
17899  }
17900 
17901  i += am_pm_len;
17902  }
17903  break;
17904 
17905  case DT_A_M:
17906  case DT_P_M:
17907  {
17908  int am_pm_id = -1;
17909  int am_pm_len = 0;
17910 
17911  if (0 <= hour && hour <= 11)
17912  {
17913  if (*cur_format_str_ptr == 'a' || *cur_format_str_ptr == 'p')
17914  {
17915  am_pm_id = (int) a_m_NAME;
17916  }
17917  else if (*(cur_format_str_ptr + 2) == 'm')
17918  {
17919  am_pm_id = (int) A_m_NAME;
17920  }
17921  else
17922  {
17923  am_pm_id = (int) A_M_NAME;
17924  }
17925  }
17926  else if (12 <= hour && hour <= 23)
17927  {
17928  if (*cur_format_str_ptr == 'p' || *cur_format_str_ptr == 'a')
17929  {
17930  am_pm_id = (int) p_m_NAME;
17931  }
17932  else if (*(cur_format_str_ptr + 2) == 'm')
17933  {
17934  am_pm_id = (int) P_m_NAME;
17935  }
17936  else
17937  {
17938  am_pm_id = (int) P_M_NAME;
17939  }
17940  }
17941  else
17942  {
17943  error_status = ER_QSTR_INVALID_FORMAT;
17944  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17945  db_private_free_and_init (NULL, result_buf);
17946  goto exit;
17947  }
17948 
17949  assert (am_pm_id >= (int) am_NAME && am_pm_id <= (int) P_M_NAME);
17950 
17951  error_status =
17952  print_string_date_token (SDT_AM_PM, date_lang_id, codeset, am_pm_id, 0, &result_buf[i], &am_pm_len);
17953 
17954  if (error_status != NO_ERROR)
17955  {
17956  db_private_free_and_init (NULL, result_buf);
17957  goto exit;
17958  }
17959 
17960  i += am_pm_len;
17961  }
17962  break;
17963 
17964  case DT_HH:
17965  case DT_HH12:
17966  tmp_int = hour % 12;
17967  if (tmp_int == 0)
17968  {
17969  tmp_int = 12;
17970  }
17971  sprintf (&result_buf[i], "%02d\n", tmp_int);
17972  i += 2;
17973  break;
17974 
17975  case DT_HH24:
17976  sprintf (&result_buf[i], "%02d\n", hour);
17977  i += 2;
17978  break;
17979 
17980  case DT_MI:
17981  sprintf (&result_buf[i], "%02d\n", minute);
17982  i += 2;
17983  break;
17984 
17985  case DT_SS:
17986  sprintf (&result_buf[i], "%02d\n", second);
17987  i += 2;
17988  break;
17989 
17990  case DT_MS:
17991  sprintf (&result_buf[i], "%03d\n", millisecond);
17992  i += 3;
17993  break;
17994 
17995  case DT_INVALID:
17996  error_status = ER_QSTR_INVALID_FORMAT;
17997  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
17998  db_private_free_and_init (NULL, result_buf);
17999  goto exit;
18000 
18001  case DT_NORMAL:
18002  memcpy (&result_buf[i], cur_format_str_ptr, cur_format_size);
18003  i += cur_format_size;
18004  break;
18005 
18006  case DT_TEXT:
18007  memcpy (&result_buf[i], cur_format_str_ptr + 1, cur_format_size - 2);
18008  i += cur_format_size - 2;
18009  break;
18010 
18011  case DT_PUNCTUATION:
18012  memcpy (&result_buf[i], cur_format_str_ptr, cur_format_size);
18013  i += cur_format_size;
18014  break;
18015 
18016  case DT_TZR:
18017  {
18018  memcpy (&result_buf[i], tzr, len_tzr);
18019  i += len_tzr;
18020  }
18021  break;
18022 
18023  case DT_TZD:
18024  {
18025  memcpy (&result_buf[i], tzd, len_tzd);
18026  i += len_tzd;
18027  }
18028  break;
18029 
18030  case DT_TZH:
18031  if ((tzh >= 0) && (tzm >= 0))
18032  {
18033  sprintf (&result_buf[i], "%c%02d\n", '+', tzh);
18034  }
18035  else
18036  {
18037  tzh = -tzh;
18038  sprintf (&result_buf[i], "%c%02d\n", '-', tzh);
18039  }
18040  i += 3;
18041  break;
18042 
18043  case DT_TZM:
18044  if (tzm < 0)
18045  {
18046  tzm = -tzm;
18047  }
18048  sprintf (&result_buf[i], "%02d\n", tzm);
18049  result_size--;
18050  i += 2;
18051  break;
18052 
18053  default:
18054  break;
18055  }
18056 
18057  cur_format_str_ptr = next_format_str_ptr;
18058  if (next_format_str_ptr == last_format_str_ptr)
18059  {
18060  break;
18061  }
18062  }
18063 
18064  db_make_varchar (result_str, result_len, result_buf, i, codeset, collation_id);
18065  }
18066 
18067  result_str->need_clear = true;
18068 
18069 exit:
18070  if (do_free_buf_format)
18071  {
18072  assert (initial_buf_format != NULL);
18073  db_private_free_and_init (NULL, initial_buf_format);
18074  }
18075  return error_status;
18076 
18077 zerodate_exit:
18078  if (result_buf != NULL)
18079  {
18080  db_private_free_and_init (NULL, result_buf);
18081  }
18082  db_make_null (result_str);
18083  goto exit;
18084 }
18085 
18086 /*
18087  * number_to_char () -
18088  *
18089  * Note : This function is localized in relation to fractional and digit
18090  * grouping symbols.
18091  */
18092 static int
18093 number_to_char (const DB_VALUE * src_value, const DB_VALUE * format_str, const DB_VALUE * number_lang,
18094  DB_VALUE * result_str, const TP_DOMAIN * domain)
18095 {
18096  int error_status = NO_ERROR;
18097  char tmp_str[NUMERIC_MAX_STRING_SIZE];
18098 
18099  char *cs = NULL; /* current source string pointer */
18100  char *format_str_ptr, *last_format;
18101  char *next_fsp; /* next format string pointer */
18102  int token_length = 0;
18103  int cur_format;
18104  char *res_string, *res_ptr;
18105  int i, j;
18106  char stack_buf_format[64];
18107  char *initial_buf_format = NULL;
18108  bool do_free_buf_format = false;
18109  INTL_LANG number_lang_id;
18110  char fraction_symbol;
18111  char digit_grouping_symbol;
18112  bool has_user_format = false;
18113  bool dummy;
18114  const INTL_CODESET codeset = TP_DOMAIN_CODESET (domain);
18115  const int collation_id = TP_DOMAIN_COLLATION (domain);
18116  DB_CURRENCY currency = DB_CURRENCY_NULL;
18117 
18118  assert (src_value != (DB_VALUE *) NULL);
18119  assert (result_str != (DB_VALUE *) NULL);
18120  assert (number_lang != (DB_VALUE *) NULL);
18121 
18122  if (number_lang == NULL)
18123  {
18125  assert (number_lang != NULL);
18126  return ER_OBJ_INVALID_ARGUMENTS;
18127  }
18128 
18129  /* now return null */
18130  if (DB_IS_NULL (src_value))
18131  {
18132  db_make_null (result_str);
18133  return error_status;
18134  }
18135 
18136  number_lang_id = lang_get_lang_id_from_flag (db_get_int (number_lang), &has_user_format, &dummy);
18137  fraction_symbol = lang_digit_fractional_symbol (number_lang_id);
18138  digit_grouping_symbol = lang_digit_grouping_symbol (number_lang_id);
18139  currency = lang_locale_currency (lang_get_lang_name_from_id (number_lang_id));
18140 
18141  switch (DB_VALUE_TYPE (src_value))
18142  {
18143  case DB_TYPE_NUMERIC:
18144  numeric_db_value_print (src_value, tmp_str);
18145  cs = (char *) db_private_alloc (NULL, strlen (tmp_str) + 1);
18146  if (cs == NULL)
18147  {
18148  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
18149  return error_status;
18150  }
18151  if (number_lang_id != INTL_LANG_ENGLISH)
18152  {
18153  convert_locale_number (tmp_str, strlen (tmp_str), INTL_LANG_ENGLISH, number_lang_id);
18154  }
18155  strcpy (cs, tmp_str);
18156  break;
18157 
18158  case DB_TYPE_INTEGER:
18159  sprintf (tmp_str, "%d", db_get_int (src_value));
18160  cs = (char *) db_private_alloc (NULL, strlen (tmp_str) + 1);
18161  if (cs == NULL)
18162  {
18163  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
18164  return error_status;
18165  }
18166  strcpy (cs, tmp_str);
18167  break;
18168 
18169  case DB_TYPE_BIGINT:
18170  sprintf (tmp_str, "%lld", (long long) db_get_bigint (src_value));
18171  cs = (char *) db_private_alloc (NULL, strlen (tmp_str) + 1);
18172  if (cs == NULL)
18173  {
18174  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
18175  return error_status;
18176  }
18177  strcpy (cs, tmp_str);
18178  break;
18179 
18180  case DB_TYPE_SMALLINT:
18181  sprintf (tmp_str, "%d", db_get_short (src_value));
18182  cs = (char *) db_private_alloc (NULL, strlen (tmp_str) + 1);
18183  if (cs == NULL)
18184  {
18185  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
18186  return error_status;
18187  }
18188  strcpy (cs, tmp_str);
18189  break;
18190 
18191  case DB_TYPE_FLOAT:
18192  sprintf (tmp_str, "%.6e", db_get_float (src_value));
18193  if (number_lang_id != INTL_LANG_ENGLISH)
18194  {
18195  convert_locale_number (tmp_str, strlen (tmp_str), INTL_LANG_ENGLISH, number_lang_id);
18196  }
18197  if (scientific_to_decimal_string (number_lang_id, tmp_str, &cs) != NO_ERROR)
18198  {
18200  return ER_OBJ_INVALID_ARGUMENTS;
18201  }
18202  break;
18203 
18204  case DB_TYPE_DOUBLE:
18205  sprintf (tmp_str, "%.15e", db_get_double (src_value));
18206  if (number_lang_id != INTL_LANG_ENGLISH)
18207  {
18208  convert_locale_number (tmp_str, strlen (tmp_str), INTL_LANG_ENGLISH, number_lang_id);
18209  }
18210  if (scientific_to_decimal_string (number_lang_id, tmp_str, &cs) != NO_ERROR)
18211  {
18213  return ER_OBJ_INVALID_ARGUMENTS;
18214  }
18215  break;
18216 
18217  case DB_TYPE_MONETARY:
18218  currency = (db_get_monetary (src_value))->type;
18219  sprintf (tmp_str, "%.15e", (db_get_monetary (src_value))->amount);
18220  if (number_lang_id != INTL_LANG_ENGLISH)
18221  {
18222  convert_locale_number (tmp_str, strlen (tmp_str), INTL_LANG_ENGLISH, number_lang_id);
18223  }
18224  if (scientific_to_decimal_string (number_lang_id, tmp_str, &cs) != NO_ERROR)
18225  {
18227  return ER_OBJ_INVALID_ARGUMENTS;
18228  }
18229  break;
18230 
18231  default:
18232  error_status = ER_QSTR_INVALID_DATA_TYPE;
18233  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
18234  return error_status;
18235  }
18236 
18237  assert (cs != NULL);
18238 
18239  /* Remove 'trailing zero' source string */
18240  for (i = 0; i < strlen (cs); i++)
18241  {
18242  if (cs[i] == fraction_symbol)
18243  {
18244  i = strlen (cs);
18245  i--;
18246  while (cs[i] == '0')
18247  {
18248  i--;
18249  }
18250  if (cs[i] == fraction_symbol)
18251  {
18252  cs[i] = '\0';
18253  }
18254  else
18255  {
18256  i++;
18257  cs[i] = '\0';
18258  }
18259  break;
18260  }
18261  }
18262 
18263  if (format_str == NULL || !has_user_format)
18264  {
18265  /* Caution: VARCHAR's Size */
18266  db_make_varchar (result_str, (ssize_t) strlen (cs), cs, strlen (cs), codeset, collation_id);
18267  result_str->need_clear = true;
18268  return error_status;
18269  }
18270  else
18271  {
18272  if (DB_IS_NULL (format_str))
18273  {
18275  db_make_null (result_str);
18276  return error_status;
18277  }
18278 
18279  /* Format string type checking */
18280  if (is_char_string (format_str))
18281  {
18282  if (db_get_string_size (format_str) > MAX_TOKEN_SIZE)
18283  {
18284  error_status = ER_QSTR_FORMAT_TOO_LONG;
18285  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
18287  return error_status;
18288  }
18289 
18290  error_status =
18291  db_check_or_create_null_term_string (format_str, stack_buf_format, sizeof (stack_buf_format), true, false,
18292  &initial_buf_format, &do_free_buf_format);
18293  if (error_status != NO_ERROR)
18294  {
18296  goto exit;
18297  }
18298 
18299  format_str_ptr = initial_buf_format;
18300  last_format = format_str_ptr + strlen (format_str_ptr);
18301  }
18302  else
18303  {
18304  error_status = ER_QSTR_INVALID_DATA_TYPE;
18305  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
18307  return error_status;
18308  }
18309 
18310  if (db_get_string_size (format_str) == 0)
18311  {
18312  error_status = ER_QSTR_EMPTY_STRING;
18313  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
18315  goto exit;
18316  }
18317 
18318  /* Memory allocation for result */
18319  /* size is bigger two times than strlen(format_str_ptr) */
18320  /* because of format 'C'(currency) */
18321  /* 'C' can be expanded accoding to CODE_SET */
18322  /* +1 implies minus - */
18323  res_string = (char *) db_private_alloc (NULL, strlen (format_str_ptr) * 2 + 1);
18324  if (res_string == NULL)
18325  {
18327  assert (er_errid () != NO_ERROR);
18328  error_status = er_errid ();
18329  goto exit;
18330  }
18331 
18332  res_ptr = res_string;
18333 
18334  /* Skip space, tab, CR */
18335  while (strchr (WHITE_CHARS, *cs))
18336  {
18337  cs++;
18338  }
18339 
18340  while (format_str_ptr != last_format)
18341  {
18342  cur_format =
18343  get_number_token (number_lang_id, format_str_ptr, &token_length, last_format, &next_fsp, codeset);
18344  switch (cur_format)
18345  {
18346  case N_FORMAT:
18347  if (make_number_to_char (number_lang_id, cs, format_str_ptr, &token_length, currency, &res_ptr, codeset)
18348  != NO_ERROR)
18349  {
18350  error_status = ER_QSTR_INVALID_FORMAT;
18351  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
18353  db_private_free_and_init (NULL, res_string);
18354  goto exit;
18355  }
18356  /* Remove space character between sign,curerency and number */
18357  i = 0;
18358  j = 0;
18359  while (i < token_length)
18360  {
18361  DB_CURRENCY currency = DB_CURRENCY_NULL;
18362  int symbol_size = 0;
18363 
18364  /* check currency symbols */
18365  if (intl_is_currency_symbol (&(res_ptr[i]), &currency, &symbol_size,
18369  {
18370  i += symbol_size;
18371  }
18372  else if (res_ptr[i] == '+' || res_ptr[i] == '-')
18373  {
18374  i += 1;
18375  }
18376  else if (res_ptr[i] == ' ')
18377  {
18378  while (res_ptr[i + j] == ' ')
18379  {
18380  j++;
18381  }
18382  while (i > 0)
18383  {
18384  i--;
18385  res_ptr[i + j] = res_ptr[i];
18386  res_ptr[i] = ' ';
18387  }
18388  break;
18389  }
18390  else
18391  {
18392  break;
18393  }
18394  }
18395  res_ptr += token_length;
18396  break;
18397  case N_SPACE:
18398  strncpy (res_ptr, format_str_ptr, token_length);
18399  res_ptr += token_length;
18400  break;
18401  case N_TEXT:
18402  strncpy (res_ptr, (format_str_ptr + 1), token_length - 2);
18403  res_ptr += token_length - 2;
18404  break;
18405  case N_INVALID:
18406  error_status = ER_QSTR_INVALID_FORMAT;
18407  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
18409  db_private_free_and_init (NULL, res_string);
18410  goto exit;
18411  case N_END:
18412  *res_ptr = '\0';
18413  break;
18414  }
18415 
18416  format_str_ptr = next_fsp;
18417  }
18418 
18419  *res_ptr = '\0';
18420  }
18421 
18422  /* Both format and src should end at same time */
18423  if (format_str_ptr != last_format)
18424  {
18425  error_status = ER_QSTR_INVALID_FORMAT;
18426  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
18428  db_private_free_and_init (NULL, res_string);
18429 
18430  goto exit;
18431  }
18432 
18433  db_make_varchar (result_str, (ssize_t) strlen (res_string), res_string, strlen (res_string), codeset, collation_id);
18434  result_str->need_clear = true;
18436 
18437 exit:
18438  if (do_free_buf_format)
18439  {
18440  assert (initial_buf_format != NULL);
18441  db_private_free (NULL, initial_buf_format);
18442  }
18443  return error_status;
18444 }
18445 
18446 /*
18447  * lob_to_bit_char ()
18448  */
18449 static int
18450 lob_to_bit_char (const DB_VALUE * src_value, DB_VALUE * result_value, DB_TYPE lob_type, int max_length)
18451 {
18452  int error_status = NO_ERROR;
18453  DB_ELO *elo;
18454  char *cs = NULL; /* current source string pointer */
18455  INT64 size = 0LL;
18456 
18457  assert (lob_type == DB_TYPE_BLOB || lob_type == DB_TYPE_CLOB);
18458 
18459  elo = db_get_elo (src_value);
18460  if (elo)
18461  {
18462  size = db_elo_size (elo);
18463  if (size < 0)
18464  {
18465  if (er_errid () == ER_ES_GENERAL)
18466  {
18467  /* by the spec, some lob handling functions treats the read error as a NULL value */
18468  db_make_null (result_value);
18469  /* clear the error set before */
18470  er_clear ();
18471  return NO_ERROR;
18472  }
18474  return ER_QSTR_BAD_LENGTH;
18475  }
18476  if (max_length < 0 || max_length > DB_MAX_STRING_LENGTH)
18477  {
18478  max_length = DB_MAX_STRING_LENGTH;
18479  }
18480  if (lob_type == DB_TYPE_BLOB)
18481  {
18482  /* convert max_length, which is a number of bits, to number of bytes to read */
18483  max_length = QSTR_NUM_BYTES (max_length);
18484  }
18485  if (max_length > size)
18486  {
18487  max_length = (int) size;
18488  }
18489 
18490  cs = (char *) db_private_alloc (NULL, max_length + 1);
18491  if (cs == NULL)
18492  {
18493  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
18494  return error_status;
18495  }
18496  if (max_length > 0)
18497  {
18498  error_status = db_elo_read (elo, 0, cs, max_length, NULL);
18499  if (error_status == ER_ES_GENERAL)
18500  {
18501  /* by the spec, some lob handling functions treats the read error as a NULL value */
18502  db_make_null (result_value);
18504 
18505  /* clear the error set before */
18506  er_clear ();
18507  return NO_ERROR;
18508  }
18509  else if (error_status < 0)
18510  {
18512  return error_status;
18513  }
18514  }
18515  cs[max_length] = '\0';
18516 
18517  if (lob_type == DB_TYPE_BLOB)
18518  {
18519  /* convert the converted max_length to number of bits */
18520  max_length *= 8;
18521  db_make_varbit (result_value, max_length, cs, max_length);
18522  }
18523  else
18524  {
18525  db_make_varchar (result_value, max_length, cs, max_length, LANG_COERCIBLE_CODESET, LANG_COERCIBLE_COLL);
18526  }
18527  result_value->need_clear = true;
18528  }
18529  else
18530  {
18531  db_make_null (result_value);
18532  }
18533  return error_status;
18534 }
18535 
18536 /*
18537  * lob_from_file () -
18538  */
18539 static int
18540 lob_from_file (const char *path, const DB_VALUE * src_value, DB_VALUE * lob_value, DB_TYPE lob_type)
18541 {
18542  int error_status = NO_ERROR;
18543  DB_ELO temp_elo, *result_elo;
18544  INT64 size, chk_size;
18545  off_t pos;
18546  char lob_chunk[LOB_CHUNK_SIZE + 1];
18547 
18548  assert (lob_type == DB_TYPE_BLOB || lob_type == DB_TYPE_CLOB);
18549 
18550  elo_init_structure (&temp_elo);
18551  temp_elo.type = ELO_FBO;
18552  temp_elo.locator = (char *) path;
18553  size = db_elo_size (&temp_elo);
18554  if (size < 0)
18555  {
18556  error_status = ER_ES_INVALID_PATH;
18557  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 1, db_get_string (src_value));
18558  return error_status;
18559  }
18560 
18561  error_status = db_create_fbo (lob_value, lob_type);
18562  if (error_status != NO_ERROR)
18563  {
18564  return error_status;
18565  }
18566  result_elo = db_get_elo (lob_value);
18567 
18568  pos = 0;
18569  while (size > 0)
18570  {
18571  chk_size = (size < LOB_CHUNK_SIZE) ? size : LOB_CHUNK_SIZE;
18572  error_status = db_elo_read (&temp_elo, pos, lob_chunk, chk_size, &chk_size);
18573  if (error_status < 0)
18574  {
18575  return error_status;
18576  }
18577  error_status = db_elo_write (result_elo, pos, lob_chunk, chk_size, NULL);
18578  if (error_status < 0)
18579  {
18580  return error_status;
18581  }
18582  size -= chk_size;
18583  pos += chk_size;
18584  }
18585 
18586  return NO_ERROR;
18587 }
18588 
18589 /*
18590  * lob_length () -
18591  */
18592 static int
18593 lob_length (const DB_VALUE * src_value, DB_VALUE * result_value)
18594 {
18595  int error_status = NO_ERROR;
18596  DB_ELO *elo;
18597  INT64 length;
18598 
18599  elo = db_get_elo (src_value);
18600  if (elo)
18601  {
18602  /*
18603  * Hack:
18604  * In order to check the existence of the file,
18605  * it is required to make to invoke real file operation.
18606  * Because elo_size() will return the cached elo->size,
18607  * we need to reset it to -1.
18608  */
18609  elo->size = -1;
18610  length = db_elo_size (elo);
18611  if (length < 0)
18612  {
18613  if (er_errid () == ER_ES_GENERAL)
18614  {
18615  /* by the spec, some lob handling functions treats the read error as a NULL value */
18616  db_make_null (result_value);
18617  /* clear the error set before */
18618  er_clear ();
18619  return NO_ERROR;
18620  }
18621  error_status = (int) length;
18622  }
18623  else
18624  {
18625  db_make_bigint (result_value, length);
18626  }
18627  }
18628  else
18629  {
18630  db_make_null (result_value);
18631  }
18632  return error_status;
18633 }
18634 
18635 /*
18636  * make_number_to_char () -
18637  *
18638  * Note : This function is localized in relation to fractional and digit
18639  * grouping symbols.
18640  */
18641 static int
18642 make_number_to_char (const INTL_LANG lang, char *num_string, char *format_str, int *length, DB_CURRENCY currency,
18643  char **result_str, INTL_CODESET codeset)
18644 {
18645  int flag_sign = 1;
18646  int leadingzero = false;
18647  char *res_str = *result_str;
18648  char *num, *format, *res;
18649  char *init_format = format_str;
18650 
18651  char format_end_char = init_format[*length];
18652  const char fraction_symbol = lang_digit_fractional_symbol (lang);
18653  const char digit_grouping_symbol = lang_digit_grouping_symbol (lang);
18654 
18655  init_format[*length] = '\0';
18656 
18657  /* code for patch.. emm.. */
18658  if (strlen (format_str) == 5 && !strncasecmp (format_str, "seeee", 5))
18659  {
18660  return ER_FAILED;
18661  }
18662  else if (strlen (format_str) == 5 && !strncasecmp (format_str, "ceeee", 5))
18663  {
18664  return ER_FAILED;
18665  }
18666  else if (strlen (format_str) == 6 && !strncasecmp (format_str, "sceeee", 6))
18667  {
18668  return ER_FAILED;
18669  }
18670 
18671  /* Check minus */
18672  if (*num_string == '-')
18673  {
18674  *res_str = '-';
18675  num_string++;
18676  res_str++;
18677  flag_sign = -1;
18678  }
18679 
18680  /* Check sign */
18681  if (char_tolower (*format_str) == 's')
18682  {
18683  if (flag_sign == 1)
18684  {
18685  *res_str = '+';
18686  res_str++;
18687  }
18688  format_str++;
18689  }
18690 
18691  if (*format_str == '\0')
18692  {
18693  init_format[*length] = format_end_char;
18694  /* patch for format: '9999 s' */
18695  *res_str = '\0';
18696 
18697  *length = strlen (*result_str);
18698  return NO_ERROR;
18699  }
18700 
18701  /* Check currency */
18702  if (char_tolower (*format_str) == 'c')
18703  {
18704  const char *money_symbol = intl_get_money_symbol (currency, codeset);
18705 
18706  strcpy (res_str, money_symbol);
18707  res_str += strlen (money_symbol);
18708 
18709  format_str++;
18710  }
18711 
18712  if (*format_str == '\0')
18713  {
18714  init_format[*length] = format_end_char;
18715  /* patch for format: '9999 s' */
18716  *res_str = '\0';
18717  *length = strlen (*result_str);
18718 
18719  return NO_ERROR;
18720  }
18721 
18722  /* So far, format:'s','c' are settled */
18723  if (*length > 4 && !strncasecmp (&init_format[*length - 4], "eeee", 4))
18724  {
18725  int cipher = 0;
18726 
18727  num = num_string;
18728  format = format_str;
18729 
18730  if (*num == '0')
18731  {
18732  num++;
18733  if (*num == '\0')
18734  {
18735  while (*format == '0' || *format == '9' || *format == digit_grouping_symbol)
18736  {
18737  format++;
18738  }
18739 
18740  if (*format == fraction_symbol)
18741  {
18742  *res_str = '0';
18743  res_str++;
18744 
18745  format++;
18746 
18747  *res_str = fraction_symbol;
18748  res_str++;
18749 
18750  while (1)
18751  {
18752  if (*format == '0' || *format == '9')
18753  {
18754  *res_str = '0';
18755  res_str++;
18756  format++;
18757  }
18758  else if (char_tolower (*format) == 'e')
18759  {
18760  *res_str = '\0';
18761  init_format[*length] = format_end_char;
18762  make_scientific_notation (*result_str, cipher);
18763  *length = strlen (*result_str);
18764 
18765  return NO_ERROR;
18766  }
18767  else
18768  {
18769  return ER_FAILED;
18770  }
18771  }
18772  }
18773  else if (*format == 'e')
18774  {
18775  *res_str = '0';
18776  res_str++;
18777  *res_str = '\0';
18778  init_format[*length] = format_end_char;
18779  make_scientific_notation (*result_str, cipher);
18780  *length = strlen (*result_str);
18781 
18782  return NO_ERROR;
18783  }
18784  else
18785  {
18786  return ER_FAILED;
18787  }
18788  }
18789  else if (*num == fraction_symbol)
18790  {
18791  num++;
18792  while (1)
18793  {
18794  if (*num == '0')
18795  {
18796  cipher--;
18797  num++;
18798  }
18799  else if (char_isdigit (*num))
18800  {
18801  cipher--;
18802  break;
18803  }
18804  else if (char_tolower (*num) == 'e')
18805  {
18806  break;
18807  }
18808  else if (*num == '\0')
18809  {
18810  return ER_FAILED;
18811  }
18812  else
18813  {
18814  return ER_FAILED;
18815  }
18816  }
18817  }
18818  else
18819  {
18820  return ER_FAILED;
18821  }
18822  }
18823  else
18824  {
18825  while (1)
18826  {
18827  if (char_isdigit (*num))
18828  {
18829  cipher++;
18830  num++;
18831  }
18832  else if (*num == fraction_symbol || *num == '\0')
18833  {
18834  cipher--;
18835  break;
18836  }
18837  else
18838  {
18839  return ER_FAILED;
18840  }
18841  }
18842  }
18843 
18844  while (*format == '0' || *format == '9' || *format == digit_grouping_symbol)
18845  {
18846  format++;
18847  }
18848 
18849  if (*format != fraction_symbol && char_tolower (*format) != 'e')
18850  {
18851  return ER_FAILED;
18852  }
18853 
18854  num = num_string;
18855  res = res_str;
18856 
18857  while (1)
18858  {
18859  if ('0' < *num && *num <= '9')
18860  {
18861  *res = *num;
18862  res++;
18863  num++;
18864  break;
18865  }
18866  else
18867  {
18868  num++;
18869  }
18870  }
18871 
18872  if (char_tolower (*format) == 'e')
18873  {
18874  *res = '\0';
18875  if (*num == fraction_symbol)
18876  {
18877  num++;
18878  if (char_isdigit (*num) && *num - '0' > 4)
18879  {
18880  roundoff (lang, *result_str, 1, &cipher, (char *) NULL);
18881  }
18882  }
18883  else if (char_isdigit (*num))
18884  {
18885  if (char_isdigit (*num) && *num - '0' > 4)
18886  {
18887  roundoff (lang, *result_str, 1, &cipher, (char *) NULL);
18888  }
18889  }
18890  else if (*num == '\0')
18891  {
18892  /* do nothing */
18893  }
18894  else
18895  {
18896  return ER_FAILED;
18897  }
18898 
18899  /* emm */
18900  init_format[*length] = format_end_char;
18901  make_scientific_notation (*result_str, cipher);
18902  *length = strlen (*result_str);
18903 
18904  return NO_ERROR;
18905  }
18906  else
18907  {
18908  *res = *format;
18909  res++;
18910  format++;
18911  }
18912 
18913  while (1)
18914  {
18915  if (*format == '0' || *format == '9')
18916  {
18917  if (*num == fraction_symbol)
18918  {
18919  num++;
18920  *res = *num;
18921  }
18922  else if (*num == '\0')
18923  {
18924  while (*format == '0' || *format == '9')
18925  {
18926  *res = '0';
18927  format++;
18928  res++;
18929  }
18930 
18931  if (char_tolower (*format) != 'e')
18932  {
18933  return ER_FAILED;
18934  }
18935 
18936  *res = '\0';
18937  init_format[*length] = format_end_char;
18938  make_scientific_notation (*result_str, cipher);
18939  *length = strlen (*result_str);
18940 
18941  return NO_ERROR;
18942  }
18943  else
18944  {
18945  *res = *num;
18946  }
18947 
18948  format++;
18949  res++;
18950  num++;
18951  }
18952  else if (char_tolower (*format) == 'e')
18953  {
18954  if (strlen (format) > 4)
18955  {
18956  return ER_FAILED;
18957  }
18958 
18959  if (*num == '\0')
18960  {
18961  *res = '\0';
18962  init_format[*length] = format_end_char;
18963  make_scientific_notation (*result_str, cipher);
18964  *length = strlen (*result_str);
18965 
18966  return NO_ERROR;
18967  }
18968  else
18969  {
18970  *res = '\0';
18971  /* patch */
18972  if (*num == fraction_symbol && *(num + 1) - '0' > 4)
18973  {
18974  roundoff (lang, *result_str, 1, &cipher, (char *) NULL);
18975  }
18976  if (*num - '0' > 4)
18977  {
18978  roundoff (lang, *result_str, 1, &cipher, (char *) NULL);
18979  }
18980  /* emm */
18981  init_format[*length] = format_end_char;
18982  make_scientific_notation (*result_str, cipher);
18983  *length = strlen (*result_str);
18984 
18985  return NO_ERROR;
18986  }
18987  }
18988  else
18989  {
18990  return ER_FAILED;
18991  }
18992  }
18993  }
18994  /* So far, format:scientific notation are settled */
18995 
18996  /* Check leading zero */
18997  if (*format_str == '0')
18998  {
18999  leadingzero = true;
19000  }
19001 
19002  num = num_string;
19003  format = format_str;
19004 
19005  /* Scan unitl '.' or '\0' of both num or format */
19006  while (char_isdigit (*num))
19007  {
19008  num++;
19009  }
19010 
19011  while (*format == '0' || *format == '9' || *format == digit_grouping_symbol)
19012  {
19013  format++;
19014  }
19015 
19016  if (*format != fraction_symbol && *format != '\0')
19017  {
19018  return ER_FAILED;
19019  }
19020 
19021  /* '.' or '\0' is copied into middle or last position of res_string */
19022  *(res_str + (format - format_str)) = *format;
19023  res = res_str + (format - format_str);
19024 
19025  /* num: .xxx format: .xxx */
19026  if (format == format_str && num == num_string)
19027  {
19028  ;
19029  }
19030  /* num: .xxx format: xxx.xxx */
19031  else if (format != format_str && num == num_string)
19032  {
19033  if (leadingzero != 0)
19034  {
19035  while (format != format_str)
19036  {
19037  format--;
19038 
19039  if (*format == '9' || *format == '0')
19040  {
19041  *(res_str + (format - format_str)) = '0';
19042  }
19043  else if (*format == digit_grouping_symbol)
19044  {
19045  *(res_str + (format - format_str)) = digit_grouping_symbol;
19046  }
19047  else
19048  {
19049  return ER_FAILED;
19050  }
19051  }
19052  }
19053  else
19054  {
19055  while (format != format_str)
19056  {
19057  format--;
19058  *(res_str + (format - format_str)) = ' ';
19059  }
19060  }
19061  }
19062  /* num: xxx.xxx format: .xxx */
19063  else if (format == format_str && num != num_string)
19064  {
19065  while (num != num_string)
19066  {
19067  num--;
19068  if (*num != '0')
19069  {
19070  /* Make num be different from num_string */
19071  num = num_string + 1;
19072  break;
19073  }
19074  }
19075  }
19076  /* num: xxx.xxx format: xxx.xxx */
19077  else
19078  {
19079  format--;
19080  num--;
19081  /* if size of format string is 1 */
19082  if (format == format_str)
19083  {
19084  *res_str = *num;
19085  }
19086  else
19087  {
19088  while (format != format_str)
19089  {
19090  if (*format == digit_grouping_symbol)
19091  {
19092  *(res_str + (format - format_str)) = *format;
19093  }
19094  else if ((*format == '9' || *format == '0') && num != num_string)
19095  {
19096  *(res_str + (format - format_str)) = *num;
19097  num--;
19098  }
19099  else
19100  {
19101  *(res_str + (format - format_str)) = *num;
19102  if (leadingzero != 0)
19103  {
19104  while (format != format_str)
19105  {
19106  format--;
19107  if (*format == '9' || *format == '0')
19108  {
19109  *(res_str + (format - format_str)) = '0';
19110  }
19111  else if (*format == digit_grouping_symbol)
19112  {
19113  *(res_str + (format - format_str)) = digit_grouping_symbol;
19114  }
19115  else
19116  {
19117  return ER_FAILED;
19118  }
19119  }
19120  }
19121  else
19122  {
19123  while (format != format_str)
19124  {
19125  format--;
19126  *(res_str + (format - format_str)) = ' ';
19127  }
19128  }
19129  break;
19130  }
19131  format--;
19132  if (format == format_str && num == num_string)
19133  {
19134  *(res_str + (format - format_str)) = *num;
19135  }
19136  }
19137  }
19138  }
19139 
19140  if (num != num_string)
19141  {
19142  int i;
19143 
19144  i = strlen (init_format) - 1;
19145  while (init_format != &init_format[i])
19146  {
19147  if (init_format[i] == fraction_symbol)
19148  {
19149  break;
19150  }
19151  else if (init_format[i] != '0' && init_format[i] != '9' && init_format[i] != 's' && init_format[i] != 'c'
19152  && init_format[i] != digit_grouping_symbol)
19153  {
19154  return ER_FAILED;
19155  }
19156  else
19157  {
19158  i--;
19159  }
19160  }
19161 
19162  i = 0;
19163  while (i < *length)
19164  {
19165  (*result_str)[i] = '#';
19166  i++;
19167  }
19168 
19169  (*result_str)[*length] = '\0';
19170  init_format[*length] = format_end_char;
19171 
19172  return NO_ERROR;
19173  }
19174  /* So far, Left side of decimal point is settled */
19175 
19176  while (char_isdigit (*num))
19177  {
19178  num++;
19179  }
19180 
19181  while (*format == '0' || *format == '9' || *format == digit_grouping_symbol)
19182  {
19183  format++;
19184  }
19185 
19186  if (*format != fraction_symbol && *format != '\0')
19187  {
19188  return ER_FAILED;
19189  }
19190 
19191  if (*format == fraction_symbol && *num == fraction_symbol)
19192  {
19193  res++;
19194  format++;
19195  num++;
19196 
19197  while (*format != '\0')
19198  {
19199  if ((*format == '9' || *format == '0') && *num != '\0')
19200  {
19201  *res = *num;
19202  num++;
19203  res++;
19204  }
19205  else
19206  {
19207  while (*format != '\0')
19208  {
19209  if (*format == '9' || *format == '0')
19210  {
19211  *res = '0';
19212  }
19213  else
19214  {
19215  return ER_FAILED;
19216  }
19217 
19218  format++;
19219  res++;
19220  }
19221 
19222  *res = '\0';
19223  break;
19224  }
19225 
19226  format++;
19227  }
19228 
19229  *res = '\0';
19230  if (*num != '\0')
19231  {
19232  /* rounding */
19233  if (*num - '0' > 4)
19234  {
19235  if (roundoff (lang, *result_str, 0, (int *) NULL, format_str) != NO_ERROR)
19236  {
19237  return ER_FAILED;
19238  }
19239  }
19240  }
19241  }
19242  else if (*format == fraction_symbol && *num == '\0')
19243  {
19244  res++;
19245  format++;
19246 
19247  while (*format != '\0')
19248  {
19249  if (*format == '9' || *format == '0')
19250  {
19251  *res = '0';
19252  }
19253  else
19254  {
19255  return ER_FAILED;
19256  }
19257 
19258  format++;
19259  res++;
19260  }
19261 
19262  *res = '\0';
19263  }
19264  else if (*format == '\0' && *num == fraction_symbol)
19265  {
19266  if (*(num + 1) - '0' > 4)
19267  {
19268  if (roundoff (lang, *result_str, 0, (int *) NULL, format_str) != NO_ERROR)
19269  {
19270  return ER_FAILED;
19271  }
19272  }
19273  /* rounding */
19274  }
19275  else if (*format == '\0' && *num == '\0')
19276  {
19277  /* Nothing */
19278  }
19279  else
19280  {
19281  return ER_FAILED;
19282  }
19283 
19284  init_format[*length] = format_end_char;
19285  *length = strlen (*result_str);
19286 
19287  return NO_ERROR;
19288 }
19289 
19290 /*
19291  * make_scientific_notation () -
19292  */
19293 static int
19294 make_scientific_notation (char *src_string, int cipher)
19295 {
19296  int leng = strlen (src_string);
19297 
19298  src_string[leng] = 'E';
19299  leng++;
19300 
19301  if (cipher >= 0)
19302  {
19303  src_string[leng] = '+';
19304  }
19305  else
19306  {
19307  src_string[leng] = '-';
19308  cipher *= (-1);
19309  }
19310 
19311  leng++;
19312 
19313  if (cipher > 99)
19314  {
19315  sprintf (&src_string[leng], "%d", cipher);
19316  }
19317  else
19318  {
19319  sprintf (&src_string[leng], "%02d", cipher);
19320  }
19321 
19322  return NO_ERROR;
19323 }
19324 
19325 /*
19326  * roundoff () -
19327  *
19328  * Note : This function is localized in relation to fractional and digit
19329  * grouping symbols.
19330  */
19331 static int
19332 roundoff (const INTL_LANG lang, char *src_string, int flag, int *cipher, char *format)
19333 {
19334  int loop_state = true;
19335  int is_overflow = false;
19336  char *res = &src_string[strlen (src_string)];
19337  char *for_ptr = NULL;
19338  int i;
19339  const char fraction_symbol = lang_digit_fractional_symbol (lang);
19340  const char digit_grouping_symbol = lang_digit_grouping_symbol (lang);
19341 
19342  if (flag == 0)
19343  {
19344  for_ptr = &format[strlen (format)];
19345  }
19346 
19347  if (*src_string == '\0')
19348  {
19349  return ER_FAILED;
19350  }
19351  if (flag == 0 && *format == '\0')
19352  {
19353  return ER_FAILED;
19354  }
19355 
19356  res--;
19357 
19358  if (flag == 0)
19359  {
19360  for_ptr--;
19361  }
19362 
19363  while (loop_state)
19364  {
19365  if ('0' <= *res && *res <= '9')
19366  {
19367  switch (*res - '0' + 1)
19368  {
19369  case 1:
19370  case 2:
19371  case 3:
19372  case 4:
19373  case 5:
19374  case 6:
19375  case 7:
19376  case 8:
19377  case 9:
19378  *res = *res + 1;
19379  loop_state = false;
19380  break;
19381 
19382  case 10:
19383  *res = '0';
19384  if (res == src_string)
19385  {
19386  loop_state = false;
19387  is_overflow = true;
19388  }
19389  else
19390  {
19391  res--;
19392  if (flag == 0)
19393  {
19394  for_ptr--;
19395  }
19396  }
19397  break;
19398  }
19399  }
19400  else if (*res == fraction_symbol || *res == digit_grouping_symbol)
19401  {
19402  if (res == src_string)
19403  {
19404  loop_state = false;
19405  is_overflow = true;
19406  }
19407  else
19408  {
19409  res--;
19410  if (flag == 0)
19411  {
19412  for_ptr--;
19413  }
19414  }
19415  }
19416  else if (*res == ' ')
19417  {
19418  if (flag == 0 && *for_ptr == digit_grouping_symbol)
19419  {
19420  *res = digit_grouping_symbol;
19421  res--;
19422  for_ptr--;
19423  }
19424 
19425  *res = '1';
19426  loop_state = false;
19427  }
19428  else
19429  { /* in case of sign, currency */
19430  loop_state = false;
19431  is_overflow = true;
19432  }
19433  }
19434 
19435  if (is_overflow)
19436  {
19437  if (flag == 0)
19438  { /* if decimal format */
19439  i = 0;
19440 
19441  while (i < strlen (src_string))
19442  {
19443  src_string[i] = '#';
19444  i++;
19445  }
19446 
19447  src_string[i] = '\0';
19448  }
19449  else
19450  { /* if scientific format */
19451  i = 0;
19452 
19453  res = src_string;
19454  while (!('0' <= *res && *res <= '9'))
19455  {
19456  res++;
19457  }
19458 
19459  while (i < strlen (res))
19460  {
19461  if (i == 0)
19462  {
19463  res[i] = '1';
19464  }
19465  else if (i == 1)
19466  {
19467  res[i] = fraction_symbol;
19468  }
19469  else
19470  {
19471  res[i] = '0';
19472  }
19473  i++;
19474  }
19475 
19476  (*cipher)++;
19477  res[i] = '\0';
19478  }
19479  }
19480 
19481  return NO_ERROR;
19482 }
19483 
19484 /*
19485  * scientific_to_decimal_string () -
19486  *
19487  * Note : This function is localized in relation to fractional and digit
19488  * grouping symbols.
19489  */
19490 static int
19491 scientific_to_decimal_string (const INTL_LANG lang, char *src_string, char **scientific_str)
19492 {
19493 #define PLUS 1
19494 #define MINUS 0
19495  int src_len = strlen (src_string);
19496  int sign = PLUS, exponent_sign = PLUS, cipher = 0;
19497  char *ptr = src_string;
19498  char *result_str;
19499  int i;
19500  int tmp_digit;
19501  const char fraction_symbol = lang_digit_fractional_symbol (lang);
19502 
19503  while (char_isspace (*ptr))
19504  {
19505  ptr++;
19506  }
19507 
19508  if (*ptr == '+')
19509  {
19510  sign = PLUS;
19511  ptr++;
19512  }
19513  else if (*ptr == '-')
19514  {
19515  sign = MINUS;
19516  ptr++;
19517  }
19518 
19519  tmp_digit = 0;
19520  while (char_isdigit (*ptr))
19521  {
19522  tmp_digit = tmp_digit * 10 + (*ptr - '0');
19523  ptr++;
19524  }
19525  if (tmp_digit >= 10)
19526  {
19527  return ER_FAILED;
19528  }
19529  if (*ptr != fraction_symbol)
19530  {
19531  return ER_FAILED;
19532  }
19533  ptr++;
19534  while (char_isdigit (*ptr))
19535  {
19536  ptr++;
19537  }
19538  if (*ptr == 'e' || *ptr == 'E')
19539  {
19540  ptr++;
19541  }
19542  else
19543  {
19544  return ER_FAILED;
19545  }
19546 
19547  if (*ptr == '+')
19548  {
19549  exponent_sign = PLUS;
19550  }
19551  else if (*ptr == '-')
19552  {
19553  exponent_sign = MINUS;
19554  }
19555  else
19556  {
19557  return ER_FAILED;
19558  }
19559 
19560  ptr++;
19561  for (; char_isdigit (*ptr); ptr++)
19562  {
19563  cipher = cipher * 10 + (*ptr - '0');
19564  }
19565  /* So far, one pass */
19566  /* Fron now, two pass */
19567  while (char_isspace (*ptr))
19568  {
19569  ptr++;
19570  }
19571  if (*ptr != '\0')
19572  {
19573  return ER_FAILED;
19574  }
19575  ptr = src_string;
19576  while (char_isspace (*ptr))
19577  {
19578  ptr++;
19579  }
19580  *scientific_str = (char *) db_private_alloc (NULL, src_len + cipher);
19581  if (*scientific_str == NULL)
19582  {
19583  return ER_FAILED;
19584  }
19585  /* patch for MemoryTrash */
19586  for (i = 0; i < src_len + cipher; i++)
19587  {
19588  (*scientific_str)[i] = '\0';
19589  }
19590 
19591  result_str = *scientific_str;
19592  if (sign == MINUS)
19593  {
19594  *result_str = '-';
19595  result_str++;
19596  ptr++;
19597  }
19598  if (exponent_sign == PLUS)
19599  {
19600  i = 0;
19601  while (char_isdigit (*ptr))
19602  {
19603  *result_str = *ptr;
19604  (result_str)++;
19605  ptr++;
19606  }
19607  *(result_str + cipher) = fraction_symbol;
19608  ptr++;
19609  while (i < cipher || char_isdigit (*ptr))
19610  {
19611  if (*result_str == fraction_symbol)
19612  {
19613  (result_str)++;
19614  continue;
19615  }
19616  else if (char_isdigit (*ptr))
19617  {
19618  *result_str = *ptr;
19619  ptr++;
19620  }
19621  else
19622  {
19623  *result_str = '0';
19624  }
19625  (result_str)++;
19626  i++;
19627  }
19628  }
19629  else
19630  {
19631  *result_str = '0';
19632  result_str++;
19633  *result_str = fraction_symbol;
19634  result_str++;
19635  i = 0;
19636  while (i < cipher - 1)
19637  {
19638  *result_str = '0';
19639  result_str++;
19640  i++;
19641  }
19642  while (char_isdigit (*ptr) || *ptr == fraction_symbol)
19643  {
19644  if (*ptr == fraction_symbol)
19645  {
19646  ptr++;
19647  }
19648  *result_str = *ptr;
19649  (result_str)++;
19650  ptr++;
19651  }
19652  }
19653  *result_str = '\0';
19654  return NO_ERROR;
19655 }
19656 
19657 /*
19658  * to_number_next_state () -
19659  *
19660  * Note : This function is localized in relation to fractional and digit
19661  * grouping symbols.
19662  */
19663 static int
19664 to_number_next_state (const int previous_state, const int input_char, const INTL_LANG number_lang_id)
19665 {
19666  int state_table[7][7] = { {4, 5, 2, 3, -1, 6, -1},
19667  {4, 5, -1, 3, -1, 6, -1},
19668  {4, 5, -1, -1, -1, 6, -1},
19669  {4, 4, -1, -1, 4, 6, 7},
19670  {5, 5, -1, -1, 5, 6, 7},
19671  {6, 6, -1, -1, 6, -1, 7},
19672  {0, 0, 0, 0, 0, 0, 0}
19673  };
19674  int state;
19675  const char fraction_symbol = lang_digit_fractional_symbol (number_lang_id);
19676  const char digit_grouping_symbol = lang_digit_grouping_symbol (number_lang_id);
19677 
19678  if (previous_state == -1)
19679  {
19680  return -1;
19681  }
19682 
19683  switch (char_tolower (input_char))
19684  {
19685  case '0':
19686  state = state_table[previous_state - 1][0];
19687  break;
19688  case '9':
19689  state = state_table[previous_state - 1][1];
19690  break;
19691  case 's':
19692  state = state_table[previous_state - 1][2];
19693  break;
19694  case 'c':
19695  state = state_table[previous_state - 1][3];
19696  break;
19697  default:
19698  if (input_char == digit_grouping_symbol)
19699  {
19700  state = state_table[previous_state - 1][4];
19701  break;
19702  }
19703  else if (input_char == fraction_symbol)
19704  {
19705  state = state_table[previous_state - 1][5];
19706  break;
19707  }
19708  state = state_table[previous_state - 1][6];
19709  break;
19710  }
19711 
19712  return state;
19713 }
19714 
19715 /*
19716  * to_number_next_state () -
19717  * Note: assume precision and scale are correct
19718  * This function is localized in relation to fractional and digit
19719  * grouping symbols.
19720  */
19721 static int
19722 make_number (char *src, char *last_src, INTL_CODESET codeset, char *token, int *token_length, DB_VALUE * r,
19723  const int precision, const int scale, const INTL_LANG number_lang_id)
19724 {
19725  int error_status = NO_ERROR;
19726  int state = 1;
19727  int i, j, k;
19728  char result_str[DB_MAX_NUMERIC_PRECISION + 2];
19729  char *res_ptr;
19730  const char fraction_symbol = lang_digit_fractional_symbol (number_lang_id);
19731  const char digit_grouping_symbol = lang_digit_grouping_symbol (number_lang_id);
19732 
19733  result_str[0] = '\0';
19734  result_str[DB_MAX_NUMERIC_PRECISION] = '\0';
19735  result_str[DB_MAX_NUMERIC_PRECISION + 1] = '\0';
19736  *token_length = 0;
19737 
19738  while (state != 7 && src < last_src)
19739  {
19740  switch (to_number_next_state (state, *token, number_lang_id))
19741  {
19742  case 1: /* Not reachable state */
19743  break;
19744  case 2:
19745  if (*src == '-')
19746  {
19747  strncat (result_str, src, 1);
19748  src++;
19749  (*token_length)++;
19750  token++;
19751  state = 2;
19752  }
19753  else if (*src == '+')
19754  {
19755  src++;
19756  (*token_length)++;
19757  token++;
19758  state = 2;
19759  }
19760  else
19761  {
19763  }
19764  break;
19765  case 3:
19766  {
19767  DB_CURRENCY currency = DB_CURRENCY_NULL;
19768  int symbol_size = 0;
19769 
19771  (src, &currency, &symbol_size,
19774  {
19775  src += symbol_size;
19776  (*token_length) += symbol_size;
19777  token++;
19778  }
19779  }
19780  state = 3;
19781  break;
19782  case 4:
19783  case 5:
19784  if (*src == '-')
19785  {
19786  strncat (result_str, src, 1);
19787  src++;
19788  (*token_length)++;
19789  }
19790  j = 0;
19791  k = 0;
19792  while (token[j] == '0' || token[j] == '9' || token[j] == digit_grouping_symbol)
19793  {
19794  j++;
19795  }
19796  while ((&src[k] < last_src) && (char_isdigit (src[k]) || src[k] == digit_grouping_symbol))
19797  {
19798  k++;
19799  }
19800  i = j;
19801 
19802  if (k > DB_MAX_NUMERIC_PRECISION)
19803  {
19804  return ER_IT_DATA_OVERFLOW;
19805  }
19806  if (k > 0)
19807  {
19808  k--;
19809  }
19810  j--;
19811  while (k > 0 && j > 0)
19812  {
19813  if (token[j] == digit_grouping_symbol && src[k] != digit_grouping_symbol)
19814  {
19816  }
19817  k--;
19818  j--;
19819  }
19820 
19821  if (k != 0)
19822  { /* format = '99' && src = '4444' */
19824  }
19825  /* patch select to_number('30','9,9') from dual; */
19826  if ((src[k] == digit_grouping_symbol && token[j] != digit_grouping_symbol)
19827  || (token[j] == digit_grouping_symbol && src[k] != digit_grouping_symbol))
19828  {
19830  }
19831  if (j > 0)
19832  {
19833  j = 0;
19834  }
19835  while (src < last_src && (char_isdigit (*src) || *src == digit_grouping_symbol))
19836  {
19837  if (*src != digit_grouping_symbol)
19838  {
19839  strncat (result_str, src, 1);
19840  }
19841  (*token_length)++;
19842  src++;
19843  }
19844  token = token + i;
19845  state = 4;
19846  break;
19847  case 6:
19848  token++;
19849  if (*src == fraction_symbol)
19850  {
19851  strncat (result_str, src, 1);
19852  src++;
19853  (*token_length)++;
19854  while (src < last_src && char_isdigit (*src))
19855  {
19856  if (*token == '0' || *token == '9')
19857  {
19858  strncat (result_str, src, 1);
19859  token++;
19860  src++;
19861  (*token_length)++;
19862  }
19863  else
19864  {
19866  }
19867  }
19868  }
19869  while (*token == '0' || *token == '9')
19870  {
19871  token++;
19872  }
19873  state = 6;
19874  break;
19875  case 7:
19876  state = 7;
19877  break;
19878  case -1:
19880  } /* switch */
19881  } /* while */
19882 
19883  /* For Scientific notation */
19884  if (strlen (token) >= 4 && strncasecmp (token, "eeee", 4) == 0 && char_tolower (*src) == 'e'
19885  && (*(src + 1) == '+' || *(src + 1) == '-'))
19886  {
19887  strncat (result_str, src, 2);
19888  src += 2;
19889  (*token_length) += 2;
19890 
19891  while (src < last_src && char_isdigit (*src))
19892  {
19893  strncat (result_str, src, 1);
19894  src += 1;
19895  (*token_length) += 1;
19896  }
19897 
19898  if (scientific_to_decimal_string (number_lang_id, result_str, &res_ptr) != NO_ERROR)
19899  {
19901  /* This line needs to be modified to reflect appropriate error */
19902  }
19903 
19904  /*
19905  * modify result_str to contain correct string value with respect to
19906  * the given precision and scale.
19907  */
19908  strncpy (result_str, res_ptr, sizeof (result_str) - 1);
19909  db_private_free_and_init (NULL, res_ptr);
19910 
19911  if (number_lang_id != INTL_LANG_ENGLISH)
19912  {
19913  convert_locale_number (result_str, strlen (result_str), number_lang_id, INTL_LANG_ENGLISH);
19914  }
19915 
19916  error_status = adjust_precision (result_str, precision, scale);
19917  if (error_status == DOMAIN_OVERFLOW)
19918  {
19919  return ER_IT_DATA_OVERFLOW;
19920  }
19921 
19922  if (error_status != NO_ERROR
19923  || numeric_coerce_string_to_num (result_str, strlen (result_str), codeset, r) != NO_ERROR)
19924  {
19925  /* patch for to_number('-1.23e+03','9.99eeee') */
19927  }
19928  /* old comment db_make_numeric(r,num,precision,scale); */
19929  }
19930  else
19931  {
19932  if (number_lang_id != INTL_LANG_ENGLISH)
19933  {
19934  convert_locale_number (result_str, strlen (result_str), number_lang_id, INTL_LANG_ENGLISH);
19935  }
19936  /*
19937  * modify result_str to contain correct string value with respect to
19938  * the given precision and scale.
19939  */
19940  error_status = adjust_precision (result_str, precision, scale);
19941  if (error_status == DOMAIN_OVERFLOW)
19942  {
19943  return ER_IT_DATA_OVERFLOW;
19944  }
19945 
19946  if (error_status != NO_ERROR
19947  || numeric_coerce_string_to_num (result_str, strlen (result_str), codeset, r) != NO_ERROR)
19948  {
19950  }
19951  }
19952 
19953  return error_status;
19954 }
19955 
19956 /*
19957  * get_number_token () -
19958  *
19959  * Note : This function is localized in relation to fractional and digit
19960  * grouping symbols.
19961  */
19962 static int
19963 get_number_token (const INTL_LANG lang, char *fsp, int *length, char *last_position, char **next_fsp,
19964  INTL_CODESET codeset)
19965 {
19966  const char fraction_symbol = lang_digit_fractional_symbol (lang);
19967  const char digit_grouping_symbol = lang_digit_grouping_symbol (lang);
19968  char c;
19969 
19970  *length = 0;
19971 
19972  if (fsp == last_position)
19973  {
19974  return N_END;
19975  }
19976 
19977  c = char_tolower (fsp[*length]);
19978  switch (c)
19979  {
19980  case 'c':
19981  case 's':
19982  if (fsp[*length + 1] == digit_grouping_symbol)
19983  {
19984  return N_INVALID;
19985  }
19986 
19987  if ((char_tolower (fsp[*length + 1]) == 'c' || char_tolower (fsp[*length + 1]) == 's')
19988  && fsp[*length + 2] == digit_grouping_symbol)
19989  {
19990  return N_INVALID;
19991  }
19992  /* FALLTHRU */
19993 
19994  case '9':
19995  case '0':
19996  while (fsp[*length] == '9' || fsp[*length] == '0' || char_tolower (fsp[*length]) == 's'
19997  || char_tolower (fsp[*length]) == 'c' || fsp[*length] == fraction_symbol
19998  || fsp[*length] == digit_grouping_symbol)
19999  {
20000  *length += 1;
20001  }
20002 
20003  *next_fsp = &fsp[*length];
20004  if (strlen (*next_fsp) >= 4 && !strncasecmp (*next_fsp, "eeee", 4))
20005  {
20006  *length += 4;
20007  *next_fsp = &fsp[*length];
20008  }
20009  return N_FORMAT;
20010 
20011  case ' ':
20012  case '\t':
20013  case '\n':
20014  while (last_position != &fsp[*length] && (fsp[*length] == ' ' || fsp[*length] == '\t' || fsp[*length] == '\n'))
20015  {
20016  *length += 1;
20017  }
20018  *next_fsp = &fsp[*length];
20019  return N_SPACE;
20020 
20021  case (char) 0xa1:
20022  if (codeset == INTL_CODESET_KSC5601_EUC && (&fsp[*length + 1]) < last_position && fsp[*length + 1] == (char) 0xa1)
20023  {
20024  while ((&fsp[*length + 1]) < last_position && fsp[*length] == (char) 0xa1 && fsp[*length + 1] == (char) 0xa1)
20025  {
20026  *length += 2;
20027  }
20028  *next_fsp = &fsp[*length];
20029  return N_SPACE;
20030  }
20031  return N_INVALID;
20032 
20033  case '"':
20034  *length += 1;
20035  while (fsp[*length] != '"')
20036  {
20037  if (&fsp[*length] == last_position)
20038  {
20039  return N_INVALID;
20040  }
20041  *length += 1;
20042  }
20043  *length += 1;
20044  *next_fsp = &fsp[*length];
20045  return N_TEXT;
20046 
20047  default:
20048  if (c == fraction_symbol)
20049  {
20050  while (fsp[*length] == '9' || fsp[*length] == '0' || char_tolower (fsp[*length]) == 's'
20051  || char_tolower (fsp[*length]) == 'c' || fsp[*length] == fraction_symbol
20052  || fsp[*length] == digit_grouping_symbol)
20053  {
20054  *length += 1;
20055  }
20056 
20057  *next_fsp = &fsp[*length];
20058  if (strlen (*next_fsp) >= 4 && !strncasecmp (*next_fsp, "eeee", 4))
20059  {
20060  *length += 4;
20061  *next_fsp = &fsp[*length];
20062  }
20063  return N_FORMAT;
20064  }
20065  return N_INVALID;
20066  }
20067 }
20068 
20069 /*
20070  * get_number_format () -
20071  */
20072 static TIMESTAMP_FORMAT
20073 get_next_format (const char *sp, const INTL_CODESET codeset, DB_TYPE str_type, int *format_length,
20074  const char **next_pos)
20075 {
20076  /* sp : start position */
20077  *format_length = 0;
20078 
20079  switch (char_tolower (*sp))
20080  {
20081  case 'y':
20082  if (str_type == DB_TYPE_TIME)
20083  {
20084  return DT_INVALID;
20085  }
20086 
20087  if (strncasecmp (sp, "yyyy", 4) == 0)
20088  {
20089  *format_length += 4;
20090  *next_pos = sp + *format_length;
20091  return DT_YYYY;
20092  }
20093  else if (strncasecmp (sp, "yy", 2) == 0)
20094  {
20095  *format_length += 2;
20096  *next_pos = sp + *format_length;
20097  return DT_YY;
20098  }
20099  else
20100  {
20101  return DT_INVALID;
20102  }
20103 
20104  case 'd':
20105  if (str_type == DB_TYPE_TIME)
20106  {
20107  return DT_INVALID;
20108  }
20109 
20110  if (strncasecmp (sp, "dd", 2) == 0)
20111  {
20112  *format_length += 2;
20113  *next_pos = sp + *format_length;
20114  return DT_DD;
20115  }
20116  else if (strncasecmp (sp, "dy", 2) == 0)
20117  {
20118  *format_length += 2;
20119  *next_pos = sp + *format_length;
20120  return DT_DY;
20121  }
20122  else if (strncasecmp (sp, "day", 3) == 0)
20123  {
20124  *format_length += 3;
20125  *next_pos = sp + *format_length;
20126  return DT_DAY;
20127  }
20128  else
20129  {
20130  *format_length += 1;
20131  *next_pos = sp + *format_length;
20132  return DT_D;
20133  }
20134 
20135  case 'c':
20136  if (str_type == DB_TYPE_TIME)
20137  {
20138  return DT_INVALID;
20139  }
20140 
20141  if (strncasecmp (sp, "cc", 2) == 0)
20142  {
20143  *format_length += 2;
20144  *next_pos = sp + *format_length;
20145  return DT_CC;
20146  }
20147  else
20148  {
20149  return DT_INVALID;
20150  }
20151 
20152  case 'q':
20153  if (str_type == DB_TYPE_TIME)
20154  {
20155  return DT_INVALID;
20156  }
20157 
20158  *format_length += 1;
20159  *next_pos = sp + *format_length;
20160  return DT_Q;
20161 
20162  case 'm':
20163  if (str_type != DB_TYPE_TIME && strncasecmp (sp, "mm", 2) == 0)
20164  {
20165  *format_length += 2;
20166  *next_pos = sp + *format_length;
20167  return DT_MM;
20168  }
20169  else if (str_type != DB_TYPE_TIME && strncasecmp (sp, "month", 5) == 0)
20170  {
20171  *format_length += 5;
20172  *next_pos = sp + *format_length;
20173  return DT_MONTH;
20174  }
20175  else if (str_type != DB_TYPE_TIME && strncasecmp (sp, "mon", 3) == 0)
20176  {
20177  *format_length += 3;
20178  *next_pos = sp + *format_length;
20179  return DT_MON;
20180  }
20181  else if (str_type != DB_TYPE_DATE && strncasecmp (sp, "mi", 2) == 0)
20182  {
20183  *format_length += 2;
20184  *next_pos = sp + *format_length;
20185  return DT_MI;
20186  }
20187  else
20188  {
20189  return DT_INVALID;
20190  }
20191 
20192  case 'a':
20193  if (str_type == DB_TYPE_DATE)
20194  {
20195  return DT_INVALID;
20196  }
20197 
20198  if (strncasecmp (sp, "am", 2) == 0)
20199  {
20200  *format_length += 2;
20201  *next_pos = sp + *format_length;
20202  return DT_AM;
20203  }
20204  else if (strncasecmp (sp, "a.m.", 4) == 0)
20205  {
20206  *format_length += 4;
20207  *next_pos = sp + *format_length;
20208  return DT_A_M;
20209  }
20210  else
20211  {
20212  return DT_INVALID;
20213  }
20214 
20215  case 'p':
20216  if (str_type == DB_TYPE_DATE)
20217  {
20218  return DT_INVALID;
20219  }
20220 
20221  if (strncasecmp (sp, "pm", 2) == 0)
20222  {
20223  *format_length += 2;
20224  *next_pos = sp + *format_length;
20225  return DT_PM;
20226  }
20227  else if (strncasecmp (sp, "p.m.", 4) == 0)
20228  {
20229  *format_length += 4;
20230  *next_pos = sp + *format_length;
20231  return DT_P_M;
20232  }
20233  else
20234  {
20235  return DT_INVALID;
20236  }
20237 
20238  case 'h':
20239  if (str_type == DB_TYPE_DATE)
20240  {
20241  return DT_INVALID;
20242  }
20243 
20244  if (strncasecmp (sp, "hh24", 4) == 0)
20245  {
20246  *format_length += 4;
20247  *next_pos = sp + *format_length;
20248  return DT_HH24;
20249  }
20250  else if (strncasecmp (sp, "hh12", 4) == 0)
20251  {
20252  *format_length += 4;
20253  *next_pos = sp + *format_length;
20254  return DT_HH12;
20255  }
20256  else if (strncasecmp (sp, "hh", 2) == 0)
20257  {
20258  *format_length += 2;
20259  *next_pos = sp + *format_length;
20260  return DT_HH;
20261  }
20262  else if (strncasecmp (sp, "h", 1) == 0)
20263  {
20264  *format_length += 1;
20265  *next_pos = sp + *format_length;
20266  return DT_H;
20267  }
20268  else
20269  {
20270  return DT_INVALID;
20271  }
20272 
20273  case 's':
20274  if (str_type == DB_TYPE_DATE)
20275  {
20276  return DT_INVALID;
20277  }
20278 
20279  if (strncasecmp (sp, "ss", 2) == 0)
20280  {
20281  *format_length += 2;
20282  *next_pos = sp + *format_length;
20283  return DT_SS;
20284  }
20285  else
20286  {
20287  return DT_INVALID;
20288  }
20289 
20290  case 'f':
20291  if ((str_type == DB_TYPE_DATETIME || str_type == DB_TYPE_DATETIMETZ || str_type == DB_TYPE_DATETIMELTZ)
20292  && strncasecmp (sp, "ff", 2) == 0)
20293  {
20294  *format_length += 2;
20295  *next_pos = sp + *format_length;
20296  return DT_MS;
20297  }
20298  else
20299  {
20300  return DT_INVALID;
20301  }
20302 
20303  case '"':
20304  *format_length += 1;
20305  while (sp[*format_length] != '"')
20306  {
20307  int char_size;
20308  const unsigned char *ptr = (const unsigned char *) sp + (*format_length);
20309  if (sp[*format_length] == '\0')
20310  {
20311  return DT_INVALID;
20312  }
20313  INTL_NEXT_CHAR (ptr, ptr, codeset, &char_size);
20314  *format_length += char_size;
20315  }
20316  *format_length += 1;
20317  *next_pos = &sp[*format_length];
20318  return DT_TEXT;
20319 
20320  case '-':
20321  case '/':
20322  /* this is not a numeric format: it is not necessary to localize point and comma symbols here */
20323  case ',':
20324  case '.':
20325  case ';':
20326  case ':':
20327  case ' ':
20328  case '\t':
20329  case '\n':
20330  *format_length += 1;
20331  *next_pos = sp + *format_length;
20332  return DT_PUNCTUATION;
20333 
20334  case 't':
20335  if (str_type == DB_TYPE_DATE)
20336  {
20337  return DT_INVALID;
20338  }
20339 
20340  if (strncasecmp (sp, "tzr", 3) == 0)
20341  {
20342  *format_length += 3;
20343  *next_pos = sp + *format_length;
20344  return DT_TZR;
20345  }
20346  else if (strncasecmp (sp, "tzd", 3) == 0)
20347  {
20348  *format_length += 3;
20349  *next_pos = sp + *format_length;
20350  return DT_TZD;
20351  }
20352  else if (strncasecmp (sp, "tzh", 3) == 0)
20353  {
20354  *format_length += 3;
20355  *next_pos = sp + *format_length;
20356  return DT_TZH;
20357  }
20358  else if (strncasecmp (sp, "tzm", 3) == 0)
20359  {
20360  *format_length += 3;
20361  *next_pos = sp + *format_length;
20362  return DT_TZM;
20363  }
20364  else
20365  {
20366  return DT_INVALID;
20367  }
20368  default:
20369  return DT_INVALID;
20370  }
20371 }
20372 
20373 /*
20374  * get_cur_year () -
20375  */
20376 static int
20378 {
20379  time_t tloc;
20380  struct tm *tm, tm_val;
20381 
20382  if (time (&tloc) == -1)
20383  {
20384  return -1;
20385  }
20386 
20387  tm = localtime_r (&tloc, &tm_val);
20388  if (tm == NULL)
20389  {
20390  return -1;
20391  }
20392 
20393  return tm->tm_year + 1900;
20394 }
20395 
20396 /*
20397  * get_cur_month () -
20398  */
20399 static int
20401 {
20402  time_t tloc;
20403  struct tm *tm, tm_val;
20404 
20405  if (time (&tloc) == -1)
20406  {
20407  return -1;
20408  }
20409 
20410  tm = localtime_r (&tloc, &tm_val);
20411  if (tm == NULL)
20412  {
20413  return -1;
20414  }
20415 
20416  return tm->tm_mon + 1;
20417 }
20418 
20419 /*
20420  * get_day () -
20421  */
20422 int
20423 get_day (int month, int day, int year)
20424 {
20425  return day_of_week (julian_encode (month, day, year));
20426 }
20427 
20428 /*
20429  * db_format () -
20430  *
20431  * Note : This function is localized in relation to fractional and digit
20432  * grouping symbols.
20433  */
20434 int
20435 db_format (const DB_VALUE * value, const DB_VALUE * decimals, const DB_VALUE * number_lang, DB_VALUE * result,
20436  const TP_DOMAIN * domain)
20437 {
20438  DB_TYPE arg1_type, arg2_type;
20439  int error = NO_ERROR;
20440  int ndec = 0, i, j;
20441  const char *integer_format_max = "99,999,999,999,999,999,999,999,999,999,999,999,999";
20442  char format[128];
20443  DB_VALUE format_val, formatted_val, numeric_val, trimmed_val;
20444  const DB_VALUE *num_dbval_p = NULL;
20445  char fraction_symbol;
20446  char digit_grouping_symbol;
20447  bool dummy;
20448  INTL_LANG number_lang_id;
20449 
20450  assert (value != NULL);
20451  assert (decimals != NULL);
20452  assert (number_lang != NULL);
20453 
20454  arg1_type = DB_VALUE_DOMAIN_TYPE (value);
20455  arg2_type = DB_VALUE_DOMAIN_TYPE (decimals);
20456 
20457  if (arg1_type == DB_TYPE_NULL || DB_IS_NULL (value) || arg2_type == DB_TYPE_NULL || DB_IS_NULL (decimals))
20458  {
20459  db_make_null (result);
20460  return NO_ERROR;
20461  }
20462 
20463  assert (DB_VALUE_TYPE (number_lang) == DB_TYPE_INTEGER);
20464  number_lang_id = lang_get_lang_id_from_flag (db_get_int (number_lang), &dummy, &dummy);
20465  fraction_symbol = lang_digit_fractional_symbol (number_lang_id);
20466  digit_grouping_symbol = lang_digit_grouping_symbol (number_lang_id);
20467 
20468  db_make_null (&formatted_val);
20469  db_make_null (&trimmed_val);
20470 
20471  if (arg2_type == DB_TYPE_INTEGER)
20472  {
20473  ndec = db_get_int (decimals);
20474  }
20475  else if (arg2_type == DB_TYPE_SHORT)
20476  {
20477  ndec = db_get_short (decimals);
20478  }
20479  else if (arg2_type == DB_TYPE_BIGINT)
20480  {
20481  DB_BIGINT bi = db_get_bigint (decimals);
20482  if (bi > INT_MAX || bi < 0)
20483  {
20484  goto invalid_argument_error;
20485  }
20486  ndec = (int) bi;
20487  }
20488  else
20489  {
20491  return ER_FAILED;
20492  }
20493 
20494  if (ndec < 0)
20495  {
20496  goto invalid_argument_error;
20497  }
20498  /* 30 is the decimal limit for formating floating points with this function, in mysql */
20499  if (ndec > 30)
20500  {
20501  ndec = 30;
20502  }
20503 
20504  switch (arg1_type)
20505  {
20506  case DB_TYPE_VARCHAR:
20507  case DB_TYPE_VARNCHAR:
20508  case DB_TYPE_CHAR:
20509  case DB_TYPE_NCHAR:
20510  {
20511  char *c;
20512  int len, dot = 0;
20513  /* Trim first because the input string can be given like below: - ' 1.1 ', '1.1 ', ' 1.1' */
20514  error = db_string_trim (BOTH, NULL, value, &trimmed_val);
20515  if (error != NO_ERROR)
20516  {
20517  return error;
20518  }
20519 
20520  c = CONST_CAST (char *, db_get_string (&trimmed_val));
20521  if (c == NULL)
20522  {
20523  goto invalid_argument_error;
20524  }
20525 
20526  len = strlen (c);
20527 
20528  for (i = 0; i < len; i++)
20529  {
20530  if (c[i] == fraction_symbol)
20531  {
20532  dot++;
20533  continue;
20534  }
20535  if (!char_isdigit (c[i]))
20536  {
20537  goto invalid_argument_error;
20538  }
20539  }
20540  if (dot > 1)
20541  {
20542  goto invalid_argument_error;
20543  }
20544 
20545  if (number_lang_id != INTL_LANG_ENGLISH)
20546  {
20547  convert_locale_number (c, len, number_lang_id, INTL_LANG_ENGLISH);
20548  }
20549 
20550  error = numeric_coerce_string_to_num (c, len, db_get_string_codeset (&trimmed_val), &numeric_val);
20551  if (error != NO_ERROR)
20552  {
20553  pr_clear_value (&trimmed_val);
20554  return error;
20555  }
20556 
20557  num_dbval_p = &numeric_val;
20558  pr_clear_value (&trimmed_val);
20559  }
20560  break;
20561 
20562  case DB_TYPE_MONETARY:
20563  {
20564  double d = db_value_get_monetary_amount_as_double (value);
20565  db_make_double (&numeric_val, d);
20566  num_dbval_p = &numeric_val;
20567  }
20568  break;
20569 
20570  case DB_TYPE_SHORT:
20571  case DB_TYPE_INTEGER:
20572  case DB_TYPE_BIGINT:
20573  case DB_TYPE_FLOAT:
20574  case DB_TYPE_DOUBLE:
20575  case DB_TYPE_NUMERIC:
20576  num_dbval_p = value;
20577  break;
20578 
20579  default:
20581  return ER_FAILED;
20582  }
20583 
20584  /* Make format string. */
20585  i = snprintf (format, sizeof (format) - 1, "%s", integer_format_max);
20586  if (number_lang_id != INTL_LANG_ENGLISH)
20587  {
20588  convert_locale_number (format, strlen (format), INTL_LANG_ENGLISH, number_lang_id);
20589  }
20590  if (ndec > 0)
20591  {
20592  format[i++] = fraction_symbol;
20593  for (j = 0; j < ndec; j++)
20594  {
20595  format[i++] = '9';
20596  }
20597  format[i] = '\0';
20598  }
20599 
20600  db_make_string (&format_val, format);
20601 
20602  error = number_to_char (num_dbval_p, &format_val, number_lang, &formatted_val, domain);
20603  if (error == NO_ERROR)
20604  {
20605  /* number_to_char function returns a string with leading empty characters. So, we need to remove them. */
20606  error = db_string_trim (LEADING, NULL, &formatted_val, result);
20607 
20608  pr_clear_value (&formatted_val);
20609  }
20610 
20611  return error;
20612 
20613 invalid_argument_error:
20614  if (!DB_IS_NULL (&trimmed_val))
20615  {
20616  pr_clear_value (&trimmed_val);
20617  }
20618  if (!DB_IS_NULL (&formatted_val))
20619  {
20620  pr_clear_value (&formatted_val);
20621  }
20622 
20624  return ER_FAILED;
20625 }
20626 
20627 /*
20628  * db_string_reverse () - reverse the source DB_VALUE string
20629  *
20630  * return:
20631  * src_str(in): source DB_VALUE string
20632  * result_str(in/out): result DB_VALUE string
20633  */
20634 int
20635 db_string_reverse (const DB_VALUE * src_str, DB_VALUE * result_str)
20636 {
20637  int error_status = NO_ERROR;
20638  DB_TYPE str_type;
20639  char *res = NULL;
20640 
20641  /*
20642  * Assert that DB_VALUE structures have been allocated.
20643  */
20644  assert (src_str != (DB_VALUE *) NULL);
20645  assert (result_str != (DB_VALUE *) NULL);
20646 
20647  /*
20648  * Categorize the two input parameters and check for errors.
20649  * Verify that the parameters are both character strings.
20650  */
20651 
20652  str_type = DB_VALUE_DOMAIN_TYPE (src_str);
20653  if (DB_IS_NULL (src_str))
20654  {
20655  db_make_null (result_str);
20656  }
20657  else if (!QSTR_IS_ANY_CHAR (str_type))
20658  {
20659  error_status = ER_QSTR_INVALID_DATA_TYPE;
20660  }
20661  /*
20662  * If the input parameters have been properly validated, then
20663  * we are ready to operate.
20664  */
20665  else
20666  {
20667  res = (char *) db_private_alloc (NULL, db_get_string_size (src_str) + 1);
20668  if (res == NULL)
20669  {
20670  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
20671  }
20672 
20673  if (error_status == NO_ERROR)
20674  {
20675  memset (res, 0, db_get_string_size (src_str) + 1);
20676  intl_reverse_string (DB_GET_UCHAR (src_str),
20677  REINTERPRET_CAST (unsigned char *, res), db_get_string_length (src_str),
20678  db_get_string_size (src_str), db_get_string_codeset (src_str));
20679  if (QSTR_IS_CHAR (str_type))
20680  {
20681  db_make_varchar (result_str, DB_GET_STRING_PRECISION (src_str), res, db_get_string_size (src_str),
20682  db_get_string_codeset (src_str), db_get_string_collation (src_str));
20683  }
20684  else
20685  {
20686  db_make_varnchar (result_str, DB_GET_STRING_PRECISION (src_str), res, db_get_string_size (src_str),
20687  db_get_string_codeset (src_str), db_get_string_collation (src_str));
20688  }
20689  result_str->need_clear = true;
20690  }
20691  }
20692 
20693  return error_status;
20694 }
20695 
20696 /*
20697  * add_and_normalize_date_time ()
20698  *
20699  * Arguments: date & time values to modify,
20700  * date & time amounts to add
20701  *
20702  * Returns: NO_ERROR/ER_FAILED
20703  *
20704  * Errors:
20705  *
20706  * Note:
20707  * transforms all values in a correct interval (h: 0..23, m: 0..59, etc)
20708  */
20709 int
20710 add_and_normalize_date_time (int *year, int *month, int *day, int *hour, int *minute, int *second, int *millisecond,
20712  DB_BIGINT ms)
20713 {
20714  DB_BIGINT days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
20715  DB_BIGINT i;
20716  DB_BIGINT _y, _m, _d, _h, _mi, _s, _ms;
20717  DB_BIGINT old_day = *day;
20718 
20719  _y = *year;
20720  _m = *month;
20721  _d = *day;
20722  _h = *hour;
20723  _mi = *minute;
20724  _s = *second;
20725  _ms = *millisecond;
20726 
20727  _y += y;
20728  _m += m;
20729  _d += d;
20730  _h += h;
20731  _mi += mi;
20732  _s += s;
20733  _ms += ms;
20734 
20735  /* just years and/or months case */
20736  if (d == 0 && h == 0 && mi == 0 && s == 0 && ms == 0 && (m > 0 || y > 0))
20737  {
20738  if (_m % 12 == 0)
20739  {
20740  _y += (_m - 12) / 12;
20741  _m = 12;
20742  }
20743  else
20744  {
20745  _y += _m / 12;
20746  _m %= 12;
20747  }
20748 
20749  days[2] = LEAP (_y) ? 29 : 28;
20750 
20751  if (old_day > days[_m])
20752  {
20753  _d = days[_m];
20754  }
20755 
20756  goto set_and_return;
20757  }
20758 
20759  /* time */
20760  _s += _ms / 1000;
20761  _ms %= 1000;
20762 
20763  _mi += _s / 60;
20764  _s %= 60;
20765 
20766  _h += _mi / 60;
20767  _mi %= 60;
20768 
20769  _d += _h / 24;
20770  _h %= 24;
20771 
20772  /* date */
20773  if (_m > 12)
20774  {
20775  _y += _m / 12;
20776  _m %= 12;
20777 
20778  if (_m == 0)
20779  {
20780  _m = 1;
20781  }
20782  }
20783 
20784  days[2] = LEAP (_y) ? 29 : 28;
20785 
20786  if (_d > days[_m])
20787  {
20788  /* rewind to 1st january */
20789  for (i = 1; i < _m; i++)
20790  {
20791  _d += days[i];
20792  }
20793  _m = 1;
20794 
20795  /* days for years */
20796  while (_d >= 366)
20797  {
20798  days[2] = LEAP (_y) ? 29 : 28;
20799  _d -= (days[2] == 29) ? 366 : 365;
20800  _y++;
20801  if (_y > 9999)
20802  {
20803  goto set_and_return;
20804  }
20805  }
20806 
20807  /* days within a year */
20808  days[2] = LEAP (_y) ? 29 : 28;
20809  for (_m = 1;; _m++)
20810  {
20811  if (_d <= days[_m])
20812  {
20813  break;
20814  }
20815  _d -= days[_m];
20816  }
20817  }
20818 
20819  if (_m == 0)
20820  {
20821  _m = 1;
20822  }
20823  if (_d == 0)
20824  {
20825  _d = 1;
20826  }
20827 
20828 set_and_return:
20829 
20830  if (_y >= 10000 || _y < 0)
20831  {
20832  return ER_FAILED;
20833  }
20834 
20835  *year = (int) _y;
20836  *month = (int) _m;
20837  *day = (int) _d;
20838  *hour = (int) _h;
20839  *minute = (int) _mi;
20840  *second = (int) _s;
20841  *millisecond = (int) _ms;
20842 
20843  return NO_ERROR;
20844 }
20845 
20846 /*
20847  * sub_and_normalize_date_time ()
20848  *
20849  * Arguments: date & time values to modify,
20850  * date & time amounts to subtract
20851  *
20852  * Returns: NO_ERROR/ER_FAILED
20853  *
20854  * Errors:
20855  *
20856  * Note:
20857  * transforms all values in a correct interval (h: 0..23, m: 0..59, etc)
20858  */
20859 int
20860 sub_and_normalize_date_time (int *year, int *month, int *day, int *hour, int *minute, int *second, int *millisecond,
20862  DB_BIGINT ms)
20863 {
20864  DB_BIGINT days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
20865  DB_BIGINT i;
20866  DB_BIGINT old_day = *day;
20867  DB_BIGINT _y, _m, _d, _h, _mi, _s, _ms;
20868 
20869  _y = *year;
20870  _m = *month;
20871  _d = *day;
20872  _h = *hour;
20873  _mi = *minute;
20874  _s = *second;
20875  _ms = *millisecond;
20876 
20877  _y -= y;
20878  _m -= m;
20879  _d -= d;
20880  _h -= h;
20881  _mi -= mi;
20882  _s -= s;
20883  _ms -= ms;
20884 
20885  days[2] = LEAP (_y) ? 29 : 28;
20886 
20887  /* time */
20888  _s += _ms / 1000;
20889  _ms %= 1000;
20890  if (_ms < 0)
20891  {
20892  _ms += 1000;
20893  _s--;
20894  }
20895 
20896  _mi += _s / 60;
20897  _s %= 60;
20898  if (_s < 0)
20899  {
20900  _s += 60;
20901  _mi--;
20902  }
20903 
20904  _h += _mi / 60;
20905  _mi %= 60;
20906  if (_mi < 0)
20907  {
20908  _mi += 60;
20909  _h--;
20910  }
20911 
20912  _d += _h / 24;
20913  _h %= 24;
20914  if (_h < 0)
20915  {
20916  _h += 24;
20917  _d--;
20918  }
20919 
20920  if (_d == 0)
20921  {
20922  _m--;
20923 
20924  if (_m == 0)
20925  {
20926  _y--;
20927  days[2] = LEAP (_y) ? 29 : 28;
20928  _m = 12;
20929  }
20930  _d = days[_m];
20931  }
20932 
20933  /* date */
20934  if (_m <= 0)
20935  {
20936  _y += (_m / 12);
20937  _m %= 12;
20938  if (_m <= 0)
20939  {
20940  _m += 12;
20941  _y--;
20942  }
20943  days[2] = LEAP (_y) ? 29 : 28;
20944  }
20945 
20946  /* just years and/or months case */
20947  if (d == 0 && h == 0 && mi == 0 && s == 0 && ms == 0 && (m > 0 || y > 0))
20948  {
20949  if (_m <= 0)
20950  {
20951  _y += (_m / 12);
20952  _m %= 12;
20953  if (_m <= 0)
20954  {
20955  _m += 12;
20956  _y--;
20957  }
20958  }
20959 
20960  days[2] = LEAP (_y) ? 29 : 28;
20961 
20962  if (old_day > days[_m])
20963  {
20964  _d = days[_m];
20965  }
20966 
20967  goto set_and_return;
20968  }
20969 
20970  days[2] = LEAP (_y) ? 29 : 28;
20971 
20972  if (_d > days[_m] || _d < 0)
20973  {
20974  /* rewind to 1st january */
20975  for (i = 1; i < _m; i++)
20976  {
20977  _d += days[i];
20978  }
20979  _m = 1;
20980 
20981  /* days for years */
20982  while (_d < 0)
20983  {
20984  _y--;
20985  if (_y < 0)
20986  {
20987  goto set_and_return;
20988  }
20989  days[2] = LEAP (_y) ? 29 : 28;
20990  _d += (days[2] == 29) ? 366 : 365;
20991  }
20992 
20993  /* days within a year */
20994  days[2] = LEAP (_y) ? 29 : 28;
20995  for (_m = 1;; _m++)
20996  {
20997  if (_d <= days[_m])
20998  {
20999  break;
21000  }
21001  _d -= days[_m];
21002  }
21003  }
21004 
21005  if (_m == 0)
21006  {
21007  _m = 1;
21008  }
21009  if (_d == 0)
21010  {
21011  _d = 1;
21012  }
21013 
21014 set_and_return:
21015 
21016  if (_y >= 10000 || _y < 0)
21017  {
21018  return ER_FAILED;
21019  }
21020 
21021  *year = (int) _y;
21022  *month = (int) _m;
21023  *day = (int) _d;
21024  *hour = (int) _h;
21025  *minute = (int) _mi;
21026  *second = (int) _s;
21027  *millisecond = (int) _ms;
21028 
21029  return NO_ERROR;
21030 }
21031 
21032 /* TODO : refactor with db_date_add_sub_interval_expr
21033  * db_date_add_sub_interval_days ()
21034  *
21035  * Arguments:
21036  * date: starting date
21037  * db_days: number of days to add
21038  *
21039  * Returns: int
21040  *
21041  * Errors:
21042  *
21043  * Note:
21044  * Returns date + an interval of db_days days.
21045  */
21046 static int
21047 db_date_add_sub_interval_days (DB_VALUE * result, const DB_VALUE * date, const DB_VALUE * db_days, bool is_add)
21048 {
21049  int error_status = NO_ERROR;
21050  int days;
21051  DB_DATETIME db_datetime, *dt_p = NULL;
21052  DB_DATETIMETZ dt_tz;
21053  DB_TIME db_time;
21054  DB_DATE db_date, *d_p;
21055  DB_TIMESTAMP db_timestamp, *ts_p = NULL;
21056  int is_dt = -1, is_d = -1, is_t = -1, is_timest = -1, is_timezone = -1, is_local_timezone = -1;
21057  DB_TYPE res_type;
21058  const char *date_s = NULL;
21059  char res_s[64];
21060  int y, m, d, h, mi, s, ms;
21061  int ret;
21062  char *res_final;
21063  TZ_ID tz_id;
21064 
21065  res_type = DB_VALUE_DOMAIN_TYPE (date);
21066  if (res_type == DB_TYPE_NULL || DB_IS_NULL (date))
21067  {
21068  db_make_null (result);
21069  return NO_ERROR;
21070  }
21071 
21072  if (DB_VALUE_DOMAIN_TYPE (db_days) == DB_TYPE_NULL || DB_IS_NULL (db_days))
21073  {
21074  db_make_null (result);
21075  return NO_ERROR;
21076  }
21077 
21078  /* simple case, where just a number of days is added to date */
21079 
21080  days = db_get_int (db_days);
21081 
21082  switch (res_type)
21083  {
21084  case DB_TYPE_STRING:
21085  case DB_TYPE_VARNCHAR:
21086  case DB_TYPE_CHAR:
21087  case DB_TYPE_NCHAR:
21088  {
21089  bool has_explicit_time = false;
21090  int str_len = db_get_string_size (date);
21091  date_s = db_get_string (date);
21092 
21093  /* try to figure out the string format */
21094  if (db_date_parse_datetime_parts (date_s, str_len, &db_datetime, &has_explicit_time, NULL, NULL, NULL))
21095  {
21096  is_dt = ER_TIMESTAMP_CONVERSION;
21097  is_timest = ER_TIMESTAMP_CONVERSION;
21098  is_d = ER_DATE_CONVERSION;
21099  is_t = db_string_to_time_ex (date_s, str_len, &db_time);
21100  }
21101  else
21102  {
21103  if (has_explicit_time)
21104  {
21105  is_dt = NO_ERROR;
21106  is_timest = ER_TIMESTAMP_CONVERSION;
21107  is_d = ER_DATE_CONVERSION;
21108  is_t = ER_TIME_CONVERSION;
21109  }
21110  else
21111  {
21112  db_date = db_datetime.date;
21113  is_dt = ER_TIMESTAMP_CONVERSION;
21114  is_timest = ER_TIMESTAMP_CONVERSION;
21115  is_d = NO_ERROR;
21116  is_t = ER_TIME_CONVERSION;
21117  }
21118  }
21119 
21120  if (is_dt && is_d && is_t && is_timest)
21121  {
21122  error_status = ER_OBJ_INVALID_ARGUMENTS;
21123  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
21124  goto error;
21125  }
21126 
21127  /* add date stuff to a time -> error */
21128  /* in fact, disable time operations, not available on mysql */
21129  if (is_t == 0)
21130  {
21131  error_status = ER_OBJ_INVALID_ARGUMENTS;
21132  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
21133  goto error;
21134  }
21135 
21136  dt_p = &db_datetime;
21137  d_p = &db_date;
21138  ts_p = &db_timestamp;
21139 
21140  /* except just TIME business, convert all to DATETIME */
21141  }
21142  break;
21143 
21144  case DB_TYPE_DATE:
21145  is_d = 1;
21146  d_p = db_get_date (date);
21147  break;
21148 
21149  case DB_TYPE_DATETIMELTZ:
21150  case DB_TYPE_DATETIME:
21151  is_dt = 1;
21152  dt_p = db_get_datetime (date);
21153  if (res_type == DB_TYPE_DATETIMELTZ)
21154  {
21155  is_local_timezone = 1;
21156  }
21157  break;
21158 
21159  case DB_TYPE_DATETIMETZ:
21160  {
21161  DB_DATETIMETZ *dt_tz_p;
21162 
21163  dt_tz_p = db_get_datetimetz (date);
21164  dt_p = &dt_tz_p->datetime;
21165  tz_id = dt_tz_p->tz_id;
21166  is_dt = 1;
21167  is_timezone = 1;
21168  break;
21169  }
21170 
21171  case DB_TYPE_TIMESTAMP:
21172  case DB_TYPE_TIMESTAMPLTZ:
21173  is_timest = 1;
21174  ts_p = db_get_timestamp (date);
21175  if (res_type == DB_TYPE_TIMESTAMPLTZ)
21176  {
21177  is_local_timezone = 1;
21178  }
21179  break;
21180 
21181  case DB_TYPE_TIMESTAMPTZ:
21182  {
21183  DB_TIMESTAMPTZ *ts_tz_p;
21184 
21185  ts_tz_p = db_get_timestamptz (date);
21186  ts_p = &ts_tz_p->timestamp;
21187  tz_id = ts_tz_p->tz_id;
21188  is_timest = 1;
21189  is_timezone = 1;
21190  break;
21191  }
21192 
21193  case DB_TYPE_TIME:
21194  /* should not reach here */
21195  assert (0);
21196  break;
21197 
21198  default:
21199  error_status = ER_OBJ_INVALID_ARGUMENTS;
21200  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
21201  goto error;
21202  }
21203 
21204  if (is_d >= 0)
21205  {
21206  y = m = d = h = mi = s = ms = 0;
21207  db_date_decode (d_p, &m, &d, &y);
21208 
21209  if (m == 0 && d == 0 && y == 0)
21210  {
21211  db_make_null (result);
21212  er_clear ();
21214  {
21215  return NO_ERROR;
21216  }
21219  }
21220 
21221  if (is_add)
21222  {
21223  if (days > 0)
21224  {
21225  ret = add_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, 0, 0, days, 0, 0, 0, 0);
21226  }
21227  else
21228  {
21229  ret = sub_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, 0, 0, -days, 0, 0, 0, 0);
21230  }
21231  }
21232  else
21233  {
21234  if (days > 0)
21235  {
21236  ret = sub_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, 0, 0, days, 0, 0, 0, 0);
21237  }
21238  else
21239  {
21240  ret = add_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, 0, 0, -days, 0, 0, 0, 0);
21241  }
21242  }
21243 
21244  /* year should always be greater than 1 and less than 9999 */
21245  if (ret != NO_ERROR)
21246  {
21247  error_status = ER_OBJ_INVALID_ARGUMENTS;
21248  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
21249  goto error;
21250  }
21251 
21252  db_date_encode (&db_date, m, d, y);
21253 
21254  if (res_type == DB_TYPE_STRING || res_type == DB_TYPE_CHAR)
21255  {
21256  db_date_to_string (res_s, 64, &db_date);
21257 
21258  res_final = (char *) db_private_alloc (NULL, strlen (res_s) + 1);
21259  if (!res_final)
21260  {
21261  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
21262  goto error;
21263  }
21264  strcpy (res_final, res_s);
21265  db_make_string (result, res_final);
21266  result->need_clear = true;
21267  }
21268  else
21269  {
21270  db_make_date (result, m, d, y);
21271  }
21272  }
21273  else if (is_dt >= 0)
21274  {
21275  assert (dt_p != NULL);
21276 
21277  y = m = d = h = mi = s = ms = 0;
21278  db_datetime_decode (dt_p, &m, &d, &y, &h, &mi, &s, &ms);
21279 
21280  if (m == 0 && d == 0 && y == 0 && h == 0 && mi == 0 && s == 0 && ms == 0)
21281  {
21282  db_make_null (result);
21283  er_clear ();
21285  {
21286  return NO_ERROR;
21287  }
21290  }
21291 
21292  if (is_add)
21293  {
21294  if (days > 0)
21295  {
21296  ret = add_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, 0, 0, days, 0, 0, 0, 0);
21297  }
21298  else
21299  {
21300  ret = sub_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, 0, 0, -days, 0, 0, 0, 0);
21301  }
21302  }
21303  else
21304  {
21305  if (days > 0)
21306  {
21307  ret = sub_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, 0, 0, days, 0, 0, 0, 0);
21308  }
21309  else
21310  {
21311  ret = add_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, 0, 0, -days, 0, 0, 0, 0);
21312  }
21313  }
21314  /* year should always be greater than 1 and less than 9999 */
21315  if (ret != NO_ERROR)
21316  {
21317  error_status = ER_OBJ_INVALID_ARGUMENTS;
21318  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
21319  goto error;
21320  }
21321 
21322  if (is_timezone > 0)
21323  {
21324  error_status = tz_create_datetimetz_from_parts (m, d, y, h, mi, s, ms, &tz_id, &dt_tz);
21325  }
21326  else
21327  {
21328  error_status = db_datetime_encode (&db_datetime, m, d, y, h, mi, s, ms);
21329  }
21330 
21331  if (error_status != NO_ERROR)
21332  {
21333  goto error;
21334  }
21335 
21336  if (res_type == DB_TYPE_STRING || res_type == DB_TYPE_CHAR)
21337  {
21338  if (is_timezone > 0)
21339  {
21340  db_datetimetz_to_string (res_s, 64, &dt_tz.datetime, &dt_tz.tz_id);
21341  }
21342  else
21343  {
21344  db_datetime_to_string (res_s, 64, &db_datetime);
21345  }
21346 
21347  res_final = (char *) db_private_alloc (NULL, strlen (res_s) + 1);
21348  if (!res_final)
21349  {
21350  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
21351  goto error;
21352  }
21353  strcpy (res_final, res_s);
21354  db_make_string (result, res_final);
21355  result->need_clear = true;
21356  }
21357  else
21358  {
21359  if (is_timezone > 0)
21360  {
21361  db_make_datetimetz (result, &dt_tz);
21362  }
21363  else if (is_local_timezone > 0)
21364  {
21365  db_make_datetimeltz (result, &db_datetime);
21366  }
21367  else
21368  {
21369  db_make_datetime (result, &db_datetime);
21370  }
21371  }
21372  }
21373  else if (is_timest >= 0)
21374  {
21375  assert (ts_p != NULL);
21376 
21377  y = m = d = h = mi = s = ms = 0;
21378 
21379  db_timestamp_decode_utc (ts_p, &db_date, &db_time);
21380  db_date_decode (&db_date, &m, &d, &y);
21381  db_time_decode (&db_time, &h, &mi, &s);
21382 
21383  if (m == 0 && d == 0 && y == 0 && h == 0 && mi == 0 && s == 0)
21384  {
21385  db_make_null (result);
21386  er_clear ();
21388  {
21389  return NO_ERROR;
21390  }
21393  }
21394 
21395  if (is_add)
21396  {
21397  if (days > 0)
21398  {
21399  ret = add_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, 0, 0, days, 0, 0, 0, 0);
21400  }
21401  else
21402  {
21403  ret = sub_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, 0, 0, -days, 0, 0, 0, 0);
21404  }
21405  }
21406  else
21407  {
21408  if (days > 0)
21409  {
21410  ret = sub_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, 0, 0, days, 0, 0, 0, 0);
21411  }
21412  else
21413  {
21414  ret = add_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, 0, 0, -days, 0, 0, 0, 0);
21415  }
21416  }
21417 
21418  /* year should always be greater than 1 and less than 9999 */
21419  if (ret != NO_ERROR)
21420  {
21421  error_status = ER_OBJ_INVALID_ARGUMENTS;
21422  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
21423  goto error;
21424  }
21425 
21426  if (is_local_timezone <= 0)
21427  {
21428  if (is_timezone > 0)
21429  {
21430  error_status = tz_create_datetimetz_from_parts (m, d, y, h, mi, s, ms, &tz_id, &dt_tz);
21431  }
21432  else
21433  {
21434  error_status = tz_create_datetimetz_from_parts (m, d, y, h, mi, s, ms, NULL, &dt_tz);
21435  }
21436  }
21437  else
21438  {
21439  error_status = db_datetime_encode (&db_datetime, m, d, y, h, mi, s, ms);
21440  dt_tz.datetime = db_datetime;
21441  dt_tz.tz_id = tz_id;
21442  }
21443  if (error_status != NO_ERROR)
21444  {
21445  goto error;
21446  }
21447 
21448  if (res_type == DB_TYPE_STRING || res_type == DB_TYPE_CHAR)
21449  {
21450  DB_DATETIME dt_local;
21451 
21452  error_status = tz_utc_datetimetz_to_local (&dt_tz.datetime, &dt_tz.tz_id, &dt_local);
21453  if (error_status != NO_ERROR)
21454  {
21455  goto error;
21456  }
21457 
21458  db_datetime_to_string (res_s, 64, &dt_local);
21459 
21460  res_final = (char *) db_private_alloc (NULL, strlen (res_s) + 1);
21461  if (!res_final)
21462  {
21463  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
21464  goto error;
21465  }
21466  strcpy (res_final, res_s);
21467  db_make_string (result, res_final);
21468  result->need_clear = true;
21469  }
21470  else
21471  {
21472  if (is_timezone > 0)
21473  {
21474  db_make_datetimetz (result, &dt_tz);
21475  }
21476  else if (is_local_timezone > 0)
21477  {
21478  db_make_datetimeltz (result, &db_datetime);
21479  }
21480  else
21481  {
21482  DB_DATETIME dt_local;
21483 
21484  error_status = tz_utc_datetimetz_to_local (&dt_tz.datetime, &dt_tz.tz_id, &dt_local);
21485  if (error_status != NO_ERROR)
21486  {
21487  goto error;
21488  }
21489  db_make_datetime (result, &dt_local);
21490  }
21491  }
21492  }
21493 
21494 error:
21495  return error_status;
21496 }
21497 
21498 int
21499 db_date_add_interval_days (DB_VALUE * result, const DB_VALUE * date, const DB_VALUE * db_days)
21500 {
21501  return db_date_add_sub_interval_days (result, date, db_days, true);
21502 }
21503 
21504 int
21505 db_date_sub_interval_days (DB_VALUE * result, const DB_VALUE * date, const DB_VALUE * db_days)
21506 {
21507  return db_date_add_sub_interval_days (result, date, db_days, false);
21508 }
21509 
21510 /*
21511  * db_str_to_millisec () -
21512  *
21513  * Arguments:
21514  * str: millisecond format
21515  *
21516  * Returns: int
21517  *
21518  * Errors:
21519  */
21520 static int
21521 db_str_to_millisec (const char *str)
21522 {
21523  int digit_num, value, ret;
21524 
21525  if (str == NULL || str[0] == '\0')
21526  {
21527  return 0;
21528  }
21529 
21530  digit_num = strlen (str);
21531  if (digit_num >= 1 && str[0] == '-')
21532  {
21533  digit_num--;
21534  ret = sscanf (str, "%4d", &value);
21535  }
21536  else
21537  {
21538  ret = sscanf (str, "%3d", &value);
21539  }
21540 
21541  if (ret != 1)
21542  {
21543  return 0;
21544  }
21545 
21546  switch (digit_num)
21547  {
21548  case 1:
21549  value *= 100;
21550  break;
21551 
21552  case 2:
21553  value *= 10;
21554  break;
21555 
21556  default:
21557  break;
21558  }
21559 
21560  return value;
21561 }
21562 
21563 /*
21564  * copy_and_shift_values () -
21565  *
21566  * Arguments:
21567  * shift: the offset the values are shifted
21568  * n: normal number of arguments
21569  * first...: arguments
21570  *
21571  * Returns: int
21572  *
21573  * Errors:
21574  *
21575  * Note:
21576  * shifts all arguments by the given value
21577  */
21578 static void
21579 copy_and_shift_values (int shift, int n, DB_BIGINT * first, ...)
21580 {
21581  va_list marker;
21582  DB_BIGINT *curr = first;
21583  DB_BIGINT *v[16]; /* will contain max 5 elements */
21584  int i, count = 0, cnt_src = 0;
21585 
21586  /*
21587  * numeric arguments from interval expression have a delimiter read also
21588  * as argument so out of N arguments there are actually (N + 1)/2 numeric
21589  * values (ex: 1:2:3:4 or 1:2 or 1:2:3)
21590  */
21591  shift = (shift + 1) / 2;
21592 
21593  if (shift == n)
21594  {
21595  return;
21596  }
21597 
21598  va_start (marker, first); /* init variable arguments */
21599  while (cnt_src < n)
21600  {
21601  cnt_src++;
21602  v[count++] = curr;
21603  curr = va_arg (marker, DB_BIGINT *);
21604  }
21605  va_end (marker);
21606 
21607  cnt_src = shift - 1;
21608  /* move backwards to not overwrite values */
21609  for (i = count - 1; i >= 0; i--)
21610  {
21611  if (cnt_src >= 0)
21612  {
21613  /* replace */
21614  *v[i] = *v[cnt_src--];
21615  }
21616  else
21617  {
21618  /* reset */
21619  *v[i] = 0;
21620  }
21621  }
21622 }
21623 
21624 /*
21625  * get_single_unit_value () -
21626  * return:
21627  * expr (in): input as string
21628  * int_val (in) : input as integer
21629  */
21630 static DB_BIGINT
21631 get_single_unit_value (const char *expr, DB_BIGINT int_val)
21632 {
21633  DB_BIGINT v = 0;
21634 
21635  if (expr == NULL)
21636  {
21637  v = int_val;
21638  }
21639  else
21640  {
21641  sscanf (expr, "%lld", (long long *) &v);
21642  }
21643 
21644  return v;
21645 }
21646 
21647 /*
21648  * db_date_add_sub_interval_expr () -
21649  *
21650  * Arguments:
21651  * date: starting date
21652  * expr: string with the amounts to add
21653  * unit: unit(s) of the amounts
21654  *
21655  * Returns: int
21656  *
21657  * Errors:
21658  *
21659  * Note:
21660  * Returns date + the amounts from expr
21661  */
21662 static int
21663 db_date_add_sub_interval_expr (DB_VALUE * result, const DB_VALUE * date, const DB_VALUE * expr, const int unit,
21664  int is_add)
21665 {
21666  int sign = 0;
21667  int type = 0; /* 1 -> time, 2 -> date, 3 -> both */
21668  DB_TYPE res_type, expr_type;
21669  const char *expr_s = NULL, *date_s = NULL;
21670  char res_s[64], millisec_s[64];
21671  int error_status = NO_ERROR;
21672  DB_BIGINT millisec, seconds, minutes, hours;
21673  DB_BIGINT days, weeks, months, quarters, years;
21674  DB_DATETIME db_datetime, *dt_p = NULL;
21675  DB_DATETIMETZ dt_tz;
21676  DB_TIME db_time;
21677  DB_DATE db_date, *d_p;
21678  DB_TIMESTAMP db_timestamp, *ts_p = NULL;
21679  int narg, is_dt = -1, is_d = -1, is_t = -1, is_timest = -1, is_timezone = -1, is_local_timezone = -1;
21680  char delim;
21681  DB_VALUE trimed_expr;
21682  DB_BIGINT unit_int_val;
21683  double dbl;
21684  int y, m, d, h, mi, s, ms;
21685  int ret;
21686  char *res_final;
21687  TZ_ID tz_id = 0;
21688 
21689  res_type = DB_VALUE_DOMAIN_TYPE (date);
21690  if (res_type == DB_TYPE_NULL || DB_IS_NULL (date))
21691  {
21692  db_make_null (result);
21693  return NO_ERROR;
21694  }
21695 
21696  expr_type = DB_VALUE_DOMAIN_TYPE (expr);
21697  if (expr_type == DB_TYPE_NULL || DB_IS_NULL (expr))
21698  {
21699  db_make_null (result);
21700  return NO_ERROR;
21701  }
21702 
21703  db_make_null (&trimed_expr);
21704  unit_int_val = 0;
21705  expr_s = NULL;
21706 
21707  /* 1. Prepare the input: convert expr to char */
21708 
21709  /*
21710  * expr is converted to char because it may contain a more complicated form
21711  * for the multiple unit formats, for example:
21712  * 'DAYS HOURS:MINUTES:SECONDS.MILLISECONDS'
21713  * For the simple unit tags, expr is integer
21714  */
21715 
21716  expr_type = DB_VALUE_DOMAIN_TYPE (expr);
21717  switch (expr_type)
21718  {
21719  case DB_TYPE_CHAR:
21720  case DB_TYPE_VARCHAR:
21721  case DB_TYPE_NCHAR:
21722  case DB_TYPE_VARNCHAR:
21723  error_status = db_string_trim (BOTH, NULL, expr, &trimed_expr);
21724  if (error_status != NO_ERROR)
21725  {
21726  goto error;
21727  }
21728 
21729  /* db_string_trim builds a NULL terminated string, expr_s is NULL terminated */
21730  expr_s = db_get_string (&trimed_expr);
21731  if (expr_s == NULL)
21732  {
21733  error_status = ER_OBJ_INVALID_ARGUMENTS;
21734  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
21735  goto error;
21736  }
21737  break;
21738 
21739  case DB_TYPE_SHORT:
21740  unit_int_val = db_get_short (expr);
21741  break;
21742 
21743  case DB_TYPE_INTEGER:
21744  unit_int_val = db_get_int (expr);
21745  break;
21746 
21747  case DB_TYPE_BIGINT:
21748  unit_int_val = db_get_bigint (expr);
21749  break;
21750 
21751  case DB_TYPE_FLOAT:
21752  unit_int_val = (DB_BIGINT) round (db_get_float (expr));
21753  break;
21754 
21755  case DB_TYPE_DOUBLE:
21756  unit_int_val = (DB_BIGINT) round (db_get_double (expr));
21757  break;
21758 
21759  case DB_TYPE_NUMERIC:
21761  unit_int_val = (DB_BIGINT) round (dbl);
21762  break;
21763 
21764  default:
21765  error_status = ER_OBJ_INVALID_ARGUMENTS;
21766  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
21767  goto error;
21768  }
21769 
21770  /* 2. the big switch: according to unit, we parse expr and get amounts of ms/s/m/h/d/m/y/w/q to add or subtract */
21771 
21772  millisec_s[0] = '\0';
21773  millisec = seconds = minutes = hours = 0;
21774  days = weeks = months = quarters = years = 0;
21775 
21776 #if defined (SERVER_MODE)
21777  /* FIXME!! */
21778 #define PT_MILLISECOND 3087
21779 #define PT_SECOND (PT_MILLISECOND + 1)
21780 #define PT_MINUTE (PT_MILLISECOND + 2)
21781 #define PT_HOUR (PT_MILLISECOND + 3)
21782 #define PT_DAY (PT_MILLISECOND + 4)
21783 #define PT_WEEK (PT_MILLISECOND + 5)
21784 #define PT_MONTH (PT_MILLISECOND + 6)
21785 #define PT_QUARTER (PT_MILLISECOND + 7)
21786 #define PT_YEAR (PT_MILLISECOND + 8)
21787 #define PT_SECOND_MILLISECOND (PT_MILLISECOND + 9)
21788 #define PT_MINUTE_MILLISECOND (PT_MILLISECOND + 10)
21789 #define PT_MINUTE_SECOND (PT_MILLISECOND + 11)
21790 #define PT_HOUR_MILLISECOND (PT_MILLISECOND + 12)
21791 #define PT_HOUR_SECOND (PT_MILLISECOND + 13)
21792 #define PT_HOUR_MINUTE (PT_MILLISECOND + 14)
21793 #define PT_DAY_MILLISECOND (PT_MILLISECOND + 15)
21794 #define PT_DAY_SECOND (PT_MILLISECOND + 16)
21795 #define PT_DAY_MINUTE (PT_MILLISECOND + 17)
21796 #define PT_DAY_HOUR (PT_MILLISECOND + 18)
21797 #define PT_YEAR_MONTH (PT_MILLISECOND + 19)
21798 #endif /* SERVER_MODE */
21799 
21800  switch (unit)
21801  {
21802  case PT_MILLISECOND:
21803  millisec = get_single_unit_value (expr_s, unit_int_val);
21804  sign = (millisec >= 0);
21805  type |= 1;
21806  break;
21807 
21808  case PT_SECOND:
21809  seconds = get_single_unit_value (expr_s, unit_int_val);
21810  sign = (seconds >= 0);
21811  type |= 1;
21812  break;
21813 
21814  case PT_MINUTE:
21815  minutes = get_single_unit_value (expr_s, unit_int_val);
21816  sign = (minutes >= 0);
21817  type |= 1;
21818  break;
21819 
21820  case PT_HOUR:
21821  hours = get_single_unit_value (expr_s, unit_int_val);
21822  sign = (hours >= 0);
21823  type |= 1;
21824  break;
21825 
21826  case PT_DAY:
21827  days = get_single_unit_value (expr_s, unit_int_val);
21828  sign = (days >= 0);
21829  type |= 2;
21830  break;
21831 
21832  case PT_WEEK:
21833  weeks = get_single_unit_value (expr_s, unit_int_val);
21834  sign = (weeks >= 0);
21835  type |= 2;
21836  break;
21837 
21838  case PT_MONTH:
21839  months = get_single_unit_value (expr_s, unit_int_val);
21840  sign = (months >= 0);
21841  type |= 2;
21842  break;
21843 
21844  case PT_QUARTER:
21845  quarters = get_single_unit_value (expr_s, unit_int_val);
21846  sign = (quarters >= 0);
21847  type |= 2;
21848  break;
21849 
21850  case PT_YEAR:
21851  years = get_single_unit_value (expr_s, unit_int_val);
21852  sign = (years >= 0);
21853  type |= 2;
21854  break;
21855 
21856  case PT_SECOND_MILLISECOND:
21857  if (expr_s)
21858  {
21859  narg = sscanf (expr_s, "%lld%c%s", (long long *) &seconds, &delim, millisec_s);
21860  millisec = db_str_to_millisec (millisec_s);
21861  copy_and_shift_values (narg, 2, &seconds, &millisec);
21862  }
21863  else
21864  {
21865  millisec = unit_int_val;
21866  }
21867  sign = (seconds >= 0);
21868  type |= 1;
21869  break;
21870 
21871  case PT_MINUTE_MILLISECOND:
21872  if (expr_s)
21873  {
21874  narg =
21875  sscanf (expr_s, "%lld%c%lld%c%s", (long long *) &minutes, &delim, (long long *) &seconds, &delim,
21876  millisec_s);
21877  millisec = db_str_to_millisec (millisec_s);
21878  copy_and_shift_values (narg, 3, &minutes, &seconds, &millisec);
21879  }
21880  else
21881  {
21882  millisec = unit_int_val;
21883  }
21884  sign = (minutes >= 0);
21885  type |= 1;
21886  break;
21887 
21888  case PT_MINUTE_SECOND:
21889  if (expr_s)
21890  {
21891  narg = sscanf (expr_s, "%lld%c%lld", (long long *) &minutes, &delim, (long long *) &seconds);
21892  copy_and_shift_values (narg, 2, &minutes, &seconds);
21893  }
21894  else
21895  {
21896  seconds = unit_int_val;
21897  }
21898  sign = (minutes >= 0);
21899  type |= 1;
21900  break;
21901 
21902  case PT_HOUR_MILLISECOND:
21903  if (expr_s)
21904  {
21905  narg =
21906  sscanf (expr_s, "%lld%c%lld%c%lld%c%s", (long long *) &hours, &delim, (long long *) &minutes, &delim,
21907  (long long *) &seconds, &delim, millisec_s);
21908  millisec = db_str_to_millisec (millisec_s);
21909  copy_and_shift_values (narg, 4, &hours, &minutes, &seconds, &millisec);
21910  }
21911  else
21912  {
21913  millisec = unit_int_val;
21914  }
21915  sign = (hours >= 0);
21916  type |= 1;
21917  break;
21918 
21919  case PT_HOUR_SECOND:
21920  if (expr_s)
21921  {
21922  narg =
21923  sscanf (expr_s, "%lld%c%lld%c%lld", (long long *) &hours, &delim, (long long *) &minutes, &delim,
21924  (long long *) &seconds);
21925  copy_and_shift_values (narg, 3, &hours, &minutes, &seconds);
21926  }
21927  else
21928  {
21929  seconds = unit_int_val;
21930  }
21931  sign = (hours >= 0);
21932  type |= 1;
21933  break;
21934 
21935  case PT_HOUR_MINUTE:
21936  if (expr_s)
21937  {
21938  narg = sscanf (expr_s, "%lld%c%lld", (long long *) &hours, &delim, (long long *) &minutes);
21939  copy_and_shift_values (narg, 2, &hours, &minutes);
21940  }
21941  else
21942  {
21943  minutes = unit_int_val;
21944  }
21945  sign = (hours >= 0);
21946  type |= 1;
21947  break;
21948 
21949  case PT_DAY_MILLISECOND:
21950  if (expr_s)
21951  {
21952  narg =
21953  sscanf (expr_s, "%lld%c%lld%c%lld%c%lld%c%s", (long long *) &days, &delim, (long long *) &hours, &delim,
21954  (long long *) &minutes, &delim, (long long *) &seconds, &delim, millisec_s);
21955  millisec = db_str_to_millisec (millisec_s);
21956  copy_and_shift_values (narg, 5, &days, &hours, &minutes, &seconds, &millisec);
21957  }
21958  else
21959  {
21960  millisec = unit_int_val;
21961  }
21962  sign = (days >= 0);
21963  type |= 1;
21964  type |= 2;
21965  break;
21966 
21967  case PT_DAY_SECOND:
21968  if (expr_s)
21969  {
21970  narg =
21971  sscanf (expr_s, "%lld%c%lld%c%lld%c%lld", (long long *) &days, &delim, (long long *) &hours, &delim,
21972  (long long *) &minutes, &delim, (long long *) &seconds);
21973  copy_and_shift_values (narg, 4, &days, &hours, &minutes, &seconds);
21974  }
21975  else
21976  {
21977  seconds = unit_int_val;
21978  }
21979  sign = (days >= 0);
21980  type |= 1;
21981  type |= 2;
21982  break;
21983 
21984  case PT_DAY_MINUTE:
21985  if (expr_s)
21986  {
21987  narg =
21988  sscanf (expr_s, "%lld%c%lld%c%lld", (long long *) &days, &delim, (long long *) &hours, &delim,
21989  (long long *) &minutes);
21990  copy_and_shift_values (narg, 3, &days, &hours, &minutes);
21991  }
21992  else
21993  {
21994  minutes = unit_int_val;
21995  }
21996  sign = (days >= 0);
21997  type |= 1;
21998  type |= 2;
21999  break;
22000 
22001  case PT_DAY_HOUR:
22002  if (expr_s)
22003  {
22004  narg = sscanf (expr_s, "%lld%c%lld", (long long *) &days, &delim, (long long *) &hours);
22005  copy_and_shift_values (narg, 2, &days, &hours);
22006  }
22007  else
22008  {
22009  hours = unit_int_val;
22010  }
22011  sign = (days >= 0);
22012  type |= 1;
22013  type |= 2;
22014  break;
22015 
22016  case PT_YEAR_MONTH:
22017  if (expr_s)
22018  {
22019  narg = sscanf (expr_s, "%lld%c%lld", (long long *) &years, &delim, (long long *) &months);
22020  copy_and_shift_values (narg, 2, &years, &months);
22021  }
22022  else
22023  {
22024  months = unit_int_val;
22025  }
22026  sign = (years >= 0);
22027  type |= 2;
22028  break;
22029 
22030  default:
22031  error_status = ER_OBJ_INVALID_ARGUMENTS;
22032  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
22033  goto error;
22034  }
22035 
22036 #if defined (SERVER_MODE)
22037  /* FIXME!! */
22038 #undef PT_MILLISECOND
22039 #undef PT_SECOND
22040 #undef PT_MINUTE
22041 #undef PT_HOUR
22042 #undef PT_DAY
22043 #undef PT_WEEK
22044 #undef PT_MONTH
22045 #undef PT_QUARTER
22046 #undef PT_YEAR
22047 #undef PT_SECOND_MILLISECOND
22048 #undef PT_MINUTE_MILLISECOND
22049 #undef PT_MINUTE_SECOND
22050 #undef PT_HOUR_MILLISECOND
22051 #undef PT_HOUR_SECOND
22052 #undef PT_HOUR_MINUTE
22053 #undef PT_DAY_MILLISECOND
22054 #undef PT_DAY_SECOND
22055 #undef PT_DAY_MINUTE
22056 #undef PT_DAY_HOUR
22057 #undef PT_YEAR_MONTH
22058 #endif /* SERVER_MODE */
22059 
22060  /* we have the sign of the amounts, turn them in absolute value */
22061  years = ABS (years);
22062  months = ABS (months);
22063  days = ABS (days);
22064  weeks = ABS (weeks);
22065  quarters = ABS (quarters);
22066  hours = ABS (hours);
22067  minutes = ABS (minutes);
22068  seconds = ABS (seconds);
22069  millisec = ABS (millisec);
22070 
22071  /* convert weeks and quarters to our units */
22072  if (weeks != 0)
22073  {
22074  days += weeks * 7;
22075  weeks = 0;
22076  }
22077 
22078  if (quarters != 0)
22079  {
22080  months += 3 * quarters;
22081  quarters = 0;
22082  }
22083 
22084  /* 3. Convert string with date to DateTime or Time */
22085 
22086  switch (res_type)
22087  {
22088  case DB_TYPE_CHAR:
22089  case DB_TYPE_VARCHAR:
22090  case DB_TYPE_NCHAR:
22091  case DB_TYPE_VARNCHAR:
22092  {
22093  bool has_explicit_time = false;
22094  bool has_zone = false;
22095  int str_len = db_get_string_size (date);
22096  date_s = db_get_string (date);
22097 
22098  if (db_string_to_datetimetz_ex (date_s, str_len, &dt_tz, &has_zone) == NO_ERROR && has_zone == true)
22099  {
22100  is_dt = NO_ERROR;
22101  is_timest = ER_TIMESTAMP_CONVERSION;
22102  is_d = ER_DATE_CONVERSION;
22103  is_t = ER_TIME_CONVERSION;
22104  is_timezone = 1;
22105  db_datetime = dt_tz.datetime;
22106  tz_id = dt_tz.tz_id;
22107  }
22108  /* try to figure out the string format */
22109  else if (db_date_parse_datetime_parts (date_s, str_len, &db_datetime, &has_explicit_time, NULL, NULL, NULL))
22110  {
22111  is_dt = ER_TIMESTAMP_CONVERSION;
22112  is_timest = ER_TIMESTAMP_CONVERSION;
22113  is_d = ER_DATE_CONVERSION;
22114  is_t = db_string_to_time_ex (date_s, str_len, &db_time);
22115  }
22116  else if (has_explicit_time)
22117  {
22118  is_dt = NO_ERROR;
22119  is_timest = ER_TIMESTAMP_CONVERSION;
22120  is_d = ER_DATE_CONVERSION;
22121  is_t = ER_TIME_CONVERSION;
22122  }
22123  else
22124  {
22125  db_date = db_datetime.date;
22126  is_dt = ER_TIMESTAMP_CONVERSION;
22127  is_timest = ER_TIMESTAMP_CONVERSION;
22128  is_d = NO_ERROR;
22129  is_t = ER_TIME_CONVERSION;
22130  }
22131 
22132  if (is_dt && is_d && is_t && is_timest)
22133  {
22134  error_status = ER_DATE_CONVERSION;
22135  goto error;
22136  }
22137 
22138  /* add date stuff to a time -> error */
22139  /* in fact, disable time operations, not available on mysql */
22140  if (is_t == 0)
22141  {
22142  error_status = ER_OBJ_INVALID_ARGUMENTS;
22143  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
22144  goto error;
22145  }
22146 
22147  dt_p = &db_datetime;
22148  d_p = &db_date;
22149  ts_p = &db_timestamp;
22150 
22151  /* except just TIME business, convert all to DATETIME */
22152  }
22153  break;
22154 
22155  case DB_TYPE_DATE:
22156  is_d = 1;
22157  d_p = db_get_date (date);
22158  break;
22159 
22160  case DB_TYPE_DATETIME:
22161  case DB_TYPE_DATETIMELTZ:
22162  is_dt = 1;
22163  dt_p = db_get_datetime (date);
22164  if (res_type == DB_TYPE_DATETIMELTZ)
22165  {
22166  is_local_timezone = 1;
22167  }
22168  break;
22169 
22170  case DB_TYPE_DATETIMETZ:
22171  {
22172  DB_DATETIMETZ *dt_tz_p;
22173 
22174  dt_tz_p = db_get_datetimetz (date);
22175 
22176  dt_p = &dt_tz_p->datetime;
22177  tz_id = dt_tz_p->tz_id;
22178  is_dt = 1;
22179  is_timezone = 1;
22180  break;
22181  }
22182 
22183  case DB_TYPE_TIMESTAMP:
22184  case DB_TYPE_TIMESTAMPLTZ:
22185  is_timest = 1;
22186  ts_p = db_get_timestamp (date);
22187  if (res_type == DB_TYPE_TIMESTAMPLTZ)
22188  {
22189  is_local_timezone = 1;
22190  }
22191  break;
22192 
22193  case DB_TYPE_TIMESTAMPTZ:
22194  {
22195  DB_TIMESTAMPTZ *ts_tz_p;
22196 
22197  ts_tz_p = db_get_timestamptz (date);
22198  ts_p = &ts_tz_p->timestamp;
22199  tz_id = ts_tz_p->tz_id;
22200  is_timest = 1;
22201  is_timezone = 1;
22202  break;
22203  }
22204 
22205  case DB_TYPE_TIME:
22206  /* should not reach here */
22207  assert (0);
22208  break;
22209 
22210  default:
22211  error_status = ER_OBJ_INVALID_ARGUMENTS;
22212  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
22213  goto error;
22214  }
22215 
22216  /* treat as date only if adding date units, else treat as datetime */
22217  if (is_d >= 0)
22218  {
22219  y = m = d = h = mi = s = ms = 0;
22220  db_date_decode (d_p, &m, &d, &y);
22221 
22222  if (m == 0 && d == 0 && y == 0)
22223  {
22224  pr_clear_value (&trimed_expr);
22225  db_make_null (result);
22226  er_clear ();
22228  {
22229  return NO_ERROR;
22230  }
22232  return ER_DATE_CONVERSION;
22233  }
22234 
22235  if (sign ^ is_add)
22236  {
22237  ret =
22238  sub_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, years, months, days, hours, minutes, seconds,
22239  millisec);
22240  }
22241  else
22242  {
22243  ret =
22244  add_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, years, months, days, hours, minutes, seconds,
22245  millisec);
22246  }
22247 
22248  /* year should always be greater than 1 and less than 9999 */
22249  if (ret != NO_ERROR)
22250  {
22251  error_status = ER_OBJ_INVALID_ARGUMENTS;
22252  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
22253  goto error;
22254  }
22255 
22256  if (type == 2)
22257  {
22258  db_date_encode (&db_date, m, d, y);
22259 
22260  if (m == 0 && d == 0 && y == 0)
22261  {
22262  pr_clear_value (&trimed_expr);
22263  db_make_null (result);
22264  er_clear ();
22266  {
22267  return NO_ERROR;
22268  }
22270  return ER_DATE_CONVERSION;
22271  }
22272 
22273  if (res_type == DB_TYPE_STRING || res_type == DB_TYPE_CHAR)
22274  {
22275  db_date_to_string (res_s, 64, &db_date);
22276 
22277  res_final = (char *) db_private_alloc (NULL, strlen (res_s) + 1);
22278  if (res_final == NULL)
22279  {
22280  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
22281  goto error;
22282  }
22283  strcpy (res_final, res_s);
22284  db_make_string (result, res_final);
22285  result->need_clear = true;
22286  }
22287  else
22288  {
22289  db_make_date (result, m, d, y);
22290  }
22291  }
22292  else if (type & 1)
22293  {
22294  db_datetime.date = db_datetime.time = 0;
22295  db_datetime_encode (&db_datetime, m, d, y, h, mi, s, ms);
22296 
22297  if (m == 0 && d == 0 && y == 0 && h == 0 && mi == 0 && s == 0 && ms == 0)
22298  {
22299  pr_clear_value (&trimed_expr);
22300  db_make_null (result);
22301  er_clear ();
22303  {
22304  return NO_ERROR;
22305  }
22307  return ER_DATE_CONVERSION;
22308  }
22309 
22310  if (res_type == DB_TYPE_STRING || res_type == DB_TYPE_CHAR)
22311  {
22312  db_datetime_to_string (res_s, 64, &db_datetime);
22313 
22314  res_final = (char *) db_private_alloc (NULL, strlen (res_s) + 1);
22315  if (res_final == NULL)
22316  {
22317  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
22318  goto error;
22319  }
22320  strcpy (res_final, res_s);
22321  db_make_string (result, res_final);
22322  result->need_clear = true;
22323  }
22324  else
22325  {
22326  if (is_local_timezone > 0)
22327  {
22328  error_status = tz_create_datetimetz_from_ses (&db_datetime, &dt_tz);
22329  if (error_status != NO_ERROR)
22330  {
22331  goto error;
22332  }
22333  db_make_datetimeltz (result, &dt_tz.datetime);
22334  }
22335  else if (is_timezone > 0)
22336  {
22338 
22339  tz_id_to_region (&tz_id, &tz_region);
22340  error_status = tz_create_datetimetz (&db_datetime, NULL, 0, &tz_region, &dt_tz, NULL);
22341  if (error_status != NO_ERROR)
22342  {
22343  goto error;
22344  }
22345  db_make_datetimetz (result, &dt_tz);
22346  }
22347  else
22348  {
22349  db_make_datetime (result, &db_datetime);
22350  }
22351  }
22352  }
22353  }
22354  else if (is_dt >= 0)
22355  {
22356  assert (dt_p != NULL);
22357  y = m = d = h = mi = s = ms = 0;
22358 
22359  db_datetime_decode (dt_p, &m, &d, &y, &h, &mi, &s, &ms);
22360 
22361  if (m == 0 && d == 0 && y == 0 && h == 0 && mi == 0 && s == 0 && ms == 0)
22362  {
22363  pr_clear_value (&trimed_expr);
22364  db_make_null (result);
22365  er_clear ();
22367  {
22368  return NO_ERROR;
22369  }
22371  return ER_DATE_CONVERSION;
22372  }
22373 
22374  if (sign ^ is_add)
22375  {
22376  ret =
22377  sub_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, years, months, days, hours, minutes, seconds,
22378  millisec);
22379  }
22380  else
22381  {
22382  ret =
22383  add_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, years, months, days, hours, minutes, seconds,
22384  millisec);
22385  }
22386 
22387  /* year should always be greater than 1 and less than 9999 */
22388  if (ret != NO_ERROR)
22389  {
22390  error_status = ER_OBJ_INVALID_ARGUMENTS;
22391  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
22392  goto error;
22393  }
22394 
22395  if (is_timezone > 0)
22396  {
22397  error_status = tz_create_datetimetz_from_parts (m, d, y, h, mi, s, ms, &tz_id, &dt_tz);
22398  }
22399  else
22400  {
22401  error_status = db_datetime_encode (&db_datetime, m, d, y, h, mi, s, ms);
22402  }
22403 
22404  if (error_status != NO_ERROR)
22405  {
22406  goto error;
22407  }
22408 
22409  if (res_type == DB_TYPE_STRING || res_type == DB_TYPE_CHAR)
22410  {
22411  if (is_timezone > 0)
22412  {
22413  db_datetimetz_to_string (res_s, 64, &dt_tz.datetime, &dt_tz.tz_id);
22414  }
22415  else
22416  {
22417  db_datetime_to_string (res_s, 64, &db_datetime);
22418  }
22419 
22420  res_final = (char *) db_private_alloc (NULL, strlen (res_s) + 1);
22421  if (res_final == NULL)
22422  {
22423  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
22424  goto error;
22425  }
22426  strcpy (res_final, res_s);
22427  db_make_string (result, res_final);
22428  result->need_clear = true;
22429  }
22430  else
22431  {
22432  /* datetime, date + time units, timestamp => return datetime */
22433  if (is_local_timezone > 0)
22434  {
22435  db_make_datetimeltz (result, &db_datetime);
22436  }
22437  else if (is_timezone > 0)
22438  {
22439  db_make_datetimetz (result, &dt_tz);
22440  }
22441  else
22442  {
22443  db_make_datetime (result, &db_datetime);
22444  }
22445  }
22446  }
22447  else if (is_timest >= 0)
22448  {
22449  assert (ts_p != NULL);
22450 
22451  y = m = d = h = mi = s = ms = 0;
22452 
22453  db_timestamp_decode_utc (ts_p, &db_date, &db_time);
22454  db_date_decode (&db_date, &m, &d, &y);
22455  db_time_decode (&db_time, &h, &mi, &s);
22456 
22457  if (m == 0 && d == 0 && y == 0 && h == 0 && mi == 0 && s == 0)
22458  {
22459  pr_clear_value (&trimed_expr);
22460  db_make_null (result);
22461  er_clear ();
22463  {
22464  return NO_ERROR;
22465  }
22467  return ER_TIMESTAMP_CONVERSION;
22468  }
22469 
22470  if (sign ^ is_add)
22471  {
22472  ret =
22473  sub_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, years, months, days, hours, minutes, seconds,
22474  millisec);
22475  }
22476  else
22477  {
22478  ret =
22479  add_and_normalize_date_time (&y, &m, &d, &h, &mi, &s, &ms, years, months, days, hours, minutes, seconds,
22480  millisec);
22481  }
22482 
22483  /* year should always be greater than 1 and less than 9999 */
22484  if (ret != NO_ERROR)
22485  {
22486  error_status = ER_OBJ_INVALID_ARGUMENTS;
22487  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
22488  goto error;
22489  }
22490 
22491  if (is_local_timezone <= 0)
22492  {
22493  if (is_timezone > 0)
22494  {
22495  error_status = tz_create_datetimetz_from_parts (m, d, y, h, mi, s, ms, &tz_id, &dt_tz);
22496  }
22497  else
22498  {
22499  error_status = tz_create_datetimetz_from_parts (m, d, y, h, mi, s, ms, NULL, &dt_tz);
22500  }
22501  }
22502  else
22503  {
22504  error_status = db_datetime_encode (&db_datetime, m, d, y, h, mi, s, ms);
22505  dt_tz.datetime = db_datetime;
22506  dt_tz.tz_id = tz_id;
22507  }
22508 
22509  if (error_status != NO_ERROR)
22510  {
22511  goto error;
22512  }
22513 
22514  if (res_type == DB_TYPE_STRING || res_type == DB_TYPE_CHAR)
22515  {
22516  DB_DATETIME dt_local;
22517 
22518  error_status = tz_utc_datetimetz_to_local (&dt_tz.datetime, &dt_tz.tz_id, &dt_local);
22519  if (error_status != NO_ERROR)
22520  {
22521  goto error;
22522  }
22523 
22524  db_datetime_to_string (res_s, 64, &dt_local);
22525 
22526  res_final = (char *) db_private_alloc (NULL, strlen (res_s) + 1);
22527  if (res_final == NULL)
22528  {
22529  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
22530  goto error;
22531  }
22532  strcpy (res_final, res_s);
22533  db_make_string (result, res_final);
22534  result->need_clear = true;
22535  }
22536  else
22537  {
22538  /* datetime, date + time units, timestamp => return datetime */
22539  if (is_local_timezone > 0)
22540  {
22541  db_make_datetimeltz (result, &db_datetime);
22542  }
22543  else if (is_timezone > 0)
22544  {
22545  db_make_datetimetz (result, &dt_tz);
22546  }
22547  else
22548  {
22549  DB_DATETIME dt_local;
22550 
22551  error_status = tz_utc_datetimetz_to_local (&dt_tz.datetime, &dt_tz.tz_id, &dt_local);
22552  if (error_status != NO_ERROR)
22553  {
22554  goto error;
22555  }
22556  db_make_datetime (result, &dt_local);
22557  }
22558  }
22559  }
22560 
22561 error:
22562  pr_clear_value (&trimed_expr);
22563  return error_status;
22564 }
22565 
22566 /*
22567  * db_date_add_interval_expr ()
22568  *
22569  * Arguments:
22570  * result(out):
22571  * date(in): source date
22572  * expr(in): to be added interval
22573  * unit(in): unit of interval expr
22574  *
22575  * Returns: int
22576  *
22577  * Note:
22578  */
22579 int
22580 db_date_add_interval_expr (DB_VALUE * result, const DB_VALUE * date, const DB_VALUE * expr, const int unit)
22581 {
22582  return db_date_add_sub_interval_expr (result, date, expr, unit, 1);
22583 }
22584 
22585 /*
22586  * db_date_sub_interval_expr ()
22587  *
22588  * Arguments:
22589  * result(out):
22590  * date(in): source date
22591  * expr(in): to be subtracted interval
22592  * unit(in): unit of interval expr
22593  *
22594  * Returns: int
22595  *
22596  * Note:
22597  */
22598 int
22599 db_date_sub_interval_expr (DB_VALUE * result, const DB_VALUE * date, const DB_VALUE * expr, const int unit)
22600 {
22601  return db_date_add_sub_interval_expr (result, date, expr, unit, 0);
22602 }
22603 
22604 /*
22605  * db_date_format ()
22606  *
22607  * Arguments:
22608  * date_value: source date
22609  * format: string with format specifiers
22610  * result: output string
22611  * domain: domain of result
22612  *
22613  * Returns: int
22614  *
22615  * Errors:
22616  *
22617  * Note:
22618  * formats the date according to a specified format
22619  */
22620 int
22621 db_date_format (const DB_VALUE * date_value, const DB_VALUE * format, const DB_VALUE * date_lang, DB_VALUE * result,
22622  const TP_DOMAIN * domain)
22623 {
22624  DB_DATETIME *dt_p;
22625  DB_DATE db_date, *d_p;
22626  DB_TIME db_time;
22627  DB_TIMESTAMP *ts_p;
22628  DB_TYPE res_type, format_type;
22629  const char *format_s = NULL, *strend = NULL;
22630  char *res, *res2;
22631  int format_s_len;
22632  int error_status = NO_ERROR, len;
22633  int y, m, d, h, mi, s, ms;
22634  int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
22635  char format_specifiers[256][64];
22636  int i, j;
22637  int dow, dow2;
22638  INTL_LANG date_lang_id;
22639  int tu, tv, tx, weeks, ld_fw, days_counter;
22640  char och = -1, ch;
22641  const LANG_LOCALE_DATA *lld;
22642  bool dummy;
22643  INTL_CODESET codeset;
22644  int res_collation;
22645  char tzr[TZR_SIZE + 1], tzd[TZ_DS_STRING_SIZE + 1];
22646  char hours_or_minutes[4];
22647  int tzh = 0, tzm = 0;
22648  bool is_valid_tz = false;
22649  bool has_tzh = false;
22650 
22651  assert (date_lang != NULL);
22652 
22653  y = m = d = h = mi = s = ms = 0;
22654  tzr[0] = '\0';
22655  tzd[0] = '\0';
22656  memset (hours_or_minutes, 0, sizeof (hours_or_minutes));
22657  memset (format_specifiers, 0, sizeof (format_specifiers));
22658 
22659  res = NULL;
22660  res2 = NULL;
22661 
22662  if (date_value == NULL || format == NULL || DB_IS_NULL (date_value) || DB_IS_NULL (format))
22663  {
22664  db_make_null (result);
22665  goto error;
22666  }
22667 
22668  if (!is_char_string (format))
22669  {
22670  error_status = ER_QSTR_INVALID_DATA_TYPE;
22671  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
22672  return error_status;
22673  }
22674 
22675  assert (DB_VALUE_TYPE (date_lang) == DB_TYPE_INTEGER);
22676  date_lang_id = lang_get_lang_id_from_flag (db_get_int (date_lang), &dummy, &dummy);
22677  if (domain != NULL && domain->collation_flag != TP_DOMAIN_COLL_LEAVE)
22678  {
22679  codeset = TP_DOMAIN_CODESET (domain);
22680  res_collation = TP_DOMAIN_COLLATION (domain);
22681  }
22682  else
22683  {
22684  codeset = db_get_string_codeset (format);
22685  res_collation = db_get_string_collation (format);
22686  }
22687 
22688  lld = lang_get_specific_locale (date_lang_id, codeset);
22689  if (lld == NULL)
22690  {
22691  error_status = ER_LANG_CODESET_NOT_AVAILABLE;
22692  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 2, lang_get_lang_name_from_id (date_lang_id),
22693  lang_charset_name (codeset));
22694  return error_status;
22695  }
22696 
22697  res_type = DB_VALUE_DOMAIN_TYPE (date_value);
22698 
22699  /* 1. Get date values */
22700  switch (res_type)
22701  {
22702  case DB_TYPE_DATETIME:
22703  {
22704  TZ_ID tz_id;
22705 
22706  dt_p = db_get_datetime (date_value);
22707  error_status = tz_create_session_tzid_for_datetime (dt_p, true, &tz_id);
22708  if (error_status != NO_ERROR)
22709  {
22710  return error_status;
22711  }
22712  db_datetime_decode (dt_p, &m, &d, &y, &h, &mi, &s, &ms);
22713 
22714  error_status = tz_explain_tz_id (&tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
22715  if (error_status != NO_ERROR)
22716  {
22717  return error_status;
22718  }
22719  is_valid_tz = true;
22720  }
22721  break;
22722 
22723  case DB_TYPE_DATE:
22724  d_p = db_get_date (date_value);
22725  db_date_decode (d_p, &m, &d, &y);
22726  break;
22727 
22728  case DB_TYPE_TIMESTAMP:
22729  {
22730  TZ_ID tz_id;
22731  ts_p = db_get_timestamp (date_value);
22732  error_status = tz_create_session_tzid_for_timestamp (ts_p, &tz_id);
22733  if (error_status != NO_ERROR)
22734  {
22735  return error_status;
22736  }
22737 
22738  (void) db_timestamp_decode_ses (ts_p, &db_date, &db_time);
22739  db_time_decode (&db_time, &h, &mi, &s);
22740  db_date_decode (&db_date, &m, &d, &y);
22741 
22742  error_status = tz_explain_tz_id (&tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
22743  if (error_status != NO_ERROR)
22744  {
22745  return error_status;
22746  }
22747  is_valid_tz = true;
22748  }
22749  break;
22750 
22751  case DB_TYPE_DATETIMETZ:
22752  {
22753  DB_DATETIME dt_local;
22754  DB_DATETIMETZ *dt_tz;
22755  dt_tz = db_get_datetimetz (date_value);
22756  error_status = tz_utc_datetimetz_to_local (&dt_tz->datetime, &dt_tz->tz_id, &dt_local);
22757  if (error_status != NO_ERROR)
22758  {
22759  return error_status;
22760  }
22761  db_datetime_decode (&dt_local, &m, &d, &y, &h, &mi, &s, &ms);
22762 
22763  error_status = tz_explain_tz_id (&dt_tz->tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
22764  if (error_status != NO_ERROR)
22765  {
22766  return error_status;
22767  }
22768  is_valid_tz = true;
22769  }
22770  break;
22771 
22772  case DB_TYPE_DATETIMELTZ:
22773  {
22774  DB_DATETIME *dt, dt_local;
22775  TZ_ID tz_id;
22776 
22777  dt = db_get_datetime (date_value);
22778  error_status = tz_create_session_tzid_for_datetime (dt, true, &tz_id);
22779  if (error_status != NO_ERROR)
22780  {
22781  return error_status;
22782  }
22783 
22784  error_status = tz_utc_datetimetz_to_local (dt, &tz_id, &dt_local);
22785  if (error_status != NO_ERROR)
22786  {
22787  return error_status;
22788  }
22789 
22790  error_status = tz_explain_tz_id (&tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
22791  if (error_status != NO_ERROR)
22792  {
22793  return error_status;
22794  }
22795  db_datetime_decode (&dt_local, &m, &d, &y, &h, &mi, &s, &ms);
22796  is_valid_tz = true;
22797  }
22798  break;
22799 
22800  case DB_TYPE_TIMESTAMPTZ:
22801  {
22802  DB_TIMESTAMPTZ *tsmp_tz;
22803  DB_DATE date;
22804  DB_TIME time;
22805 
22806  tsmp_tz = db_get_timestamptz (date_value);
22807  error_status = db_timestamp_decode_w_tz_id (&tsmp_tz->timestamp, &tsmp_tz->tz_id, &date, &time);
22808  if (error_status != NO_ERROR)
22809  {
22810  return error_status;
22811  }
22812 
22813  db_date_decode (&date, &m, &d, &y);
22814  db_time_decode (&time, &h, &mi, &s);
22815 
22816  error_status = tz_explain_tz_id (&tsmp_tz->tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
22817  if (error_status != NO_ERROR)
22818  {
22819  return error_status;
22820  }
22821  is_valid_tz = true;
22822  }
22823  break;
22824 
22825  case DB_TYPE_TIMESTAMPLTZ:
22826  {
22827  DB_TIMESTAMP *tsmp;
22828  DB_DATE date;
22829  DB_TIME time;
22830  TZ_ID tz_id;
22831 
22832  tsmp = db_get_timestamp (date_value);
22833  error_status = tz_create_session_tzid_for_timestamp (tsmp, &tz_id);
22834 
22835  if (error_status != NO_ERROR)
22836  {
22837  return error_status;
22838  }
22839  error_status = db_timestamp_decode_w_tz_id (tsmp, &tz_id, &date, &time);
22840  if (error_status != NO_ERROR)
22841  {
22842  return error_status;
22843  }
22844 
22845  error_status = tz_explain_tz_id (&tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm);
22846  if (error_status != NO_ERROR)
22847  {
22848  return error_status;
22849  }
22850 
22851  db_date_decode (&date, &m, &d, &y);
22852  db_time_decode (&time, &h, &mi, &s);
22853  is_valid_tz = true;
22854  }
22855  break;
22856 
22857  case DB_TYPE_CHAR:
22858  case DB_TYPE_NCHAR:
22859  case DB_TYPE_VARCHAR:
22860  case DB_TYPE_VARNCHAR:
22861  {
22862  DB_VALUE dt;
22865 
22866  if (tp_value_cast (date_value, &dt, tp_datetime, false) != DOMAIN_COMPATIBLE)
22867  {
22868  error_status = ER_QSTR_INVALID_DATA_TYPE;
22869  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
22870  goto error;
22871  }
22872 
22873  db_datetime_decode (db_get_datetime (&dt), &m, &d, &y, &h, &mi, &s, &ms);
22874 
22875  if (tp_value_cast (date_value, &dt, tp_datetimetz, false) == DOMAIN_COMPATIBLE)
22876  {
22877  DB_DATETIMETZ dt_tz;
22878 
22879  dt_tz = *db_get_datetimetz (&dt);
22880  if (tz_explain_tz_id (&dt_tz.tz_id, tzr, TZR_SIZE + 1, tzd, TZ_DS_STRING_SIZE + 1, &tzh, &tzm) == NO_ERROR)
22881  {
22882  is_valid_tz = true;
22883  }
22884  }
22885  break;
22886  }
22887 
22888  default:
22889  error_status = ER_QSTR_INVALID_DATA_TYPE;
22890  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
22891  goto error;
22892  }
22893 
22894  /* 2. Compute the value for each format specifier */
22895  days[2] += LEAP (y);
22896  dow = db_get_day_of_week (y, m, d);
22897 
22898  /* %a Abbreviated weekday name (Sun..Sat) */
22899  strcpy (format_specifiers['a'], lld->day_short_name[dow]);
22900 
22901  /* %b Abbreviated m name (Jan..Dec) */
22902  if (m > 0)
22903  {
22904  strcpy (format_specifiers['b'], lld->month_short_name[m - 1]);
22905  }
22906 
22907  /* %c Month, numeric (0..12) - actually (1..12) */
22908  sprintf (format_specifiers['c'], "%d", m);
22909 
22910  /* %D Day of the m with English suffix (0th, 1st, 2nd, 3rd,...) */
22911  sprintf (format_specifiers['D'], "%d", d);
22912  /* 11-19 are special */
22913  if (date_lang_id == INTL_LANG_ENGLISH)
22914  {
22915  if (d % 10 == 1 && d / 10 != 1)
22916  {
22917  strcat (format_specifiers['D'], "st");
22918  }
22919  else if (d % 10 == 2 && d / 10 != 1)
22920  {
22921  strcat (format_specifiers['D'], "nd");
22922  }
22923  else if (d % 10 == 3 && d / 10 != 1)
22924  {
22925  strcat (format_specifiers['D'], "rd");
22926  }
22927  else
22928  {
22929  strcat (format_specifiers['D'], "th");
22930  }
22931  }
22932 
22933  /* %d Day of the m, numeric (00..31) */
22934  sprintf (format_specifiers['d'], "%02d", d);
22935 
22936  /* %e Day of the m, numeric (0..31) - actually (1..31) */
22937  sprintf (format_specifiers['e'], "%d", d);
22938 
22939  /* %f Milliseconds (000..999) */
22940  sprintf (format_specifiers['f'], "%03d", ms);
22941 
22942  /* %H Hour (00..23) */
22943  sprintf (format_specifiers['H'], "%02d", h);
22944 
22945  /* %h Hour (01..12) */
22946  sprintf (format_specifiers['h'], "%02d", (h % 12 == 0) ? 12 : (h % 12));
22947 
22948  /* %I Hour (01..12) */
22949  sprintf (format_specifiers['I'], "%02d", (h % 12 == 0) ? 12 : (h % 12));
22950 
22951  /* %i Minutes, numeric (00..59) */
22952  sprintf (format_specifiers['i'], "%02d", mi);
22953 
22954  /* %j Day of y (001..366) */
22955  for (j = d, i = 1; i < m; i++)
22956  {
22957  j += days[i];
22958  }
22959  sprintf (format_specifiers['j'], "%03d", j);
22960 
22961  /* %k Hour (0..23) */
22962  sprintf (format_specifiers['k'], "%d", h);
22963 
22964  /* %l Hour (1..12) */
22965  sprintf (format_specifiers['l'], "%d", (h % 12 == 0) ? 12 : (h % 12));
22966 
22967  /* %M Month name (January..December) */
22968  if (m > 0)
22969  {
22970  strcpy (format_specifiers['M'], lld->month_name[m - 1]);
22971  }
22972 
22973  /* %m Month, numeric (00..12) */
22974  sprintf (format_specifiers['m'], "%02d", m);
22975 
22976  /* %p AM or PM */
22977  strcpy (format_specifiers['p'], (h > 11) ? lld->am_pm[PM_NAME] : lld->am_pm[AM_NAME]);
22978 
22979  /* %r Time, 12-hour (hh:mm:ss followed by AM or PM) */
22980  sprintf (format_specifiers['r'], "%02d:%02d:%02d %s", (h % 12 == 0) ? 12 : (h % 12), mi, s,
22981  (h > 11) ? lld->am_pm[PM_NAME] : lld->am_pm[AM_NAME]);
22982 
22983  /* %S Seconds (00..59) */
22984  sprintf (format_specifiers['S'], "%02d", s);
22985 
22986  /* %s Seconds (00..59) */
22987  sprintf (format_specifiers['s'], "%02d", s);
22988 
22989  /* %T Time, 24-hour (hh:mm:ss) */
22990  sprintf (format_specifiers['T'], "%02d:%02d:%02d", h, mi, s);
22991 
22992  /* %U Week (00..53), where Sunday is the first d of the week */
22993  /* %V Week (01..53), where Sunday is the first d of the week; used with %X */
22994  /* %X Year for the week where Sunday is the first day of the week, numeric, four digits; used with %V */
22995 
22996  dow2 = db_get_day_of_week (y, 1, 1);
22997 
22998  ld_fw = 7 - dow2;
22999 
23000  for (days_counter = d, i = 1; i < m; i++)
23001  {
23002  days_counter += days[i];
23003  }
23004 
23005  if (days_counter <= ld_fw)
23006  {
23007  weeks = dow2 == 0 ? 1 : 0;
23008  }
23009  else
23010  {
23011  days_counter -= (dow2 == 0) ? 0 : ld_fw;
23012  weeks = days_counter / 7 + (days_counter % 7 ? 1 : 0);
23013  }
23014 
23015  tu = tv = weeks;
23016  tx = y;
23017  if (tv == 0)
23018  {
23019  dow2 = db_get_day_of_week (y - 1, 1, 1);
23020  days_counter = 365 + LEAP (y - 1) - (dow2 == 0 ? 0 : 7 - dow2);
23021  tv = days_counter / 7 + (days_counter % 7 ? 1 : 0);
23022  tx = y - 1;
23023  }
23024 
23025  sprintf (format_specifiers['U'], "%02d", tu);
23026  sprintf (format_specifiers['V'], "%02d", tv);
23027  sprintf (format_specifiers['X'], "%04d", tx);
23028 
23029  /* %u Week (00..53), where Monday is the first d of the week */
23030  /* %v Week (01..53), where Monday is the first d of the week; used with %x */
23031  /* %x Year for the week, where Monday is the first day of the week, numeric, four digits; used with %v */
23032 
23033  dow2 = db_get_day_of_week (y, 1, 1);
23034  weeks = dow2 >= 1 && dow2 <= 4 ? 1 : 0;
23035 
23036  ld_fw = dow2 == 0 ? 1 : 7 - dow2 + 1;
23037 
23038  for (days_counter = d, i = 1; i < m; i++)
23039  {
23040  days_counter += days[i];
23041  }
23042 
23043  if (days_counter > ld_fw)
23044  {
23045  days_counter -= ld_fw;
23046  weeks += days_counter / 7 + (days_counter % 7 ? 1 : 0);
23047  }
23048 
23049  tu = weeks;
23050  tv = weeks;
23051  tx = y;
23052  if (tv == 0)
23053  {
23054  dow2 = db_get_day_of_week (y - 1, 1, 1);
23055  weeks = dow2 >= 1 && dow2 <= 4 ? 1 : 0;
23056  ld_fw = dow2 == 0 ? 1 : 7 - dow2 + 1;
23057  days_counter = 365 + LEAP (y - 1) - ld_fw;
23058  tv = weeks + days_counter / 7 + (days_counter % 7 ? 1 : 0);
23059  tx = y - 1;
23060  }
23061  else if (tv == 53)
23062  {
23063  dow2 = db_get_day_of_week (y + 1, 1, 1);
23064  if (dow2 >= 1 && dow2 <= 4)
23065  {
23066  tv = 1;
23067  tx = y + 1;
23068  }
23069  }
23070 
23071  sprintf (format_specifiers['u'], "%02d", tu);
23072  sprintf (format_specifiers['v'], "%02d", tv);
23073  sprintf (format_specifiers['x'], "%04d", tx);
23074 
23075  /* %W Weekday name (Sunday..Saturday) */
23076  strcpy (format_specifiers['W'], lld->day_name[dow]);
23077 
23078  /* %w Day of the week (0=Sunday..6=Saturday) */
23079  sprintf (format_specifiers['w'], "%d", dow);
23080 
23081  /* %Y Year, numeric, four digits */
23082  sprintf (format_specifiers['Y'], "%04d", y);
23083 
23084  /* %y Year, numeric (two digits) */
23085  sprintf (format_specifiers['y'], "%02d", y % 100);
23086 
23087  /* 3. Generate the output according to the format and the values */
23088  format_type = DB_VALUE_DOMAIN_TYPE (format);
23089  switch (format_type)
23090  {
23091  case DB_TYPE_STRING:
23092  case DB_TYPE_VARNCHAR:
23093  case DB_TYPE_CHAR:
23094  case DB_TYPE_NCHAR:
23095  format_s = db_get_string (format);
23096  format_s_len = db_get_string_size (format);
23097  break;
23098 
23099  default:
23100  /* we should not get a nonstring format */
23101  assert (false);
23102  return ER_FAILED;
23103  }
23104 
23105  len = 1024;
23106  res = (char *) db_private_alloc (NULL, len);
23107  if (res == NULL)
23108  {
23109  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
23110  goto error;
23111  }
23112  memset (res, 0, len);
23113 
23114  ch = *format_s;
23115  strend = format_s + format_s_len;
23116  while (format_s < strend)
23117  {
23118  format_s++;
23119  och = ch;
23120  ch = *format_s;
23121 
23122  if (och == '%' /* && (res[strlen(res) - 1] != '%') */ )
23123  {
23124  if (ch == '%')
23125  {
23126  STRCHCAT (res, '%');
23127 
23128  /* jump a character */
23129  format_s++;
23130  och = ch;
23131  ch = *format_s;
23132 
23133  continue;
23134  }
23135  if (ch == 'T' && format_s + 2 < strend && *(format_s + 1) == 'Z'
23136  && (*(format_s + 2) == 'R' || *(format_s + 2) == 'D' || *(format_s + 2) == 'H' || *(format_s + 2) == 'M'))
23137  {
23138  if (is_valid_tz == false)
23139  {
23140  if (er_errid () != ER_TZ_LOAD_ERROR)
23141  {
23142  error_status = ER_QSTR_INVALID_DATA_TYPE;
23143  }
23144  er_clear ();
23145  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
23146  goto error;
23147  }
23148  switch (*(format_s + 2))
23149  {
23150  case 'R':
23151  strcat (res, tzr);
23152  break;
23153  case 'D':
23154  strcat (res, tzd);
23155  break;
23156  case 'H':
23157  has_tzh = true;
23158  if ((tzh >= 0) && (tzm >= 0))
23159  {
23160  sprintf (hours_or_minutes, "%c%02d", '+', tzh);
23161  }
23162  else
23163  {
23164  sprintf (hours_or_minutes, "%c%02d", '-', -tzh);
23165  }
23166  strcat (res, hours_or_minutes);
23167  break;
23168  case 'M':
23169  if (tzm >= 0)
23170  {
23171  sprintf (hours_or_minutes, "%02d", tzm);
23172  }
23173  else
23174  {
23175  sprintf (hours_or_minutes, "%02d", -tzm);
23176  }
23177  strcat (res, hours_or_minutes);
23178  break;
23179  }
23180  format_s += 2;
23181  }
23182  /* parse the character */
23183  else if (strlen (format_specifiers[(unsigned char) ch]) == 0)
23184  {
23185  /* append the character itself */
23186  STRCHCAT (res, ch);
23187  }
23188  else
23189  {
23190  strcat (res, format_specifiers[(unsigned char) ch]);
23191  }
23192 
23193  /* jump a character */
23194  format_s++;
23195  och = ch;
23196  ch = *format_s;
23197  }
23198  else
23199  {
23200  STRCHCAT (res, och);
23201  }
23202 
23203  /* chance of overflow ? */
23204  /* assume we can't add at a time mode than 16 chars */
23205  if (strlen (res) + 16 > len)
23206  {
23207  /* realloc - copy temporary in res2 */
23208  res2 = (char *) db_private_alloc (NULL, len);
23209  if (res2 == NULL)
23210  {
23211  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
23212  goto error;
23213  }
23214  memset (res2, 0, len);
23215  strcpy (res2, res);
23217 
23218  len += 1024;
23219  res = (char *) db_private_alloc (NULL, len);
23220  if (res == NULL)
23221  {
23222  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
23223  goto error;
23224  }
23225  memset (res, 0, len);
23226  strcpy (res, res2);
23228  }
23229  }
23230  /* finished string */
23231 
23232  /* 4. */
23233 
23234  db_make_string (result, res);
23235 
23236  db_string_put_cs_and_collation (result, codeset, res_collation);
23237 
23238  result->need_clear = true;
23239 
23240  return error_status;
23241 
23242 error:
23243  if (res != NULL)
23244  {
23246  }
23247 
23248  if (res2 != NULL)
23249  {
23251  }
23252 
23253  return error_status;
23254 }
23255 
23256 /*
23257  * parse_digits ()
23258  *
23259  * Arguments:
23260  * s: source string to parse
23261  * nr: output number
23262  * cnt: length at which we trim the number (-1 if none)
23263  *
23264  * Returns: int - actual number of characters read
23265  *
23266  * Errors:
23267  *
23268  * Note:
23269  * reads cnt digits until non-digit char reached
23270  */
23271 int
23272 parse_digits (char *s, int *nr, int cnt)
23273 {
23274  int count = 0, len;
23275  char *ch;
23276  /* res[64] is safe because res has a max length of cnt, which is max 4 */
23277  char res[64];
23278  const int res_count = sizeof (res) / sizeof (char);
23279 
23280  ch = s;
23281  *nr = 0;
23282 
23283  memset (res, 0, sizeof (res));
23284 
23285  while (WHITESPACE (*ch))
23286  {
23287  ch++;
23288  count++;
23289  }
23290 
23291  /* do not support negative numbers because... they are not supported :) */
23292  while (*ch != 0 && (*ch >= '0' && *ch <= '9'))
23293  {
23294  STRCHCAT (res, *ch);
23295 
23296  ch++;
23297  count++;
23298 
23299  /* trim at cnt characters */
23300  len = strlen (res);
23301  if (len == cnt || len == res_count - 1)
23302  {
23303  break;
23304  }
23305  }
23306 
23307  *nr = atol (res);
23308 
23309  return count;
23310 }
23311 
23312 /*
23313  * db_str_to_date ()
23314  *
23315  * Arguments:
23316  * str: string from which we get the data
23317  * format: format specifiers to match the str
23318  * date_lang: id of language to use
23319  * domain: expected domain of result, may be NULL; If NULL the domain
23320  * output domain is determined according to format
23321  *
23322  * Returns: int
23323  *
23324  * Errors:
23325  *
23326  * Note:
23327  * inverse function for date_format - compose a date/time from some format
23328  * specifiers and some informations.
23329  */
23330 int
23331 db_str_to_date (const DB_VALUE * str, const DB_VALUE * format, const DB_VALUE * date_lang, DB_VALUE * result,
23332  TP_DOMAIN * domain)
23333 {
23334  const char *format2_s = NULL;
23335  char *sstr = NULL, *format_s = NULL;
23336  int i, j, k, error_status = NO_ERROR;
23337  int type, len1, len2, h24 = 0, _v, _x;
23338  DB_TYPE res_type;
23339  int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
23340  int y, m, d, h, mi, s, ms, am /* 0 = AM, 1 = PM */ ;
23341  int u, U, v, V, dow, doy, w;
23342  char stack_buf_str[64];
23343  char *initial_buf_str = NULL;
23344  bool do_free_buf_str = false;
23345  INTL_CODESET codeset;
23346  INTL_LANG date_lang_id;
23347  bool dummy;
23348  int tzm = 0, tzh = 0;
23349  bool set_tzh = false, set_tzm = false;
23350  int start_tzr = -1, len_tzr = -1, start_tzd = -1, len_tzd = -1;
23351  int zone_id = -1;
23352  bool is_negative_tzd = false;
23353 
23354  if (str == NULL || format == NULL || date_lang == NULL)
23355  {
23356  error_status = ER_OBJ_INVALID_ARGUMENTS;
23357  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
23358  goto error;
23359  }
23360 
23361  db_make_null (result);
23362 
23363  if (DB_IS_NULL (str) || DB_IS_NULL (format))
23364  {
23365  return NO_ERROR;
23366  }
23367 
23368  codeset = db_get_string_codeset (str);
23369  assert (DB_VALUE_TYPE (date_lang) == DB_TYPE_INTEGER);
23370  date_lang_id = lang_get_lang_id_from_flag (db_get_int (date_lang), &dummy, &dummy);
23371  if (lang_get_specific_locale (date_lang_id, codeset) == NULL)
23372  {
23373  error_status = ER_LANG_CODESET_NOT_AVAILABLE;
23374  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 2, lang_get_lang_name_from_id (date_lang_id),
23375  lang_charset_name (codeset));
23376  goto error;
23377  }
23378 
23379  y = m = d = V = v = U = u = -1;
23380  h = mi = s = ms = 0;
23381  dow = doy = am = -1;
23382  _v = _x = 0;
23383 
23384  error_status =
23385  db_check_or_create_null_term_string (str, stack_buf_str, sizeof (stack_buf_str), true, true, &initial_buf_str,
23386  &do_free_buf_str);
23387  if (error_status != NO_ERROR)
23388  {
23389  goto error;
23390  }
23391 
23392  sstr = initial_buf_str;
23393 
23394  format2_s = db_get_string (format);
23395  len2 = db_get_string_size (format);
23396  len2 = (len2 < 0) ? strlen (format2_s) : len2;
23397 
23398  format_s = (char *) db_private_alloc (NULL, len2 + 1);
23399  if (!format_s)
23400  {
23401  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
23402  goto error;
23403  }
23404  memset (format_s, 0, sizeof (char) * (len2 + 1));
23405 
23406  /* delete all whitespace from format */
23407  for (i = 0; i < len2; i++)
23408  {
23409  if (!WHITESPACE (format2_s[i]))
23410  {
23411  STRCHCAT (format_s, format2_s[i]);
23412  }
23413  /* '%' without format specifier */
23414  else if (WHITESPACE (format2_s[i]) && i > 0 && format2_s[i - 1] == '%')
23415  {
23417  {
23418  error_status = ER_OBJ_INVALID_ARGUMENTS;
23419  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
23420  }
23421  goto error;
23422  }
23423  }
23424 
23425  if (domain == NULL)
23426  {
23427  type = db_check_time_date_format (format_s);
23428  if (type == TIME_SPECIFIER)
23429  {
23430  res_type = DB_TYPE_TIME;
23431  }
23432  else if (type == DATE_SPECIFIER)
23433  {
23434  res_type = DB_TYPE_DATE;
23435  }
23436  else if (type == DATETIME_SPECIFIER)
23437  {
23438  res_type = DB_TYPE_DATETIME;
23439  }
23440  else if (type == DATETIMETZ_SPECIFIER)
23441  {
23442  res_type = DB_TYPE_DATETIMETZ;
23443  }
23444  else
23445  {
23446  error_status = ER_OBJ_INVALID_ARGUMENTS;
23447  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
23448  goto error;
23449  }
23450  }
23451  else
23452  {
23453  res_type = TP_DOMAIN_TYPE (domain);
23454  if (res_type != DB_TYPE_TIME && res_type != DB_TYPE_DATE && res_type != DB_TYPE_DATETIME
23455  && res_type != DB_TYPE_DATETIMETZ)
23456  {
23457  error_status = ER_OBJ_INVALID_ARGUMENTS;
23458  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
23459  goto error;
23460  }
23461  }
23462 
23463  /*
23464  * 1. Get information according to format specifiers
23465  * iterate simultaneously through each string and sscanf when
23466  * it is a format specifier.
23467  * If a format specifier has more than one occurrence, get the last value.
23468  */
23469  do
23470  {
23471  len1 = strlen (sstr);
23472  len2 = strlen (format_s);
23473 
23474  i = j = k = 0;
23475 
23476  while (i < len1 && j < len2)
23477  {
23478  while (WHITESPACE (sstr[i]))
23479  {
23480  i++;
23481  }
23482 
23483  while (WHITESPACE (format_s[j]))
23484  {
23485  j++;
23486  }
23487 
23488  if (j > 0 && format_s[j - 1] == '%')
23489  {
23490  int token_size;
23491  int am_pm_id;
23492 
23493  /* do not accept a double % */
23494  if (j > 1 && format_s[j - 2] == '%')
23495  {
23497  {
23498  error_status = ER_OBJ_INVALID_ARGUMENTS;
23499  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
23500  }
23501  goto error;
23502  }
23503 
23504  /* we have a format specifier */
23505  switch (format_s[j])
23506  {
23507  case 'a':
23508  /* %a Abbreviated weekday name (Sun..Sat) */
23509  error_status =
23510  get_string_date_token_id (SDT_DAY_SHORT, date_lang_id, sstr + i, codeset, &dow, &token_size);
23511  if (error_status != NO_ERROR)
23512  {
23513  goto conversion_error;
23514  }
23515 
23516  i += token_size;
23517 
23518  if (dow == 0) /* not found - error */
23519  {
23520  goto conversion_error;
23521  }
23522 
23523  dow = dow - 1;
23524  break;
23525 
23526  case 'b':
23527  /* %b Abbreviated month name (Jan..Dec) */
23528  error_status =
23529  get_string_date_token_id (SDT_MONTH_SHORT, date_lang_id, sstr + i, codeset, &m, &token_size);
23530  if (error_status != NO_ERROR)
23531  {
23532  goto conversion_error;
23533  }
23534 
23535  i += token_size;
23536 
23537  if (m == 0) /* not found - error */
23538  {
23539  goto conversion_error;
23540  }
23541  break;
23542 
23543  case 'c':
23544  /* %c Month, numeric (0..12) */
23545  k = parse_digits (sstr + i, &m, 2);
23546  if (k <= 0)
23547  {
23548  goto conversion_error;
23549  }
23550  i += k;
23551  break;
23552 
23553  case 'D':
23554  /* %D Day of the month with English suffix (0th, 1st, 2nd, 3rd, ...) */
23555  k = parse_digits (sstr + i, &d, 2);
23556  if (k <= 0)
23557  {
23558  goto conversion_error;
23559  }
23560  i += k;
23561  /* need 2 necessary characters or whitespace (!) after */
23562  i += 2;
23563  break;
23564 
23565  case 'd':
23566  /* %d Day of the month, numeric (00..31) */
23567  k = parse_digits (sstr + i, &d, 2);
23568  if (k <= 0)
23569  {
23570  goto conversion_error;
23571  }
23572  i += k;
23573  break;
23574 
23575  case 'e':
23576  /* %e Day of the month, numeric (0..31) */
23577  k = parse_digits (sstr + i, &d, 2);
23578  if (k <= 0)
23579  {
23580  goto conversion_error;
23581  }
23582  i += k;
23583  break;
23584 
23585  case 'f':
23586  /* %f Milliseconds (000..999) */
23587  k = parse_digits (sstr + i, &ms, 3);
23588  if (k <= 0)
23589  {
23590  goto conversion_error;
23591  }
23592  i += k;
23593  break;
23594 
23595  case 'H':
23596  /* %H Hour (00..23) */
23597  k = parse_digits (sstr + i, &h, 2);
23598  if (k <= 0)
23599  {
23600  goto conversion_error;
23601  }
23602  i += k;
23603  h24 = 1;
23604  break;
23605 
23606  case 'h':
23607  /* %h Hour (01..12) */
23608  k = parse_digits (sstr + i, &h, 2);
23609  if (k <= 0)
23610  {
23611  goto conversion_error;
23612  }
23613  i += k;
23614  break;
23615 
23616  case 'I':
23617  /* %I Hour (01..12) */
23618  k = parse_digits (sstr + i, &h, 2);
23619  if (k <= 0)
23620  {
23621  goto conversion_error;
23622  }
23623  i += k;
23624  break;
23625 
23626  case 'i':
23627  /* %i Minutes, numeric (00..59) */
23628  k = parse_digits (sstr + i, &mi, 2);
23629  if (k <= 0)
23630  {
23631  goto conversion_error;
23632  }
23633  i += k;
23634  break;
23635 
23636  case 'j':
23637  /* %j Day of year (001..366) */
23638  k = parse_digits (sstr + i, &doy, 3);
23639  if (k <= 0)
23640  {
23641  goto conversion_error;
23642  }
23643  i += k;
23644  break;
23645 
23646  case 'k':
23647  /* %k Hour (0..23) */
23648  k = parse_digits (sstr + i, &h, 2);
23649  if (k <= 0)
23650  {
23651  goto conversion_error;
23652  }
23653  i += k;
23654  h24 = 1;
23655  break;
23656 
23657  case 'l':
23658  /* %l Hour (1..12) */
23659  k = parse_digits (sstr + i, &h, 2);
23660  if (k <= 0)
23661  {
23662  goto conversion_error;
23663  }
23664  i += k;
23665  break;
23666 
23667  case 'M':
23668  /* %M Month name (January..December) */
23669  error_status = get_string_date_token_id (SDT_MONTH, date_lang_id, sstr + i, codeset, &m, &token_size);
23670  if (error_status != NO_ERROR)
23671  {
23672  goto conversion_error;
23673  }
23674 
23675  i += token_size;
23676 
23677  if (m == 0) /* not found - error */
23678  {
23679  goto conversion_error;
23680  }
23681  break;
23682 
23683  case 'm':
23684  /* %m Month, numeric (00..12) */
23685  k = parse_digits (sstr + i, &m, 2);
23686  if (k <= 0)
23687  {
23688  goto conversion_error;
23689  }
23690  i += k;
23691  break;
23692 
23693  case 'p':
23694  /* %p AM or PM */
23695  error_status =
23696  get_string_date_token_id (SDT_AM_PM, date_lang_id, sstr + i, codeset, &am_pm_id, &token_size);
23697  if (error_status != NO_ERROR)
23698  {
23699  goto conversion_error;
23700  }
23701 
23702  i += token_size;
23703 
23704  if (am_pm_id > 0)
23705  {
23706  if (am_pm_id % 2)
23707  {
23708  am = 0;
23709  }
23710  else
23711  {
23712  am = 1;
23713  }
23714  }
23715  else
23716  {
23717  goto conversion_error;
23718  }
23719 
23720  break;
23721 
23722  case 'r':
23723  /* %r Time, 12-hour (hh:mm:ss followed by AM or PM) */
23724 
23725  k = parse_digits (sstr + i, &h, 2);
23726  if (k <= 0)
23727  {
23728  goto conversion_error;
23729  }
23730  i += k;
23731 
23732  while (WHITESPACE (sstr[i]))
23733  {
23734  i++;
23735  }
23736 
23737  if (sstr[i] != ':')
23738  {
23739  goto conversion_error;
23740  }
23741  i++;
23742 
23743  k = parse_digits (sstr + i, &mi, 2);
23744  if (k <= 0)
23745  {
23746  goto conversion_error;
23747  }
23748  i += k;
23749 
23750  while (WHITESPACE (sstr[i]))
23751  {
23752  i++;
23753  }
23754 
23755  if (sstr[i] != ':')
23756  {
23757  goto conversion_error;
23758  }
23759  i++;
23760 
23761  k = parse_digits (sstr + i, &s, 2);
23762  if (k <= 0)
23763  {
23764  goto conversion_error;
23765  }
23766  i += k;
23767 
23768  error_status =
23769  get_string_date_token_id (SDT_AM_PM, date_lang_id, sstr + i, codeset, &am_pm_id, &token_size);
23770  if (error_status != NO_ERROR)
23771  {
23772  goto conversion_error;
23773  }
23774 
23775  i += token_size;
23776 
23777  if (am_pm_id > 0)
23778  {
23779  if (am_pm_id % 2)
23780  {
23781  am = 0;
23782  }
23783  else
23784  {
23785  am = 1;
23786  }
23787  }
23788  else
23789  {
23790  goto conversion_error;
23791  }
23792 
23793  break;
23794 
23795  case 'S':
23796  /* %S Seconds (00..59) */
23797  k = parse_digits (sstr + i, &s, 2);
23798  if (k <= 0)
23799  {
23800  goto conversion_error;
23801  }
23802  i += k;
23803  break;
23804 
23805  case 's':
23806  /* %s Seconds (00..59) */
23807  k = parse_digits (sstr + i, &s, 2);
23808  if (k <= 0)
23809  {
23810  goto conversion_error;
23811  }
23812  i += k;
23813  break;
23814 
23815  case 'T':
23816  /* %T Time, 24-hour (hh:mm:ss) */
23817  if ((j + 1 < len2 && format_s[j + 1] != 'Z') || (j + 1 == len2))
23818  {
23819  k = parse_digits (sstr + i, &h, 2);
23820  if (k <= 0)
23821  {
23822  goto conversion_error;
23823  }
23824  i += k;
23825 
23826  while (WHITESPACE (sstr[i]))
23827  {
23828  i++;
23829  }
23830 
23831  if (sstr[i] != ':')
23832  {
23833  goto conversion_error;
23834  }
23835  i++;
23836 
23837  k = parse_digits (sstr + i, &mi, 2);
23838  if (k <= 0)
23839  {
23840  goto conversion_error;
23841  }
23842 
23843  i += k;
23844  while (WHITESPACE (sstr[i]))
23845  {
23846  i++;
23847  }
23848 
23849  if (sstr[i] != ':')
23850  {
23851  goto conversion_error;
23852  }
23853  i++;
23854 
23855  k = parse_digits (sstr + i, &s, 2);
23856  if (k <= 0)
23857  {
23858  goto conversion_error;
23859  }
23860  i += k;
23861  h24 = 1;
23862  }
23863  else if (j + 2 < len2)
23864  {
23865  switch (format_s[j + 2])
23866  {
23867  case 'R':
23868  {
23869  start_tzr = i;
23870  zone_id = tz_get_best_match_zone (sstr + i, &len_tzr);
23871  if (zone_id < 0)
23872  {
23873  error_status = ER_OBJ_INVALID_ARGUMENTS;
23874  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
23875  goto error;
23876  }
23877  i += len_tzr;
23878  j += 2;
23879  }
23880  break;
23881 
23882  case 'D':
23883  {
23884  int frmt_len_spec = 0;
23885  int tzd_exp_len = TZD_DEFAULT_EXPECTED_LEN;
23886  int j_tzd = j + 3;
23887 
23888  /* format TZD[number] */
23889  if (j_tzd + frmt_len_spec < len2)
23890  {
23891  while (char_isdigit (format_s[j_tzd + frmt_len_spec]))
23892  {
23893  frmt_len_spec++;
23894  }
23895 
23896  if (frmt_len_spec > 0)
23897  {
23898  k = parse_digits (&format_s[j_tzd], &tzd_exp_len, frmt_len_spec);
23899  if (k <= 0)
23900  {
23901  goto conversion_error;
23902  }
23903  }
23904  }
23905 
23906  if (tzd_exp_len <= 1 || tzd_exp_len > TZD_MAX_EXPECTED_LEN)
23907  {
23908  goto conversion_error;
23909  }
23910 
23911  start_tzd = i;
23912  len_tzd = parse_tzd (sstr + i, tzd_exp_len);
23913  if (len_tzd < 0)
23914  {
23915  error_status = ER_OBJ_INVALID_ARGUMENTS;
23916  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
23917  goto error;
23918  }
23919  i += len_tzd;
23920  /* skip 'ZD[number]', leading 'T' is skipped by loop common code */
23921  j += 2 + frmt_len_spec;
23922  }
23923  break;
23924 
23925  case 'H':
23926  case 'M':
23927  {
23928  int *p = NULL;
23929 
23930  if (format_s[j + 2] == 'H')
23931  {
23932  p = &tzh;
23933  set_tzh = true;
23934  }
23935  else
23936  {
23937  p = &tzm;
23938  set_tzm = true;
23939  }
23940 
23941  /* Get the timezone hour offset */
23942  if (sstr[i] == '+' || sstr[i] == '-')
23943  {
23944  if (format_s[j + 2] == 'M')
23945  {
23946  error_status = ER_OBJ_INVALID_ARGUMENTS;
23947  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
23948  goto error;
23949  }
23950  if (sstr[i] == '-')
23951  {
23952  is_negative_tzd = true;
23953  }
23954  else
23955  {
23956  is_negative_tzd = false;
23957  }
23958  i++;
23959  }
23960 
23961  k = parse_digits (sstr + i, p, 2);
23962  if (k <= 0)
23963  {
23964  goto conversion_error;
23965  }
23966  i += k;
23967  j += 2;
23968  }
23969  break;
23970 
23971  default:
23972  error_status = ER_OBJ_INVALID_ARGUMENTS;
23973  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
23974  goto error;
23975  }
23976  }
23977 
23978  break;
23979 
23980  case 'U':
23981  /* %U Week (00..53), where Sunday is the first day of the week */
23982  k = parse_digits (sstr + i, &U, 2);
23983  if (k <= 0)
23984  {
23985  goto conversion_error;
23986  }
23987  i += k;
23988  break;
23989 
23990  case 'u':
23991  /* %u Week (00..53), where Monday is the first day of the week */
23992  k = parse_digits (sstr + i, &u, 2);
23993  if (k <= 0)
23994  {
23995  goto conversion_error;
23996  }
23997  i += k;
23998  break;
23999 
24000  case 'V':
24001  /* %V Week (01..53), where Sunday is the first day of the week; used with %X */
24002  k = parse_digits (sstr + i, &V, 2);
24003  if (k <= 0)
24004  {
24005  goto conversion_error;
24006  }
24007  i += k;
24008  _v = 1;
24009  break;
24010 
24011  case 'v':
24012  /* %v Week (01..53), where Monday is the first day of the week; used with %x */
24013  k = parse_digits (sstr + i, &v, 2);
24014  if (k <= 0)
24015  {
24016  goto conversion_error;
24017  }
24018  i += k;
24019  _v = 2;
24020  break;
24021 
24022  case 'W':
24023  /* %W Weekday name (Sunday..Saturday) */
24024  error_status = get_string_date_token_id (SDT_DAY, date_lang_id, sstr + i, codeset, &dow, &token_size);
24025  if (error_status != NO_ERROR)
24026  {
24027  goto conversion_error;
24028  }
24029 
24030  i += token_size;
24031 
24032  if (dow == 0) /* not found - error */
24033  {
24034  goto conversion_error;
24035  }
24036  dow = dow - 1;
24037  break;
24038 
24039  case 'w':
24040  /* %w Day of the week (0=Sunday..6=Saturday) */
24041  k = parse_digits (sstr + i, &dow, 1);
24042  if (k <= 0)
24043  {
24044  goto conversion_error;
24045  }
24046  i += k;
24047  break;
24048 
24049  case 'X':
24050  /* %X Year for the week where Sunday is the first day of the week, numeric, four digits; used with %V
24051  */
24052  k = parse_digits (sstr + i, &y, 4);
24053  if (k <= 0)
24054  {
24055  goto conversion_error;
24056  }
24057  i += k;
24058  _x = 1;
24059  break;
24060 
24061  case 'x':
24062  /* %x Year for the week, where Monday is the first day of the week, numeric, four digits; used with
24063  * %v */
24064  k = parse_digits (sstr + i, &y, 4);
24065  if (k <= 0)
24066  {
24067  goto conversion_error;
24068  }
24069  i += k;
24070  _x = 2;
24071  break;
24072 
24073  case 'Y':
24074  /* %Y Year, numeric, four digits */
24075  k = parse_digits (sstr + i, &y, 4);
24076  if (k <= 0)
24077  {
24078  goto conversion_error;
24079  }
24080  i += k;
24081  break;
24082 
24083  case 'y':
24084  /* %y Year, numeric (two digits) */
24085  k = parse_digits (sstr + i, &y, 2);
24086  if (k <= 0)
24087  {
24088  goto conversion_error;
24089  }
24090  i += k;
24091 
24092  /* TODO: 70 convention always available? */
24093  if (y < 70)
24094  {
24095  y = 2000 + y;
24096  }
24097  else
24098  {
24099  y = 1900 + y;
24100  }
24101 
24102  break;
24103 
24104  default:
24105  goto conversion_error;
24106  break;
24107  }
24108  }
24109  else if (sstr[i] != format_s[j] && format_s[j] != '%')
24110  {
24112  {
24113  error_status = ER_OBJ_INVALID_ARGUMENTS;
24114  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
24115  }
24116  goto error;
24117  }
24118  else if (format_s[j] != '%')
24119  {
24120  i++;
24121  }
24122 
24123  /* when is a format specifier do not advance in sstr because we need the entire value */
24124  j++;
24125  }
24126  }
24127  while (0);
24128 
24129  /* 2. Validations */
24130  if (len_tzd > 0 || len_tzr > 0)
24131  {
24132  if (set_tzh == true || set_tzm == true)
24133  {
24134  error_status = ER_OBJ_INVALID_ARGUMENTS;
24135  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
24136  goto error;
24137  }
24138  }
24139  if (is_negative_tzd)
24140  {
24141  tzh = -tzh;
24142  tzm = -tzm;
24143  }
24144 
24145  if (am != -1) /* 24h time format and am/pm */
24146  {
24147  if (h24 == 1 || h == 0)
24148  {
24149  goto conversion_error;
24150  }
24151 
24152  if (h == 12)
24153  {
24154  h = 0;
24155  }
24156  }
24157  if (h24 == 0 && h > 12)
24158  {
24159  goto conversion_error;
24160  }
24161 
24162  if (_x != _v && _x != -1) /* accept %v only if %x and %V only if %X */
24163  {
24164  goto conversion_error;
24165  }
24166 
24167  days[2] += LEAP (y);
24168 
24169  /*
24170  * validations are done here because they are done just on the last memorized
24171  * values (ie: if you supply a month 99 then a month 12 the 99 isn't validated
24172  * because it's overwritten by 12 which is correct).
24173  */
24174 
24175  /*
24176  * check only upper bounds, lower bounds will be checked later and
24177  * will return error
24178  */
24179  if (res_type == DB_TYPE_DATE || res_type == DB_TYPE_DATETIME || res_type == DB_TYPE_DATETIMETZ)
24180  {
24181  /* replace invalid initial year with default year */
24182  y = (y == -1) ? 1 : y;
24183  /* year is validated because it's vital for m & d */
24184  if (y > 9999)
24185  {
24186  goto conversion_error;
24187  }
24188 
24189  if (m > 12)
24190  {
24191  goto conversion_error;
24192  }
24193 
24194  /* because we do not support invalid dates ... */
24195  if (m != -1 && d > days[m])
24196  {
24197  goto conversion_error;
24198  }
24199 
24200  if (u > 53)
24201  {
24202  goto conversion_error;
24203  }
24204 
24205  if (v > 53)
24206  {
24207  goto conversion_error;
24208  }
24209 
24210  if (v == 0 || u > 53)
24211  {
24212  goto conversion_error;
24213  }
24214 
24215  if (V == 0 || u > 53)
24216  {
24217  goto conversion_error;
24218  }
24219 
24220  if (doy == 0 || doy > 365 + LEAP (y))
24221  {
24222  goto conversion_error;
24223  }
24224 
24225  if (dow > 6)
24226  {
24227  goto conversion_error;
24228  }
24229  }
24230 
24231  if (res_type == DB_TYPE_TIME || res_type == DB_TYPE_DATETIME || res_type == DB_TYPE_DATETIMETZ)
24232  {
24233  if ((am != -1 && h > 12) || (am == -1 && h > 23))
24234  {
24235  goto conversion_error;
24236  }
24237  if (am == 1 && h != -1)
24238  {
24239  h += 12;
24240  /* reset AM flag */
24241  am = -1;
24242  }
24243 
24244  if (mi > 59)
24245  {
24246  goto conversion_error;
24247  }
24248 
24249  if (s > 59)
24250  {
24251  goto conversion_error;
24252  }
24253  /* mili does not need checking, it has all values from 0 to 999 */
24254  }
24255 
24256 
24257  /* 3. Try to compute a date according to the information from the format specifiers */
24258 
24259  if (res_type == DB_TYPE_TIME)
24260  {
24261  /* --- no job to do --- */
24262  goto write_results;
24263  }
24264 
24265  /* the year is fixed, compute the day and month from dow, doy, etc */
24266  /*
24267  * the day and month can be supplied specifically which supress all other
24268  * informations or can be computed from dow and week or from doy
24269  */
24270 
24271  /* 3.1 - we have a valid day and month */
24272  if (m >= 1 && m <= 12 && d >= 1 && d <= days[m])
24273  {
24274  /* --- no job to do --- */
24275  goto write_results;
24276  }
24277 
24278  w = MAX (v, MAX (V, MAX (u, U)));
24279  /* 3.2 - we have the day of week and a week */
24280  if (dow != -1 && w != -1)
24281  {
24282  int dow2 = db_get_day_of_week (y, 1, 1);
24283  int ld_fw, save_dow, dowdiff;
24284 
24285  if (U == w || V == w)
24286  {
24287  ld_fw = 7 - dow2;
24288 
24289  if (w == 0)
24290  {
24291  dowdiff = dow - dow2;
24292  d = dow2 == 0 ? 32 - (7 - dow) : dowdiff < 0 ? 32 + dowdiff : 1 + dowdiff;
24293  m = dow2 == 0 || dowdiff < 0 ? 12 : 1;
24294  y = dow2 == 0 || dowdiff < 0 ? y - 1 : y;
24295  }
24296  else
24297  {
24298  d = dow2 == 0 ? 1 : ld_fw + 1;
24299  m = 1;
24300  if (db_add_weeks_and_days_to_date (&d, &m, &y, w - 1, dow) == ER_FAILED)
24301  {
24302  goto conversion_error;
24303  }
24304  }
24305  }
24306  else if (u == w || v == w)
24307  {
24308  ld_fw = dow2 == 0 ? 1 : 7 - dow2 + 1;
24309  if (w == 0 || w == 1)
24310  {
24311  save_dow = dow;
24312  dow = dow == 0 ? 7 : dow;
24313  dow2 = dow2 == 0 ? 7 : dow2;
24314  dowdiff = dow - dow2;
24315 
24316  if (dow2 >= 1 && dow2 <= 4) /* start with week 1 */
24317  {
24318  d = w == 0 ? 32 + dowdiff - 7 : dowdiff < 0 ? 32 + dowdiff : 1 + dowdiff;
24319  m = w == 0 || dowdiff < 0 ? 12 : 1;
24320  y = w == 0 || dowdiff < 0 ? y - 1 : y;
24321  }
24322  else
24323  {
24324  d = dowdiff < 0 ? (w == 0 ? 32 + dowdiff : ld_fw + dow) : (w == 0 ? 1 + dowdiff : 1 + dowdiff + 7);
24325  m = dowdiff < 0 && w == 0 ? 12 : 1;
24326  y = dowdiff < 0 && w == 0 ? y - 1 : y;
24327  }
24328  dow = save_dow;
24329  }
24330  else
24331  {
24332  d = ld_fw + 1;
24333  m = 1;
24334 
24335  if (db_add_weeks_and_days_to_date (&d, &m, &y, dow2 >= 1 && dow2 <= 4 ? w - 2 : w - 1,
24336  dow == 0 ? 6 : dow - 1) == ER_FAILED)
24337  {
24338  goto conversion_error;
24339  }
24340  }
24341  }
24342  else
24343  {
24344  goto conversion_error; /* should not happen */
24345  }
24346  }
24347  /* 3.3 - we have the day of year */
24348  else if (doy != -1)
24349  {
24350  for (m = 1; doy > days[m] && m <= 12; m++)
24351  {
24352  doy -= days[m];
24353  }
24354 
24355  d = doy;
24356  }
24357 
24358 write_results:
24359  /* last validations before writing results - we need only complete data info */
24360 
24361  if (res_type == DB_TYPE_DATE || res_type == DB_TYPE_DATETIME || res_type == DB_TYPE_DATETIMETZ)
24362  {
24363  /* replace invalid initial date (-1,-1,-1) with default date (1,1,1) */
24364  y = (y == -1) ? 1 : y;
24365  m = (m == -1) ? 1 : m;
24366  d = (d == -1) ? 1 : d;
24367 
24368  if (y < 0 || m < 0 || d < 0)
24369  {
24370  goto conversion_error;
24371  }
24372 
24373  if (d > days[m])
24374  {
24375  goto conversion_error;
24376  }
24377  }
24378 
24379  if (res_type == DB_TYPE_TIME || res_type == DB_TYPE_DATETIME || res_type == DB_TYPE_DATETIMETZ)
24380  {
24381  if (h < 0 || mi < 0 || s < 0)
24382  {
24383  goto conversion_error;
24384  }
24385  }
24386 
24387  if (res_type == DB_TYPE_DATE)
24388  {
24389  db_make_date (result, m, d, y);
24390  }
24391  else if (res_type == DB_TYPE_TIME)
24392  {
24393  db_make_time (result, h, mi, s);
24394  }
24395  else if (res_type == DB_TYPE_DATETIME)
24396  {
24398 
24399  db_datetime_encode (&db_datetime, m, d, y, h, mi, s, ms);
24400 
24401  db_make_datetime (result, &db_datetime);
24402  }
24403  else if (res_type == DB_TYPE_DATETIMETZ)
24404  {
24407 
24408  db_datetime_encode (&db_datetime, m, d, y, h, mi, s, ms);
24409 
24410  if (set_tzh == true || set_tzm == true)
24411  {
24412  error_status = tz_create_datetimetz_from_offset (&db_datetime, tzh, tzm, &db_datetimetz);
24413  if (error_status != NO_ERROR)
24414  {
24415  goto conversion_error;
24416  }
24417  }
24418  else
24419  {
24420  const char *dst = NULL;
24421  TZ_REGION session_tz_region;
24422 
24423  if (len_tzd > 0)
24424  {
24425  assert (start_tzd >= 0);
24426  dst = sstr + start_tzd;
24427  }
24428  tz_get_session_tz_region (&session_tz_region);
24429  error_status = tz_create_datetimetz_from_zoneid_and_tzd (&db_datetime, &session_tz_region, zone_id, dst,
24430  len_tzd, false, &db_datetimetz);
24431  if (error_status != NO_ERROR)
24432  {
24433  goto conversion_error;
24434  }
24435  }
24436 
24437  db_make_datetimetz (result, &db_datetimetz);
24438  }
24439 
24440 error:
24441  if (format_s)
24442  {
24443  db_private_free_and_init (NULL, format_s);
24444  }
24445  if (do_free_buf_str)
24446  {
24447  assert (initial_buf_str != NULL);
24448  db_private_free (NULL, initial_buf_str);
24449  }
24450  return error_status;
24451 
24452 conversion_error:
24453  if (do_free_buf_str)
24454  {
24455  assert (initial_buf_str != NULL);
24456  db_private_free (NULL, initial_buf_str);
24457  }
24458  if (format_s)
24459  {
24460  db_private_free_and_init (NULL, format_s);
24461  }
24462 
24464  {
24465  er_clear ();
24466  error_status = NO_ERROR;
24467  }
24468  else
24469  {
24470  error_status = ER_DATE_CONVERSION;
24471  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
24472  }
24473 
24474  db_make_null (result);
24475  return error_status;
24476 }
24477 
24478 /*
24479  * db_time_dbval () - extract the time from input parameter.
24480  * return: NO_ERROR, or error code
24481  * result(out) : resultant db_value
24482  * datetime_value(in) : time, timestamp or datetime expression
24483  * domain(in): result domain
24484  */
24485 int
24486 db_time_dbval (DB_VALUE * result, const DB_VALUE * datetime_value, const TP_DOMAIN * domain)
24487 {
24488  DB_TYPE type;
24489  char *res_s;
24490  int hour = 0, min = 0, sec = 0, milisec = 0;
24491  int size;
24492 
24493  if (DB_IS_NULL (datetime_value))
24494  {
24495  db_make_null (result);
24496  return NO_ERROR;
24497  }
24498 
24499  type = DB_VALUE_TYPE (datetime_value);
24500 
24501  if (db_get_time_from_dbvalue (datetime_value, &hour, &min, &sec, &milisec) != NO_ERROR)
24502  {
24503  db_make_null (result);
24505  {
24506  er_clear ();
24507  return NO_ERROR;
24508  }
24510  return ER_TIME_CONVERSION;
24511  }
24512 
24513  if (milisec != 0)
24514  {
24515  size = 12 + 1; /* HH:MM:SS.MMM */
24516  }
24517  else
24518  {
24519  size = 8 + 1; /* HH:MM:SS */
24520  }
24521 
24522  res_s = (char *) db_private_alloc (NULL, size);
24523  if (res_s == NULL)
24524  {
24525  return ER_OUT_OF_VIRTUAL_MEMORY;
24526  }
24527 
24528  if (milisec != 0)
24529  {
24530  sprintf (res_s, "%02d:%02d:%02d.%03d", hour, min, sec, milisec);
24531  }
24532  else
24533  {
24534  sprintf (res_s, "%02d:%02d:%02d", hour, min, sec);
24535  }
24536 
24537  switch (type)
24538  {
24539  case DB_TYPE_VARNCHAR:
24540  case DB_TYPE_NCHAR:
24541  db_make_varnchar (result, TP_FLOATING_PRECISION_VALUE, res_s, strlen (res_s),
24542  db_get_string_codeset (datetime_value), db_get_string_collation (datetime_value));
24543  break;
24544 
24545  case DB_TYPE_VARCHAR:
24546  case DB_TYPE_CHAR:
24547  db_make_varchar (result, TP_FLOATING_PRECISION_VALUE, res_s, strlen (res_s),
24548  db_get_string_codeset (datetime_value), db_get_string_collation (datetime_value));
24549  break;
24550 
24551  default:
24552  db_make_string (result, res_s);
24553  break;
24554  }
24555 
24556  if (domain != NULL)
24557  {
24558  assert (TP_DOMAIN_TYPE (domain) == DB_VALUE_TYPE (result));
24559 
24561  }
24562 
24563  result->need_clear = true;
24564 
24565  return NO_ERROR;
24566 }
24567 
24568 /*
24569  * db_date_dbval () - extract the date from input parameter.
24570  * return: NO_ERROR, or ER_code
24571  * result(out) : resultant db_value
24572  * date_value(in) : date or datetime expression
24573  * domain: domain of result
24574  */
24575 int
24576 db_date_dbval (DB_VALUE * result, const DB_VALUE * date_value, const TP_DOMAIN * domain)
24577 {
24578  DB_TYPE type;
24579  char *res_s;
24580  int y, m, d, hour, min, sec, ms;
24581  int error_status = NO_ERROR;
24582  INTL_CODESET codeset;
24583  int collation_id;
24584 
24585  if (date_value == NULL || result == NULL)
24586  {
24587  return ER_FAILED;
24588  }
24589 
24590  y = m = d = 0;
24591 
24592  type = DB_VALUE_DOMAIN_TYPE (date_value);
24593  if (type == DB_TYPE_NULL || DB_IS_NULL (date_value))
24594  {
24595  db_make_null (result);
24596  return NO_ERROR;
24597  }
24598 
24599  if (db_get_datetime_from_dbvalue (date_value, &y, &m, &d, &hour, &min, &sec, &ms, NULL) != NO_ERROR)
24600  {
24601  db_make_null (result);
24603  {
24604  er_clear ();
24605  return NO_ERROR;
24606  }
24608  return ER_DATE_CONVERSION;
24609  }
24610 
24611  res_s = (char *) db_private_alloc (NULL, 10 + 1); /* MM/DD/YYYY */
24612  if (res_s == NULL)
24613  {
24614  return ER_OUT_OF_VIRTUAL_MEMORY;
24615  }
24616 
24617  sprintf (res_s, "%02d/%02d/%04d", m, d, y);
24618 
24619  if (domain != NULL)
24620  {
24621  codeset = TP_DOMAIN_CODESET (domain);
24622  collation_id = TP_DOMAIN_COLLATION (domain);
24623  }
24624  else if (TP_IS_STRING_TYPE (DB_VALUE_TYPE (date_value)))
24625  {
24626  codeset = db_get_string_codeset (date_value);
24627  collation_id = db_get_string_collation (date_value);
24628  }
24629  else
24630  {
24631  codeset = LANG_SYS_CODESET;
24632  collation_id = LANG_SYS_COLLATION;
24633  }
24634 
24635  if (QSTR_IS_NATIONAL_CHAR (type))
24636  {
24637  db_make_varnchar (result, 10, res_s, 10, codeset, collation_id);
24638  }
24639  else
24640  {
24641  db_make_string (result, res_s);
24642  db_string_put_cs_and_collation (result, codeset, collation_id);
24643  }
24644 
24645  result->need_clear = true;
24646 
24647  return error_status;
24648 }
24649 
24650 /*
24651  * count_leap_years_up_to - count the leap years up to year
24652  * return: the counted value
24653  * year(in) : the last year to evaluate
24654  */
24655 int
24657 {
24658  return (year / 4 - year / 100 + year / 400);
24659 }
24660 
24661 /*
24662  * count_nonleap_years_up_to - count the non leap years up to year
24663  * return: the counted value
24664  * year(in) : the last year to evaluate
24665  */
24666 int
24668 {
24669  return (year - count_leap_years_up_to (year));
24670 }
24671 
24672 /*
24673  * db_date_diff () - expr1 ?? expr2 expressed as a value in days from
24674  * one date to the other.
24675  * return: int
24676  * result(out) : resultant db_value
24677  * date_value1(in) : first date
24678  * date_value2(in) : second date
24679  */
24680 int
24681 db_date_diff (const DB_VALUE * date_value1, const DB_VALUE * date_value2, DB_VALUE * result)
24682 {
24683  DB_TYPE type1, type2;
24684  int y1 = 0, m1 = 0, d1 = 0;
24685  int y2 = 0, m2 = 0, d2 = 0;
24686  int hour, min, sec, ms;
24687  int cly1, cly2, cnly1, cnly2, cdpm1, cdpm2, cdpy1, cdpy2, diff, i, cd1, cd2;
24688  int m_days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
24689  int error_status = NO_ERROR;
24690  int retval;
24691 
24692  if (date_value1 == NULL || date_value2 == NULL || result == NULL)
24693  {
24694  error_status = ER_FAILED;
24695  goto error;
24696  }
24697 
24698  type1 = DB_VALUE_DOMAIN_TYPE (date_value1);
24699  if (type1 == DB_TYPE_NULL || DB_IS_NULL (date_value1))
24700  {
24701  db_make_null (result);
24702  goto error;
24703  }
24704 
24705  type2 = DB_VALUE_DOMAIN_TYPE (date_value2);
24706  if (type2 == DB_TYPE_NULL || DB_IS_NULL (date_value2))
24707  {
24708  db_make_null (result);
24709  goto error;
24710  }
24711 
24712  retval = db_get_datetime_from_dbvalue (date_value1, &y1, &m1, &d1, &hour, &min, &sec, &ms, NULL);
24713  if (retval != NO_ERROR)
24714  {
24715  error_status = ER_DATE_CONVERSION;
24716  db_make_null (result);
24717  goto error;
24718  }
24719 
24720  retval = db_get_datetime_from_dbvalue (date_value2, &y2, &m2, &d2, &hour, &min, &sec, &ms, NULL);
24721  if (retval != NO_ERROR)
24722  {
24723  error_status = ER_DATE_CONVERSION;
24724  db_make_null (result);
24725  goto error;
24726  }
24727 
24728  if ((y1 == 0 && m1 == 0 && d1 == 0 && hour == 0 && min == 0 && sec == 0 && ms == 0)
24729  || (y2 == 0 && m2 == 0 && d2 == 0 && hour == 0 && min == 0 && sec == 0 && ms == 0))
24730  {
24731  er_clear ();
24732  db_make_null (result);
24734  {
24735  return NO_ERROR;
24736  }
24739  }
24740 
24741  cly1 = count_leap_years_up_to (y1 - 1);
24742  cnly1 = count_nonleap_years_up_to (y1 - 1);
24743  cdpy1 = cly1 * 366 + cnly1 * 365;
24744  m_days[2] = LEAP (y1) ? 29 : 28;
24745  cdpm1 = 0;
24746  for (i = 1; i < m1; i++)
24747  {
24748  cdpm1 += m_days[i];
24749  }
24750 
24751  cly2 = count_leap_years_up_to (y2 - 1);
24752  cnly2 = count_nonleap_years_up_to (y2 - 1);
24753  cdpy2 = cly2 * 366 + cnly2 * 365;
24754  m_days[2] = LEAP (y2) ? 29 : 28;
24755  cdpm2 = 0;
24756  for (i = 1; i < m2; i++)
24757  {
24758  cdpm2 += m_days[i];
24759  }
24760 
24761  cd1 = cdpy1 + cdpm1 + d1;
24762  cd2 = cdpy2 + cdpm2 + d2;
24763  diff = cd1 - cd2;
24764 
24765  db_make_int (result, diff);
24766 
24767 error:
24768  return error_status;
24769 }
24770 
24771 int
24772 db_from_unixtime (const DB_VALUE * src_value, const DB_VALUE * format, const DB_VALUE * date_lang, DB_VALUE * result,
24773  const TP_DOMAIN * domain)
24774 {
24775  time_t unix_timestamp;
24776  DB_TYPE format_type;
24777  int error_status = NO_ERROR;
24778 
24779  assert (src_value != NULL);
24780 
24781  if (DB_IS_NULL (src_value))
24782  {
24783  db_make_null (result);
24784  return NO_ERROR;
24785  }
24786  if (DB_VALUE_TYPE (src_value) != DB_TYPE_INTEGER)
24787  {
24788  error_status = ER_TIMESTAMP_CONVERSION;
24789  goto error;
24790  }
24791  unix_timestamp = db_get_int (src_value);
24792  if (unix_timestamp < 0)
24793  {
24794  error_status = ER_TIMESTAMP_CONVERSION;
24795  goto error;
24796  }
24797 
24798  if (format == NULL)
24799  {
24800  /* if unix_timestamp is called without a format argument, return the timestamp */
24801  db_make_timestamp (result, (DB_TIMESTAMP) unix_timestamp);
24802  return NO_ERROR;
24803  }
24804 
24805  if (DB_IS_NULL (format))
24806  {
24807  db_make_null (result);
24808  return NO_ERROR;
24809  }
24810 
24811  format_type = DB_VALUE_TYPE (format);
24812  switch (format_type)
24813  {
24814  case DB_TYPE_VARCHAR:
24815  case DB_TYPE_CHAR:
24816  case DB_TYPE_NCHAR:
24817  case DB_TYPE_VARNCHAR:
24818  {
24819  DB_VALUE ts_val;
24820  DB_VALUE default_date_lang;
24821 
24822  db_make_timestamp (&ts_val, (DB_TIMESTAMP) unix_timestamp);
24823  if (date_lang == NULL || DB_IS_NULL (date_lang))
24824  {
24825  /* use date_lang for en_US */
24826  db_make_int (&default_date_lang, 0);
24827  date_lang = &default_date_lang;
24828  }
24829 
24830  error_status = db_date_format (&ts_val, format, date_lang, result, domain);
24831  if (error_status != NO_ERROR)
24832  {
24833  goto error;
24834  }
24835  return NO_ERROR;
24836  }
24837 
24838  default:
24839  error_status = ER_TIMESTAMP_CONVERSION;
24840  goto error;
24841  }
24842 
24843 error:
24844  db_make_null (result);
24846  {
24847  er_clear ();
24848  return NO_ERROR;
24849  }
24850  if (er_errid () == NO_ERROR)
24851  {
24852  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
24853  }
24854  return error_status;
24855 }
24856 
24857 /*
24858  * db_time_diff () - return the difference between TIME values val1 and val2,
24859  * expressed as a TIME value
24860  * return: NO_ERROR or error code
24861  * result(out) : resultant db_value
24862  * val1(in) : first date/time value
24863  * val2(in) : second date/time value
24864  */
24865 int
24866 db_time_diff (const DB_VALUE * val1, const DB_VALUE * val2, DB_VALUE * result)
24867 {
24868  int y1 = 0, m1 = 0, d1 = 0, hour1 = 0, min1 = 0, sec1 = 0;
24869  int y2 = 0, m2 = 0, d2 = 0, hour2 = 0, min2 = 0, sec2 = 0;
24870  int error_status = NO_ERROR;
24871  int leap_years1, leap_years2, days_this_year1, days_this_year2;
24872  int total_days1, total_days2;
24873  int total_seconds1, total_seconds2, time_diff, date_diff = 0;
24874  int min_res, sec_res, hour_res;
24875  int ret_int, ms;
24876  DB_TYPE val1_type = DB_TYPE_TIME, val2_type = DB_TYPE_TIME;
24877  int hour_aux, min_aux, sec_aux, ms_aux;
24878 
24879  assert (val1 != NULL);
24880  assert (val2 != NULL);
24881 
24882  if (DB_IS_NULL (val1) || DB_IS_NULL (val2))
24883  {
24884  db_make_null (result);
24885  return NO_ERROR;
24886  }
24887 
24888  if (DB_VALUE_DOMAIN_TYPE (val1) != DB_VALUE_DOMAIN_TYPE (val2))
24889  {
24890  error_status = ER_QPROC_INVALID_PARAMETER;
24891  goto error;
24892  }
24893 
24894  /* get date/time information from val1 */
24895  if (db_get_time_from_dbvalue (val1, &hour1, &min1, &sec1, &ms) == NO_ERROR)
24896  {
24897  if (db_get_datetime_from_dbvalue (val1, &y1, &m1, &d1, &hour_aux, &min_aux, &sec_aux, &ms_aux, NULL) == NO_ERROR)
24898  {
24899  if (hour_aux != hour1 || min_aux != min1 || sec_aux != sec1)
24900  {
24901  y1 = 0;
24902  m1 = 0;
24903  d1 = 0;
24904  }
24905  else
24906  {
24907  val1_type = DB_TYPE_DATETIME;
24908  }
24909  }
24910  else
24911  {
24912  /* Extracted time is used. Make sure error is not leaked. */
24913  er_clear ();
24914  }
24915  }
24916  else
24917  {
24918  /* val1 may be Date type, try it here */
24919  if (db_get_datetime_from_dbvalue (val1, &y1, &m1, &d1, &hour_aux, &min_aux, &sec_aux, &ms_aux, NULL) == NO_ERROR)
24920  {
24921  val1_type = DB_TYPE_DATE;
24922  /* Extracted time is used. Make sure error is not leaked. */
24923  er_clear ();
24924  }
24925  else
24926  {
24927  error_status = ER_TIME_CONVERSION;
24928  goto error;
24929  }
24930  }
24931 
24932  /* get date/time information from val2 */
24933  if (db_get_time_from_dbvalue (val2, &hour2, &min2, &sec2, &ms) == NO_ERROR)
24934  {
24935  if (db_get_datetime_from_dbvalue (val2, &y2, &m2, &d2, &hour_aux, &min_aux, &sec_aux, &ms_aux, NULL) == NO_ERROR)
24936  {
24937  if (hour_aux != hour2 || min_aux != min2 || sec_aux != sec2)
24938  {
24939  y2 = 0;
24940  m2 = 0;
24941  d2 = 0;
24942  }
24943  else
24944  {
24945  val2_type = DB_TYPE_DATETIME;
24946  }
24947  }
24948  else
24949  {
24950  /* Extracted time is used. Make sure error is not leaked. */
24951  er_clear ();
24952  }
24953  }
24954  else
24955  {
24956  /* val2 may be Date type, try it here */
24957  if (db_get_datetime_from_dbvalue (val2, &y2, &m2, &d2, &hour_aux, &min_aux, &sec_aux, &ms_aux, NULL) == NO_ERROR)
24958  {
24959  /* Extracted time is used. Make sure error is not leaked. */
24960  er_clear ();
24961  val2_type = DB_TYPE_DATE;
24962  }
24963  else
24964  {
24965  error_status = ER_TIME_CONVERSION;
24966  goto error;
24967  }
24968  }
24969  if (val1_type != val2_type)
24970  {
24971  error_status = ER_QPROC_INVALID_PARAMETER;
24972  goto error;
24973  }
24974 
24975  if (val1_type != DB_TYPE_TIME)
24976  {
24977  /* convert dates to days */
24978  leap_years1 = count_leap_years_up_to (y1 - 1);
24979  days_this_year1 = db_get_day_of_year (y1, m1, d1);
24980  total_days1 = y1 * 365 + leap_years1 + days_this_year1;
24981 
24982  leap_years2 = count_leap_years_up_to (y2 - 1);
24983  days_this_year2 = db_get_day_of_year (y2, m2, d2);
24984  total_days2 = y2 * 365 + leap_years2 + days_this_year2;
24985 
24986  date_diff = total_days1 - total_days2;
24987  }
24988 
24989  total_seconds1 = sec1 + min1 * 60 + hour1 * 3600;
24990  total_seconds2 = sec2 + min2 * 60 + hour2 * 3600;
24991  time_diff = total_seconds1 - total_seconds2;
24992 
24993  date_diff = date_diff * 3600 * 24 + time_diff;
24994 
24995  hour_res = (date_diff / 3600);
24996  min_res = (date_diff % 3600) / 60;
24997  sec_res = date_diff - 3600 * hour_res - 60 * min_res;
24998 
24999  db_make_time (result, hour_res, min_res, sec_res);
25000  ret_int = (int) *(db_get_time (result));
25001 
25002  /* check time overflow on result */
25003  if (ret_int < 0)
25004  {
25005  error_status = ER_TIME_CONVERSION;
25006  goto error;
25007  }
25008  return NO_ERROR;
25009 
25010 error:
25011  db_make_null (result);
25012  er_clear ();
25014  {
25015  return NO_ERROR;
25016  }
25017  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
25018  return error_status;
25019 }
25020 
25021 /*
25022  * parse_time_string - parse a string given by the second argument of
25023  * timestamp function
25024  * return: NO_ERROR
25025  *
25026  * timestr(in) : input string
25027  * timestr_size(in): input string size
25028  * sign(out) : 0 if positive, -1 if negative
25029  * h(out) : hours
25030  * m(out) : minutes
25031  * s(out) : seconds
25032  * ms(out) : milliseconds
25033  */
25034 static int
25035 parse_time_string (const char *timestr, int timestr_size, int *sign, int *h, int *m, int *s, int *ms)
25036 {
25037  int args[4], num_args = 0, tmp;
25038  const char *ch;
25039  const char *dot = NULL, *end;
25040 
25041  assert (sign != NULL && h != NULL && m != NULL && s != NULL && ms != NULL);
25042  *sign = *h = *m = *s = *ms = 0;
25043 
25044  if (!timestr || !timestr_size)
25045  {
25046  return NO_ERROR;
25047  }
25048 
25049  ch = timestr;
25050  end = timestr + timestr_size;
25051 
25052  SKIP_SPACES (ch, end);
25053 
25054  if (*ch == '-')
25055  {
25056  *sign = 1;
25057  ch++;
25058  }
25059 
25060  /* Find dot('.') to separate milli-seconds part from whole string. */
25061  dot = ch;
25062  while (dot != end && *dot != '.')
25063  {
25064  dot++;
25065  }
25066 
25067  if (dot != end)
25068  {
25069  char ms_string[4];
25070 
25071  dot++;
25072  tmp = CAST_BUFLEN (end - dot);
25073  if (tmp)
25074  {
25075  tmp = (tmp < 3 ? tmp : 3);
25076  strncpy (ms_string, dot, tmp);
25077  }
25078  ms_string[3] = '\0';
25079 
25080  switch (tmp)
25081  {
25082  case 0:
25083  *ms = 0;
25084  break;
25085 
25086  case 1:
25087  ms_string[1] = '0';
25088  /* FALLTHRU */
25089  case 2:
25090  ms_string[2] = '0';
25091  /* FALLTHRU */
25092  default:
25093  *ms = atoi (ms_string);
25094  }
25095  }
25096 
25097  /* First ':' character means '0:'. */
25098  SKIP_SPACES (ch, end);
25099  if (ch != end && *ch == ':')
25100  {
25101  args[num_args++] = 0;
25102  ch++;
25103  }
25104 
25105  if (ch != end)
25106  {
25107  while (num_args < (int) (sizeof (args) / sizeof (*args)) && char_isdigit (*ch))
25108  {
25109  tmp = 0;
25110  do
25111  {
25112  /* check for overflow */
25113  if (tmp >= INT_MAX / 10)
25114  {
25115  tmp = INT_MAX;
25116  }
25117  else
25118  {
25119  tmp = tmp * 10 + *ch - '0';
25120  }
25121  ch++;
25122  }
25123  while (ch != end && char_isdigit (*ch));
25124 
25125  args[num_args++] = tmp;
25126 
25127  /* Digits should be separated by ':' character. If we meet other characters, stop parsing. */
25128  if (ch == end || *ch != ':')
25129  {
25130  break;
25131  }
25132  ch++;
25133  }
25134  }
25135 
25136  switch (num_args)
25137  {
25138  case 1:
25139  /* Consider single value as H...HMMSS. */
25140  *s = args[0] % 100;
25141  args[0] /= 100;
25142  *m = args[0] % 100;
25143  *h = args[0] / 100;
25144  break;
25145 
25146  case 2:
25147  *h = args[0];
25148  *m = args[1];
25149  break;
25150 
25151  case 3:
25152  *h = args[0];
25153  *m = args[1];
25154  *s = args[2];
25155  break;
25156 
25157  case 0:
25158  default:
25159  /* do nothing */
25160  ;
25161  }
25162  return NO_ERROR;
25163 }
25164 
25165 /*
25166  * db_bit_to_blob - convert bit string value to blob value
25167  * return: NO_ERROR or error code
25168  * src_value(in): bit string value
25169  * result_value(out): blob value
25170  */
25171 int
25172 db_bit_to_blob (const DB_VALUE * src_value, DB_VALUE * result_value)
25173 {
25174  DB_TYPE src_type;
25175  int error_status = NO_ERROR;
25176  DB_ELO *elo;
25177  const char *src_str;
25178  int src_length = 0;
25179 
25180  assert (src_value != NULL && result_value != NULL);
25181 
25182  src_type = DB_VALUE_DOMAIN_TYPE (src_value);
25183  if (src_type == DB_TYPE_NULL)
25184  {
25185  db_make_null (result_value);
25186  return NO_ERROR;
25187  }
25188  else if (QSTR_IS_BIT (src_type))
25189  {
25190  error_status = db_create_fbo (result_value, DB_TYPE_BLOB);
25191  if (error_status == NO_ERROR)
25192  {
25193  elo = db_get_elo (result_value);
25194  src_str = db_get_bit (src_value, &src_length);
25195  if (src_length > 0)
25196  {
25197  error_status = db_elo_write (elo, 0, src_str, QSTR_NUM_BYTES (src_length), NULL);
25198  }
25199  }
25200  }
25201  else
25202  {
25203  error_status = ER_QSTR_INVALID_DATA_TYPE;
25204  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
25205  }
25206 
25207  return error_status;
25208 }
25209 
25210 /*
25211  * db_char_to_blob - convert char string value to blob value
25212  * return: NO_ERROR or error code
25213  * src_value(in): char string value
25214  * result_value(out): blob value
25215  */
25216 int
25217 db_char_to_blob (const DB_VALUE * src_value, DB_VALUE * result_value)
25218 {
25219  DB_TYPE src_type;
25220  int error_status = NO_ERROR;
25221  DB_ELO *elo;
25222  const char *src_str;
25223  int src_size;
25224 
25225  assert (src_value != NULL && result_value != NULL);
25226 
25227  src_type = DB_VALUE_DOMAIN_TYPE (src_value);
25228  if (src_type == DB_TYPE_NULL)
25229  {
25230  db_make_null (result_value);
25231  return NO_ERROR;
25232  }
25233 
25234  if (QSTR_IS_ANY_CHAR (src_type))
25235  {
25236  error_status = db_create_fbo (result_value, DB_TYPE_BLOB);
25237  if (error_status == NO_ERROR)
25238  {
25239  elo = db_get_elo (result_value);
25240  src_str = db_get_string (src_value);
25241  src_size = db_get_string_size (src_value);
25242  if (src_size > 0)
25243  {
25244  error_status = db_elo_write (elo, 0, src_str, src_size, NULL);
25245  }
25246  }
25247  }
25248  else
25249  {
25250  error_status = ER_QSTR_INVALID_DATA_TYPE;
25251  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
25252  }
25253 
25254  return error_status;
25255 }
25256 
25257 /*
25258  * db_blob_to_bit - convert blob value to bit string value
25259  * return: NO_ERROR or error code
25260  * src_value(in): blob value
25261  * length_value(in): the length to convert
25262  * result_value(out): bit string value
25263  */
25264 int
25265 db_blob_to_bit (const DB_VALUE * src_value, const DB_VALUE * length_value, DB_VALUE * result_value)
25266 {
25267  int error_status = NO_ERROR;
25268  DB_TYPE src_type, length_type;
25269  int max_length;
25270 
25271  assert (src_value != NULL && result_value != NULL);
25272 
25273  src_type = DB_VALUE_DOMAIN_TYPE (src_value);
25274  if (length_value == NULL || DB_VALUE_TYPE (length_value) == DB_TYPE_NULL)
25275  {
25276  length_type = DB_TYPE_INTEGER;
25277  max_length = -1;
25278  }
25279  else
25280  {
25281  length_type = DB_VALUE_DOMAIN_TYPE (length_value);
25282  max_length = db_get_int (length_value);
25283  }
25284  if (src_type == DB_TYPE_NULL)
25285  {
25286  db_make_null (result_value);
25287  return NO_ERROR;
25288  }
25289 
25290  if (src_type == DB_TYPE_BLOB && length_type == DB_TYPE_INTEGER)
25291  {
25292  error_status = lob_to_bit_char (src_value, result_value, DB_TYPE_BLOB, max_length);
25293  }
25294  else
25295  {
25296  error_status = ER_QSTR_INVALID_DATA_TYPE;
25297  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
25298  }
25299 
25300  return error_status;
25301 }
25302 
25303 /*
25304  * db_blob_from_file - construct blob value from the file (char string literal)
25305  * return: NO_ERROR or error code
25306  * src_value(in): char string literal (file path)
25307  * result_value(out): blob value
25308  */
25309 int
25310 db_blob_from_file (const DB_VALUE * src_value, DB_VALUE * result_value)
25311 {
25312  DB_TYPE src_type;
25313  int error_status = NO_ERROR;
25314  char path_buf[PATH_MAX + 1]; /* reserve buffer for '\0' */
25315  const char *default_prefix = ES_LOCAL_PATH_PREFIX;
25316 
25317  assert (src_value != NULL && result_value != NULL);
25318 
25319  path_buf[0] = '\0';
25320  src_type = DB_VALUE_DOMAIN_TYPE (src_value);
25321  if (src_type == DB_TYPE_NULL)
25322  {
25323  db_make_null (result_value);
25324  return NO_ERROR;
25325  }
25326 
25327  if (QSTR_IS_CHAR (src_type))
25328  {
25329  int path_buf_len = 0;
25330  int src_size = db_get_string_size (src_value);
25331 
25332  src_size = (src_size < 0) ? strlen (db_get_string (src_value)) : src_size;
25333 
25334  if (db_get_string_size (src_value) == 0)
25335  {
25336  error_status = ER_QSTR_EMPTY_STRING;
25337  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
25338  return error_status;
25339  }
25340 
25341  if (es_get_type (db_get_string (src_value)) == ES_NONE)
25342  {
25343  /* Set default prefix, if no valid prefix was set. */
25344  strcpy (path_buf, default_prefix);
25345  path_buf_len = strlen (path_buf);
25346  }
25347 
25348  strncat (path_buf, db_get_string (src_value), MIN (src_size, PATH_MAX - path_buf_len));
25349  path_buf[path_buf_len + MIN (src_size, PATH_MAX - path_buf_len)] = '\0';
25350 
25351  error_status = lob_from_file (path_buf, src_value, result_value, DB_TYPE_BLOB);
25352  }
25353  else
25354  {
25355  error_status = ER_QSTR_INVALID_DATA_TYPE;
25356  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
25357  }
25358 
25359  return error_status;
25360 }
25361 
25362 /*
25363  * db_blob_length - get the length of blob value
25364  * return: NO_ERROR or error code
25365  * src_value(in): blob value
25366  * result_value(out): bigint value
25367  */
25368 int
25369 db_blob_length (const DB_VALUE * src_value, DB_VALUE * result_value)
25370 {
25371  DB_TYPE src_type;
25372  int error_status = NO_ERROR;
25373 
25374  assert (src_value != NULL && result_value != NULL);
25375 
25376  src_type = DB_VALUE_DOMAIN_TYPE (src_value);
25377  if (src_type == DB_TYPE_NULL)
25378  {
25379  db_make_null (result_value);
25380  return NO_ERROR;
25381  }
25382 
25383  if (src_type == DB_TYPE_BLOB)
25384  {
25385  error_status = lob_length (src_value, result_value);
25386  }
25387  else
25388  {
25389  error_status = ER_QSTR_INVALID_DATA_TYPE;
25390  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
25391  }
25392 
25393  return error_status;
25394 }
25395 
25396 /*
25397  * db_char_to_clob - convert char string value to clob value
25398  * return: NO_ERROR or error code
25399  * src_value(in): char string value
25400  * result_value(out): clob value
25401  */
25402 int
25403 db_char_to_clob (const DB_VALUE * src_value, DB_VALUE * result_value)
25404 {
25405  DB_TYPE src_type;
25406  int error_status = NO_ERROR;
25407  DB_ELO *elo;
25408  const char *src_str;
25409  int src_size;
25410 
25411  assert (src_value != NULL && result_value != NULL);
25412 
25413  src_type = DB_VALUE_DOMAIN_TYPE (src_value);
25414  if (src_type == DB_TYPE_NULL)
25415  {
25416  db_make_null (result_value);
25417  return NO_ERROR;
25418  }
25419 
25420  if (QSTR_IS_ANY_CHAR (src_type))
25421  {
25422  error_status = db_create_fbo (result_value, DB_TYPE_CLOB);
25423  if (error_status == NO_ERROR)
25424  {
25425  elo = db_get_elo (result_value);
25426  src_str = db_get_string (src_value);
25427  src_size = db_get_string_size (src_value);
25428  if (src_size > 0)
25429  {
25430  error_status = db_elo_write (elo, 0, src_str, src_size, NULL);
25431  }
25432  }
25433  }
25434  else
25435  {
25436  error_status = ER_QSTR_INVALID_DATA_TYPE;
25437  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
25438  }
25439 
25440  return error_status;
25441 }
25442 
25443 /*
25444  * db_clob_to_char - convert clob value to char string value
25445  * return: NO_ERROR or error code
25446  * src_value(in): clob value
25447  * codeset_value(in): the codeset of output string
25448  * result_value(out): char string value
25449  */
25450 int
25451 db_clob_to_char (const DB_VALUE * src_value, const DB_VALUE * codeset_value, DB_VALUE * result_value)
25452 {
25453  int error_status = NO_ERROR;
25454  DB_TYPE src_type;
25455  int max_length;
25456  int cs = LANG_SYS_CODESET;
25457 
25458  assert (src_value != NULL && result_value != NULL);
25459 
25460  if (codeset_value != NULL)
25461  {
25462  assert (DB_VALUE_DOMAIN_TYPE (codeset_value) == DB_TYPE_INTEGER);
25463 
25464  cs = db_get_int (codeset_value);
25466  {
25467  error_status = ER_OBJ_INVALID_ARGUMENTS;
25468  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
25469  return error_status;
25470  }
25471  }
25472  src_type = DB_VALUE_DOMAIN_TYPE (src_value);
25473 
25474  max_length = -1;
25475 
25476  if (src_type == DB_TYPE_NULL)
25477  {
25478  db_make_null (result_value);
25479  return NO_ERROR;
25480  }
25481 
25482  if (src_type == DB_TYPE_CLOB)
25483  {
25484  error_status = lob_to_bit_char (src_value, result_value, DB_TYPE_CLOB, max_length);
25485 
25486  if (result_value != NULL && DB_VALUE_DOMAIN_TYPE (result_value) == DB_TYPE_VARCHAR)
25487  {
25489  }
25490  }
25491  else
25492  {
25493  error_status = ER_QSTR_INVALID_DATA_TYPE;
25494  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
25495  }
25496 
25497  return error_status;
25498 }
25499 
25500 /*
25501  * db_clob_from_file - construct clob value from the file (char string literal)
25502  * return: NO_ERROR or error code
25503  * src_value(in): char string literal (file path)
25504  * result_value(out): clob value
25505  */
25506 int
25507 db_clob_from_file (const DB_VALUE * src_value, DB_VALUE * result_value)
25508 {
25509  DB_TYPE src_type;
25510  int error_status = NO_ERROR;
25511  char path_buf[PATH_MAX + 1]; /* reserve buffer for '\0' */
25512  const char *default_prefix = ES_LOCAL_PATH_PREFIX;
25513 
25514  assert (src_value != (DB_VALUE *) NULL);
25515 
25516  path_buf[0] = '\0';
25517  src_type = DB_VALUE_DOMAIN_TYPE (src_value);
25518  if (src_type == DB_TYPE_NULL)
25519  {
25520  db_make_null (result_value);
25521  return NO_ERROR;
25522  }
25523 
25524  if (QSTR_IS_CHAR (src_type))
25525  {
25526  int path_buf_len = 0;
25527  int src_size = db_get_string_size (src_value);
25528 
25529  src_size = (src_size < 0) ? strlen (db_get_string (src_value)) : src_size;
25530 
25531  if (db_get_string_size (src_value) == 0)
25532  {
25533  error_status = ER_QSTR_EMPTY_STRING;
25534  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
25535  return error_status;
25536  }
25537 
25538  if (es_get_type (db_get_string (src_value)) == ES_NONE)
25539  {
25540  /* Set default prefix, if no valid prefix was set. */
25541  strcpy (path_buf, default_prefix);
25542  path_buf_len = strlen (path_buf);
25543  }
25544 
25545  strncat (path_buf, db_get_string (src_value), MIN (src_size, PATH_MAX - path_buf_len));
25546  path_buf[path_buf_len + MIN (src_size, PATH_MAX - path_buf_len)] = '\0';
25547 
25548  error_status = lob_from_file (path_buf, src_value, result_value, DB_TYPE_CLOB);
25549  }
25550  else
25551  {
25552  error_status = ER_QSTR_INVALID_DATA_TYPE;
25553  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
25554  }
25555 
25556  return error_status;
25557 }
25558 
25559 /*
25560  * db_clob_length - get the length of clob value
25561  * return: NO_ERROR or error code
25562  * src_value(in): clob value
25563  * result_value(out): bigint value
25564  */
25565 int
25566 db_clob_length (const DB_VALUE * src_value, DB_VALUE * result_value)
25567 {
25568  DB_TYPE src_type;
25569  int error_status = NO_ERROR;
25570 
25571  assert (src_value != NULL && result_value != NULL);
25572 
25573  src_type = DB_VALUE_DOMAIN_TYPE (src_value);
25574  if (src_type == DB_TYPE_NULL)
25575  {
25576  db_make_null (result_value);
25577  return NO_ERROR;
25578  }
25579 
25580  if (src_type == DB_TYPE_CLOB)
25581  {
25582  error_status = lob_length (src_value, result_value);
25583  }
25584  else
25585  {
25586  error_status = ER_QSTR_INVALID_DATA_TYPE;
25587  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
25588  }
25589 
25590  return error_status;
25591 }
25592 
25593 /*
25594  * db_get_datetime_from_dbvalue () - splits a generic DB_VALUE to
25595  * year, month, day, hour, minute, second
25596  * Arguments:
25597  * src_date(in) : db_value to split
25598  * year(out) : year
25599  * month(out) : month
25600  * day(out) : day
25601  * hour(out) : hour
25602  * minute(out) : minute
25603  * second(out) : second
25604  * millisecond(out) : millisecond
25605  * endp(out) : end pointer into src_date after parsing string
25606  * Returns: int
25607  * Note: Callers should not use the global error mechanism.
25608  * This function returns ER_FAILED without setting the global error info
25609  */
25610 int
25611 db_get_datetime_from_dbvalue (const DB_VALUE * src_date, int *year, int *month, int *day, int *hour, int *minute,
25612  int *second, int *millisecond, const char **endp)
25613 {
25614  DB_TYPE arg_type = DB_TYPE_UNKNOWN;
25615 
25616  if (DB_IS_NULL (src_date))
25617  {
25618  /* return error if src_date is null */
25619  return ER_FAILED;
25620  }
25621 
25622  arg_type = DB_VALUE_DOMAIN_TYPE (src_date);
25623  switch (arg_type)
25624  {
25625  case DB_TYPE_CHAR:
25626  case DB_TYPE_NCHAR:
25627  case DB_TYPE_VARCHAR:
25628  case DB_TYPE_VARNCHAR:
25629  {
25631  int str_len;
25632  const char *strp;
25633 
25634  strp = db_get_string (src_date);
25635  str_len = db_get_string_size (src_date);
25636  if (db_date_parse_datetime_parts (strp, str_len, &db_datetime, NULL, NULL, NULL, endp) != NO_ERROR)
25637  {
25638  return ER_FAILED;
25639  }
25640 
25641  return db_datetime_decode (&db_datetime, month, day, year, hour, minute, second, millisecond);
25642  }
25643 
25644  case DB_TYPE_DATE:
25645  {
25646  *hour = 0;
25647  *minute = 0;
25648  *second = 0;
25649  *millisecond = 0;
25650  db_date_decode (db_get_date (src_date), month, day, year);
25651 
25652  return NO_ERROR;
25653  }
25654 
25655  case DB_TYPE_DATETIME:
25656  case DB_TYPE_DATETIMELTZ:
25657  case DB_TYPE_DATETIMETZ:
25658  {
25659  DB_DATETIME *dt_p;
25660  DB_DATETIME dt_local;
25661  DB_DATETIMETZ *dt_tz_p;
25662 
25663  if (arg_type == DB_TYPE_DATETIMELTZ)
25664  {
25665  dt_p = db_get_datetime (src_date);
25666  if (tz_datetimeltz_to_local (dt_p, &dt_local) != NO_ERROR)
25667  {
25668  er_clear ();
25669  return ER_FAILED;
25670  }
25671  dt_p = &dt_local;
25672  }
25673  else if (arg_type == DB_TYPE_DATETIMETZ)
25674  {
25675  dt_tz_p = db_get_datetimetz (src_date);
25676  if (tz_utc_datetimetz_to_local (&dt_tz_p->datetime, &dt_tz_p->tz_id, &dt_local) != NO_ERROR)
25677  {
25678  er_clear ();
25679  return ER_FAILED;
25680  }
25681  dt_p = &dt_local;
25682  }
25683  else
25684  {
25685  dt_p = db_get_datetime (src_date);
25686  }
25687 
25688  return db_datetime_decode (dt_p, month, day, year, hour, minute, second, millisecond);
25689  }
25690 
25691  case DB_TYPE_TIMESTAMP:
25692  case DB_TYPE_TIMESTAMPLTZ:
25693  case DB_TYPE_TIMESTAMPTZ:
25694  {
25695  DB_DATE db_date = 0;
25696  DB_TIME db_time = 0;
25697  DB_TIMESTAMP *ts_p;
25698  DB_TIMESTAMPTZ *ts_tz_p;
25699 
25700  if (arg_type == DB_TYPE_TIMESTAMPTZ)
25701  {
25702  ts_tz_p = db_get_timestamptz (src_date);
25703  if (db_timestamp_decode_w_tz_id (&ts_tz_p->timestamp, &ts_tz_p->tz_id, &db_date, &db_time) != NO_ERROR)
25704  {
25705  er_clear ();
25706  return ER_FAILED;
25707  }
25708  }
25709  else
25710  {
25711  ts_p = db_get_timestamp (src_date);
25712  (void) db_timestamp_decode_ses (ts_p, &db_date, &db_time);
25713  }
25714 
25715  db_date_decode (&db_date, month, day, year);
25716  db_time_decode (&db_time, hour, minute, second);
25717 
25718  return NO_ERROR;
25719  }
25720 
25721  default:
25722  return ER_FAILED;
25723  }
25724 
25725  return ER_FAILED;
25726 }
25727 
25728 /* TODO : refactor with db_get_datetime_from_dbvalue
25729  * db_get_time_from_dbvalue () - splits a generic DB_VALUE to
25730  * hour, minute, second , millisecond
25731  * Arguments:
25732  * src_date(in) : db_value to split
25733  * hour(out) : hour
25734  * minute(out) : minute
25735  * second(out) : second
25736  * millisecond(out) : millisecond
25737  * Returns: int
25738  *
25739  * Note: Callers should not use the global error mechanism.
25740  * This function returns ER_FAILED without setting the global error info
25741  * For arguments of type having timezone, the returned values are in
25742  * the local timezone (session or timezone of value).
25743  */
25744 int
25745 db_get_time_from_dbvalue (const DB_VALUE * src_date, int *hour, int *minute, int *second, int *millisecond)
25746 {
25747  DB_TYPE arg_type = DB_TYPE_UNKNOWN;
25748 
25749  *millisecond = 0;
25750 
25751  if (DB_IS_NULL (src_date))
25752  {
25753  return ER_FAILED;
25754  }
25755 
25756  arg_type = DB_VALUE_DOMAIN_TYPE (src_date);
25757  switch (arg_type)
25758  {
25759  case DB_TYPE_DATE:
25760  {
25761  /* set all to 0 because we don't have any time information */
25762  *hour = 0;
25763  *minute = 0;
25764  *second = 0;
25765  return NO_ERROR;
25766  }
25767 
25768  case DB_TYPE_STRING:
25769  case DB_TYPE_VARNCHAR:
25770  case DB_TYPE_CHAR:
25771  case DB_TYPE_NCHAR:
25772  {
25773  DB_TIME db_time;
25774  int str_len;
25775  const char *strp;
25776 
25777  strp = db_get_string (src_date);
25778  str_len = db_get_string_size (src_date);
25779  if (db_date_parse_time (strp, str_len, &db_time, millisecond) != NO_ERROR)
25780  {
25781  return ER_FAILED;
25782  }
25783 
25784  db_time_decode (&db_time, hour, minute, second);
25785  return NO_ERROR;
25786  }
25787 
25788  case DB_TYPE_DATETIME:
25789  case DB_TYPE_DATETIMELTZ:
25790  case DB_TYPE_DATETIMETZ:
25791  {
25792  int month = 0, day = 0, year = 0;
25793  DB_DATETIME *dt_p;
25794  DB_DATETIME dt_local;
25795  DB_DATETIMETZ *dt_tz_p;
25796 
25797  if (arg_type == DB_TYPE_DATETIMELTZ)
25798  {
25799  dt_p = db_get_datetime (src_date);
25800  if (tz_datetimeltz_to_local (dt_p, &dt_local) != NO_ERROR)
25801  {
25802  er_clear ();
25803  return ER_FAILED;
25804  }
25805  dt_p = &dt_local;
25806  }
25807  else if (arg_type == DB_TYPE_DATETIMETZ)
25808  {
25809  dt_tz_p = db_get_datetimetz (src_date);
25810  if (tz_utc_datetimetz_to_local (&dt_tz_p->datetime, &dt_tz_p->tz_id, &dt_local) != NO_ERROR)
25811  {
25812  er_clear ();
25813  return ER_FAILED;
25814  }
25815  dt_p = &dt_local;
25816  }
25817  else
25818  {
25819  dt_p = db_get_datetime (src_date);
25820  }
25821 
25822  return db_datetime_decode (dt_p, &month, &day, &year, hour, minute, second, millisecond);
25823  }
25824 
25825  case DB_TYPE_TIME:
25826  {
25827  DB_TIME *time_p;
25828 
25829  time_p = db_get_time (src_date);
25830 
25831  db_time_decode (time_p, hour, minute, second);
25832  return NO_ERROR;
25833  }
25834 
25835  case DB_TYPE_TIMESTAMP:
25836  case DB_TYPE_TIMESTAMPLTZ:
25837  case DB_TYPE_TIMESTAMPTZ:
25838  {
25839  DB_DATE db_date = 0;
25840  DB_TIME db_time = 0;
25841  DB_TIMESTAMP *ts_p;
25842  DB_TIMESTAMPTZ *ts_tz_p;
25843 
25844  if (arg_type == DB_TYPE_TIMESTAMPTZ)
25845  {
25846  ts_tz_p = db_get_timestamptz (src_date);
25847  if (db_timestamp_decode_w_tz_id (&ts_tz_p->timestamp, &ts_tz_p->tz_id, &db_date, &db_time) != NO_ERROR)
25848  {
25849  er_clear ();
25850  return ER_FAILED;
25851  }
25852  }
25853  else
25854  {
25855  ts_p = db_get_timestamp (src_date);
25856  (void) db_timestamp_decode_ses (ts_p, &db_date, &db_time);
25857  }
25858 
25859  db_time_decode (&db_time, hour, minute, second);
25860 
25861  return NO_ERROR;
25862  }
25863 
25864  default:
25865  return ER_FAILED;
25866  }
25867 
25868  return ER_FAILED;
25869 }
25870 
25871 #if defined(ENABLE_UNUSED_FUNCTION)
25872 /*
25873  * db_null_terminate_string () - create a null terminated c string from a
25874  * DB_VALUE of type DB_TYPE_CHAR or
25875  * DB_TYPE_NCHAR
25876  * return : NO_ERROR or error code
25877  * src_value(in) : DB_VALUE containing the string
25878  * strp(out) : pointer for output
25879  *
25880  * Note: the strp argument should not be allocated before calling this
25881  * function and should be freed by the code calling this function
25882  */
25883 int
25884 db_null_terminate_string (const DB_VALUE * src_value, char **strp)
25885 {
25886  int src_size = 0;
25887  DB_TYPE src_type = DB_TYPE_UNKNOWN;
25888 
25889  if (src_value == NULL)
25890  {
25891  return ER_FAILED;
25892  }
25893 
25894  src_size = db_get_string_size (src_value);
25895  src_type = DB_VALUE_DOMAIN_TYPE (src_value);
25896 
25897  if (src_type != DB_TYPE_CHAR && src_type != DB_TYPE_NCHAR)
25898  {
25899  return ER_FAILED;
25900  }
25901 
25902  *strp = (char *) db_private_alloc (NULL, (size_t) src_size + 1);
25903  if (*strp == NULL)
25904  {
25905  return ER_OUT_OF_VIRTUAL_MEMORY;
25906  }
25907 
25908  memcpy (*strp, db_get_string (src_value), src_size);
25909  (*strp)[src_size] = '\0';
25910 
25911  return NO_ERROR;
25912 }
25913 #endif
25914 
25915 /*
25916  * db_get_next_like_pattern_character () - Iterates through a LIKE pattern
25917  *
25918  * returns: NO_ERROR or error code
25919  *
25920  * pattern(in): the pattern that will be iterated upon
25921  * length(in): the length of the pattern (bytes)
25922  * codeset(in): codeset oof pattern string
25923  * has_escape_char(in): whether the LIKE pattern can use an escape character
25924  * escape_str(in): if has_escape_char is true this is the escaping character
25925  * used in the pattern, otherwise the parameter has no
25926  * meaning and should have the value NULL
25927  * position(in/out): pointer to the pattern position counter. The initial
25928  * value of the counter should be 0, meaning no characters
25929  * have yet been iterated. When (*position == length) the
25930  * iteration has come to an end. While iterating the pattern
25931  * the position value should not be changed by the callers
25932  * of this function.
25933  * crt_char_p(out): when the function returns this is the current character in
25934  * the pattern
25935  * is_escaped(out): whether the current character pointed to by "character"
25936  * is escaped in the pattern
25937  */
25938 static int
25939 db_get_next_like_pattern_character (const char *const pattern, const int length, const INTL_CODESET codeset,
25940  const bool has_escape_char, const char *escape_str, int *const position,
25941  char **crt_char_p, bool * const is_escaped)
25942 {
25943  int error_code = NO_ERROR;
25944  int char_size = 1;
25945 
25946  if (pattern == NULL || length < 0 || position == NULL || crt_char_p == NULL || is_escaped == NULL || *position < 0
25947  || *position >= length)
25948  {
25949  error_code = ER_OBJ_INVALID_ARGUMENTS;
25950  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
25951  goto error_exit;
25952  }
25953 
25954  assert (has_escape_char ^ (escape_str == NULL));
25955 
25956  *crt_char_p = NULL;
25957  *is_escaped = false;
25958 
25959  if (has_escape_char
25960  && intl_cmp_char ((unsigned char *) &(pattern[*position]), (unsigned char *) escape_str, codeset,
25961  &char_size) == 0)
25962  {
25963  *position += char_size;
25964  if (*position >= length)
25965  {
25966  /* To keep MySQL compatibility, when the last character is escape char, do not return error. */
25967  *crt_char_p = (char *) (&(pattern[*position - char_size]));
25968  return error_code;
25969  }
25970  *is_escaped = true;
25971  }
25972 
25973  *crt_char_p = (char *) (&(pattern[*position]));
25974  intl_char_size ((unsigned char *) *crt_char_p, 1, codeset, &char_size);
25975  *position += char_size;
25976 
25977  return error_code;
25978 
25979 error_exit:
25980  return error_code;
25981 }
25982 
25983 /*
25984  * is_safe_last_char_for_like_optimization () -
25985  *
25986  * return: whether a character can be the last one in the string for LIKE
25987  * index optimization. See db_get_info_for_like_optimization for
25988  * details.
25989  *
25990  * chr(in) : the character to consider
25991  * is_escaped(in) : whether the character is escaped in the LIKE pattern
25992  */
25993 static bool
25994 is_safe_last_char_for_like_optimization (const char *chr, const bool is_escaped, INTL_CODESET codeset)
25995 {
25996  assert (chr != NULL);
25997 
25998  if (!is_escaped && QSTR_IS_LIKE_WILDCARD_CHAR (*chr))
25999  {
26000  return false;
26001  }
26002 
26003  if (intl_is_max_bound_chr (codeset, (const unsigned char *) chr)
26004  || intl_is_min_bound_chr (codeset, (const unsigned char *) chr))
26005  {
26006  return false;
26007  }
26008  return true;
26009 }
26010 
26011 /*
26012  * db_get_info_for_like_optimization () - Gathers the information required for
26013  * performing the LIKE index
26014  * optimization
26015  *
26016  * returns: NO_ERROR or error code
26017  *
26018  * pattern(in): the LIKE pattern
26019  * has_escape_char(in): whether the LIKE pattern can use an escape character
26020  * escape_str(in): if has_escape_char is true this is the escaping character
26021  * used in the pattern, otherwise the parameter has no
26022  * meaning and should have the value NULL
26023  * num_logical_chars(out): the number of logical characters in the pattern.
26024  * This is equal to the pattern length minus the
26025  * escaping characters.
26026  * last_safe_logical_pos(out): the last character that can be used for the
26027  * string in the predicate rewrite or a negative
26028  * value if that particular rewrite cannot be
26029  * performed
26030  * num_match_many(out): the number of LIKE_WILDCARD_MATCH_MANY logical
26031  * characters (not escaped '%' characters)
26032  * num_match_one(out): the number of LIKE_WILDCARD_MATCH_ONE logical
26033  * characters (not escaped '_' characters)
26034  *
26035  * Note: db_compress_like_pattern should be applied on the pattern before
26036  * calling this function.
26037  *
26038  * Note: This function can be used for rewriting a LIKE predicate in order to
26039  * maximize the chance of using an index scan. The possible rewrites for
26040  * "expr LIKE pattern [ESCAPE escape]" are the following:
26041  *
26042  * 1)
26043  * if the pattern is '%' we match any non-null value; we can rewrite to:
26044  * expr IS NOT NULL
26045  *
26046  * 2)
26047  * if the pattern has no wildcards (num_match_many == 0 && num_match_one == 0)
26048  * and there are no comparison issues caused by trailing pattern whitespace,
26049  * we can rewrite to a simple equality predicate:
26050  * expr = remove_escaping (pattern [, escape])
26051  *
26052  * 3.1)
26053  * in most other cases we can rewrite to:
26054  * expr >= like_lower_bound ( like_prefix (pattern [, escape]) ) &&
26055  * expr < like_upper_bound ( like_prefix (pattern [, escape]) ) &&
26056  * expr LIKE pattern [ESCAPE escape]
26057  * The first two predicates provide early filtering of possible matches and
26058  * can be optimized through index scans. The last predicate provides an extra
26059  * filter to ensure that the expression actually matches the original pattern.
26060  *
26061  * This rewrite is only possible if there exist strings S_lower and S_upper
26062  * such that all LIKE matches are "BETWEEN S_lower GE_LT S_upper". We can
26063  * compute these strings (see db_get_like_optimization_bounds) based on the
26064  * longest prefix that does not contain a '%' character. The prefix itself can
26065  * generally serve as S_lower while the prefix with the last character
26066  * incremented by one can serve as S_upper. However, this imposes some
26067  * restrictions on the last character in the prefix: it must have a succesor
26068  * (it must not be the character 255), it must not cause issues during index
26069  * scans (the space character might cause such issues because of its collation
26070  * properties for VARCHAR). The special '_' wildcard can become the smallest
26071  * possible character of the collation in S_lower (a space character) and the
26072  * highest possible character in S_upper (character 255). Because of these
26073  * properties, the '_' wildcard cannot be the last character in the prefix.
26074  * Also see the is_safe_last_char_for_like_optimization function that codes
26075  * this logic used to compute the last_safe_logical_pos parameter value.
26076  *
26077  * 3.2)
26078  * If (pattern == like_prefix (pattern) + '%') and if the pattern does not
26079  * contain additional wildcards ('_') then we can exclude the LIKE predicate
26080  * and rewrite to:
26081  * expr >= like_lower_bound ( like_prefix (pattern [, escape]) ) &&
26082  * expr < like_upper_bound ( like_prefix (pattern [, escape]) )
26083  *
26084  * 3.3)
26085  * If the rewrite 3.1 cannot be performed we can still use an index scan if
26086  * like_lower_bound would returns negative infinity and like_upper_bound
26087  * returns positive infinity, leading to:
26088  * expr >= -infinity &&
26089  * expr < +infinity &&
26090  * expr LIKE pattern [ESCAPE escape]
26091  * See db_get_like_optimization_bounds for details.
26092  *
26093  * Rewrite 3.1 (combined with the special case 3.3) is the most general,
26094  * covering all the possible combinations, although it might result in slower
26095  * execution than the alternatives.
26096  */
26097 int
26098 db_get_info_for_like_optimization (const DB_VALUE * const pattern, const bool has_escape_char, const char *escape_str,
26099  int *const num_logical_chars, int *const last_safe_logical_pos,
26100  int *const num_match_many, int *const num_match_one)
26101 {
26102  int i = 0;
26103  int error_code = NO_ERROR;
26104  const char *pattern_str = NULL;
26105  int pattern_size = 0;
26106 
26107  if (pattern == NULL || num_logical_chars == NULL || last_safe_logical_pos == NULL || num_match_many == NULL
26108  || num_match_one == NULL)
26109  {
26110  error_code = ER_OBJ_INVALID_ARGUMENTS;
26111  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
26112  goto error_exit;
26113  }
26114 
26115  assert (has_escape_char ^ (escape_str == NULL));
26116 
26117  if (DB_IS_NULL (pattern) || !QSTR_IS_CHAR (DB_VALUE_DOMAIN_TYPE (pattern)))
26118  {
26119  error_code = ER_QSTR_INVALID_DATA_TYPE;
26120  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
26121  goto error_exit;
26122  }
26123 
26124  *num_logical_chars = 0;
26125  *last_safe_logical_pos = -22;
26126  *num_match_many = 0;
26127  *num_match_one = 0;
26128  pattern_str = db_get_string (pattern);
26129  pattern_size = db_get_string_size (pattern);
26130 
26131  for (i = 0; i < pattern_size;)
26132  {
26133  char *crt_char_p = NULL;
26134  bool is_escaped = false;
26135 
26136  error_code =
26137  db_get_next_like_pattern_character (pattern_str, pattern_size, db_get_string_codeset (pattern), has_escape_char,
26138  escape_str, &i, &crt_char_p, &is_escaped);
26139  if (error_code != NO_ERROR)
26140  {
26141  goto error_exit;
26142  }
26143 
26144  if (!is_escaped)
26145  {
26146  if (*crt_char_p == LIKE_WILDCARD_MATCH_MANY)
26147  {
26148  ++(*num_match_many);
26149  }
26150  else if (*crt_char_p == LIKE_WILDCARD_MATCH_ONE)
26151  {
26152  ++(*num_match_one);
26153  }
26154  }
26155 
26156  if (*num_match_many == 0
26157  && is_safe_last_char_for_like_optimization (crt_char_p, is_escaped, db_get_string_codeset (pattern)))
26158  {
26159  *last_safe_logical_pos = *num_logical_chars;
26160  }
26161 
26162  ++(*num_logical_chars);
26163  }
26164 
26165  return error_code;
26166 
26167 error_exit:
26168  return error_code;
26169 }
26170 
26171 /*
26172  * db_get_like_optimization_bounds () - Computes the bounding limits required
26173  * for performing the LIKE index
26174  * optimization
26175  *
26176  * returns: NO_ERROR or error code
26177  *
26178  * pattern(in): the LIKE pattern
26179  * bound(out): the computed upper or lower bound.
26180  * has_escape_char(in): whether the LIKE pattern can use an escape character
26181  * escape_str(in): if has_escape_char is true this is the escaping character
26182  * used in the pattern, otherwise the parameter has no
26183  * meaning and should have the value NULL
26184  * compute_lower_bound(in): whether to compute the upper or the lower bound
26185  * last_safe_logical_pos(in): the last character that can be used for the
26186  * string in the predicate rewrite or a negative
26187  * value if that particular rewrite cannot be
26188  * performed.
26189  *
26190  * Note: See the comments on db_get_info_for_like_optimization for details
26191  * on what this function computes.
26192  *
26193  * Note: If last_safe_logical_pos is negative the lower bound of the index
26194  * scan is negative infinity (equivalent to the empty string or the
26195  * string ' ' for the CHAR/VARCHAR default collation) and the upper
26196  * bound is positive infinity (currently approximated by a string of
26197  * one character code 255).
26198  */
26199 int
26200 db_get_like_optimization_bounds (const DB_VALUE * const pattern, DB_VALUE * bound, const bool has_escape_char,
26201  const char *escape_str, const bool compute_lower_bound,
26202  const int last_safe_logical_pos)
26203 {
26204  int error_code = NO_ERROR;
26205  const char *original = NULL;
26206  int original_size = 0;
26207  char *result = NULL;
26208  int result_length = 0;
26209  int result_size = 0;
26210  int i = 0;
26211  int alloc_size;
26212  int char_count;
26213  INTL_CODESET codeset;
26214  int collation_id;
26215 
26216  if (pattern == NULL || bound == NULL)
26217  {
26218  error_code = ER_OBJ_INVALID_ARGUMENTS;
26219  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
26220  goto error_exit;
26221  }
26222 
26223  assert (has_escape_char ^ (escape_str == NULL));
26224 
26225  if (DB_IS_NULL (pattern))
26226  {
26227  db_make_null (bound);
26228  goto fast_exit;
26229  }
26230 
26231  codeset = db_get_string_codeset (pattern);
26232  collation_id = db_get_string_collation (pattern);
26233 
26234  if (!QSTR_IS_CHAR (DB_VALUE_DOMAIN_TYPE (pattern)))
26235  {
26236  error_code = ER_QSTR_INVALID_DATA_TYPE;
26237  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
26238  goto error_exit;
26239  }
26240 
26241  if (last_safe_logical_pos < 0)
26242  {
26243  if (compute_lower_bound)
26244  {
26245  error_code =
26247  codeset, collation_id, NULL);
26248  if (error_code != NO_ERROR)
26249  {
26250  goto error_exit;
26251  }
26252  }
26253  else
26254  {
26255  error_code =
26257  codeset, collation_id, NULL);
26258  if (error_code != NO_ERROR)
26259  {
26260  goto error_exit;
26261  }
26262  }
26263 
26264  goto fast_exit;
26265  }
26266 
26267  original = db_get_string (pattern);
26268  original_size = db_get_string_size (pattern);
26269 
26270  /* assume worst case scenario : all characters in output bound string are stored on the maximum character size */
26271  intl_char_count ((unsigned char *) original, original_size, codeset, &char_count);
26272  alloc_size = LOC_MAX_UCA_CHARS_SEQ * char_count * INTL_CODESET_MULT (codeset);
26273  assert (alloc_size >= original_size);
26274 
26275  result = (char *) db_private_alloc (NULL, alloc_size + 1);
26276  if (result == NULL)
26277  {
26278  assert (er_errid () != NO_ERROR);
26279  error_code = er_errid ();
26280  goto error_exit;
26281  }
26282 
26283  assert (last_safe_logical_pos < char_count);
26284 
26285  for (i = 0, result_length = 0, result_size = 0; result_length <= last_safe_logical_pos;)
26286  {
26287  char *crt_char_p = NULL;
26288  bool is_escaped = false;
26289 
26290  error_code =
26291  db_get_next_like_pattern_character (original, original_size, codeset, has_escape_char, escape_str, &i,
26292  &crt_char_p, &is_escaped);
26293  if (error_code != NO_ERROR)
26294  {
26295  goto error_exit;
26296  }
26297 
26298  if (result_length == last_safe_logical_pos)
26299  {
26300  assert (is_safe_last_char_for_like_optimization (crt_char_p, is_escaped, codeset));
26301  }
26302 
26303  if (!is_escaped && *crt_char_p == LIKE_WILDCARD_MATCH_ONE)
26304  {
26305  assert (result_length < last_safe_logical_pos);
26306  if (compute_lower_bound)
26307  {
26308  result_size += intl_set_min_bound_chr (codeset, result + result_size);
26309  }
26310  else
26311  {
26312  result_size += intl_set_max_bound_chr (codeset, result + result_size);
26313  }
26314  result_length++;
26315  }
26316  else
26317  {
26318  if (result_length == last_safe_logical_pos && !compute_lower_bound)
26319  {
26320  char *next_alpha_char_p = result + result_size;
26321  int next_len = 0;
26322 
26323  result_size +=
26324  QSTR_NEXT_ALPHA_CHAR (collation_id, (unsigned char *) crt_char_p,
26325  CAST_BUFLEN (original - crt_char_p) + original_size,
26326  (unsigned char *) next_alpha_char_p, &next_len);
26327  result_length += next_len;
26328  }
26329  else
26330  {
26331  result_size +=
26332  intl_put_char ((unsigned char *) result + result_size, (unsigned char *) crt_char_p, codeset);
26333  result_length++;
26334  }
26335 
26336  }
26337  }
26338 
26339  assert (result_size <= alloc_size);
26340  qstr_make_typed_string (DB_TYPE_VARCHAR, bound, DB_VALUE_PRECISION (pattern), result, result_size, codeset,
26341  collation_id);
26342  result[result_size] = 0;
26343  bound->need_clear = true;
26344 
26345 fast_exit:
26346  return error_code;
26347 
26348 error_exit:
26349  if (result != NULL)
26350  {
26351  db_private_free_and_init (NULL, result);
26352  }
26353  return error_code;
26354 }
26355 
26356 /*
26357  * db_compress_like_pattern () - Optimizes a LIKE pattern for faster execution
26358  * and easier processing.
26359  *
26360  * returns: NO_ERROR or error code
26361  *
26362  * pattern(in): the LIKE pattern to be compressed
26363  * compressed_pattern(out): the optimized pattern (should be cleared before
26364  * being passed to this function)
26365  * has_escape_char(in): whether the LIKE pattern can use an escape character
26366  * escape_str(in): if has_escape_char is true this is the escaping character
26367  * used in the pattern, otherwise the parameter has no
26368  * meaning and should have the value NULL
26369  *
26370  * Note: This function removes all the unnecessary escape characters in
26371  * order to ease subsequent processing of the pattern. Currently there
26372  * are no such unnecessary escape sequences, but there might be in the
26373  * future if supporting MySQL semantics. See the comments in
26374  * db_get_next_like_pattern_character.
26375  */
26376 /* TODO This function could perform an extra optimization. The pattern
26377  * 'a%___%b' can be compressed to either 'a___%b' or 'a%___b'. The first
26378  * form is prefferable as it should execute faster than the second.
26379  * Also, if 'a%___b' is initially present, it can be changed to 'a___%b'.
26380  */
26381 int
26382 db_compress_like_pattern (const DB_VALUE * const pattern, DB_VALUE * compressed_pattern, const bool has_escape_char,
26383  const char *escape_str)
26384 {
26385  int error_code = NO_ERROR;
26386  const char *original = NULL;
26387  int original_size = 0;
26388  char *result = NULL;
26389  int result_length = 0;
26390  int result_size = 0;
26391  int i = 0;
26392  int alloc_size;
26393  bool in_percent_sequence = false;
26394  INTL_CODESET codeset;
26395 
26396  if (pattern == NULL || compressed_pattern == NULL)
26397  {
26398  error_code = ER_OBJ_INVALID_ARGUMENTS;
26399  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
26400  goto error_exit;
26401  }
26402 
26403  assert (has_escape_char ^ (escape_str == NULL));
26404 
26405  if (DB_IS_NULL (pattern))
26406  {
26407  db_make_null (compressed_pattern);
26408  goto fast_exit;
26409  }
26410 
26411  if (!QSTR_IS_ANY_CHAR (DB_VALUE_DOMAIN_TYPE (pattern)))
26412  {
26413  error_code = ER_QSTR_INVALID_DATA_TYPE;
26414  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
26415  goto error_exit;
26416  }
26417 
26418  codeset = db_get_string_codeset (pattern);
26419  original = db_get_string (pattern);
26420  original_size = db_get_string_size (pattern);
26421 
26422  if (has_escape_char)
26423  {
26424  int char_count;
26425 
26426  intl_char_count ((unsigned char *) original, original_size, codeset, &char_count);
26427  /* assume worst case : each character in the compressed pattern is precedeed by the escape char */
26428  alloc_size = original_size + char_count * strlen (escape_str);
26429  }
26430  else
26431  {
26432  alloc_size = original_size;
26433  }
26434 
26435  result = (char *) db_private_alloc (NULL, alloc_size + 1);
26436  if (result == NULL)
26437  {
26438  assert (er_errid () != NO_ERROR);
26439  error_code = er_errid ();
26440  goto error_exit;
26441  }
26442 
26443  for (i = 0, result_length = 0, result_size = 0, in_percent_sequence = false; i < original_size;)
26444  {
26445  char *crt_char_p = NULL;
26446  bool keep_crt_char = false;
26447  bool needs_escape = false;
26448  bool is_escaped = false;
26449 
26450  error_code =
26451  db_get_next_like_pattern_character (original, original_size, codeset, has_escape_char, escape_str, &i,
26452  &crt_char_p, &is_escaped);
26453  if (error_code != NO_ERROR)
26454  {
26455  goto error_exit;
26456  }
26457 
26458  if (is_escaped)
26459  {
26460  needs_escape = true;
26461  }
26462 
26463  assert (crt_char_p != NULL);
26464 
26465  if (!is_escaped && *crt_char_p == LIKE_WILDCARD_MATCH_MANY && in_percent_sequence)
26466  {
26467  keep_crt_char = false;
26468  }
26469  else
26470  {
26471  keep_crt_char = true;
26472  }
26473 
26474  if (keep_crt_char)
26475  {
26476  if (needs_escape)
26477  {
26478  assert (has_escape_char);
26479  result_size +=
26480  intl_put_char ((unsigned char *) result + result_size, (unsigned char *) escape_str, codeset);
26481  result_length++;
26482  }
26483  result_size += intl_put_char ((unsigned char *) result + result_size, (unsigned char *) crt_char_p, codeset);
26484  result_length++;
26485  }
26486 
26487  if (!is_escaped && *crt_char_p == LIKE_WILDCARD_MATCH_MANY)
26488  {
26489  in_percent_sequence = true;
26490  }
26491  else
26492  {
26493  in_percent_sequence = false;
26494  }
26495  }
26496 
26497  assert (result_length <= alloc_size);
26498  result[result_size] = 0;
26499  db_make_varchar (compressed_pattern, TP_FLOATING_PRECISION_VALUE, result, result_size, codeset,
26500  db_get_string_collation (pattern));
26501  compressed_pattern->need_clear = true;
26502 
26503 fast_exit:
26504  return error_code;
26505 
26506 error_exit:
26507  if (result != NULL)
26508  {
26509  db_private_free_and_init (NULL, result);
26510  }
26511  return error_code;
26512 }
26513 
26514 /*
26515  * db_like_bound () - Computes the bounding limits required for performing the
26516  * LIKE index optimization
26517  *
26518  * returns: NO_ERROR or error code
26519  *
26520  * src_pattern(in): the LIKE pattern
26521  * src_escape(in): the escape character or NULL if there is no escaping
26522  * result_bound(out): the computed upper or lower bound.
26523  * compute_lower_bound(in): whether to compute the upper or the lower bound
26524  *
26525  * Note: See the comments on db_get_info_for_like_optimization for details
26526  * on what this function computes.
26527  */
26528 int
26529 db_like_bound (const DB_VALUE * const src_pattern, const DB_VALUE * const src_escape, DB_VALUE * const result_bound,
26530  const bool compute_lower_bound)
26531 {
26532  int error_code = NO_ERROR;
26533  bool has_escape_char = false;
26534  DB_VALUE compressed_pattern;
26535  int num_logical_chars = 0;
26536  int last_safe_logical_pos = 0;
26537  int num_match_many = 0;
26538  int num_match_one = 0;
26539  const char *escape_str = NULL;
26540 
26541  db_make_null (&compressed_pattern);
26542 
26543  if (src_pattern == NULL || result_bound == NULL)
26544  {
26545  error_code = ER_OBJ_INVALID_ARGUMENTS;
26546  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
26547  goto error_exit;
26548  }
26549 
26550  if (DB_IS_NULL (src_pattern))
26551  {
26552  db_make_null (result_bound);
26553  goto fast_exit;
26554  }
26555 
26556  if (!QSTR_IS_ANY_CHAR (DB_VALUE_DOMAIN_TYPE (src_pattern)))
26557  {
26558  error_code = ER_QSTR_INVALID_DATA_TYPE;
26559  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
26560  goto error_exit;
26561  }
26562 
26563  if (src_escape == NULL)
26564  {
26565  has_escape_char = false;
26566  }
26567  else
26568  {
26569  if (DB_IS_NULL (src_escape))
26570  {
26571  /* a LIKE b ESCAPE NULL means use the default escape character '\\' */
26572  has_escape_char = true;
26573  escape_str = "\\";
26574  }
26575  else
26576  {
26577  if (!QSTR_IS_ANY_CHAR (DB_VALUE_DOMAIN_TYPE (src_pattern)))
26578  {
26579  error_code = ER_QSTR_INVALID_DATA_TYPE;
26580  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
26581  goto error_exit;
26582  }
26583 
26584  escape_str = db_get_string (src_escape);
26585 
26586  if (db_get_string_length (src_escape) != 1 || escape_str[0] == 0)
26587  {
26588  error_code = ER_QSTR_INVALID_ESCAPE_CHARACTER;
26589  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
26590  goto error_exit;
26591  }
26592 
26593  has_escape_char = true;
26594  }
26595  }
26596 
26597  error_code = db_compress_like_pattern (src_pattern, &compressed_pattern, has_escape_char, escape_str);
26598  if (error_code != NO_ERROR)
26599  {
26600  goto error_exit;
26601  }
26602 
26603  error_code =
26604  db_get_info_for_like_optimization (&compressed_pattern, has_escape_char, escape_str, &num_logical_chars,
26605  &last_safe_logical_pos, &num_match_many, &num_match_one);
26606  if (error_code != NO_ERROR)
26607  {
26608  goto error_exit;
26609  }
26610 
26611  error_code =
26612  db_get_like_optimization_bounds (&compressed_pattern, result_bound, has_escape_char, escape_str,
26613  compute_lower_bound, last_safe_logical_pos);
26614  if (error_code != NO_ERROR)
26615  {
26616  goto error_exit;
26617  }
26618 
26619 fast_exit:
26620  pr_clear_value (&compressed_pattern);
26621  return error_code;
26622 
26623 error_exit:
26624  pr_clear_value (&compressed_pattern);
26625  return error_code;
26626 }
26627 
26628 
26629 /*
26630  * db_check_or_create_null_term_string () - checks if the buffer associated to
26631  * string DB_VALUE is null terminated; if it is returns it
26632  * LIKE index optimization
26633  *
26634  * returns: NO_ERROR or error code
26635  *
26636  * str_val(in): source string DB_VALUE
26637  * pre_alloc_buf(in): preallocated buffer to store null terminated string
26638  * pre_alloc_buf_size(in): size of preallocated buffer
26639  * ignore_prec_spaces(in): true if it should ignore preceding spaces
26640  * (used only when new buffer needs to be allocated)
26641  * ignore_trail_spaces(in): true if it should ignore trailing spaces
26642  * (used only when new buffer needs to be allocated)
26643  * str_out(out): pointer to null terminated string
26644  * do_alloc(out): set to true if new buffer was allocated
26645  *
26646  */
26647 static int
26648 db_check_or_create_null_term_string (const DB_VALUE * str_val, char *pre_alloc_buf, int pre_alloc_buf_size,
26649  bool ignore_prec_spaces, bool ignore_trail_spaces, char **str_out, bool * do_alloc)
26650 {
26651  const char *val_buf;
26652  char *new_buf;
26653  const char *val_buf_end = NULL, *val_buf_end_non_space = NULL;
26654  int val_size;
26655 
26656  assert (pre_alloc_buf != NULL);
26657  assert (pre_alloc_buf_size > 1);
26658  assert (str_out != NULL);
26659  assert (do_alloc != NULL);
26661 
26662  *do_alloc = false;
26663 
26664  val_buf = db_get_string (str_val);
26665  if (val_buf == NULL)
26666  {
26667  *str_out = NULL;
26668  return NO_ERROR;
26669  }
26670  val_size = db_get_string_size (str_val);
26671 
26672  /* size < 0 assumes a null terminated string */
26673  if (val_size < 0)
26674  {
26675  val_size = strlen (val_buf);
26676  }
26677 
26678  if (val_size < pre_alloc_buf_size)
26679  {
26680  /* use the preallocated buffer supplied to copy the content */
26681  strncpy (pre_alloc_buf, val_buf, val_size);
26682  pre_alloc_buf[val_size] = '\0';
26683  *str_out = pre_alloc_buf;
26684  return NO_ERROR;
26685  }
26686 
26687  /* trim preceding and trailing spaces */
26688  val_buf_end = val_buf + val_size;
26689  if (ignore_prec_spaces)
26690  {
26691  while (val_buf < val_buf_end
26692  && ((*val_buf) == ' ' || (*val_buf) == '\t' || (*val_buf) == '\r' || (*val_buf) == '\n'))
26693  {
26694  val_buf++;
26695  }
26696  val_size = CAST_BUFLEN (val_buf_end - val_buf);
26697  assert (val_size >= 0);
26698  }
26699 
26700  if (ignore_trail_spaces && val_size > 0)
26701  {
26702  val_buf_end_non_space = val_buf + val_size - 1;
26703 
26704  while (val_buf < val_buf_end_non_space
26705  && ((*val_buf_end_non_space) == ' ' || (*val_buf_end_non_space) == '\t' || (*val_buf_end_non_space) == '\r'
26706  || (*val_buf_end_non_space) == '\n'))
26707  {
26708  val_buf_end_non_space--;
26709  }
26710  val_size = CAST_BUFLEN (val_buf_end_non_space - val_buf) + 1;
26711  assert (val_size >= 0);
26712  }
26713 
26714  if (val_size < pre_alloc_buf_size)
26715  {
26716  assert (ignore_prec_spaces || ignore_trail_spaces);
26717 
26718  /* use the preallocated buffer supplied to copy the content */
26719  strncpy (pre_alloc_buf, val_buf, val_size);
26720  pre_alloc_buf[val_size] = '\0';
26721  *str_out = pre_alloc_buf;
26722  return NO_ERROR;
26723  }
26724 
26725  new_buf = (char *) db_private_alloc (NULL, val_size + 1);
26726  if (new_buf == NULL)
26727  {
26728  return ER_OUT_OF_VIRTUAL_MEMORY;
26729  }
26730  strncpy (new_buf, val_buf, val_size);
26731  new_buf[val_size] = '\0';
26732  *str_out = new_buf;
26733  *do_alloc = true;
26734 
26735  return NO_ERROR;
26736 }
26737 
26738 /*
26739  * get_string_date_token_id() - get the id of date token identifier
26740  * return: NO_ERROR or error code
26741  * token_type(in): string-to-date token type
26742  * intl_lang_id(in):
26743  * cs(in): input string to search for token (considered NULL terminated)
26744  * token_id(out): id of token (if non-zero) or zero if not found;
26745  * range begins from 1 :days 1 - 7, months 1 - 12
26746  * token_size(out): size in bytes ocupied by token in input string 'cs'
26747  */
26748 static int
26749 get_string_date_token_id (const STRING_DATE_TOKEN token_type, const INTL_LANG intl_lang_id, const char *cs,
26750  const INTL_CODESET codeset, int *token_id, int *token_size)
26751 {
26752  const char **p;
26753  int error_status = NO_ERROR;
26754  int search_size;
26755  const char *parse_order;
26756  int i;
26757  int cs_size;
26758  int skipped_leading_chars = 0;
26759  const LANG_LOCALE_DATA *lld = lang_get_specific_locale (intl_lang_id, codeset);
26760 
26761  assert (cs != NULL);
26762  assert (token_id != NULL);
26763  assert (token_size != NULL);
26764 
26765  if (lld == NULL)
26766  {
26767  error_status = ER_LANG_CODESET_NOT_AVAILABLE;
26768  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 2, lang_get_lang_name_from_id (intl_lang_id),
26769  lang_charset_name (codeset));
26770  return error_status;
26771  }
26772 
26773 #if 0
26774  /* special case : korean short month name is read as digit */
26775  if (intl_lang_id == INTL_LANG_KOREAN && codeset == INTL_CODESET_ISO88591 && token_type == SDT_MONTH_SHORT)
26776  {
26777  i = parse_digits ((char *) cs, token_id, 2);
26778  if (i <= 0)
26779  {
26780  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
26781  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
26782  return error_status;
26783  }
26784 
26785  if (*token_id < 1 || *token_id > 12)
26786  {
26787  error_status = ER_QSTR_MISMATCHING_ARGUMENTS;
26788  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
26789  return error_status;
26790  }
26791 
26792  *token_size = i;
26793 
26794  return NO_ERROR;
26795  }
26796 #endif
26797 
26798  switch (token_type)
26799  {
26800  case SDT_DAY:
26801  p = (const char **) lld->day_name;
26802  parse_order = lld->day_parse_order;
26803  search_size = 7;
26804  break;
26805  case SDT_DAY_SHORT:
26806  p = (const char **) lld->day_short_name;
26807  parse_order = lld->day_short_parse_order;
26808  search_size = 7;
26809  break;
26810  case SDT_MONTH:
26811  p = (const char **) lld->month_name;
26812  parse_order = lld->month_parse_order;
26813  search_size = 12;
26814  break;
26815  case SDT_MONTH_SHORT:
26816  p = (const char **) lld->month_short_name;
26817  parse_order = lld->month_short_parse_order;
26818  search_size = 12;
26819  break;
26820  case SDT_AM_PM:
26821  p = (const char **) lld->am_pm;
26822  parse_order = lld->am_pm_parse_order;
26823  search_size = 12;
26824  break;
26825  default:
26826  assert (false);
26828  return ER_GENERIC_ERROR;
26829  }
26830 
26831  *token_id = 0;
26832 
26833  while (WHITESPACE (*cs))
26834  {
26835  cs++;
26836  skipped_leading_chars++;
26837  }
26838 
26839  cs_size = strlen (cs);
26840 
26841  for (i = 0; i < search_size; i++)
26842  {
26843  int cmp = 0;
26844  int token_index = parse_order[i];
26845  cmp =
26846  intl_case_match_tok (intl_lang_id, codeset, (unsigned char *) p[token_index], (unsigned char *) cs,
26847  strlen (p[token_index]), cs_size, token_size);
26848 
26849  assert (*token_size <= cs_size);
26850 
26851  if (cmp == 0)
26852  {
26853  *token_id = token_index + 1;
26854  *token_size += skipped_leading_chars;
26855  break;
26856  }
26857  }
26858 
26859  return NO_ERROR;
26860 }
26861 
26862 /*
26863  * print_string_date_token() - prints a date token to a buffer
26864  * return: NO_ERROR or error code
26865  * token_type(in): string-to-date token type
26866  * intl_lang_id(in): locale identifier
26867  * codeset(in): codeset to use for string to print; paired with intl_lang_id
26868  * token_id(in): id of token (zero-based index)
26869  * for days: 0 - 6, months: 0 - 11
26870  * case_mode(in): casing for printing token:
26871  * 0 : unchanged; 1 - force lowercase; 2 - force uppercase
26872  * buffer(in/out) : buffer to print to
26873  * token_size(out): size in bytes of token printed
26874  */
26875 static int
26876 print_string_date_token (const STRING_DATE_TOKEN token_type, const INTL_LANG intl_lang_id, const INTL_CODESET codeset,
26877  int token_id, int case_mode, char *buffer, int *token_size)
26878 {
26879  const char *p;
26880  int error_status = NO_ERROR;
26881  int token_len;
26882  int token_bytes;
26883  int print_len = -1;
26884  const LANG_LOCALE_DATA *lld = lang_get_specific_locale (intl_lang_id, codeset);
26885 
26886  assert (buffer != NULL);
26887  assert (token_id >= 0);
26888  assert (token_size != NULL);
26889 
26890  if (lld == NULL)
26891  {
26892  error_status = ER_LANG_CODESET_NOT_AVAILABLE;
26893  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 2, lang_get_lang_name_from_id (intl_lang_id),
26894  lang_charset_name (codeset));
26895  return error_status;
26896  }
26897 
26898  switch (token_type)
26899  {
26900  case SDT_DAY:
26901  assert (token_id < 7);
26902  p = lld->day_name[token_id];
26903 
26904  /* day names for all language use at most 9 chars */
26905  print_len = 9;
26906  break;
26907 
26908  case SDT_DAY_SHORT:
26909  assert (token_id < 7);
26910  p = lld->day_short_name[token_id];
26911 
26912  switch (intl_lang_id)
26913  {
26914  case INTL_LANG_ENGLISH:
26915  print_len = 3;
26916  break;
26917  case INTL_LANG_TURKISH:
26918  print_len = 2;
26919  break;
26920  default:
26921  print_len = -1;
26922  break;
26923  }
26924  break;
26925 
26926  case SDT_MONTH:
26927  assert (token_id < 12);
26928  p = lld->month_name[token_id];
26929 
26930  switch (intl_lang_id)
26931  {
26932  case INTL_LANG_ENGLISH:
26933  print_len = 9;
26934  break;
26935  case INTL_LANG_TURKISH:
26936  print_len = 7;
26937  break;
26938  default:
26939  print_len = -1;
26940  break;
26941  }
26942 
26943  break;
26944 
26945  case SDT_MONTH_SHORT:
26946  assert (token_id < 12);
26947  p = lld->month_short_name[token_id];
26948 
26949  /* all short names for months have 3 chars */
26950  print_len = 3;
26951  break;
26952 
26953  case SDT_AM_PM:
26954  assert (token_id < 12);
26955  p = lld->am_pm[token_id];
26956 
26957  /* AM/PM tokens are printed without padding */
26958  print_len = -1;
26959  break;
26960 
26961  default:
26962  assert (false);
26964  return ER_GENERIC_ERROR;
26965  }
26966 
26967 #if 0
26968  if (codeset == INTL_CODESET_KSC5601_EUC && intl_lang_id == INTL_LANG_KOREAN)
26969  {
26970  /* korean names dot not use compatible codeset, we use specific code to print them */
26971  switch (token_type)
26972  {
26973  case SDT_DAY:
26974  sprintf (buffer, "%-6s", p);
26975  *token_size = 6;
26976  break;
26977  case SDT_MONTH:
26978  sprintf (buffer, "%-4s", p);
26979  *token_size = 4;
26980  break;
26981  case SDT_DAY_SHORT:
26982  memcpy (buffer, p, 2);
26983  *token_size = 2;
26984  break;
26985  case SDT_MONTH_SHORT:
26986  sprintf (buffer, "%d", token_id + 1);
26987  *token_size = (token_id < 10) ? 1 : 2;
26988  break;
26989  case SDT_AM_PM:
26990  sprintf (buffer, "%s", p);
26991  *token_size = strlen (p);
26992  break;
26993  }
26994 
26995  return NO_ERROR;
26996  }
26997 #endif
26998 
26999  /* determine length of token */
27000  token_bytes = strlen (p);
27001  intl_char_count ((unsigned char *) p, token_bytes, codeset, &token_len);
27002 
27003  if (case_mode == 2)
27004  {
27005  /* uppercase */
27006  intl_upper_string (&(lld->alphabet), (unsigned char *) p, (unsigned char *) buffer, token_len);
27007  intl_char_size ((unsigned char *) buffer, token_len, codeset, token_size);
27008  }
27009  else if (case_mode == 1)
27010  {
27011  /* lowercase */
27012  intl_lower_string (&(lld->alphabet), (unsigned char *) p, (unsigned char *) buffer, token_len);
27013  intl_char_size ((unsigned char *) buffer, token_len, codeset, token_size);
27014  }
27015  else
27016  {
27017  intl_char_size ((unsigned char *) p, token_len, codeset, token_size);
27018  memcpy (buffer, p, *token_size);
27019  }
27020 
27021  /* padding */
27022  if (token_len < print_len)
27023  {
27024  (void) qstr_pad_string ((unsigned char *) buffer + *token_size, print_len - token_len, codeset);
27025  *token_size += intl_pad_size (codeset) * (print_len - token_len);
27026  }
27027 
27028  return NO_ERROR;
27029 }
27030 
27031 /*
27032  * convert_locale_number() - transforms a string containing a number in a
27033  * locale representation into another locale
27034  * return: void
27035  * sz(in/out): string to be transformed
27036  * src_locale(in):
27037  * dst_locale(in):
27038  *
27039  */
27040 static void
27041 convert_locale_number (char *sz, const int size, const INTL_LANG src_locale, const INTL_LANG dst_locale)
27042 {
27043  const char src_locale_group = lang_digit_grouping_symbol (src_locale);
27044  const char src_locale_frac = lang_digit_fractional_symbol (src_locale);
27045 
27046  const char dst_locale_group = lang_digit_grouping_symbol (dst_locale);
27047  const char dst_locale_frac = lang_digit_fractional_symbol (dst_locale);
27048  char *sz_end = sz + size;
27049 
27050  assert (src_locale != dst_locale);
27051 
27052  if (src_locale_group == dst_locale_group)
27053  {
27054  assert (src_locale_frac == dst_locale_frac);
27055  return;
27056  }
27057 
27058  assert (dst_locale_frac != dst_locale_group);
27059 
27060  for (; sz < sz_end && *sz != '\0'; sz++)
27061  {
27062  if (*sz == src_locale_group)
27063  {
27064  *sz = dst_locale_group;
27065  }
27066  else if (*sz == src_locale_frac)
27067  {
27068  *sz = dst_locale_frac;
27069  }
27070  }
27071 }
27072 
27073 
27074 /*
27075  * db_hex() - return hexadecimal representation
27076  * returns: error code or NO_ERROR
27077  * param(in): parameter to turn to hex
27078  * result(out): varchar db_value with hex representation
27079  *
27080  * Note:
27081  * If param is a generic string, the hex representation will be the
27082  * concatenation of hex values of each byte.
27083  * If param is a generic numeric, the hex representation will be that of
27084  * param casted to bigint (64bit unsigned integer). if value exceeds UINT64
27085  * capacity, the return value is 'FFFFFFFFFFFFFFFF'.
27086  */
27087 int
27088 db_hex (const DB_VALUE * param, DB_VALUE * result)
27089 {
27090  /* String length limits for numeric values of param. When param is numeric, it will be cast to BIGINT db type and
27091  * then internally to UINT64. hex_lenght_limits[i] is the upper limit of the closed set of integers that can be
27092  * represented in hex on i digits. */
27093  const UINT64 hex_length_limits[UINT64_MAX_HEX_DIGITS + 1] = {
27094  0x0, 0xF, 0xFF, 0xFFF, 0xFFFF,
27095  0xFFFFF, 0xFFFFFF, 0xFFFFFFF,
27096  0xFFFFFFFF, 0xFFFFFFFFF,
27097  0xFFFFFFFFFF, 0xFFFFFFFFFFF,
27098  0xFFFFFFFFFFFF, 0xFFFFFFFFFFFFF,
27099  0xFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFF,
27100  0xFFFFFFFFFFFFFFFF
27101  };
27102 
27103  /* hex digits */
27104  const char hex_digit[] = "0123456789ABCDEF";
27105 
27106  /* other variables */
27107  DB_TYPE param_type = DB_TYPE_UNKNOWN;
27108  const char *str = NULL;
27109  char *hexval = NULL;
27110  int str_size = 0, hexval_len = 0, i = 0, error_code = NO_ERROR;
27111 
27112  /* check parameters for NULL values */
27113  if (param == NULL || result == NULL)
27114  {
27115  error_code = ER_OBJ_INVALID_ARGUMENTS;
27116  goto error;
27117  }
27118 
27119  if (DB_IS_NULL (param))
27120  {
27121  db_make_null (result);
27122  return NO_ERROR;
27123  }
27124 
27125  /* compute hex representation */
27126  param_type = DB_VALUE_DOMAIN_TYPE (param);
27127 
27128  if (TP_IS_CHAR_TYPE (param_type) || TP_IS_BIT_TYPE (param_type))
27129  {
27130  if (TP_IS_CHAR_TYPE (param_type))
27131  {
27132  /* retrieve source string */
27133  str = db_get_string (param);
27134  str_size = db_get_string_size (param);
27135 
27136  /* remove padding from end of string */
27137  if (param_type == DB_TYPE_CHAR || param_type == DB_TYPE_NCHAR)
27138  {
27139  unsigned char pad_char[2];
27140  int pad_char_size;
27141  intl_pad_char (db_get_string_codeset (param), pad_char, &pad_char_size);
27142 
27143  while (str_size >= pad_char_size
27144  && memcmp (&(str[str_size - pad_char_size]), pad_char, pad_char_size) == 0)
27145  {
27146  str_size -= pad_char_size;
27147  }
27148  }
27149  }
27150  else
27151  {
27152  /* get bytes of bitfield */
27153  str = db_get_bit (param, &str_size);
27154  str_size = QSTR_NUM_BYTES (str_size);
27155  }
27156 
27157  /* allocate hex string */
27158  hexval_len = str_size * 2;
27159  hexval = (char *) db_private_alloc (NULL, hexval_len + 1);
27160  if (hexval == NULL)
27161  {
27162  error_code = ER_OUT_OF_VIRTUAL_MEMORY;
27163  goto error;
27164  }
27165  hexval[hexval_len] = 0;
27166 
27167  /* compute hex representation */
27168  for (i = 0; i < str_size; i++)
27169  {
27170  hexval[i * 2] = hex_digit[(str[i] >> 4) & 0xF];
27171  hexval[i * 2 + 1] = hex_digit[str[i] & 0xF];
27172  }
27173 
27174  /* set return string */
27175  db_make_string (result, hexval);
27176  result->need_clear = true;
27177  }
27178  else if (TP_IS_NUMERIC_TYPE (param_type))
27179  {
27180  DB_VALUE param_db_bigint;
27181  TP_DOMAIN *domain, *param_domain;
27182  UINT64 param_bigint;
27183 
27184  /* try to convert to bigint */
27185  param_domain = tp_domain_resolve_default (param_type);
27187  /* don't mind error code here, we need to know if param is out of range */
27188  (void) tp_value_auto_cast (param, &param_db_bigint, domain);
27189  if (DB_IS_NULL (&param_db_bigint))
27190  {
27191  /* param is out of range, set it to max */
27192  param_bigint = hex_length_limits[UINT64_MAX_HEX_DIGITS];
27193  }
27194  else
27195  {
27196  param_bigint = (UINT64) db_get_bigint (&param_db_bigint);
27197  }
27198 
27199  /* compute hex representation length */
27200  hexval_len = 1;
27201  while (param_bigint > hex_length_limits[hexval_len] && hexval_len < UINT64_MAX_HEX_DIGITS)
27202  {
27203  hexval_len++;
27204  }
27205 
27206  /* allocate memory */
27207  hexval = (char *) db_private_alloc (NULL, hexval_len + 1);
27208  if (hexval == NULL)
27209  {
27210  error_code = ER_OUT_OF_VIRTUAL_MEMORY;
27211  goto error;
27212  }
27213  hexval[hexval_len] = 0;
27214 
27215  /* compute hex representation */
27216  for (i = hexval_len - 1; i >= 0; --i)
27217  {
27218  hexval[i] = hex_digit[param_bigint & 0xF];
27219  param_bigint >>= 4;
27220  }
27221 
27222  /* set return string */
27223  db_make_string (result, hexval);
27224  result->need_clear = true;
27225  }
27226  else
27227  {
27228  error_code = ER_QSTR_INVALID_DATA_TYPE;
27229  goto error;
27230  }
27231 
27232  /* all ok */
27233  return NO_ERROR;
27234 
27235 error:
27236  if (result)
27237  {
27238  db_make_null (result);
27239  }
27241  {
27242  er_clear ();
27243  return NO_ERROR;
27244  }
27245 
27246  if (er_errid () == NO_ERROR)
27247  {
27248  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
27249  }
27250  return error_code;
27251 }
27252 
27253 #if !defined (CS_MODE)
27254 /*
27255  * db_guid() - Generate a type 4 (randomly generated) UUID.
27256  * return: error code or NO_ERROR
27257  * thread_p(in): thread context
27258  * result(out): HEX encoded UUID string
27259  * Note:
27260  */
27261 int
27262 db_guid (THREAD_ENTRY * thread_p, DB_VALUE * result)
27263 {
27264  int i = 0, error_code = NO_ERROR;
27265  const char hex_digit[] = "0123456789ABCDEF";
27266  char guid_bytes[GUID_STANDARD_BYTES_LENGTH];
27267  char *guid_hex = NULL;
27268 
27269  if (result == NULL)
27270  {
27271  error_code = ER_OBJ_INVALID_ARGUMENTS;
27272  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
27273  goto error;
27274  }
27275 
27276  db_make_null (result);
27277 
27278  /* Generate random bytes */
27279  error_code = crypt_generate_random_bytes (guid_bytes, GUID_STANDARD_BYTES_LENGTH);
27280 
27281  if (error_code != NO_ERROR)
27282  {
27283  goto error;
27284  }
27285 
27286  /* Clear UUID version field */
27287  guid_bytes[6] &= 0x0F;
27288  /* Set UUID version according to UUID version 4 protocol */
27289  guid_bytes[6] |= 0x40;
27290 
27291  /* Clear variant field */
27292  guid_bytes[8] &= 0x3f;
27293  /* Set variant according to UUID version 4 protocol */
27294  guid_bytes[8] |= 0x80;
27295 
27296  guid_hex = (char *) db_private_alloc (thread_p, GUID_STANDARD_BYTES_LENGTH * 2 + 1);
27297  if (guid_hex == NULL)
27298  {
27299  error_code = er_errid ();
27300  goto error;
27301  }
27302 
27303  guid_hex[GUID_STANDARD_BYTES_LENGTH * 2] = '\0';
27304 
27305  /* Encode the bytes to HEX */
27306  for (i = 0; i < GUID_STANDARD_BYTES_LENGTH; i++)
27307  {
27308  guid_hex[i * 2] = hex_digit[(guid_bytes[i] >> 4) & 0xF];
27309  guid_hex[i * 2 + 1] = hex_digit[(guid_bytes[i] & 0xF)];
27310  }
27311 
27312  db_make_string (result, guid_hex);
27313  result->need_clear = true;
27314 
27315  return NO_ERROR;
27316 
27317 error:
27319  {
27320  er_clear ();
27321  error_code = NO_ERROR;
27322  }
27323 
27324  return error_code;
27325 }
27326 #endif /* !defined (CS_MODE) */
27327 
27328 /*
27329  * db_ascii() - return ASCII code of first character in string
27330  * returns: error code or NO_ERROR
27331  * param(in): string
27332  * result(out): smallint db_value of ASCII code
27333  *
27334  * Note:
27335  * If param is a zero-length string, result should be zero.
27336  * If param is DB null, result should be DB null
27337  */
27338 int
27339 db_ascii (const DB_VALUE * param, DB_VALUE * result)
27340 {
27341  /* other variables */
27342  DB_TYPE param_type = DB_TYPE_UNKNOWN;
27343  const char *str = NULL;
27344  int str_size = 0, error_code = NO_ERROR;
27345 
27346  /* check parameters for NULL values */
27347  if (param == NULL || result == NULL)
27348  {
27349  error_code = ER_OBJ_INVALID_ARGUMENTS;
27350  goto error;
27351  }
27352 
27353  if (DB_IS_NULL (param))
27354  {
27355  db_make_null (result);
27356  return NO_ERROR;
27357  }
27358 
27359  /* get ASCII value */
27360  param_type = DB_VALUE_DOMAIN_TYPE (param);
27361 
27362  if (TP_IS_CHAR_TYPE (param_type))
27363  {
27364  /* get string and length */
27365  str = db_get_string (param);
27366  str_size = db_get_string_size (param);
27367 
27368  /* remove padding from end of string */
27369  if (param_type == DB_TYPE_CHAR || param_type == DB_TYPE_NCHAR)
27370  {
27371  unsigned char pad_char[2];
27372  int pad_char_size;
27373  intl_pad_char (db_get_string_codeset (param), pad_char, &pad_char_size);
27374 
27375  while (str_size >= pad_char_size && memcmp (&(str[str_size - pad_char_size]), pad_char, pad_char_size) == 0)
27376  {
27377  str_size -= pad_char_size;
27378  }
27379  }
27380 
27381  /* return first character */
27382  if (str_size > 0)
27383  {
27384  db_make_short (result, (unsigned char) str[0]);
27385  }
27386  else
27387  {
27388  db_make_short (result, 0);
27389  }
27390  }
27391  else if (TP_IS_BIT_TYPE (param_type))
27392  {
27393  /* get bitfield as char array */
27394  str = db_get_bit (param, &str_size);
27395 
27396  /* return first byte */
27397  if (str_size > 0)
27398  {
27399  db_make_short (result, (unsigned char) str[0]);
27400  }
27401  else
27402  {
27403  db_make_short (result, 0);
27404  }
27405  }
27406  else
27407  {
27408  error_code = ER_QSTR_INVALID_DATA_TYPE;
27409  goto error;
27410  }
27411 
27412  /* no error */
27413  return NO_ERROR;
27414 
27415 error:
27416  if (result)
27417  {
27418  db_make_null (result);
27419  }
27420  er_clear ();
27422  {
27423  return NO_ERROR;
27424  }
27425 
27426  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
27427  return error_code;
27428 }
27429 
27430 
27431 /*
27432  * db_conv() - convert number form one base to another
27433  * returns: error code or NO_ERROR
27434  * num(in): number to convert
27435  * from_base(in): base of num
27436  * to_base(in): base to convert num to
27437  * result(out): string db_value with number in new base
27438  *
27439  * Note:
27440  * From_base and to_base should satisfy 2 <= abs(base) <= 36
27441  */
27442 int
27443 db_conv (const DB_VALUE * num, const DB_VALUE * from_base, const DB_VALUE * to_base, DB_VALUE * result)
27444 {
27445  /* digit value lookup table vars */
27446  const unsigned char base_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
27447 
27448  /* error handling vars */
27449  int error_code = NO_ERROR;
27450 
27451  /* type checking vars */
27452  DB_TYPE num_type = DB_TYPE_UNKNOWN;
27453  DB_TYPE from_base_type = DB_TYPE_UNKNOWN;
27454  DB_TYPE to_base_type = DB_TYPE_UNKNOWN;
27455 
27456  /* sign flags */
27457  bool num_is_signed = false, res_is_signed = false;
27458  bool res_has_minus = false;
27459 
27460  /* string representations of input number and result; size of buffer is maximum computable value in base 2 (64
27461  * digits) + sign (1 digit) + NULL terminator (1 byte) */
27462  char num_str[UINT64_MAX_BIN_DIGITS + 2] = { 0 };
27463  unsigned char res_str[UINT64_MAX_BIN_DIGITS + 2] = { 0 };
27464  char *num_p_str = num_str, *res_p_str = NULL;
27465  char *num_end_ptr = NULL;
27466  char str_buf[NUMERIC_MAX_STRING_SIZE];
27467  unsigned char swap = 0;
27468  int num_size = 0, res_size = 0;
27469 
27470  /* auxiliary variables */
27471  UINT64 base10 = 0;
27472  int from_base_int = 0, to_base_int = 0, i = 0;
27473 
27474  /* check parameters for NULL values */
27475  if (num == NULL || from_base == NULL || to_base == NULL || result == NULL)
27476  {
27477  error_code = ER_OBJ_INVALID_ARGUMENTS;
27478  goto error;
27479  }
27480 
27481  if (DB_IS_NULL (num) || DB_IS_NULL (from_base) || DB_IS_NULL (to_base))
27482  {
27483  db_make_null (result);
27484  return NO_ERROR;
27485  }
27486 
27487  /* type checking; do not check num_type here, we will do it later on */
27488  num_type = DB_VALUE_DOMAIN_TYPE (num);
27489  from_base_type = DB_VALUE_DOMAIN_TYPE (from_base);
27490  to_base_type = DB_VALUE_DOMAIN_TYPE (to_base);
27491 
27492  if (from_base_type != DB_TYPE_SMALLINT || to_base_type != DB_TYPE_SMALLINT)
27493  {
27494  error_code = ER_QSTR_INVALID_DATA_TYPE;
27495  goto error;
27496  }
27497 
27498  /* from_base and to_base bounds checking */
27499  from_base_int = db_get_short (from_base);
27500  to_base_int = db_get_short (to_base);
27501  num_is_signed = (from_base_int < 0);
27502  res_is_signed = (to_base_int < 0);
27503  from_base_int = ABS (from_base_int);
27504  to_base_int = ABS (to_base_int);
27505 
27506  if (from_base_int < 2 || from_base_int > 36 || to_base_int < 2 || to_base_int > 36)
27507  {
27508  db_make_null (result);
27509  return NO_ERROR;
27510  }
27511 
27512  /* compute input number string from either generic NUMERIC or generic STRING types */
27513  if (TP_IS_NUMERIC_TYPE (num_type))
27514  {
27515  /* generic number -> string */
27516  switch (num_type)
27517  {
27518  case DB_TYPE_SMALLINT:
27519  snprintf (num_p_str, UINT64_MAX_BIN_DIGITS + 1, "%d", db_get_short (num));
27520  break;
27521 
27522  case DB_TYPE_INTEGER:
27523  snprintf (num_p_str, UINT64_MAX_BIN_DIGITS + 1, "%d", db_get_int (num));
27524  break;
27525 
27526  case DB_TYPE_BIGINT:
27527  snprintf (num_p_str, UINT64_MAX_BIN_DIGITS + 1, "%lld", (long long int) db_get_bigint (num));
27528  break;
27529 
27530  case DB_TYPE_NUMERIC:
27531  num_p_str = numeric_db_value_print (num, str_buf);
27532  /* set the decimal point to '\0' to bypass end_ptr check, make it looks like we already trucated out the
27533  * fractional part, as we do to float. */
27534  for (i = 0; num_p_str[i] != '\0'; ++i)
27535  {
27536  if (num_p_str[i] == '.')
27537  {
27538  num_p_str[i] = '\0';
27539  break;
27540  }
27541  }
27542  break;
27543 
27544  case DB_TYPE_FLOAT:
27545  snprintf (num_p_str, UINT64_MAX_BIN_DIGITS + 1, "%.0f", db_get_float (num));
27546  break;
27547 
27548  case DB_TYPE_DOUBLE:
27549  snprintf (num_p_str, UINT64_MAX_BIN_DIGITS + 1, "%.0f", db_get_double (num));
27550  break;
27551 
27552  case DB_TYPE_MONETARY:
27553  snprintf (num_p_str, UINT64_MAX_BIN_DIGITS + 1, "%.0f", db_value_get_monetary_amount_as_double (num));
27554  break;
27555 
27556  default:
27557  db_make_null (result);
27558  return NO_ERROR;
27559  }
27560  }
27561  else if (TP_IS_CHAR_TYPE (num_type))
27562  {
27563  /* copy into a null-terminated string */
27564  int str_size = db_get_string_size (num);
27565  INTL_CODESET codeset = db_get_string_codeset (num);
27566  int prev_char_length = 0;
27567  char *str_start = NULL, *str_end = NULL;
27568  char *prev_char = NULL;
27569 
27570  if (str_size >= 0)
27571  {
27572  str_size = MIN (str_size, sizeof (num_str) - 1);
27573  strncpy (num_str, db_get_string (num), str_size);
27574  str_start = num_str;
27575  str_end = num_str + str_size;
27576 
27577  /* trim the tailing white spaces */
27578  do
27579  {
27580  prev_char =
27581  (char *) intl_prev_char ((unsigned char *) str_end, (unsigned char *) str_start, codeset,
27582  &prev_char_length);
27583  assert (prev_char >= str_start);
27584 
27585  if (intl_is_space (prev_char, str_end, codeset, NULL))
27586  {
27587  str_size -= prev_char_length;
27588  assert (str_size >= 0);
27589 
27590  str_end = prev_char;
27591  }
27592  else
27593  {
27594  break;
27595  }
27596  }
27597  while (str_end > str_start);
27598  }
27599  else
27600  {
27601  str_size = 0;
27602  }
27603 
27604  num_str[str_size] = '\0';
27605  num_p_str = num_str;
27606 
27607  if (!is_str_valid_number (num_p_str, str_end, from_base_int, codeset))
27608  {
27609  error_code = ER_OBJ_INVALID_ARGUMENTS;
27610  goto error;
27611  }
27612  }
27613  else if (TP_IS_BIT_TYPE (num_type))
27614  {
27615  /* get raw bytes */
27616  const char *num_bit_str = db_get_bit (num, &num_size);
27617  num_size = QSTR_NUM_BYTES (num_size);
27618 
27619  /* convert to hex; NOTE: qstr_bin_to_hex returns number of converted bytes, not the size of the hex string; also,
27620  * we convert at most 64 digits even if we need only 16 in order to let strtoll handle overflow (weird stuff
27621  * happens there ...) */
27622  num_size = qstr_bin_to_hex (num_str, UINT64_MAX_BIN_DIGITS, num_bit_str, num_size);
27623  num_str[num_size * 2] = '\0';
27624 
27625  /* set up variables for hex -> base10 conversion */
27626  num_p_str = num_str;
27627  from_base_int = 16;
27628  num_is_signed = false;
27629  }
27630  else
27631  {
27632  /* we cannot process the input in any way */
27633  error_code = ER_QSTR_INVALID_DATA_TYPE;
27634  goto error;
27635  }
27636 
27637  /* convert from string to INT64/UINT64 */
27638  errno = 0;
27639  if (num_is_signed)
27640  {
27641  base10 = (UINT64) strtoll (num_p_str, &num_end_ptr, from_base_int);
27642  }
27643  else
27644  {
27645  base10 = (UINT64) strtoull (num_p_str, &num_end_ptr, from_base_int);
27646  }
27647 
27648  if (errno != 0)
27649  {
27652  error_code = ER_TP_CANT_COERCE_OVERFLOW;
27653  goto error;
27654  }
27655  if (num_end_ptr != NULL && *num_end_ptr != '\0')
27656  {
27657  error_code = ER_OBJ_INVALID_ARGUMENTS;
27658  goto error;
27659  }
27660 
27661  /* compute signed part of number */
27662  if (res_is_signed && base10 > DB_BIGINT_MAX)
27663  {
27664  /* result should be signed and we DO have a negative INT64; compute complement and remember to add minus sign to
27665  * string */
27666  base10 = ~base10;
27667  ++base10;
27668  res_has_minus = true;
27669  }
27670 
27671  /* convert base 10 -> to_base */
27672  if (base10 == 0)
27673  {
27674  /* number is zero? display it as such */
27675  res_str[res_size++] = '0';
27676  res_has_minus = false;
27677  }
27678 
27679  while (base10 > 0)
27680  {
27681  /* convert another digit */
27682  res_str[res_size++] = base_digits[base10 % to_base_int];
27683  base10 /= to_base_int;
27684  }
27685 
27686  if (res_has_minus)
27687  {
27688  /* add minus sign to number string */
27689  res_str[res_size++] = '-';
27690  }
27691 
27692  /* reverse string (duh!) */
27693  res_str[res_size] = 0;
27694  for (i = 0; i < res_size / 2; i++)
27695  {
27696  swap = res_str[i];
27697  res_str[i] = res_str[res_size - i - 1];
27698  res_str[res_size - i - 1] = swap;
27699  }
27700 
27701  /* return string */
27702  res_p_str = (char *) db_private_alloc (NULL, res_size + 1);
27703  if (res_p_str == NULL)
27704  {
27705  error_code = ER_OUT_OF_VIRTUAL_MEMORY;
27706  goto error;
27707  }
27708  memcpy (res_p_str, res_str, res_size + 1);
27709  db_make_string (result, res_p_str);
27710  result->need_clear = true;
27711 
27712  /* all ok */
27713  return NO_ERROR;
27714 
27715 error:
27716  if (result)
27717  {
27718  db_make_null (result);
27719  }
27721  {
27722  if (er_errid () != NO_ERROR)
27723  {
27724  er_clear ();
27725  }
27726  return NO_ERROR;
27727  }
27728 
27729  if (er_errid () == NO_ERROR)
27730  {
27731  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
27732  }
27733  return error_code;
27734 }
27735 
27736 /*
27737  * is_str_valid_number() - check whether the given string is a valid number.
27738  *
27739  * return: true if it's valid, false otherwise
27740  * num_p(in): the number in string pointer
27741  * str_end(in): end of string (pointer to first character after last
27742  * character of string) or NULL if str is null terminated
27743  * base(in): from 2 to 36 inclusive
27744  *
27745  */
27746 bool
27747 is_str_valid_number (char *num_p, char *str_end, int base, INTL_CODESET codeset)
27748 {
27749  char digit_max = (char) ('0' + base);
27750  char lower_char_max = (char) ('a' - 10 + base);
27751  char upper_char_max = (char) ('A' - 10 + base);
27752  bool has_decimal_point = false;
27753  int space_length = 0;
27754 
27755  /* skip leading space */
27756  while (num_p < str_end)
27757  {
27758  if (!intl_is_space (num_p, str_end, codeset, &space_length))
27759  {
27760  break;
27761  }
27762 
27763  num_p += space_length;
27764  assert (num_p <= str_end);
27765  }
27766 
27767  /* just space, no digit */
27768  if (num_p == str_end)
27769  {
27770  return false;
27771  }
27772 
27773  /* check number sign */
27774  if (*num_p == '-' || *num_p == '+')
27775  {
27776  ++num_p;
27777  }
27778 
27779  /* check base16 prefix '0x' */
27780  if (base == 16 && *num_p == '0' && (*(num_p + 1) == 'x' || *(num_p + 1) == 'X'))
27781  {
27782  num_p += 2;
27783 
27784  /* just space, no digit */
27785  if (num_p == str_end)
27786  {
27787  return false;
27788  }
27789  }
27790 
27791  /* check the digits */
27792  for (; num_p != str_end; ++num_p)
27793  {
27794  if (base < 10 && *num_p >= '0' && *num_p < digit_max)
27795  {
27796  continue;
27797  }
27798  if (base >= 10 && *num_p >= '0' && *num_p <= '9')
27799  {
27800  continue;
27801  }
27802 
27803  if (base > 10 && *num_p >= 'a' && *num_p < lower_char_max)
27804  {
27805  continue;
27806  }
27807  if (base > 10 && *num_p >= 'A' && *num_p < upper_char_max)
27808  {
27809  continue;
27810  }
27811 
27812  if (*num_p == '.' && !has_decimal_point)
27813  {
27814  /* truncate out the fractional part */
27815  *num_p = '\0';
27816  has_decimal_point = true;
27817  continue;
27818  }
27819 
27820  return false;
27821  }
27822  return true;
27823 }
27824 
27825 /*
27826  * init_builtin_calendar_names() - initializes builtin localizations for
27827  * calendar names
27828  * return: void
27829  * lld(in/out): locale data
27830  *
27831  */
27832 void
27834 {
27835  int i;
27836 
27837  assert (lld != NULL);
27838 
27839  if (lld->codeset == INTL_CODESET_UTF8)
27840  {
27841  for (i = 0; i < 7; i++)
27842  {
27843  lld->day_short_name[i] = Short_Day_name_UTF8[lld->lang_id][i];
27844  lld->day_name[i] = Day_name_UTF8[lld->lang_id][i];
27845  }
27846 
27847  for (i = 0; i < 12; i++)
27848  {
27850  lld->month_name[i] = Month_name_UTF8[lld->lang_id][i];
27851  }
27852 
27853  for (i = 0; i < 12; i++)
27854  {
27855  lld->am_pm[i] = Am_Pm_name_UTF8[lld->lang_id][i];
27856  }
27857  }
27858  else if (lld->codeset == INTL_CODESET_KSC5601_EUC)
27859  {
27860  for (i = 0; i < 7; i++)
27861  {
27863  lld->day_name[i] = Day_name_EUCKR[lld->lang_id][i];
27864  }
27865 
27866  for (i = 0; i < 12; i++)
27867  {
27869  lld->month_name[i] = Month_name_EUCKR[lld->lang_id][i];
27870  }
27871 
27872  for (i = 0; i < 12; i++)
27873  {
27874  lld->am_pm[i] = Am_Pm_name_EUCKR[lld->lang_id][i];
27875  }
27876  }
27877  else
27878  {
27879  for (i = 0; i < 7; i++)
27880  {
27881  lld->day_short_name[i] = Short_Day_name_ISO[lld->lang_id][i];
27882  lld->day_name[i] = Day_name_ISO[lld->lang_id][i];
27883  }
27884 
27885  for (i = 0; i < 12; i++)
27886  {
27888  lld->month_name[i] = Month_name_ISO[lld->lang_id][i];
27889  }
27890 
27891  for (i = 0; i < 12; i++)
27892  {
27893  lld->am_pm[i] = Am_Pm_name_ISO[lld->lang_id][i];
27894  }
27895  }
27896 
27902 }
27903 
27904 /*
27905  * db_value_to_enumeration_value () - convert a DB_VALUE to an enumeration
27906  * value ignoring out of range values
27907  * return : error code or NO_ERROR
27908  * src (in) : source value
27909  * result (in/out) : enumeration value
27910  * enum_domain (in) : enumeration domain
27911  *
27912  * Note: The result value will hold the index of the enum if src has a
27913  * corespondent in the enumeration values or 0 otherwise.
27914  */
27915 int
27916 db_value_to_enumeration_value (const DB_VALUE * src, DB_VALUE * result, const TP_DOMAIN * enum_domain)
27917 {
27919 
27920  if (src == NULL || result == NULL || enum_domain == NULL)
27921  {
27922  assert (false);
27924  return ER_FAILED;
27925  }
27926 
27927  db_make_null (result);
27928 
27929  status = tp_value_cast (src, result, enum_domain, false);
27930  if (status != DOMAIN_COMPATIBLE)
27931  {
27932  if (status == DOMAIN_ERROR)
27933  {
27934  return ER_FAILED;
27935  }
27936  db_make_enumeration (result, DB_ENUM_OVERFLOW_VAL, NULL, 0, TP_DOMAIN_CODESET (enum_domain),
27937  TP_DOMAIN_COLLATION (enum_domain));
27938  er_clear ();
27939  /* continue, no error */
27940  }
27941 
27942  return NO_ERROR;
27943 }
27944 
27945 
27946 /*
27947  * db_inet_aton () - convert a string formatted IPv4 address
27948  * to a number formatted IPv4 address
27949  * Arguments:
27950  * string (in) : source ip string
27951  * result_numbered_ip (in/out) : result number
27952  *
27953  * Returns: int
27954  * error code or NO_ERROR
27955  *
27956  * Errors:
27957  * ER_OBJ_INVALID_ARGUMENTS
27958  * ER_QSTR_INVALID_DATA_TYPE
27959  * ER_OPFUNC_INET_NTOA_ARG
27960  * ER_OUT_OF_VIRTUAL_MEMORY
27961  *
27962  * Note: the ip "226.000.000.037" is 226.0.0.31, not 226.0.0.37
27963  * support "0x3d.037.12.25" format
27964  */
27965 int
27966 db_inet_aton (DB_VALUE * result_numbered_ip, const DB_VALUE * string)
27967 {
27968  int error_code = NO_ERROR;
27969  DB_BIGINT numbered_ip = (DB_BIGINT) 0;
27970  const char *ip_string = NULL;
27971  char *local_ipstring = NULL;
27972  char *local_ipslice = NULL;
27973  char *local_pivot = NULL;
27974  int slice = 0;
27975  int result = 0;
27976  const int ipsegmax = 256;
27977  DB_BIGINT ipbase;
27978  int slice_count = 0;
27979  int cnt;
27980  char *temp_tok;
27981 
27982  if (string == NULL || result_numbered_ip == NULL)
27983  {
27984  error_code = ER_OBJ_INVALID_ARGUMENTS;
27985  goto error;
27986  }
27987 
27988  if (DB_IS_NULL (string))
27989  {
27990  db_make_null (result_numbered_ip);
27991  return NO_ERROR;
27992  }
27993 
27994  if (!is_char_string (string))
27995  {
27996  error_code = ER_QSTR_INVALID_DATA_TYPE;
27997  goto error;
27998  }
27999 
28000  /* there is no need to check db_get_string_length or db_get_string_size or cnt, we control ip format by ourselves */
28001  ip_string = db_get_char (string, &cnt);
28002  local_ipstring = (char *) db_private_alloc (NULL, cnt + 1);
28003  if (local_ipstring == NULL)
28004  {
28005  error_code = ER_OUT_OF_VIRTUAL_MEMORY;
28006  goto error;
28007  }
28008  memcpy (local_ipstring, ip_string, cnt);
28009  local_ipstring[cnt] = '\0';
28010 
28011  ipbase = (DB_BIGINT) ipsegmax *ipsegmax * ipsegmax;
28012  for (temp_tok = local_ipstring;; temp_tok = NULL)
28013  {
28014  /* use ". \t" to be more tolerable of input format. */
28015  local_ipslice = strtok_r (temp_tok, ". \t", &local_pivot);
28016  if (local_ipslice == NULL)
28017  {
28018  break;
28019  }
28020 
28021  if (!is_valid_ip_slice (local_ipslice))
28022  {
28024  error_code = ER_OPFUNC_INET_ATON_ARG;
28025  goto error;
28026  }
28027 
28028  result = parse_int (&slice, local_ipslice, 0);
28029  if (result != 0 || slice < 0 || slice >= ipsegmax)
28030  {
28032  error_code = ER_OPFUNC_INET_ATON_ARG;
28033  goto error;
28034  }
28035  numbered_ip += slice * ipbase;
28036  ipbase /= ipsegmax;
28037  slice_count++;
28038  }
28039  if (numbered_ip < 0 || numbered_ip > (DB_BIGINT) ipsegmax * ipsegmax * ipsegmax * ipsegmax || slice_count != 4)
28040  {
28042  error_code = ER_OPFUNC_INET_ATON_ARG;
28043  goto error;
28044  }
28045 
28046  db_private_free (NULL, local_ipstring);
28047  db_make_bigint (result_numbered_ip, numbered_ip);
28048  return NO_ERROR;
28049 
28050 error:
28051  if (local_ipstring != NULL)
28052  {
28053  db_private_free (NULL, local_ipstring);
28054  }
28055  db_make_null (result_numbered_ip);
28056 
28058  {
28059  er_clear ();
28060  return NO_ERROR;
28061  }
28062  return error_code;
28063 }
28064 
28065 /*
28066  * db_inet_ntoa () - convert a number formatted IPv4 address
28067  * to a string formatted IPv4 address
28068  * Arguments:
28069  * number (in) : source numbered ip
28070  * result_ip_string (in/out) : result ip string
28071  *
28072  * Returns: int
28073  * error code or NO_ERROR
28074  *
28075  * Errors:
28076  * ER_QSTR_INVALID_DATA_TYPE
28077  * ER_OBJ_INVALID_ARGUMENTS
28078  * ER_OPFUNC_INET_NTOA_ARG
28079  *
28080  * Note:
28081  */
28082 int
28083 db_inet_ntoa (DB_VALUE * result_ip_string, const DB_VALUE * number)
28084 {
28085  int error_code = NO_ERROR;
28086  DB_TYPE number_type = DB_TYPE_UNKNOWN;
28087  DB_BIGINT ip_number = 0;
28088  char ip_string[16] = { '\0' };
28089  char ip_seg_string[4] = { '\0' };
28090  const int ip_seg_string_cnt = 4;
28091  const DB_BIGINT ipmax = (DB_BIGINT) 256 * 256 * 256 * 256;
28092  const unsigned int ipv4_mask[] = { 0xFF000000, 0xFF0000, 0xFF00, 0xFF };
28093  const unsigned int ipfactor[] = { 256 * 256 * 256, 256 * 256, 256, 1 };
28094  unsigned int slice;
28095  int i;
28096  int ret_string_len;
28097  char *res_p_str;
28098 
28099  if (number == NULL || result_ip_string == NULL)
28100  {
28101  error_code = ER_OBJ_INVALID_ARGUMENTS;
28102  goto error;
28103  }
28104 
28105  if (DB_IS_NULL (number))
28106  {
28107  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OPFUNC_INET_NTOA_ARG, 1, (long long int) ip_number);
28108  error_code = ER_OPFUNC_INET_NTOA_ARG;
28109  goto error;
28110  }
28111 
28112  number_type = DB_VALUE_DOMAIN_TYPE (number);
28113  if (number_type != DB_TYPE_BIGINT)
28114  {
28115  error_code = ER_QSTR_INVALID_DATA_TYPE;
28116  goto error;
28117  }
28118 
28119  ip_number = db_get_bigint (number);
28120  if (ip_number > ipmax || ip_number < 0)
28121  {
28122  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OPFUNC_INET_NTOA_ARG, 1, (long long int) ip_number);
28123  error_code = ER_OPFUNC_INET_NTOA_ARG;
28124  goto error;
28125  }
28126 
28127  for (i = 0; i < 4; i++)
28128  {
28129  slice = (ip_number & ipv4_mask[i]) / ipfactor[i];
28130  snprintf (ip_seg_string, ip_seg_string_cnt, "%u", slice);
28131  /* safe to use strcat rather than strncat */
28132  strcat (ip_string, ip_seg_string);
28133  if (i != 3)
28134  {
28135  strcat (ip_string, ".");
28136  }
28137  }
28138 
28139  /* return string */
28140  ret_string_len = strlen (ip_string);
28141  res_p_str = (char *) db_private_alloc (NULL, ret_string_len + 1);
28142  if (res_p_str == NULL)
28143  {
28144  error_code = ER_OUT_OF_VIRTUAL_MEMORY;
28145  goto error;
28146  }
28147  memcpy (res_p_str, ip_string, ret_string_len + 1);
28148  db_make_string (result_ip_string, res_p_str);
28149  result_ip_string->need_clear = true;
28150 
28151  return NO_ERROR;
28152 
28153 error:
28154  db_make_null (result_ip_string);
28155 
28157  {
28158  er_clear ();
28159  return NO_ERROR;
28160  }
28161  return error_code;
28162 }
28163 
28164 /*
28165  * is_valid_ip_slice () - check whether ip slice is valid
28166  *
28167  * Arguments:
28168  * ipslice (in) : IP slice
28169  *
28170  * Returns: true or false
28171  */
28172 static bool
28173 is_valid_ip_slice (const char *ipslice)
28174 {
28175  int pos = 0;
28176  int base_type = 10; /* base type can be 8(oct), 10(dec), 16(hex) */
28177 
28178  assert (ipslice != NULL);
28179  if (ipslice[0] == '\0')
28180  {
28181  return false;
28182  }
28183 
28184  if (ipslice[0] == '0')
28185  {
28186  if (char_tolower (ipslice[1]) == 'x')
28187  {
28188  if (ipslice[2] == '\0')
28189  {
28190  return false;
28191  }
28192  base_type = 16;
28193  pos = 2;
28194  }
28195  else if (ipslice[1] != '\0')
28196  {
28197  base_type = 8;
28198  pos = 1;
28199  }
28200  }
28201 
28202  while (ipslice[pos] != '\0')
28203  {
28204  if (base_type == 10)
28205  {
28206  if (!char_isdigit (ipslice[pos]))
28207  {
28208  return false;
28209  }
28210  }
28211  else if (base_type == 8)
28212  {
28213  if (!('0' <= ipslice[pos] && ipslice[pos] <= '7'))
28214  {
28215  return false;
28216  }
28217  }
28218  else
28219  { /* base_type = 16 */
28220  if (!char_isxdigit (ipslice[pos]))
28221  {
28222  return false;
28223  }
28224  }
28225  pos++;
28226  }
28227 
28228  return true;
28229 }
28230 
28231 /*
28232  * db_get_date_format () -
28233  * Returns: error number
28234  * format_str(in):
28235  * format(in/out):
28236  *
28237  */
28238 int
28239 db_get_date_format (const DB_VALUE * format_str, TIMESTAMP_FORMAT * format)
28240 {
28241  const char *fmt_str_ptr, *next_fmt_str_ptr, *last_fmt;
28242  INTL_CODESET codeset;
28243  char stack_buf_format[64];
28244  char *initial_buf_format = NULL;
28245  bool do_free_buf_format = false;
28246  int format_size;
28247  int error = NO_ERROR;
28248 
28249  assert (format_str != NULL);
28250  assert (format != NULL);
28251 
28252  if (DB_IS_NULL (format_str))
28253  {
28254  *format = DT_INVALID;
28255  goto end;
28256  }
28257 
28258  if (is_char_string (format_str) == false)
28259  {
28260  error = ER_QSTR_INVALID_DATA_TYPE;
28261  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
28262  *format = DT_INVALID;
28263  goto end;
28264  }
28265 
28266  if (db_get_string_size (format_str) == 0)
28267  {
28268  error = ER_QSTR_EMPTY_STRING;
28269  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
28270  *format = DT_INVALID;
28271  goto end;
28272  }
28273 
28274  if (db_get_string_size (format_str) > MAX_TOKEN_SIZE)
28275  {
28276  error = ER_QSTR_SRC_TOO_LONG;
28277  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
28278  *format = DT_INVALID;
28279  goto end;
28280  }
28281 
28282  codeset = db_get_string_codeset (format_str);
28283 
28284  error =
28285  db_check_or_create_null_term_string (format_str, stack_buf_format, sizeof (stack_buf_format), true, true,
28286  &initial_buf_format, &do_free_buf_format);
28287  if (error != NO_ERROR)
28288  {
28289  *format = DT_INVALID;
28290  goto end;
28291  }
28292 
28293  fmt_str_ptr = initial_buf_format;
28294  last_fmt = fmt_str_ptr + strlen (fmt_str_ptr);
28295  /* Skip space, tab, CR */
28296  while (fmt_str_ptr < last_fmt && strchr (WHITE_CHARS, *fmt_str_ptr))
28297  {
28298  fmt_str_ptr++;
28299  }
28300 
28301  next_fmt_str_ptr = NULL;
28302  *format = get_next_format (fmt_str_ptr, codeset, DB_TYPE_DATETIME, &format_size, &next_fmt_str_ptr);
28303 
28304  if (next_fmt_str_ptr != NULL && *next_fmt_str_ptr != 0)
28305  {
28306  error = ER_QSTR_INVALID_FORMAT;
28307  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
28308  *format = DT_INVALID;
28309  goto end;
28310  }
28311 
28312 end:
28313  if (do_free_buf_format)
28314  {
28315  assert (initial_buf_format != NULL);
28316  db_private_free (NULL, initial_buf_format);
28317  }
28318 
28319  return error;
28320 }
28321 
28322 /*
28323  * db_get_cs_coll_info() - get codeset or collation from a value
28324  *
28325  * return: status
28326  * result(out): result (string type)
28327  * val(in): input value
28328  * mode(in): 0 : get charset, 1 : get collation
28329  *
28330  */
28331 int
28332 db_get_cs_coll_info (DB_VALUE * result, const DB_VALUE * val, const int mode)
28333 {
28334  int status = NO_ERROR;
28335 
28336  assert (result != NULL);
28337  assert (val != NULL);
28338 
28339  if (DB_IS_NULL (val))
28340  {
28341  db_make_null (result);
28342  }
28343  else if (!TP_TYPE_HAS_COLLATION (DB_VALUE_TYPE (val)))
28344  {
28346  {
28347  er_clear ();
28348  db_make_null (result);
28349  }
28350  else
28351  {
28352  status = ER_OBJ_INVALID_ARGUMENTS;
28353  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, status, 0);
28354  }
28355  }
28356  else
28357  {
28358  int cs, coll;
28359 
28360  if (TP_IS_CHAR_TYPE (DB_VALUE_TYPE (val)))
28361  {
28362  cs = db_get_string_codeset (val);
28363  coll = db_get_string_collation (val);
28364  }
28365  else
28366  {
28368  cs = db_get_enum_codeset (val);
28369  coll = db_get_enum_collation (val);
28370  }
28371 
28372  if (mode == 0)
28373  {
28375  }
28376  else
28377  {
28378  assert (mode == 1);
28379  db_make_string (result, lang_get_collation_name (coll));
28380  }
28381  }
28382 
28383  return status;
28384 }
28385 
28386 /*
28387  * db_string_index_prefix () -
28388  */
28389 int
28390 db_string_index_prefix (const DB_VALUE * string1, const DB_VALUE * string2, const DB_VALUE * index_type,
28391  DB_VALUE * prefix_index)
28392 {
28393  int error_status = NO_ERROR;
28394  TP_DOMAIN key_domain;
28395  DB_VALUE db_cmp_res;
28396  int cmp_res;
28397 
28398  assert (string1 != (DB_VALUE *) NULL);
28399  assert (string2 != (DB_VALUE *) NULL);
28400  assert (index_type != (DB_VALUE *) NULL);
28401 
28402  if (DB_IS_NULL (string1) || DB_IS_NULL (string2) || DB_IS_NULL (index_type))
28403  {
28405  {
28407  }
28408  else if (QSTR_IS_BIT (DB_VALUE_DOMAIN_TYPE (string1)))
28409  {
28411  }
28412  else
28413  {
28415  }
28416  return error_status;
28417  }
28418 
28420  || !QSTR_IS_ANY_CHAR_OR_BIT (DB_VALUE_DOMAIN_TYPE (string2)) || !is_char_string (index_type))
28421  {
28422  error_status = ER_QSTR_INVALID_DATA_TYPE;
28423  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
28424  return error_status;
28425  }
28426 
28427  if ((qstr_get_category (string1) != qstr_get_category (string2))
28428  || (db_get_string_codeset (string1) != db_get_string_codeset (string2)))
28429  {
28430  error_status = ER_QSTR_INCOMPATIBLE_CODE_SETS;
28431  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
28432  return error_status;
28433  }
28434 
28435  key_domain.is_desc = false;
28436  if (strncasecmp (db_get_string (index_type), "d", 1) == 0)
28437  {
28438  key_domain.is_desc = true;
28439  }
28440 
28441  error_status = db_string_compare (string1, string2, &db_cmp_res);
28442  if (error_status != NO_ERROR)
28443  {
28444  return error_status;
28445  }
28446  cmp_res = db_get_int (&db_cmp_res);
28447  if ((key_domain.is_desc && cmp_res <= 0) || (!key_domain.is_desc && cmp_res >= 0))
28448  {
28449  error_status = ER_OBJ_INVALID_ARGUMENTS;
28450  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
28451  return error_status;
28452  }
28453 
28454  error_status = db_string_unique_prefix (string1, string2, prefix_index, &key_domain);
28455 
28456  return error_status;
28457 }
28458 
28459 /*
28460  * db_string_to_base64 () - Using base64 to encode arbitrary input
28461  * return: int(NO_ERROR if successful, other error status if fail)
28462  * src(in): source which holds plain-text string
28463  * result(in/out): dest which holds encoded buffer
28464  *
28465  * Note: handling of special cases:
28466  * 1. source string is NULL, result is NULL
28467  * 2. source string is empty string, result is empty string
28468  */
28469 int
28470 db_string_to_base64 (DB_VALUE const *src, DB_VALUE * result)
28471 {
28472  int error_status, encode_len, src_len;
28473  const unsigned char *src_buf = NULL;
28474  unsigned char *encode_buf = NULL;
28475  DB_TYPE val_type;
28476 
28477  assert (src != (DB_VALUE *) NULL);
28478  assert (result != (DB_VALUE *) NULL);
28479 
28480  error_status = NO_ERROR;
28481 
28482  if (DB_IS_NULL (src))
28483  {
28484  db_make_null (result);
28485  return error_status;
28486  }
28487 
28488  src_buf = DB_GET_UCHAR (src);
28489 
28490  /* length in bytes */
28491  src_len = db_get_string_size (src);
28492 
28493  assert (src_len >= 0);
28494 
28495  /* if input is empty string, output is also empty string */
28496  if (src_len == 0)
28497  {
28498  error_status =
28500  db_get_string_collation (src));
28501  if (error_status != NO_ERROR)
28502  {
28503  assert_release (false);
28504  return error_status;
28505  }
28506  return NO_ERROR;
28507  }
28508 
28509  val_type = DB_VALUE_DOMAIN_TYPE (src);
28510  if (QSTR_IS_ANY_CHAR (val_type))
28511  {
28512  /* currently base64_encode always returns NO_ERROR except for memory buffer allocation fail */
28513  error_status = base64_encode (src_buf, src_len, &encode_buf, &encode_len);
28514 
28515  if (error_status == NO_ERROR)
28516  {
28517  qstr_make_typed_string (DB_TYPE_VARCHAR, result, encode_len, (char *) encode_buf, encode_len,
28519 
28520  result->need_clear = true;
28521 
28522  return NO_ERROR;
28523  }
28524  }
28525  else /* val_type != QSTR_IS_ANY_CHAR */
28526  {
28527  error_status = ER_QSTR_INVALID_DATA_TYPE; /* reset error code */
28528  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
28529  }
28530 
28532  {
28533  db_make_null (result);
28534  er_clear (); /* forget previous error */
28535  return NO_ERROR;
28536  }
28537  else
28538  {
28539  return error_status;
28540  }
28541 }
28542 
28543 /*
28544  * db_string_from_base64 () - Convert a buffer into plain-text by base64 decoding
28545  * There is no assumption the input is base64 encoded,
28546  * in this case, result is NULL
28547  * return: int(NO_ERROR if successful, other error status if fail)
28548  * src(in): source which holds encoded buffer
28549  * result(in/out): dest which holds plain-text string
28550  *
28551  * Note: handling of special cases:
28552  * 1. source string is NULL, result is NULL
28553  * 2. source string is empty string, result is empty string
28554  * 3. source string contains invalid base64 encoded character,
28555  * result is NULL
28556  * 4. source string has insufficient length even some bytes have been
28557  * decoded, result is NULL
28558  */
28559 int
28561 {
28562  int error_status, err, decode_len, src_len;
28563  const unsigned char *src_buf = NULL;
28564  unsigned char *decode_buf = NULL;
28565  DB_TYPE val_type;
28566 
28567  assert (src != (DB_VALUE *) NULL);
28568  assert (result != (DB_VALUE *) NULL);
28569 
28570  error_status = NO_ERROR;
28571 
28572  /* source is NULL */
28573  if (DB_IS_NULL (src))
28574  {
28575  db_make_null (result);
28576  return NO_ERROR;
28577  }
28578 
28579  src_buf = DB_GET_UCHAR (src);
28580 
28581  /* length in bytes */
28582  src_len = db_get_string_size (src);
28583 
28584  assert (src_len >= 0);
28585 
28586  /* source is empty string */
28587  if (src_len == 0)
28588  {
28589  error_status =
28591  db_get_string_collation (src));
28592  if (error_status != NO_ERROR)
28593  {
28594  assert_release (false);
28595  goto error_handling;
28596  }
28597  return NO_ERROR;
28598  }
28599 
28600  val_type = DB_VALUE_DOMAIN_TYPE (src);
28601 
28602  if (QSTR_IS_ANY_CHAR (val_type))
28603  {
28604  err = base64_decode (src_buf, src_len, &decode_buf, &decode_len);
28605 
28606  switch (err)
28607  {
28608  case BASE64_EMPTY_INPUT:
28609  error_status =
28611  db_get_string_collation (src));
28612  if (error_status != NO_ERROR)
28613  {
28614  assert_release (false);
28615  goto error_handling;
28616  }
28617  break;
28618 
28619  case NO_ERROR:
28620  qstr_make_typed_string (DB_TYPE_VARCHAR, result, decode_len, (char *) decode_buf, decode_len,
28622  result->need_clear = true;
28623  break;
28624 
28625  case BASE64_INVALID_INPUT:
28626  error_status = ER_QSTR_INVALID_FORMAT; /* reset error code */
28627  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
28628  goto error_handling;
28629 
28630  default:
28631  assert (er_errid () != NO_ERROR);
28632  error_status = err;
28633  goto error_handling;
28634  }
28635  }
28636  else /* val_type != QSTR_IS_ANY_CHAR */
28637  {
28638  error_status = ER_QSTR_INVALID_DATA_TYPE; /* reset error code */
28639  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
28640  goto error_handling;
28641  }
28642 
28643  assert (error_status == NO_ERROR);
28644  return error_status;
28645 
28646 error_handling:
28647 
28649  {
28650  db_make_null (result);
28651  er_clear (); /* forget previous error */
28652  return NO_ERROR;
28653  }
28654  else
28655  {
28656  return error_status;
28657  }
28658 }
28659 
28660 /*
28661  * db_string_extract_dbval () -
28662  * return: NO_ERROR, or ER_code
28663  * extr_operand(in) : Specifies datetime field to be extracted
28664  * dbval(in) : Extract source db_value node
28665  * res(out) : Resultant db_value node
28666  * domain(in) :
28667  *
28668  * Note: Extract a datetime field from db_value.
28669  */
28670 int
28671 db_string_extract_dbval (const MISC_OPERAND extr_operand, DB_VALUE * dbval_p, DB_VALUE * result_p, TP_DOMAIN * domain_p)
28672 {
28673  DB_TYPE dbval_type;
28674  DB_DATE date;
28675  DB_TIME time;
28676  DB_UTIME *utime;
28677  DB_DATETIME datetime, *datetime_p;
28678  DB_TIMESTAMPTZ *ts_tz_p;
28679  DB_DATETIMETZ *dt_tz_p;
28680  int extvar[NUM_MISC_OPERANDS];
28681  int err = NO_ERROR;
28682 
28683  dbval_type = DB_VALUE_DOMAIN_TYPE (dbval_p);
28684  if (TP_DOMAIN_TYPE (domain_p) == DB_TYPE_NULL || DB_IS_NULL (dbval_p))
28685  {
28686  return NO_ERROR;
28687  }
28688 
28689  switch (dbval_type)
28690  {
28691  case DB_TYPE_TIME:
28692  time = *db_get_time (dbval_p);
28693  db_time_decode (&time, &extvar[HOUR], &extvar[MINUTE], &extvar[SECOND]);
28694  break;
28695 
28696  case DB_TYPE_DATE:
28697  date = *db_get_date (dbval_p);
28698  db_date_decode (&date, &extvar[MONTH], &extvar[DAY], &extvar[YEAR]);
28699  break;
28700 
28701  case DB_TYPE_TIMESTAMP:
28702  case DB_TYPE_TIMESTAMPLTZ:
28703  utime = db_get_timestamp (dbval_p);
28704  (void) db_timestamp_decode_ses (utime, &date, &time);
28705 
28706  if (extr_operand == YEAR || extr_operand == MONTH || extr_operand == DAY)
28707  {
28708  db_date_decode (&date, &extvar[MONTH], &extvar[DAY], &extvar[YEAR]);
28709  }
28710  else
28711  {
28712  db_time_decode (&time, &extvar[HOUR], &extvar[MINUTE], &extvar[SECOND]);
28713  }
28714  break;
28715 
28716  case DB_TYPE_TIMESTAMPTZ:
28717  ts_tz_p = db_get_timestamptz (dbval_p);
28718  err = db_timestamp_decode_w_tz_id (&ts_tz_p->timestamp, &ts_tz_p->tz_id, &date, &time);
28719  if (err != NO_ERROR)
28720  {
28721  break;
28722  }
28723 
28724  if (extr_operand == YEAR || extr_operand == MONTH || extr_operand == DAY)
28725  {
28726  db_date_decode (&date, &extvar[MONTH], &extvar[DAY], &extvar[YEAR]);
28727  }
28728  else
28729  {
28730  db_time_decode (&time, &extvar[HOUR], &extvar[MINUTE], &extvar[SECOND]);
28731  }
28732  break;
28733 
28734  case DB_TYPE_DATETIME:
28735  datetime_p = db_get_datetime (dbval_p);
28736  db_datetime_decode (datetime_p, &extvar[MONTH], &extvar[DAY], &extvar[YEAR], &extvar[HOUR], &extvar[MINUTE],
28737  &extvar[SECOND], &extvar[MILLISECOND]);
28738  break;
28739 
28740  case DB_TYPE_DATETIMELTZ:
28741  datetime_p = db_get_datetime (dbval_p);
28742  err = tz_datetimeltz_to_local (datetime_p, &datetime);
28743  if (err != NO_ERROR)
28744  {
28745  break;
28746  }
28747 
28748  db_datetime_decode (&datetime, &extvar[MONTH], &extvar[DAY], &extvar[YEAR], &extvar[HOUR], &extvar[MINUTE],
28749  &extvar[SECOND], &extvar[MILLISECOND]);
28750  break;
28751 
28752  case DB_TYPE_DATETIMETZ:
28753  dt_tz_p = db_get_datetimetz (dbval_p);
28754  err = tz_utc_datetimetz_to_local (&dt_tz_p->datetime, &dt_tz_p->tz_id, &datetime);
28755  if (err != NO_ERROR)
28756  {
28757  break;
28758  }
28759  db_datetime_decode (&datetime, &extvar[MONTH], &extvar[DAY], &extvar[YEAR], &extvar[HOUR], &extvar[MINUTE],
28760  &extvar[SECOND], &extvar[MILLISECOND]);
28761  break;
28762  case DB_TYPE_CHAR:
28763  case DB_TYPE_VARCHAR:
28764  case DB_TYPE_NCHAR:
28765  case DB_TYPE_VARNCHAR:
28766  {
28767  DB_UTIME utime_s;
28768  DB_DATETIME datetime_s;
28769  const char *str_date = db_get_string (dbval_p);
28770  int str_date_len = db_get_string_size (dbval_p);
28771 
28772  switch (extr_operand)
28773  {
28774  case YEAR:
28775  case MONTH:
28776  case DAY:
28777  if (db_string_to_date_ex (str_date, str_date_len, &date) == NO_ERROR)
28778  {
28779  db_date_decode (&date, &extvar[MONTH], &extvar[DAY], &extvar[YEAR]);
28780  break;
28781  }
28782  if (db_string_to_timestamp_ex (str_date, str_date_len, &utime_s) == NO_ERROR)
28783  {
28784  (void) db_timestamp_decode_ses (&utime_s, &date, &time);
28785  db_date_decode (&date, &extvar[MONTH], &extvar[DAY], &extvar[YEAR]);
28786  break;
28787  }
28788  if (db_string_to_datetime_ex (str_date, str_date_len, &datetime_s) == NO_ERROR)
28789  {
28790  db_datetime_decode (&datetime_s, &extvar[MONTH], &extvar[DAY], &extvar[YEAR], &extvar[HOUR],
28791  &extvar[MINUTE], &extvar[SECOND], &extvar[MILLISECOND]);
28792  break;
28793  }
28794  /* no date/time can be extracted from string, error */
28797 
28798  case HOUR:
28799  case MINUTE:
28800  case SECOND:
28801  if (db_string_to_time_ex (str_date, str_date_len, &time) == NO_ERROR)
28802  {
28803  db_time_decode (&time, &extvar[HOUR], &extvar[MINUTE], &extvar[SECOND]);
28804  break;
28805  }
28806  if (db_string_to_timestamp_ex (str_date, str_date_len, &utime_s) == NO_ERROR)
28807  {
28808  (void) db_timestamp_decode_ses (&utime_s, &date, &time);
28809  db_time_decode (&time, &extvar[HOUR], &extvar[MINUTE], &extvar[SECOND]);
28810  break;
28811  }
28812  /* fall through */
28813  case MILLISECOND:
28814  if (db_string_to_datetime_ex (str_date, str_date_len, &datetime_s) == NO_ERROR)
28815  {
28816  db_datetime_decode (&datetime_s, &extvar[MONTH], &extvar[DAY], &extvar[YEAR], &extvar[HOUR],
28817  &extvar[MINUTE], &extvar[SECOND], &extvar[MILLISECOND]);
28818  break;
28819  }
28820  /* no date/time can be extracted from string, error */
28823 
28824  default:
28827  }
28828  }
28829  break;
28830 
28831  default:
28834  }
28835 
28836  if (err == NO_ERROR)
28837  {
28838  db_make_int (result_p, extvar[extr_operand]);
28839  }
28840  return err;
28841 }
28842 
28843 /*
28844  * db_new_time () - converts the time_val from the source_timezone into
28845  * the destination timezone
28846  *
28847  * return error code or NO_ERROR
28848  * time_val (in) : time value (datetime or time)
28849  * tz_source (in) : source timezone string
28850  * tz_dest (in) : dest timezone string
28851  * result_time (out) : result
28852  */
28853 int
28854 db_new_time (DB_VALUE * time_val, DB_VALUE * tz_source, DB_VALUE * tz_dest, DB_VALUE * result_time)
28855 {
28856  int error = NO_ERROR, len_source, len_dest;
28857  DB_DATETIME *datetime = NULL;
28858  DB_TIME *time = NULL;
28859  const char *t_source, *t_dest;
28860 
28861  /*
28862  * Assert that DB_VALUE structures have been allocated.
28863  */
28864  assert (time_val != (DB_VALUE *) NULL);
28865  assert (tz_source != (DB_VALUE *) NULL);
28866  assert (tz_dest != (DB_VALUE *) NULL);
28867  assert (result_time != (DB_VALUE *) NULL);
28868 
28869  if (DB_IS_NULL (time_val) || DB_IS_NULL (tz_source) || DB_IS_NULL (tz_dest))
28870  {
28871  db_make_null (result_time);
28872  return NO_ERROR;
28873  }
28874 
28875  t_source = db_get_string (tz_source);
28876  t_dest = db_get_string (tz_dest);
28877 
28878  len_source = db_get_string_size (tz_source);
28879  len_dest = db_get_string_size (tz_dest);
28880 
28881  if (len_source < 0)
28882  {
28883  len_source = strlen (t_source);
28884  }
28885  if (len_dest < 0)
28886  {
28887  len_dest = strlen (t_dest);
28888  }
28889 
28890  switch (DB_VALUE_TYPE (time_val))
28891  {
28892  case DB_TYPE_DATETIME:
28893  {
28894  DB_DATETIME result;
28895  int month, day, year, julian_date;
28896 
28897  datetime = db_get_datetime (time_val);
28898  db_date_decode (&(datetime->date), &month, &day, &year);
28899  julian_date = julian_encode (month, day, year);
28900  datetime->date = julian_date;
28901 
28902  error = tz_conv_tz_datetime_w_zone_name (datetime, t_source, len_source, t_dest, len_dest, &result);
28903 
28904  if (error != NO_ERROR)
28905  {
28906  return error;
28907  }
28908  db_make_datetime (result_time, &result);
28909  }
28910  break;
28911 
28912  case DB_TYPE_TIME:
28913  {
28914  DB_TIME time_res;
28915  int hour, min, sec;
28916 
28917  time = db_get_time (time_val);
28918  error = tz_conv_tz_time_w_zone_name (time, t_source, len_source, t_dest, len_dest, &time_res);
28919  if (error != NO_ERROR)
28920  {
28921  return error;
28922  }
28923  db_time_decode (&time_res, &hour, &min, &sec);
28924  db_make_time (result_time, hour, min, sec);
28925  }
28926  break;
28927 
28928  default:
28929  error = ER_QSTR_INVALID_DATA_TYPE;
28930  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
28931  break;
28932  }
28933 
28934  return error;
28935 }
28936 
28937 /*
28938  * db_tz_offset () - retrieve the timezone offset for src_str source timezone
28939  *
28940  * return: error or no error
28941  * src_str(in): source DB_VALUE timezone string or offset
28942  * date_time(in): current UTC datetime
28943  * result_str(out): result DB_VALUE string
28944  */
28945 
28946 int
28947 db_tz_offset (const DB_VALUE * src_str, DB_VALUE * result_str, DB_DATETIME * datetime)
28948 {
28949  int error_status = NO_ERROR;
28950  DB_TYPE str_type;
28951  char *res;
28952 
28953  /*
28954  * Assert that DB_VALUE structures have been allocated.
28955  */
28956  assert (src_str != (DB_VALUE *) NULL);
28957  assert (result_str != (DB_VALUE *) NULL);
28958 
28959  /*
28960  * Categorize the two input parameters and check for errors.
28961  * Verify that the parameters are both character strings.
28962  */
28963 
28964  str_type = DB_VALUE_DOMAIN_TYPE (src_str);
28965  if (DB_IS_NULL (src_str))
28966  {
28967  db_make_null (result_str);
28968  }
28969  else if (!QSTR_IS_CHAR (str_type))
28970  {
28971  error_status = ER_QSTR_INVALID_DATA_TYPE;
28972  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 0);
28973  }
28974  /*
28975  * If the input parameters have been properly validated, then
28976  * we are ready to operate.
28977  */
28978  else
28979  {
28980  int len = db_get_string_size (src_str);
28981  if (len < 0)
28982  {
28983  len = strlen (db_get_string (src_str));
28984  }
28985 
28986  res = (char *) db_private_alloc (NULL, MAX_LEN_OFFSET);
28987  if (res == NULL)
28988  {
28989  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
28990  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_status, 1, (size_t) 0);
28991  return error_status;
28992  }
28993 
28994  error_status = tz_get_timezone_offset (db_get_string (src_str), len, res, datetime);
28995  if (error_status == NO_ERROR)
28996  {
28999  result_str->need_clear = true;
29000  }
29001  else
29002  {
29003  db_private_free (NULL, res);
29004  }
29005  }
29006 
29007  return error_status;
29008 }
29009 
29010 /*
29011  * db_from_tz () - adds timezone information to the time_val
29012  * Return: error code or NO_ERROR
29013  * time_val (in) : time value (datetime, time or timestamp)
29014  * tz (in) : timezone string
29015  * time_val_with_tz (out) : timeval with timezone information
29016  */
29017 
29018 int
29019 db_from_tz (DB_VALUE * time_val, DB_VALUE * tz, DB_VALUE * time_val_with_tz)
29020 {
29021  const char *timezone_str = NULL;
29022  int len_timezone, error = NO_ERROR;
29023  DB_DATETIME *datetime = NULL;
29024 
29025  /*
29026  * Assert that DB_VALUE structures have been allocated.
29027  */
29028  assert (time_val != (DB_VALUE *) NULL);
29029  assert (tz != (DB_VALUE *) NULL);
29030  assert (time_val_with_tz != (DB_VALUE *) NULL);
29031 
29032  if (DB_IS_NULL (time_val) || DB_IS_NULL (tz))
29033  {
29034  db_make_null (time_val_with_tz);
29035  return NO_ERROR;
29036  }
29037 
29038  timezone_str = db_get_string (tz);
29039  len_timezone = db_get_string_size (tz);
29040 
29041  if (len_timezone < 0)
29042  {
29043  len_timezone = strlen (timezone_str);
29044  }
29045 
29046  switch (DB_VALUE_TYPE (time_val))
29047  {
29048  case DB_TYPE_DATETIME:
29049  {
29050  DB_DATETIMETZ result;
29051  TZ_REGION region;
29052 
29053  datetime = db_get_datetime (time_val);
29054  error = tz_str_to_region (timezone_str, len_timezone, &region);
29055  if (error != NO_ERROR)
29056  {
29057  return error;
29058  }
29059  error = tz_create_datetimetz (datetime, NULL, 0, &region, &result, NULL);
29060  if (error != NO_ERROR)
29061  {
29062  return error;
29063  }
29064  db_make_datetimetz (time_val_with_tz, &result);
29065  }
29066  break;
29067 
29068  default:
29069  error = ER_QSTR_INVALID_DATA_TYPE;
29070  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
29071  break;
29072  }
29073 
29074  return error;
29075 }
29076 
29077 /*
29078 * parse_tzd() - finds the length of the daylight saving time information
29079 * It stops either on first non alpha-numeric or when expected
29080 * length is reached.
29081 *
29082 * Returns length of daylight
29083 * str(in): string to search in
29084 * max_expect_len(in): maximum length to expected
29085 */
29086 static int
29087 parse_tzd (const char *str, const int max_expect_len)
29088 {
29089  const char *p;
29090 
29091  assert (max_expect_len > 1);
29092 
29093  p = str;
29094  if (*p == '-' || *p == '+')
29095  {
29096  p++;
29097  }
29098  while (p < str + max_expect_len && char_isalnum (*p))
29099  {
29100  p++;
29101  }
29102 
29103  return CAST_BUFLEN (p - str);
29104 }
29105 
29106 /*
29107  * db_conv_tz () - Converts a timezone data type from one timezone library to another
29108  *
29109  * return ERROR or NO_ERROR
29110  * time_val (in) : time value (datetimetz, datetimeltz, timestamptz, timestampltz)
29111  * result_time (out) : result
29112  *
29113  */
29114 int
29115 db_conv_tz (DB_VALUE * time_val, DB_VALUE * result_time)
29116 {
29117  int error = NO_ERROR;
29118  DB_DATETIMETZ *datetimetz = NULL;
29119  DB_DATETIME *datetime = NULL;
29120  DB_TIMESTAMPTZ *timestamptz = NULL;
29121  DB_TIMESTAMP *timestamp = NULL;
29122 
29123  /*
29124  * Assert that DB_VALUE structures have been allocated.
29125  */
29126  assert (time_val != (DB_VALUE *) NULL);
29127  assert (result_time != (DB_VALUE *) NULL);
29128 
29129  if (DB_IS_NULL (time_val))
29130  {
29131  db_make_null (result_time);
29132  return NO_ERROR;
29133  }
29134 
29135  switch (DB_VALUE_TYPE (time_val))
29136  {
29137  case DB_TYPE_DATETIMETZ:
29138  {
29139  DB_DATETIMETZ datetimetz_out;
29140 
29141  datetimetz = db_get_datetimetz (time_val);
29142 
29143  error = conv_tz (&datetimetz_out, datetimetz, DB_TYPE_DATETIMETZ);
29144  if (error != NO_ERROR)
29145  {
29146  return error;
29147  }
29148  db_make_datetimetz (result_time, &datetimetz_out);
29149  }
29150  break;
29151 
29152  case DB_TYPE_DATETIMELTZ:
29153  {
29154  DB_DATETIME datetime_out;
29155 
29156  datetime = db_get_datetime (time_val);
29157 
29158  error = conv_tz (&datetime_out, datetime, DB_TYPE_DATETIMELTZ);
29159  if (error != NO_ERROR)
29160  {
29161  return error;
29162  }
29163  db_make_datetimeltz (result_time, &datetime_out);
29164  }
29165  break;
29166 
29167  case DB_TYPE_TIMESTAMPTZ:
29168  {
29169  DB_TIMESTAMPTZ timestamptz_out;
29170 
29171  timestamptz = db_get_timestamptz (time_val);
29172 
29173  error = conv_tz (&timestamptz_out, timestamptz, DB_TYPE_TIMESTAMPTZ);
29174  if (error != NO_ERROR)
29175  {
29176  return error;
29177  }
29178  db_make_timestamptz (result_time, &timestamptz_out);
29179  }
29180  break;
29181 
29182  case DB_TYPE_TIMESTAMPLTZ:
29183  {
29184  DB_TIMESTAMP timestamp_out;
29185 
29186  timestamp = db_get_timestamp (time_val);
29187 
29188  error = conv_tz (&timestamp_out, timestamp, DB_TYPE_TIMESTAMPLTZ);
29189  if (error != NO_ERROR)
29190  {
29191  return error;
29192  }
29193  db_make_timestampltz (result_time, timestamp_out);
29194  }
29195  break;
29196 
29197  default:
29198  error = ER_QSTR_INVALID_DATA_TYPE;
29199  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
29200  break;
29201  }
29202 
29203  return error;
29204 }
static int end_day(void *data, const char *el_name)
int julian_encode(int m, int d, int y)
Definition: db_date.c:113
#define QSTR_DATE_LENGTH
unsigned int TZ_ID
Definition: dbtype_def.h:756
int db_inet_ntoa(DB_VALUE *result_ip_string, const DB_VALUE *number)
DB_C_FLOAT db_get_float(const DB_VALUE *value)
int char_isspace(int c)
Definition: chartype.c:109
const char * month_short_parse_order
struct db_domain_info::char_info char_info
int db_compress_like_pattern(const DB_VALUE *const pattern, DB_VALUE *compressed_pattern, const bool has_escape_char, const char *escape_str)
int db_date_format(const DB_VALUE *date_value, const DB_VALUE *format, const DB_VALUE *date_lang, DB_VALUE *result, const TP_DOMAIN *domain)
int tz_create_session_tzid_for_time(const DB_TIME *src_time, bool src_is_utc, TZ_ID *tz_id)
Definition: tz_support.c:1091
#define TP_IS_DATE_OR_TIME_TYPE(typeid)
int db_time_format(const DB_VALUE *src_value, const DB_VALUE *format, const DB_VALUE *date_lang, DB_VALUE *result, const TP_DOMAIN *domain)
const char * month_name[CAL_MONTH_COUNT]
int bit_compare(const unsigned char *string1, int size1, const unsigned char *string2, int size2)
unsigned char * qstr_pad_string(unsigned char *s, int length, INTL_CODESET codeset)
#define DB_GET_STRING_PRECISION(v)
Definition: dbtype.h:139
int db_make_datetime(DB_VALUE *value, const DB_DATETIME *datetime)
int intl_lower_string(const ALPHABET_DATA *alphabet, const unsigned char *src, unsigned char *dst, int length_in_chars)
int db_find_string_in_in_set(const DB_VALUE *needle, const DB_VALUE *stack, DB_VALUE *result)
char * trim(char *str)
Definition: porting.c:2260
int db_get_info_for_like_optimization(const DB_VALUE *const pattern, const bool has_escape_char, const char *escape_str, int *const num_logical_chars, int *const last_safe_logical_pos, int *const num_match_many, int *const num_match_one)
int db_value_coerce(const DB_VALUE *src, DB_VALUE *dest, const DB_DOMAIN *desired_domain)
Definition: db_macro.c:1779
#define NO_ERROR
Definition: error_code.h:46
#define QSTR_IS_LIKE_WILDCARD_CHAR(ch)
static long calc_unix_timestamp(struct tm *time_argument)
int db_get_date_weekday(const DB_VALUE *src_date, const int mode, DB_VALUE *result)
int db_get_date_quarter(const DB_VALUE *src_date, DB_VALUE *result)
int db_get_date_totaldays(const DB_VALUE *src_date, DB_VALUE *result)
void qstr_trim_trailing(const unsigned char *trim_charset_ptr, int trim_charset_size, const unsigned char *src_ptr, DB_TYPE src_type, int src_length, int src_size, INTL_CODESET codeset, int *trail_trimmed_length, int *trail_trimmed_size, bool trim_ascii_spaces)
char buf[DB_SMALL_CHAR_BUF_SIZE]
Definition: dbtype_def.h:991
#define LANG_SYS_COLLATION
#define LANG_GET_BINARY_COLLATION(c)
int db_string_space(DB_VALUE const *count, DB_VALUE *result)
#define ER_TP_CANT_COERCE_OVERFLOW
Definition: error_code.h:251
unsigned char codeset
Definition: dbtype_def.h:980
static int qstr_bit_position(const unsigned char *sub_string, int sub_length, const unsigned char *src_string, int src_length, int *position)
int db_timestamptz_to_string(char *buf, int bufsize, DB_TIMESTAMP *utime, const TZ_ID *tz_id)
Definition: db_date.c:4090
#define TZD_DEFAULT_EXPECTED_LEN
static int bstring_fls(const char *s, int n)
int db_get_week_of_year(int year, int month, int day, int mode)
Definition: db_date.c:4854
int db_value_domain_min(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale, const int codeset, const int collation_id, const DB_ENUMERATION *enumeration)
Definition: db_macro.c:413
int db_elo_write(DB_ELO *elo, off_t pos, const void *buf, size_t count, DB_BIGINT *written_bytes)
Definition: db_elo.c:177
#define ASSERT_ERROR()
#define LEAP(y)
Definition: string_opfunc.c:90
#define db_locate_numeric(value)
int intl_pad_size(INTL_CODESET codeset)
int get_day(int month, int day, int year)
static int db_string_prefix_compare(const DB_VALUE *string1, const DB_VALUE *string2, DB_VALUE *result)
static int add_and_normalize_date_time(int *years, int *months, int *days, int *hours, int *minutes, int *seconds, int *milliseconds, DB_BIGINT y, DB_BIGINT m, DB_BIGINT d, DB_BIGINT h, DB_BIGINT mi, DB_BIGINT s, DB_BIGINT ms)
#define QSTR_IS_ANY_CHAR(s)
Definition: string_opfunc.h:46
void qstr_make_typed_string(const DB_TYPE db_type, DB_VALUE *value, const int precision, DB_CONST_C_CHAR src, const int s_unit, const int codeset, const int collation_id)
const char * Short_Day_name_ISO[][7]
static int lob_from_file(const char *path, const DB_VALUE *src_value, DB_VALUE *lob_value, DB_TYPE lob_type)
int db_string_unique_prefix(const DB_VALUE *db_string1, const DB_VALUE *db_string2, DB_VALUE *db_result, TP_DOMAIN *key_domain)
static QSTR_CATEGORY qstr_get_category(const DB_VALUE *s)
const char * Short_Day_name_EUCKR[][7]
DB_CONST_C_BIT db_get_bit(const DB_VALUE *value, int *length)
int char_tolower(int c)
Definition: chartype.c:146
int db_bigint_to_binary_string(const DB_VALUE *src_bigint, DB_VALUE *result)
DB_CONST_C_NCHAR db_get_nchar(const DB_VALUE *value, int *length)
#define DB_MAX_STRING_LENGTH
Definition: dbtype_def.h:516
int db_bit_string_coerce(const DB_VALUE *src_string, DB_VALUE *dest_string, DB_DATA_STATUS *data_status)
int db_add_int_to_datetime(DB_DATETIME *datetime, DB_BIGINT bi2, DB_DATETIME *result_datetime)
Definition: db_date.c:4656
int db_date_to_string(char *buf, int bufsize, DB_DATE *date)
Definition: db_date.c:3953
int db_string_chr(DB_VALUE *res, DB_VALUE *dbval1, DB_VALUE *dbval2)
int db_get_date_format(const DB_VALUE *format_str, TIMESTAMP_FORMAT *format)
#define ER_ES_INVALID_PATH
Definition: error_code.h:1272
int db_string_index_prefix(const DB_VALUE *string1, const DB_VALUE *string2, const DB_VALUE *index_type, DB_VALUE *prefix_index)
int db_make_bigint(DB_VALUE *value, const DB_BIGINT num)
int db_get_int(const DB_VALUE *value)
static int lob_length(const DB_VALUE *src_value, DB_VALUE *result_value)
DB_TIMESTAMP timestamp
Definition: dbtype_def.h:766
int db_string_insert_substring(DB_VALUE *src_string, const DB_VALUE *position, const DB_VALUE *length, DB_VALUE *sub_string, DB_VALUE *result)
int db_string_regexp_replace(DB_VALUE *result, DB_VALUE *args[], int const num_args, cub_regex_object **comp_regex, char **comp_pattern)
DB_TYPE
Definition: dbtype_def.h:670
#define INTL_NEXT_CHAR(ptr, s, codeset, current_char_size)
Definition: intl_support.h:99
int parse_int(int *ret_p, const char *str_p, int base)
Definition: porting.c:2290
static bool is_safe_last_char_for_like_optimization(const char *chr, const bool is_escaped, INTL_CODESET codeset)
int tz_create_datetimetz_from_ses(const DB_DATETIME *dt, DB_DATETIMETZ *dt_tz)
Definition: tz_support.c:1493
DB_C_DOUBLE db_get_double(const DB_VALUE *value)
#define ER_FAILED
Definition: error_code.h:47
void numeric_coerce_num_to_double(DB_C_NUMERIC num, int scale, double *adouble)
int db_char_to_blob(const DB_VALUE *src_value, DB_VALUE *result_value)
int db_make_varchar(DB_VALUE *value, const int max_char_length, DB_CONST_C_CHAR str, const int char_str_byte_size, const int codeset, const int collation_id)
#define ER_DATE_EXCEED_LIMIT
Definition: error_code.h:973
int db_new_time(DB_VALUE *time_val, DB_VALUE *tz_source, DB_VALUE *tz_dest, DB_VALUE *result_time)
int db_datetime_decode(const DB_DATETIME *datetime, int *month, int *day, int *year, int *hour, int *minute, int *second, int *millisecond)
Definition: db_date.c:4574
int db_convert_sec_to_time(const DB_VALUE *src, DB_VALUE *result)
int db_get_string_collation(const DB_VALUE *value)
#define ABS(i)
Definition: string_opfunc.c:86
static int db_get_next_like_pattern_character(const char *const pattern, const int length, const INTL_CODESET codeset, const bool has_escape_char, const char *escape_str, int *const position, char **crt_char_p, bool *const is_escaped)
static char db_string_escape_char(char c)
#define LOC_MAX_UCA_CHARS_SEQ
static bool varbit_truncated(const unsigned char *s, int s_length, int used_bits)
DB_ELO_TYPE type
Definition: dbtype_def.h:950
int db_timestamp_encode_ses(const DB_DATE *date, const DB_TIME *timeval, DB_TIMESTAMP *utime, TZ_ID *dest_tz_id)
Definition: db_date.c:597
#define ER_QSTR_INVALID_ESCAPE_SEQUENCE
Definition: error_code.h:748
int crypt_sha_two(THREAD_ENTRY *thread_p, const char *src, int src_len, int need_hash_len, char **dest_p, int *dest_len_p)
Definition: crypt_opfunc.c:490
int db_string_fix_string_size(DB_VALUE *src_string)
static void left_nshift(const unsigned char *bit_string, int bit_string_size, int shift_amount, unsigned char *r, int r_size)
static int db_date_add_sub_interval_expr(DB_VALUE *result, const DB_VALUE *date, const DB_VALUE *expr, const int unit, int is_add)
TP_DOMAIN_STATUS tp_value_auto_cast(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain)
int tz_create_datetimetz_from_offset(const DB_DATETIME *dt, const int tzh, const int tzm, DB_DATETIMETZ *dt_tz)
Definition: tz_support.c:4068
int tz_create_datetimetz_from_zoneid_and_tzd(const DB_DATETIME *dt, TZ_REGION *default_tz_region, const int zone_id, const char *tzd, const int tzd_len, bool is_time_tz, DB_DATETIMETZ *dt_tz)
Definition: tz_support.c:4212
int count_nonleap_years_up_to(int year)
int db_get_enum_codeset(const DB_VALUE *value)
int db_guid(THREAD_ENTRY *thread_p, DB_VALUE *result)
const char * lang_date_format_parse(const INTL_LANG lang_id, const INTL_CODESET codeset, const DB_TYPE type, INTL_CODESET *format_codeset)
int tz_create_timestamptz_from_offset(const DB_DATE *date, const DB_TIME *time, const int tzh, const int tzm, DB_TIMESTAMPTZ *timestamp_tz)
Definition: tz_support.c:4107
void tz_get_session_tz_region(TZ_REGION *tz_region)
Definition: tz_support.c:767
#define assert_release(e)
Definition: error_manager.h:96
int db_create_fbo(DB_VALUE *value, DB_TYPE type)
Definition: db_elo.c:47
ALPHABET_DATA alphabet
#define QSTR_MAX_PRECISION(str_type)
Definition: string_opfunc.c:81
#define ER_QSTR_INVALID_DATA_TYPE
Definition: error_code.h:746
int varbit_compare(const unsigned char *string1, int size1, const unsigned char *string2, int size2)
int db_subtract_int_from_datetime(DB_DATETIME *dt1, DB_BIGINT bi2, DB_DATETIME *result_datetime)
Definition: db_date.c:4612
int db_get_time_from_dbvalue(const DB_VALUE *src_date, int *hour, int *minute, int *second, int *millisecond)
const char * am_pm[CAL_AM_PM_COUNT]
static int make_number(char *src, char *last_src, INTL_CODESET codeset, char *token, int *token_length, DB_VALUE *r, const int precision, const int scale, const INTL_LANG number_lang_id)
void intl_binary_to_euckr(const unsigned char *in_buf, const int in_size, unsigned char **out_buf, int *out_size)
int db_timestampltz_to_string(char *buf, int bufsize, DB_TIMESTAMP *utime)
Definition: db_date.c:4146
static int qstr_pad(MISC_OPERAND pad_operand, int pad_length, const unsigned char *pad_charset_ptr, int pad_charset_length, int pad_charset_size, const unsigned char *src_ptr, DB_TYPE src_type, int src_length, int src_size, INTL_CODESET codeset, unsigned char **result, DB_TYPE *result_type, int *result_length, int *result_size)
#define ZERO
INTL_LANG lang_get_lang_id_from_flag(const int flag, bool *has_user_format, bool *has_user_lang)
int db_string_reverse(const DB_VALUE *src_str, DB_VALUE *result_str)
#define UINT64_MAX_HEX_DIGITS
Definition: string_opfunc.c:93
int db_string_to_datetime_ex(const char *str, int str_len, DB_DATETIME *datetime)
Definition: db_date.c:4414
int tz_create_datetimetz_from_parts(const int m, const int d, const int y, const int h, const int mi, const int s, const int ms, const TZ_ID *tz_id, DB_DATETIMETZ *dt_tz)
Definition: tz_support.c:5138
int tz_create_timestamptz_from_zoneid_and_tzd(const DB_DATE *date, const DB_TIME *time, TZ_REGION *default_tz_region, const int zone_id, const char *tzd, const int tzd_len, DB_TIMESTAMPTZ *timestamp_tz)
Definition: tz_support.c:4280
#define SPACE()
#define DB_NUMERIC_E38_MAX
#define QSTR_SPLIT_KEY(id, is_desc, str1, size1, str2, size2, k, s, ti)
Definition: string_opfunc.h:78
int db_make_date(DB_VALUE *value, const int month, const int day, const int year)
static int get_string_date_token_id(const STRING_DATE_TOKEN token_type, const INTL_LANG intl_lang_id, const char *cs, const INTL_CODESET codeset, int *token_id, int *token_size)
#define ER_QSTR_FORMAT_DUPLICATION
Definition: error_code.h:980
DB_DATETIMETZ * db_get_datetimetz(const DB_VALUE *value)
DB_CONST_C_CHAR db_get_char(const DB_VALUE *value, int *length)
int db_make_datetimeltz(DB_VALUE *value, const DB_DATETIME *datetime)
static int qstr_translate(const unsigned char *src_ptr, DB_TYPE src_type, int src_size, INTL_CODESET codeset, const unsigned char *from_str_ptr, int from_str_size, const unsigned char *to_str_ptr, int to_str_size, unsigned char **result_ptr, DB_TYPE *result_type, int *result_len, int *result_size)
int db_string_from_base64(DB_VALUE const *src, DB_VALUE *result)
const char Short_Month_name_parse_order[][12]
const char * Short_Month_name_ISO[][12]
#define ES_LOCAL_PATH_PREFIX
Definition: es_common.h:38
#define CAST_STRLEN
Definition: porting.h:470
#define TP_IS_STRING_TYPE(typeid)
int db_string_to_timestamptz_ex(const char *str, int str_len, DB_TIMESTAMPTZ *ts_tz, bool *has_zone, bool is_cast)
Definition: db_date.c:3820
int db_string_to_timestamp_ex(const char *str, int str_len, DB_TIMESTAMP *utime)
Definition: db_date.c:3755
#define ER_QSTR_BAD_SRC_CODESET
Definition: error_code.h:744
int tz_conv_tz_time_w_zone_name(const DB_TIME *time_source, const char *source_zone, int len_source, const char *dest_zone, int len_dest, DB_TIME *time_dest)
Definition: tz_support.c:1528
const char * month_short_name[CAL_MONTH_COUNT]
#define diff
Definition: mprec.h:352
int er_errid(void)
static int qstr_substring(const unsigned char *src, int src_length, int start, int length, INTL_CODESET codeset, unsigned char **r, int *r_length, int *r_size)
int db_time_dbval(DB_VALUE *result, const DB_VALUE *datetime_value, const TP_DOMAIN *domain)
int db_from_unixtime(const DB_VALUE *src_value, const DB_VALUE *format, const DB_VALUE *date_lang, DB_VALUE *result, const TP_DOMAIN *domain)
int db_string_sha_one(DB_VALUE const *src, DB_VALUE *result)
double db_value_get_monetary_amount_as_double(const DB_VALUE *value)
Definition: db_macro.c:1505
#define ER_TIMESTAMP_CONVERSION
Definition: error_code.h:982
const char * Month_name_UTF8[][12]
static int roundoff(const INTL_LANG lang, char *src_string, int flag, int *cipher, char *format)
int db_to_timestamp(const DB_VALUE *src_str, const DB_VALUE *format_str, const DB_VALUE *date_lang, const DB_TYPE type, DB_VALUE *result_timestamp)
#define ER_QSTR_INVALID_FORMAT
Definition: error_code.h:977
#define DB_VALUE_PRECISION(value)
Definition: dbtype.h:73
static int lob_to_bit_char(const DB_VALUE *src_value, DB_VALUE *result_value, DB_TYPE lob_type, int max_length)
static int qstr_ffs(int v)
char lang_digit_fractional_symbol(const INTL_LANG lang_id)
int db_add_time(const DB_VALUE *left, const DB_VALUE *right, DB_VALUE *result, const TP_DOMAIN *domain)
enum tp_domain_status TP_DOMAIN_STATUS
bool intl_is_space(const char *str, const char *str_end, const INTL_CODESET codeset, int *space_size)
unsigned char style
Definition: dbtype_def.h:979
const unsigned char * intl_prev_char(const unsigned char *s, const unsigned char *s_start, INTL_CODESET codeset, int *prev_char_size)
int intl_case_match_tok(const INTL_LANG lang_id, const INTL_CODESET codeset, unsigned char *tok, unsigned char *src, const int size_tok, const int size_src, int *matched_size_src)
static int get_number_token(const INTL_LANG lang, char *fsp, int *length, char *last_position, char **next_fsp, INTL_CODESET codeset)
bool intl_is_max_bound_chr(INTL_CODESET codeset, const unsigned char *chr)
int instr(int &result, const cub_regex_object &reg, const std::string &src, const int position, const int occurrence, const int return_opt, const INTL_CODESET codeset)
#define ER_QSTR_SRC_TOO_LONG
Definition: error_code.h:979
static bool is_char_string(const DB_VALUE *s)
int base64_decode(const unsigned char *src, int src_len, unsigned char **dest, int *dest_len)
Definition: base64.c:387
int db_blob_length(const DB_VALUE *src_value, DB_VALUE *result_value)
static int qstr_concatenate(const unsigned char *s1, int s1_length, int s1_precision, DB_TYPE s1_type, const unsigned char *s2, int s2_length, int s2_precision, DB_TYPE s2_type, INTL_CODESET codeset, unsigned char **result, int *result_length, int *result_size, DB_TYPE *result_type, DB_DATA_STATUS *data_status)
int db_string_make_empty_typed_string(DB_VALUE *db_val, const DB_TYPE db_type, int precision, int codeset, int collation_id)
#define ESCAPE_CHAR(c)
int db_string_substring(const MISC_OPERAND substr_operand, const DB_VALUE *src_string, const DB_VALUE *start_position, const DB_VALUE *extraction_length, DB_VALUE *sub_string)
DB_DOMAIN_INFO domain
Definition: dbtype_def.h:1082
static int make_scientific_notation(char *src_string, int cipher)
#define DB_VALUE_SCALE(value)
Definition: dbtype.h:74
DB_ELO * db_get_elo(const DB_VALUE *value)
#define QSTR_IS_BIT(s)
Definition: string_opfunc.h:44
int db_datetimetz_to_string(char *buf, int bufsize, DB_DATETIME *dt, const TZ_ID *tz_id)
Definition: db_date.c:4302
static int scientific_to_decimal_string(const INTL_LANG lang, char *src_string, char **scientific_str)
void THREAD_ENTRY
void qstr_bit_to_hex_coerce(char *buffer, int buffer_size, const char *src, int src_length, int pad_flag, int *copy_size, int *truncation)
const char * Day_name_EUCKR[][7]
#define QSTR_IS_CHAR(s)
Definition: string_opfunc.h:40
int crypt_generate_random_bytes(char *dest, int length)
Definition: crypt_opfunc.c:688
#define REINTERPRET_CAST(dest_type, expr)
Definition: porting.h:1080
#define DATETIMETZ_BUF_SIZE
Definition: string_opfunc.h:95
DB_TIMESTAMPTZ * db_get_timestamptz(const DB_VALUE *value)
int db_date_encode(DB_DATE *date, int month, int day, int year)
Definition: db_date.c:275
int db_make_short(DB_VALUE *value, const DB_C_SHORT num)
int intl_euckr_to_utf8(const unsigned char *in_buf, const int in_size, unsigned char **out_buf, int *out_size)
int db_timestamp_to_string(char *buf, int bufsize, DB_TIMESTAMP *utime)
Definition: db_date.c:4054
const char * Short_Day_name_UTF8[][7]
const char * lang_get_collation_name(const int coll_id)
int intl_put_char(unsigned char *dest, const unsigned char *char_p, const INTL_CODESET codeset)
int db_check_time_date_format(const char *format_s)
Definition: db_date.c:4914
int db_string_aes_decrypt(DB_VALUE const *src, DB_VALUE const *key, DB_VALUE *result)
int compile(cub_regex_object *&compiled_regex, const char *pattern, const std::regex_constants::syntax_option_type reg_flags, const LANG_COLLATION *collation)
int db_make_string(DB_VALUE *value, DB_CONST_C_CHAR str)
static int qstr_grow_string(DB_VALUE *src_string, DB_VALUE *result, int new_size)
#define SKIP_SPACES(ch, end)
DB_MONETARY * db_get_monetary(const DB_VALUE *value)
static int qstr_position(const char *sub_string, const int sub_size, const int sub_length, const char *src_string, const char *src_end, const char *src_string_bound, int src_length, int coll_id, bool is_forward_search, int *position)
UINT64 prm_get_bigint_value(PARAM_ID prm_id)
STRING_DATE_TOKEN
bool intl_is_min_bound_chr(INTL_CODESET codeset, const unsigned char *chr)
int tz_get_best_match_zone(const char *name, int *size)
Definition: tz_support.c:4157
DB_DATA data
Definition: dbtype_def.h:1083
int db_string_position(const DB_VALUE *sub_string, const DB_VALUE *src_string, DB_VALUE *result)
DB_CURRENCY
Definition: dbtype_def.h:799
int char_isxdigit(int c)
Definition: chartype.c:85
#define QSTR_MATCH(id, string1, size1, string2, size2, esc, has_last_escape, match_size)
Definition: string_opfunc.h:69
int tz_create_datetimetz(const DB_DATETIME *dt, const char *tz_str, const int tz_size, const TZ_REGION *default_tz_region, DB_DATETIMETZ *dt_tz, const char **end_tz_str)
Definition: tz_support.c:1383
static bool is_integer(const DB_VALUE *i)
unsigned int DB_TIMESTAMP
Definition: dbtype_def.h:759
static bool is_number(const DB_VALUE *n)
int db_unix_timestamp(const DB_VALUE *src_date, DB_VALUE *result_timestamp)
int db_add_days_to_year(const DB_VALUE *src_year, const DB_VALUE *src_days, DB_VALUE *result)
TP_DOMAIN * tp_domain_resolve_default(DB_TYPE type)
int db_string_concatenate(const DB_VALUE *string1, const DB_VALUE *string2, DB_VALUE *result, DB_DATA_STATUS *data_status)
static int qstr_bit_substring(const unsigned char *src, int src_length, int start, int length, unsigned char **r, int *r_length)
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
INTL_CODESET codeset
int db_string_lower(const DB_VALUE *string, DB_VALUE *lower_string)
LANG_COLLATION * lang_get_collation(const int coll_id)
#define PAD
int db_make_enumeration(DB_VALUE *value, unsigned short index, DB_CONST_C_CHAR str, int size, unsigned char codeset, const int collation_id)
int db_value_put_encoded_time(DB_VALUE *value, const DB_TIME *time)
Definition: db_macro.c:1357
#define ER_QPROC_INVALID_PARAMETER
Definition: error_code.h:963
DB_BIGINT db_elo_size(DB_ELO *elo)
Definition: db_elo.c:128
enum currency_check_mode CURRENCY_CHECK_MODE
Definition: intl_support.h:162
#define DB_MAX_NUMERIC_PRECISION
Definition: dbtype_def.h:522
#define ER_QPROC_STRING_SIZE_TOO_BIG
Definition: error_code.h:1300
#define LIKE_WILDCARD_MATCH_MANY
#define assert(x)
#define ER_LANG_CODESET_NOT_AVAILABLE
Definition: error_code.h:1382
int db_string_elt(DB_VALUE *result, DB_VALUE *arg[], int const num_args)
#define LIKE_WILDCARD_MATCH_ONE
static int db_date_add_sub_interval_days(DB_VALUE *result, const DB_VALUE *date, const DB_VALUE *db_days, bool is_add)
int tz_create_session_tzid_for_datetime(const DB_DATETIME *src_dt, bool src_is_utc, TZ_ID *tz_id)
Definition: tz_support.c:1037
char lang_digit_grouping_symbol(const INTL_LANG lang_id)
static void bit_ncat(unsigned char *r, int offset, const unsigned char *s, int n)
INTL_UTF8_VALIDITY intl_check_utf8(const unsigned char *buf, int size, char **pos)
#define LANG_COERCIBLE_CODESET
#define QSTR_NUM_BYTES(a)
Definition: string_opfunc.h:58
int qstr_hex_to_bin(char *dest, int dest_size, const char *src, int src_size)
int db_string_to_datetimetz_ex(const char *str, int str_len, DB_DATETIMETZ *dt_tz, bool *has_zone)
Definition: db_date.c:4455
struct db_domain_info::numeric_info numeric_info
#define ER_QSTR_TONUM_FORMAT_MISMATCH
Definition: error_code.h:1038
int prm_get_integer_value(PARAM_ID prm_id)
#define QSTR_TIME_STAMPLENGTH
#define ER_TIME_CONVERSION
Definition: error_code.h:981
#define ER_GENERIC_ERROR
Definition: error_code.h:49
void intl_pad_char(const INTL_CODESET codeset, unsigned char *pad_char, int *pad_size)
int db_string_regexp_like(DB_VALUE *result, DB_VALUE *args[], int const num_args, cub_regex_object **comp_regex, char **comp_pattern)
static int start_month(void *data, const char **attr)
int db_timestamp_encode_utc(const DB_DATE *date, const DB_TIME *timeval, DB_TIMESTAMP *utime)
Definition: db_date.c:635
#define QSTR_TO_CHAR_LEN_MULTIPLIER_RATIO
struct db_char::@52 info
static int parse_tzd(const char *str, const int max_expect_len)
int db_string_replace(const DB_VALUE *src_string, const DB_VALUE *srch_string, const DB_VALUE *repl_string, DB_VALUE *replaced_string)
#define ER_PRECISION_OVERFLOW
Definition: error_code.h:1538
static bool is_valid_ip_slice(const char *ipslice)
#define ER_IT_DATA_OVERFLOW
Definition: error_code.h:505
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
#define PM_NAME_KR_UTF8
#define DB_ENUM_OVERFLOW_VAL
Definition: dbtype_def.h:645
int db_format(const DB_VALUE *value, const DB_VALUE *decimals, const DB_VALUE *number_lang, DB_VALUE *result, const TP_DOMAIN *domain)
bool intl_is_currency_symbol(const char *src, DB_CURRENCY *currency, int *symbol_size, const CURRENCY_CHECK_MODE check_mode)
static int db_str_to_millisec(const char *str)
#define MAX_LEN_OFFSET
Definition: tz_support.h:45
int db_time_encode(DB_TIME *timeval, int hour, int minute, int second)
Definition: db_date.c:370
unsigned is_desc
int db_string_compare(const DB_VALUE *string1, const DB_VALUE *string2, DB_VALUE *result)
int qstr_compare(const unsigned char *string1, int size1, const unsigned char *string2, int size2)
int db_sys_date_and_epoch_time(DB_VALUE *dt_dbval, DB_VALUE *ts_dbval)
#define ER_ATTEMPT_TO_USE_ZERODATE
Definition: error_code.h:1478
DB_DATETIME datetime
Definition: dbtype_def.h:783
const char * day_parse_order
static int shift_left(unsigned char *bit_string, int bit_string_size)
int db_string_pad(const MISC_OPERAND pad_operand, const DB_VALUE *src_string, const DB_VALUE *pad_length, const DB_VALUE *pad_charset, DB_VALUE *padded_string)
#define DB_VALUE_DOMAIN_TYPE(value)
Definition: dbtype.h:70
int db_to_datetime(const DB_VALUE *src_str, const DB_VALUE *format_str, const DB_VALUE *date_lang, const DB_TYPE type, DB_VALUE *result_datetime)
int tp_value_string_to_double(const DB_VALUE *value, DB_VALUE *result)
#define DB_INT32_MAX
Definition: dbtype_def.h:633
int db_ascii(const DB_VALUE *param, DB_VALUE *result)
#define ER_QSTR_MISMATCHING_ARGUMENTS
Definition: error_code.h:978
int intl_iso88591_to_euckr(const unsigned char *in_buf, const int in_size, unsigned char **out_buf, int *out_size)
int db_string_substring_index(DB_VALUE *src_string, DB_VALUE *delim_string, const DB_VALUE *count, DB_VALUE *result)
int db_get_date_item(const DB_VALUE *src_date, const int item_type, DB_VALUE *result)
#define TP_DOMAIN_COLLATION(dom)
#define TP_IS_NUMERIC_TYPE(typeid)
const char * Month_name_EUCKR[][12]
#define DB_IS_STRING(value)
Definition: dbtype.h:65
int db_string_upper(const DB_VALUE *string, DB_VALUE *upper_string)
static enum scanner_mode mode
static int make_number_to_char(const INTL_LANG lang, char *num_string, char *format_str, int *length, DB_CURRENCY currency, char **result_str, INTL_CODESET codeset)
static int qstr_trim(MISC_OPERAND tr_operand, const unsigned char *trim, int trim_length, int trim_size, const unsigned char *src_ptr, DB_TYPE src_type, int src_length, int src_size, INTL_CODESET codeset, unsigned char **res, DB_TYPE *res_type, int *res_length, int *res_size)
const char * day_short_parse_order
NUMBER_FORMAT
#define OR_CHECK_INT_OVERFLOW(i)
#define min(a, b)
static int start_day(void *data, const char **attr)
const char * am_pm_parse_order
int db_date_dbval(DB_VALUE *result, const DB_VALUE *date_value, const TP_DOMAIN *domain)
int tz_str_to_region(const char *tz_str, const int tz_str_size, TZ_REGION *tz_region)
Definition: tz_support.c:1286
int substr(std::string &result, bool &is_matched, const cub_regex_object &reg, const std::string &src, const int position, const int occurrence, const INTL_CODESET codeset)
static int end_month(void *data, const char *el_name)
int db_make_timestamptz(DB_VALUE *value, const DB_C_TIMESTAMPTZ *ts_tz_val)
int db_string_put_cs_and_collation(DB_VALUE *value, const int codeset, const int collation_id)
Definition: db_macro.c:4164
const char * Short_Month_name_EUCKR[][12]
void intl_binary_to_utf8(const unsigned char *in_buf, const int in_size, unsigned char **out_buf, int *out_size)
TP_DOMAIN_STATUS tp_value_cast(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain, bool implicit_coercion)
int db_char_string_coerce(const DB_VALUE *src_string, DB_VALUE *dest_string, DB_DATA_STATUS *data_status)
#define TP_DOMAIN_TYPE(dom)
const char AM_PM_parse_order[][12]
const char * Am_Pm_name_EUCKR[][12]
int db_datetime_to_timestamp(const DB_VALUE *src_datetime, DB_VALUE *result_timestamp)
#define TZ_DS_STRING_SIZE
Definition: tz_support.h:85
static void cleanup(int signo)
Definition: broker.c:717
int char_isdigit(int c)
Definition: chartype.c:73
#define ER_QSTR_INVALID_ESCAPE_CHARACTER
Definition: error_code.h:749
int db_timestamp(const DB_VALUE *src_datetime1, const DB_VALUE *src_time2, DB_VALUE *result_datetime)
int db_str_to_date(const DB_VALUE *str, const DB_VALUE *format, const DB_VALUE *date_lang, DB_VALUE *result, TP_DOMAIN *domain)
int db_sys_timestamp(DB_VALUE *result_timestamp)
int db_string_translate(const DB_VALUE *src_string, const DB_VALUE *from_string, const DB_VALUE *to_string, DB_VALUE *transed_string)
#define NULL
Definition: freelistheap.h:34
#define MINUS
const char * Am_Pm_name_ISO[][12]
int db_date_parse_time(char const *str, int str_len, DB_TIME *time, int *millisecond)
Definition: db_date.c:2933
int db_blob_to_bit(const DB_VALUE *src_value, const DB_VALUE *length_value, DB_VALUE *result_value)
#define NUMERIC_MAX_STRING_SIZE
#define WHITE_CHARS
unsigned char * DB_C_NUMERIC
Definition: dbtype_def.h:1214
#define AM_NAME_KR
int db_get_day_of_week(int year, int month, int day)
Definition: db_date.c:4723
int db_string_instr(const DB_VALUE *src_string, const DB_VALUE *sub_string, const DB_VALUE *start_pos, DB_VALUE *result)
DB_CHAR ch
Definition: dbtype_def.h:1070
#define GUID_STANDARD_BYTES_LENGTH
int tz_datetimeltz_to_local(const DB_DATETIME *dt_ltz, DB_DATETIME *dt_local)
Definition: tz_support.c:1628
int db_date_add_interval_days(DB_VALUE *result, const DB_VALUE *date, const DB_VALUE *db_days)
#define LANG_COERCIBLE_COLL
unsigned char size
Definition: dbtype_def.h:990
const char * pr_type_name(DB_TYPE id)
if(extra_options)
Definition: dynamic_load.c:958
int db_blob_from_file(const DB_VALUE *src_value, DB_VALUE *result_value)
DB_DATE date
Definition: dbtype_def.h:1057
int db_value_to_enumeration_value(const DB_VALUE *src, DB_VALUE *result, const TP_DOMAIN *enum_domain)
#define ER_QSTR_INCOMPATIBLE_CODE_SETS
Definition: error_code.h:747
int db_get_time_item(const DB_VALUE *src_date, const int item_type, DB_VALUE *result)
#define TZD_MAX_EXPECTED_LEN
#define QSTR_VALUE_PRECISION(value)
Definition: string_opfunc.c:76
int db_value_domain_max(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale, const int codeset, const int collation_id, const DB_ENUMERATION *enumeration)
Definition: db_macro.c:581
const char * day_name[CAL_DAY_COUNT]
static int qstr_bit_coerce(const unsigned char *src, int src_length, int src_precision, DB_TYPE src_type, unsigned char **dest, int *dest_length, int dest_precision, DB_TYPE dest_type, DB_DATA_STATUS *data_status)
int char_compare(const unsigned char *string1, int size1, const unsigned char *string2, int size2)
#define err(fd,...)
Definition: porting.h:431
int crypt_md5_buffer_hex(const char *buffer, size_t len, char *resblock)
Definition: crypt_opfunc.c:646
#define ER_SYSTEM_DATE
Definition: error_code.h:974
#define db_private_free_and_init(thrd, ptr)
Definition: memory_alloc.h:141
int db_value_put_encoded_date(DB_VALUE *value, const DB_DATE *date)
Definition: db_macro.c:1383
int db_timestamp_decode_w_tz_id(const DB_TIMESTAMP *utime, const TZ_ID *tz_id, DB_DATE *date, DB_TIME *timeval)
Definition: db_date.c:902
static int qstr_replace(const unsigned char *src_buf, int src_len, int src_size, INTL_CODESET codeset, int coll_id, const unsigned char *srch_str_buf, int srch_str_size, const unsigned char *repl_str_buf, int repl_str_size, unsigned char **result_buf, int *result_len, int *result_size)
int db_add_months(const DB_VALUE *src_date, const DB_VALUE *nmonth, DB_VALUE *result_date)
int db_from_tz(DB_VALUE *time_val, DB_VALUE *tz, DB_VALUE *time_val_with_tz)
int db_sys_date(DB_VALUE *result_date)
#define db_private_free(thrd, ptr)
Definition: memory_alloc.h:229
int db_to_number(const DB_VALUE *src_str, const DB_VALUE *format_str, const DB_VALUE *number_lang, DB_VALUE *result_num)
static int to_number_next_state(const int previous_state, const int input_char, const INTL_LANG number_lang_id)
int conv_tz(void *p_out, const void *p_in, DB_TYPE type)
Definition: tz_support.c:5209
#define db_private_alloc(thrd, size)
Definition: memory_alloc.h:227
int intl_char_size(const unsigned char *src, int length_in_chars, INTL_CODESET src_codeset, int *byte_count)
#define MAX_TOKEN_SIZE
#define CONST_CAST(dest_type, expr)
Definition: porting.h:1060
const char * Month_name_ISO[][12]
int db_string_aes_encrypt(DB_VALUE const *src, DB_VALUE const *key, DB_VALUE *result)
const char * month_parse_order
need_clear_type need_clear
Definition: dbtype_def.h:1084
int nchar_compare(const unsigned char *string1, int size1, const unsigned char *string2, int size2, INTL_CODESET codeset)
#define STACK_SIZE
Definition: string_opfunc.c:88
int db_get_cs_coll_info(DB_VALUE *result, const DB_VALUE *val, const int mode)
int db_date_diff(const DB_VALUE *date_value1, const DB_VALUE *date_value2, DB_VALUE *result)
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
#define cmp
Definition: mprec.h:351
int pr_clear_value(DB_VALUE *value)
const LANG_LOCALE_DATA * lang_get_specific_locale(const INTL_LANG lang, const INTL_CODESET codeset)
int db_timestamp_decode_ses(const DB_TIMESTAMP *utime, DB_DATE *date, DB_TIME *timeval)
Definition: db_date.c:764
DB_BIGINT db_get_bigint(const DB_VALUE *value)
#define ER_OPFUNC_INET_ATON_ARG
Definition: error_code.h:1374
int db_get_date_from_days(const DB_VALUE *src, DB_VALUE *result)
TIMESTAMP_FORMAT
int db_string_rlike(const DB_VALUE *src, const DB_VALUE *pattern, const DB_VALUE *case_sensitive, cub_regex_object **comp_regex, char **comp_pattern, int *result)
int db_time_to_string(char *buf, int bufsize, DB_TIME *time)
Definition: db_date.c:3994
const char * lang_charset_cubrid_name(const INTL_CODESET codeset)
int db_string_char_length(const DB_VALUE *string, DB_VALUE *char_count)
static int adjust_precision(char *data, int precision, int scale)
#define DB_DEFAULT_NUMERIC_PRECISION
Definition: dbtype_def.h:564
DB_DOMAIN * db_type_to_db_domain(const DB_TYPE type)
Definition: db_macro.c:1710
int db_json_copy_and_convert_to_utf8(const DB_VALUE *src_dbval, DB_VALUE *dest_dbval, const DB_VALUE **json_str_dbval)
int db_make_time(DB_VALUE *value, const int hour, const int minute, const int second)
int db_datetime_to_string(char *buf, int bufsize, DB_DATETIME *datetime)
Definition: db_date.c:4225
#define DB_DEFAULT_SCALE
Definition: dbtype_def.h:561
int db_string_limit_size_string(DB_VALUE *src_string, DB_VALUE *result, const int new_size, int *spare_bytes)
int varnchar_compare(const unsigned char *string1, int size1, const unsigned char *string2, int size2, INTL_CODESET codeset)
int db_make_datetimetz(DB_VALUE *value, const DB_DATETIMETZ *datetimetz)
const char * intl_backskip_spaces(const char *str_begin, const char *str_end, const INTL_CODESET codeset)
struct db_domain_info::general_info general_info
int64_t DB_BIGINT
Definition: dbtype_def.h:751
#define d1
#define ER_DATE_CONVERSION
Definition: error_code.h:242
static int get_cur_year(void)
int db_clob_to_char(const DB_VALUE *src_value, const DB_VALUE *codeset_value, DB_VALUE *result_value)
#define UINT64_MAX_BIN_DIGITS
Definition: string_opfunc.c:94
int intl_euckr_to_iso88591(const unsigned char *in_buf, const int in_size, unsigned char **out_buf, int *out_size)
const char * Day_name_UTF8[][7]
void util_get_second_and_ms_since_epoch(time_t *secs, int *msec)
Definition: util_func.c:829
int db_last_day(const DB_VALUE *src_date, DB_VALUE *result_day)
#define CAST_BUFLEN
Definition: porting.h:471
static int qstr_bit_concatenate(const unsigned char *s1, int s1_length, int s1_precision, DB_TYPE s1_type, const unsigned char *s2, int s2_length, int s2_precision, DB_TYPE s2_type, unsigned char **result, int *result_length, int *result_size, DB_TYPE *result_type, DB_DATA_STATUS *data_status)
int crypt_default_encrypt(THREAD_ENTRY *thread_p, const char *src, int src_len, const char *key, int key_len, char **dest_p, int *dest_len_p, CIPHER_ENCRYPTION_TYPE enc_type)
Definition: crypt_opfunc.c:212
static int print_string_date_token(const STRING_DATE_TOKEN token_type, const INTL_LANG intl_lang_id, const INTL_CODESET codeset, int token_id, int case_mode, char *buffer, int *token_size)
int parse_match_type(std::regex_constants::syntax_option_type &reg_flags, std::string &opt_str)
#define QSTR_TIME_LENGTH
int db_inet_aton(DB_VALUE *result_numbered_ip, const DB_VALUE *string)
#define TP_IS_CHAR_TYPE(typeid)
TP_DOMAIN_COLL_ACTION collation_flag
Definition: object_domain.h:94
static void error(const char *msg)
Definition: gencat.c:331
const char Day_name_parse_order[][7]
int db_date_add_interval_expr(DB_VALUE *result, const DB_VALUE *date, const DB_VALUE *expr, const int unit)
int db_string_to_base64(DB_VALUE const *src, DB_VALUE *result)
static int hextoi(char hex_char)
int qstr_bit_to_bin(char *dest, int dest_size, const char *src, int src_size)
#define DB_DEFAULT_PRECISION
Definition: dbtype_def.h:558
void tz_id_to_region(const TZ_ID *tz_id, TZ_REGION *tz_region)
Definition: tz_support.c:803
#define TP_TYPE_HAS_COLLATION(typeid)
char * numeric_db_value_print(const DB_VALUE *val, char *buf)
int tz_utc_datetimetz_to_local(const DB_DATETIME *dt_utc, const TZ_ID *tz_id, DB_DATETIME *dt_local)
Definition: tz_support.c:1571
#define TZR_SIZE
Definition: tz_support.h:86
#define ARG_FILE_LINE
Definition: error_manager.h:44
int db_sys_datetime(DB_VALUE *result_datetime)
int db_string_to_time_ex(const char *str, int str_len, DB_TIME *time)
Definition: db_date.c:3708
int(* strmatch)(const LANG_COLLATION *lang_coll, bool is_match, const unsigned char *string1, int size1, const unsigned char *string2, int size2, const unsigned char *escape, const bool has_last_escape, int *str1_match_size, bool ignore_trailing_space)
#define QSTR_IS_NATIONAL_CHAR(s)
Definition: string_opfunc.h:42
unsigned int INTL_LANG
Definition: intl_support.h:132
int qstr_bin_to_hex(char *dest, int dest_size, const char *src, int src_size)
#define DB_BIGINT_MAX
Definition: dbtype_def.h:640
int pr_clone_value(const DB_VALUE *src, DB_VALUE *dest)
int tz_conv_tz_datetime_w_zone_name(const DB_DATETIME *src_dt, const char *source_zone, int len_source, const char *dest_zone, int len_dest, DB_DATETIME *dest_dt)
Definition: tz_support.c:3858
int crypt_default_decrypt(THREAD_ENTRY *thread_p, const char *src, int src_len, const char *key, int key_len, char **dest_p, int *dest_len_p, CIPHER_ENCRYPTION_TYPE enc_type)
Definition: crypt_opfunc.c:334
QSTR_CATEGORY
static int sub_and_normalize_date_time(int *years, int *months, int *days, int *hours, int *minutes, int *seconds, int *milliseconds, DB_BIGINT y, DB_BIGINT m, DB_BIGINT d, DB_BIGINT h, DB_BIGINT mi, DB_BIGINT s, DB_BIGINT ms)
unsigned int DB_TIME
Definition: dbtype_def.h:754
int db_sys_time(DB_VALUE *result_time)
static int db_check_or_create_null_term_string(const DB_VALUE *str_val, char *pre_alloc_buf, int pre_alloc_buf_size, bool ignore_prec_spaces, bool ignore_trail_spaces, char **str_out, bool *do_alloc)
#define QSTR_IS_FIXED_LENGTH(s)
Definition: string_opfunc.h:50
int db_convert_time_to_sec(const DB_VALUE *src_date, DB_VALUE *result)
const char * Am_Pm_name_UTF8[][12]
#define ER_QSTR_EMPTY_STRING
Definition: error_code.h:976
int db_make_varbit(DB_VALUE *value, const int max_bit_length, DB_CONST_C_BIT bit_str, const int bit_str_bit_size)
unsigned int DB_DATE
Definition: dbtype_def.h:771
void julian_decode(int jul, int *monthp, int *dayp, int *yearp, int *weekp)
Definition: db_date.c:196
int db_string_escape_str(const char *src_str, size_t src_size, char **res_string, size_t *dest_size)
#define ER_ES_GENERAL
Definition: error_code.h:1271
DB_DATA_STATUS
int db_get_date_dayofyear(const DB_VALUE *src_date, DB_VALUE *result)
int db_make_db_char(DB_VALUE *value, const INTL_CODESET codeset, const int collation_id, const char *str, const int size)
#define PM_NAME_KR_EUC
static void str_out(const char *fmt,...)
void init_builtin_calendar_names(LANG_LOCALE_DATA *lld)
#define REPL_POS_ARRAY_EXTENT
char * locator
Definition: dbtype_def.h:948
int db_hex(const DB_VALUE *param, DB_VALUE *result)
#define STRCHCAT(s, c)
#define ER_QSTR_BAD_LENGTH
Definition: error_code.h:829
#define strlen(s1)
Definition: intl_support.c:43
int db_datetime_encode(DB_DATETIME *datetime, int month, int day, int year, int hour, int minute, int second, int millisecond)
Definition: db_date.c:4597
int db_string_trim(const MISC_OPERAND tr_operand, const DB_VALUE *trim_charset, const DB_VALUE *src_string, DB_VALUE *trimmed_string)
static int number_to_char(const DB_VALUE *src_value, const DB_VALUE *format_str, const DB_VALUE *number_lang, DB_VALUE *result_str, const TP_DOMAIN *domain)
int intl_lower_string_size(const ALPHABET_DATA *alphabet, const unsigned char *src, int src_size, int src_length)
int db_make_timestampltz(DB_VALUE *value, const DB_C_TIMESTAMP ts_val)
DB_DATE * db_get_date(const DB_VALUE *value)
int db_convert_to_time(const DB_VALUE *src_hour, const DB_VALUE *src_minute, const DB_VALUE *src_second, DB_VALUE *result)
int intl_set_min_bound_chr(INTL_CODESET codeset, char *chr)
int db_value_precision(const DB_VALUE *value)
#define ER_OBJ_INVALID_ARGUMENTS
Definition: error_code.h:275
int replace(std::string &result, const cub_regex_object &reg, const std::string &src, const std::string &repl, const int position, const int occurrence, const INTL_CODESET codeset)
const char * lang_get_lang_name_from_id(const INTL_LANG lang_id)
int count_leap_years_up_to(int year)
int db_to_time(const DB_VALUE *src_str, const DB_VALUE *format_str, const DB_VALUE *date_lang, const DB_TYPE type, DB_VALUE *result_time)
unsigned int date
Definition: dbtype_def.h:776
#define BYTE_SIZE
Definition: string_opfunc.c:75
#define QSTR_IS_VARIABLE_LENGTH(s)
Definition: string_opfunc.h:54
int db_string_convert_to(const DB_VALUE *src_str_dbval, DB_VALUE *dest_str_dbval, INTL_CODESET dest_codeset, int dest_col)
char * intl_get_money_symbol(const DB_CURRENCY currency, INTL_CODESET codeset)
enum intl_codeset INTL_CODESET
Definition: intl_support.h:190
int tz_get_offset_in_mins()
Definition: tz_support.c:5480
int intl_char_count(const unsigned char *src, int length_in_bytes, INTL_CODESET src_codeset, int *char_count)
Definition: intl_support.c:983
static int qstr_coerce(const unsigned char *src, int src_length, int src_precision, DB_TYPE src_type, INTL_CODESET src_codeset, INTL_CODESET dest_codeset, unsigned char **dest, int *dest_length, int *dest_size, int dest_precision, DB_TYPE dest_type, DB_DATA_STATUS *data_status)
static const char nbits[]
Definition: query_bitset.c:44
const ALPHABET_DATA * lang_user_alphabet_w_coll(const int collation_id)
int intl_utf8_to_euckr(const unsigned char *in_buf, const int in_size, unsigned char **out_buf, int *out_size)
bool prm_get_bool_value(PARAM_ID prm_id)
#define PM_NAME_KR
int db_months_between(const DB_VALUE *start_mon, const DB_VALUE *end_mon, DB_VALUE *result_mon)
#define DB_MAX_BIT_LENGTH
Definition: dbtype_def.h:519
#define QSTR_IS_ANY_CHAR_OR_BIT(s)
Definition: string_opfunc.h:47
int64_t size
Definition: dbtype_def.h:947
const char * Short_Month_name_UTF8[][12]
DB_TIMESTAMP * db_get_timestamp(const DB_VALUE *value)
int db_get_string_size(const DB_VALUE *value)
DB_C_SHORT db_get_short(const DB_VALUE *value)
static int parse_digits(char *s, int *nr, int cnt)
INTL_CODESET codeset
#define NUM_MISC_OPERANDS
void er_clear(void)
int db_to_date(const DB_VALUE *src_str, const DB_VALUE *format_str, const DB_VALUE *date_lang, DB_VALUE *result_date)
int intl_cmp_char(const unsigned char *s1, const unsigned char *s2, INTL_CODESET codeset, int *char_size)
bool check_should_recompile(const cub_regex_object *compiled_regex, const char *compiled_pattern, const std::string &pattern, const std::regex_constants::syntax_option_type reg_flags)
void elo_init_structure(DB_ELO *elo)
Definition: elo.c:127
int char_isalnum(int c)
Definition: chartype.c:97
void db_timestamp_decode_utc(const DB_TIMESTAMP *utime, DB_DATE *date, DB_TIME *timeval)
Definition: db_date.c:781
int db_make_varnchar(DB_VALUE *value, const int max_nchar_length, DB_CONST_C_NCHAR str, const int nchar_str_byte_size, const int codeset, const int collation_id)
int db_string_regexp_instr(DB_VALUE *result, DB_VALUE *args[], int const num_args, cub_regex_object **comp_regex, char **comp_pattern)
int db_string_regexp_count(DB_VALUE *result, DB_VALUE *args[], int const num_args, cub_regex_object **comp_regex, char **comp_pattern)
#define QSTR_DATETIME_LENGTH
#define TP_FLOATING_PRECISION_VALUE
#define TIMESTAMPTZ_BUF_SIZE
Definition: string_opfunc.h:94
int db_time_diff(const DB_VALUE *val1, const DB_VALUE *val2, DB_VALUE *result)
#define AM_NAME_KR_UTF8
#define ER_QSTR_INCOMPATIBLE_COLLATIONS
Definition: error_code.h:1472
#define DB_VALUE_TYPE(value)
Definition: dbtype.h:72
int db_string_like(const DB_VALUE *src_string, const DB_VALUE *pattern, const DB_VALUE *esc_char, int *result)
static DB_BIGINT get_single_unit_value(const char *expr, DB_BIGINT int_val)
int db_get_enum_collation(const DB_VALUE *value)
int db_get_datetime_from_dbvalue(const DB_VALUE *src_date, int *year, int *month, int *day, int *hour, int *minute, int *second, int *millisecond, const char **endp)
int i
Definition: dynamic_load.c:954
int db_timestamp_encode(DB_TIMESTAMP *utime, DB_DATE *date, DB_TIME *timeval)
Definition: db_date.c:579
int db_to_char(const DB_VALUE *src_value, const DB_VALUE *format_or_length, const DB_VALUE *lang_str, DB_VALUE *result_str, const TP_DOMAIN *domain)
int db_make_null(DB_VALUE *value)
#define DB_IS_NULL(value)
Definition: dbtype.h:63
int db_date_sub_interval_days(DB_VALUE *result, const DB_VALUE *date, const DB_VALUE *db_days)
int db_string_sha_two(DB_VALUE const *src, DB_VALUE const *hash_len, DB_VALUE *result)
int db_make_double(DB_VALUE *value, const DB_C_DOUBLE num)
#define ER_QSTR_FORMAT_TOO_LONG
Definition: error_code.h:975
int db_add_weeks_and_days_to_date(int *day, int *month, int *year, int weeks, int day_week)
Definition: db_date.c:5009
int db_date_sub_interval_expr(DB_VALUE *result, const DB_VALUE *date, const DB_VALUE *expr, const int unit)
int db_string_bit_length(const DB_VALUE *string, DB_VALUE *bit_count)
int db_clob_from_file(const DB_VALUE *src_value, DB_VALUE *result_value)
INTL_UTF8_VALIDITY intl_check_euckr(const unsigned char *buf, int size, char **pos)
int intl_upper_string(const ALPHABET_DATA *alphabet, const unsigned char *src, unsigned char *dst, int length_in_chars)
int base64_encode(const unsigned char *src, int src_len, unsigned char **dest, int *dest_len)
Definition: base64.c:502
void db_date_decode(const DB_DATE *date, int *monthp, int *dayp, int *yearp)
Definition: db_date.c:338
int db_elo_read(const DB_ELO *elo, off_t pos, void *buf, size_t count, DB_BIGINT *read_bytes)
Definition: db_elo.c:145
DB_DATETIME * db_get_datetime(const DB_VALUE *value)
int db_string_quote(const DB_VALUE *str, DB_VALUE *res)
int db_char_to_clob(const DB_VALUE *src_value, DB_VALUE *result_value)
#define ER_OPFUNC_INET_NTOA_ARG
Definition: error_code.h:1375
int db_string_regexp_substr(DB_VALUE *result, DB_VALUE *args[], int const num_args, cub_regex_object **comp_regex, char **comp_pattern)
static void copy_and_shift_values(int shift, int n, DB_BIGINT *first,...)
const char Month_name_parse_order[][12]
static TIMESTAMP_FORMAT get_next_format(const char *sp, const INTL_CODESET codeset, DB_TYPE str_type, int *format_length, const char **next_pos)
int db_string_repeat(const DB_VALUE *src_string, const DB_VALUE *count, DB_VALUE *result)
int db_make_timestamp(DB_VALUE *value, const DB_C_TIMESTAMP timeval)
int db_make_int(DB_VALUE *value, const int num)
int db_get_string_length(const DB_VALUE *value)
int db_conv(const DB_VALUE *num, const DB_VALUE *from_base, const DB_VALUE *to_base, DB_VALUE *result)
int db_tz_offset(const DB_VALUE *src_str, DB_VALUE *result_str, DB_DATETIME *datetime)
int intl_convert_charset(const unsigned char *src, int length_in_chars, INTL_CODESET src_codeset, unsigned char *dest, INTL_CODESET dest_codeset, int *unconverted)
Definition: intl_support.c:953
#define LANG_RT_COMMON_COLL(c1, c2, coll)
int tz_get_timezone_offset(const char *tz_str, int tz_size, char *result, DB_DATETIME *utc_datetime)
Definition: tz_support.c:935
int db_make_char(DB_VALUE *value, const int char_length, DB_CONST_C_CHAR str, const int char_str_byte_size, const int codeset, const int collation_id)
int db_sys_timezone(DB_VALUE *result_timezone)
static int date_to_char(const DB_VALUE *src_value, const DB_VALUE *format_str, const DB_VALUE *date_lang, DB_VALUE *result_str, const TP_DOMAIN *domain)
const char * Day_name_ISO[][7]
static void set_time_argument(struct tm *dest, int year, int month, int day, int hour, int min, int sec)
int tz_explain_tz_id(const TZ_ID *tz_id, char *tzr, const int tzr_size, char *tzdst, const int tzdst_size, int *tzh, int *tzm)
Definition: tz_support.c:3893
DB_TIMESTAMP DB_UTIME
Definition: dbtype_def.h:761
#define LANG_SYS_CODESET
#define TP_DOMAIN_CODESET(dom)
int intl_reverse_string(const unsigned char *src, unsigned char *dst, int length_in_chars, int size_in_bytes, INTL_CODESET codeset)
int db_clob_length(const DB_VALUE *src_value, DB_VALUE *result_value)
DB_TIME * db_get_time(const DB_VALUE *value)
int db_string_md5(DB_VALUE const *val, DB_VALUE *result)
#define ER_QPROC_INVALID_DATATYPE
Definition: error_code.h:534
#define INTL_CAN_COERCE_CS(cs_from, cs_to)
Definition: intl_support.h:97
static bool is_str_valid_number(char *num_p, char *str_end, int base, INTL_CODESET codeset)
int numeric_coerce_string_to_num(const char *astring, int astring_length, INTL_CODESET codeset, DB_VALUE *result)
static bool varchar_truncated(const unsigned char *s, DB_TYPE s_type, int s_length, int used_chars, INTL_CODESET codeset)
void db_time_decode(DB_TIME *timeval, int *hourp, int *minutep, int *secondp)
Definition: db_date.c:432
static int qstr_eval_like(const char *tar, int tar_length, const char *expr, int expr_length, const char *escape, INTL_CODESET codeset, int coll_id)
int db_conv_tz(DB_VALUE *time_val, DB_VALUE *result_time)
const char * lang_charset_name(const INTL_CODESET codeset)
DB_CURRENCY lang_locale_currency(const char *locale_str)
static int get_cur_month(void)
int db_string_to_date_ex(const char *str, int str_len, DB_DATE *date)
Definition: db_date.c:3661
int tz_create_session_tzid_for_timestamp(const DB_UTIME *src_ts, TZ_ID *tz_id)
Definition: tz_support.c:1068
static void convert_locale_number(char *sz, const int size, const INTL_LANG src_locale, const INTL_LANG dst_locale)
#define INTL_CODESET_MULT(codeset)
Definition: intl_support.h:77
#define TP_IS_BIT_TYPE(typeid)
const char * DB_CONST_C_CHAR
Definition: dbtype_def.h:1155
int intl_set_max_bound_chr(INTL_CODESET codeset, char *chr)
#define QSTR_NEXT_ALPHA_CHAR(id, cur_chr, size, next_chr, len)
Definition: string_opfunc.h:75
#define db_private_realloc(thrd, ptr, size)
Definition: memory_alloc.h:231
int day_of_week(int jul_day)
Definition: db_date.c:176
#define DB_GET_UCHAR(dbval)
Definition: string_opfunc.c:97
int intl_fast_iso88591_to_utf8(const unsigned char *in_buf, const int in_size, unsigned char **out_buf, int *out_size)
int db_string_extract_dbval(const MISC_OPERAND extr_operand, DB_VALUE *dbval_p, DB_VALUE *result_p, TP_DOMAIN *domain_p)
int intl_utf8_to_iso88591(const unsigned char *in_buf, const int in_size, unsigned char **out_buf, int *out_size)
static int parse_time_string(const char *timestr, int timestr_size, int *sign, int *h, int *m, int *s, int *ms)
#define ER_TZ_LOAD_ERROR
Definition: error_code.h:1487
const char Short_Day_name_parse_order[][7]
#define PLUS
int db_json_convert_to_utf8(DB_VALUE *dbval)
int db_make_bit(DB_VALUE *value, const int bit_length, DB_CONST_C_BIT bit_str, const int bit_str_bit_size)
#define WHITESPACE(c)
int db_get_string_codeset(const DB_VALUE *value)
static int db_round_dbvalue_to_int(const DB_VALUE *src, int *result)
int db_get_day_of_year(int year, int month, int day)
Definition: db_date.c:4697
int intl_upper_string_size(const ALPHABET_DATA *alphabet, const unsigned char *src, int src_size, int src_length)
static void trim_leading(const unsigned char *trim_charset_ptr, int trim_charset_size, const unsigned char *src_ptr, DB_TYPE src_type, int src_length, int src_size, INTL_CODESET codeset, unsigned char **lead_trimmed_ptr, int *lead_trimmed_length, int *lead_trimmed_size, bool skip_spaces)
#define AM_NAME_KR_EUC
ES_TYPE es_get_type(const char *uri)
Definition: es_common.c:43
const char ** p
Definition: dynamic_load.c:945
int db_get_like_optimization_bounds(const DB_VALUE *const pattern, DB_VALUE *bound, const bool has_escape_char, const char *escape_str, const bool compute_lower_bound, const int last_safe_logical_pos)
DB_CONST_C_CHAR db_get_string(const DB_VALUE *value)
MISC_OPERAND
#define DB_UINT32_MAX
Definition: dbtype_def.h:635
struct db_char::@54 medium
int db_bit_to_blob(const DB_VALUE *src_value, DB_VALUE *result_value)
unsigned int time
Definition: dbtype_def.h:777
int db_get_date_week(const DB_VALUE *src_date, const DB_VALUE *mode, DB_VALUE *result)
#define QSTR_COMPARE(id, string1, size1, string2, size2, ti)
Definition: string_opfunc.h:66
int db_make_nchar(DB_VALUE *value, const int nchar_length, DB_CONST_C_NCHAR str, const int nchar_str_byte_size, const int codeset, const int collation_id)
int db_datetimeltz_to_string(char *buf, int bufsize, DB_DATETIME *dt)
Definition: db_date.c:4350
#define LOB_CHUNK_SIZE
Definition: string_opfunc.c:96
int db_like_bound(const DB_VALUE *const src_pattern, const DB_VALUE *const src_escape, DB_VALUE *const result_bound, const bool compute_lower_bound)
int db_value_domain_init(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale)
Definition: db_macro.c:153
int search(int &result, const cub_regex_object &reg, const std::string &src, const INTL_CODESET codeset)
int char_isalpha(int c)
Definition: chartype.c:61
void clear(cub_regex_object *&regex, char *&pattern)
int get_last_day(int month, int year)
int db_date_parse_datetime_parts(char const *str, int str_len, DB_DATETIME *datetime, bool *has_explicit_time, bool *has_explicit_msec, bool *fits_as_timestamp, char const **endp)
Definition: db_date.c:3176
const char * day_short_name[CAL_DAY_COUNT]
int crypt_sha_one(THREAD_ENTRY *thread_p, const char *src, int src_len, char **dest_p, int *dest_len_p)
Definition: crypt_opfunc.c:473