CUBRID Engine  latest
catalog_class.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  * catalog_class.c - catalog class
21  */
22 
23 #ident "$Id$"
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 
30 #include "system_catalog.h"
31 
32 #include "btree.h" // for single/multi ops
33 #include "error_manager.h"
34 #include "heap_file.h"
35 #include "transform.h"
36 #include "set_object.h"
37 #include "locator_sr.h"
38 #include "xserver_interface.h"
39 #include "object_primitive.h"
40 #include "object_representation.h"
41 #include "query_dump.h"
42 #include "tz_support.h"
43 #include "db_date.h"
44 #include "dbtype.h"
45 #include "string_opfunc.h"
46 #include "thread_manager.hpp"
47 
48 #define IS_SUBSET(value) (value).sub.count >= 0
49 
50 #define EXCHANGE_OR_VALUE(a,b) \
51  do { \
52  OR_VALUE t; \
53  t = a; \
54  a = b; \
55  b = t; \
56  } while (0)
57 
58 #define CATCLS_INDEX_NAME "i__db_class_class_name"
59 #define CATCLS_INDEX_KEY 11
60 
61 #define CATCLS_OID_TABLE_SIZE 1024
62 
63 typedef struct or_value OR_VALUE;
64 typedef struct catcls_entry CATCLS_ENTRY;
66 typedef int (*CREADER) (THREAD_ENTRY * thread_p, OR_BUF * buf, OR_VALUE * value_p);
67 
68 struct or_value
69 {
70  union or_id
71  {
74  } id;
76  struct or_sub
77  {
78  struct or_value *value;
79  int count;
80  } sub;
81 };
82 
84 {
88 };
89 
91 {
92  const char *name;
94  int size;
95  int is_unique;
99 };
100 
101 /* TODO: add to ct_class.h */
102 bool catcls_Enable = false;
103 
107 
108 /* TODO: move to ct_class.h */
109 extern int catcls_compile_catalog_classes (THREAD_ENTRY * thread_p);
110 extern int catcls_insert_catalog_classes (THREAD_ENTRY * thread_p, RECDES * record);
111 extern int catcls_delete_catalog_classes (THREAD_ENTRY * thread_p, const char *name, OID * class_oid);
112 extern int catcls_update_catalog_classes (THREAD_ENTRY * thread_p, const char *name, RECDES * record, OID * class_oid_p,
113  UPDATE_INPLACE_STYLE force_in_place);
115 extern int catcls_remove_entry (THREAD_ENTRY * thread_p, OID * class_oid);
116 extern int catcls_get_server_compat_info (THREAD_ENTRY * thread_p, INTL_CODESET * charset_id_p, char *lang_buf,
117  const int lang_buf_size, char *timezone_checksum);
118 extern int catcls_get_db_collation (THREAD_ENTRY * thread_p, LANG_COLL_COMPAT ** db_collations, int *coll_cnt);
119 extern int catcls_get_apply_info_log_record_time (THREAD_ENTRY * thread_p, time_t * log_record_time);
120 extern int catcls_find_and_set_cached_class_oid (THREAD_ENTRY * thread_p);
121 
122 static int catcls_initialize_class_oid_to_oid_hash_table (THREAD_ENTRY * thread_p, int num_entry);
123 static int catcls_get_or_value_from_class (THREAD_ENTRY * thread_p, OR_BUF * buf_p, OR_VALUE * value_p);
124 static int catcls_get_or_value_from_attribute (THREAD_ENTRY * thread_p, OR_BUF * buf_p, OR_VALUE * value_p);
125 static int catcls_get_or_value_from_attrid (THREAD_ENTRY * thread_p, OR_BUF * buf_p, OR_VALUE * value_p);
126 static int catcls_get_or_value_from_domain (THREAD_ENTRY * thread_p, OR_BUF * buf_p, OR_VALUE * value_p);
127 static int catcls_get_or_value_from_method (THREAD_ENTRY * thread_p, OR_BUF * buf_p, OR_VALUE * value_p);
128 static int catcls_get_or_value_from_method_signiture (THREAD_ENTRY * thread_p, OR_BUF * buf_p, OR_VALUE * value_p);
129 static int catcls_get_or_value_from_method_argument (THREAD_ENTRY * thread_p, OR_BUF * buf_p, OR_VALUE * value_p);
130 static int catcls_get_or_value_from_method_file (THREAD_ENTRY * thread_p, OR_BUF * buf_p, OR_VALUE * value_p);
131 static int catcls_get_or_value_from_resolution (THREAD_ENTRY * thread_p, OR_BUF * buf_p, OR_VALUE * value_p);
132 static int catcls_get_or_value_from_query_spec (THREAD_ENTRY * thread_p, OR_BUF * buf_p, OR_VALUE * value_p);
133 
134 static int catcls_get_or_value_from_indexes (DB_SEQ * seq, OR_VALUE * subset, int is_unique, int is_reverse,
135  int is_primary_key, int is_foreign_key);
136 static int catcls_get_subset (THREAD_ENTRY * thread_p, OR_BUF * buf_p, int expected_size, OR_VALUE * value_p,
137  CREADER reader);
138 static int catcls_get_object_set (THREAD_ENTRY * thread_p, OR_BUF * buf_p, int expected_size, OR_VALUE * value);
139 static int catcls_get_property_set (THREAD_ENTRY * thread_p, OR_BUF * buf_p, int expected_size, OR_VALUE * value_p);
140 static int catcls_reorder_attributes_by_repr (THREAD_ENTRY * thread_p, OR_VALUE * value_p);
141 static int catcls_expand_or_value_by_repr (OR_VALUE * value_p, OID * class_oid, DISK_REPR * rep);
142 static int catcls_expand_or_value_by_subset (THREAD_ENTRY * thread_p, OR_VALUE * value_p);
143 
144 static int catcls_get_or_value_from_buffer (THREAD_ENTRY * thread_p, OR_BUF * buf_p, OR_VALUE * value_p,
145  DISK_REPR * rep);
146 static int catcls_put_or_value_into_buffer (OR_VALUE * value_p, int chn, OR_BUF * buf_p, OID * class_oid,
147  DISK_REPR * rep);
148 
150 static OR_VALUE *catcls_get_or_value_from_record (THREAD_ENTRY * thread_p, RECDES * record, OID * class_oid);
151 static int catcls_put_or_value_into_record (THREAD_ENTRY * thread_p, OR_VALUE * value_p, int chn, RECDES * record,
152  OID * class_oid);
153 
154 static int catcls_insert_subset (THREAD_ENTRY * thread_p, OR_VALUE * value_p, OID * root_oid);
155 static int catcls_delete_subset (THREAD_ENTRY * thread_p, OR_VALUE * value_p);
156 static int catcls_update_subset (THREAD_ENTRY * thread_p, OR_VALUE * value_p, OR_VALUE * old_value, bool * uflag,
157  UPDATE_INPLACE_STYLE force_in_place);
158 static int catcls_insert_instance (THREAD_ENTRY * thread_p, OR_VALUE * value_p, OID * oid, OID * root_oid,
159  OID * class_oid, HFID * hfid, HEAP_SCANCACHE * scan);
160 static int catcls_delete_instance (THREAD_ENTRY * thread_p, OID * oid, OID * class_oid, HFID * hfid,
161  HEAP_SCANCACHE * scan);
162 static int catcls_update_instance (THREAD_ENTRY * thread_p, OR_VALUE * value_p, OID * oid, OID * class_oid, HFID * hfid,
163  HEAP_SCANCACHE * scan, UPDATE_INPLACE_STYLE force_in_place);
164 static CATCLS_ENTRY *catcls_allocate_entry (THREAD_ENTRY * thread_p);
165 static int catcls_free_entry_kv (const void *key, void *data, void *args);
166 static int catcls_free_entry (CATCLS_ENTRY * entry_p);
167 static OID *catcls_find_oid (THREAD_ENTRY * thread_p, OID * class_oid);
168 static int catcls_put_entry (THREAD_ENTRY * thread_p, CATCLS_ENTRY * entry, bool * already_exists);
169 static char *catcls_unpack_allocator (int size);
170 static OR_VALUE *catcls_allocate_or_value (int size);
171 static void catcls_free_sub_value (OR_VALUE * values, int count);
172 static void catcls_free_or_value (OR_VALUE * value);
173 static int catcls_expand_or_value_by_def (OR_VALUE * value_p, CT_CLASS * def);
174 static int catcls_guess_record_length (OR_VALUE * value_p);
175 static int catcls_find_class_oid_by_class_name (THREAD_ENTRY * thread_p, const char *name, OID * class_oid);
176 static int catcls_find_btid_of_class_name (THREAD_ENTRY * thread_p, BTID * btid);
177 static int catcls_find_oid_by_class_name (THREAD_ENTRY * thread_p, const char *name, OID * oid);
178 static int catcls_convert_class_oid_to_oid (THREAD_ENTRY * thread_p, DB_VALUE * oid_val);
179 static int catcls_convert_attr_id_to_name (THREAD_ENTRY * thread_p, OR_BUF * orbuf_p, OR_VALUE * value_p);
180 static void catcls_apply_component_type (OR_VALUE * value_p, int type);
181 static int catcls_resolution_space (int name_space);
182 static void catcls_apply_resolutions (OR_VALUE * value_p, OR_VALUE * resolution_p);
183 static int catcls_replace_entry_oid (THREAD_ENTRY * thread_p, OID * entry_class_oid, OID * entry_new_oid);
184 static int catcls_get_or_value_from_partition (THREAD_ENTRY * thread_p, OR_BUF * buf_p, OR_VALUE * value_p);
185 
186 /*
187  * catcls_allocate_entry () -
188  * return:
189  * thread_p(in):
190  */
191 static CATCLS_ENTRY *
193 {
194  CATCLS_ENTRY *entry_p;
195 
196  assert (csect_check_own (thread_p, CSECT_CT_OID_TABLE) == 1);
197 
198  if (catcls_Free_entry_list != NULL)
199  {
200  entry_p = catcls_Free_entry_list;
201  catcls_Free_entry_list = catcls_Free_entry_list->next;
202  }
203  else
204  {
205  entry_p = (CATCLS_ENTRY *) malloc (sizeof (CATCLS_ENTRY));
206  if (entry_p == NULL)
207  {
209  return NULL;
210  }
211  }
212 
213  entry_p->next = NULL;
214  return entry_p;
215 }
216 
217 /*
218  * catcls_free_entry_kv () - A callback function to free memory
219  * allocated for a catcls entry.
220  * return:
221  * key(in):
222  * data(in):
223  * args(in):
224  */
225 static int
226 catcls_free_entry_kv (const void *key, void *data, void *args)
227 {
228  return catcls_free_entry ((CATCLS_ENTRY *) data);
229 }
230 
231 /*
232  * catcls_free_entry () - free memory allocated for a catcls entry.
233  * return:
234  * entry_p(in)
235  */
236 static int
238 {
240 
241  entry_p->next = catcls_Free_entry_list;
242  catcls_Free_entry_list = entry_p;
243 
244  return NO_ERROR;
245 }
246 
247 /*
248  * catcls_initialize_class_oid_to_oid_hash_table () -
249  * return:
250  * thread_p(in):
251  * num_entry(in):
252  */
253 static int
255 {
256  if (csect_enter (thread_p, CSECT_CT_OID_TABLE, INF_WAIT) != NO_ERROR)
257  {
258  return ER_FAILED;
259  }
260 
261  catcls_Class_oid_to_oid_hash_table = mht_create ("Class OID to OID", num_entry, oid_hash, oid_compare_equals);
262 
263  if (catcls_Class_oid_to_oid_hash_table == NULL)
264  {
265  csect_exit (thread_p, CSECT_CT_OID_TABLE);
266  return ER_FAILED;
267  }
268 
269  csect_exit (thread_p, CSECT_CT_OID_TABLE);
270 
271  return NO_ERROR;
272 }
273 
274 /*
275  * catcls_finalize_class_oid_to_oid_hash_table () -
276  * return:
277  * thread_p(in):
278  */
279 int
281 {
282  CATCLS_ENTRY *entry_p, *next_p;
283 
284  if (csect_enter (thread_p, CSECT_CT_OID_TABLE, INF_WAIT) != NO_ERROR)
285  {
286  return ER_FAILED;
287  }
288 
289  if (catcls_Class_oid_to_oid_hash_table)
290  {
291  mht_map (catcls_Class_oid_to_oid_hash_table, catcls_free_entry_kv, NULL);
292  mht_destroy (catcls_Class_oid_to_oid_hash_table);
293  }
294 
295  for (entry_p = catcls_Free_entry_list; entry_p; entry_p = next_p)
296  {
297  next_p = entry_p->next;
298  free_and_init (entry_p);
299  }
300  catcls_Free_entry_list = NULL;
301  catcls_Class_oid_to_oid_hash_table = NULL;
302 
303  csect_exit (thread_p, CSECT_CT_OID_TABLE);
304 
305  return NO_ERROR;
306 }
307 
308 /*
309  * catcls_find_oid () -
310  * return:
311  * thread_p(in):
312  * class_oid(in):
313  */
314 static OID *
315 catcls_find_oid (THREAD_ENTRY * thread_p, OID * class_oid_p)
316 {
317  CATCLS_ENTRY *entry_p;
318 
319 #if defined (SERVER_MODE)
320  assert (csect_check_own (thread_p, CSECT_CT_OID_TABLE) == 2);
321 #endif
322 
323  if (catcls_Class_oid_to_oid_hash_table)
324  {
325  entry_p = (CATCLS_ENTRY *) mht_get (catcls_Class_oid_to_oid_hash_table, (void *) class_oid_p);
326  if (entry_p != NULL)
327  {
328  return &entry_p->oid;
329  }
330  else
331  {
332  return NULL;
333  }
334  }
335 
336  return NULL;
337 }
338 
339 /*
340  * catcls_put_entry () -
341  * return:
342  * thread_p(in):
343  * entry(in):
344  * already_exists(out):
345  */
346 static int
347 catcls_put_entry (THREAD_ENTRY * thread_p, CATCLS_ENTRY * entry_p, bool * already_exists)
348 {
349  const CATCLS_ENTRY *val_p = NULL;
350  *already_exists = true;
351 
352  assert (csect_check_own (thread_p, CSECT_CT_OID_TABLE) == 1);
353 
354  if (catcls_Class_oid_to_oid_hash_table)
355  {
356  val_p =
357  (const CATCLS_ENTRY *) mht_put_if_not_exists (catcls_Class_oid_to_oid_hash_table, &entry_p->class_oid, entry_p);
358  if (val_p == NULL)
359  {
360  return ER_FAILED;
361  }
362 
363  if ((void *) val_p != (void *) entry_p)
364  {
365  assert (OID_EQ (&val_p->class_oid, &entry_p->class_oid));
366  assert (OID_EQ (&val_p->oid, &entry_p->oid));
367  *already_exists = true;
368  }
369  else
370  {
371  *already_exists = false;
372  }
373  }
374 
375  return NO_ERROR;
376 }
377 
378 /*
379  * catcls_remove_entry () -
380  * return:
381  * thread_p(in):
382  * class_oid(in):
383  */
384 int
385 catcls_remove_entry (THREAD_ENTRY * thread_p, OID * class_oid_p)
386 {
387  assert (csect_check_own (thread_p, CSECT_CT_OID_TABLE) == 1);
388 
389  if (catcls_Class_oid_to_oid_hash_table)
390  {
391  mht_rem (catcls_Class_oid_to_oid_hash_table, class_oid_p, catcls_free_entry_kv, NULL);
392  }
393 
394  return NO_ERROR;
395 }
396 
397 /*
398  * catcls_replace_entry_oid () - replace entry OID
399  * return: error code
400  * thread_p(in): thread entry
401  * entry_class_oid(in): entry class OID
402  * entry_new_oid(in): entry new OID
403  */
404 int
405 catcls_replace_entry_oid (THREAD_ENTRY * thread_p, OID * entry_class_oid, OID * entry_new_oid)
406 {
407  CATCLS_ENTRY *entry_p;
408 
409  assert (csect_check_own (thread_p, CSECT_CT_OID_TABLE) == 1);
410 
411  if (catcls_Class_oid_to_oid_hash_table)
412  {
413  entry_p = (CATCLS_ENTRY *) mht_get (catcls_Class_oid_to_oid_hash_table, (void *) entry_class_oid);
414  if (entry_p != NULL)
415  {
416  COPY_OID (&entry_p->oid, entry_new_oid);
417  return NO_ERROR;
418  }
419  else
420  {
421  return ER_FAILED;
422  }
423  }
424 
425  return NO_ERROR;
426 }
427 
428 /*
429  * catcls_unpack_allocator () -
430  * return:
431  * size(in):
432  */
433 static char *
435 {
436  return ((char *) malloc (size));
437 }
438 
439 /*
440  * catcls_allocate_or_value () -
441  * return:
442  * size(in):
443  */
444 static OR_VALUE *
446 {
447  OR_VALUE *value_p;
448  int i;
449  size_t msize;
450 
451  msize = size * sizeof (OR_VALUE);
452  value_p = (OR_VALUE *) malloc (msize);
453  if (value_p == NULL)
454  {
456  }
457  else
458  {
459  for (i = 0; i < size; i++)
460  {
461  db_value_put_null (&value_p[i].value);
462  value_p[i].sub.value = NULL;
463  value_p[i].sub.count = -1;
464  }
465  }
466 
467  return (value_p);
468 }
469 
470 /*
471  * cr_free_sub_value () -
472  * return:
473  * values(in):
474  * count(in):
475  */
476 static void
478 {
479  int i;
480 
481  if (values != NULL)
482  {
483  for (i = 0; i < count; i++)
484  {
485  pr_clear_value (&values[i].value);
486  catcls_free_sub_value (values[i].sub.value, values[i].sub.count);
487  }
488  free_and_init (values);
489  }
490 }
491 
492 /*
493  * catcls_free_or_value () -
494  * return:
495  * value(in):
496  */
497 static void
499 {
500  if (value_p != NULL)
501  {
502  pr_clear_value (&value_p->value);
503  catcls_free_sub_value (value_p->sub.value, value_p->sub.count);
504  free_and_init (value_p);
505  }
506 }
507 
508 /*
509  * catcls_expand_or_value_by_def () -
510  * return:
511  * value(in):
512  * def(in):
513  */
514 static int
516 {
517  OR_VALUE *attrs_p;
518  int n_attrs;
519  CT_ATTR *att_def_p;
520  int i;
521  int error;
522 
523  if (value_p != NULL)
524  {
525  /* index_of */
526  COPY_OID (&value_p->id.classoid, &def_p->cc_classoid);
527 
528  n_attrs = def_p->cc_n_atts;
529  attrs_p = catcls_allocate_or_value (n_attrs);
530  if (attrs_p == NULL)
531  {
533  }
534 
535  value_p->sub.value = attrs_p;
536  value_p->sub.count = n_attrs;
537 
538  att_def_p = def_p->cc_atts;
539  for (i = 0; i < n_attrs; i++)
540  {
541  attrs_p[i].id.attrid = att_def_p[i].ca_id;
542  error =
543  db_value_domain_init (&attrs_p[i].value, att_def_p[i].ca_type, DB_DEFAULT_PRECISION, DB_DEFAULT_SCALE);
544  if (error != NO_ERROR)
545  {
546  return error;
547  }
548  }
549  }
550 
551  return NO_ERROR;
552 }
553 
554 /*
555  * catcls_guess_record_length () -
556  * return:
557  * value(in):
558  */
559 static int
561 {
562  int length;
564  PR_TYPE *map_p;
565  OR_VALUE *attrs_p;
566  int n_attrs, i;
567 
568  attrs_p = value_p->sub.value;
569  n_attrs = value_p->sub.count;
570 
571  length = OR_MVCC_MAX_HEADER_SIZE + OR_VAR_TABLE_SIZE (n_attrs) + OR_BOUND_BIT_BYTES (n_attrs);
572 
573  for (i = 0; i < n_attrs; i++)
574  {
575  data_type = DB_VALUE_DOMAIN_TYPE (&attrs_p[i].value);
576  map_p = tp_Type_id_map[data_type];
577  length += map_p->get_disk_size_of_value (&attrs_p[i].value);
578  }
579 
580  return (length);
581 }
582 
583 /*
584  * catcls_find_class_oid_by_class_name () -
585  * return:
586  * name(in):
587  * class_oid(in):
588  */
589 static int
590 catcls_find_class_oid_by_class_name (THREAD_ENTRY * thread_p, const char *name_p, OID * class_oid_p)
591 {
592  LC_FIND_CLASSNAME status;
593 
594  status = xlocator_find_class_oid (thread_p, name_p, class_oid_p, NULL_LOCK);
595 
596  if (status == LC_CLASSNAME_ERROR)
597  {
599  return ER_FAILED;
600  }
601  else if (status == LC_CLASSNAME_DELETED)
602  {
603  /* not found the class */
604  OID_SET_NULL (class_oid_p);
605  }
606 
607  return NO_ERROR;
608 }
609 
610 /*
611  * catcls_find_btid_of_class_name () -
612  * return:
613  * btid(in):
614  */
615 static int
617 {
618  DISK_REPR *repr_p = NULL;
619  DISK_ATTR *att_repr_p;
620  REPR_ID repr_id;
621  OID *index_class_p;
622  ATTR_ID index_key;
623  int error = NO_ERROR;
624 
625  index_class_p = &ct_Class.cc_classoid;
626  index_key = (ct_Class.cc_atts)[CATCLS_INDEX_KEY].ca_id;
627 
628  error = catalog_get_last_representation_id (thread_p, index_class_p, &repr_id);
629  if (error != NO_ERROR)
630  {
631  goto error;
632  }
633  else
634  {
635  repr_p = catalog_get_representation (thread_p, index_class_p, repr_id, NULL);
636  if (repr_p == NULL)
637  {
638  assert (er_errid () != NO_ERROR);
639  error = er_errid ();
640  goto error;
641  }
642  }
643 
644  for (att_repr_p = repr_p->variable; att_repr_p->id != index_key; att_repr_p++)
645  {
646  ;
647  }
648 
649  if (att_repr_p->bt_stats == NULL)
650  {
651  error = ER_SM_NO_INDEX;
653  goto error;
654 
655  }
656  else
657  {
658  BTID_COPY (btid_p, &(att_repr_p->bt_stats->btid));
659  }
660 
662  return NO_ERROR;
663 
664 error:
665 
666  if (repr_p)
667  {
669  }
670 
671  return error;
672 }
673 
674 /*
675  * catcls_find_oid_by_class_name () - Get an instance oid in the ct_Class using the
676  * index for classname
677  * return:
678  * name(in):
679  * oid(in):
680  */
681 static int
682 catcls_find_oid_by_class_name (THREAD_ENTRY * thread_p, const char *name_p, OID * oid_p)
683 {
684  DB_VALUE key_val;
685  int error = NO_ERROR;
686 
687  error = db_make_varchar (&key_val, DB_MAX_IDENTIFIER_LENGTH, name_p, (int) strlen (name_p), LANG_SYS_CODESET,
689  if (error != NO_ERROR)
690  {
691  return error;
692  }
693 
694  error = xbtree_find_unique (thread_p, &catcls_Btid, S_SELECT, &key_val, &ct_Class.cc_classoid, oid_p, false);
695  if (error == BTREE_ERROR_OCCURRED)
696  {
697  pr_clear_value (&key_val);
698  assert (er_errid () != NO_ERROR);
699  error = er_errid ();
700  return ((error == NO_ERROR) ? ER_FAILED : error);
701  }
702  else if (error == BTREE_KEY_NOTFOUND)
703  {
704  OID_SET_NULL (oid_p);
705  }
706 
707  pr_clear_value (&key_val);
708  return NO_ERROR;
709 }
710 
711 /*
712  * catcls_convert_class_oid_to_oid () -
713  * return:
714  * oid_val(in):
715  */
716 static int
718 {
719  char *name_p = NULL;
720  OID oid_buf;
721  OID *class_oid_p, *oid_p;
722  CATCLS_ENTRY *entry_p;
723  bool already_exists;
724 
725  if (DB_IS_NULL (oid_val_p))
726  {
727  return NO_ERROR;
728  }
729 
730  class_oid_p = db_get_oid (oid_val_p);
731 
733  {
734  return ER_FAILED;
735  }
736 
737  oid_p = catcls_find_oid (thread_p, class_oid_p);
738 
739  csect_exit (thread_p, CSECT_CT_OID_TABLE);
740 
741  if (oid_p == NULL)
742  {
743  oid_p = &oid_buf;
744  if (heap_get_class_name (thread_p, class_oid_p, &name_p) != NO_ERROR)
745  {
746  /* class_oid object may be deleted */
747  ASSERT_ERROR ();
748  db_make_null (oid_val_p);
749 
750  return er_errid ();
751  }
752 
753  if (name_p == NULL)
754  {
755  /* this is only possible if ER_HEAP_NODATA_NEWADDRESS occur */
756  db_make_null (oid_val_p);
757  return NO_ERROR;
758  }
759 
760  if (catcls_find_oid_by_class_name (thread_p, name_p, oid_p) != NO_ERROR)
761  {
762  free_and_init (name_p);
763 
764  assert (er_errid () != NO_ERROR);
765  return er_errid ();
766  }
767 
768  if (!OID_ISNULL (oid_p))
769  {
770  if (csect_enter (thread_p, CSECT_CT_OID_TABLE, INF_WAIT) != NO_ERROR)
771  {
772  return ER_FAILED;
773  }
774 
775  if ((entry_p = catcls_allocate_entry (thread_p)) != NULL)
776  {
777  COPY_OID (&entry_p->class_oid, class_oid_p);
778  COPY_OID (&entry_p->oid, oid_p);
779  catcls_put_entry (thread_p, entry_p, &already_exists);
780  /* if it already exists, just free current entry_p */
781  if (already_exists)
782  {
783  catcls_free_entry (entry_p);
784  }
785  }
786 
787  csect_exit (thread_p, CSECT_CT_OID_TABLE);
788  }
789  }
790 
791  db_make_oid (oid_val_p, oid_p);
792 
793  if (name_p)
794  {
795  free_and_init (name_p);
796  }
797 
798  return NO_ERROR;
799 }
800 
801 /*
802  * catcls_convert_attr_id_to_name () -
803  * return:
804  * obuf(in):
805  * value(in):
806  */
807 static int
808 catcls_convert_attr_id_to_name (THREAD_ENTRY * thread_p, OR_BUF * orbuf_p, OR_VALUE * value_p)
809 {
810  OR_BUF *buf_p, orep;
811  OR_VALUE *indexes, *keys;
812  OR_VALUE *index_atts, *key_atts;
813  OR_VALUE *id_val_p = NULL, *id_atts;
814  OR_VALUE *ids;
815  OR_VARINFO *vars = NULL;
816  int id;
817  int size;
818  int i, j, k;
819  int error = NO_ERROR;
820 
821  buf_p = &orep;
822  or_init (buf_p, orbuf_p->buffer, (int) (orbuf_p->endptr - orbuf_p->buffer));
823 
825 
827  vars = or_get_var_table (buf_p, size, catcls_unpack_allocator);
828  if (vars == NULL)
829  {
830  size_t msize = size * sizeof (OR_VARINFO);
831  error = ER_OUT_OF_VIRTUAL_MEMORY;
832  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, msize);
833 
834  return error;
835  }
836 
837  /* jump to the 'attributes' and extract its id/name. there are no indexes for shared or class attributes, so we need
838  * only id/name for 'attributes'. the offsets are relative to end of the class record header */
839  or_seek (buf_p, vars[ORC_ATTRIBUTES_INDEX].offset + OR_NON_MVCC_HEADER_SIZE);
840 
841  id_val_p = catcls_allocate_or_value (1);
842  if (id_val_p == NULL)
843  {
844  free_and_init (vars);
846  }
847 
848  error =
849  catcls_get_subset (thread_p, buf_p, vars[ORC_ATTRIBUTES_INDEX].length, id_val_p, catcls_get_or_value_from_attrid);
850  if (error != NO_ERROR)
851  {
852  free_and_init (vars);
853  free_and_init (id_val_p);
854  return error;
855  }
856 
857  /* replace id with name for each key attribute */
858  for (indexes = value_p->sub.value, i = 0; i < value_p->sub.count; i++)
859  {
860  index_atts = indexes[i].sub.value;
861 
862  for (keys = (index_atts[4]).sub.value, j = 0; j < (index_atts[4]).sub.count; j++)
863  {
864  key_atts = keys[j].sub.value;
865 
866  if (!DB_IS_NULL (&key_atts[1].value))
867  {
868  id = db_get_int (&key_atts[1].value);
869 
870  for (ids = id_val_p->sub.value, k = 0; k < id_val_p->sub.count; k++)
871  {
872  id_atts = ids[k].sub.value;
873  if (!DB_IS_NULL (&id_atts[0].value) && id == db_get_int (&id_atts[0].value))
874  {
875  pr_clear_value (&key_atts[1].value);
876  pr_clone_value (&id_atts[1].value, &key_atts[1].value);
877  }
878  }
879  }
880  }
881  }
882 
883  catcls_free_or_value (id_val_p);
884  free_and_init (vars);
885 
886  return NO_ERROR;
887 }
888 
889 /*
890  * catcls_apply_component_type () -
891  * return:
892  * value(in):
893  * type(in):
894  */
895 static void
897 {
898  OR_VALUE *subset_p, *attrs;
899  int i;
900 
901  for (subset_p = value_p->sub.value, i = 0; i < value_p->sub.count; i++)
902  {
903  attrs = subset_p[i].sub.value;
904  /* assume that the attribute values of xxx are ordered by { class_of, xxx_name, xxx_type, from_xxx_name, ... } */
905  db_make_int (&attrs[2].value, type);
906  }
907 }
908 
909 /*
910  * catcls_resolution_space () - modified of sm_resolution_space()
911  * return:
912  * name_space(in):
913  *
914  * TODO: need to integrate
915  */
916 static int
917 catcls_resolution_space (int name_space)
918 {
919  int res_space = 5; /* ID_INSTANCE */
920 
921  /* TODO: is ID_CLASS_ATTRIBUTE corret?? */
922  if (name_space == 1) /* ID_SHARED_ATTRIBUTE */
923  {
924  res_space = 6; /* ID_CLASS */
925  }
926 
927  return res_space;
928 }
929 
930 /*
931  * catcls_apply_resolutions () -
932  * return:
933  * value(in):
934  * res(in):
935  */
936 static void
937 catcls_apply_resolutions (OR_VALUE * value_p, OR_VALUE * resolution_p)
938 {
939  OR_VALUE *subset_p, *resolution_subset_p;
940  OR_VALUE *attrs, *res_attrs;
941  int i, j;
942  int attr_name_space;
943 
944  for (resolution_subset_p = resolution_p->sub.value, i = 0; i < resolution_p->sub.count; i++)
945  {
946  res_attrs = resolution_subset_p[i].sub.value;
947 
948  for (subset_p = value_p->sub.value, j = 0; j < value_p->sub.count; j++)
949  {
950  attrs = subset_p[j].sub.value;
951 
952  /* assume that the attribute values of xxx are ordered by { class_of, xxx_name, xxx_type, from_xxx_name, ...
953  * } */
954 
955  /* compare component name & name space */
956  if (tp_value_compare (&attrs[1].value, &res_attrs[1].value, 1, 0) == DB_EQ)
957  {
958  attr_name_space = catcls_resolution_space (db_get_int (&attrs[2].value));
959  if (attr_name_space == db_get_int (&res_attrs[2].value))
960  {
961  /* set the value as 'from_xxx_name' */
962  pr_clear_value (&attrs[3].value);
963  pr_clone_value (&res_attrs[3].value, &attrs[3].value);
964  }
965  }
966  }
967  }
968 }
969 
970 /*
971  * catcls_get_or_value_from_class () -
972  * return:
973  * buf(in):
974  * value(in):
975  */
976 static int
978 {
979  OR_VALUE *attrs;
980  DB_VALUE *attr_val_p;
981  OR_VARINFO *vars = NULL;
982  int size;
983  OR_VALUE *resolution_p = NULL;
984  OID class_oid;
985  int error = NO_ERROR;
986 
987  error = catcls_expand_or_value_by_def (value_p, &ct_Class);
988  if (error != NO_ERROR)
989  {
990  goto error;
991  }
992 
993  attrs = value_p->sub.value;
994 
997  vars = or_get_var_table (buf_p, size, catcls_unpack_allocator);
998  if (vars == NULL)
999  {
1000  size_t msize = size * sizeof (OR_VARINFO);
1001 
1002  error = ER_OUT_OF_VIRTUAL_MEMORY;
1003  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, msize);
1004  goto error;
1005  }
1006 
1007  /* fixed */
1008 
1010 
1011  /* attribute_count */
1012  tp_Integer.data_readval (buf_p, &attrs[1].value, NULL, -1, true, NULL, 0);
1013 
1014  /* object_size */
1015  or_advance (buf_p, OR_INT_SIZE);
1016 
1017  /* shared_count */
1018  tp_Integer.data_readval (buf_p, &attrs[2].value, NULL, -1, true, NULL, 0);
1019 
1020  /* method_count */
1021  tp_Integer.data_readval (buf_p, &attrs[3].value, NULL, -1, true, NULL, 0);
1022 
1023  /* class_method_count */
1024  tp_Integer.data_readval (buf_p, &attrs[4].value, NULL, -1, true, NULL, 0);
1025 
1026  /* class_att_count */
1027  tp_Integer.data_readval (buf_p, &attrs[5].value, NULL, -1, true, NULL, 0);
1028 
1029  /* flags */
1030  tp_Integer.data_readval (buf_p, &attrs[6].value, NULL, -1, true, NULL, 0);
1031 
1032  /* class_type */
1033  tp_Integer.data_readval (buf_p, &attrs[7].value, NULL, -1, true, NULL, 0);
1034 
1035  /* owner */
1036  tp_Object.data_readval (buf_p, &attrs[8].value, NULL, -1, true, NULL, 0);
1037 
1038  /* collation_id */
1039  tp_Integer.data_readval (buf_p, &attrs[9].value, NULL, -1, true, NULL, 0);
1040 
1041  /* tde_algorithm */
1042  tp_Integer.data_readval (buf_p, &attrs[10].value, NULL, -1, true, NULL, 0);
1043 
1044  /* variable */
1045 
1046  /* name */
1047  attr_val_p = &attrs[11].value;
1048  tp_String.data_readval (buf_p, attr_val_p, NULL, vars[ORC_NAME_INDEX].length, true, NULL, 0);
1050 
1051  /* (class_of) */
1052  if (catcls_find_class_oid_by_class_name (thread_p, db_get_string (&attrs[11].value), &class_oid) != NO_ERROR)
1053  {
1054  assert (er_errid () != NO_ERROR);
1055  error = er_errid ();
1056  goto error;
1057  }
1058  db_make_oid (&attrs[0].value, &class_oid);
1059 
1060  /* loader_commands */
1061  or_advance (buf_p, vars[ORC_LOADER_COMMANDS_INDEX].length);
1062 
1063  /* representations */
1064  or_advance (buf_p, vars[ORC_REPRESENTATIONS_INDEX].length);
1065 
1066  /* sub_classes */
1067  error = catcls_get_object_set (thread_p, buf_p, vars[ORC_SUBCLASSES_INDEX].length, &attrs[12]);
1068  if (error != NO_ERROR)
1069  {
1070  goto error;
1071  }
1072 
1073  /* super_classes */
1074  error = catcls_get_object_set (thread_p, buf_p, vars[ORC_SUPERCLASSES_INDEX].length, &attrs[13]);
1075  if (error != NO_ERROR)
1076  {
1077  goto error;
1078  }
1079 
1080  /* attributes */
1081  error =
1082  catcls_get_subset (thread_p, buf_p, vars[ORC_ATTRIBUTES_INDEX].length, &attrs[14],
1084  if (error != NO_ERROR)
1085  {
1086  goto error;
1087  }
1088 
1089  /* shared_attributes */
1090  error =
1091  catcls_get_subset (thread_p, buf_p, vars[ORC_SHARED_ATTRS_INDEX].length, &attrs[15],
1093  if (error != NO_ERROR)
1094  {
1095  goto error;
1096  }
1097 
1098  /* class_attributes */
1099  error =
1100  catcls_get_subset (thread_p, buf_p, vars[ORC_CLASS_ATTRS_INDEX].length, &attrs[16],
1102  if (error != NO_ERROR)
1103  {
1104  goto error;
1105  }
1106 
1107  /* methods */
1108  error =
1109  catcls_get_subset (thread_p, buf_p, vars[ORC_METHODS_INDEX].length, &attrs[17], catcls_get_or_value_from_method);
1110  if (error != NO_ERROR)
1111  {
1112  goto error;
1113  }
1114 
1115  /* class_methods */
1116  error =
1117  catcls_get_subset (thread_p, buf_p, vars[ORC_CLASS_METHODS_INDEX].length, &attrs[18],
1119  if (error != NO_ERROR)
1120  {
1121  goto error;
1122  }
1123 
1124  /* (apply attribute & method type) */
1125  catcls_apply_component_type (&attrs[14], 0);
1126  catcls_apply_component_type (&attrs[15], 2);
1127  catcls_apply_component_type (&attrs[16], 1);
1128  catcls_apply_component_type (&attrs[17], 0);
1129  catcls_apply_component_type (&attrs[18], 1);
1130 
1131  /* method_files */
1132  error =
1133  catcls_get_subset (thread_p, buf_p, vars[ORC_METHOD_FILES_INDEX].length, &attrs[19],
1135  if (error != NO_ERROR)
1136  {
1137  goto error;
1138  }
1139 
1140  /* (resolutions) */
1141  if (vars[ORC_RESOLUTIONS_INDEX].length > 0)
1142  {
1143  resolution_p = catcls_allocate_or_value (1);
1144  if (resolution_p == NULL)
1145  {
1146  error = ER_OUT_OF_VIRTUAL_MEMORY;
1147  goto error;
1148  }
1149 
1150  error =
1151  catcls_get_subset (thread_p, buf_p, vars[ORC_RESOLUTIONS_INDEX].length, resolution_p,
1153  if (error != NO_ERROR)
1154  {
1155  goto error;
1156  }
1157 
1158  catcls_apply_resolutions (&attrs[14], resolution_p);
1159  catcls_apply_resolutions (&attrs[15], resolution_p);
1160  catcls_apply_resolutions (&attrs[16], resolution_p);
1161  catcls_apply_resolutions (&attrs[17], resolution_p);
1162  catcls_apply_resolutions (&attrs[18], resolution_p);
1163  catcls_free_or_value (resolution_p);
1164  resolution_p = NULL;
1165  }
1166 
1167  /* query_spec */
1168  error =
1169  catcls_get_subset (thread_p, buf_p, vars[ORC_QUERY_SPEC_INDEX].length, &attrs[20],
1171  if (error != NO_ERROR)
1172  {
1173  goto error;
1174  }
1175 
1176  /* triggers */
1177  or_advance (buf_p, vars[ORC_TRIGGERS_INDEX].length);
1178 
1179  /* properties */
1180  error = catcls_get_property_set (thread_p, buf_p, vars[ORC_PROPERTIES_INDEX].length, &attrs[21]);
1181  if (error != NO_ERROR)
1182  {
1183  goto error;
1184  }
1185 
1186  /* comment */
1187  attr_val_p = &attrs[22].value;
1188  tp_String.data_readval (buf_p, attr_val_p, NULL, vars[ORC_COMMENT_INDEX].length, true, NULL, 0);
1190 
1191  /* partition information */
1192  error =
1193  catcls_get_subset (thread_p, buf_p, vars[ORC_PARTITION_INDEX].length, &attrs[23],
1195  if (error != NO_ERROR)
1196  {
1197  goto error;
1198  }
1199 
1200  if (vars)
1201  {
1202  free_and_init (vars);
1203  }
1204 
1205  return NO_ERROR;
1206 
1207 error:
1208 
1209  if (vars)
1210  {
1211  free_and_init (vars);
1212  }
1213 
1214  if (resolution_p)
1215  {
1216  catcls_free_or_value (resolution_p);
1217  }
1218 
1219  return error;
1220 }
1221 
1222 /*
1223  * catcls_get_or_value_from_attribute () -
1224  * return:
1225  * buf(in):
1226  * value(in):
1227  */
1228 static int
1230 {
1231  OR_VALUE *attrs;
1232  DB_VALUE *attr_val_p;
1233  DB_VALUE default_expr, val, db_value_default_expr_type, db_value_default_expr_format, db_value_default_expr_op;
1234  DB_DEFAULT_EXPR_TYPE default_expr_type;
1235  DB_SEQ *def_expr_seq = NULL;
1236  DB_SEQ *att_props = NULL;
1237  OR_VARINFO *vars = NULL;
1238  int size;
1239  int error = NO_ERROR;
1240  const char *default_expr_type_string = NULL;
1241  const char *def_expr_format_string = NULL;
1242  bool with_to_char = false;
1243 
1244  error = catcls_expand_or_value_by_def (value_p, &ct_Attribute);
1245  if (error != NO_ERROR)
1246  {
1247  goto error;
1248  }
1249 
1250  /* The order of attrs[] is same with that of ct_attribute_atts[]. */
1251  attrs = value_p->sub.value;
1252 
1255  vars = or_get_var_table (buf_p, size, catcls_unpack_allocator);
1256  if (vars == NULL)
1257  {
1258  size_t msize = size * sizeof (OR_VARINFO);
1259 
1260  error = ER_OUT_OF_VIRTUAL_MEMORY;
1261  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, msize);
1262  goto error;
1263  }
1264 
1265  /* id */
1266  or_advance (buf_p, OR_INT_SIZE);
1267 
1268  /* type */
1269  tp_Integer.data_readval (buf_p, &attrs[4].value, NULL, -1, true, NULL, 0);
1270 
1271  /* offset */
1272  or_advance (buf_p, OR_INT_SIZE);
1273 
1274  /* order */
1275  tp_Integer.data_readval (buf_p, &attrs[5].value, NULL, -1, true, NULL, 0);
1276 
1277  /* class */
1278  attr_val_p = &attrs[6].value;
1279  tp_Object.data_readval (buf_p, attr_val_p, NULL, -1, true, NULL, 0);
1280  error = catcls_convert_class_oid_to_oid (thread_p, attr_val_p);
1281  if (error != NO_ERROR)
1282  {
1283  ASSERT_ERROR ();
1284  goto error;
1285  }
1286 
1287  /* flag */
1288  attr_val_p = &attrs[7].value;
1289  tp_Integer.data_readval (buf_p, attr_val_p, NULL, -1, true, NULL, 0);
1290 
1291  /* for 'is_nullable', reverse NON_NULL flag */
1292  db_make_int (attr_val_p, (db_get_int (attr_val_p) & SM_ATTFLAG_NON_NULL) ? false : true);
1293 
1294  /* index_file_id */
1295  or_advance (buf_p, OR_INT_SIZE);
1296 
1297  /* index_root_pageid */
1298  or_advance (buf_p, OR_INT_SIZE);
1299 
1300  /* index_volid_key */
1301  or_advance (buf_p, OR_INT_SIZE);
1302 
1305  /* name */
1306  attr_val_p = &attrs[1].value;
1307  tp_String.data_readval (buf_p, attr_val_p, NULL, vars[ORC_ATT_NAME_INDEX].length, true, NULL, 0);
1309 
1310  /* default value */
1311  attr_val_p = &attrs[8].value;
1312  or_get_value (buf_p, attr_val_p, NULL, vars[ORC_ATT_CURRENT_VALUE_INDEX].length, true);
1313 
1314  /* original value - advance only */
1315  or_advance (buf_p, vars[ORC_ATT_ORIGINAL_VALUE_INDEX].length);
1316 
1317  /* domain */
1318  error =
1319  catcls_get_subset (thread_p, buf_p, vars[ORC_ATT_DOMAIN_INDEX].length, &attrs[9], catcls_get_or_value_from_domain);
1320  if (error != NO_ERROR)
1321  {
1322  goto error;
1323  }
1324 
1325  /* Complete default value of enumeration type. We need to access domain structure of the attribute in order to get
1326  * access to the elements of enumeration type. */
1327  if (DB_VALUE_TYPE (attr_val_p) == DB_TYPE_ENUMERATION && attrs[9].sub.count > 0)
1328  {
1329  OR_VALUE *or_val = attrs[9].sub.value;
1330 
1331  if (or_val == NULL || or_val->sub.count < 8)
1332  {
1333  error = ER_FAILED;
1334  goto error;
1335  }
1336  or_val = or_val[0].sub.value;
1337  if (or_val == NULL)
1338  {
1339  error = ER_FAILED;
1340  goto error;
1341  }
1342  or_val = &or_val[7];
1343  if (!TP_IS_SET_TYPE (DB_VALUE_TYPE (&or_val->value))
1344  || db_get_enum_short (attr_val_p) > or_val->value.data.set->set->size)
1345  {
1346  error = ER_FAILED;
1347  goto error;
1348  }
1349  error = set_get_element (db_get_set (&or_val->value), db_get_enum_short (attr_val_p) - 1, &val);
1350  if (error != NO_ERROR)
1351  {
1352  goto error;
1353  }
1354 
1355  val.need_clear = false;
1356  db_make_enumeration (attr_val_p, db_get_enum_short (attr_val_p), db_get_string (&val), db_get_string_size (&val),
1357  db_get_enum_codeset (attr_val_p), db_get_enum_collation (attr_val_p));
1358  attr_val_p->need_clear = true;
1359  }
1360  /* triggers - advance only */
1361  or_advance (buf_p, vars[ORC_ATT_TRIGGER_INDEX].length);
1362 
1363  /* properties */
1365  att_props = db_get_set (&val);
1366  attr_val_p = &attrs[8].value;
1367  db_make_null (&default_expr);
1368  if (att_props != NULL)
1369  {
1370  size_t default_value_len = 0;
1371  const char *default_str_val = NULL;
1372 
1373  if (classobj_get_prop (att_props, "default_expr", &default_expr) > 0)
1374  {
1375  size_t len;
1376 
1377  if (DB_VALUE_TYPE (&default_expr) == DB_TYPE_SEQUENCE)
1378  {
1379  assert (set_size (db_get_set (&default_expr)) == 3);
1380  def_expr_seq = db_get_set (&default_expr);
1381 
1382  error = set_get_element_nocopy (def_expr_seq, 0, &db_value_default_expr_op);
1383  if (error != NO_ERROR)
1384  {
1385  goto error;
1386  }
1387  assert (DB_VALUE_TYPE (&db_value_default_expr_op) == DB_TYPE_INTEGER
1388  && db_get_int (&db_value_default_expr_op) == (int) T_TO_CHAR);
1389  with_to_char = true;
1390 
1391  error = set_get_element_nocopy (def_expr_seq, 1, &db_value_default_expr_type);
1392  if (error != NO_ERROR)
1393  {
1394  goto error;
1395  }
1396  default_expr_type = (DB_DEFAULT_EXPR_TYPE) db_get_int (&db_value_default_expr_type);
1397 
1398  error = set_get_element_nocopy (def_expr_seq, 2, &db_value_default_expr_format);
1399  if (error != NO_ERROR)
1400  {
1401  goto error;
1402  }
1403 
1404  if (!db_value_is_null (&db_value_default_expr_format))
1405  {
1406 #if !defined(NDEBUG)
1407  DB_TYPE db_value_type_local = db_value_type (&db_value_default_expr_format);
1408  assert (db_value_type_local == DB_TYPE_NULL || db_value_type_local == DB_TYPE_CHAR
1409  || db_value_type_local == DB_TYPE_NCHAR || db_value_type_local == DB_TYPE_VARCHAR
1410  || db_value_type_local == DB_TYPE_VARNCHAR);
1411 #endif
1412  assert (DB_VALUE_TYPE (&db_value_default_expr_format) == DB_TYPE_STRING);
1413  def_expr_format_string = db_get_string (&db_value_default_expr_format);
1414  }
1415  }
1416  else
1417  {
1418  default_expr_type = (DB_DEFAULT_EXPR_TYPE) db_get_int (&default_expr);
1419  }
1420 
1421  default_expr_type_string = db_default_expression_string (default_expr_type);
1422  if (default_expr_type_string == NULL)
1423  {
1424  pr_clear_value (&default_expr);
1425  pr_clear_value (&val);
1426  assert (false);
1427  error = ER_GENERIC_ERROR;
1429  goto error;
1430  }
1431  len = strlen (default_expr_type_string);
1432  char *default_str_val_tmp = NULL;
1433 
1434  if (with_to_char)
1435  {
1436  const char *default_expr_op_string = qdump_operator_type_string (T_TO_CHAR);
1437  assert (default_expr_op_string != NULL);
1438 
1439  len += ((default_expr_op_string ? strlen (default_expr_op_string) : 0) /* to_char */
1440  + 6 /* parenthesis, a comma, a blank and quotes */
1441  + (def_expr_format_string ? strlen (def_expr_format_string) : 0)); /* nothing or format */
1442 
1443  default_str_val_tmp = (char *) db_private_alloc (thread_p, len + 1);
1444  if (default_str_val_tmp == NULL)
1445  {
1446  pr_clear_value (&default_expr);
1447  pr_clear_value (&val);
1448  error = ER_OUT_OF_VIRTUAL_MEMORY;
1449  goto error;
1450  }
1451 
1452  strcpy (default_str_val_tmp, default_expr_op_string);
1453  strcat (default_str_val_tmp, "(");
1454  strcat (default_str_val_tmp, default_expr_type_string);
1455  if (def_expr_format_string)
1456  {
1457  strcat (default_str_val_tmp, ", \'");
1458  strcat (default_str_val_tmp, def_expr_format_string);
1459  strcat (default_str_val_tmp, "\'");
1460  }
1461  strcat (default_str_val_tmp, ")");
1462  }
1463  else
1464  {
1465  default_str_val_tmp = (char *) db_private_alloc (thread_p, len + 1);
1466  if (default_str_val_tmp == NULL)
1467  {
1468  pr_clear_value (&default_expr);
1469  pr_clear_value (&val);
1470  error = ER_OUT_OF_VIRTUAL_MEMORY;
1471  goto error;
1472  }
1473  strcpy (default_str_val_tmp, default_expr_type_string);
1474  }
1475  default_str_val = default_str_val_tmp;
1476 
1477  pr_clear_value (attr_val_p); /* clean old default value */
1478  db_make_string (attr_val_p, default_str_val);
1479  attr_val_p->need_clear = true;
1480  default_value_len = len;
1481  }
1482  else
1483  {
1484  /* update_default exists and default_expr is not a DEFAULT EXPRESSION or does not exist */
1485  valcnv_convert_value_to_string (attr_val_p);
1487  default_str_val = db_get_string (attr_val_p);
1488  if (default_str_val != NULL)
1489  {
1490  default_value_len = strlen (default_str_val);
1491  }
1492  }
1493 
1494  if (classobj_get_prop (att_props, "update_default", &default_expr) > 0)
1495  {
1496  default_expr_type = (DB_DEFAULT_EXPR_TYPE) db_get_int (&default_expr);
1497 
1498  char *str_val = NULL;
1499  size_t len;
1500  default_expr_type_string = db_default_expression_string (default_expr_type);
1501  if (default_expr_type_string == NULL)
1502  {
1503  pr_clear_value (&default_expr);
1504  pr_clear_value (&val);
1505  assert (false);
1506  error = ER_GENERIC_ERROR;
1508  goto error;
1509  }
1510  len = strlen (default_expr_type_string);
1511 
1512  /* add whitespace character if default_str_val is not an empty string */
1513  str_val =
1514  (char *) db_private_alloc (thread_p,
1515  (default_value_len + (default_value_len ? 1 : 0) + len + strlen ("ON UPDATE ")
1516  + 1));
1517  if (str_val == NULL)
1518  {
1519  pr_clear_value (&default_expr);
1520  pr_clear_value (&val);
1521  error = ER_OUT_OF_VIRTUAL_MEMORY;
1522  goto error;
1523  }
1524  if (default_str_val != NULL)
1525  {
1526  strcpy (str_val, default_str_val);
1527  strcat (str_val, " ON UPDATE ");
1528  strcat (str_val, default_expr_type_string);
1529  }
1530  else
1531  {
1532  strcpy (str_val, "ON UPDATE ");
1533  strcat (str_val, default_expr_type_string);
1534  }
1535 
1536  pr_clear_value (attr_val_p); /* clean old default value */
1537  db_make_string (attr_val_p, str_val);
1538  attr_val_p->need_clear = true;
1539  }
1540  }
1541  else
1542  {
1543  valcnv_convert_value_to_string (attr_val_p);
1544  }
1545  pr_clear_value (&default_expr);
1546  pr_clear_value (&val);
1547  attr_val_p->need_clear = true;
1549 
1550  /* comment */
1551  attr_val_p = &attrs[10].value;
1552  tp_String.data_readval (buf_p, attr_val_p, NULL, vars[ORC_ATT_COMMENT_INDEX].length, true, NULL, 0);
1554 
1555  if (vars)
1556  {
1557  free_and_init (vars);
1558  }
1559 
1560  return NO_ERROR;
1561 
1562 error:
1563 
1564  if (vars)
1565  {
1566  free_and_init (vars);
1567  }
1568 
1569  return error;
1570 }
1571 
1572 /*
1573  * catcls_get_or_value_from_attrid () -
1574  * return:
1575  * buf(in):
1576  * value(in):
1577  */
1578 static int
1580 {
1581  OR_VALUE *attrs;
1582  DB_VALUE *attr_val;
1583  OR_VARINFO *vars = NULL;
1584  int size;
1585  char *start_ptr;
1586  int error = NO_ERROR;
1587 
1588  error = catcls_expand_or_value_by_def (value, &ct_Attrid);
1589  if (error != NO_ERROR)
1590  {
1591  goto error;
1592  }
1593 
1594  attrs = value->sub.value;
1595 
1596  /* variable offset */
1597  start_ptr = buf->ptr;
1598 
1600  vars = or_get_var_table (buf, size, catcls_unpack_allocator);
1601  if (vars == NULL)
1602  {
1603  size_t msize = size * sizeof (OR_VARINFO);
1604 
1605  error = ER_OUT_OF_VIRTUAL_MEMORY;
1606  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, msize);
1607  goto error;
1608  }
1609 
1610  /* id */
1611  tp_Integer.data_readval (buf, &attrs[0].value, NULL, -1, true, NULL, 0);
1612 
1613  or_advance (buf, (int) (start_ptr - buf->ptr) + vars[ORC_ATT_NAME_INDEX].offset);
1614 
1615  /* name */
1616  attr_val = &attrs[1].value;
1617  tp_String.data_readval (buf, attr_val, NULL, vars[ORC_ATT_NAME_INDEX].length, true, NULL, 0);
1619 
1620  /* go to the end */
1621  or_advance (buf, (int) (start_ptr - buf->ptr) + (vars[(size - 1)].offset + vars[(size - 1)].length));
1622 
1623  if (vars)
1624  {
1625  free_and_init (vars);
1626  }
1627 
1628  return NO_ERROR;
1629 
1630 error:
1631 
1632  if (vars)
1633  {
1634  free_and_init (vars);
1635  }
1636 
1637  return error;
1638 }
1639 
1640 /*
1641  * catcls_get_or_value_from_domain () -
1642  * return:
1643  * buf(in):
1644  * value(in):
1645  */
1646 static int
1648 {
1649  OR_VALUE *attrs;
1650  DB_VALUE *attr_val_p;
1651  OR_VARINFO *vars = NULL;
1652  int size;
1653  int error = NO_ERROR;
1654 
1655  error = catcls_expand_or_value_by_def (value_p, &ct_Domain);
1656  if (error != NO_ERROR)
1657  {
1658  goto error;
1659  }
1660 
1661  attrs = value_p->sub.value;
1662 
1665  vars = or_get_var_table (buf_p, size, catcls_unpack_allocator);
1666  if (vars == NULL)
1667  {
1668  size_t msize = size * sizeof (OR_VARINFO);
1669 
1670  error = ER_OUT_OF_VIRTUAL_MEMORY;
1671  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, msize);
1672  goto error;
1673  }
1674 
1675  /* type */
1676  tp_Integer.data_readval (buf_p, &attrs[1].value, NULL, -1, true, NULL, 0);
1677 
1678  /* precision */
1679  tp_Integer.data_readval (buf_p, &attrs[2].value, NULL, -1, true, NULL, 0);
1680 
1681  /* scale */
1682  tp_Integer.data_readval (buf_p, &attrs[3].value, NULL, -1, true, NULL, 0);
1683 
1684  /* codeset */
1685  tp_Integer.data_readval (buf_p, &attrs[4].value, NULL, -1, true, NULL, 0);
1686 
1687  /* collation id */
1688  tp_Integer.data_readval (buf_p, &attrs[5].value, NULL, -1, true, NULL, 0);
1689 
1690  /* class */
1691  attr_val_p = &attrs[6].value;
1692  tp_Object.data_readval (buf_p, attr_val_p, NULL, -1, true, NULL, 0);
1693 
1694  if (!DB_IS_NULL (attr_val_p))
1695  {
1696  error = catcls_convert_class_oid_to_oid (thread_p, attr_val_p);
1697  if (error != NO_ERROR)
1698  {
1699  ASSERT_ERROR ();
1700  if (er_errid () == ER_HEAP_UNKNOWN_OBJECT)
1701  {
1702  /* class oid may be deleted; class_oid will be set to NULL OID */
1703  er_clear ();
1704  assert (DB_IS_NULL (attr_val_p));
1705  }
1706  else
1707  {
1708  goto error;
1709  }
1710  }
1711 
1712  if (DB_IS_NULL (attr_val_p))
1713  {
1714  /* if self reference for example, "class x (a x)" set an invalid data type, and fill its value later */
1716  if (error != NO_ERROR)
1717  {
1718  goto error;
1719  }
1720  }
1721  }
1722 
1723  /* enumeration */
1724  if (vars[ORC_DOMAIN_ENUMERATION_INDEX].length)
1725  {
1726  /* enumerations are stored as a collection of strings */
1729 
1730  TP_DOMAIN *domain = tp_domain_construct (DB_TYPE_SEQUENCE, NULL, 0, 0, string_dom);
1731  if (domain == NULL)
1732  {
1733  error = ER_FAILED;
1734  goto error;
1735  }
1736  domain = tp_domain_cache (domain);
1737 
1738  seq_type->data_readval (buf_p, &attrs[7].value, domain, -1, true, NULL, 0);
1739  }
1740 
1741  /* set_domain */
1742  error =
1743  catcls_get_subset (thread_p, buf_p, vars[ORC_DOMAIN_SETDOMAIN_INDEX].length, &attrs[8],
1745 
1746  if (vars[ORC_DOMAIN_SCHEMA_JSON_OFFSET].length > 0)
1747  {
1748  char *schema_str;
1749  error = or_get_json_schema (buf_p, schema_str);
1750  if (error != NO_ERROR)
1751  {
1752  goto error;
1753  }
1754  db_make_string (&attrs[9].value, schema_str);
1755  attrs[9].value.need_clear = true;
1756  }
1757  else
1758  {
1759  db_make_null (&attrs[9].value);
1760  }
1761 
1762  if (error != NO_ERROR)
1763  {
1764  goto error;
1765  }
1766 
1767  if (vars)
1768  {
1769  free_and_init (vars);
1770  }
1771 
1772  return NO_ERROR;
1773 
1774 error:
1775 
1776  if (vars)
1777  {
1778  free_and_init (vars);
1779  }
1780 
1781  return error;
1782 }
1783 
1784 /*
1785  * catcls_get_or_value_from_method () -
1786  * return:
1787  * buf(in):
1788  * value(in):
1789  */
1790 static int
1792 {
1793  OR_VALUE *attrs;
1794  DB_VALUE *attr_val_p;
1795  OR_VARINFO *vars = NULL;
1796  int size;
1797  int error = NO_ERROR;
1798 
1799  error = catcls_expand_or_value_by_def (value_p, &ct_Method);
1800  if (error != NO_ERROR)
1801  {
1802  goto error;
1803  }
1804 
1805  attrs = value_p->sub.value;
1806 
1809  vars = or_get_var_table (buf_p, size, catcls_unpack_allocator);
1810  if (vars == NULL)
1811  {
1812  size_t msize = size * sizeof (OR_VARINFO);
1813 
1814  error = ER_OUT_OF_VIRTUAL_MEMORY;
1815  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, msize);
1816  goto error;
1817  }
1818 
1819  /* class */
1820  attr_val_p = &attrs[4].value;
1821  tp_Object.data_readval (buf_p, attr_val_p, NULL, -1, true, NULL, 0);
1822  error = catcls_convert_class_oid_to_oid (thread_p, attr_val_p);
1823  if (error != NO_ERROR)
1824  {
1825  ASSERT_ERROR ();
1826  goto error;
1827  }
1828 
1829  /* id */
1830  or_advance (buf_p, OR_INT_SIZE);
1831 
1832  /* name */
1833  attr_val_p = &attrs[1].value;
1834  tp_String.data_readval (buf_p, attr_val_p, NULL, vars[ORC_METHOD_NAME_INDEX].length, true, NULL, 0);
1836 
1837  /* signatures */
1838  error =
1839  catcls_get_subset (thread_p, buf_p, vars[ORC_METHOD_SIGNATURE_INDEX].length, &attrs[5],
1841  if (error != NO_ERROR)
1842  {
1843  goto error;
1844  }
1845 
1846  /* properties */
1847  or_advance (buf_p, vars[ORC_METHOD_PROPERTIES_INDEX].length);
1848 
1849  if (vars)
1850  {
1851  free_and_init (vars);
1852  }
1853 
1854  return NO_ERROR;
1855 
1856 error:
1857 
1858  if (vars)
1859  {
1860  free_and_init (vars);
1861  }
1862 
1863  return error;
1864 }
1865 
1866 /*
1867  * catcls_get_or_value_from_method_signiture () -
1868  * return:
1869  * buf(in):
1870  * value(in):
1871  */
1872 static int
1874 {
1875  OR_VALUE *attrs;
1876  DB_VALUE *attr_val_p;
1877  OR_VARINFO *vars = NULL;
1878  int size;
1879  int error = NO_ERROR;
1880 
1881  error = catcls_expand_or_value_by_def (value_p, &ct_Methsig);
1882  if (error != NO_ERROR)
1883  {
1884  goto error;
1885  }
1886 
1887  attrs = value_p->sub.value;
1888 
1889  /* variable offset */
1891  vars = or_get_var_table (buf_p, size, catcls_unpack_allocator);
1892  if (vars == NULL)
1893  {
1894  size_t msize = size * sizeof (OR_VARINFO);
1895 
1896  error = ER_OUT_OF_VIRTUAL_MEMORY;
1897  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, msize);
1898  goto error;
1899  }
1900 
1901  /* arg_count */
1902  tp_Integer.data_readval (buf_p, &attrs[1].value, NULL, -1, true, NULL, 0);
1903 
1904  /* function_name */
1905  attr_val_p = &attrs[2].value;
1906  tp_String.data_readval (buf_p, attr_val_p, NULL, vars[ORC_METHSIG_FUNCTION_NAME_INDEX].length, true, NULL, 0);
1908 
1909  /* string_def */
1910  or_advance (buf_p, vars[ORC_METHSIG_SQL_DEF_INDEX].length);
1911 
1912  /* return_value */
1913  error =
1914  catcls_get_subset (thread_p, buf_p, vars[ORC_METHSIG_RETURN_VALUE_INDEX].length, &attrs[3],
1916  if (error != NO_ERROR)
1917  {
1918  goto error;
1919  }
1920 
1921  /* arguments */
1922  error =
1923  catcls_get_subset (thread_p, buf_p, vars[ORC_METHSIG_ARGUMENTS_INDEX].length, &attrs[4],
1925  if (error != NO_ERROR)
1926  {
1927  goto error;
1928  }
1929 
1930  if (vars)
1931  {
1932  free_and_init (vars);
1933  }
1934 
1935  return NO_ERROR;
1936 
1937 error:
1938 
1939  if (vars)
1940  {
1941  free_and_init (vars);
1942  }
1943 
1944  return error;
1945 }
1946 
1947 /*
1948  * catcls_get_or_value_from_method_argument () -
1949  * return:
1950  * buf(in):
1951  * value(in):
1952  */
1953 static int
1955 {
1956  OR_VALUE *attrs;
1957  OR_VARINFO *vars = NULL;
1958  int size;
1959  int error;
1960 
1961  error = catcls_expand_or_value_by_def (value_p, &ct_Metharg);
1962  if (error != NO_ERROR)
1963  {
1964  goto error;
1965  }
1966 
1967  attrs = value_p->sub.value;
1968 
1971  vars = or_get_var_table (buf_p, size, catcls_unpack_allocator);
1972  if (vars == NULL)
1973  {
1974  size_t msize = size * sizeof (OR_VARINFO);
1975 
1976  error = ER_OUT_OF_VIRTUAL_MEMORY;
1977  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, msize);
1978  goto error;
1979  }
1980 
1981  /* type */
1982  tp_Integer.data_readval (buf_p, &attrs[1].value, NULL, -1, true, NULL, 0);
1983 
1984  /* index */
1985  tp_Integer.data_readval (buf_p, &attrs[2].value, NULL, -1, true, NULL, 0);
1986 
1987  /* domain */
1988  error =
1989  catcls_get_subset (thread_p, buf_p, vars[ORC_METHARG_DOMAIN_INDEX].length, &attrs[3],
1991  if (error != NO_ERROR)
1992  {
1993  goto error;
1994  }
1995 
1996  if (vars)
1997  {
1998  free_and_init (vars);
1999  }
2000 
2001  return NO_ERROR;
2002 
2003 error:
2004 
2005  if (vars)
2006  {
2007  free_and_init (vars);
2008  }
2009 
2010  return error;
2011 }
2012 
2013 /*
2014  * catcls_get_or_value_from_method_file () -
2015  * return:
2016  * buf(in):
2017  * value(in):
2018  */
2019 static int
2021 {
2022  OR_VALUE *attrs;
2023  DB_VALUE *attr_val_p;
2024  OR_VARINFO *vars = NULL;
2025  int size;
2026  int error = NO_ERROR;
2027 
2028  error = catcls_expand_or_value_by_def (value_p, &ct_Methfile);
2029  if (error != NO_ERROR)
2030  {
2031  goto error;
2032  }
2033 
2034  attrs = value_p->sub.value;
2035 
2038  vars = or_get_var_table (buf_p, size, catcls_unpack_allocator);
2039  if (vars == NULL)
2040  {
2041  size_t msize = size * sizeof (OR_VARINFO);
2042 
2043  error = ER_OUT_OF_VIRTUAL_MEMORY;
2044  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, msize);
2045  goto error;
2046  }
2047 
2048  /* class */
2049  attr_val_p = &attrs[1].value;
2050  tp_Object.data_readval (buf_p, attr_val_p, NULL, -1, true, NULL, 0);
2051  error = catcls_convert_class_oid_to_oid (thread_p, attr_val_p);
2052  if (error != NO_ERROR)
2053  {
2054  ASSERT_ERROR ();
2055  goto error;
2056  }
2057 
2058  /* name */
2059  attr_val_p = &attrs[2].value;
2060  tp_String.data_readval (buf_p, attr_val_p, NULL, vars[ORC_METHFILE_NAME_INDEX].length, true, NULL, 0);
2062 
2063  /* properties */
2064  or_advance (buf_p, vars[ORC_METHFILE_PROPERTIES_INDEX].length);
2065 
2066  if (vars)
2067  {
2068  free_and_init (vars);
2069  }
2070 
2071  return NO_ERROR;
2072 
2073 error:
2074 
2075  if (vars)
2076  {
2077  free_and_init (vars);
2078  }
2079 
2080  return error;
2081 }
2082 
2083 /*
2084  * catcls_get_or_value_from_resolution () -
2085  * return:
2086  * buf(in):
2087  * value(in):
2088  */
2089 static int
2091 {
2092  OR_VALUE *attrs;
2093  DB_VALUE *attr_val_p;
2094  OR_VARINFO *vars = NULL;
2095  int size;
2096  int error = NO_ERROR;
2097 
2098  error = catcls_expand_or_value_by_def (value_p, &ct_Resolution);
2099  if (error != NO_ERROR)
2100  {
2101  goto error;
2102  }
2103 
2104  attrs = value_p->sub.value;
2105 
2108  vars = or_get_var_table (buf_p, size, catcls_unpack_allocator);
2109  if (vars == NULL)
2110  {
2111  size_t msize = size * sizeof (OR_VARINFO);
2112 
2113  error = ER_OUT_OF_VIRTUAL_MEMORY;
2114  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, msize);
2115  goto error;
2116  }
2117 
2118  /* class */
2119  attr_val_p = &attrs[0].value;
2120  tp_Object.data_readval (buf_p, attr_val_p, NULL, -1, true, NULL, 0);
2121  error = catcls_convert_class_oid_to_oid (thread_p, attr_val_p);
2122  if (error != NO_ERROR)
2123  {
2124  ASSERT_ERROR ();
2125  goto error;
2126  }
2127 
2128  /* type */
2129  tp_Integer.data_readval (buf_p, &attrs[2].value, NULL, -1, true, NULL, 0);
2130 
2131  /* name */
2132  attr_val_p = &attrs[3].value;
2133  tp_String.data_readval (buf_p, attr_val_p, NULL, vars[ORC_RES_NAME_INDEX].length, true, NULL, 0);
2135 
2136  /* alias */
2137  attr_val_p = &attrs[1].value;
2138  tp_String.data_readval (buf_p, attr_val_p, NULL, vars[ORC_RES_ALIAS_INDEX].length, true, NULL, 0);
2140 
2141  if (vars)
2142  {
2143  free_and_init (vars);
2144  }
2145 
2146  return NO_ERROR;
2147 
2148 error:
2149 
2150  if (vars)
2151  {
2152  free_and_init (vars);
2153  }
2154 
2155  return error;
2156 }
2157 
2158 /*
2159  * catcls_get_or_value_from_query_spec () -
2160  * return:
2161  * buf(in):
2162  * value(in):
2163  */
2164 static int
2166 {
2167  OR_VALUE *attrs;
2168  DB_VALUE *attr_val_p;
2169  OR_VARINFO *vars = NULL;
2170  int size;
2171  int error = NO_ERROR;
2172 
2173  error = catcls_expand_or_value_by_def (value_p, &ct_Queryspec);
2174  if (error != NO_ERROR)
2175  {
2176  goto error;
2177  }
2178 
2179  attrs = value_p->sub.value;
2180 
2183  vars = or_get_var_table (buf_p, size, catcls_unpack_allocator);
2184  if (vars == NULL)
2185  {
2186  size_t msize = size * sizeof (OR_VARINFO);
2187 
2188  error = ER_OUT_OF_VIRTUAL_MEMORY;
2189  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, msize);
2190  goto error;
2191  }
2192 
2193  /* specification */
2194  attr_val_p = &attrs[1].value;
2195  tp_String.data_readval (buf_p, attr_val_p, NULL, vars[ORC_QUERY_SPEC_SPEC_INDEX].length, true, NULL, 0);
2196  db_string_truncate (attr_val_p, DB_MAX_SPEC_LENGTH);
2197 
2198  if (vars)
2199  {
2200  free_and_init (vars);
2201  }
2202 
2203  return NO_ERROR;
2204 
2205 error:
2206 
2207  if (vars)
2208  {
2209  free_and_init (vars);
2210  }
2211 
2212  return error;
2213 }
2214 
2215 /*
2216  * catcls_get_or_value_from_indexes () -
2217  * return:
2218  * seq(in):
2219  * values(in):
2220  * is_unique(in):
2221  * is_reverse(in):
2222  * is_primary_key(in):
2223  * is_foreign_key(in):
2224  */
2225 static int
2226 catcls_get_or_value_from_indexes (DB_SEQ * seq_p, OR_VALUE * values, int is_unique, int is_reverse, int is_primary_key,
2227  int is_foreign_key)
2228 {
2229  int seq_size;
2230  DB_VALUE keys, svalue, val, avalue, *pvalue = NULL, *status_value = NULL;
2231  DB_SEQ *key_seq_p = NULL, *seq = NULL, *pred_seq = NULL, *prefix_seq = NULL, *status_seq = NULL;
2232  int key_size, att_cnt;
2233  OR_VALUE *attrs, *key_attrs;
2234  DB_VALUE *attr_val_p;
2235  OR_VALUE *subset_p = NULL;
2236  int e, i, j, k;
2237  int has_function_index = 0;
2238  int error = NO_ERROR;
2239 
2240  db_value_put_null (&keys);
2241  db_value_put_null (&svalue);
2242  db_value_put_null (&val);
2243  db_value_put_null (&avalue);
2244  seq_size = set_size (seq_p);
2245  for (i = 0, j = 0; i < seq_size; i += 2, j++)
2246  {
2247  has_function_index = 0;
2248  prefix_seq = NULL;
2249  error = catcls_expand_or_value_by_def (&values[j], &ct_Index);
2250  if (error != NO_ERROR)
2251  {
2252  goto error;
2253  }
2254 
2255  attrs = values[j].sub.value;
2256 
2257  /* index_name */
2258  attr_val_p = &attrs[1].value;
2259  error = set_get_element (seq_p, i, attr_val_p);
2260  if (error != NO_ERROR)
2261  {
2262  goto error;
2263  }
2265 
2266  /* (is_unique) */
2267  db_make_int (&attrs[2].value, is_unique);
2268 
2269  error = set_get_element (seq_p, i + 1, &keys);
2270  if (error != NO_ERROR)
2271  {
2272  goto error;
2273  }
2274 
2275  if (DB_VALUE_TYPE (&keys) == DB_TYPE_SEQUENCE)
2276  {
2277  key_seq_p = db_get_set (&keys);
2278  }
2279  else
2280  {
2281  assert (0);
2282  error = ER_SM_INVALID_PROPERTY;
2283  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
2284  goto error;
2285  }
2286 
2287  /* the sequence of keys also includes the B+tree ID and the filter predicate expression in the first two
2288  * positions (0 and 1) */
2289  key_size = set_size (key_seq_p);
2290  att_cnt = (key_size - 3) / 2;
2291 
2292  /* Get status. */
2293  error = set_get_element (key_seq_p, key_size - 2, &attrs[11].value);
2294 
2295  /* comment */
2296  error = set_get_element (key_seq_p, key_size - 1, &attrs[10].value);
2297  if (error != NO_ERROR)
2298  {
2299  goto error;
2300  }
2301  db_string_truncate (&attrs[10].value, DB_MAX_COMMENT_LENGTH);
2302 
2303  if (!is_primary_key && !is_foreign_key)
2304  {
2305  /* prefix_length or filter index */
2306  error = set_get_element (key_seq_p, key_size - 3, &svalue);
2307  if (error != NO_ERROR)
2308  {
2309  goto error;
2310  }
2311 
2312  if (DB_VALUE_TYPE (&svalue) != DB_TYPE_SEQUENCE)
2313  {
2314  error = ER_SM_INVALID_PROPERTY;
2315  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
2316  goto error;
2317  }
2318 
2319  seq = db_get_set (&svalue);
2320  error = set_get_element (seq, 0, &val);
2321  if (error != NO_ERROR)
2322  {
2323  goto error;
2324  }
2325 
2326  if (DB_VALUE_TYPE (&val) == DB_TYPE_INTEGER)
2327  {
2328  /* have prefix length */
2329  prefix_seq = seq;
2330  }
2331  else if (DB_VALUE_TYPE (&val) == DB_TYPE_SEQUENCE)
2332  {
2333  DB_SET *child_seq = db_get_set (&val);
2334  int seq_size = set_size (seq);
2335  int flag, l = 0;
2336  DB_VALUE temp;
2337  int col_id, att_index_start;
2338  char *buffer, *ptr;
2339  TP_DOMAIN *fi_domain = NULL;
2340 
2341  /* have filter or function index */
2342  while (true)
2343  {
2344  flag = 0;
2345  error = set_get_element (child_seq, 0, &avalue);
2346  if (error != NO_ERROR)
2347  {
2348  goto error;
2349  }
2350 
2351  if (DB_IS_NULL (&avalue) || DB_VALUE_TYPE (&avalue) != DB_TYPE_STRING)
2352  {
2353  error = ER_SM_INVALID_PROPERTY;
2354  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
2355  goto error;
2356  }
2357 
2359  {
2360  flag = 0x01;
2361  }
2363  {
2364  flag = 0x02;
2365  }
2367  {
2368  flag = 0x03;
2369  }
2370 
2371  pr_clear_value (&avalue);
2372 
2373  error = set_get_element (child_seq, 1, &avalue);
2374  if (error != NO_ERROR)
2375  {
2376  goto error;
2377  }
2378 
2379  if (DB_VALUE_TYPE (&avalue) != DB_TYPE_SEQUENCE)
2380  {
2381  error = ER_SM_INVALID_PROPERTY;
2382  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
2383  goto error;
2384  }
2385 
2386  switch (flag)
2387  {
2388  case 0x01:
2389  pred_seq = db_get_set (&avalue);
2390  attr_val_p = &attrs[8].value;
2391  error = set_get_element (pred_seq, 0, attr_val_p);
2392  if (error != NO_ERROR)
2393  {
2394  goto error;
2395  }
2396  break;
2397 
2398  case 0x02:
2399  has_function_index = 1;
2400  pred_seq = db_get_set (&avalue);
2401 
2402  error = set_get_element_nocopy (pred_seq, 2, &temp);
2403  if (error != NO_ERROR)
2404  {
2405  goto error;
2406  }
2407  col_id = db_get_int (&temp);
2408 
2409  error = set_get_element_nocopy (pred_seq, 3, &temp);
2410  if (error != NO_ERROR)
2411  {
2412  goto error;
2413  }
2414  att_index_start = db_get_int (&temp);
2415  assert (col_id <= att_index_start);
2416 
2417  att_cnt = att_index_start + 1;
2418 
2419  /* key_count */
2420  db_make_int (&attrs[3].value, att_cnt);
2421 
2422  subset_p = catcls_allocate_or_value (att_cnt);
2423  if (subset_p == NULL)
2424  {
2425  error = ER_OUT_OF_VIRTUAL_MEMORY;
2426  goto error;
2427  }
2428 
2429  attrs[4].sub.value = subset_p;
2430  attrs[4].sub.count = att_cnt;
2431 
2432  /* key_attrs */
2433  e = 1;
2434  for (k = 0; k < att_cnt; k++) /* for each [attrID, asc_desc]+ */
2435  {
2436  error = catcls_expand_or_value_by_def (&subset_p[k], &ct_Indexkey);
2437  if (error != NO_ERROR)
2438  {
2439  goto error;
2440  }
2441 
2442  key_attrs = subset_p[k].sub.value;
2443 
2444  if (k != col_id)
2445  {
2446  /* key_attr_id */
2447  attr_val_p = &key_attrs[1].value;
2448  error = set_get_element (key_seq_p, e++, attr_val_p);
2449  if (error != NO_ERROR)
2450  {
2451  goto error;
2452  }
2453 
2454  /* key_order */
2455  db_make_int (&key_attrs[2].value, k);
2456 
2457  /* asc_desc */
2458  attr_val_p = &key_attrs[3].value;
2459  error = set_get_element (key_seq_p, e++, attr_val_p);
2460  if (error != NO_ERROR)
2461  {
2462  goto error;
2463  }
2464 
2465  /* function name */
2466  db_make_null (&key_attrs[5].value);
2467  }
2468  else
2469  {
2470  /* key_attr_id */
2471  db_make_null (&key_attrs[1].value);
2472 
2473  /* key_order */
2474  db_make_int (&key_attrs[2].value, k);
2475 
2476  /* asc_desc */
2477  error = set_get_element_nocopy (pred_seq, 4, &temp);
2478  if (error != NO_ERROR)
2479  {
2480  goto error;
2481  }
2482 
2483  // use const_cast since of a limitation of or_unpack_* functions which do not accept const
2484  buffer = CONST_CAST (char *, db_get_string (&temp));
2485  ptr = buffer;
2486  ptr = or_unpack_domain (ptr, &fi_domain, NULL);
2487 
2488  db_make_int (&key_attrs[3].value, fi_domain->is_desc);
2489  tp_domain_free (fi_domain);
2490 
2491  /* function name */
2492  attr_val_p = &key_attrs[5].value;
2493  error = set_get_element (pred_seq, 0, attr_val_p);
2494  if (error != NO_ERROR)
2495  {
2496  goto error;
2497  }
2498  }
2499 
2500  /* prefix_length */
2501  db_make_int (&key_attrs[4].value, -1);
2502  }
2503 
2504  break;
2505 
2506  case 0x03:
2507  pvalue = db_value_copy (&avalue);
2508  prefix_seq = db_get_set (pvalue);
2509  break;
2510 
2511  default:
2512  break;
2513  }
2514 
2515  pr_clear_value (&avalue);
2516 
2517  l++;
2518  if (l >= seq_size)
2519  {
2520  break;
2521  }
2522 
2523  pr_clear_value (&val);
2524  if (set_get_element (seq, l, &val) != NO_ERROR)
2525  {
2526  error = ER_FAILED;
2527  goto error;
2528  }
2529  if (DB_VALUE_TYPE (&val) != DB_TYPE_SEQUENCE)
2530  {
2531  error = ER_FAILED;
2532  goto error;
2533  }
2534 
2535  child_seq = db_get_set (&val);
2536  }
2537  }
2538  else
2539  {
2540  error = ER_SM_INVALID_PROPERTY;
2541  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
2542  goto error;
2543  }
2544  pr_clear_value (&val);
2545  }
2546 
2547  /* key_count */
2548  if (has_function_index == 0)
2549  {
2550  db_make_int (&attrs[3].value, att_cnt);
2551 
2552  subset_p = catcls_allocate_or_value (att_cnt);
2553  if (subset_p == NULL)
2554  {
2555  error = ER_OUT_OF_VIRTUAL_MEMORY;
2556  goto error;
2557  }
2558 
2559  attrs[4].sub.value = subset_p;
2560  attrs[4].sub.count = att_cnt;
2561 
2562  /* key_attrs */
2563  e = 1;
2564  for (k = 0; k < att_cnt; k++) /* for each [attrID, asc_desc]+ */
2565  {
2566  error = catcls_expand_or_value_by_def (&subset_p[k], &ct_Indexkey);
2567  if (error != NO_ERROR)
2568  {
2569  goto error;
2570  }
2571 
2572  key_attrs = subset_p[k].sub.value;
2573 
2574  /* key_attr_id */
2575  attr_val_p = &key_attrs[1].value;
2576  error = set_get_element (key_seq_p, e++, attr_val_p);
2577  if (error != NO_ERROR)
2578  {
2579  goto error;
2580  }
2581 
2582  /* key_order */
2583  db_make_int (&key_attrs[2].value, k);
2584 
2585  /* asc_desc */
2586  attr_val_p = &key_attrs[3].value;
2587  error = set_get_element (key_seq_p, e++, attr_val_p);
2588  if (error != NO_ERROR)
2589  {
2590  goto error;
2591  }
2592 
2593  /* prefix_length */
2594  db_make_int (&key_attrs[4].value, -1);
2595 
2596  /* function name */
2597  db_make_null (&key_attrs[5].value);
2598  }
2599  }
2600 
2601  if (prefix_seq)
2602  {
2603  for (k = 0; k < att_cnt; k++)
2604  {
2605  key_attrs = subset_p[k].sub.value;
2606  attr_val_p = &key_attrs[4].value;
2607 
2608  error = set_get_element (prefix_seq, k, attr_val_p);
2609  if (error != NO_ERROR)
2610  {
2611  goto error;
2612  }
2613  }
2614  }
2615 
2616  pr_clear_value (&svalue);
2617  pr_clear_value (&keys);
2618  if (pvalue)
2619  {
2620  pr_free_ext_value (pvalue);
2621  pvalue = NULL;
2622  }
2623 
2624  /* is_reverse */
2625  db_make_int (&attrs[5].value, is_reverse);
2626 
2627  /* is_primary_key */
2628  db_make_int (&attrs[6].value, is_primary_key);
2629 
2630  /* is_foreign_key */
2631  db_make_int (&attrs[7].value, is_foreign_key);
2632 
2633  /* have_function */
2634  db_make_int (&attrs[9].value, has_function_index);
2635  }
2636 
2637  return NO_ERROR;
2638 
2639 error:
2640 
2641  pr_clear_value (&keys);
2642  pr_clear_value (&svalue);
2643  pr_clear_value (&val);
2644  pr_clear_value (&avalue);
2645 
2646  if (pvalue)
2647  {
2648  pr_free_ext_value (pvalue);
2649  }
2650  return error;
2651 }
2652 
2653 /*
2654  * catcls_get_subset () -
2655  * return:
2656  * buf(in):
2657  * expected_size(in):
2658  * value(in):
2659  * reader(in):
2660  */
2661 static int
2662 catcls_get_subset (THREAD_ENTRY * thread_p, OR_BUF * buf_p, int expected_size, OR_VALUE * value_p, CREADER reader)
2663 {
2664  OR_VALUE *subset_p;
2665  int count, i;
2666  int error = NO_ERROR;
2667 
2668  if (expected_size == 0)
2669  {
2670  value_p->sub.count = 0;
2671  return NO_ERROR;
2672  }
2673 
2674  count = or_skip_set_header (buf_p);
2675  subset_p = catcls_allocate_or_value (count);
2676  if (subset_p == NULL)
2677  {
2678  return ER_OUT_OF_VIRTUAL_MEMORY;
2679  }
2680 
2681  value_p->sub.value = subset_p;
2682  value_p->sub.count = count;
2683 
2684  for (i = 0; i < count; i++)
2685  {
2686  error = (*reader) (thread_p, buf_p, &subset_p[i]);
2687  if (error != NO_ERROR)
2688  {
2689  return error;
2690  }
2691  }
2692 
2693  return NO_ERROR;
2694 }
2695 
2696 /*
2697  * catcls_get_object_set () -
2698  * return:
2699  * buf(in):
2700  * expected_size(in):
2701  * value(in):
2702  */
2703 static int
2704 catcls_get_object_set (THREAD_ENTRY * thread_p, OR_BUF * buf_p, int expected_size, OR_VALUE * value_p)
2705 {
2706  DB_SET *oid_set_p = NULL;
2707  DB_VALUE oid_val;
2708  int count, i;
2709  int error = NO_ERROR;
2710 
2711  if (expected_size == 0)
2712  {
2713  return NO_ERROR;
2714  }
2715 
2716  count = or_skip_set_header (buf_p);
2717  oid_set_p = set_create_sequence (count);
2718  if (oid_set_p == NULL)
2719  {
2720  assert (er_errid () != NO_ERROR);
2721  error = er_errid ();
2722  goto error;
2723  }
2724 
2725  for (i = 0; i < count; i++)
2726  {
2727  tp_Object.data_readval (buf_p, &oid_val, NULL, -1, true, NULL, 0);
2728 
2729  error = catcls_convert_class_oid_to_oid (thread_p, &oid_val);
2730  if (error != NO_ERROR)
2731  {
2732  ASSERT_ERROR ();
2733  goto error;
2734  }
2735 
2736  error = set_put_element (oid_set_p, i, &oid_val);
2737  if (error != NO_ERROR)
2738  {
2739  goto error;
2740  }
2741  }
2742 
2743  db_make_sequence (&value_p->value, oid_set_p);
2744  return NO_ERROR;
2745 
2746 error:
2747 
2748  if (oid_set_p)
2749  {
2750  set_free (oid_set_p);
2751  }
2752 
2753  return error;
2754 }
2755 
2756 /*
2757  * catcls_get_property_set () -
2758  * return:
2759  * buf(in):
2760  * expected_size(in):
2761  * value(in):
2762  */
2763 static int
2764 catcls_get_property_set (THREAD_ENTRY * thread_p, OR_BUF * buf_p, int expected_size, OR_VALUE * value_p)
2765 {
2766  DB_VALUE prop_val;
2767  DB_SEQ *prop_seq_p = NULL;
2768  int n_size = 0;
2770  {SM_PROPERTY_PRIMARY_KEY, NULL, 0, true, false, true, false},
2771  {SM_PROPERTY_UNIQUE, NULL, 0, true, false, false, false},
2772  {SM_PROPERTY_REVERSE_UNIQUE, NULL, 0, true, true, false, false},
2773  {SM_PROPERTY_INDEX, NULL, 0, false, false, false, false},
2774  {SM_PROPERTY_REVERSE_INDEX, NULL, 0, false, true, false, false},
2775  {SM_PROPERTY_FOREIGN_KEY, NULL, 0, false, false, false, true},
2776  };
2777 
2779  OR_VALUE *subset_p = NULL;
2780  int error = NO_ERROR;
2781  int i, idx;
2782 
2783  if (expected_size == 0)
2784  {
2785  value_p->sub.count = 0;
2786  return NO_ERROR;
2787  }
2788 
2789  db_value_put_null (&prop_val);
2790  for (i = 0; i < SM_PROPERTY_NUM_INDEX_FAMILY; i++)
2791  {
2792  db_value_put_null (&vals[i]);
2793  }
2794 
2795  tp_Sequence.data_readval (buf_p, &prop_val, NULL, expected_size, true, NULL, 0);
2796  prop_seq_p = db_get_set (&prop_val);
2797 
2798  for (i = 0; i < SM_PROPERTY_NUM_INDEX_FAMILY; i++)
2799  {
2800  if (prop_seq_p != NULL && (classobj_get_prop (prop_seq_p, property_vars[i].name, &vals[i]) > 0))
2801  {
2802 
2803  if (DB_VALUE_TYPE (&vals[i]) == DB_TYPE_SEQUENCE)
2804  {
2805  property_vars[i].seq = db_get_set (&vals[i]);
2806  }
2807 
2808  if (property_vars[i].seq != NULL)
2809  {
2810  property_vars[i].size = set_size (property_vars[i].seq) / 2;
2811  n_size += property_vars[i].size;
2812  }
2813  }
2814  }
2815 
2816  if (n_size > 0)
2817  {
2818  subset_p = catcls_allocate_or_value (n_size);
2819  if (subset_p == NULL)
2820  {
2821  error = ER_OUT_OF_VIRTUAL_MEMORY;
2822  goto error;
2823  }
2824 
2825  value_p->sub.value = subset_p;
2826  value_p->sub.count = n_size;
2827  }
2828  else
2829  {
2830  value_p->sub.value = NULL;
2831  value_p->sub.count = 0;
2832  }
2833 
2834  idx = 0;
2835  for (i = 0; i < SM_PROPERTY_NUM_INDEX_FAMILY; i++)
2836  {
2837  if (property_vars[i].seq != NULL)
2838  {
2839  error =
2840  catcls_get_or_value_from_indexes (property_vars[i].seq, &subset_p[idx], property_vars[i].is_unique,
2841  property_vars[i].is_reverse, property_vars[i].is_primary_key,
2842  property_vars[i].is_foreign_key);
2843  if (error != NO_ERROR)
2844  {
2845  goto error;
2846  }
2847  }
2848 
2849  idx += property_vars[i].size;
2850  }
2851 
2852  error = catcls_convert_attr_id_to_name (thread_p, buf_p, value_p);
2853  if (error != NO_ERROR)
2854  {
2855  goto error;
2856  }
2857 
2858  pr_clear_value (&prop_val);
2859  for (i = 0; i < SM_PROPERTY_NUM_INDEX_FAMILY; i++)
2860  {
2861  pr_clear_value (&vals[i]);
2862  }
2863 
2864  return NO_ERROR;
2865 
2866 error:
2867  pr_clear_value (&prop_val);
2868  for (i = 0; i < SM_PROPERTY_NUM_INDEX_FAMILY; i++)
2869  {
2870  pr_clear_value (&vals[i]);
2871  }
2872 
2873  return error;
2874 }
2875 
2876 /*
2877  * catcls_reorder_attributes_by_repr () -
2878  * return:
2879  * value(in):
2880  */
2881 static int
2883 {
2884  OR_VALUE *attrs, *var_attrs;
2885  int n_attrs;
2886  DISK_ATTR *fixed_p, *variable_p;
2887  int n_fixed, n_variable;
2888  DISK_REPR *repr_p = NULL;
2889  REPR_ID repr_id;
2890  OID *class_oid_p;
2891  int i, j;
2892  int error = NO_ERROR;
2893 
2894  class_oid_p = &value_p->id.classoid;
2895  error = catalog_get_last_representation_id (thread_p, class_oid_p, &repr_id);
2896  if (error != NO_ERROR)
2897  {
2898  goto error;
2899  }
2900  else
2901  {
2902  repr_p = catalog_get_representation (thread_p, class_oid_p, repr_id, NULL);
2903  if (repr_p == NULL)
2904  {
2905  assert (er_errid () != NO_ERROR);
2906  error = er_errid ();
2907  goto error;
2908  }
2909  }
2910 
2911  fixed_p = repr_p->fixed;
2912  n_fixed = repr_p->n_fixed;
2913  variable_p = repr_p->variable;
2914  n_variable = repr_p->n_variable;
2915 
2916  attrs = value_p->sub.value;
2917  n_attrs = n_fixed + n_variable;
2918 
2919  for (i = 0; i < n_fixed; i++)
2920  {
2921  for (j = i; j < n_attrs; j++)
2922  {
2923  if (fixed_p[i].id == attrs[j].id.attrid)
2924  {
2925  if (i != j)
2926  { /* need to exchange */
2927  EXCHANGE_OR_VALUE (attrs[i], attrs[j]);
2928  }
2929  break;
2930  }
2931  }
2932  }
2933 
2934  var_attrs = &attrs[n_fixed];
2935  for (i = 0; i < n_variable; i++)
2936  {
2937  for (j = i; j < n_variable; j++)
2938  {
2939  if (variable_p[i].id == var_attrs[j].id.attrid)
2940  {
2941  if (i != j)
2942  { /* need to exchange */
2943  EXCHANGE_OR_VALUE (var_attrs[i], var_attrs[j]);
2944  }
2945  break;
2946  }
2947  }
2948  }
2950 
2951  return NO_ERROR;
2952 
2953 error:
2954 
2955  if (repr_p)
2956  {
2958  }
2959 
2960  return error;
2961 }
2962 
2963 /*
2964  * catcls_expand_or_value_by_repr () -
2965  * return:
2966  * value(in):
2967  * class_oid(in):
2968  * rep(in):
2969  */
2970 static int
2971 catcls_expand_or_value_by_repr (OR_VALUE * value_p, OID * class_oid_p, DISK_REPR * repr_p)
2972 {
2973  OR_VALUE *attrs, *var_attrs;
2974  int n_attrs;
2975  DISK_ATTR *fixed_p, *variable_p;
2976  int n_fixed, n_variable;
2977  int i;
2978  int error = NO_ERROR;
2979 
2980  fixed_p = repr_p->fixed;
2981  n_fixed = repr_p->n_fixed;
2982  variable_p = repr_p->variable;
2983  n_variable = repr_p->n_variable;
2984 
2985  n_attrs = n_fixed + n_variable;
2986  attrs = catcls_allocate_or_value (n_attrs);
2987  if (attrs == NULL)
2988  {
2989  return ER_OUT_OF_VIRTUAL_MEMORY;
2990  }
2991 
2992  value_p->sub.value = attrs;
2993  value_p->sub.count = n_attrs;
2994 
2995  COPY_OID (&value_p->id.classoid, class_oid_p);
2996 
2997  for (i = 0; i < n_fixed; i++)
2998  {
2999  attrs[i].id.attrid = fixed_p[i].id;
3000  error = db_value_domain_init (&attrs[i].value, fixed_p[i].type, DB_DEFAULT_PRECISION, DB_DEFAULT_SCALE);
3001  if (error != NO_ERROR)
3002  {
3003  return error;
3004  }
3005  }
3006 
3007  var_attrs = &attrs[n_fixed];
3008  for (i = 0; i < n_variable; i++)
3009  {
3010  var_attrs[i].id.attrid = variable_p[i].id;
3011  error = db_value_domain_init (&var_attrs[i].value, variable_p[i].type, DB_DEFAULT_PRECISION, DB_DEFAULT_SCALE);
3012  if (error != NO_ERROR)
3013  {
3014  return error;
3015  }
3016  }
3017 
3018  return NO_ERROR;
3019 }
3020 
3021 /*
3022  * catcls_expand_or_value_by_subset () -
3023  * return:
3024  * value(in):
3025  */
3026 static int
3028 {
3029  DB_SET *set_p;
3030  int size, i;
3031  DB_VALUE element;
3032  OID *oid_p, class_oid;
3033  OR_VALUE *subset_p;
3034  SCAN_CODE scan_code;
3035  int err = NO_ERROR;
3036 
3037  if (!pr_is_set_type (DB_VALUE_TYPE (&value_p->value)))
3038  {
3039  return NO_ERROR;
3040  }
3041 
3042  set_p = db_get_set (&value_p->value);
3043  size = set_size (set_p);
3044  if (size > 0)
3045  {
3046  set_get_element_nocopy (set_p, 0, &element);
3047  if (DB_VALUE_TYPE (&element) == DB_TYPE_OID)
3048  {
3049  oid_p = db_get_oid (&element);
3050 
3051  scan_code = heap_get_class_oid (thread_p, oid_p, &class_oid);
3052  if (er_errid () == ER_HEAP_UNKNOWN_OBJECT)
3053  {
3054  /* Currently, we have reached here the situation where an instance has already been removed by the same
3055  * transaction. One example is when dropping a partition. The instances corresponding the partitions will
3056  * first be removed, which implies that the class OID can no longer be found and will be set to NULL. */
3057  er_clear ();
3058  }
3059  else if (scan_code == S_ERROR)
3060  {
3061  ASSERT_ERROR_AND_SET (err);
3062  }
3063 
3064  if (!OID_EQ (&class_oid, &ct_Class.cc_classoid) && !OID_ISNULL (&class_oid))
3065  {
3066  subset_p = catcls_allocate_or_value (size);
3067  if (subset_p != NULL)
3068  {
3069  value_p->sub.value = subset_p;
3070  value_p->sub.count = size;
3071 
3072  for (i = 0; i < size; i++)
3073  {
3074  COPY_OID (&((subset_p[i]).id.classoid), &class_oid);
3075  }
3076  }
3077  }
3078  }
3079  }
3080 
3081  return err;
3082 }
3083 
3084 /*
3085  * catcls_put_or_value_into_buffer () -
3086  * return:
3087  * value(in):
3088  * chn(in):
3089  * buf(in):
3090  * class_oid(in):
3091  * rep(in):
3092  */
3093 static int
3094 catcls_put_or_value_into_buffer (OR_VALUE * value_p, int chn, OR_BUF * buf_p, OID * class_oid_p, DISK_REPR * repr_p)
3095 {
3096  OR_VALUE *attrs, *var_attrs;
3097  int n_attrs;
3098  DISK_ATTR *fixed_p, *variable_p;
3099  int n_fixed, n_variable;
3101  unsigned int repr_id_bits;
3102  char *bound_bits = NULL;
3103  int bound_size;
3104  char *offset_p, *start_p;
3105  int i, pad, offset, header_size;
3106  int error = NO_ERROR;
3107 
3108  fixed_p = repr_p->fixed;
3109  n_fixed = repr_p->n_fixed;
3110  variable_p = repr_p->variable;
3111  n_variable = repr_p->n_variable;
3112 
3113  attrs = value_p->sub.value;
3114  n_attrs = n_fixed + n_variable;
3115 
3116  bound_size = OR_BOUND_BIT_BYTES (n_fixed);
3117  bound_bits = (char *) malloc (bound_size);
3118  if (bound_bits == NULL)
3119  {
3120  error = ER_OUT_OF_VIRTUAL_MEMORY;
3121  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, (size_t) bound_size);
3122  goto error;
3123  }
3124  memset (bound_bits, 0, bound_size);
3125 
3126  /* header */
3127 
3128  repr_id_bits = repr_p->id;
3129  if (n_fixed)
3130  {
3131  repr_id_bits |= OR_BOUND_BIT_FLAG;
3132  }
3133 
3134  OR_SET_VAR_OFFSET_SIZE (repr_id_bits, BIG_VAR_OFFSET_SIZE); /* 4byte */
3135 
3137  or_put_int (buf_p, repr_id_bits);
3138  or_put_int (buf_p, chn); /* CHN */
3139  or_put_bigint (buf_p, MVCCID_NULL); /* MVCC insert id */
3140  header_size = OR_MVCC_INSERT_HEADER_SIZE;
3141 
3142  /* offset table */
3143  offset_p = buf_p->ptr;
3144  or_advance (buf_p, OR_VAR_TABLE_SIZE (n_variable));
3145 
3146  /* fixed */
3147  start_p = buf_p->ptr;
3148  for (i = 0; i < n_fixed; i++)
3149  {
3150  data_type = fixed_p[i].type;
3151 
3152  if (DB_IS_NULL (&attrs[i].value))
3153  {
3154  or_advance (buf_p, (*tp_Type_id_map[data_type]).disksize);
3155  OR_CLEAR_BOUND_BIT (bound_bits, i);
3156  }
3157  else
3158  {
3159  (*tp_Type_id_map[data_type]).data_writeval (buf_p, &attrs[i].value);
3160  OR_ENABLE_BOUND_BIT (bound_bits, i);
3161  }
3162  }
3163 
3164  pad = (int) (buf_p->ptr - start_p);
3165  if (pad < repr_p->fixed_length)
3166  {
3167  or_pad (buf_p, repr_p->fixed_length - pad);
3168  }
3169  else if (pad > repr_p->fixed_length)
3170  {
3171  error = ER_SM_CORRUPTED;
3172  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
3173  goto error;
3174  }
3175 
3176  /* bound bits */
3177  if (n_fixed)
3178  {
3179  or_put_data (buf_p, bound_bits, bound_size);
3180  }
3181 
3182  /* variable */
3183  var_attrs = &attrs[n_fixed];
3184  for (i = 0; i < n_variable; i++)
3185  {
3186  /* the variable offsets are relative to end of the class record header */
3187  offset = (int) (buf_p->ptr - buf_p->buffer - header_size);
3188 
3189  data_type = variable_p[i].type;
3190  (*tp_Type_id_map[data_type]).data_writeval (buf_p, &var_attrs[i].value);
3191 
3192  OR_PUT_OFFSET (offset_p, offset);
3193  offset_p += BIG_VAR_OFFSET_SIZE;
3194  }
3195 
3196  /* put last offset */
3197  offset = (int) (buf_p->ptr - buf_p->buffer - header_size);
3198  OR_PUT_OFFSET (offset_p, offset);
3199 
3200  if (bound_bits)
3201  {
3202  free_and_init (bound_bits);
3203  }
3204 
3205  return NO_ERROR;
3206 
3207 error:
3208 
3209  if (bound_bits)
3210  {
3211  free_and_init (bound_bits);
3212  }
3213 
3214  return error;
3215 }
3216 
3217 /*
3218  * catcls_get_or_value_from_buffer () -
3219  * return:
3220  * buf(in):
3221  * value(in):
3222  * rep(in):
3223  */
3224 static int
3225 catcls_get_or_value_from_buffer (THREAD_ENTRY * thread_p, OR_BUF * buf_p, OR_VALUE * value_p, DISK_REPR * repr_p)
3226 {
3227  OR_VALUE *attrs, *var_attrs;
3228  int n_attrs;
3229  DISK_ATTR *fixed_p, *variable_p;
3230  int n_fixed, n_variable;
3232  OR_VARINFO *vars = NULL;
3233  unsigned int repr_id_bits;
3234  char *bound_bits = NULL;
3235  int bound_bits_flag = false;
3236  char *start_p;
3237  int i, pad, size, rc;
3238  int error = NO_ERROR;
3239  char mvcc_flags;
3240 
3241  fixed_p = repr_p->fixed;
3242  n_fixed = repr_p->n_fixed;
3243  variable_p = repr_p->variable;
3244  n_variable = repr_p->n_variable;
3245 
3246  attrs = value_p->sub.value;
3247  n_attrs = n_fixed + n_variable;
3248 
3249  /* header */
3251 
3252  repr_id_bits = or_mvcc_get_repid_and_flags (buf_p, &rc);
3253  /* get bound_bits_flag and skip other MVCC header fields */
3254  bound_bits_flag = repr_id_bits & OR_BOUND_BIT_FLAG;
3255  mvcc_flags = (char) ((repr_id_bits >> OR_MVCC_FLAG_SHIFT_BITS) & OR_MVCC_FLAG_MASK);
3256  repr_id_bits = repr_id_bits & OR_MVCC_REPID_MASK;
3257 
3258  or_advance (buf_p, OR_INT_SIZE); /* skip CHN */
3259 
3260  if (mvcc_flags & OR_MVCC_FLAG_VALID_INSID)
3261  {
3262  or_advance (buf_p, OR_MVCCID_SIZE); /* skip INS_ID */
3263  }
3264 
3265  if (mvcc_flags & OR_MVCC_FLAG_VALID_DELID)
3266  {
3267  or_advance (buf_p, OR_MVCCID_SIZE); /* skip DEL_ID */
3268  }
3269 
3270  if (mvcc_flags & OR_MVCC_FLAG_VALID_PREV_VERSION)
3271  {
3272  /* skip previous version lsa */
3274  }
3275 
3276  if (bound_bits_flag)
3277  {
3278  size = OR_BOUND_BIT_BYTES (n_fixed);
3279  bound_bits = (char *) malloc (size);
3280  if (bound_bits == NULL)
3281  {
3282  error = ER_OUT_OF_VIRTUAL_MEMORY;
3283  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, (size_t) size);
3284  goto error;
3285  }
3286  memset (bound_bits, 0, size);
3287  }
3288 
3289  /* get the offsets relative to the end of the header (beginning of variable table) */
3290  vars = or_get_var_table (buf_p, n_variable, catcls_unpack_allocator);
3291  if (vars == NULL)
3292  {
3293  error = ER_OUT_OF_VIRTUAL_MEMORY;
3294  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, n_variable * sizeof (OR_VARINFO));
3295  goto error;
3296  }
3297 
3298  /* fixed */
3299  start_p = buf_p->ptr;
3300 
3301  /* read bound bits before accessing fixed attributes */
3302  buf_p->ptr += repr_p->fixed_length;
3303  if (bound_bits_flag)
3304  {
3305  or_get_data (buf_p, bound_bits, OR_BOUND_BIT_BYTES (n_fixed));
3306  }
3307 
3308  buf_p->ptr = start_p;
3309  for (i = 0; i < n_fixed; i++)
3310  {
3311  data_type = fixed_p[i].type;
3312 
3313  if (bound_bits_flag && OR_GET_BOUND_BIT (bound_bits, i))
3314  {
3315  (*tp_Type_id_map[data_type]).data_readval (buf_p, &attrs[i].value, NULL, -1, true, NULL, 0);
3316  }
3317  else
3318  {
3319  db_value_put_null (&attrs[i].value);
3320  or_advance (buf_p, (*tp_Type_id_map[data_type]).disksize);
3321  }
3322  }
3323 
3324  pad = (int) (buf_p->ptr - start_p);
3325  if (pad < repr_p->fixed_length)
3326  {
3327  or_advance (buf_p, repr_p->fixed_length - pad);
3328  }
3329  else if (pad > repr_p->fixed_length)
3330  {
3331  error = ER_SM_CORRUPTED;
3332  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
3333  goto error;
3334  }
3335 
3336  /* bound bits */
3337  if (bound_bits_flag)
3338  {
3339  or_advance (buf_p, OR_BOUND_BIT_BYTES (n_fixed));
3340  }
3341 
3342  /* variable */
3343  var_attrs = &attrs[n_fixed];
3344  for (i = 0; i < n_variable; i++)
3345  {
3346  data_type = variable_p[i].type;
3347  (*tp_Type_id_map[data_type]).data_readval (buf_p, &var_attrs[i].value, NULL, vars[i].length, true, NULL, 0);
3348  error = catcls_expand_or_value_by_subset (thread_p, &var_attrs[i]);
3349  if (error != NO_ERROR)
3350  {
3351  goto error;
3352  }
3353  }
3354 
3355  if (vars)
3356  {
3357  free_and_init (vars);
3358  }
3359 
3360  if (bound_bits)
3361  {
3362  free_and_init (bound_bits);
3363  }
3364 
3365  return NO_ERROR;
3366 
3367 error:
3368 
3369  if (vars)
3370  {
3371  free_and_init (vars);
3372  }
3373 
3374  if (bound_bits)
3375  {
3376  free_and_init (bound_bits);
3377  }
3378 
3379  return error;
3380 }
3381 
3382 /*
3383  * catcls_put_or_value_into_record () -
3384  * return:
3385  * value(in):
3386  * chn(in):
3387  * record(in):
3388  * class_oid(in):
3389  */
3390 static int
3391 catcls_put_or_value_into_record (THREAD_ENTRY * thread_p, OR_VALUE * value_p, int chn, RECDES * record_p,
3392  OID * class_oid_p)
3393 {
3394  OR_BUF *buf_p, repr_buffer;
3395  DISK_REPR *repr_p = NULL;
3396  REPR_ID repr_id;
3397  int error = NO_ERROR;
3398 
3399  error = catalog_get_last_representation_id (thread_p, class_oid_p, &repr_id);
3400  if (error != NO_ERROR)
3401  {
3402  return error;
3403  }
3404  else
3405  {
3406  repr_p = catalog_get_representation (thread_p, class_oid_p, repr_id, NULL);
3407  if (repr_p == NULL)
3408  {
3409  assert (er_errid () != NO_ERROR);
3410  error = er_errid ();
3411  return error;
3412  }
3413  }
3414 
3415  buf_p = &repr_buffer;
3416  or_init (buf_p, record_p->data, record_p->length);
3417 
3418  error = catcls_put_or_value_into_buffer (value_p, chn, buf_p, class_oid_p, repr_p);
3419  if (error != NO_ERROR)
3420  {
3422  return error;
3423  }
3424 
3425  record_p->length = (int) (buf_p->ptr - buf_p->buffer);
3427 
3428  return NO_ERROR;
3429 }
3430 
3431 /*
3432  * catcls_get_or_value_from_class_record () -
3433  * return:
3434  * record(in):
3435  */
3436 static OR_VALUE *
3438 {
3439  OR_VALUE *value_p = NULL;
3440  OR_BUF *buf_p, repr_buffer;
3441 
3442  value_p = catcls_allocate_or_value (1);
3443  if (value_p == NULL)
3444  {
3445  return NULL;
3446  }
3447 
3449 
3450  buf_p = &repr_buffer;
3451  or_init (buf_p, record_p->data, record_p->length);
3452 
3453  /* class record header does not contain MVCC info */
3455  if (catcls_get_or_value_from_class (thread_p, buf_p, value_p) != NO_ERROR)
3456  {
3457  catcls_free_or_value (value_p);
3458  return NULL;
3459  }
3460 
3461  return value_p;
3462 }
3463 
3464 /*
3465  * catcls_get_or_value_from_record () -
3466  * return:
3467  * record(in):
3468  * class_oid(in):
3469  */
3470 static OR_VALUE *
3471 catcls_get_or_value_from_record (THREAD_ENTRY * thread_p, RECDES * record_p, OID * class_oid_p)
3472 {
3473  OR_VALUE *value_p = NULL;
3474  OR_BUF *buf_p, repr_buffer;
3475  REPR_ID repr_id;
3476  DISK_REPR *repr_p = NULL;
3477 
3478  if (catalog_get_last_representation_id (thread_p, class_oid_p, &repr_id) != NO_ERROR)
3479  {
3480  goto error;
3481  }
3482 
3483  repr_p = catalog_get_representation (thread_p, class_oid_p, repr_id, NULL);
3484  if (repr_p == NULL)
3485  {
3486  assert (er_errid () != NO_ERROR);
3487  goto error;
3488  }
3489 
3490  value_p = catcls_allocate_or_value (1);
3491  if (value_p == NULL)
3492  {
3493  goto error;
3494  }
3495 
3496  if (catcls_expand_or_value_by_repr (value_p, class_oid_p, repr_p) != NO_ERROR)
3497  {
3498  goto error;
3499  }
3500 
3501  buf_p = &repr_buffer;
3502  or_init (buf_p, record_p->data, record_p->length);
3503 
3504  if (catcls_get_or_value_from_buffer (thread_p, buf_p, value_p, repr_p) != NO_ERROR)
3505  {
3506  goto error;
3507  }
3508 
3510  return value_p;
3511 
3512 error:
3513 
3514  if (value_p)
3515  {
3516  catcls_free_or_value (value_p);
3517  }
3518 
3519  if (repr_p)
3520  {
3522  }
3523 
3524  return NULL;
3525 }
3526 
3527 /*
3528  * catcls_insert_subset () -
3529  * return:
3530  * value(in):
3531  * root_oid(in):
3532  */
3533 static int
3534 catcls_insert_subset (THREAD_ENTRY * thread_p, OR_VALUE * value_p, OID * root_oid_p)
3535 {
3536  OR_VALUE *subset_p;
3537  int n_subset;
3538  OID *class_oid_p, oid;
3539  CLS_INFO *cls_info_p = NULL;
3540  HFID *hfid_p;
3541  DB_SET *oid_set_p = NULL;
3542  DB_VALUE oid_val;
3543  int i;
3544  HEAP_SCANCACHE scan;
3545  bool is_scan_inited = false;
3546  int error = NO_ERROR;
3547 
3548  subset_p = value_p->sub.value;
3549  n_subset = value_p->sub.count;
3550 
3551  if (n_subset == 0)
3552  {
3553  return NO_ERROR;
3554  }
3555 
3556  oid_set_p = set_create_sequence (n_subset);
3557  if (oid_set_p == NULL)
3558  {
3559  assert (er_errid () != NO_ERROR);
3560  error = er_errid ();
3561  goto error;
3562  }
3563 
3564  class_oid_p = &subset_p[0].id.classoid;
3565  cls_info_p = catalog_get_class_info (thread_p, class_oid_p, NULL);
3566  if (cls_info_p == NULL)
3567  {
3568  assert (er_errid () != NO_ERROR);
3569  error = er_errid ();
3570  goto error;
3571  }
3572 
3573  hfid_p = &cls_info_p->ci_hfid;
3574  /* need to update assigned oid of each instance */
3575  if (heap_scancache_start_modify (thread_p, &scan, hfid_p, class_oid_p, MULTI_ROW_UPDATE, NULL) != NO_ERROR)
3576  {
3577  assert (er_errid () != NO_ERROR);
3578  error = er_errid ();
3579  goto error;
3580  }
3581 
3582  is_scan_inited = true;
3583 
3584  for (i = 0; i < n_subset; i++)
3585  {
3586  error = catcls_insert_instance (thread_p, &subset_p[i], &oid, root_oid_p, class_oid_p, hfid_p, &scan);
3587  if (error != NO_ERROR)
3588  {
3589  goto error;
3590  }
3591 
3592  db_make_oid (&oid_val, &oid);
3593  error = set_put_element (oid_set_p, i, &oid_val);
3594  if (error != NO_ERROR)
3595  {
3596  goto error;
3597  }
3598  }
3599 
3600  db_make_sequence (&value_p->value, oid_set_p);
3601 
3602  heap_scancache_end_modify (thread_p, &scan);
3603  catalog_free_class_info_and_init (cls_info_p);
3604 
3605  return NO_ERROR;
3606 
3607 error:
3608 
3609  if (oid_set_p)
3610  {
3611  set_free (oid_set_p);
3612  }
3613 
3614  if (is_scan_inited)
3615  {
3616  heap_scancache_end_modify (thread_p, &scan);
3617  }
3618 
3619  if (cls_info_p)
3620  {
3621  catalog_free_class_info_and_init (cls_info_p);
3622  }
3623 
3624  return error;
3625 }
3626 
3627 /*
3628  * catcls_delete_subset () -
3629  * return:
3630  * value(in):
3631  */
3632 static int
3634 {
3635  OR_VALUE *subset_p;
3636  int n_subset;
3637  OID *class_oid_p, *oid_p;
3638  CLS_INFO *cls_info_p = NULL;
3639  HFID *hfid_p;
3640  DB_SET *oid_set_p;
3641  DB_VALUE oid_val;
3642  int i;
3643  HEAP_SCANCACHE scan;
3644  bool is_scan_inited = false;
3645  int error = NO_ERROR;
3646 
3647  subset_p = value_p->sub.value;
3648  n_subset = value_p->sub.count;
3649 
3650  if (n_subset == 0)
3651  {
3652  return NO_ERROR;
3653  }
3654 
3655  oid_set_p = db_get_set (&value_p->value);
3656  class_oid_p = &subset_p[0].id.classoid;
3657 
3658  cls_info_p = catalog_get_class_info (thread_p, class_oid_p, NULL);
3659  if (cls_info_p == NULL)
3660  {
3661  assert (er_errid () != NO_ERROR);
3662  error = er_errid ();
3663  goto error;
3664  }
3665 
3666  hfid_p = &cls_info_p->ci_hfid;
3667  if (heap_scancache_start_modify (thread_p, &scan, hfid_p, class_oid_p, MULTI_ROW_DELETE, NULL) != NO_ERROR)
3668  {
3669  assert (er_errid () != NO_ERROR);
3670  error = er_errid ();
3671  goto error;
3672  }
3673 
3674  is_scan_inited = true;
3675 
3676  for (i = 0; i < n_subset; i++)
3677  {
3678  error = set_get_element (oid_set_p, i, &oid_val);
3679  if (error != NO_ERROR)
3680  {
3681  goto error;
3682  }
3683 
3684  oid_p = db_get_oid (&oid_val);
3685  error = catcls_delete_instance (thread_p, oid_p, class_oid_p, hfid_p, &scan);
3686  if (error != NO_ERROR)
3687  {
3688  goto error;
3689  }
3690  }
3691 
3692  heap_scancache_end_modify (thread_p, &scan);
3693  catalog_free_class_info_and_init (cls_info_p);
3694 
3695  return NO_ERROR;
3696 
3697 error:
3698 
3699  if (is_scan_inited)
3700  {
3701  heap_scancache_end_modify (thread_p, &scan);
3702  }
3703 
3704  if (cls_info_p)
3705  {
3706  catalog_free_class_info_and_init (cls_info_p);
3707  }
3708 
3709  return error;
3710 }
3711 
3712 /*
3713  * catcls_insert_instance () -
3714  * return:
3715  * value(in):
3716  * oid(in):
3717  * root_oid(in):
3718  * class_oid(in):
3719  * hfid(in):
3720  * scan(in):
3721  */
3722 static int
3723 catcls_insert_instance (THREAD_ENTRY * thread_p, OR_VALUE * value_p, OID * oid_p, OID * root_oid_p, OID * class_oid_p,
3724  HFID * hfid_p, HEAP_SCANCACHE * scan_p)
3725 {
3726  HEAP_OPERATION_CONTEXT update_context;
3727  RECDES record;
3728  OR_VALUE *attrs;
3729  OR_VALUE *subset_p, *attr_p;
3730  int i, j, k;
3731  bool is_lock_inited = false;
3732  int error = NO_ERROR;
3733 
3734  record.data = NULL;
3735 
3736  if (heap_assign_address (thread_p, hfid_p, class_oid_p, oid_p, 0) != NO_ERROR)
3737  {
3738  assert (er_errid () != NO_ERROR);
3739  error = er_errid ();
3740  goto error;
3741  }
3742 
3743  is_lock_inited = true;
3744 
3745  if (OID_ISNULL (root_oid_p))
3746  {
3747  COPY_OID (root_oid_p, oid_p);
3748  }
3749 
3750  for (attrs = value_p->sub.value, i = 0; i < value_p->sub.count; i++)
3751  {
3752  if (IS_SUBSET (attrs[i]))
3753  {
3754  /* set backward oid */
3755  for (subset_p = attrs[i].sub.value, j = 0; j < attrs[i].sub.count; j++)
3756  {
3757  /* assume that the attribute values of xxx are ordered by { class_of, xxx_name, xxx_type, from_xxx_name,
3758  * ... } */
3759 
3760  attr_p = subset_p[j].sub.value;
3761  db_make_oid (&attr_p[0].value, oid_p);
3762 
3763  if (OID_EQ (class_oid_p, &ct_Class.cc_classoid))
3764  {
3765  /* if root node, eliminate self references */
3766  for (k = 1; k < subset_p[j].sub.count; k++)
3767  {
3768  if (DB_VALUE_TYPE (&attr_p[k].value) == DB_TYPE_OID)
3769  {
3770  if (OID_EQ (oid_p, db_get_oid (&attr_p[k].value)))
3771  {
3772  db_value_put_null (&attr_p[k].value);
3773  }
3774  }
3775  }
3776  }
3777  }
3778 
3779  error = catcls_insert_subset (thread_p, &attrs[i], root_oid_p);
3780  if (error != NO_ERROR)
3781  {
3782  goto error;
3783  }
3784  }
3785  else if (DB_VALUE_DOMAIN_TYPE (&attrs[i].value) == DB_TYPE_VARIABLE)
3786  {
3787  /* set a self referenced oid */
3788  db_make_oid (&attrs[i].value, root_oid_p);
3789  }
3790  }
3791 
3792  error = catcls_reorder_attributes_by_repr (thread_p, value_p);
3793  if (error != NO_ERROR)
3794  {
3795  goto error;
3796  }
3797 
3798  record.length = catcls_guess_record_length (value_p);
3799  record.area_size = record.length;
3800  record.type = REC_HOME;
3801  record.data = (char *) malloc (record.length);
3802 
3803  if (record.data == NULL)
3804  {
3805  error = ER_OUT_OF_VIRTUAL_MEMORY;
3806  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, (size_t) record.length);
3807  goto error;
3808  }
3809 
3810  error = catcls_put_or_value_into_record (thread_p, value_p, 0, &record, class_oid_p);
3811  if (error != NO_ERROR)
3812  {
3813  goto error;
3814  }
3815 
3816  /* for replication */
3817  if (locator_add_or_remove_index (thread_p, &record, oid_p, class_oid_p, true, SINGLE_ROW_INSERT, scan_p, false, false,
3818  hfid_p, NULL, false, false) != NO_ERROR)
3819  {
3820  assert (er_errid () != NO_ERROR);
3821  error = er_errid ();
3822  goto error;
3823  }
3824 
3825  heap_create_update_context (&update_context, hfid_p, oid_p, class_oid_p, &record, scan_p,
3827  if (heap_update_logical (thread_p, &update_context) != NO_ERROR)
3828  {
3829  error = er_errid ();
3830  assert (error != NO_ERROR);
3831  goto error;
3832  }
3833 
3834  free_and_init (record.data);
3835 
3836  return NO_ERROR;
3837 
3838 error:
3839 
3840  if (record.data)
3841  {
3842  free_and_init (record.data);
3843  }
3844 
3845  return error;
3846 }
3847 
3848 /*
3849  * catcls_delete_instance () -
3850  * return:
3851  * oid(in):
3852  * class_oid(in):
3853  * hfid(in):
3854  * scan(in):
3855  */
3856 static int
3857 catcls_delete_instance (THREAD_ENTRY * thread_p, OID * oid_p, OID * class_oid_p, HFID * hfid_p, HEAP_SCANCACHE * scan_p)
3858 {
3859  HEAP_OPERATION_CONTEXT delete_context;
3860  RECDES record = RECDES_INITIALIZER;
3861  OR_VALUE *value_p = NULL;
3862  OR_VALUE *attrs;
3863  int i;
3864 #if defined(SERVER_MODE)
3865  bool is_lock_inited = false;
3866 #endif /* SERVER_MODE */
3867  int error = NO_ERROR;
3868 
3869  assert (oid_p != NULL && class_oid_p != NULL && hfid_p != NULL && scan_p != NULL);
3870 
3871 #if defined(SERVER_MODE)
3872  if (lock_object (thread_p, oid_p, class_oid_p, X_LOCK, LK_UNCOND_LOCK) != LK_GRANTED)
3873  {
3874  assert (er_errid () != NO_ERROR);
3875  error = er_errid ();
3876  goto error;
3877  }
3878  is_lock_inited = true;
3879 #endif /* SERVER_MODE */
3880 
3881  if (heap_get_visible_version (thread_p, oid_p, class_oid_p, &record, scan_p, COPY, NULL_CHN) != S_SUCCESS)
3882  {
3883  assert (er_errid () != NO_ERROR);
3884  error = er_errid ();
3885  goto error;
3886  }
3887 
3888  value_p = catcls_get_or_value_from_record (thread_p, &record, class_oid_p);
3889  if (value_p == NULL)
3890  {
3891  assert (er_errid () != NO_ERROR);
3892  error = er_errid ();
3893  goto error;
3894  }
3895 
3896  for (attrs = value_p->sub.value, i = 0; i < value_p->sub.count; i++)
3897  {
3898  if (IS_SUBSET (attrs[i]))
3899  {
3900  error = catcls_delete_subset (thread_p, &attrs[i]);
3901  if (error != NO_ERROR)
3902  {
3903  goto error;
3904  }
3905  }
3906  }
3907 
3908  /* for replication */
3909  if (locator_add_or_remove_index (thread_p, &record, oid_p, class_oid_p, false, SINGLE_ROW_DELETE, scan_p, false,
3910  false, hfid_p, NULL, false, false) != NO_ERROR)
3911  {
3912  assert (er_errid () != NO_ERROR);
3913  error = er_errid ();
3914  goto error;
3915  }
3916 
3917  /* build operation context */
3918  heap_create_delete_context (&delete_context, hfid_p, oid_p, class_oid_p, scan_p);
3919 
3920  /* delete */
3921  if (heap_delete_logical (thread_p, &delete_context) != NO_ERROR)
3922  {
3923  assert (er_errid () != NO_ERROR);
3924  error = er_errid ();
3925  goto error;
3926  }
3927 
3928  catcls_free_or_value (value_p);
3929 
3930  return NO_ERROR;
3931 
3932 error:
3933 
3934  if (value_p)
3935  {
3936  catcls_free_or_value (value_p);
3937  }
3938 
3939  return error;
3940 }
3941 
3942 /*
3943  * catcls_update_instance () -
3944  * return:
3945  * value(in):
3946  * oid(in):
3947  * class_oid(in):
3948  * hfid(in):
3949  * scan(in):
3950  * force_in_place(in): UPDATE_INPLACE style
3951  */
3952 static int
3953 catcls_update_instance (THREAD_ENTRY * thread_p, OR_VALUE * value_p, OID * oid_p, OID * class_oid_p, HFID * hfid_p,
3954  HEAP_SCANCACHE * scan_p, UPDATE_INPLACE_STYLE force_in_place)
3955 {
3956  RECDES record = RECDES_INITIALIZER, old_record = RECDES_INITIALIZER;
3957  OR_VALUE *old_value_p = NULL;
3958  OR_VALUE *attrs, *old_attrs;
3959  OR_VALUE *subset_p, *attr_p;
3960  int old_chn;
3961  bool uflag = false;
3962  int i, j, k;
3963  int error = NO_ERROR;
3964 
3965  if (heap_get_visible_version (thread_p, oid_p, class_oid_p, &old_record, scan_p, COPY, NULL_CHN) != S_SUCCESS)
3966  {
3967  assert (er_errid () != NO_ERROR);
3968  error = er_errid ();
3969  goto error;
3970  }
3971 
3972  old_chn = or_chn (&old_record);
3973  old_value_p = catcls_get_or_value_from_record (thread_p, &old_record, class_oid_p);
3974  if (old_value_p == NULL)
3975  {
3976  assert (er_errid () != NO_ERROR);
3977  error = er_errid ();
3978  goto error;
3979  }
3980 
3981  error = catcls_reorder_attributes_by_repr (thread_p, value_p);
3982  if (error != NO_ERROR)
3983  {
3984  goto error;
3985  }
3986 
3987  /* update old_value */
3988  for (attrs = value_p->sub.value, old_attrs = old_value_p->sub.value, i = 0; i < value_p->sub.count; i++)
3989  {
3990  if (IS_SUBSET (attrs[i]))
3991  {
3992  /* set backward oid */
3993  for (subset_p = attrs[i].sub.value, j = 0; j < attrs[i].sub.count; j++)
3994  {
3995  /* assume that the attribute values of xxx are ordered by { class_of, xxx_name, xxx_type, from_xxx_name,
3996  * ... } */
3997  attr_p = subset_p[j].sub.value;
3998  db_make_oid (&attr_p[0].value, oid_p);
3999 
4000  if (OID_EQ (class_oid_p, &ct_Class.cc_classoid))
4001  {
4002  /* if root node, eliminate self references */
4003  for (k = 1; k < subset_p[j].sub.count; k++)
4004  {
4005  if (DB_VALUE_TYPE (&attr_p[k].value) == DB_TYPE_OID)
4006  {
4007  if (OID_EQ (oid_p, db_get_oid (&attr_p[k].value)))
4008  {
4009  db_value_put_null (&attr_p[k].value);
4010  }
4011  }
4012  }
4013  }
4014  }
4015 
4016  error = catcls_update_subset (thread_p, &attrs[i], &old_attrs[i], &uflag, force_in_place);
4017  if (error != NO_ERROR)
4018  {
4019  goto error;
4020  }
4021  }
4022  else
4023  {
4024  if (tp_value_compare (&old_attrs[i].value, &attrs[i].value, 1, 1) != DB_EQ)
4025  {
4026  uflag = true;
4027  }
4028  }
4029  }
4030 
4031  if (uflag == true)
4032  {
4033  HEAP_OPERATION_CONTEXT update_context;
4034 
4035  record.length = catcls_guess_record_length (value_p);
4036  record.area_size = record.length;
4037  record.type = REC_HOME;
4038  record.data = (char *) malloc (record.length);
4039 
4040  if (record.data == NULL)
4041  {
4042  error = ER_OUT_OF_VIRTUAL_MEMORY;
4043  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, (size_t) record.length);
4044  goto error;
4045  }
4046 
4047  error = catcls_put_or_value_into_record (thread_p, value_p, old_chn + 1, &record, class_oid_p);
4048  if (error != NO_ERROR)
4049  {
4050  goto error;
4051  }
4052 
4053  /* give up setting updated attr info */
4054  if (locator_update_index (thread_p, &record, &old_record, NULL, 0, oid_p, class_oid_p, SINGLE_ROW_UPDATE,
4055  scan_p, NULL) != NO_ERROR)
4056  {
4057  assert (er_errid () != NO_ERROR);
4058  error = er_errid ();
4059  goto error;
4060  }
4061 
4062  /* update in place */
4063  heap_create_update_context (&update_context, hfid_p, oid_p, class_oid_p, &record, scan_p, force_in_place);
4064  if (heap_update_logical (thread_p, &update_context) != NO_ERROR)
4065  {
4066  assert (er_errid () != NO_ERROR);
4067  error = er_errid ();
4068  goto error;
4069  }
4070 
4071  free_and_init (record.data);
4072  }
4073 
4074  catcls_free_or_value (old_value_p);
4075 
4076  return NO_ERROR;
4077 
4078 error:
4079 
4080  if (record.data)
4081  {
4082  free_and_init (record.data);
4083  }
4084 
4085  if (old_value_p)
4086  {
4087  catcls_free_or_value (old_value_p);
4088  }
4089 
4090  return error;
4091 }
4092 
4093 /*
4094  * catcls_insert_catalog_classes () -
4095  * return:
4096  * record(in):
4097  */
4098 int
4100 {
4101  OR_VALUE *value_p = NULL;
4102  OID oid, *class_oid_p;
4103  OID root_oid = { NULL_PAGEID, NULL_SLOTID, NULL_VOLID };
4104  CLS_INFO *cls_info_p = NULL;
4105  HFID *hfid_p;
4106  HEAP_SCANCACHE scan;
4107  bool is_scan_inited = false;
4108 
4109  value_p = catcls_get_or_value_from_class_record (thread_p, record_p);
4110  if (value_p == NULL)
4111  {
4112  goto error;
4113  }
4114 
4115  class_oid_p = &ct_Class.cc_classoid;
4116  cls_info_p = catalog_get_class_info (thread_p, class_oid_p, NULL);
4117  if (cls_info_p == NULL)
4118  {
4119  goto error;
4120  }
4121 
4122  hfid_p = &cls_info_p->ci_hfid;
4123  if (heap_scancache_start_modify (thread_p, &scan, hfid_p, class_oid_p, SINGLE_ROW_UPDATE, NULL) != NO_ERROR)
4124  {
4125  goto error;
4126  }
4127 
4128  is_scan_inited = true;
4129 
4130  if (catcls_insert_instance (thread_p, value_p, &oid, &root_oid, class_oid_p, hfid_p, &scan) != NO_ERROR)
4131  {
4132  goto error;
4133  }
4134 
4135  heap_scancache_end_modify (thread_p, &scan);
4136  catalog_free_class_info_and_init (cls_info_p);
4137  catcls_free_or_value (value_p);
4138 
4139  return NO_ERROR;
4140 
4141 error:
4142 
4143  if (is_scan_inited)
4144  {
4145  heap_scancache_end_modify (thread_p, &scan);
4146  }
4147 
4148  if (cls_info_p)
4149  {
4150  catalog_free_class_info_and_init (cls_info_p);
4151  }
4152 
4153  if (value_p)
4154  {
4155  catcls_free_or_value (value_p);
4156  }
4157 
4158  return ER_FAILED;
4159 }
4160 
4161 /*
4162  * catcls_delete_catalog_classes () -
4163  * return:
4164  * name(in):
4165  * class_oid(in):
4166  */
4167 int
4168 catcls_delete_catalog_classes (THREAD_ENTRY * thread_p, const char *name_p, OID * class_oid_p)
4169 {
4170  OID oid, *ct_class_oid_p;
4171  CLS_INFO *cls_info_p = NULL;
4172  HFID *hfid_p;
4173  HEAP_SCANCACHE scan;
4174  bool is_scan_inited = false;
4175 
4176  if (catcls_find_oid_by_class_name (thread_p, name_p, &oid) != NO_ERROR)
4177  {
4178  goto error;
4179  }
4180 
4181  if (OID_ISNULL (&oid))
4182  {
4184  goto error;
4185  }
4186 
4187  ct_class_oid_p = &ct_Class.cc_classoid;
4188  cls_info_p = catalog_get_class_info (thread_p, ct_class_oid_p, NULL);
4189  if (cls_info_p == NULL)
4190  {
4191  goto error;
4192  }
4193 
4194  hfid_p = &cls_info_p->ci_hfid;
4195  /* in MVCC, do not physically remove the row */
4196  if (heap_scancache_start_modify (thread_p, &scan, hfid_p, ct_class_oid_p, SINGLE_ROW_DELETE, NULL) != NO_ERROR)
4197  {
4198  goto error;
4199  }
4200 
4201  is_scan_inited = true;
4202 
4203  if (catcls_delete_instance (thread_p, &oid, ct_class_oid_p, hfid_p, &scan) != NO_ERROR)
4204  {
4205  goto error;
4206  }
4207 
4208  if (csect_enter (thread_p, CSECT_CT_OID_TABLE, INF_WAIT) != NO_ERROR)
4209  {
4210  goto error;
4211  }
4212 
4213  if (catcls_remove_entry (thread_p, class_oid_p) != NO_ERROR)
4214  {
4215  csect_exit (thread_p, CSECT_CT_OID_TABLE);
4216  goto error;
4217  }
4218 
4219  csect_exit (thread_p, CSECT_CT_OID_TABLE);
4220 
4221  heap_scancache_end_modify (thread_p, &scan);
4222  catalog_free_class_info_and_init (cls_info_p);
4223 
4224  return NO_ERROR;
4225 
4226 error:
4227 
4228  if (is_scan_inited)
4229  {
4230  heap_scancache_end_modify (thread_p, &scan);
4231  }
4232 
4233  if (cls_info_p)
4234  {
4235  catalog_free_class_info_and_init (cls_info_p);
4236  }
4237 
4238  return ER_FAILED;
4239 }
4240 
4241 /*
4242  * catcls_update_catalog_classes () -
4243  * return:
4244  * name(in):
4245  * record(in):
4246  * class_oid_p(in): class OID
4247  * force_in_place(in): if UPDATE_INPLACE_NONE then the 'in place' will not be forced
4248  * and the update style will be decided in this function.
4249  * Otherwise the update of the instance will be made in
4250  * place and according to provided style.
4251  */
4252 int
4253 catcls_update_catalog_classes (THREAD_ENTRY * thread_p, const char *name_p, RECDES * record_p, OID * class_oid_p,
4254  UPDATE_INPLACE_STYLE force_in_place)
4255 {
4256  OR_VALUE *value_p = NULL;
4257  OID oid, *catalog_class_oid_p;
4258  CLS_INFO *cls_info_p = NULL;
4259  HFID *hfid_p;
4260  HEAP_SCANCACHE scan;
4261  bool is_scan_inited = false;
4262 
4263  if (catcls_find_oid_by_class_name (thread_p, name_p, &oid) != NO_ERROR)
4264  {
4265  goto error;
4266  }
4267 
4268  if (OID_ISNULL (&oid))
4269  {
4270  return (catcls_insert_catalog_classes (thread_p, record_p));
4271  }
4272 
4273  value_p = catcls_get_or_value_from_class_record (thread_p, record_p);
4274  if (value_p == NULL)
4275  {
4276  goto error;
4277  }
4278 
4279  catalog_class_oid_p = &ct_Class.cc_classoid;
4280  cls_info_p = catalog_get_class_info (thread_p, catalog_class_oid_p, NULL);
4281  if (cls_info_p == NULL)
4282  {
4283  goto error;
4284  }
4285 
4286  hfid_p = &cls_info_p->ci_hfid;
4287  if (heap_scancache_start_modify (thread_p, &scan, hfid_p, catalog_class_oid_p, SINGLE_ROW_UPDATE, NULL) != NO_ERROR)
4288  {
4289  goto error;
4290  }
4291 
4292  is_scan_inited = true;
4293 
4294  /* update catalog classes */
4295  if (catcls_update_instance (thread_p, value_p, &oid, catalog_class_oid_p, hfid_p, &scan, force_in_place) != NO_ERROR)
4296  {
4297  goto error;
4298  }
4299 
4300  heap_scancache_end_modify (thread_p, &scan);
4301  catalog_free_class_info_and_init (cls_info_p);
4302  catcls_free_or_value (value_p);
4303 
4304  return NO_ERROR;
4305 
4306 error:
4307 
4308  if (is_scan_inited)
4309  {
4310  heap_scancache_end_modify (thread_p, &scan);
4311  }
4312 
4313  if (cls_info_p)
4314  {
4315  catalog_free_class_info_and_init (cls_info_p);
4316  }
4317 
4318  if (value_p)
4319  {
4320  catcls_free_or_value (value_p);
4321  }
4322 
4323  return ER_FAILED;
4324 }
4325 
4326 /*
4327  * catcls_compile_catalog_classes () -
4328  * return:
4329  * void(in):
4330  */
4331 int
4333 {
4334  RECDES class_record;
4335  OID *class_oid_p, tmp_oid;
4336  const char *class_name_p;
4337  char *attr_name_p;
4338  CT_ATTR *atts;
4339  int n_atts;
4340  int c, a, i;
4341  HEAP_SCANCACHE scan;
4342  char *string = NULL;
4343  int alloced_string = 0;
4344  int error = NO_ERROR;
4345 
4346  if (thread_p == NULL)
4347  {
4348  // because SA_MODE client calls this directly with NULL argument...
4349  thread_p = thread_get_thread_entry_info ();
4350  }
4351 
4352  /* check if an old version database */
4353  if (catcls_find_class_oid_by_class_name (thread_p, CT_CLASS_NAME, &tmp_oid) != NO_ERROR)
4354  {
4355  return ER_FAILED;
4356  }
4357  else if (OID_ISNULL (&tmp_oid))
4358  {
4359  /* no catalog classes */
4360  return NO_ERROR;
4361  }
4362 
4363  /* fill classoid and attribute ids for each meta catalog classes */
4364  for (c = 0; ct_Classes[c] != NULL; c++)
4365  {
4366  class_name_p = ct_Classes[c]->cc_name;
4367  class_oid_p = &ct_Classes[c]->cc_classoid;
4368 
4369  if (catcls_find_class_oid_by_class_name (thread_p, class_name_p, class_oid_p) != NO_ERROR)
4370  {
4371  return ER_FAILED;
4372  }
4373 
4374  atts = ct_Classes[c]->cc_atts;
4375  n_atts = ct_Classes[c]->cc_n_atts;
4376 
4377  if (heap_scancache_quick_start_root_hfid (thread_p, &scan) != NO_ERROR)
4378  {
4379  return ER_FAILED;
4380  }
4381  if (heap_get_class_record (thread_p, class_oid_p, &class_record, &scan, PEEK) != S_SUCCESS)
4382  {
4383  (void) heap_scancache_end (thread_p, &scan);
4384  return ER_FAILED;
4385  }
4386 
4387  for (i = 0; i < n_atts; i++)
4388  {
4389  string = NULL;
4390  alloced_string = 0;
4391 
4392  error = or_get_attrname (&class_record, i, &string, &alloced_string);
4393  if (error != NO_ERROR)
4394  {
4395  ASSERT_ERROR ();
4396  (void) heap_scancache_end (thread_p, &scan);
4397  return error;
4398  }
4399 
4400  attr_name_p = string;
4401  if (attr_name_p == NULL)
4402  {
4403  (void) heap_scancache_end (thread_p, &scan);
4404  return ER_FAILED;
4405  }
4406 
4407  for (a = 0; a < n_atts; a++)
4408  {
4409  if (strcmp (atts[a].ca_name, attr_name_p) == 0)
4410  {
4411  atts[a].ca_id = i;
4412 
4413  if (string != NULL && alloced_string == 1)
4414  {
4415  db_private_free_and_init (thread_p, string);
4416  }
4417 
4418  break;
4419  }
4420  }
4421 
4422  if (string != NULL && alloced_string == 1)
4423  {
4424  db_private_free_and_init (thread_p, string);
4425  }
4426  }
4427  if (heap_scancache_end (thread_p, &scan) != NO_ERROR)
4428  {
4429  return ER_FAILED;
4430  }
4431  }
4432 
4433  catcls_Enable = true;
4434 
4435  if (catcls_find_btid_of_class_name (thread_p, &catcls_Btid) != NO_ERROR)
4436  {
4437  return ER_FAILED;
4438  }
4439 
4441  {
4442  return ER_FAILED;
4443  }
4444 
4445  return NO_ERROR;
4446 }
4447 
4448 /*
4449  * catcls_get_server_compat_info () - get the language id, charset id and
4450  * timezone checksum stored in the
4451  * "db_root" system table
4452  * return: NO_ERROR, or error code
4453  * thread_p(in) : thread context
4454  * charset_id_p(out):
4455  * lang_buf(in/out): buffer language string
4456  * lang_buf_size(in): size of buffer language string
4457  * timezone_checksum(out): timezone_checksum
4458  * Note : This function is called during server initialization, for this
4459  * reason, no locks are required on the class.
4460  */
4461 int
4462 catcls_get_server_compat_info (THREAD_ENTRY * thread_p, INTL_CODESET * charset_id_p, char *lang_buf,
4463  const int lang_buf_size, char *timezone_checksum)
4464 {
4465  OID class_oid;
4466  OID inst_oid;
4467  HFID hfid;
4468  HEAP_CACHE_ATTRINFO attr_info;
4469  HEAP_SCANCACHE scan_cache;
4470  RECDES recdes;
4471  const char *class_name = "db_root";
4472  int charset_att_id = -1, lang_att_id = -1;
4473  int timezone_id = -1;
4474  int i;
4475  int error = NO_ERROR;
4476  bool scan_cache_inited = false;
4477  bool attr_info_inited = false;
4478 
4479  assert (charset_id_p != NULL);
4480  assert (lang_buf != NULL);
4481  assert (timezone_checksum != NULL);
4482 
4483  OID_SET_NULL (&class_oid);
4484  OID_SET_NULL (&inst_oid);
4485 
4486  error = catcls_find_class_oid_by_class_name (thread_p, class_name, &class_oid);
4487  if (error != NO_ERROR)
4488  {
4489  goto exit;
4490  }
4491 
4492  if (OID_ISNULL (&class_oid))
4493  {
4495  error = ER_LC_UNKNOWN_CLASSNAME;
4496  goto exit;
4497  }
4498 
4499  error = heap_attrinfo_start (thread_p, &class_oid, -1, NULL, &attr_info);
4500  if (error != NO_ERROR)
4501  {
4502  goto exit;
4503  }
4504  attr_info_inited = true;
4505 
4506  (void) heap_scancache_quick_start_root_hfid (thread_p, &scan_cache);
4507  scan_cache_inited = true;
4508 
4509  if (heap_get_class_record (thread_p, &class_oid, &recdes, &scan_cache, PEEK) != S_SUCCESS)
4510  {
4511  error = ER_FAILED;
4512  goto exit;
4513  }
4514 
4515  for (i = 0; i < attr_info.num_values; i++)
4516  {
4517  char *rec_attr_name_p, *string = NULL;
4518  int alloced_string = 0;
4519  bool set_break = false;
4520 
4521  error = or_get_attrname (&recdes, i, &string, &alloced_string);
4522  if (error != NO_ERROR)
4523  {
4524  ASSERT_ERROR ();
4525  goto exit;
4526  }
4527 
4528  rec_attr_name_p = string;
4529  if (rec_attr_name_p == NULL)
4530  {
4531  error = ER_FAILED;
4532  goto exit;
4533  }
4534 
4535  if (strcmp ("charset", rec_attr_name_p) == 0)
4536  {
4537  charset_att_id = i;
4538  if (lang_att_id != -1)
4539  {
4540  set_break = true;
4541  goto clean_string;
4542  }
4543  }
4544 
4545  if (strcmp ("lang", rec_attr_name_p) == 0)
4546  {
4547  lang_att_id = i;
4548  if (charset_att_id != -1)
4549  {
4550  set_break = true;
4551  goto clean_string;
4552  }
4553  }
4554 
4555  if (strcmp ("timezone_checksum", rec_attr_name_p) == 0)
4556  {
4557  timezone_id = i;
4558  }
4559 
4560  clean_string:
4561  if (string != NULL && alloced_string == 1)
4562  {
4563  db_private_free_and_init (thread_p, string);
4564  }
4565 
4566  if (set_break == true)
4567  {
4568  break;
4569  }
4570  }
4571 
4572  if (charset_att_id == -1 || lang_att_id == -1 || timezone_id == -1)
4573  {
4575  error = ER_FAILED;
4576  goto exit;
4577  }
4578 
4579  (void) heap_scancache_end (thread_p, &scan_cache);
4580  scan_cache_inited = false;
4581 
4582  /* read values of the single record in heap */
4583  error = heap_get_class_info (thread_p, &class_oid, &hfid, NULL, NULL);
4584  if (error != NO_ERROR || HFID_IS_NULL (&hfid))
4585  {
4586  error = ER_FAILED;
4587  goto exit;
4588  }
4589 
4590  error = heap_scancache_start (thread_p, &scan_cache, &hfid, NULL, true, false, NULL);
4591  if (error != NO_ERROR)
4592  {
4593  goto exit;
4594  }
4595  scan_cache_inited = true;
4596 
4597  while (heap_next (thread_p, &hfid, NULL, &inst_oid, &recdes, &scan_cache, PEEK) == S_SUCCESS)
4598  {
4599  HEAP_ATTRVALUE *heap_value = NULL;
4600 
4601  if (heap_attrinfo_read_dbvalues (thread_p, &inst_oid, &recdes, NULL, &attr_info) != NO_ERROR)
4602  {
4603  error = ER_FAILED;
4604  goto exit;
4605  }
4606 
4607  for (i = 0, heap_value = attr_info.values; i < attr_info.num_values; i++, heap_value++)
4608  {
4609  if (heap_value->attrid == charset_att_id)
4610  {
4611  if (DB_IS_NULL (&heap_value->dbvalue))
4612  {
4613  error = ER_FAILED;
4615  goto exit;
4616  }
4617  assert (DB_VALUE_DOMAIN_TYPE (&(heap_value->dbvalue)) == DB_TYPE_INTEGER);
4618 
4619  *charset_id_p = (INTL_CODESET) db_get_int (&heap_value->dbvalue);
4620  }
4621  else if (heap_value->attrid == lang_att_id)
4622  {
4623  const char *lang_str = NULL;
4624  size_t lang_str_len;
4625 
4626  if (DB_IS_NULL (&heap_value->dbvalue))
4627  {
4628  error = ER_FAILED;
4630  goto exit;
4631  }
4632 
4633  assert (DB_VALUE_DOMAIN_TYPE (&(heap_value->dbvalue)) == DB_TYPE_STRING);
4634 
4635  lang_str = db_get_string (&heap_value->dbvalue);
4636  lang_str_len = (lang_str != NULL) ? strlen (lang_str) : 0;
4637 
4638  assert ((int) lang_str_len < lang_buf_size);
4639  if (lang_str_len > 0)
4640  {
4641  /* Copying length 0 from NULL pointer fails when DUMA is enabled. */
4642  assert (lang_str != NULL);
4643  assert (lang_buf_size > 0);
4644  strncpy (lang_buf, lang_str, MIN (lang_str_len, lang_buf_size));
4645  }
4646  lang_buf[MIN (lang_str_len, lang_buf_size)] = '\0';
4647  }
4648  else if (heap_value->attrid == timezone_id)
4649  {
4650  const char *checksum = NULL;
4651  size_t checksum_len;
4652 
4653  if (DB_IS_NULL (&heap_value->dbvalue))
4654  {
4655  error = ER_FAILED;
4657  goto exit;
4658  }
4659 
4660  assert (DB_VALUE_DOMAIN_TYPE (&(heap_value->dbvalue)) == DB_TYPE_STRING);
4661 
4662  checksum = db_get_string (&heap_value->dbvalue);
4663  checksum_len = (checksum != NULL) ? strlen (checksum) : 0;
4664 
4665  assert (checksum_len <= TZ_CHECKSUM_SIZE);
4666  if (checksum_len > 0)
4667  {
4668  /* Copying length 0 from NULL pointer fails when DUMA is enabled. */
4669  assert (checksum != NULL);
4670  strcpy (timezone_checksum, checksum);
4671  }
4672  timezone_checksum[checksum_len] = '\0';
4673  }
4674  }
4675  }
4676 
4677 exit:
4678  if (scan_cache_inited == true)
4679  {
4680  (void) heap_scancache_end (thread_p, &scan_cache);
4681  scan_cache_inited = false;
4682  }
4683  if (attr_info_inited == true)
4684  {
4685  heap_attrinfo_end (thread_p, &attr_info);
4686  attr_info_inited = false;
4687  }
4688 
4689  return error;
4690 }
4691 
4692 /*
4693  * catcls_update_subset () - Update catalog class subset
4694  * return:
4695  * thread_p(in): thred entry
4696  * value(in): new values
4697  * old_value_p(in): old values
4698  * uflag(in): update necessary flag
4699  * force_in_place(in): UPDATE_INPLACE style
4700  */
4701 static int
4702 catcls_update_subset (THREAD_ENTRY * thread_p, OR_VALUE * value_p, OR_VALUE * old_value_p, bool * uflag,
4703  UPDATE_INPLACE_STYLE force_in_place)
4704 {
4705  OR_VALUE *subset_p = NULL, *old_subset_p = NULL;
4706  DB_SET *oid_set_p = NULL;
4707  int n_subset, n_old_subset;
4708  int n_min_subset;
4709  OID *class_oid_p = NULL;
4710  CLS_INFO *cls_info_p = NULL;
4711  HFID *hfid_p = NULL;
4712  OID *oid_p = NULL, tmp_oid;
4713  DB_SET *old_oid_set_p = NULL;
4714  DB_VALUE oid_val;
4715  int i;
4716  HEAP_SCANCACHE scan;
4717  bool is_scan_inited = false;
4718  int error = NO_ERROR;
4719 
4720  old_subset_p = old_value_p->sub.value;
4721  n_old_subset = old_value_p->sub.count;
4722  if (n_old_subset < 0)
4723  {
4724  n_old_subset = 0;
4725  }
4726 
4727  subset_p = value_p->sub.value;
4728  n_subset = value_p->sub.count;
4729  if (n_subset < 0)
4730  {
4731  n_subset = 0;
4732  }
4733 
4734  if (subset_p != NULL)
4735  {
4736  class_oid_p = &subset_p[0].id.classoid;
4737  }
4738  else if (old_subset_p != NULL)
4739  {
4740  class_oid_p = &old_subset_p[0].id.classoid;
4741  }
4742  else
4743  {
4744  return NO_ERROR;
4745  }
4746 
4747  if (n_subset > 0)
4748  {
4749  /* get the OIDs set */
4750  if (DB_IS_NULL (&value_p->value))
4751  {
4752  oid_set_p = set_create_sequence (n_subset);
4753  if (oid_set_p == NULL)
4754  {
4755  error = er_errid ();
4756  goto error;
4757  }
4758  }
4759  else
4760  {
4761  oid_set_p = db_get_set (&value_p->value);
4762  }
4763  }
4764 
4765  if (n_old_subset > 0)
4766  {
4767  old_oid_set_p = db_get_set (&old_value_p->value);
4768  }
4769 
4770  cls_info_p = catalog_get_class_info (thread_p, class_oid_p, NULL);
4771  if (cls_info_p == NULL)
4772  {
4773  error = er_errid ();
4774  goto error;
4775  }
4776 
4777  hfid_p = &cls_info_p->ci_hfid;
4778  error = heap_scancache_start_modify (thread_p, &scan, hfid_p, class_oid_p, MULTI_ROW_UPDATE, NULL);
4779  if (error != NO_ERROR)
4780  {
4781  goto error;
4782  }
4783 
4784  is_scan_inited = true;
4785 
4786  n_min_subset = (n_subset > n_old_subset) ? n_old_subset : n_subset;
4787  /* update components */
4788  for (i = 0; i < n_min_subset; i++)
4789  {
4790  error = set_get_element (old_oid_set_p, i, &oid_val);
4791  if (error != NO_ERROR)
4792  {
4793  goto error;
4794  }
4795 
4796  if (DB_VALUE_TYPE (&oid_val) != DB_TYPE_OID)
4797  {
4798  error = ER_FAILED;
4799  goto error;
4800  }
4801 
4802  oid_p = db_get_oid (&oid_val);
4803  error = catcls_update_instance (thread_p, &subset_p[i], oid_p, class_oid_p, hfid_p, &scan, force_in_place);
4804  if (error != NO_ERROR)
4805  {
4806  goto error;
4807  }
4808 
4809  /* oid_p remains the same, but it has to be reinserted in set; set_get_element don't let the value unchanged */
4810  db_make_oid (&oid_val, oid_p);
4811  error = set_put_element (oid_set_p, i, &oid_val);
4812  if (error != NO_ERROR)
4813  {
4814  goto error;
4815  }
4816  }
4817 
4818  /* drop components */
4819  if (n_old_subset > n_subset)
4820  {
4821  for (i = n_old_subset - 1; i >= n_min_subset; i--)
4822  {
4823  error = set_get_element (old_oid_set_p, i, &oid_val);
4824  if (error != NO_ERROR)
4825  {
4826  goto error;
4827  }
4828 
4829  if (DB_VALUE_TYPE (&oid_val) != DB_TYPE_OID)
4830  {
4831  error = ER_FAILED;
4832  goto error;
4833  }
4834 
4835  /* logical deletion - keep OID in sequence */
4836  oid_p = db_get_oid (&oid_val);
4837  error = catcls_delete_instance (thread_p, oid_p, class_oid_p, hfid_p, &scan);
4838  if (error != NO_ERROR)
4839  {
4840  goto error;
4841  }
4842  }
4843  *uflag = true;
4844  }
4845  /* add components */
4846  else if (n_old_subset < n_subset)
4847  {
4848  OID root_oid = { NULL_PAGEID, NULL_SLOTID, NULL_VOLID };
4849  for (i = n_min_subset, oid_p = &tmp_oid; i < n_subset; i++)
4850  {
4851  error = catcls_insert_instance (thread_p, &subset_p[i], oid_p, &root_oid, class_oid_p, hfid_p, &scan);
4852  if (error != NO_ERROR)
4853  {
4854  goto error;
4855  }
4856 
4857  db_make_oid (&oid_val, oid_p);
4858  error = set_put_element (oid_set_p, i, &oid_val);
4859  if (error != NO_ERROR)
4860  {
4861  goto error;
4862  }
4863  }
4864  *uflag = true;
4865  }
4866 
4867  if (DB_IS_NULL (&value_p->value))
4868  {
4869  db_make_sequence (&value_p->value, oid_set_p);
4870  }
4871 
4872  heap_scancache_end_modify (thread_p, &scan);
4873  catalog_free_class_info_and_init (cls_info_p);
4874 
4875  return NO_ERROR;
4876 
4877 error:
4878  if (oid_set_p && DB_IS_NULL (&value_p->value))
4879  {
4880  set_free (oid_set_p);
4881  }
4882 
4883  if (is_scan_inited)
4884  {
4885  heap_scancache_end_modify (thread_p, &scan);
4886  }
4887 
4888  if (cls_info_p)
4889  {
4890  catalog_free_class_info_and_init (cls_info_p);
4891  }
4892 
4893  assert (error != NO_ERROR);
4894  return error;
4895 }
4896 
4897 /*
4898  * catcls_get_db_collation () - get infomation on all collation in DB
4899  * stored in the "_db_collation" system table
4900  *
4901  * return: NO_ERROR, or error code
4902  * thread_p(in) : thread context
4903  * db_collations(out): array of collation info
4904  * coll_cnt(out): number of collations found in DB
4905  *
4906  * Note : This function is called during server initialization, for this
4907  * reason, no locks are required on the class.
4908  */
4909 int
4910 catcls_get_db_collation (THREAD_ENTRY * thread_p, LANG_COLL_COMPAT ** db_collations, int *coll_cnt)
4911 {
4912  OID class_oid;
4913  OID inst_oid;
4914  HFID hfid;
4915  HEAP_CACHE_ATTRINFO attr_info;
4916  HEAP_SCANCACHE scan_cache;
4917  RECDES recdes;
4918  const char *class_name = "_db_collation";
4919  int i;
4920  int error = NO_ERROR;
4921  int att_id_cnt = 0;
4922  int max_coll_cnt;
4923  int coll_id_att_id = -1, coll_name_att_id = -1, charset_id_att_id = -1, checksum_att_id = -1;
4924  int alloc_size;
4925  bool attr_info_inited = false;
4926  bool scan_cache_inited = false;
4927 
4928  assert (db_collations != NULL);
4929  assert (coll_cnt != NULL);
4930 
4931  OID_SET_NULL (&class_oid);
4932  OID_SET_NULL (&inst_oid);
4933 
4934  error = catcls_find_class_oid_by_class_name (thread_p, class_name, &class_oid);
4935  if (error != NO_ERROR)
4936  {
4937  goto exit;
4938  }
4939 
4940  if (OID_ISNULL (&class_oid))
4941  {
4943  error = ER_LC_UNKNOWN_CLASSNAME;
4944  goto exit;
4945  }
4946 
4947  error = heap_attrinfo_start (thread_p, &class_oid, -1, NULL, &attr_info);
4948  if (error != NO_ERROR)
4949  {
4950  goto exit;
4951  }
4952  attr_info_inited = true;
4953 
4954  (void) heap_scancache_quick_start_root_hfid (thread_p, &scan_cache);
4955  scan_cache_inited = true;
4956 
4957  if (heap_get_class_record (thread_p, &class_oid, &recdes, &scan_cache, PEEK) != S_SUCCESS)
4958  {
4959  error = ER_FAILED;
4960  goto exit;
4961  }
4962 
4963  for (i = 0; i < attr_info.num_values; i++)
4964  {
4965  char *rec_attr_name_p, *string = NULL;
4966  int alloced_string = 0;
4967 
4968  error = or_get_attrname (&recdes, i, &string, &alloced_string);
4969  if (error != NO_ERROR)
4970  {
4971  ASSERT_ERROR ();
4972  goto exit;
4973  }
4974 
4975  rec_attr_name_p = string;
4976  if (rec_attr_name_p == NULL)
4977  {
4978  error = ER_FAILED;
4979  goto exit;
4980  }
4981 
4982  if (strcmp (CT_DBCOLL_COLL_ID_COLUMN, rec_attr_name_p) == 0)
4983  {
4984  coll_id_att_id = i;
4985  att_id_cnt++;
4986  }
4987  else if (strcmp (CT_DBCOLL_COLL_NAME_COLUMN, rec_attr_name_p) == 0)
4988  {
4989  coll_name_att_id = i;
4990  att_id_cnt++;
4991  }
4992  else if (strcmp (CT_DBCOLL_CHARSET_ID_COLUMN, rec_attr_name_p) == 0)
4993  {
4994  charset_id_att_id = i;
4995  att_id_cnt++;
4996  }
4997  else if (strcmp (CT_DBCOLL_CHECKSUM_COLUMN, rec_attr_name_p) == 0)
4998  {
4999  checksum_att_id = i;
5000  att_id_cnt++;
5001  }
5002 
5003  if (string != NULL && alloced_string == 1)
5004  {
5005  db_private_free_and_init (thread_p, string);
5006  }
5007 
5008  if (att_id_cnt >= 4)
5009  {
5010  break;
5011  }
5012  }
5013 
5014  if (att_id_cnt != 4)
5015  {
5017  error = ER_FAILED;
5018  goto exit;
5019  }
5020 
5021  (void) heap_scancache_end (thread_p, &scan_cache);
5022  scan_cache_inited = false;
5023 
5024  /* read values of all records in heap */
5025  error = heap_get_class_info (thread_p, &class_oid, &hfid, NULL, NULL);
5026  if (error != NO_ERROR || HFID_IS_NULL (&hfid))
5027  {
5028  error = ER_FAILED;
5029  goto exit;
5030  }
5031 
5032  error = heap_scancache_start (thread_p, &scan_cache, &hfid, NULL, true, false, NULL);
5033  if (error != NO_ERROR)
5034  {
5035  goto exit;
5036  }
5037  scan_cache_inited = true;
5038 
5039  max_coll_cnt = LANG_MAX_COLLATIONS;
5040  alloc_size = max_coll_cnt * sizeof (LANG_COLL_COMPAT);
5041  *db_collations = (LANG_COLL_COMPAT *) db_private_alloc (thread_p, alloc_size);
5042  if (*db_collations == NULL)
5043  {
5044  error = ER_OUT_OF_VIRTUAL_MEMORY;
5045  goto exit;
5046  }
5047 
5048  *coll_cnt = 0;
5049  while (heap_next (thread_p, &hfid, NULL, &inst_oid, &recdes, &scan_cache, PEEK) == S_SUCCESS)
5050  {
5051  HEAP_ATTRVALUE *heap_value = NULL;
5052  LANG_COLL_COMPAT *curr_coll;
5053 
5054  if (heap_attrinfo_read_dbvalues (thread_p, &inst_oid, &recdes, NULL, &attr_info) != NO_ERROR)
5055  {
5056  error = ER_FAILED;
5057  goto exit;
5058  }
5059 
5060  if (*coll_cnt >= max_coll_cnt)
5061  {
5062  max_coll_cnt = max_coll_cnt * 2;
5063  alloc_size = max_coll_cnt * sizeof (LANG_COLL_COMPAT);
5064  *db_collations = (LANG_COLL_COMPAT *) db_private_realloc (thread_p, *db_collations, alloc_size);
5065  if (db_collations == NULL)
5066  {
5067  error = ER_OUT_OF_VIRTUAL_MEMORY;
5068  goto exit;
5069  }
5070  }
5071 
5072  curr_coll = &((*db_collations)[(*coll_cnt)++]);
5073  memset (curr_coll, 0, sizeof (LANG_COLL_COMPAT));
5074 
5075  for (i = 0, heap_value = attr_info.values; i < attr_info.num_values; i++, heap_value++)
5076  {
5077  if (heap_value->attrid == coll_id_att_id)
5078  {
5079  assert (DB_VALUE_DOMAIN_TYPE (&(heap_value->dbvalue)) == DB_TYPE_INTEGER);
5080 
5081  curr_coll->coll_id = db_get_int (&heap_value->dbvalue);
5082  }
5083  else if (heap_value->attrid == coll_name_att_id)
5084  {
5085  const char *lang_str = NULL;
5086  size_t lang_str_len;
5087 
5088  assert (DB_VALUE_DOMAIN_TYPE (&(heap_value->dbvalue)) == DB_TYPE_STRING);
5089 
5090  lang_str = db_get_string (&heap_value->dbvalue);
5091  lang_str_len = (lang_str != NULL) ? strlen (lang_str) : 0;
5092  lang_str_len = MIN (lang_str_len, sizeof (curr_coll->coll_name));
5093 
5094  strncpy (curr_coll->coll_name, lang_str, lang_str_len);
5095  curr_coll->coll_name[lang_str_len] = '\0';
5096  }
5097  else if (heap_value->attrid == charset_id_att_id)
5098  {
5099  assert (DB_VALUE_DOMAIN_TYPE (&(heap_value->dbvalue)) == DB_TYPE_INTEGER);
5100 
5101  curr_coll->codeset = (INTL_CODESET) db_get_int (&heap_value->dbvalue);
5102  }
5103  else if (heap_value->attrid == checksum_att_id)
5104  {
5105  const char *checksum_str = NULL;
5106  size_t str_len;
5107 
5108  assert (DB_VALUE_DOMAIN_TYPE (&(heap_value->dbvalue)) == DB_TYPE_STRING);
5109 
5110  checksum_str = db_get_string (&heap_value->dbvalue);
5111  str_len = (checksum_str != NULL) ? strlen (checksum_str) : 0;
5112 
5113  assert (str_len == 32);
5114 
5115  strncpy (curr_coll->checksum, checksum_str, str_len);
5116  curr_coll->checksum[str_len] = '\0';
5117  }
5118  }
5119  }
5120 
5121 exit:
5122  if (scan_cache_inited == true)
5123  {
5124  (void) heap_scancache_end (thread_p, &scan_cache);
5125  scan_cache_inited = false;
5126  }
5127 
5128  if (attr_info_inited == true)
5129  {
5130  heap_attrinfo_end (thread_p, &attr_info);
5131  attr_info_inited = false;
5132  }
5133 
5134  return error;
5135 }
5136 
5137 /*
5138  * catcls_get_apply_info_log_record_time () - get max log_record_time
5139  * in db_ha_apply_info
5140  *
5141  * return: NO_ERROR, or error code
5142  * thread_p(in) : thread context
5143  * log_record_time(out): log_record_time
5144  *
5145  */
5146 int
5147 catcls_get_apply_info_log_record_time (THREAD_ENTRY * thread_p, time_t * log_record_time)
5148 {
5149  OID class_oid;
5150  OID inst_oid;
5151  HFID hfid;
5152  HEAP_CACHE_ATTRINFO attr_info;
5153  HEAP_SCANCACHE scan_cache;
5154  RECDES recdes;
5155  DB_DATETIME tmp_datetime;
5156  time_t tmp_log_record_time = 0;
5157  int log_record_time_att_id = -1;
5158  int error = NO_ERROR;
5159  int i;
5160  bool attr_info_inited = false;
5161  bool scan_cache_inited = false;
5162  int num_record = 0;
5163 
5164  assert (log_record_time != NULL);
5165  *log_record_time = 0;
5166 
5167  OID_SET_NULL (&class_oid);
5168  OID_SET_NULL (&inst_oid);
5169 
5170  error = catcls_find_class_oid_by_class_name (thread_p, CT_HA_APPLY_INFO_NAME, &class_oid);
5171  if (error != NO_ERROR)
5172  {
5173  goto exit;
5174  }
5175 
5176  if (OID_ISNULL (&class_oid))
5177  {
5179  error = ER_LC_UNKNOWN_CLASSNAME;
5180  goto exit;
5181  }
5182 
5183  error = heap_attrinfo_start (thread_p, &class_oid, -1, NULL, &attr_info);
5184  if (error != NO_ERROR)
5185  {
5186  goto exit;
5187  }
5188  attr_info_inited = true;
5189 
5190  heap_scancache_quick_start_root_hfid (thread_p, &scan_cache);
5191  scan_cache_inited = true;
5192 
5193  if (heap_get_class_record (thread_p, &class_oid, &recdes, &scan_cache, PEEK) != S_SUCCESS)
5194  {
5195  error = ER_FAILED;
5196  goto exit;
5197  }
5198 
5199  for (i = 0; i < attr_info.num_values; i++)
5200  {
5201  char *rec_attr_name_p, *string = NULL;
5202  int alloced_string = 0;
5203 
5204  error = or_get_attrname (&recdes, i, &string, &alloced_string);
5205  if (error != NO_ERROR)
5206  {
5207  ASSERT_ERROR ();
5208  goto exit;
5209  }
5210 
5211  rec_attr_name_p = string;
5212  if (rec_attr_name_p == NULL)
5213  {
5214  error = ER_FAILED;
5215  goto exit;
5216  }
5217 
5218  if (strcmp ("log_record_time", rec_attr_name_p) == 0)
5219  {
5220  log_record_time_att_id = i;
5221 
5222  if (string != NULL && alloced_string == 1)
5223  {
5224  db_private_free_and_init (thread_p, string);
5225  }
5226 
5227  break;
5228  }
5229 
5230  if (string != NULL && alloced_string == 1)
5231  {
5232  db_private_free_and_init (thread_p, string);
5233  }
5234  }
5235 
5236  if (log_record_time_att_id == -1)
5237  {
5239  error = ER_FAILED;
5240  goto exit;
5241  }
5242 
5243  heap_scancache_end (thread_p, &scan_cache);
5244  scan_cache_inited = false;
5245 
5246  error = heap_get_class_info (thread_p, &class_oid, &hfid, NULL, NULL);
5247  if (error != NO_ERROR || HFID_IS_NULL (&hfid))
5248  {
5249  error = ER_FAILED;
5250  goto exit;
5251  }
5252 
5253  error = heap_scancache_start (thread_p, &scan_cache, &hfid, NULL, true, false, NULL);
5254  if (error != NO_ERROR)
5255  {
5256  goto exit;
5257  }
5258  scan_cache_inited = true;
5259 
5260  while (heap_next (thread_p, &hfid, NULL, &inst_oid, &recdes, &scan_cache, PEEK) == S_SUCCESS)
5261  {
5262  HEAP_ATTRVALUE *heap_value = NULL;
5263 
5264  if (heap_attrinfo_read_dbvalues (thread_p, &inst_oid, &recdes, NULL, &attr_info) != NO_ERROR)
5265  {
5266  error = ER_FAILED;
5267  goto exit;
5268  }
5269 
5270  for (i = 0, heap_value = attr_info.values; i < attr_info.num_values; i++, heap_value++)
5271  {
5272  if (heap_value->attrid == log_record_time_att_id)
5273  {
5274  tmp_log_record_time = 0;
5275  if (!DB_IS_NULL (&heap_value->dbvalue))
5276  {
5277  tmp_datetime = *(db_get_datetime (&heap_value->dbvalue));
5278  tmp_datetime.time /= 1000;
5279 
5280  tmp_log_record_time = db_mktime (&tmp_datetime.date, &tmp_datetime.time);
5281  }
5282  break;
5283  }
5284  }
5285 
5286  if (tmp_log_record_time > *log_record_time)
5287  {
5288  *log_record_time = tmp_log_record_time;
5289  }
5290 
5291  num_record++;
5292  }
5293 
5294 exit:
5295  if (scan_cache_inited == true)
5296  {
5297  (void) heap_scancache_end (thread_p, &scan_cache);
5298  scan_cache_inited = false;
5299  }
5300 
5301  if (attr_info_inited == true)
5302  {
5303  heap_attrinfo_end (thread_p, &attr_info);
5304  attr_info_inited = false;
5305  }
5306 
5307  if (error == NO_ERROR && num_record == 0)
5308  {
5309  error = ER_FAILED;
5310  }
5311 
5312  return error;
5313 }
5314 
5315 /*
5316  * catcls_find_and_set_cached_class_oid () - Used to find OID for collation
5317  * class and set the global
5318  * variable for collation class
5319  * OID.
5320  *
5321  * return : Error code.
5322  * thread_p (in) : Thread entry.
5323  */
5324 int
5326 {
5327  OID class_oid;
5328  LC_FIND_CLASSNAME status;
5329  int i;
5330 
5331  /* skip OID for root class, is already set with 'boot_get_db_parm' */
5332  for (i = OID_CACHE_CLASS_CLASS_ID; i < OID_CACHE_SIZE; i++)
5333  {
5334  status = xlocator_find_class_oid (thread_p, oid_get_cached_class_name (i), &class_oid, NULL_LOCK);
5335  if (status == LC_CLASSNAME_ERROR)
5336  {
5337  return ER_FAILED;
5338  }
5339 
5340  oid_set_cached_class_oid (i, &class_oid);
5341  }
5342 
5343  return NO_ERROR;
5344 }
5345 
5346 /*
5347  * catcls_get_or_value_from_partition () -
5348  * return: error code
5349  *
5350  * thread_p (in):
5351  * buf(in):
5352  * value(in):
5353  */
5354 static int
5356 {
5357  OR_VALUE *attrs;
5358  DB_VALUE *attr_val_p;
5359  OR_VARINFO *vars = NULL;
5360  int size;
5361  int error = NO_ERROR;
5362 
5363  error = catcls_expand_or_value_by_def (value_p, &ct_Partition);
5364  if (error != NO_ERROR)
5365  {
5366  goto error;
5367  }
5368 
5369  attrs = value_p->sub.value;
5370 
5373  vars = or_get_var_table (buf_p, size, catcls_unpack_allocator);
5374  if (vars == NULL)
5375  {
5376  size_t msize = size * sizeof (OR_VARINFO);
5377 
5378  error = ER_OUT_OF_VIRTUAL_MEMORY;
5379  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, msize);
5380  goto error;
5381  }
5382 
5383  /* type */
5384  tp_Integer.data_readval (buf_p, &attrs[1].value, NULL, -1, true, NULL, 0);
5385 
5386  /* name */
5387  attr_val_p = &attrs[2].value;
5388  tp_String.data_readval (buf_p, attr_val_p, NULL, vars[ORC_PARTITION_NAME_INDEX].length, true, NULL, 0);
5389  db_string_truncate (attr_val_p, DB_MAX_SPEC_LENGTH);
5390 
5391  /* expr */
5392  attr_val_p = &attrs[3].value;
5393  tp_String.data_readval (buf_p, attr_val_p, NULL, vars[ORC_PARTITION_EXPR_INDEX].length, true, NULL, 0);
5394  assert (DB_IS_NULL (attr_val_p) || db_get_string_length (attr_val_p) <= DB_MAX_PARTITION_EXPR_LENGTH);
5395 
5396  /* values */
5397  attr_val_p = &attrs[4].value;
5398  error = or_get_value (buf_p, attr_val_p, NULL, vars[ORC_PARTITION_VALUES_INDEX].length, true);
5399  if (error != NO_ERROR)
5400  {
5401  goto error;
5402  }
5403 
5404  /* comment */
5405  attr_val_p = &attrs[5].value;
5406  tp_String.data_readval (buf_p, attr_val_p, NULL, vars[ORC_PARTITION_COMMENT_INDEX].length, true, NULL, 0);
5407  db_string_truncate (attr_val_p, DB_MAX_SPEC_LENGTH);
5408 
5409  if (vars)
5410  {
5411  free_and_init (vars);
5412  }
5413 
5414  return NO_ERROR;
5415 
5416 error:
5417 
5418  if (vars)
5419  {
5420  free_and_init (vars);
5421  }
5422 
5423  return error;
5424 }
static int catcls_update_instance(THREAD_ENTRY *thread_p, OR_VALUE *value_p, OID *oid, OID *class_oid, HFID *hfid, HEAP_SCANCACHE *scan, UPDATE_INPLACE_STYLE force_in_place)
#define OR_SET_VAR_OFFSET_SIZE(val, offset_size)
META_CLASS tf_Metaclass_methsig
Definition: transform.c:115
int data_readval(struct or_buf *buf, DB_VALUE *value, const tp_domain *domain, int size, bool copy, char *copy_buf, int copy_buf_len) const
#define LANG_MAX_COLLATIONS
#define OR_PUT_OFFSET(ptr, val)
void heap_scancache_end_modify(THREAD_ENTRY *thread_p, HEAP_SCANCACHE *scan_cache)
Definition: heap_file.c:7230
static OR_VALUE * catcls_allocate_or_value(int size)
cubthread::entry * thread_get_thread_entry_info(void)
#define NO_ERROR
Definition: error_code.h:46
CLS_INFO * catalog_get_class_info(THREAD_ENTRY *thread_p, OID *class_id_p, CATALOG_ACCESS_INFO *catalog_access_info_p)
int set_get_element_nocopy(DB_COLLECTION *set, int index, DB_VALUE *value)
Definition: set_object.c:2616
int area_size
int db_value_put_null(DB_VALUE *value)
Definition: db_macro.c:122
DB_COLLECTION * db_get_set(const DB_VALUE *value)
META_CLASS tf_Metaclass_method
Definition: transform.c:128
#define LANG_SYS_COLLATION
int catcls_compile_catalog_classes(THREAD_ENTRY *thread_p)
PR_TYPE * tp_Type_id_map[]
DB_VALUE_COMPARE_RESULT tp_value_compare(const DB_VALUE *value1, const DB_VALUE *value2, int allow_coercion, int total_order)
static int catcls_convert_class_oid_to_oid(THREAD_ENTRY *thread_p, DB_VALUE *oid_val)
#define ASSERT_ERROR()
SCAN_CODE
static int catcls_get_or_value_from_query_spec(THREAD_ENTRY *thread_p, OR_BUF *buf_p, OR_VALUE *value_p)
static int catcls_convert_attr_id_to_name(THREAD_ENTRY *thread_p, OR_BUF *orbuf_p, OR_VALUE *value_p)
META_CLASS tf_Metaclass_domain
Definition: transform.c:67
int catcls_find_and_set_cached_class_oid(THREAD_ENTRY *thread_p)
int heap_scancache_start_modify(THREAD_ENTRY *thread_p, HEAP_SCANCACHE *scan_cache, const HFID *hfid, const OID *class_oid, int op_type, MVCC_SNAPSHOT *mvcc_snapshot)
Definition: heap_file.c:6867
static int catcls_resolution_space(int name_space)
META_CLASS tf_Metaclass_class
Definition: transform.c:221
SCAN_CODE heap_get_visible_version(THREAD_ENTRY *thread_p, const OID *oid, OID *class_oid, RECDES *recdes, HEAP_SCANCACHE *scan_cache, int ispeeking, int old_chn)
Definition: heap_file.c:24272
int or_get_json_schema(OR_BUF *buf, REFPTR(char, schema))
int locator_add_or_remove_index(THREAD_ENTRY *thread_p, RECDES *recdes, OID *inst_oid, OID *class_oid, int is_insert, int op_type, HEAP_SCANCACHE *scan_cache, bool datayn, bool need_replication, HFID *hfid, FUNC_PRED_UNPACK_INFO *func_preds, bool has_BU_lock, bool skip_checking_fk)
Definition: locator_sr.c:7545
#define TP_IS_SET_TYPE(typenum)
void set_free(DB_COLLECTION *set)
Definition: set_object.c:2560
#define CT_DBCOLL_CHECKSUM_COLUMN
Definition: transform.h:174
static int catcls_find_oid_by_class_name(THREAD_ENTRY *thread_p, const char *name, OID *oid)
int db_get_int(const DB_VALUE *value)
DB_TYPE
Definition: dbtype_def.h:670
#define ER_FAILED
Definition: error_code.h:47
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)
static int catcls_get_or_value_from_domain(THREAD_ENTRY *thread_p, OR_BUF *buf_p, OR_VALUE *value_p)
Definition: catalog_class.c:83
#define csect_enter(a, b, c)
Definition: cnv.c:138
void oid_set_cached_class_oid(const int cache_id, const OID *oid)
Definition: oid.c:339
#define OR_MVCC_REPID_MASK
const void * mht_put_if_not_exists(MHT_TABLE *ht, const void *key, void *data)
Definition: memory_hash.c:1749
static int catcls_find_btid_of_class_name(THREAD_ENTRY *thread_p, BTID *btid)
int mht_rem(MHT_TABLE *ht, const void *key, int(*rem_func)(const void *key, void *data, void *args), void *func_args)
Definition: memory_hash.c:1952
CT_CLASS ct_Index
Definition: transform.c:493
#define SM_FILTER_INDEX_ID
#define ER_SM_CORRUPTED
Definition: error_code.h:335
int classobj_get_prop(DB_SEQ *properties, const char *name, DB_VALUE *pvalue)
CATCLS_ENTRY * next
Definition: catalog_class.c:87
int db_get_enum_codeset(const DB_VALUE *value)
struct setobj * set
Definition: db_set.h:43
#define ASSERT_ERROR_AND_SET(error_code)
#define OR_MVCC_FLAG_VALID_INSID
DB_COLLECTION * set_create_sequence(int size)
Definition: set_object.c:2432
#define DB_MAX_SPEC_LENGTH
Definition: dbtype_def.h:508
int lock_object(THREAD_ENTRY *thread_p, const OID *oid, const OID *class_oid, LOCK lock, int cond_flag)
#define MVCCID_NULL
int heap_scancache_quick_start_root_hfid(THREAD_ENTRY *thread_p, HEAP_SCANCACHE *scan_cache)
Definition: heap_file.c:19255
#define OR_MVCC_FLAG_VALID_DELID
#define OR_MVCCID_SIZE
int catcls_get_db_collation(THREAD_ENTRY *thread_p, LANG_COLL_COMPAT **db_collations, int *coll_cnt)
#define OID_SET_NULL(oidp)
Definition: oid.h:85
#define NULL_SLOTID
#define OR_MVCC_FLAG_SHIFT_BITS
char * data
int db_make_sequence(DB_VALUE *value, DB_C_SET *set)
const char * db_default_expression_string(DB_DEFAULT_EXPR_TYPE default_expr_type)
Definition: db_macro.c:4947
struct or_varinfo OR_VARINFO
CT_CLASS ct_Queryspec
Definition: transform.c:472
PR_TYPE tp_Integer
static void catcls_apply_resolutions(OR_VALUE *value_p, OR_VALUE *resolution_p)
#define MULTI_ROW_DELETE
Definition: btree.h:57
#define DB_MAX_PARTITION_EXPR_LENGTH
Definition: dbtype_def.h:619
int er_errid(void)
union or_value::or_id id
#define OR_BOUND_BIT_BYTES(count)
static int catcls_guess_record_length(OR_VALUE *value_p)
int set_size(DB_COLLECTION *set)
Definition: set_object.c:3036
CT_CLASS ct_Metharg
Definition: transform.c:458
#define SM_PROPERTY_NUM_INDEX_FAMILY
static int catcls_get_or_value_from_method_argument(THREAD_ENTRY *thread_p, OR_BUF *buf_p, OR_VALUE *value_p)
OID cc_classoid
Definition: transform.h:69
int heap_scancache_end(THREAD_ENTRY *thread_p, HEAP_SCANCACHE *scan_cache)
Definition: heap_file.c:7195
#define CT_CLASS_NAME
Definition: transform.h:119
OID oid
Definition: catalog_class.c:86
const char * cc_name
Definition: transform.h:68
#define COPY_OID(dest_oid_ptr, src_oid_ptr)
Definition: oid.h:63
#define OR_MVCC_MAX_HEADER_SIZE
static BTID catcls_Btid
static int catcls_delete_subset(THREAD_ENTRY *thread_p, OR_VALUE *value_p)
const char * oid_get_cached_class_name(const int cache_id)
Definition: oid.c:351
int or_skip_set_header(OR_BUF *buf)
struct lang_coll_compat LANG_COLL_COMPAT
void THREAD_ENTRY
#define TZ_CHECKSUM_SIZE
static int catcls_delete_instance(THREAD_ENTRY *thread_p, OID *oid, OID *class_oid, HFID *hfid, HEAP_SCANCACHE *scan)
#define NULL_PAGEID
#define IS_SUBSET(value)
Definition: catalog_class.c:48
int ATTR_ID
int pr_free_ext_value(DB_VALUE *value)
#define OR_VAR_TABLE_SIZE(vars)
int size
Definition: set_object.h:72
static OID * catcls_find_oid(THREAD_ENTRY *thread_p, OID *class_oid)
int catcls_delete_catalog_classes(THREAD_ENTRY *thread_p, const char *name, OID *class_oid)
BTREE_SEARCH xbtree_find_unique(THREAD_ENTRY *thread_p, BTID *btid, SCAN_OPERATION_TYPE scan_op_type, DB_VALUE *key, OID *class_oid, OID *oid, bool is_all_class_srch)
Definition: btree.c:23990
int db_make_string(DB_VALUE *value, DB_CONST_C_CHAR str)
int heap_scancache_start(THREAD_ENTRY *thread_p, HEAP_SCANCACHE *scan_cache, const HFID *hfid, const OID *class_oid, int cache_last_fix_page, int is_indexscan, MVCC_SNAPSHOT *mvcc_snapshot)
Definition: heap_file.c:6833
void mht_destroy(MHT_TABLE *ht)
Definition: memory_hash.c:1140
bool pr_is_set_type(DB_TYPE type)
DB_DATA data
Definition: dbtype_def.h:1083
int catcls_finalize_class_oid_to_oid_hash_table(THREAD_ENTRY *thread_p)
CT_CLASS ct_Methsig
Definition: transform.c:451
#define CT_HA_APPLY_INFO_NAME
Definition: transform.h:136
static int catcls_free_entry_kv(const void *key, void *data, void *args)
int heap_attrinfo_start(THREAD_ENTRY *thread_p, const OID *class_oid, int requested_num_attrs, const ATTR_ID *attrids, HEAP_CACHE_ATTRINFO *attr_info)
Definition: heap_file.c:9427
PR_TYPE * pr_type_from_id(DB_TYPE id)
#define RECDES_INITIALIZER
static OR_VALUE * catcls_get_or_value_from_record(THREAD_ENTRY *thread_p, RECDES *record, OID *class_oid)
TP_DOMAIN * tp_domain_resolve_default(DB_TYPE type)
PR_TYPE tp_Sequence
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
Definition: db_set.h:35
#define csect_check_own(a, b)
static int catcls_get_or_value_from_method_signiture(THREAD_ENTRY *thread_p, OR_BUF *buf_p, OR_VALUE *value_p)
CT_CLASS ct_Partition
Definition: transform.c:479
#define OR_MVCC_FLAG_VALID_PREV_VERSION
int db_make_enumeration(DB_VALUE *value, unsigned short index, DB_CONST_C_CHAR str, int size, unsigned char codeset, const int collation_id)
#define assert(x)
#define ER_SM_NO_INDEX
Definition: error_code.h:345
BTREE_STATS * bt_stats
static OR_VALUE * catcls_get_or_value_from_class_record(THREAD_ENTRY *thread_p, RECDES *record)
#define ER_LC_UNKNOWN_CLASSNAME
Definition: error_code.h:121
#define OR_MVCC_FLAG_MASK
#define OR_ENABLE_BOUND_BIT(bitptr, element)
META_CLASS tf_Metaclass_resolution
Definition: transform.c:151
static int catcls_get_or_value_from_resolution(THREAD_ENTRY *thread_p, OR_BUF *buf_p, OR_VALUE *value_p)
struct or_value OR_VALUE
Definition: catalog_class.c:63
#define ER_GENERIC_ERROR
Definition: error_code.h:49
int or_mvcc_get_repid_and_flags(OR_BUF *buf, int *error)
META_CLASS tf_Metaclass_attribute
Definition: transform.c:91
LC_FIND_CLASSNAME xlocator_find_class_oid(THREAD_ENTRY *thread_p, const char *classname, OID *class_oid, LOCK lock)
Definition: locator_sr.c:1033
static int catcls_get_or_value_from_class(THREAD_ENTRY *thread_p, OR_BUF *buf_p, OR_VALUE *value_p)
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
int or_chn(RECDES *record)
DB_TYPE db_value_type(const DB_VALUE *value)
const char * qdump_operator_type_string(OPERATOR_TYPE optype)
Definition: query_dump.c:1016
#define SINGLE_ROW_UPDATE
Definition: btree.h:54
unsigned is_desc
static int catcls_replace_entry_oid(THREAD_ENTRY *thread_p, OID *entry_class_oid, OID *entry_new_oid)
static int catcls_expand_or_value_by_def(OR_VALUE *value_p, CT_CLASS *def)
int or_put_int(OR_BUF *buf, int num)
int heap_update_logical(THREAD_ENTRY *thread_p, HEAP_OPERATION_CONTEXT *context)
Definition: heap_file.c:22771
int intl_identifier_casecmp(const char *str1, const char *str2)
#define DB_VALUE_DOMAIN_TYPE(value)
Definition: dbtype.h:70
#define DB_MAX_IDENTIFIER_LENGTH
Definition: dbtype_def.h:495
META_CLASS tf_Metaclass_query_spec
Definition: transform.c:230
void heap_create_update_context(HEAP_OPERATION_CONTEXT *context, HFID *hfid_p, OID *oid_p, OID *class_oid_p, RECDES *recdes_p, HEAP_SCANCACHE *scancache_p, UPDATE_INPLACE_STYLE in_place)
Definition: heap_file.c:22378
int or_put_bigint(OR_BUF *buf, DB_BIGINT num)
static int catcls_put_or_value_into_record(THREAD_ENTRY *thread_p, OR_VALUE *value_p, int chn, RECDES *record, OID *class_oid)
static int catcls_get_or_value_from_attribute(THREAD_ENTRY *thread_p, OR_BUF *buf_p, OR_VALUE *value_p)
static int catcls_insert_subset(THREAD_ENTRY *thread_p, OR_VALUE *value_p, OID *root_oid)
int catcls_get_apply_info_log_record_time(THREAD_ENTRY *thread_p, time_t *log_record_time)
const char * name
Definition: catalog_class.c:92
CT_CLASS ct_Class
Definition: transform.c:416
#define OID_EQ(oidp1, oidp2)
Definition: oid.h:92
CT_CLASS ct_Method
Definition: transform.c:444
int catcls_insert_catalog_classes(THREAD_ENTRY *thread_p, RECDES *record)
static int catcls_update_subset(THREAD_ENTRY *thread_p, OR_VALUE *value_p, OR_VALUE *old_value, bool *uflag, UPDATE_INPLACE_STYLE force_in_place)
static int catcls_get_or_value_from_indexes(DB_SEQ *seq, OR_VALUE *subset, int is_unique, int is_reverse, int is_primary_key, int is_foreign_key)
#define OR_MVCC_PREV_VERSION_LSA_SIZE
DB_VALUE * db_value_copy(DB_VALUE *value)
Definition: db_macro.c:1537
int heap_attrinfo_read_dbvalues(THREAD_ENTRY *thread_p, const OID *inst_oid, RECDES *recdes, HEAP_SCANCACHE *scan_cache, HEAP_CACHE_ATTRINFO *attr_info)
Definition: heap_file.c:10337
#define DB_MAX_COMMENT_LENGTH
Definition: dbtype_def.h:513
struct or_value * value
Definition: catalog_class.c:78
#define OR_MVCC_INSERT_HEADER_SIZE
void * mht_get(MHT_TABLE *ht, const void *key)
Definition: memory_hash.c:1419
static int catcls_get_or_value_from_method_file(THREAD_ENTRY *thread_p, OR_BUF *buf_p, OR_VALUE *value_p)
OID class_oid
Definition: catalog_class.c:85
#define NULL
Definition: freelistheap.h:34
unsigned short db_get_enum_short(const DB_VALUE *value)
int db_string_truncate(DB_VALUE *value, const int precision)
Definition: db_macro.c:962
#define CT_DBCOLL_COLL_ID_COLUMN
Definition: transform.h:167
struct disk_attribute * variable
static void catcls_free_sub_value(OR_VALUE *values, int count)
#define SM_PROPERTY_UNIQUE
#define SINGLE_ROW_DELETE
Definition: btree.h:53
LC_FIND_CLASSNAME
TP_DOMAIN * tp_domain_cache(TP_DOMAIN *transient)
#define err(fd,...)
Definition: porting.h:431
#define db_private_free_and_init(thrd, ptr)
Definition: memory_alloc.h:141
#define CATCLS_INDEX_KEY
Definition: catalog_class.c:59
MHT_TABLE * mht_create(const char *name, int est_size, unsigned int(*hash_func)(const void *key, unsigned int ht_size), int(*cmp_func)(const void *key1, const void *key2))
Definition: memory_hash.c:894
static MHT_TABLE * catcls_Class_oid_to_oid_hash_table
#define csect_exit(a, b)
Definition: cnv.c:139
void or_init(OR_BUF *buf, char *data, int length)
unsigned int oid_hash(const void *key_oid, unsigned int htsize)
Definition: oid.c:294
static int catcls_get_object_set(THREAD_ENTRY *thread_p, OR_BUF *buf_p, int expected_size, OR_VALUE *value)
#define db_private_alloc(thrd, size)
Definition: memory_alloc.h:227
#define CONST_CAST(dest_type, expr)
Definition: porting.h:1060
int set_get_element(DB_COLLECTION *set, int index, DB_VALUE *value)
Definition: set_object.c:2575
struct disk_attribute * fixed
#define BIG_VAR_OFFSET_SIZE
need_clear_type need_clear
Definition: dbtype_def.h:1084
#define DB_MAX_CLASS_COMMENT_LENGTH
Definition: dbtype_def.h:511
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
static CATCLS_ENTRY * catcls_allocate_entry(THREAD_ENTRY *thread_p)
int pr_clear_value(DB_VALUE *value)
int catcls_remove_entry(THREAD_ENTRY *thread_p, OID *class_oid)
#define DB_DEFAULT_SCALE
Definition: dbtype_def.h:561
void heap_create_delete_context(HEAP_OPERATION_CONTEXT *context, HFID *hfid_p, OID *oid_p, OID *class_oid_p, HEAP_SCANCACHE *scancache_p)
Definition: heap_file.c:22351
int oid_compare_equals(const void *key_oid1, const void *key_oid2)
Definition: oid.c:310
#define CATCLS_INDEX_NAME
Definition: catalog_class.c:58
#define OR_CLEAR_BOUND_BIT(bitptr, element)
static int catcls_get_or_value_from_partition(THREAD_ENTRY *thread_p, OR_BUF *buf_p, OR_VALUE *value_p)
int set_put_element(DB_COLLECTION *set, int index, DB_VALUE *value)
Definition: set_object.c:2719
static void error(const char *msg)
Definition: gencat.c:331
#define MULTI_ROW_UPDATE
Definition: btree.h:58
time_t db_mktime(DB_DATE *date, DB_TIME *timeval)
Definition: db_date.c:557
static void catcls_free_or_value(OR_VALUE *value)
static int rc
Definition: serial.c:50
#define DB_DEFAULT_PRECISION
Definition: dbtype_def.h:558
TP_DOMAIN * tp_domain_construct(DB_TYPE domain_type, DB_OBJECT *class_obj, int precision, int scale, TP_DOMAIN *setdomain)
SCAN_CODE heap_get_class_oid(THREAD_ENTRY *thread_p, const OID *oid, OID *class_oid)
Definition: heap_file.c:9285
static int catcls_get_property_set(THREAD_ENTRY *thread_p, OR_BUF *buf_p, int expected_size, OR_VALUE *value_p)
static int catcls_expand_or_value_by_subset(THREAD_ENTRY *thread_p, OR_VALUE *value_p)
int or_seek(OR_BUF *buf, int psn)
CT_CLASS * ct_Classes[]
Definition: transform.c:507
#define HFID_IS_NULL(hfid)
int catalog_get_last_representation_id(THREAD_ENTRY *thread_p, OID *class_oid_p, REPR_ID *repr_id_p)
CT_CLASS ct_Domain
Definition: transform.c:437
static CATCLS_ENTRY * catcls_Free_entry_list
bool db_value_is_null(const DB_VALUE *value)
#define ARG_FILE_LINE
Definition: error_manager.h:44
PR_TYPE tp_String
static int catcls_initialize_class_oid_to_oid_hash_table(THREAD_ENTRY *thread_p, int num_entry)
int pr_clone_value(const DB_VALUE *src, DB_VALUE *dest)
#define SM_PROPERTY_INDEX
static const bool COPY
OID * db_get_oid(const DB_VALUE *value)
int valcnv_convert_value_to_string(DB_VALUE *value)
Definition: db_macro.c:4901
#define SM_PROPERTY_PRIMARY_KEY
int heap_delete_logical(THREAD_ENTRY *thread_p, HEAP_OPERATION_CONTEXT *context)
Definition: heap_file.c:22606
static void catcls_apply_component_type(OR_VALUE *value_p, int type)
#define csect_enter_as_reader(a, b, c)
#define free_and_init(ptr)
Definition: memory_alloc.h:147
#define CT_DBCOLL_CHARSET_ID_COLUMN
Definition: transform.h:169
#define strlen(s1)
Definition: intl_support.c:43
#define BTID_COPY(btid_ptr1, btid_ptr2)
static char * catcls_unpack_allocator(int size)
int or_get_attrname(RECDES *record, int attrid, char **string, int *alloced_string)
DB_VALUE value
Definition: catalog_class.c:75
int locator_update_index(THREAD_ENTRY *thread_p, RECDES *new_recdes, RECDES *old_recdes, ATTR_ID *att_id, int n_att_id, OID *oid, OID *class_oid, int op_type, HEAP_SCANCACHE *scan_cache, REPL_INFO *repl_info)
Definition: locator_sr.c:8147
INTL_CODESET codeset
static int catcls_reorder_attributes_by_repr(THREAD_ENTRY *thread_p, OR_VALUE *value_p)
unsigned int date
Definition: dbtype_def.h:776
#define ER_HEAP_UNKNOWN_OBJECT
Definition: error_code.h:102
OR_VARINFO * or_get_var_table(OR_BUF *buf, int nvars, char *(*allocator)(int))
enum intl_codeset INTL_CODESET
Definition: intl_support.h:190
PR_TYPE tp_Object
#define OR_NON_MVCC_HEADER_SIZE
int db_get_string_size(const DB_VALUE *value)
static int catcls_free_entry(CATCLS_ENTRY *entry_p)
void er_clear(void)
CT_ATTR * cc_atts
Definition: transform.h:71
#define SINGLE_ROW_INSERT
Definition: btree.h:52
CT_CLASS ct_Attrid
Definition: transform.c:430
int or_put_data(OR_BUF *buf, const char *data, int length)
META_CLASS tf_Metaclass_metharg
Definition: transform.c:102
META_CLASS tf_Metaclass_partition
Definition: transform.c:244
int REPR_ID
int catcls_get_server_compat_info(THREAD_ENTRY *thread_p, INTL_CODESET *charset_id_p, char *lang_buf, const int lang_buf_size, char *timezone_checksum)
#define DB_VALUE_TYPE(value)
Definition: dbtype.h:72
int cc_n_atts
Definition: transform.h:70
int db_get_enum_collation(const DB_VALUE *value)
int i
Definition: dynamic_load.c:954
int mht_map(const MHT_TABLE *ht, int(*map_func)(const void *key, void *data, void *args), void *func_args)
Definition: memory_hash.c:2199
int db_make_null(DB_VALUE *value)
#define SM_FUNCTION_INDEX_ID
#define SM_PROPERTY_FOREIGN_KEY
#define DB_IS_NULL(value)
Definition: dbtype.h:63
int heap_assign_address(THREAD_ENTRY *thread_p, const HFID *hfid, OID *class_oid, OID *oid, int expected_length)
Definition: heap_file.c:5914
#define OR_GET_OFFSET_SIZE(ptr)
DB_COLLECTION * set
Definition: dbtype_def.h:1063
#define CT_DBCOLL_COLL_NAME_COLUMN
Definition: transform.h:168
int or_get_data(OR_BUF *buf, char *data, int length)
INT16 type
static int catcls_find_class_oid_by_class_name(THREAD_ENTRY *thread_p, const char *name, OID *class_oid)
#define NULL_VOLID
DB_DATETIME * db_get_datetime(const DB_VALUE *value)
#define catalog_free_class_info_and_init(class_info_p)
int db_make_int(DB_VALUE *value, const int num)
int db_get_string_length(const DB_VALUE *value)
void heap_attrinfo_end(THREAD_ENTRY *thread_p, HEAP_CACHE_ATTRINFO *attr_info)
Definition: heap_file.c:9979
int db_make_oid(DB_VALUE *value, const OID *oid)
int mc_n_variable
Definition: transform.h:53
#define OR_BOUND_BIT_FLAG
#define OID_ISNULL(oidp)
Definition: oid.h:81
#define SM_PREFIX_INDEX_ID
static int catcls_expand_or_value_by_repr(OR_VALUE *value_p, OID *class_oid, DISK_REPR *rep)
CT_CLASS ct_Resolution
Definition: transform.c:486
SCAN_CODE heap_next(THREAD_ENTRY *thread_p, const HFID *hfid, OID *class_oid, OID *next_oid, RECDES *recdes, HEAP_SCANCACHE *scan_cache, int ispeeking)
Definition: heap_file.c:18622
#define LANG_SYS_CODESET
#define SM_PROPERTY_REVERSE_INDEX
int or_get_value(OR_BUF *buf, DB_VALUE *value, struct tp_domain *domain, int expected, bool copy)
enum update_inplace_style UPDATE_INPLACE_STYLE
Definition: heap_file.h:268
int heap_get_class_info(THREAD_ENTRY *thread_p, const OID *class_oid, HFID *hfid_out, FILE_TYPE *ftype_out, char **classname_out)
Definition: heap_file.c:16733
int or_pad(OR_BUF *buf, int length)
int catcls_update_catalog_classes(THREAD_ENTRY *thread_p, const char *name, RECDES *record, OID *class_oid_p, UPDATE_INPLACE_STYLE force_in_place)
bool catcls_Enable
char * or_unpack_domain(char *ptr, struct tp_domain **domain_ptr, int *is_null)
CT_CLASS ct_Indexkey
Definition: transform.c:500
struct or_value::or_sub sub
#define EXCHANGE_OR_VALUE(a, b)
Definition: catalog_class.c:50
#define SM_PROPERTY_REVERSE_UNIQUE
int heap_get_class_name(THREAD_ENTRY *thread_p, const OID *class_oid, char **class_name)
Definition: heap_file.c:9328
#define db_private_realloc(thrd, ptr, size)
Definition: memory_alloc.h:231
static int catcls_insert_instance(THREAD_ENTRY *thread_p, OR_VALUE *value_p, OID *oid, OID *root_oid, OID *class_oid, HFID *hfid, HEAP_SCANCACHE *scan)
int(* CREADER)(THREAD_ENTRY *thread_p, OR_BUF *buf, OR_VALUE *value_p)
Definition: catalog_class.c:66
#define PEEK
Definition: file_io.h:74
CT_CLASS ct_Attribute
Definition: transform.c:423
HFID ci_hfid
static int catcls_put_entry(THREAD_ENTRY *thread_p, CATCLS_ENTRY *entry, bool *already_exists)
CT_CLASS ct_Methfile
Definition: transform.c:465
char coll_name[COLL_NAME_SIZE]
static int catcls_get_subset(THREAD_ENTRY *thread_p, OR_BUF *buf_p, int expected_size, OR_VALUE *value_p, CREADER reader)
#define CATCLS_OID_TABLE_SIZE
Definition: catalog_class.c:61
#define catalog_free_representation_and_init(repr_p)
void tp_domain_free(TP_DOMAIN *dom)
DB_CONST_C_CHAR db_get_string(const DB_VALUE *value)
int or_advance(OR_BUF *buf, int offset)
unsigned int time
Definition: dbtype_def.h:777
DB_DEFAULT_EXPR_TYPE
Definition: dbtype_def.h:1181
static int catcls_get_or_value_from_buffer(THREAD_ENTRY *thread_p, OR_BUF *buf_p, OR_VALUE *value_p, DISK_REPR *rep)
#define OR_GET_BOUND_BIT(bitptr, element)
int get_disk_size_of_value(const DB_VALUE *value) const
static int catcls_put_or_value_into_buffer(OR_VALUE *value_p, int chn, OR_BUF *buf_p, OID *class_oid, DISK_REPR *rep)
static int catcls_get_or_value_from_method(THREAD_ENTRY *thread_p, OR_BUF *buf_p, OR_VALUE *value_p)
META_CLASS tf_Metaclass_methfile
Definition: transform.c:139
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_SM_INVALID_PROPERTY
Definition: error_code.h:368
static int catcls_get_or_value_from_attrid(THREAD_ENTRY *thread_p, OR_BUF *buf_p, OR_VALUE *value_p)
SCAN_CODE heap_get_class_record(THREAD_ENTRY *thread_p, const OID *class_oid, RECDES *recdes_p, HEAP_SCANCACHE *scan_cache, int ispeeking)
Definition: heap_file.c:24780
DISK_REPR * catalog_get_representation(THREAD_ENTRY *thread_p, OID *class_id_p, REPR_ID repr_id, CATALOG_ACCESS_INFO *catalog_access_info_p)