CUBRID Engine  latest
load_db_value_converter.cpp
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  * load_db_value_converter.cpp - conversion from string to db_value
21  */
22 
24 
25 #include "db_date.h"
26 #include "db_json.hpp"
27 #include "dbtype.h"
28 #include "language_support.h"
29 #include "load_class_registry.hpp"
30 #include "numeric_opfunc.h"
31 #include "object_domain.h"
32 #include "object_primitive.h"
33 #include "object_representation.h"
34 #include "string_opfunc.h"
35 
36 #include <array>
37 #include <cassert>
38 #include <cmath>
39 #include <cstring> // for std::memcpy
40 
41 const std::size_t MAX_DIGITS_FOR_SHORT = 5; // default for 16 bit signed shorts: 32767 (0x7FFF)
42 const std::size_t MAX_DIGITS_FOR_INT = 10; // default for 32 bit signed integers: 2147483647 (0x7FFFFFFF)
43 const std::size_t MAX_DIGITS_FOR_BIGINT = 19; // default for 64 bit signed big integers: 9223372036854775807
44 // (0x7FFFFFFFFFFFFFFF)
45 
46 namespace cubload
47 {
48  // TODO CBRD-21654 reuse conversion function in load_sa_loader.cpp source file
49  int mismatch (const char *str, const size_t str_size, const attribute *attr, db_value *val);
50  int to_db_null (const char *str, const size_t str_size, const attribute *attr, db_value *val);
51  int to_db_short (const char *str, const size_t str_size, const attribute *attr, db_value *val);
52  int to_db_int (const char *str, const size_t str_size, const attribute *attr, db_value *val);
53  int to_db_int_set (const char *str, const size_t str_size, const attribute *attr, db_value *val);
54  int to_db_bigint (const char *str, const size_t str_size, const attribute *attr, db_value *val);
55  int to_db_generic_char (DB_TYPE type, const char *str, const size_t str_size, const attribute *attr, db_value *val);
56  int to_db_char (const char *str, const size_t str_size, const attribute *attr, db_value *val);
57  int to_db_varchar (const char *str, const size_t str_size, const attribute *attr, db_value *val);
58  int to_db_make_nchar (const char *str, const size_t str_size, const attribute *attr, db_value *val);
59  int to_db_make_varnchar (const char *str, const size_t str_size, const attribute *attr, db_value *val);
60  int to_db_string (const char *str, const size_t str_size, const attribute *attr, db_value *val);
61  int to_db_float (const char *str, const size_t str_size, const attribute *attr, db_value *val);
62  int to_db_double (const char *str, const size_t str_size, const attribute *attr, db_value *val);
63  int to_db_numeric (const char *str, const size_t str_size, const attribute *attr, db_value *val);
64  int to_db_date (const char *str, const size_t str_size, const attribute *attr, db_value *val);
65  int to_db_time (const char *str, const size_t str_size, const attribute *attr, db_value *val);
66  int to_db_timestamp (const char *str, const size_t str_size, const attribute *attr, db_value *val);
67  int to_db_timestampltz (const char *str, const size_t str_size, const attribute *attr, db_value *val);
68  int to_db_timestamptz (const char *str, const size_t str_size, const attribute *attr, db_value *val);
69  int to_db_datetime (const char *str, const size_t str_size, const attribute *attr, db_value *val);
70  int to_db_datetimeltz (const char *str, const size_t str_size, const attribute *attr, db_value *val);
71  int to_db_datetimetz (const char *str, const size_t str_size, const attribute *attr, db_value *val);
72  int to_db_json (const char *str, const size_t str_size, const attribute *attr, db_value *val);
73  int to_db_monetary (const char *str, const size_t str_size, const attribute *attr, db_value *val);
74  int to_db_varbit_from_bin_str (const char *str, const size_t str_size, const attribute *attr, db_value *val);
75  int to_db_varbit_from_hex_str (const char *str, const size_t str_size, const attribute *attr, db_value *val);
76  int to_db_elo_ext (const char *str, const size_t str_size, const attribute *attr, db_value *val);
77  int to_db_elo_int (const char *str, const size_t str_size, const attribute *attr, db_value *val);
78  int to_int_generic (const char *str, const size_t str_size, const attribute *attr, db_value *val);
79 
80  using conv_setters = std::array<std::array<conv_func, NUM_LDR_TYPES>, NUM_DB_TYPES>;
81 
82  static conv_setters init_setters ();
84 
85  static conv_setters
87  {
88  conv_setters setters_;
89 
90  for (int i = 0; i < NUM_DB_TYPES; i++)
91  {
92  for (int j = 0; j < NUM_LDR_TYPES; j++)
93  {
94  setters_[i][j] = &mismatch;
95  }
96  }
97 
98  for (int i = 0; i < NUM_DB_TYPES; i++)
99  {
100  setters_[i][LDR_NULL] = &to_db_null;
101  }
102 
103  // used within collection
105  for (DB_TYPE &set_type : set_types)
106  {
107  setters_[set_type][LDR_INT] = &to_db_int_set;
108  setters_[set_type][LDR_STR] = &to_db_string;
109  setters_[set_type][LDR_NSTR] = &to_db_make_varnchar;
110  setters_[set_type][LDR_NUMERIC] = &to_db_numeric;
111  setters_[set_type][LDR_DOUBLE] = &to_db_double;
112  setters_[set_type][LDR_FLOAT] = &to_db_float;
113  setters_[set_type][LDR_DATE] = &to_db_date;
114  setters_[set_type][LDR_TIME] = &to_db_time;
115  setters_[set_type][LDR_TIMESTAMP] = &to_db_timestamp;
116  setters_[set_type][LDR_TIMESTAMPLTZ] = &to_db_timestampltz;
117  setters_[set_type][LDR_TIMESTAMPTZ] = &to_db_timestamptz;
118  setters_[set_type][LDR_DATETIME] = &to_db_datetime;
119  setters_[set_type][LDR_DATETIMELTZ] = &to_db_datetimeltz;
120  setters_[set_type][LDR_DATETIMETZ] = &to_db_datetimetz;
121  setters_[set_type][LDR_BSTR] = &to_db_varbit_from_bin_str;
122  setters_[set_type][LDR_XSTR] = &to_db_varbit_from_hex_str;
123  setters_[set_type][LDR_MONETARY] = &to_db_monetary;
124  setters_[set_type][LDR_ELO_EXT] = &to_db_elo_ext;
125  setters_[set_type][LDR_ELO_INT] = &to_db_elo_int;
126  setters_[set_type][LDR_JSON] = &to_db_json;
127  }
128 
129  setters_[DB_TYPE_CHAR][LDR_STR] = &to_db_char;
131 
132  setters_[DB_TYPE_VARCHAR][LDR_STR] = &to_db_varchar;
134 
135  setters_[DB_TYPE_BIGINT][LDR_INT] = &to_db_bigint;
136  setters_[DB_TYPE_INTEGER][LDR_INT] = &to_db_int;
137  setters_[DB_TYPE_SHORT][LDR_INT] = &to_db_short;
138 
139  setters_[DB_TYPE_FLOAT][LDR_INT] = &to_db_float;
140  setters_[DB_TYPE_FLOAT][LDR_NUMERIC] = &to_db_float;
141  setters_[DB_TYPE_FLOAT][LDR_DOUBLE] = &to_db_float;
142  setters_[DB_TYPE_FLOAT][LDR_FLOAT] = &to_db_float;
143 
144  setters_[DB_TYPE_DOUBLE][LDR_INT] = &to_db_double;
146  setters_[DB_TYPE_DOUBLE][LDR_DOUBLE] = &to_db_double;
147  setters_[DB_TYPE_DOUBLE][LDR_FLOAT] = &to_db_double;
148 
149  setters_[DB_TYPE_NUMERIC][LDR_INT] = &to_int_generic;
152  setters_[DB_TYPE_NUMERIC][LDR_FLOAT] = &to_db_double;
153 
158 
159  setters_[DB_TYPE_BLOB][LDR_ELO_EXT] = &to_db_elo_ext;
160  setters_[DB_TYPE_BLOB][LDR_ELO_INT] = &to_db_elo_int;
161  setters_[DB_TYPE_CLOB][LDR_ELO_EXT] = &to_db_elo_ext;
162  setters_[DB_TYPE_CLOB][LDR_ELO_INT] = &to_db_elo_int;
163 
164  setters_[DB_TYPE_JSON][LDR_STR] = &to_db_json;
165 
171 
172  setters_[DB_TYPE_DATE][LDR_STR] = &to_db_string;
173  setters_[DB_TYPE_TIME][LDR_STR] = &to_db_string;
174  setters_[DB_TYPE_DATETIME][LDR_STR] = &to_db_string;
177  setters_[DB_TYPE_TIMESTAMP][LDR_STR] = &to_db_string;
180 
181  setters_[DB_TYPE_DATE][LDR_DATE] = &to_db_date;
182  setters_[DB_TYPE_TIME][LDR_TIME] = &to_db_time;
189 
190  setters_[DB_TYPE_ENUMERATION][LDR_INT] = &to_db_int;
192 
193  return setters_;
194  }
195 
196  conv_func &
197  get_conv_func (const data_type ldr_type, const DB_TYPE db_type)
198  {
199  conv_func &c_func = setters[db_type][ldr_type];
200  return c_func;
201  }
202 
203  int
204  mismatch (const char *str, const size_t str_size, const attribute *attr, db_value *val)
205  {
206  int error_code = ER_OBJ_DOMAIN_CONFLICT;
207  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 1, attr->get_name ());
208  return error_code;
209  }
210 
211  int
212  to_db_null (const char *str, const size_t str_size, const attribute *attr, db_value *val)
213  {
214  if (attr->get_repr ().is_notnull)
215  {
217  }
218  else
219  {
220  return db_make_null (val);
221  }
222  }
223 
224  int
225  to_db_short (const char *str, const size_t str_size, const attribute *attr, db_value *val)
226  {
227  char *str_ptr;
228 
229  db_make_short (val, 0);
230 
231  /* Let try take the fastest path here, if we know that number we are getting fits into a long, use strtol, else we
232  * need to convert it to a double and coerce it, checking for overflow. Note if integers with leading zeros are
233  * entered this can take the slower route. */
234  if (str_size > MAX_DIGITS_FOR_SHORT)
235  {
236  double d;
237  d = strtod (str, &str_ptr);
238 
239  if (str_ptr == str || OR_CHECK_SHORT_OVERFLOW (d))
240  {
242  return ER_IT_DATA_OVERFLOW;
243  }
244  else
245  {
246  val->data.sh = (short) std::round (d);
247  }
248  }
249  else
250  {
251  int i_val;
252  int error_code = parse_int (&i_val, str, 10);
253  if (error_code != 0)
254  {
256  return ER_IT_DATA_OVERFLOW;
257  }
258  val->data.sh = (short) i_val;
259  }
260 
261  return NO_ERROR;
262  }
263 
264  int
265  to_db_int (const char *str, const size_t str_size, const attribute *attr, db_value *val)
266  {
267  char *str_ptr;
268 
269  db_make_int (val, 0);
270 
271  /* Let try take the fastest path here, if we know that number we are getting fits into a long, use strtol, else we
272  * need to convert it to a double and coerce it, checking for overflow. Note if integers with leading zeros are
273  * entered this can take the slower route. */
274  if (str_size < MAX_DIGITS_FOR_INT || (str_size == MAX_DIGITS_FOR_INT && (str[0] == '0' || str[0] == '1')))
275  {
276  int error_code = parse_int (&val->data.i, str, 10);
277  if (error_code != 0)
278  {
280  return ER_IT_DATA_OVERFLOW;
281  }
282  }
283  else
284  {
285  double d;
286  d = strtod (str, &str_ptr);
287 
288  if (str_ptr == str || OR_CHECK_INT_OVERFLOW (d))
289  {
291  return ER_IT_DATA_OVERFLOW;
292  }
293  else
294  {
295  val->data.i = (int) std::round (d);
296  }
297  }
298 
299  return NO_ERROR;
300  }
301 
305  int
306  to_db_int_set (const char *str, const size_t str_size, const attribute *attr, db_value *val)
307  {
308  int error_code = to_db_int (str, str_size, attr, val);
309  if (error_code == ER_IT_DATA_OVERFLOW)
310  {
311  // if there is overflow on integer, try as bigint
312  er_clear ();
313  error_code = to_db_bigint (str, str_size, attr, val);
314  }
315 
316  return error_code;
317  }
318 
319  int
320  to_db_bigint (const char *str, const size_t str_size, const attribute *attr, db_value *val)
321  {
322  db_make_bigint (val, 0);
323 
324  /* Let try take the fastest path here, if we know that number we are getting fits into a long, use strtol, else we
325  * need to convert it to a double and coerce it, checking for overflow. Note if integers with leading zeros are
326  * entered this can take the slower route. */
327  if (str_size < MAX_DIGITS_FOR_BIGINT || (str_size == MAX_DIGITS_FOR_BIGINT && str[0] != '9'))
328  {
329  int error_code = parse_bigint (&val->data.bigint, str, 10);
330  if (error_code != 0)
331  {
333  return ER_IT_DATA_OVERFLOW;
334  }
335  }
336  else
337  {
338  DB_NUMERIC num;
339  DB_BIGINT tmp_bigint;
340 
342  if (numeric_coerce_num_to_bigint (num.d.buf, 0, &tmp_bigint) != NO_ERROR)
343  {
345  return ER_IT_DATA_OVERFLOW;
346  }
347  else
348  {
349  val->data.bigint = tmp_bigint;
350  }
351  }
352 
353  return NO_ERROR;
354  }
355 
356  int
357  to_db_generic_char (DB_TYPE type, const char *str, const size_t str_size, const attribute *attr, db_value *val)
358  {
359  int char_count = 0;
360  int str_len = (int) str_size;
361  int error = NO_ERROR;
362  const tp_domain &domain = attr->get_domain ();
363  int precision = domain.precision;
364  INTL_CODESET codeset = (INTL_CODESET) domain.codeset;
365 
366  intl_char_count ((unsigned char *) str, str_len, codeset, &char_count);
367 
368  if (char_count > precision)
369  {
370  /*
371  * May be a violation, but first we have to check for trailing pad
372  * characters that might allow us to successfully truncate the
373  * thing.
374  */
375  const char *p;
376  int truncate_size;
377 
378  intl_char_size ((unsigned char *) str, precision, codeset, &truncate_size);
379 
380  p = intl_skip_spaces (&str[truncate_size], &str[str_len], codeset);
381  if (p >= &str[str_len])
382  {
383  str_len = truncate_size;
384  }
385  else
386  {
387  /*
388  * It's a genuine violation; raise an error.
389  */
391  return ER_IT_DATA_OVERFLOW;
392  }
393  }
394 
395  error = db_value_domain_init (val, type, char_count, 0);
396  if (error == NO_ERROR)
397  {
398  error = db_make_db_char (val, codeset, domain.collation_id, str, str_len);
399  }
400 
401  return error;
402  }
403 
404  int
405  to_db_char (const char *str, const size_t str_size, const attribute *attr, db_value *val)
406  {
407  return to_db_generic_char (DB_TYPE_CHAR, str, str_size, attr, val);
408  }
409 
410  int
411  to_db_varchar (const char *str, const size_t str_size, const attribute *attr, db_value *val)
412  {
413  return to_db_generic_char (DB_TYPE_VARCHAR, str, str_size, attr, val);
414  }
415 
416  int to_db_make_nchar (const char *str, const size_t str_size, const attribute *attr, db_value *val)
417  {
418  return to_db_generic_char (DB_TYPE_NCHAR, str, str_size, attr, val);
419  }
420 
421  int to_db_make_varnchar (const char *str, const size_t str_size, const attribute *attr, db_value *val)
422  {
423  return to_db_generic_char (DB_TYPE_VARNCHAR, str, str_size, attr, val);
424  }
425 
426  int
427  to_db_string (const char *str, const size_t str_size, const attribute *attr, db_value *val)
428  {
429  return db_make_string (val, str);
430  }
431 
432  int
433  to_db_float (const char *str, const size_t str_size, const attribute *attr, db_value *val)
434  {
435  double d;
436  char *str_ptr;
437 
438  db_make_float (val, (float) 0.0);
439  d = strtod (str, &str_ptr);
440 
441  /* The ascii representation should be ok, check for overflow */
442  if (str_ptr == str || OR_CHECK_FLOAT_OVERFLOW (d))
443  {
445  return ER_IT_DATA_OVERFLOW;
446  }
447  else
448  {
449  val->data.f = (float) d;
450  }
451 
452  return NO_ERROR;
453  }
454 
455  int
456  to_db_double (const char *str, const size_t str_size, const attribute *attr, db_value *val)
457  {
458  double d;
459  char *str_ptr;
460 
461  db_make_double (val, (double) 0.0);
462  d = strtod (str, &str_ptr);
463 
464  /* The ascii representation should be ok, check for overflow */
465  if (str_ptr == str || OR_CHECK_DOUBLE_OVERFLOW (d))
466  {
468  return ER_IT_DATA_OVERFLOW;
469  }
470  else
471  {
472  val->data.d = d;
473  }
474 
475  return NO_ERROR;
476  }
477 
478  int
479  to_db_numeric (const char *str, const size_t str_size, const attribute *attr, db_value *val)
480  {
481  int precision = (int) str_size - 1 - (str[0] == '+' || str[0] == '-');
482  int scale = (int) str_size - (int) strcspn (str, ".") - 1;
483 
484  int error_code = db_value_domain_init (val, DB_TYPE_NUMERIC, precision, scale);
485  if (error_code != NO_ERROR)
486  {
487  return error_code;
488  }
489 
490  return db_value_put (val, DB_TYPE_C_CHAR, (void *) str, (int) str_size);
491  }
492 
493  int
494  to_db_date (const char *str, const size_t str_size, const attribute *attr, db_value *val)
495  {
496  db_make_date (val, 1, 1, 1996);
497 
498  return db_string_to_date (str, &val->data.date);
499  }
500 
501  int
502  to_db_time (const char *str, const size_t str_size, const attribute *attr, db_value *val)
503  {
504  db_make_time (val, 0, 0, 0);
505 
506  return db_string_to_time (str, &val->data.time);
507  }
508 
509  int
510  to_db_timestamp (const char *str, const size_t str_size, const attribute *attr, db_value *val)
511  {
512  db_make_timestamp (val, 0);
513 
514  return db_string_to_timestamp (str, &val->data.utime);
515  }
516 
517  int
518  to_db_timestampltz (const char *str, const size_t str_size, const attribute *attr, db_value *val)
519  {
520  db_make_timestampltz (val, 0);
521 
522  return db_string_to_timestampltz (str, &val->data.utime);
523  }
524 
525  int
526  to_db_timestamptz (const char *str, const size_t str_size, const attribute *attr, db_value *val)
527  {
528  bool has_zone;
529  DB_TIMESTAMPTZ timestamptz;
530 
531  timestamptz.timestamp = 0;
532  timestamptz.tz_id = 0;
533 
534  db_make_timestamptz (val, &timestamptz);
535 
536  return db_string_to_timestamptz (str, &val->data.timestamptz, &has_zone);
537  }
538 
539  int
540  to_db_datetime (const char *str, const size_t str_size, const attribute *attr, db_value *val)
541  {
542  DB_DATETIME datetime;
543 
544  db_datetime_encode (&datetime, 1, 1, 1996, 0, 0, 0, 0);
545  db_make_datetime (val, &datetime);
546 
547  return db_string_to_datetime (str, &val->data.datetime);
548  }
549 
550  int
551  to_db_datetimeltz (const char *str, const size_t str_size, const attribute *attr, db_value *val)
552  {
553  DB_DATETIME datetime;
554 
555  db_datetime_encode (&datetime, 1, 1, 1996, 0, 0, 0, 0);
556  db_make_datetimeltz (val, &datetime);
557 
558  return db_string_to_datetimeltz (str, &val->data.datetime);
559  }
560 
561  int
562  to_db_datetimetz (const char *str, const size_t str_size, const attribute *attr, db_value *val)
563  {
564  bool has_zone;
565  DB_DATETIME datetime;
566  DB_DATETIMETZ datetimetz;
567 
568  db_datetime_encode (&datetime, 1, 1, 1996, 0, 0, 0, 0);
569 
570  datetimetz.datetime = datetime;
571  datetimetz.tz_id = 0;
572 
573  db_make_datetimetz (val, &datetimetz);
574 
575  return db_string_to_datetimetz (str, &val->data.datetimetz, &has_zone);
576  }
577 
578  int
579  to_db_json (const char *str, const size_t str_size, const attribute *attr, db_value *val)
580  {
581  JSON_DOC *document = NULL;
582 
583  int error_code = db_json_get_json_from_str (str, document, str_size);
584  if (error_code != NO_ERROR)
585  {
586  assert (document == NULL);
587  return error_code;
588  }
589 
590  return db_make_json (val, document, true);
591  }
592 
593  int
594  to_db_monetary (const char *str, const size_t str_size, const attribute *attr, db_value *val)
595  {
596  char *str_ptr;
597  double amt;
598  int symbol_size = 0;
599  DB_CURRENCY currency_type = DB_CURRENCY_NULL;
600  const unsigned char *p = (const unsigned char *) str;
601  const unsigned char *token = (const unsigned char *) str;
602 
603  if (str_size >= 2
604  && intl_is_currency_symbol ((const char *) p, &currency_type, &symbol_size,
606  {
607  token += symbol_size;
608  }
609 
610  if (currency_type == DB_CURRENCY_NULL)
611  {
612  currency_type = DB_CURRENCY_DOLLAR;
613  }
614 
615  amt = strtod ((const char *) token, &str_ptr);
616 
617  if (str == str_ptr || OR_CHECK_DOUBLE_OVERFLOW (amt))
618  {
620  return ER_IT_DATA_OVERFLOW;
621  }
622  else
623  {
624  return db_make_monetary (val, currency_type, amt);
625  }
626  }
627 
628  int
629  to_db_varbit_from_bin_str (const char *str, const size_t str_size, const attribute *attr, db_value *val)
630  {
631  int error_code = NO_ERROR;
632  char *bstring;
633  db_value temp;
634  std::size_t dest_size;
635  tp_domain temp_domain, *domain_ptr = NULL;
636 
637  dest_size = (str_size + 7) / 8;
638 
639  bstring = (char *) db_private_alloc (NULL, dest_size + 1);
640  if (bstring == NULL)
641  {
642  error_code = er_errid ();
643  assert (error_code != NO_ERROR);
644 
645  return error_code;
646  }
647 
648  if (qstr_bit_to_bin (bstring, (int) dest_size, const_cast<char *> (str), (int) str_size) != (int) str_size)
649  {
650  db_private_free_and_init (NULL, bstring);
651 
652  error_code = ER_OBJ_DOMAIN_CONFLICT;
653  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 1, attr->get_name ());
654 
655  // TODO CBRD-22271 log LOADDB_MSG_PARSE_ERROR
656  return error_code;
657  }
658 
659  error_code = db_make_varbit (&temp, TP_FLOATING_PRECISION_VALUE, bstring, (int) str_size);
660  if (error_code != NO_ERROR)
661  {
662  db_private_free_and_init (NULL, bstring);
663  return error_code;
664  }
665 
666  temp.need_clear = true;
667 
668  const tp_domain &domain = attr->get_domain ();
669  error_code = db_value_domain_init (val, domain.type->id, domain.precision, domain.scale);
670  if (error_code != NO_ERROR)
671  {
672  // TODO CBRD-22271 log LOADDB_MSG_PARSE_ERROR
673  db_value_clear (&temp);
674  return error_code;
675  }
676 
677  domain_ptr = tp_domain_resolve_value (val, &temp_domain);
678 
679  if (tp_value_cast (&temp, val, domain_ptr, false) != DOMAIN_COMPATIBLE)
680  {
681  db_value_clear (val);
682 
683  error_code = ER_OBJ_DOMAIN_CONFLICT;
684  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 1, attr->get_name ());
685 
686  // TODO CBRD-22271 log LOADDB_MSG_PARSE_ERROR
687  return error_code;
688  }
689  db_value_clear (&temp);
690 
691  return error_code;
692  }
693 
694  int
695  to_db_varbit_from_hex_str (const char *str, const size_t str_size, const attribute *attr, db_value *val)
696  {
697  int error_code = NO_ERROR;
698  char *bstring = NULL;
699  db_value temp;
700  std::size_t dest_size;
701  tp_domain *domain_ptr, temp_domain;
702 
703  db_make_null (&temp);
704 
705  dest_size = (str_size + 1) / 2;
706 
707  bstring = (char *) db_private_alloc (NULL, dest_size + 1);
708  if (bstring == NULL)
709  {
710  error_code = er_errid ();
711  assert (error_code != NO_ERROR);
712 
713  return error_code;
714  }
715 
716  if (qstr_hex_to_bin (bstring, (int) dest_size, const_cast<char *> (str), (int) str_size) != (int) str_size)
717  {
718  db_private_free_and_init (NULL, bstring);
719 
720  error_code = ER_OBJ_DOMAIN_CONFLICT;
721  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 1, attr->get_name ());
722 
723  // TODO CBRD-22271 log LOADDB_MSG_PARSE_ERROR
724  return error_code;
725  }
726 
727  error_code = db_make_varbit (&temp, TP_FLOATING_PRECISION_VALUE, bstring, ((int) str_size) * 4);
728  if (error_code != NO_ERROR)
729  {
730  db_private_free_and_init (NULL, bstring);
731  return error_code;
732  }
733 
734  temp.need_clear = true;
735 
736  const tp_domain &domain = attr->get_domain ();
737  error_code = db_value_domain_init (val, domain.type->id, domain.precision, domain.scale);
738  if (error_code != NO_ERROR)
739  {
740  // TODO CBRD-22271 log LOADDB_MSG_PARSE_ERROR
741  db_value_clear (&temp);
742  return error_code;
743  }
744 
745  domain_ptr = tp_domain_resolve_value (val, &temp_domain);
746  if (tp_value_cast (&temp, val, domain_ptr, false))
747  {
748  db_value_clear (val);
749 
750  error_code = ER_OBJ_DOMAIN_CONFLICT;
751  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 1, attr->get_name ());
752 
753  // TODO CBRD-22271 log LOADDB_MSG_PARSE_ERROR
754  return error_code;
755  }
756  db_value_clear (&temp);
757 
758  return error_code;
759  }
760 
761  int
762  to_db_elo_ext (const char *str, const size_t str_size, const attribute *attr, db_value *val)
763  {
764  db_elo elo;
765  INT64 size;
766  DB_TYPE type;
767  size_t new_len;
768  char *locator = NULL;
769  char *meta_data = NULL;
770  int error_code = NO_ERROR;
771  char *str_start_ptr = NULL, *str_end_ptr = NULL;
772  const char *meta_start_ptr = NULL, *meta_end_ptr = NULL;
773  const char *locator_start_ptr = NULL, *locator_end_ptr = NULL;
774 
775  if (str[0] == '\"')
776  {
777  str++;
778  }
779 
780  new_len = strlen (str);
781  if (new_len && str[new_len - 1] == '\"')
782  {
783  new_len--;
784  }
785 
786  assert (new_len > 0);
787  assert (str[0] == 'B' || str[0] == 'C');
788 
789  if (str[0] == 'B')
790  {
791  type = DB_TYPE_BLOB;
792  }
793  else
794  {
795  type = DB_TYPE_CLOB;
796  }
797 
798  /* size */
799  str_start_ptr = (char *) (str + 1);
800  str_end_ptr = strchr (str_start_ptr, '|');
801  if (str_end_ptr == NULL || str_end_ptr - str_start_ptr == 0)
802  {
803  error_code = ER_LDR_ELO_INPUT_FILE;
804  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 1, str);
805 
806  return error_code;
807  }
808 
809  /* locator */
810  locator_start_ptr = str_end_ptr + 1;
811  locator_end_ptr = strchr (locator_start_ptr, '|');
812  if (locator_end_ptr == NULL || locator_end_ptr - locator_start_ptr == 0)
813  {
814  error_code = ER_LDR_ELO_INPUT_FILE;
815  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 1, str);
816 
817  return error_code;
818  }
819 
820  /* meta_data */
821  meta_end_ptr = meta_start_ptr = locator_end_ptr + 1;
822  while (*meta_end_ptr)
823  {
824  meta_end_ptr++;
825  }
826 
827  int ret = str_to_int64 (&size, &str_end_ptr, str_start_ptr, 10);
828  if (ret != 0 || size < 0)
829  {
830  error_code = ER_LDR_ELO_INPUT_FILE;
831  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 1, str);
832 
833  return error_code;
834  }
835 
836  size_t locator_size = locator_end_ptr - locator_start_ptr;
837  locator = (char *) db_private_alloc (NULL, locator_size + 1);
838  if (locator == NULL)
839  {
840  error_code = er_errid ();
841  assert (error_code != NO_ERROR);
842 
843  return error_code;
844  }
845 
846  std::memcpy (locator, locator_start_ptr, locator_size);
847  locator[locator_size] = '\0';
848 
849  size_t meta_data_size = meta_end_ptr - meta_start_ptr;
850  if (meta_data_size > 0)
851  {
852  meta_data = (char *) db_private_alloc (NULL, meta_data_size + 1);
853  if (meta_data == NULL)
854  {
855  db_private_free_and_init (NULL, locator);
856 
857  error_code = er_errid ();
858  assert (error_code != NO_ERROR);
859 
860  return error_code;
861  }
862 
863  std::memcpy (meta_data, meta_start_ptr, meta_data_size);
864  meta_data[meta_data_size] = '\0';
865  }
866 
867  elo_init_structure (&elo);
868  elo.size = size;
869  elo.locator = locator;
870  elo.meta_data = meta_data;
871  elo.type = ELO_FBO;
872 
873  error_code = db_make_elo (val, type, &elo);
874  if (error_code != NO_ERROR)
875  {
876  db_private_free_and_init (NULL, locator);
877  db_private_free_and_init (NULL, meta_data);
878 
879  return error_code;
880  }
881 
882  val->need_clear = true;
883 
884  return NO_ERROR;
885  }
886 
887  int
888  to_db_elo_int (const char *str, const size_t str_size, const attribute *attr, db_value *val)
889  {
890  /* not implemented. should not be called */
891  assert (0);
892  return ER_FAILED;
893  }
894 
895  int
896  to_int_generic (const char *str, const size_t str_size, const attribute *attr, db_value *val)
897  {
898  int error_code = NO_ERROR;
899 
900  /*
901  * Watch out for really long digit strings that really are being
902  * assigned into a DB_TYPE_NUMERIC attribute; they can hold more than a
903  * standard integer can, and calling atol() on that string will lose
904  * data.
905  * Is there some better way to test for this condition?
906  */
907  if (str_size < MAX_DIGITS_FOR_INT || (str_size == MAX_DIGITS_FOR_INT && (str[0] == '0' || str[0] == '1')))
908  {
909  db_make_int (val, 0);
910  error_code = parse_int (&val->data.i, str, 10);
911  if (error_code != NO_ERROR)
912  {
914  return ER_IT_DATA_OVERFLOW;
915  }
916  }
917  else if (str_size < MAX_DIGITS_FOR_BIGINT || (str_size == MAX_DIGITS_FOR_BIGINT && str[0] != '9'))
918  {
919  db_make_bigint (val, 0);
920  error_code = parse_bigint (&val->data.bigint, str, 10);
921  if (error_code != NO_ERROR)
922  {
924  return ER_IT_DATA_OVERFLOW;
925  }
926  }
927  else
928  {
929  DB_NUMERIC num;
930  DB_BIGINT tmp_bigint;
931 
933  if (numeric_coerce_num_to_bigint (num.d.buf, 0, &tmp_bigint) != NO_ERROR)
934  {
935  error_code = db_value_domain_init (val, DB_TYPE_NUMERIC, (int) str_size, 0);
936  if (error_code != NO_ERROR)
937  {
938  ASSERT_ERROR ();
939  return error_code;
940  }
941 
942  error_code = db_value_put (val, DB_TYPE_C_CHAR, (char *) str, (int) str_size);
943  if (error_code != NO_ERROR)
944  {
945  ASSERT_ERROR ();
946  return error_code;
947  }
948  }
949  else
950  {
951  db_make_bigint (val, tmp_bigint);
952  }
953  }
954 
955  return NO_ERROR;
956  }
957 }
int to_db_monetary(const char *str, const size_t str_size, const attribute *attr, db_value *val)
DB_TIME time
Definition: dbtype_def.h:1056
#define NUM_LDR_TYPES
Definition: load_common.hpp:33
int db_make_json(DB_VALUE *value, JSON_DOC *json_document, bool need_clear)
int db_make_datetime(DB_VALUE *value, const DB_DATETIME *datetime)
#define NO_ERROR
Definition: error_code.h:46
int to_db_varbit_from_bin_str(const char *str, const size_t str_size, const attribute *attr, db_value *val)
short sh
Definition: dbtype_def.h:1050
int to_db_double(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int to_db_varchar(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int db_string_to_timestamp(const char *str, DB_TIMESTAMP *utime)
Definition: db_date.c:3802
int to_db_elo_ext(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int to_db_time(const char *str, const size_t str_size, const attribute *attr, db_value *val)
#define ASSERT_ERROR()
int to_db_char(const char *str, const size_t str_size, const attribute *attr, db_value *val)
unsigned char codeset
Definition: object_domain.h:91
int db_make_bigint(DB_VALUE *value, const DB_BIGINT num)
int db_string_to_datetimetz(const char *str, DB_DATETIMETZ *dt_tz, bool *has_zone)
Definition: db_date.c:4520
DB_TIMESTAMP timestamp
Definition: dbtype_def.h:766
DB_TYPE
Definition: dbtype_def.h:670
int parse_int(int *ret_p, const char *str_p, int base)
Definition: porting.c:2290
#define ER_FAILED
Definition: error_code.h:47
DB_ELO_TYPE type
Definition: dbtype_def.h:950
DB_DATETIME datetime
Definition: dbtype_def.h:1060
int to_int_generic(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int db_string_to_datetime(const char *str, DB_DATETIME *datetime)
Definition: db_date.c:4441
int to_db_datetimeltz(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int mismatch(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int db_make_date(DB_VALUE *value, const int month, const int day, const int year)
int db_make_datetimeltz(DB_VALUE *value, const DB_DATETIME *datetime)
TP_DOMAIN * tp_domain_resolve_value(const DB_VALUE *val, TP_DOMAIN *dbuf)
const std::size_t MAX_DIGITS_FOR_BIGINT
#define NUM_DB_TYPES
Definition: load_common.hpp:34
int to_db_null(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int to_db_short(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int er_errid(void)
int str_to_int64(INT64 *ret_p, char **end_p, const char *str_p, int base)
Definition: porting.c:2419
static conv_setters setters
int db_make_elo(DB_VALUE *value, DB_TYPE type, const DB_ELO *elo)
int db_make_short(DB_VALUE *value, const DB_C_SHORT num)
int db_make_string(DB_VALUE *value, DB_CONST_C_CHAR str)
int to_db_date(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int db_string_to_time(const char *str, DB_TIME *time)
Definition: db_date.c:3739
DB_BIGINT bigint
Definition: dbtype_def.h:1051
DB_DATA data
Definition: dbtype_def.h:1083
DB_CURRENCY
Definition: dbtype_def.h:799
#define OR_CHECK_DOUBLE_OVERFLOW(i)
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
int to_db_varbit_from_hex_str(const char *str, const size_t str_size, const attribute *attr, db_value *val)
DB_TIMESTAMP utime
Definition: dbtype_def.h:1058
enum currency_check_mode CURRENCY_CHECK_MODE
Definition: intl_support.h:162
#define assert(x)
int db_make_monetary(DB_VALUE *value, const DB_CURRENCY type, const double amount)
conv_func & get_conv_func(const data_type ldr_type, const DB_TYPE db_type)
int qstr_hex_to_bin(char *dest, int dest_size, const char *src, int src_size)
int to_db_make_varnchar(const char *str, const size_t str_size, const attribute *attr, db_value *val)
#define ER_IT_DATA_OVERFLOW
Definition: error_code.h:505
const char * intl_skip_spaces(const char *str, const char *str_end, const INTL_CODESET codeset)
bool intl_is_currency_symbol(const char *src, DB_CURRENCY *currency, int *symbol_size, const CURRENCY_CHECK_MODE check_mode)
#define OR_CHECK_SHORT_OVERFLOW(i)
const tp_domain & get_domain() const
int db_json_get_json_from_str(const char *json_raw, JSON_DOC *&doc, size_t json_raw_length)
Definition: db_json.cpp:1608
DB_DATETIME datetime
Definition: dbtype_def.h:783
int to_db_datetime(const char *str, const size_t str_size, const attribute *attr, db_value *val)
#define OR_CHECK_INT_OVERFLOW(i)
int to_db_float(const char *str, const size_t str_size, const attribute *attr, db_value *val)
std::array< std::array< conv_func, NUM_LDR_TYPES >, NUM_DB_TYPES > conv_setters
int db_make_timestamptz(DB_VALUE *value, const DB_C_TIMESTAMPTZ *ts_tz_val)
int to_db_numeric(const char *str, const size_t str_size, const attribute *attr, db_value *val)
unsigned char buf[DB_NUMERIC_BUF_SIZE]
Definition: dbtype_def.h:794
TP_DOMAIN_STATUS tp_value_cast(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain, bool implicit_coercion)
int to_db_timestamptz(const char *str, const size_t str_size, const attribute *attr, db_value *val)
#define NULL
Definition: freelistheap.h:34
#define ER_OBJ_ATTRIBUTE_CANT_BE_NULL
Definition: error_code.h:276
struct pr_type * type
Definition: object_domain.h:76
const char * pr_type_name(DB_TYPE id)
int to_db_timestamp(const char *str, const size_t str_size, const attribute *attr, db_value *val)
DB_DATE date
Definition: dbtype_def.h:1057
DB_TIMESTAMPTZ timestamptz
Definition: dbtype_def.h:1059
#define db_private_free_and_init(thrd, ptr)
Definition: memory_alloc.h:141
int to_db_bigint(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int numeric_coerce_num_to_bigint(DB_C_NUMERIC arg, int scale, DB_BIGINT *answer)
const std::size_t MAX_DIGITS_FOR_INT
#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)
int to_db_generic_char(DB_TYPE type, const char *str, const size_t str_size, const attribute *attr, db_value *val)
need_clear_type need_clear
Definition: dbtype_def.h:1084
static conv_setters init_setters()
int db_make_time(DB_VALUE *value, const int hour, const int minute, const int second)
int db_make_datetimetz(DB_VALUE *value, const DB_DATETIMETZ *datetimetz)
int64_t DB_BIGINT
Definition: dbtype_def.h:751
static void error(const char *msg)
Definition: gencat.c:331
int db_make_float(DB_VALUE *value, const DB_C_FLOAT num)
int qstr_bit_to_bin(char *dest, int dest_size, const char *src, int src_size)
int to_db_make_nchar(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int db_string_to_timestampltz(const char *str, DB_TIMESTAMP *ts)
Definition: db_date.c:3936
#define OR_CHECK_FLOAT_OVERFLOW(i)
int to_db_timestampltz(const char *str, const size_t str_size, const attribute *attr, db_value *val)
#define ARG_FILE_LINE
Definition: error_manager.h:44
int db_make_varbit(DB_VALUE *value, const int max_bit_length, DB_CONST_C_BIT bit_str, const int bit_str_bit_size)
int db_string_to_datetimeltz(const char *str, DB_DATETIME *datetime)
Definition: db_date.c:4555
int db_make_db_char(DB_VALUE *value, const INTL_CODESET codeset, const int collation_id, const char *str, const int size)
char * locator
Definition: dbtype_def.h:948
void numeric_coerce_dec_str_to_num(const char *dec_str, DB_C_NUMERIC result)
#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 to_db_elo_int(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int db_make_timestampltz(DB_VALUE *value, const DB_C_TIMESTAMP ts_val)
#define ER_LDR_ELO_INPUT_FILE
Definition: error_code.h:671
const char * get_name() const
int db_value_put(DB_VALUE *value, const DB_TYPE_C c_type, void *input, const int input_length)
Definition: db_macro.c:1256
enum intl_codeset INTL_CODESET
Definition: intl_support.h:190
int intl_char_count(const unsigned char *src, int length_in_bytes, INTL_CODESET src_codeset, int *char_count)
Definition: intl_support.c:983
int64_t size
Definition: dbtype_def.h:947
const char * get_name() const
void er_clear(void)
void elo_init_structure(DB_ELO *elo)
Definition: elo.c:127
int to_db_datetimetz(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int to_db_string(const char *str, const size_t str_size, const attribute *attr, db_value *val)
#define TP_FLOATING_PRECISION_VALUE
int i
Definition: dynamic_load.c:954
int db_make_null(DB_VALUE *value)
DB_TYPE id
#define ER_OBJ_DOMAIN_CONFLICT
Definition: error_code.h:285
int to_db_int_set(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int db_make_double(DB_VALUE *value, const DB_C_DOUBLE num)
union db_numeric::@51 d
int to_db_json(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int parse_bigint(INT64 *ret_p, const char *str_p, int base)
Definition: porting.c:2318
int db_value_clear(DB_VALUE *value)
Definition: db_macro.c:1588
int db_make_timestamp(DB_VALUE *value, const DB_C_TIMESTAMP timeval)
int db_make_int(DB_VALUE *value, const int num)
char * meta_data
Definition: dbtype_def.h:949
int db_string_to_timestamptz(const char *str, DB_TIMESTAMPTZ *ts_tz, bool *has_zone)
Definition: db_date.c:3894
int collation_id
Definition: object_domain.h:92
int(* conv_func)(const char *, const size_t, const attribute *, db_value *)
const or_attribute & get_repr() const
int db_string_to_date(const char *str, DB_DATE *date)
Definition: db_date.c:3693
float f
Definition: dbtype_def.h:1052
const char ** p
Definition: dynamic_load.c:945
double d
Definition: dbtype_def.h:1053
const std::size_t MAX_DIGITS_FOR_SHORT
int to_db_int(const char *str, const size_t str_size, const attribute *attr, db_value *val)
int db_value_domain_init(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale)
Definition: db_macro.c:153
DB_DATETIMETZ datetimetz
Definition: dbtype_def.h:1061