CUBRID Engine  latest
db_value_table.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  * db_value_table.c -
21  */
22 
23 #include "config.h"
24 #include <string.h>
25 #include <assert.h>
26 #include "db_stub.h"
27 #include "api_util.h"
28 #include "dbi.h"
29 #include "db.h"
30 
33 {
34  /* interface */
36  /* user supplied */
37  void *impl;
40  int (*get_index_by_name) (void *, const char *, int *);
41  int (*get_db_value) (void *, int, DB_VALUE *);
42  int (*set_db_value) (void *, int, DB_VALUE *);
43  int (*init_domain) (void *, int, DB_VALUE *);
44  /* implementation */
46 };
47 
48 typedef struct value_area_s_ VALUE_AREA_;
50 {
51  bool need_apply;
52  bool val_read;
53 };
54 
55 static int value_to_db_value (CI_TYPE type, void *addr, size_t len, DB_VALUE * val, bool domain_initialized);
56 static int db_value_to_value (BIND_HANDLE conn, const DB_VALUE * val, CI_TYPE type, void *addr, size_t len,
57  size_t * outlen, bool * isnull);
58 static int vbt_lazy_init_db_value (VALUE_BIND_TABLE_ * vbt, int index, CHECK_PURPOSE pup, VALUE_AREA ** rva,
59  DB_VALUE ** rv);
60 static int vbt_api_get_value (VALUE_BIND_TABLE * tbl, int index, CI_TYPE type, void *addr, size_t len, size_t * outlen,
61  bool * isnull);
62 static int vbt_api_set_value (VALUE_BIND_TABLE * tbl, int index, CI_TYPE type, void *addr, size_t len);
63 static int vbt_api_get_value_by_name (VALUE_BIND_TABLE * tbl, const char *name, CI_TYPE type, void *addr, size_t len,
64  size_t * outlen, bool * isnull);
65 static int vbt_api_set_value_by_name (VALUE_BIND_TABLE * tbl, const char *name, CI_TYPE type, void *addr, size_t len);
66 static int vbt_apply_updatesf_map (void *arg, int index, VALUE_AREA * va, API_VALUE * val);
68 static int vbt_resetf_map (void *arg, int index, VALUE_AREA * va, API_VALUE * val);
69 static int vbt_api_reset (VALUE_BIND_TABLE * tbl);
70 static void vbt_dtor (VALUE_AREA * v, API_VALUE * aval);
71 static void vbt_api_destroy (VALUE_BIND_TABLE * table);
72 
73 /*
74  * value_to_db_value -
75  * return:
76  * type():
77  * addr():
78  * len():
79  * dbval():
80  * domain_initalized():
81  */
82 static int
83 value_to_db_value (CI_TYPE type, void *addr, size_t len, DB_VALUE * dbval, bool domain_initalized)
84 {
85  DB_VALUE val_s;
86  DB_VALUE *val = &val_s;
87  int res = NO_ERROR;
88 
89  db_make_null (val);
90  if (!domain_initalized)
91  {
92  int precision, scale;
93 
94  DB_DOMAIN *dom;
95  DB_TYPE dt;
96 
97  res = type_to_db_type (type, &dt);
98  if (res != NO_ERROR)
99  return res;
100  dom = db_type_to_db_domain (dt);
101 
102  precision = scale = 0;
103  if (dom != NULL)
104  {
105  precision = db_domain_precision (dom);
106  scale = db_domain_scale (dom);
107  }
108 
109  res = db_value_domain_init (val, dt, precision, scale);
110 
111  if (res != NO_ERROR)
112  goto res_return;
113  }
114  else
115  {
116  val->domain = dbval->domain;
117  }
118 
119  if (type == CI_TYPE_NULL || addr == NULL)
120  {
121  db_make_null (val);
122  goto res_return;
123  }
124 
125  switch (type)
126  {
127  case CI_TYPE_BIGINT:
128  {
129  if (len < sizeof (INT64))
131  res = db_value_put (val, DB_TYPE_C_BIGINT, addr, len);
132  break;
133  }
134  case CI_TYPE_INT:
135  {
136  if (len < sizeof (int))
138  res = db_value_put (val, DB_TYPE_C_INT, addr, len);
139  break;
140  }
141  case CI_TYPE_SHORT:
142  {
143  if (len < sizeof (short))
145  res = db_value_put (val, DB_TYPE_C_SHORT, addr, len);
146  break;
147  }
148  case CI_TYPE_FLOAT:
149  {
150  if (len < sizeof (float))
152  res = db_value_put (val, DB_TYPE_C_FLOAT, addr, len);
153  break;
154  }
155  case CI_TYPE_DOUBLE:
156  {
157  if (len < sizeof (double))
159  res = db_value_put (val, DB_TYPE_C_DOUBLE, addr, len);
160  break;
161  }
162  case CI_TYPE_CHAR:
163  case CI_TYPE_VARCHAR:
164  case CI_TYPE_NCHAR:
165  case CI_TYPE_VARNCHAR:
166  {
167  if (len <= 0)
169  if (type == CI_TYPE_CHAR)
170  res = db_value_put (val, DB_TYPE_C_CHAR, addr, len);
171  else if (type == CI_TYPE_VARCHAR)
172  res = db_value_put (val, DB_TYPE_C_VARCHAR, addr, len);
173  else if (type == CI_TYPE_NCHAR)
174  res = db_value_put (val, DB_TYPE_C_NCHAR, addr, len);
175  else if (type == CI_TYPE_VARNCHAR)
176  res = db_value_put (val, DB_TYPE_C_VARNCHAR, addr, len);
177  break;
178  }
179  case CI_TYPE_BIT:
180  case CI_TYPE_VARBIT:
181  {
182  if (len <= 0)
184  if (type == CI_TYPE_BIT)
185  res = db_value_put (val, DB_TYPE_C_BIT, addr, len);
186  else if (type == CI_TYPE_VARBIT)
187  res = db_value_put (val, DB_TYPE_C_VARBIT, addr, len);
188  break;
189  }
190  case CI_TYPE_TIME:
191  {
192  CI_TIME *xtime;
193  DB_C_TIME time;
194 
195  if (len < sizeof (*xtime))
197  xtime = (CI_TIME *) addr;
198  time.hour = xtime->hour;
199  time.minute = xtime->minute;
200  time.second = xtime->second;
201  res = db_value_put (val, DB_TYPE_C_TIME, &time, sizeof (time));
202  break;
203  }
204  case CI_TYPE_DATE:
205  {
206  CI_TIME *xtime;
207  DB_C_DATE date;
208 
209  if (len < sizeof (*xtime))
211  xtime = (CI_TIME *) addr;
212  date.year = xtime->year;
213  date.month = xtime->month;
214  date.day = xtime->day;
215  res = db_value_put (val, DB_TYPE_C_DATE, &date, sizeof (date));
216  break;
217  }
218  case CI_TYPE_TIMESTAMP:
219  {
220  CI_TIME *xtime;
221  DB_VALUE d, t;
222  DB_TIMESTAMP ts;
223 
224  if (len < sizeof (*xtime))
226 
227  xtime = (CI_TIME *) addr;
228  (void) db_make_null (&d);
229  (void) db_make_null (&t);
230  res = db_make_date (&d, xtime->month, xtime->day, xtime->year);
231  if (res != NO_ERROR)
232  break;
233  res = db_make_time (&t, xtime->hour, xtime->minute, xtime->second);
234  if (res != NO_ERROR)
235  {
236  (void) db_value_clear (&d);
237  break;
238  }
239  res = db_timestamp_encode_ses (db_get_date (&d), db_get_time (&t), &ts, NULL);
240  if (res == NO_ERROR)
241  res = db_value_put (val, DB_TYPE_C_TIMESTAMP, &ts, sizeof (ts));
242  (void) db_value_clear (&d);
243  (void) db_value_clear (&t);
244  break;
245  }
246  case CI_TYPE_DATETIME:
247  {
248  CI_TIME *xtime;
249  DB_VALUE d, t;
250  DB_DATETIME dt;
251 
252  if (len < sizeof (*xtime))
254 
255  xtime = (CI_TIME *) addr;
256  res =
257  db_datetime_encode (&dt, xtime->month, xtime->day, xtime->year, xtime->hour, xtime->minute, xtime->second,
258  xtime->millisecond);
259  if (res == NO_ERROR)
260  res = db_value_put (val, DB_TYPE_C_DATETIME, &dt, sizeof (dt));
261  break;
262  }
263  case CI_TYPE_MONETARY:
264  {
265  if (len < sizeof (double))
267  db_value_put (val, DB_TYPE_C_MONETARY, addr, len);
268  res = db_make_monetary (val, DB_CURRENCY_DEFAULT, *(double *) addr);
269  break;
270  }
271  case CI_TYPE_NUMERIC:
272  {
273  res = db_value_put (val, DB_TYPE_C_CHAR, addr, len);
274  break;
275  }
276  case CI_TYPE_OID:
277  {
278  CI_OID *xoid;
279  DB_OBJECT *obj;
280  OID oid;
281  if (len < sizeof (CI_OID))
283  xoid = (CI_OID *) addr;
284  xoid2oid (xoid, &oid);
285 #if 1
286  obj = db_object (&oid);
287  if (obj == NULL || obj->lock == NULL_LOCK)
288  return ER_INTERFACE_GENERIC; /* no such object */
289  res = db_value_put (val, DB_TYPE_C_OBJECT, &obj, sizeof (DB_OBJECT **));
290 #else
291  res = db_make_oid (val, &oid);
292 #endif
293  break;
294  }
295  case CI_TYPE_COLLECTION:
296  {
297  CI_COLLECTION *col;
298  API_COLLECTION *col_;
299  if (len < sizeof (CI_COLLECTION *))
301  col = (CI_COLLECTION *) addr;
302  col_ = (API_COLLECTION *) * col;
303  res = api_collection_set_to_db_value (col_, val);
304  if (res == NO_ERROR)
305  res = NO_ERROR;
306  break;
307  }
308  default:
309  {
312  }
313  }
314 
315 res_return:
316  if (res != NO_ERROR)
317  return ER_INTERFACE_GENERIC;
318  else
319  res = pr_clone_value (val, dbval);
320 
321  (void) db_value_clear (val);
322 
323  if (res == NO_ERROR)
324  return NO_ERROR;
325  return ER_INTERFACE_GENERIC;
326 }
327 
328 /*
329  * db_value_to_value -
330  * return:
331  * conn():
332  * val():
333  * type():
334  * addr():
335  * len():
336  * out_len():
337  * is_null():
338  */
339 static int
340 db_value_to_value (BIND_HANDLE conn, const DB_VALUE * val, CI_TYPE type, void *addr, size_t len, size_t * out_len,
341  bool * is_null)
342 {
343  DB_TYPE dbtype;
344  int buflen, xflen, outlen;
345  int res;
346 
347  assert (val != NULL);
348  assert (out_len != NULL);
349  assert (is_null != NULL);
350 
351  dbtype = db_value_type (val);
352  if (dbtype == DB_TYPE_NULL)
353  {
354  *is_null = true;
355  return NO_ERROR;
356  }
357 
358  buflen = (int) len;
359  outlen = 0;
360 
361  switch (type)
362  {
363  case CI_TYPE_INT:
364  {
365  if (len < sizeof (int))
367 
368  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_INT, addr, buflen, &xflen, &outlen);
369  break;
370  }
371  case CI_TYPE_SHORT:
372  {
373  if (len < sizeof (short))
375 
376  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_SHORT, addr, buflen, &xflen, &outlen);
377  break;
378  }
379  case CI_TYPE_FLOAT:
380  {
381  if (len < sizeof (float))
383 
384  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_FLOAT, addr, buflen, &xflen, &outlen);
385  break;
386  }
387  case CI_TYPE_DOUBLE:
388  {
389  if (len < sizeof (double))
391 
392  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_DOUBLE, addr, buflen, &xflen, &outlen);
393  break;
394  }
395  case CI_TYPE_CHAR:
396  {
397  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_CHAR, addr, buflen, &xflen, &outlen);
398  break;
399  }
400  case CI_TYPE_VARCHAR:
401  {
402  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_VARCHAR, addr, buflen, &xflen, &outlen);
403  break;
404  }
405  case CI_TYPE_NCHAR:
406  {
407  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_NCHAR, addr, buflen, &xflen, &outlen);
408  break;
409  }
410  case CI_TYPE_VARNCHAR:
411  {
412  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_VARNCHAR, addr, buflen, &xflen, &outlen);
413  break;
414  }
415  case CI_TYPE_BIT:
416  {
417  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_BIT, addr, buflen, &xflen, &outlen);
418  break;
419  }
420  case CI_TYPE_VARBIT:
421  {
422  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_VARBIT, addr, buflen, &xflen, &outlen);
423  break;
424  }
425  case CI_TYPE_TIME:
426  {
427  CI_TIME *xtime = (CI_TIME *) addr;
428  DB_TIME t;
429  int h, m, s;
430 
431  if (len < sizeof (*xtime))
433 
434  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_TIME, &t, sizeof (t), &xflen, &outlen);
435  if (res != NO_ERROR)
436  return ER_INTERFACE_GENERIC;
437 
438  db_time_decode (&t, &h, &m, &s);
439  xtime->hour = h;
440  xtime->minute = m;
441  xtime->second = s;
442  xflen = sizeof (*xtime);
443  break;
444  }
445  case CI_TYPE_DATE:
446  {
447  CI_TIME *xtime = (CI_TIME *) addr;
448  DB_DATE d;
449  int M, D, Y;
450 
451  if (len < sizeof (*xtime))
453 
454  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_DATE, &d, sizeof (d), &xflen, &outlen);
455  if (res != NO_ERROR)
456  return ER_INTERFACE_GENERIC;
457 
458  db_date_decode (&d, &M, &D, &Y);
459  xtime->year = Y;
460  xtime->month = M;
461  xtime->day = D;
462  xflen = sizeof (*xtime);
463  break;
464  }
465  case CI_TYPE_TIMESTAMP:
466  {
467  CI_TIME *xtime = (CI_TIME *) addr;
468  DB_TIMESTAMP ts;
469  DB_DATE date;
470  DB_TIME time;
471  int D, M, Y, h, m, s;
472 
473  if (len < sizeof (*xtime))
475 
476  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_TIMESTAMP, &ts, sizeof (ts), &xflen, &outlen);
477  if (res != NO_ERROR)
478  return ER_INTERFACE_GENERIC;
479 
480  db_timestamp_decode_ses ((DB_TIMESTAMP *) (&ts), &date, &time);
481  db_date_decode (&date, &M, &D, &Y);
482  db_time_decode (&time, &h, &m, &s);
483 
484  xtime->year = Y;
485  xtime->month = M;
486  xtime->day = D;
487  xtime->hour = h;
488  xtime->minute = m;
489  xtime->second = s;
490  xflen = sizeof (*xtime);
491  break;
492  }
493  case CI_TYPE_MONETARY:
494  {
495  if (len < sizeof (double))
497 
498  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_MONETARY, addr, buflen, &xflen, &outlen);
499  break;
500  }
501  case CI_TYPE_NUMERIC:
502  {
503  if (dbtype == DB_TYPE_INTEGER || dbtype == DB_TYPE_SHORT || dbtype == DB_TYPE_BIGINT || dbtype == DB_TYPE_FLOAT
504  || dbtype == DB_TYPE_DOUBLE || dbtype == DB_TYPE_MONETARY || dbtype == DB_TYPE_NUMERIC)
505  {
506  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_CHAR, addr, buflen, &xflen, &outlen);
507  }
508  else if (dbtype == DB_TYPE_CHAR || dbtype == DB_TYPE_VARCHAR || dbtype == DB_TYPE_NCHAR
509  || dbtype == DB_TYPE_VARNCHAR)
510  {
511  DB_VALUE nval;
512  const char *nstr;
513 
514  /* need check if the string is numeric string */
515  db_make_null (&nval);
516  nstr = db_get_string (val);
517 
518  assert (nstr != NULL);
519 
520  res = numeric_coerce_string_to_num (nstr, &nval);
521  (void) db_value_clear (&nval);
522  if (res != NO_ERROR)
523  return ER_INTERFACE_GENERIC;
524 
525  res = db_value_get ((DB_VALUE *) val, DB_TYPE_C_CHAR, addr, buflen, &xflen, &outlen);
526  }
527  else
528  {
530  }
531  break;
532  }
533  case CI_TYPE_OID:
534  {
535  CI_OID *xoid = (CI_OID *) addr;
536  DB_TYPE dt;
537  OID *oid;
538 
539  if (len < sizeof (CI_OID))
540  {
542  }
543 
544  dt = DB_VALUE_DOMAIN_TYPE (val);
545  oid = NULL;
546 
547  if (dt == DB_TYPE_OBJECT)
548  {
549  DB_OBJECT *object = db_get_object (val);
550  if (object == NULL)
551  {
552  *is_null = true;
553  return NO_ERROR;
554  }
555  oid = db_identifier (object);
556  }
557  else if (dt == DB_TYPE_OID)
558  {
559  oid = db_get_oid (val);
560  }
561  if (oid == NULL)
562  {
563  *is_null = true;
564  return NO_ERROR;
565  }
566 
567  oid2xoid (oid, conn, xoid);
568  xflen = sizeof (*xoid);
569  res = NO_ERROR;
570  break;
571  }
572  case CI_TYPE_COLLECTION:
573  {
574  CI_COLLECTION *col;
575  API_COLLECTION *col_;
576 
577  if (len < sizeof (CI_COLLECTION *))
579 
580  col = (CI_COLLECTION *) addr;
581  res = api_collection_create_from_db_value (conn, val, &col_);
582  if (res == NO_ERROR)
583  {
584  *col = col_;
585  xflen = sizeof (API_COLLECTION *);
586  res = NO_ERROR;
587  }
588  else
589  {
590  res = ER_GENERIC_ERROR;
591  }
592  break;
593  }
594  default:
595  {
597  }
598  }
599 
600  if (res == NO_ERROR)
601  {
602  *out_len = ((outlen == 0) ? xflen : outlen);
603  *is_null = false;
604  return NO_ERROR;
605  }
606 
607  return ER_INTERFACE_GENERIC;
608 }
609 
610 
611 /*
612  * vbt_lazy_init_db_value -
613  * return:
614  * vbt():
615  * index():
616  * pup():
617  * rva():
618  * rv():
619  */
620 static int
622 {
623  int res;
624  VALUE_AREA_ *va;
625  DB_VALUE *val;
626 
627  assert (vbt != NULL);
628  assert (rva != NULL);
629  assert (rv != NULL);
630 
631  res = vbt->indexer->ifs->check (vbt->indexer, index, pup);
632  if (res != NO_ERROR)
633  return res;
634 
635  res = vbt->indexer->ifs->get (vbt->indexer, index, (VALUE_AREA **) (&va), (API_VALUE **) (&val));
636  if (res != NO_ERROR)
637  return res;
638 
639  if (val == NULL)
640  {
641  assert (va == NULL);
642  val = db_value_create ();
643  if (val == NULL)
645  res = vbt->init_domain (vbt->impl, index, val);
646  if (res != NO_ERROR)
647  {
648  (void) db_value_free (val);
649  return res;
650  }
651  va = API_CALLOC (1, sizeof (*va));
652  if (va == NULL)
653  {
654  (void) db_value_free (val);
656  }
657  res = vbt->indexer->ifs->set (vbt->indexer, index, (VALUE_AREA *) va, (API_VALUE *) val);
658  if (res != NO_ERROR)
659  {
660  (void) db_value_free (val);
661  API_FREE (va);
662  return res;
663  }
664  }
665  *rva = (VALUE_AREA *) va;
666  *rv = val;
667  return NO_ERROR;
668 }
669 
670 /*
671  * vbt_api_get_value -
672  * return:
673  * tbl():
674  * index():
675  * type():
676  * addr():
677  * len():
678  * outlen():
679  * isnull():
680  */
681 static int
682 vbt_api_get_value (VALUE_BIND_TABLE * tbl, int index, CI_TYPE type, void *addr, size_t len, size_t * outlen,
683  bool * isnull)
684 {
685  VALUE_BIND_TABLE_ *vbt;
686  VALUE_AREA_ *va;
687  DB_VALUE *val;
688  int res;
689 
690  assert (tbl != NULL);
691  assert (outlen != NULL);
692  assert (isnull != NULL);
693 
694  vbt = (VALUE_BIND_TABLE_ *) tbl;
695 
696  res = vbt_lazy_init_db_value (vbt, index, CHECK_FOR_GET, (VALUE_AREA **) (&va), &val);
697  if (res != NO_ERROR)
698  return res;
699  assert (val != NULL);
700  assert (va != NULL);
701  if (!va->val_read)
702  {
703  res = vbt->get_db_value (vbt->impl, index, val);
704  if (res != NO_ERROR)
705  return res;
706  va->val_read = true;
707  }
708  return db_value_to_value (vbt->conn_handle, val, type, addr, len, outlen, isnull);
709 }
710 
711 /*
712  * vbt_api_set_value -
713  * return:
714  * tbl():
715  * index():
716  * type():
717  * addr():
718  * len():
719  */
720 static int
721 vbt_api_set_value (VALUE_BIND_TABLE * tbl, int index, CI_TYPE type, void *addr, size_t len)
722 {
723  VALUE_BIND_TABLE_ *vbt;
724  VALUE_AREA_ *va;
725  DB_VALUE *val;
726  int res;
727 
728  assert (tbl != NULL);
729  vbt = (VALUE_BIND_TABLE_ *) tbl;
730 
731  res = vbt_lazy_init_db_value (vbt, index, CHECK_FOR_SET, (VALUE_AREA **) (&va), &val);
732  if (res != NO_ERROR)
733  return res;
734 
735  assert (val != NULL);
736  assert (va != NULL);
737  res = value_to_db_value (type, addr, len, val, true);
738 
739  if (res != NO_ERROR)
740  return res;
741 
742  if (vbt->auto_apply)
743  {
744  res = vbt->set_db_value (vbt->impl, index, val);
745  if (res != NO_ERROR)
746  return res;
747  va->need_apply = false;
748  }
749  else
750  {
751  va->need_apply = true;
752  }
753  return res;
754 }
755 
756 /*
757  * vbt_api_get_value_by_name -
758  * return:
759  * tbl():
760  * name():
761  * type():
762  * addr():
763  * len():
764  * outlen():
765  * isnull():
766  */
767 static int
768 vbt_api_get_value_by_name (VALUE_BIND_TABLE * tbl, const char *name, CI_TYPE type, void *addr, size_t len,
769  size_t * outlen, bool * isnull)
770 {
771  VALUE_BIND_TABLE_ *vbt;
772  int idx;
773  int res;
774  vbt = (VALUE_BIND_TABLE_ *) tbl;
775  assert (vbt != NULL);
776  res = vbt->get_index_by_name (vbt->impl, name, &idx);
777  if (res != NO_ERROR)
778  return res;
779  return vbt->tbl.ifs->get_value (tbl, idx, type, addr, len, outlen, isnull);
780 }
781 
782 /*
783  * vbt_api_set_value_by_name -
784  * return:
785  * tbl():
786  * name():
787  * type():
788  * addr():
789  * len():
790  */
791 static int
792 vbt_api_set_value_by_name (VALUE_BIND_TABLE * tbl, const char *name, CI_TYPE type, void *addr, size_t len)
793 {
794  VALUE_BIND_TABLE_ *vbt;
795  int idx;
796  int res;
797  vbt = (VALUE_BIND_TABLE_ *) tbl;
798  assert (vbt != NULL);
799  res = vbt->get_index_by_name (vbt->impl, name, &idx);
800  if (res != NO_ERROR)
801  return res;
802  return vbt->tbl.ifs->set_value (tbl, idx, type, addr, len);
803 }
804 
805 
806 /*
807  * vbt_apply_updatesf_map -
808  * return:
809  * arg():
810  * index():
811  * v():
812  * aval():
813  */
814 static int
815 vbt_apply_updatesf_map (void *arg, int index, VALUE_AREA * v, API_VALUE * aval)
816 {
817  VALUE_BIND_TABLE_ *vbt;
818  VALUE_AREA_ *va;
819  DB_VALUE *val = (DB_VALUE *) aval;
820  int res;
821 
822  vbt = (VALUE_BIND_TABLE_ *) arg;
823  assert (vbt != NULL);
824  if (val == NULL)
825  return NO_ERROR;
826  va = (VALUE_AREA_ *) v;
827  assert (va != NULL);
828  if (va->need_apply)
829  {
830  res = vbt->set_db_value (vbt->impl, index, val);
831  if (res != NO_ERROR)
832  return res;
833  va->need_apply = false;
834  }
835  return NO_ERROR;
836 }
837 
838 /*
839  * vbt_api_apply_updates -
840  * return:
841  * tbl():
842  */
843 static int
845 {
846  VALUE_BIND_TABLE_ *vbt;
847  vbt = (VALUE_BIND_TABLE_ *) tbl;
848  assert (vbt != NULL);
849 
850  if (vbt->auto_apply)
851  return NO_ERROR;
852 
853  return vbt->indexer->ifs->map (vbt->indexer, vbt_apply_updatesf_map, vbt);
854 }
855 
856 /*
857  * vbt_resetf_map -
858  * return:
859  * arg():
860  * index():
861  * v():
862  * aval():
863  */
864 static int
865 vbt_resetf_map (void *arg, int index, VALUE_AREA * v, API_VALUE * aval)
866 {
867  VALUE_BIND_TABLE_ *vbt;
868  VALUE_AREA_ *va;
869  DB_VALUE *val = (DB_VALUE *) aval;
870  int res;
871 
872  vbt = (VALUE_BIND_TABLE_ *) arg;
873 
874 
875  assert (vbt != NULL);
876  if (val == NULL)
877  return NO_ERROR;
878  va = (VALUE_AREA_ *) v;
879  assert (va != NULL);
880  /* caution : do not call delete api */
881  res = vbt->indexer->ifs->set (vbt->indexer, index, NULL, NULL);
882  if (res != NO_ERROR)
883  return res;
884  if (va)
885  API_FREE (va);
886  (void) db_value_free (val);
887  return NO_ERROR;
888 }
889 
890 /*
891  * vbt_api_reset -
892  * return:
893  * tbl():
894  */
895 static int
897 {
898  VALUE_BIND_TABLE_ *vbt;
899  int res;
900 
901  vbt = (VALUE_BIND_TABLE_ *) tbl;
902  assert (vbt != NULL);
903 
904  res = vbt->indexer->ifs->map (vbt->indexer, vbt_resetf_map, vbt);
905  return res;
906 }
907 
908 /*
909  * vbt_dtor -
910  * return:
911  * v():
912  * aval():
913  */
914 static void
916 {
917  VALUE_AREA_ *va = (VALUE_AREA_ *) v;
918  DB_VALUE *val = (DB_VALUE *) aval;
919  if (va)
920  API_FREE (va);
921  if (val)
922  (void) db_value_free (val);
923 }
924 
925 /*
926  * vbt_api_destroy -
927  * return:
928  * table():
929  */
930 static void
932 {
933  VALUE_BIND_TABLE_ *vbt = (VALUE_BIND_TABLE_ *) table;
934  assert (table != NULL);
935  vbt->indexer->ifs->destroy (vbt->indexer, vbt_dtor);
936  API_FREE (vbt);
937 }
938 
947 };
948 
949 /* ------------------------------------------------------------------------- */
950 /* VALUE_BIND_TABLE interface implementation */
951 
952 /*
953  * db_type_to_type -
954  * return:
955  * dt():
956  * xt():
957  */
958 int
959 db_type_to_type (DB_TYPE dt, CI_TYPE * xt)
960 {
961  if (xt == NULL)
963 
964  switch (dt)
965  {
966  case DB_TYPE_INTEGER:
967  *xt = CI_TYPE_INT;
968  break;
969  case DB_TYPE_BIGINT:
970  *xt = CI_TYPE_BIGINT;
971  break;
972  case DB_TYPE_FLOAT:
973  *xt = CI_TYPE_FLOAT;
974  break;
975  case DB_TYPE_DOUBLE:
976  *xt = CI_TYPE_DOUBLE;
977  break;
978  case DB_TYPE_STRING:
979  *xt = CI_TYPE_VARCHAR;
980  break;
981  case DB_TYPE_OBJECT:
982  case DB_TYPE_ELO:
983  case DB_TYPE_BLOB:
984  case DB_TYPE_CLOB:
985  case DB_TYPE_OID:
986  *xt = CI_TYPE_OID;
987  break;
988  case DB_TYPE_SET:
989  case DB_TYPE_MULTISET:
990  case DB_TYPE_SEQUENCE:
991  *xt = CI_TYPE_COLLECTION;
992  break;
993  case DB_TYPE_TIME:
994  *xt = CI_TYPE_TIME;
995  break;
996  case DB_TYPE_TIMESTAMP:
997  *xt = CI_TYPE_TIMESTAMP;
998  break;
999  case DB_TYPE_DATETIME:
1000  *xt = CI_TYPE_DATETIME;
1001  break;
1002  case DB_TYPE_DATE:
1003  *xt = CI_TYPE_DATE;
1004  break;
1005  case DB_TYPE_MONETARY:
1006  *xt = CI_TYPE_MONETARY;
1007  break;
1008  case DB_TYPE_SHORT:
1009  *xt = CI_TYPE_SHORT;
1010  break;
1011  case DB_TYPE_NUMERIC:
1012  *xt = CI_TYPE_NUMERIC;
1013  break;
1014  case DB_TYPE_BIT:
1015  *xt = CI_TYPE_BIT;
1016  break;
1017  case DB_TYPE_VARBIT:
1018  *xt = CI_TYPE_VARBIT;
1019  break;
1020  case DB_TYPE_CHAR:
1021  *xt = CI_TYPE_CHAR;
1022  break;
1023  case DB_TYPE_NCHAR:
1024  *xt = CI_TYPE_NCHAR;
1025  break;
1026  case DB_TYPE_VARNCHAR:
1027  *xt = CI_TYPE_VARNCHAR;
1028  break;
1029  case DB_TYPE_NULL:
1030  *xt = CI_TYPE_NULL;
1031  break;
1032  default:
1033  return ER_INTERFACE_GENERIC; /* unsupported db type */
1034  }
1035  return NO_ERROR;
1036 }
1037 
1038 /*
1039  * type_to_db_type -
1040  * return:
1041  * xt():
1042  * dt():
1043  */
1044 int
1045 type_to_db_type (CI_TYPE xt, DB_TYPE * dt)
1046 {
1047  if (dt == NULL)
1049  switch (xt)
1050  {
1051  case CI_TYPE_NULL:
1052  *dt = DB_TYPE_NULL;
1053  break;
1054  case CI_TYPE_INT:
1055  *dt = DB_TYPE_INTEGER;
1056  break;
1057  case CI_TYPE_SHORT:
1058  *dt = DB_TYPE_SHORT;
1059  break;
1060  case CI_TYPE_BIGINT:
1061  *dt = DB_TYPE_BIGINT;
1062  break;
1063  case CI_TYPE_FLOAT:
1064  *dt = DB_TYPE_FLOAT;
1065  break;
1066  case CI_TYPE_DOUBLE:
1067  *dt = DB_TYPE_DOUBLE;
1068  break;
1069  case CI_TYPE_CHAR:
1070  *dt = DB_TYPE_CHAR;
1071  break;
1072  case CI_TYPE_VARCHAR:
1073  *dt = DB_TYPE_VARCHAR;
1074  break;
1075  case CI_TYPE_NCHAR:
1076  *dt = DB_TYPE_NCHAR;
1077  break;
1078  case CI_TYPE_BIT:
1079  *dt = DB_TYPE_BIT;
1080  break;
1081  case CI_TYPE_VARBIT:
1082  *dt = DB_TYPE_VARBIT;
1083  break;
1084  case CI_TYPE_TIME:
1085  *dt = DB_TYPE_TIME;
1086  break;
1087  case CI_TYPE_DATE:
1088  *dt = DB_TYPE_DATE;
1089  break;
1090  case CI_TYPE_TIMESTAMP:
1091  *dt = DB_TYPE_TIMESTAMP;
1092  break;
1093  case CI_TYPE_DATETIME:
1094  *dt = DB_TYPE_DATETIME;
1095  break;
1096  case CI_TYPE_MONETARY:
1097  *dt = DB_TYPE_MONETARY;
1098  break;
1099  case CI_TYPE_NUMERIC:
1100  *dt = DB_TYPE_NUMERIC;
1101  break;
1102  case CI_TYPE_OID:
1103  *dt = DB_TYPE_OBJECT;
1104  break;
1105  case CI_TYPE_COLLECTION:
1106  *dt = DB_TYPE_SEQUENCE;
1107  break;
1108  default:
1109  return ER_INTERFACE_GENERIC;
1110  }
1111  return NO_ERROR;
1112 }
1113 
1114 /*
1115  * xoid2oid -
1116  * return:
1117  * xoid():
1118  * oid():
1119  */
1120 void
1121 xoid2oid (CI_OID * xoid, OID * oid)
1122 {
1123  assert (xoid != NULL);
1124  assert (oid != NULL);
1125  oid->pageid = xoid->d1;
1126  oid->slotid = (xoid->d2 >> 16) & 0xffff;
1127  oid->volid = xoid->d2 & 0xffff;
1128 }
1129 
1130 /*
1131  * oid2xoid -
1132  * return:
1133  * oid():
1134  * conn():
1135  * xoid():
1136  */
1137 void
1138 oid2xoid (OID * oid, BIND_HANDLE conn, CI_OID * xoid)
1139 {
1140  xoid->d1 = oid->pageid;
1141  xoid->d2 = ((oid->slotid << 16) & 0xffff0000) | oid->volid;
1142  xoid->conn = conn;
1143 }
1144 
1145 /*
1146  * coerce_value_to_db_value -
1147  * return:
1148  * type():
1149  * addr():
1150  * len():
1151  * dbval():
1152  * domain_initialized():
1153  */
1154 extern int
1155 coerce_value_to_db_value (CI_TYPE type, void *addr, size_t len, DB_VALUE * dbval, bool domain_initialized)
1156 {
1157  if (dbval == NULL || (type != CI_TYPE_NULL && (addr == NULL || len <= 0)))
1158  {
1160  }
1161 
1162  return value_to_db_value (type, addr, len, dbval, domain_initialized);
1163 }
1164 
1165 /*
1166  * coerce_db_value_to_value -
1167  * return:
1168  * dbval():
1169  * conn():
1170  * type():
1171  * addr():
1172  * len():
1173  * outlen():
1174  * isnull():
1175  */
1176 extern int
1177 coerce_db_value_to_value (const DB_VALUE * dbval, BIND_HANDLE conn, CI_TYPE type, void *addr, size_t len,
1178  size_t * outlen, bool * isnull)
1179 {
1180  if (dbval == NULL || addr == NULL || len <= 0 || outlen == NULL || isnull == NULL)
1181  {
1183  }
1184 
1185  return db_value_to_value (conn, dbval, type, addr, len, outlen, isnull);
1186 }
1187 
1188 /*
1189  * create_db_value_bind_table -
1190  * return:
1191  * nvalue():
1192  * impl():
1193  * auto_apply():
1194  * conn_handle():
1195  * get_index_by_name():
1196  * )():
1197  * get_db_value():
1198  * )():
1199  * set_db_value():
1200  * )():
1201  * init_domain():
1202  * )():
1203  * rtable():
1204  */
1205 int
1207  int (*get_index_by_name) (void *, const char *, int *), int (*get_db_value) (void *, int,
1208  DB_VALUE *),
1209  int (*set_db_value) (void *, int, DB_VALUE *), int (*init_domain) (void *, int, DB_VALUE *),
1210  VALUE_BIND_TABLE ** rtable)
1211 {
1212  VALUE_BIND_TABLE_ *vbt;
1213  int res;
1214 
1215  assert (nvalue > 0);
1216 
1217  vbt = API_MALLOC (sizeof (*vbt));
1218  if (vbt == NULL)
1220 
1221  res = array_indexer_create (nvalue, &vbt->indexer);
1222  if (res != NO_ERROR)
1223  {
1224  API_FREE (vbt);
1225  return res;
1226  }
1227 
1228  vbt->tbl.ifs = &VB_IFS_;
1229  vbt->impl = impl;
1230  vbt->auto_apply = auto_apply;
1231  vbt->conn_handle = conn_handle;
1233  vbt->get_db_value = get_db_value;
1234  vbt->set_db_value = set_db_value;
1235  vbt->init_domain = init_domain;
1236  *rtable = (VALUE_BIND_TABLE *) vbt;
1237  return NO_ERROR;
1238 }
int api_collection_set_to_db_value(API_COLLECTION *col, DB_VALUE *val)
void oid2xoid(OID *oid, BIND_HANDLE conn, CI_OID *xoid)
#define NO_ERROR
Definition: error_code.h:46
static VALUE_BIND_TABLE_IFS VB_IFS_
static void vbt_dtor(VALUE_AREA *v, API_VALUE *aval)
int db_domain_scale(const DB_DOMAIN *domain)
Definition: db_macro.c:4098
int create_db_value_bind_table(int nvalue, void *impl, int auto_apply, BIND_HANDLE conn_handle, int(*get_index_by_name)(void *, const char *, int *), int(*get_db_value)(void *, int, DB_VALUE *), int(*set_db_value)(void *, int, DB_VALUE *), int(*init_domain)(void *, int, DB_VALUE *), VALUE_BIND_TABLE **rtable)
DB_OBJECT * db_object(DB_IDENTIFIER *oid)
Definition: db_admin.c:2641
int db_domain_precision(const DB_DOMAIN *domain)
Definition: db_macro.c:4079
int(* init_domain)(void *, int, DB_VALUE *)
DB_TYPE
Definition: dbtype_def.h:670
#define ER_INTERFACE_NOT_SUPPORTED_OPERATION
Definition: error_code.h:1177
int array_indexer_create(int nvalue, VALUE_INDEXER **rvi)
#define API_CALLOC(n, s)
Definition: api_util.h:110
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
enum check_purpose_s CHECK_PURPOSE
void(* destroy)(VALUE_INDEXER *indexer, void(*df)(VALUE_AREA *va, API_VALUE *db))
Definition: api_common.h:225
int(* get_db_value)(void *, int, DB_VALUE *)
static int vbt_apply_updatesf_map(void *arg, int index, VALUE_AREA *va, API_VALUE *val)
int db_make_date(DB_VALUE *value, const int month, const int day, const int year)
static int vbt_lazy_init_db_value(VALUE_BIND_TABLE_ *vbt, int index, CHECK_PURPOSE pup, VALUE_AREA **rva, DB_VALUE **rv)
void xoid2oid(CI_OID *xoid, OID *oid)
static void vbt_api_destroy(VALUE_BIND_TABLE *table)
int db_type_to_type(DB_TYPE dt, CI_TYPE *xt)
struct VALUE_AREA VALUE_AREA
Definition: api_common.h:42
VALUE_BIND_TABLE tbl
VALUE_INDEXER * indexer
DB_DOMAIN_INFO domain
Definition: dbtype_def.h:1082
static int vbt_api_get_value(VALUE_BIND_TABLE *tbl, int index, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
int api_collection_create_from_db_value(BIND_HANDLE conn, const DB_VALUE *val, API_COLLECTION **rc)
unsigned int DB_TIMESTAMP
Definition: dbtype_def.h:759
#define api_er_set(a, b, c, d)
Definition: db_stub.h:40
#define assert(x)
int db_make_monetary(DB_VALUE *value, const DB_CURRENCY type, const double amount)
#define ER_INTERFACE_GENERIC
Definition: error_code.h:1179
static int db_value_to_value(BIND_HANDLE conn, const DB_VALUE *val, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
#define ER_GENERIC_ERROR
Definition: error_code.h:49
DB_IDENTIFIER * db_identifier(DB_OBJECT *obj)
Definition: db_admin.c:2629
static int vbt_api_set_value(VALUE_BIND_TABLE *tbl, int index, CI_TYPE type, void *addr, size_t len)
static int vbt_api_apply_updates(VALUE_BIND_TABLE *tbl)
DB_TYPE db_value_type(const DB_VALUE *value)
int coerce_db_value_to_value(const DB_VALUE *dbval, BIND_HANDLE conn, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
#define DB_VALUE_DOMAIN_TYPE(value)
Definition: dbtype.h:70
int db_value_free(DB_VALUE *value)
Definition: db_macro.c:1610
DB_OBJECT * db_get_object(const DB_VALUE *value)
static int rv
Definition: area_alloc.c:52
struct API_VALUE API_VALUE
Definition: api_common.h:43
DB_VALUE * db_value_create(void)
Definition: db_macro.c:1517
int(* map)(VALUE_INDEXER *indexer, int(*mapf)(void *, int, VALUE_AREA *, API_VALUE *), void *arg)
Definition: api_common.h:222
#define NULL
Definition: freelistheap.h:34
LOCK lock
Definition: work_space.h:134
#define API_FREE(p)
Definition: api_util.h:112
int db_timestamp_decode_ses(const DB_TIMESTAMP *utime, DB_DATE *date, DB_TIME *timeval)
Definition: db_date.c:764
DB_DOMAIN * db_type_to_db_domain(const DB_TYPE type)
Definition: db_macro.c:1710
int db_make_time(DB_VALUE *value, const int hour, const int minute, const int second)
int(* check)(VALUE_INDEXER *indexer, int index, CHECK_PURPOSE pup)
Definition: api_common.h:218
VALUE_BIND_TABLE_IFS * ifs
Definition: api_common.h:233
#define ARG_FILE_LINE
Definition: error_manager.h:44
int pr_clone_value(const DB_VALUE *src, DB_VALUE *dest)
OID * db_get_oid(const DB_VALUE *value)
unsigned int DB_TIME
Definition: dbtype_def.h:754
unsigned int DB_DATE
Definition: dbtype_def.h:771
int(* get)(VALUE_INDEXER *indexer, int index, VALUE_AREA **rva, API_VALUE **rv)
Definition: api_common.h:220
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
DB_DATE * db_get_date(const DB_VALUE *value)
BIND_HANDLE conn_handle
int db_value_put(DB_VALUE *value, const DB_TYPE_C c_type, void *input, const int input_length)
Definition: db_macro.c:1256
static int vbt_api_get_value_by_name(VALUE_BIND_TABLE *tbl, const char *name, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
int(* get_value)(VALUE_BIND_TABLE *tbl, int index, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
Definition: api_common.h:242
int db_value_get(DB_VALUE *value, const DB_TYPE_C c_type, void *buf, const int buflen, int *xflen, int *outlen)
Definition: db_macro.c:2077
int(* set_value)(VALUE_BIND_TABLE *tbl, int index, CI_TYPE type, void *addr, size_t len)
Definition: api_common.h:244
#define DB_CURRENCY_DEFAULT
Definition: dbtype.h:46
#define API_MALLOC(s)
Definition: api_util.h:111
int(* get_index_by_name)(void *, const char *, int *)
int db_make_null(DB_VALUE *value)
void db_date_decode(const DB_DATE *date, int *monthp, int *dayp, int *yearp)
Definition: db_date.c:338
int type_to_db_type(CI_TYPE xt, DB_TYPE *dt)
UINT64 BIND_HANDLE
Definition: api_handle.h:28
int db_value_clear(DB_VALUE *value)
Definition: db_macro.c:1588
int db_make_oid(DB_VALUE *value, const OID *oid)
int(* set)(VALUE_INDEXER *indexer, int index, VALUE_AREA *va, API_VALUE *val)
Definition: api_common.h:221
DB_TIME * db_get_time(const DB_VALUE *value)
static int value_to_db_value(CI_TYPE type, void *addr, size_t len, DB_VALUE *val, bool domain_initialized)
int numeric_coerce_string_to_num(const char *astring, int astring_length, INTL_CODESET codeset, DB_VALUE *result)
VALUE_INDEXER_IFS * ifs
Definition: api_common.h:208
void db_time_decode(DB_TIME *timeval, int *hourp, int *minutep, int *secondp)
Definition: db_date.c:432
#define ER_INTERFACE_INVALID_ARGUMENT
Definition: error_code.h:1174
int(* set_db_value)(void *, int, DB_VALUE *)
static int vbt_resetf_map(void *arg, int index, VALUE_AREA *va, API_VALUE *val)
DB_CONST_C_CHAR db_get_string(const DB_VALUE *value)
static int vbt_api_reset(VALUE_BIND_TABLE *tbl)
int coerce_value_to_db_value(CI_TYPE type, void *addr, size_t len, DB_VALUE *dbval, bool domain_initialized)
static int vbt_api_set_value_by_name(VALUE_BIND_TABLE *tbl, const char *name, CI_TYPE type, void *addr, size_t len)
int db_value_domain_init(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale)
Definition: db_macro.c:153
#define ER_INTERFACE_NO_MORE_MEMORY
Definition: error_code.h:1198