CUBRID Engine  latest
virtual_object.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  * virtual_object.c - Transaction object handler for virtual objects
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <stdio.h>
28 #include <string.h>
29 #include <assert.h>
30 
31 #include "authenticate.h"
32 #include "virtual_object.h"
33 #include "set_object.h"
34 #include "object_accessor.h"
35 #include "object_primitive.h"
36 #include "object_representation.h"
37 #include "db.h"
38 #include "schema_manager.h"
39 #include "view_transform.h"
40 #include "transaction_cl.h"
41 
42 #include "dbtype.h"
43 
44 #define ENCODED_LEN(siz) (2*(siz))
45 #define MAX_STRING_OID_LENGTH 4096
46 #define MIN_STRING_OID_LENGTH 18
47 
49 
50 static int vid_build_non_upd_object (MOP mop, DB_VALUE * seq);
51 
52 static int vid_make_vid (OID * view_id, OID * proxy_id, DB_VALUE * val, DB_VALUE * vobj);
53 static int vid_db_value_size (DB_VALUE * dbval);
54 static char *vid_pack_db_value (char *lbuf, DB_VALUE * dbval);
55 static int vid_pack_vobj (char *buf, OID * view, OID * proxy, DB_VALUE * keys, int *vobj_size, int buflen);
56 
57 static int vid_get_class_object (MOP class_p, SM_CLASS ** class_object_p);
58 static int vid_is_new_oobj (MOP mop);
59 #if defined(ENABLE_UNUSED_FUNCTION)
60 static int vid_convert_object_attr_value (SM_ATTRIBUTE * attribute_p, DB_VALUE * source_value,
61  DB_VALUE * destination_value, int *has_object);
62 #endif
63 
64 /*
65  * vid_get_class_object() - get class object given its class mop
66  * return: NO_ERROR if all OK, a negative error code otherwise
67  * class_p(in): a class mop
68  * obj(out): class_p' class object if all OK, NULL otherwise
69  *
70  * Note:
71  * modifies: er state, obj
72  * effects : set obj to class_p' class object
73  */
74 static int
75 vid_get_class_object (MOP class_p, SM_CLASS ** class_object_p)
76 {
77  if (!class_p || !class_object_p)
78  {
79  return ER_GENERIC_ERROR;
80  }
81 
82  if (ws_find (class_p, (MOBJ *) class_object_p) == WS_FIND_MOP_DELETED || !(*class_object_p))
83  {
84  const OID *oid = NULL;
85 
86  if (class_p->is_vid)
87  {
88  oid = &oid_Null_oid;
89  }
90  else
91  {
92  oid = &class_p->oid_info.oid;
93  }
94 
96  oid->slotid);
98  }
99  return NO_ERROR;
100 }
101 
102 /*
103  * vid_is_new_oobj() - is this a new OO instance that's about to be created?
104  * return: true iff mop is a new OO instance that's about to be created
105  * mop(in): a proxy object instance
106  *
107  * Note:
108  * effects : returns true iff mop is a new (embryonic) OO proxy object
109  */
110 static int
112 {
113  SM_CLASS *class_p;
114  int return_code = 0;
115 
116  return_code = (mop && mop->is_vid && ws_find (ws_class_mop (mop), (MOBJ *) (&class_p)) != WS_FIND_MOP_DELETED
117  && (mop->oid_info.vid_info->flags & VID_NEW));
118 
119  return return_code;
120 }
121 
122 /*
123  * vid_is_new_pobj() - is this a new proxy instance that's about to be created?
124  * return: true iff mop is a new proxy instance that's about to be created
125  * mop(in): a proxy object instance
126  *
127  * Note:
128  * effects : returns true iff mop is a new (embryonic) proxy object
129  */
130 int
132 {
133  int return_code = 0;
134  return_code = (mop && mop->is_vid && (mop->oid_info.vid_info->flags & VID_NEW));
135 
136  return return_code;
137 }
138 
139 /*
140  * vid_make_vobj() - constructor for vobj type
141  * return: int
142  * view_oid(in): DB_VALUE oid of projected view or null oid
143  * class_oid(in): DB_VALUE oid of real class or null oid
144  * keys(in): DB_VALUE oid keys
145  * vobj(in): DB_VALUE pointer for vobj
146  */
147 int
148 vid_make_vobj (const OID * view_oid, const OID * class_oid, const DB_VALUE * keys, DB_VALUE * vobj)
149 {
150  int error;
151  DB_VALUE oid_value;
152  DB_SEQ *seq;
153 
154  seq = set_create_sequence (3);
155  if (seq == NULL)
156  {
157  assert (er_errid () != NO_ERROR);
158  return er_errid ();
159  }
160 
161  db_make_oid (&oid_value, (OID *) view_oid);
162  error = set_put_element (seq, 0, &oid_value);
163  if (error < 0)
164  {
165  return error;
166  }
167 
168  db_make_oid (&oid_value, (OID *) class_oid);
169  error = set_put_element (seq, 1, &oid_value);
170  if (error < 0)
171  {
172  return error;
173  }
174 
175  error = set_put_element (seq, 2, (DB_VALUE *) keys);
176  if (error < 0)
177  {
178  return error;
179  }
180 
181  db_make_sequence (vobj, seq);
183 
184  return NO_ERROR;
185 }
186 
187 /*
188  * vid_fetch_instance() - FETCH A VIRTUAL INSTANCE
189  * return: MOBJ
190  * mop(in): Memory Object Pointer of virtual instance to fetch
191  * purpose(in): Fetch purpose: Valid ones:
192  * DB_FETCH_READ
193  * DB_FETCH_WRITE
194  * DB_FETCH_DIRTY
195  * read_fetch_version_type(in): Fetch version type in case of read
196  *
197  * Note:
198  * Fetch the instance associated with the given mop for the given purpose.
199  * Locks are handled by the underlying database.
200  */
201 MOBJ
202 vid_fetch_instance (MOP mop, DB_FETCH_MODE purpose, LC_FETCH_VERSION_TYPE read_fetch_version_type)
203 {
204  MOBJ inst;
205  MOP class_mop, base_mop;
206  SM_CLASS *class_p;
207  LC_FETCH_VERSION_TYPE fetch_version_type;
208 
209  if (!mop->is_vid)
210  {
211  return (MOBJ) 0;
212  }
213 
214  class_mop = ws_class_mop (mop);
215 
216  if (vid_get_class_object (class_mop, &class_p) < 0)
217  {
218  return (MOBJ) 0;
219  }
220 
221  ws_find (mop, &inst);
222 
223  /* check for out-of-date instance */
224  if (inst && (mop->lock == NULL_LOCK))
225  {
226  ws_decache (mop);
227  inst = (MOBJ) 0;
228  }
229  if (!inst)
230  {
231  /* fetch the object pointed to by the vclass */
232  base_mop = vid_get_referenced_mop (mop);
233  if (base_mop)
234  {
236 
237  if (purpose == DB_FETCH_WRITE)
238  {
239  fetch_mode = AU_FETCH_WRITE;
240  fetch_version_type = LC_FETCH_MVCC_VERSION;
241  }
242  else
243  {
244  fetch_mode = AU_FETCH_READ;
245  fetch_version_type = read_fetch_version_type;
246  }
247  if (au_fetch_instance_force (base_mop, &inst, fetch_mode, fetch_version_type) != NO_ERROR)
248  {
249  inst = (MOBJ) 0;
250  }
251  }
252  else
253  {
255  }
256  }
257  if ((purpose == DB_FETCH_WRITE) && (inst))
258  {
259  ws_dirty (mop);
260  }
261 
262  return inst;
263 }
264 
265 #if defined(ENABLE_UNUSED_FUNCTION)
266 /*
267  * vid_convert_object_attr_value() - Convert a object attribute value.
268  * return:
269  * attribute_p(in): attribute
270  * source_value(in): source value
271  * destination_value(in): destination value
272  * has_obj(out): nonzero iff source_value is (or has) a DB_TYPE_OBJECT (element)
273  * disguised into destination_value as a string value
274  *
275  * Note:
276  * Convert appropriate values from DB_TYPE_STRING to DB_TYPE_OBJECT &
277  * from DB_TYPE_OBJECT to DB_TYPE_STRING.
278  */
279 static int
280 vid_convert_object_attr_value (SM_ATTRIBUTE * attribute_p, DB_VALUE * source_value, DB_VALUE * destination_value,
281  int *has_object)
282 {
283  int error = NO_ERROR;
284  VID_INFO *ref_vid_info;
285  DB_SET *set;
286  DB_SET *new_set;
287  int set_size;
288  int set_index;
289  DB_VALUE set_value;
290  DB_VALUE new_set_value;
291  MOP ref_mop, proxy_class_mop;
292  DB_OBJECT *temp_object = NULL;
293 
294  *has_object = 0; /* assume no disguised objects until proven otherwise */
295 
296  switch (DB_VALUE_TYPE (source_value))
297  {
298  case DB_TYPE_OBJECT:
299  {
301  temp_object = db_get_object (source_value);
302  if (temp_object != NULL)
303  {
304  ref_vid_info = temp_object->oid_info.vid_info;
305  if (ref_vid_info)
306  {
307  pr_clone_value (&ref_vid_info->keys, destination_value);
308  *has_object = 1; /* yes, it's an object disguised as a string */
309  }
310  }
311  }
312  break;
313 
314  case DB_TYPE_VOBJ:
315  {
316  DB_TYPE type_id;
317 
318  db_make_null (destination_value);
319  if (attribute_p->domain == NULL)
320  {
321  return error;
322  }
323 
324  type_id = TP_DOMAIN_TYPE (attribute_p->domain);
325 
326  if (type_id == DB_TYPE_OBJECT || TP_IS_SET_TYPE (type_id))
327  {
328  DB_VALUE setval;
329 
330  set = db_get_set (source_value);
331  (void) db_seq_get (set, 1, &setval);
332  proxy_class_mop = db_get_object (&setval);
333 
334  if (proxy_class_mop == NULL)
335  {
336  return error;
337  }
338  (void) db_seq_get (set, 2, &setval);
339  ref_mop = ws_vmop (proxy_class_mop, VID_UPDATABLE | VID_BASE, &setval);
340  if (ref_mop)
341  {
342  db_make_object (destination_value, ref_mop);
343  }
344  pr_clear_value (&setval);
345  }
346  }
347  break;
348 
349  case DB_TYPE_SET:
350  case DB_TYPE_MULTISET:
351  {
352  set = db_get_set (source_value);
353  new_set = db_get_set (destination_value);
354  set_size = db_set_cardinality (set);
355  for (set_index = 0; set_index < set_size; ++set_index)
356  {
357  error = db_set_get (set, set_index, &set_value);
358  if (error != NO_ERROR)
359  {
360  continue;
361  }
362 
363  error = vid_convert_object_attr_value (attribute_p, &set_value, &new_set_value, has_object);
364  if (error == NO_ERROR)
365  {
366  error = db_set_add (new_set, &new_set_value);
367  pr_clear_value (&new_set_value);
368  }
369  }
370  }
371  break;
372 
373  case DB_TYPE_SEQUENCE:
374  {
375  set = db_get_set (source_value);
376  new_set = db_get_set (destination_value);
377  set_size = db_seq_size (set);
378  for (set_index = 0; set_index < set_size; ++set_index)
379  {
380  error = db_seq_get (set, set_index, &set_value);
381  if (error != NO_ERROR)
382  {
383  continue;
384  }
385  error = vid_convert_object_attr_value (attribute_p, &set_value, &new_set_value, has_object);
386  if (error == NO_ERROR)
387  {
388  error = db_seq_put (new_set, set_index, &new_set_value);
389  pr_clear_value (&new_set_value);
390  }
391  }
392  }
393  break;
394 
395  default:
396  pr_clone_value (source_value, destination_value);
397  break;
398  }
399  return error;
400 }
401 #endif
402 
403 /*
404  * vid_upd_instance() - PREPARE A VIRTUAL INSTANCE FOR UPDATE
405  * return: MOBJ
406  * mop(in): Mop of object that it is going to be updated
407  *
408  * Note:
409  * Prepare an instance for update. The instance is fetched for exclusive
410  * mode and it is set dirty. Note that it is very important the
411  * the instance is set dirty before it is actually updated, otherwise,
412  * the workspace may remain with a corrupted instance if a failure happens
413  *
414  * This function should be called before the instance is actually updated.
415  */
416 MOBJ
418 {
419  MOBJ object; /* The instance object */
420 
421  if (vid_is_new_oobj (mop))
422  {
423  /*
424  * don't fetch new (embryonic) OO instances because they
425  * are not there yet. we are buffering OO inserts.
426  */
427  ws_find (mop, &object);
428  }
429  else
430  {
432  /* The base instance is marked dirty by vid_fetch_instance */
433  }
434  return object;
435 }
436 
437 /*
438  * vid_flush_all_instances() - Flush all dirty instances of the class
439  * associated with the given class_mop
440  * to the driver
441  * return: NO_ERROR or ER_FAILED
442  * class_mop(in): The class mop of the instances to flush
443  *
444  * decache(in): True, if instances must be decached after they are flushed
445  *
446  * Note:
447  * Flush all dirty instances of the class associated with the
448  * given class_mop to the driver
449  */
450 int
451 vid_flush_all_instances (MOP class_mop, bool decache)
452 {
453  int rc;
454 
455  if (ws_map_class (class_mop, vid_flush_instance, (void *) &decache) == WS_MAP_SUCCESS)
456  {
457  rc = NO_ERROR;
458  }
459  else
460  {
461  rc = ER_FAILED;
462  }
463  return rc;
464 }
465 
466 /*
467  * vid_flush_and_rehash() - flush and rehash one proxy object instance
468  * return: NO_ERROR if all OK, an ER code otherwise
469  * mop(in): a dirty proxy object to be flushed
470  *
471  * Note:
472  * requires: mop points to a dirty proxy object to be flushed and rehashed
473  * modifies: mop
474  * effects : flush the object associated with the given mop and rehash it
475  * into its (possibly new) workspace hashtable address.
476  */
477 int
479 {
480  int return_code, isvid, isnew_oo;
481  bool isbase;
482  SM_CLASS *class_p;
483 
484  isvid = mop->is_vid;
485  isbase = vid_is_base_instance (mop);
486  isnew_oo = vid_is_new_oobj (mop);
487 
488  /* flush the proxy instance */
489  return_code = vid_flush_instance (mop, NULL);
490  if (return_code == WS_MAP_FAIL)
491  {
492  /* make sure we return an error */
493  assert (er_errid () != NO_ERROR);
494  return_code = er_errid ();
495  if (return_code >= NO_ERROR)
496  {
497  return_code = ER_GENERIC_ERROR;
498  }
499  ws_decache (mop);
500  }
501  else if (isvid && isbase && !isnew_oo)
502  {
503  /*
504  * rehash relational proxy mop into its new ws hashtable address.
505  * we must not rehash a new OO proxy mop because vid_flush_instance
506  * rehashes a new OO proxy mop (please see vid_store_oid_instance).
507  */
508  return_code = vid_get_class_object (WS_CLASS_MOP (mop), &class_p);
509  if (return_code == NO_ERROR && !ws_rehash_vmop (mop, (MOBJ) class_p, NULL))
510  {
512  return_code = ER_WS_REHASH_VMOP_ERROR;
513  }
514  }
515  return return_code;
516 }
517 
518 /*
519  * vid_flush_and_rehash_lbl() - flush and rehash a proxy object instance label
520  *
521  * return: val if all OK, NULL otherwise
522  * val(in): an interpreter parameter value container
523  *
524  * Note:
525  * requires: val is an interpreter parameter value container that may
526  * point to a dirty proxy object to be flushed and rehashed
527  * modifies: val's dirty proxy object
528  * effects : if val holds anything other than a new dirty proxy object then
529  * simply return val. Otherwise, flush and rehash val's new dirty
530  * proxy object and return val.
531  */
532 DB_VALUE *
534 {
535  DB_OBJECT *mop;
536 
537  if (!value)
538  {
539  return value;
540  }
541 
542  if (DB_VALUE_TYPE (value) != DB_TYPE_OBJECT)
543  {
544  return value;
545  }
546 
547  mop = db_get_object (value);
548 
549  /* if val has anything other than a new dirty proxy object then do nothing */
550  if (mop == NULL || !vid_is_new_pobj (mop))
551  {
552  return value;
553  }
554 
555  /* flush and rehash the new proxy object instance */
556  if (vid_flush_and_rehash (mop) != NO_ERROR)
557  {
558  return NULL; /* an error */
559  }
560 
561  return value; /* all OK */
562 }
563 
564 /*
565  * vid_allflush() - flush all dirty vclass objects
566  * return: NO_ERROR or ER_FAILED
567  *
568  * Note:
569  * modifies: all dirty vclass objects
570  * effects : flush all dirty vclass objects
571  */
572 int
574 {
575  DB_OBJLIST *cl;
576  bool return_code;
577  int isvirt;
578 
579  /*
580  * traverse the resident class list and
581  * for each proxy/vclass that has dirty instances
582  * call vid_flush_all to flush those dirty instances
583  */
584  for (cl = ws_Resident_classes, return_code = NO_ERROR; cl != NULL && return_code == NO_ERROR; cl = cl->next)
585  {
586  if (ws_has_dirty_objects (cl->op, &isvirt) && isvirt)
587  {
588  return_code = vid_flush_all_instances (cl->op, DONT_DECACHE);
589  }
590  }
591  return return_code;
592 }
593 
594 /*
595  * vid_add_virtual_instance() - INSERT A VIRTUAL OBJECT VIRTUAL INSTANCE
596  *
597  * return: MOP
598  * instance(in): Base instance object to add
599  * vclass_mop(in): Mop of vclass which will hold the instance
600  * bclass_mop(in):
601  * bclass(in):
602  *
603  * Note:
604  * Find one base class for the vclass indicated by class_mop.
605  * Make a MOP for the object for that base class. Then make a
606  * MOP for the vclass indicated by class_mop and set the keys
607  * to point to the base instance MOP.
608  */
609 MOP
610 vid_add_virtual_instance (MOBJ instance, MOP vclass_mop, MOP bclass_mop, SM_CLASS * bclass)
611 {
612  MOP bmop; /* Mop of newly created base instance */
613  MOP vmop = NULL; /* Mop of newly created virtual instance */
614 
615  if (!instance || !vclass_mop || !bclass_mop || !bclass)
616  {
618  return NULL;
619  }
620 
621  bmop = locator_add_instance (instance, bclass_mop);
622 
623  if (bmop)
624  {
625  vmop = vid_build_virtual_mop (bmop, vclass_mop);
626  }
627 
628  return vmop;
629 }
630 
631 /*
632  * vid_build_virtual_mop() - create a virtual mop from a base class
633  * instance mop
634  * return: MOP
635  * bmop(in): Base instance mop to create virtual mop for
636  * vclass_mop(in): Mop of vclass which will hold the instance
637  *
638  *
639  * Note:
640  * Make a MOP for the vclass indicated by vclass_mop and set
641  * the keys to point to the base instance MOP.
642  */
643 MOP
644 vid_build_virtual_mop (MOP bmop, MOP vclass_mop)
645 {
646  MOP vmop = NULL; /* Mop of newly created virtual instance */
647  DB_VALUE key; /* The key for the mop */
648  int vclass_updatable; /* Whether the vclass is updatable */
649 
650  if (!bmop || !vclass_mop)
651  {
653  return NULL;
654  }
655 
656  vclass_updatable = mq_is_updatable (vclass_mop);
657  db_make_object (&key, bmop);
658  vmop = ws_vmop (vclass_mop, VID_NEW | vclass_updatable ? VID_UPDATABLE : 0, &key);
659  if (!vmop)
660  {
661  return NULL;
662  }
663 
664  ws_set_lock (vmop, X_LOCK);
665 
666  return vmop;
667 
668 }
669 
670 /*
671  * vid_get_referenced_mop() - Uses the VID to find the base class referenced
672  * by a vclass.
673  * return: MOP
674  * mop(in): The MOP for the vclass instance
675  */
676 MOP
678 {
679  VID_INFO *mop_vid_info;
680 
681  if (!mop->is_vid)
682  {
683  goto end;
684  }
685  mop_vid_info = mop->oid_info.vid_info;
686 
687  if (!mop_vid_info)
688  {
689  goto end;
690  }
691 
692  if (DB_VALUE_TYPE (&mop_vid_info->keys) == DB_TYPE_OBJECT)
693  {
694  return db_get_object (&mop_vid_info->keys);
695  }
696 
697 end:
698  return (MOP) 0;
699 }
700 
701 /*
702  * vid_is_updatable() - Indicates whether the object is updatable.
703  * return: bool
704  * mop(in): The MOP for the vclass object
705  */
706 bool
708 {
709  VID_INFO *mop_vid_info;
710 
711  if (mop == NULL)
712  {
713  return false;
714  }
715 
716  if (!mop->is_vid)
717  {
718  return false;
719  }
720 
721  mop_vid_info = mop->oid_info.vid_info;
722 
723  if (!mop_vid_info)
724  {
725  return false;
726  }
727 
728  if (mop_vid_info->flags & VID_UPDATABLE)
729  {
730  return true;
731  }
732 
733  return false;
734 }
735 
736 /*
737  * vid_is_base_instance() - Indicates whether the given object is
738  * a base instance.
739  *
740  * return: bool
741  * mop(in): The MOP for the vclass object
742  */
743 bool
745 {
746  VID_INFO *mop_vid_info;
747 
748  if (!mop->is_vid)
749  {
750  return false;
751  }
752  mop_vid_info = mop->oid_info.vid_info;
753 
754  if (!mop_vid_info)
755  {
756  return false;
757  }
758 
759  if (mop_vid_info->flags & VID_BASE)
760  {
761  return true;
762  }
763 
764  return false;
765 }
766 
767 /*
768  * vid_base_instance() - Returns the object or tuple instance for which
769  * the given instance of a virtual class.
770  *
771  * return: DB_OBJECT
772  * mop(in): Virtual class instance
773  */
774 MOP
776 {
777  if (vid_is_base_instance (mop))
778  {
779  return mop;
780  }
781 
782  if (vid_is_updatable (mop))
783  {
784  return vid_get_referenced_mop (mop);
785  }
786  else
787  {
789  return (DB_OBJECT *) 0;
790  }
791 }
792 
793 /*
794  * vid_att_in_obj_id() - Indicates whether the attribute is in the object_id.
795  * return: bool
796  * att(in): Attribute
797  */
798 bool
800 {
801  if (attribute_p->flags & SM_ATTFLAG_VID)
802  {
803  return true;
804  }
805  else
806  {
807  return false;
808  }
809 }
810 
811 #if defined(ENABLE_UNUSED_FUNCTION)
812 /*
813  * vid_set_att_obj_id() - Sets the object_id position for the attribute.
814  * return: int
815  * class_name(in):
816  * att(in): Attribute
817  * id_no(in): Attribute position in object_id
818  */
819 int
820 vid_set_att_obj_id (const char *class_name, SM_ATTRIBUTE * attribute_p, int id_no)
821 {
822  int error = NO_ERROR;
823  DB_VALUE value;
824 
825  if (!attribute_p->properties)
826  {
827  attribute_p->properties = classobj_make_prop ();
828  if (attribute_p->properties == NULL)
829  {
830  assert (er_errid () != NO_ERROR);
831  return er_errid ();
832  }
833  }
834 
835  if (classobj_get_prop (attribute_p->properties, SM_PROPERTY_VID_KEY, &value) > 0)
836  {
838  er_set (ER_WARNING_SEVERITY, ARG_FILE_LINE, error, 1, class_name);
839  return error;
840  }
841 
842  attribute_p->flags |= SM_ATTFLAG_VID;
843  db_make_int (&value, id_no);
844  classobj_put_prop (attribute_p->properties, SM_PROPERTY_VID_KEY, &value);
845 
846  return error;
847 }
848 
849 /*
850  * vid_record_update() - Update the object to the driver as required.
851  * return: int
852  * mop(in): Memory Object Pointer for updated object
853  * class(in):
854  * att(in): Attribute that was updated
855  */
856 int
857 vid_record_update (MOP mop, SM_CLASS * class_p, SM_ATTRIBUTE * attribute_p)
858 {
859  VID_INFO *mop_vid_info;
860 
861  if (!mop->is_vid)
862  {
863  return NO_ERROR;
864  }
865 
866  mop_vid_info = mop->oid_info.vid_info;
867 
868  if (!mop_vid_info)
869  {
870  return NO_ERROR;
871  }
872 
873  if (!(mop_vid_info->flags & VID_BASE))
874  {
875  return NO_ERROR;
876  }
877 
878  ws_dirty (mop);
879 
880  if (!vid_att_in_obj_id (attribute_p))
881  {
882  return NO_ERROR;
883  }
884 
886  {
887  assert (er_errid () != NO_ERROR);
888  return er_errid ();
889  }
890 
891  if (!ws_rehash_vmop (mop, (MOBJ) class_p, NULL))
892  {
893  assert (er_errid () != NO_ERROR);
894  return er_errid ();
895  }
896 
897  return NO_ERROR;
898 }
899 #endif
900 
901 /*
902  * vid_compare_non_updatable_objects() - Compare the values for the two objects
903  * If they are all equal, the objects
904  * are equal.
905  * return: non-zero if the objects are equal.
906  * mop1(in): MOP for a non-updatable object
907  * mop2(in): MOP for a non-updatable object
908  */
909 bool
911 {
912  int error = NO_ERROR;
913  SM_CLASS *class1, *class2;
914  MOBJ inst1, inst2;
915  SM_ATTRIBUTE *att1, *att2;
916  char *mem1, *mem2;
917  SETREF *set1, *set2;
918  MOP attobj1, attobj2;
919  DB_VALUE val1, val2;
920  int rc;
921 
922  if ((mop1 == NULL) || (mop2 == NULL))
923  {
924  error = ER_OBJ_INVALID_ARGUMENTS;
926  return false;
927  }
928  error = au_fetch_class_force (mop1, &class1, AU_FETCH_READ);
929  if (error != NO_ERROR)
930  {
933  return false;
934  }
935  error = au_fetch_class_force (mop2, &class2, AU_FETCH_READ);
936  if (error != NO_ERROR)
937  {
940  return false;
941  }
942  inst1 = (MOBJ) mop1->object;
943  inst2 = (MOBJ) mop2->object;
944 
945  if ((!inst1) || (!inst2))
946  {
947  return false;
948  }
949 
950  for (att1 = class1->attributes, att2 = class2->attributes; att1 != NULL && att2 != NULL;
951  att1 = (SM_ATTRIBUTE *) att1->header.next, att2 = (SM_ATTRIBUTE *) att2->header.next)
952  {
953  if (att1->type != att2->type)
954  {
955  return false;
956  }
957  mem1 = inst1 + att1->offset;
958  mem2 = inst2 + att2->offset;
959  if (pr_is_set_type (att1->type->id))
960  {
963  att1->type->getmem (mem1, att1->domain, &val1);
964  att2->type->getmem (mem2, att2->domain, &val2);
965  set1 = db_get_set (&val1);
966  set2 = db_get_set (&val2);
967  db_value_put_null (&val1);
968  db_value_put_null (&val2);
969  if ((set1 != NULL) && (set2 != NULL))
970  {
971  if (set_compare (set1, set2, 0) != DB_EQ)
972  {
973  return false;
974  }
975  }
976  else
977  {
978  return false;
979  }
980  }
981  else if (att1->type == tp_Type_object)
982  {
985  att1->type->getmem (mem1, att1->domain, &val1);
986  att2->type->getmem (mem2, att2->domain, &val2);
987  attobj1 = db_get_object (&val1);
988  attobj2 = db_get_object (&val2);
989  db_value_put_null (&val1);
990  db_value_put_null (&val2);
991  if (attobj1 != NULL && WS_IS_DELETED (attobj1))
992  {
993  attobj1 = NULL;
994  }
995  if (attobj2 != NULL && WS_IS_DELETED (attobj2))
996  {
997  attobj2 = NULL;
998  }
999  if (!attobj1 || (attobj1 != attobj2))
1000  {
1001  return false;
1002  }
1003  }
1004  else
1005  {
1008  att1->type->getmem (mem1, att1->domain, &val1);
1009  att2->type->getmem (mem2, att2->domain, &val2);
1010  /*
1011  * Unlike most calls to this function, don't perform coercion
1012  * here so that an exact match can be performed. Note, this
1013  * formerly called pr_value_equal which did kind of "halfway"
1014  * coercion on the numeric types. Make sure the non-coercion
1015  * behavior of tp_value_equal is appropriate for this use.
1016  */
1017  rc = tp_value_equal (&val1, &val2, 0);
1018  db_value_put_null (&val1);
1019  db_value_put_null (&val2);
1020  if (!rc)
1021  {
1022  return false;
1023  }
1024  }
1025  }
1026  if (att1 != NULL || att2 != NULL)
1027  {
1028  return false;
1029  }
1030 
1031  return true;
1032 }
1033 
1034 /*
1035  * vid_rem_instance() - Delete an instance. The instance is marked as deleted
1036  * in the workspace.
1037  * return: none
1038  * mop(in): Memory Object pointer of object to remove
1039  */
1040 void
1042 {
1043  MOP base_mop;
1044 
1045  if (!mop->is_vid)
1046  {
1047  return;
1048  }
1049 
1050  if (!vid_is_updatable (mop))
1051  {
1052  return;
1053  }
1054 
1055  if (vid_is_base_instance (mop))
1056  {
1057  ws_mark_deleted (mop);
1058  }
1059  else
1060  {
1061  base_mop = vid_get_referenced_mop (mop);
1062  if (base_mop)
1063  {
1064  ws_mark_deleted (base_mop);
1065  }
1066  }
1067 }
1068 
1069 /*
1070  * vid_build_non_upd_object() - Builds an object for a MOP based on a sequence.
1071  * The object is not updatable.
1072  * return: int
1073  * mop(in): Memory Object pointer of object to build
1074  * seq(in): Sequence containing the non-updatable values
1075  */
1076 static int
1078 {
1079  int error = NO_ERROR;
1080  SM_CLASS *class_p;
1081  MOBJ inst;
1082  SM_ATTRIBUTE *attribute_p;
1083  char *mem;
1084  DB_VALUE val;
1085  DB_COLLECTION *col;
1086  DB_OBJECT *vmop;
1087  LOCK lock;
1088 
1089  if ((mop == NULL) || (seq == NULL))
1090  {
1091  error = ER_OBJ_INVALID_ARGUMENTS;
1092  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
1093  return error;
1094  }
1095  error = au_fetch_class_force (mop, &class_p, AU_FETCH_READ);
1096  if (error != NO_ERROR)
1097  {
1100  return error;
1101 
1102  }
1103  if (class_p->class_type != SM_VCLASS_CT)
1104  {
1105  error = ER_SM_INVALID_CLASS;
1107  return error;
1108  }
1109 
1110  inst = obj_alloc (class_p, 0);
1111  if (inst == NULL)
1112  {
1113  assert (er_errid () != NO_ERROR);
1114  error = er_errid ();
1115  return error;
1116  }
1117 
1118  /* free the previous object, if any */
1119  if (mop->object)
1120  {
1121 #if defined(CUBRID_DEBUG)
1122  /* check to see if anyone has this mop pinned */
1123  if (mop->pinned)
1124  {
1125  /*
1126  * this is a logical error, we can't free the object since
1127  * someone has it pinned. It will leak.
1128  */
1130  er_log_debug (ARG_FILE_LINE, "** SYSTEM ERROR ** crs_vobj_to_vmop() is overwriting a pinned object");
1131  }
1132 #endif /* CUBRID_DEBUG */
1133  if (!mop->pinned)
1134  {
1135  obj_free_memory ((SM_CLASS *) ws_class_mop (mop)->object, (MOBJ) mop->object);
1136  }
1137  }
1138 
1139  mop->object = inst;
1140  col = db_get_set (seq);
1141  for (attribute_p = class_p->attributes; attribute_p != NULL; attribute_p = (SM_ATTRIBUTE *) attribute_p->header.next)
1142  {
1143  error = db_seq_get (col, attribute_p->order, &val);
1144 
1145  if (error < 0)
1146  break;
1147 
1148  mem = inst + attribute_p->offset;
1149  switch (DB_VALUE_TYPE (&val))
1150  {
1151  case DB_TYPE_VOBJ:
1152  {
1153  error = vid_vobj_to_object (&val, &vmop);
1154  if (!(error < 0))
1155  {
1157  db_make_object (&val, vmop);
1158  }
1159  }
1160  break;
1161  case DB_TYPE_SET:
1162  case DB_TYPE_MULTISET:
1163  case DB_TYPE_SEQUENCE:
1164  {
1165  error = set_convert_oids_to_objects (db_get_set (&val));
1166  }
1167  break;
1168  default:
1169  break;
1170  }
1171  if (error < 0)
1172  break;
1173  obj_assign_value (mop, attribute_p, mem, &val);
1174  pr_clear_value (&val);
1175  }
1176 
1177  if (error < 0)
1178  {
1179  db_ws_free (inst);
1180  mop->object = NULL;
1181  return error;
1182  }
1183  /*
1184  * lock it to avoid getting a Workspace pin violation
1185  * later in vid_fetch_instance.
1186  */
1187  lock = ws_get_lock (mop);
1188  assert (lock >= NULL_LOCK);
1189  lock = lock_Conv[S_LOCK][lock];
1190  assert (lock != NA_LOCK);
1191 
1192  ws_set_lock (mop, lock);
1193 
1194  return error;
1195 }
1196 
1197 /*
1198  * vid_decache_instance()
1199  * return: none
1200  * mop(in): Memory Object pointer
1201  */
1202 void
1204 {
1205  if (!mop->is_vid)
1206  {
1207  return;
1208  }
1209 
1210  if ((vid_is_base_instance (mop)) || (!vid_is_updatable (mop)))
1211  {
1212  ws_set_lock (mop, NULL_LOCK);
1213  ws_decache (mop);
1214  }
1215 } /* vid_decache_instance */
1216 
1217 /*
1218  * vid_get_keys() - Returns in val a "peek" at the keys contained in the vmop.
1219  *
1220  * return: none
1221  * mop(in): Memory Object pointer
1222  *
1223  * val(in): return DB_VALUE for the vmop keys
1224  *
1225  * Note:
1226  * This is to avoid gratuitous alloc/free of the values
1227  * that would be done by db_value_clone. The caller MUST
1228  * call db_value_clone if a copy of keys is needed. The
1229  * caller should NOT clear the returned result.
1230  *
1231  * If given a non-virtual mop, this still returns the key
1232  * feild which would be in that position (3rd) of a
1233  * DB_TYPE_VOBJ. Consequently, any DB_TYPE_VOBJ can
1234  * be contructed from a DB_OBJECT * (mop) by calling this
1235  * function for the keys portion.
1236  */
1237 void
1238 vid_get_keys (MOP mop, DB_VALUE * value)
1239 {
1240  VID_INFO *mop_vid_info;
1241  OID *oid;
1242 
1243  if (mop == NULL)
1244  {
1245  return;
1246  }
1247 
1248  if (!mop->is_vid)
1249  {
1250  oid = ws_oid (mop);
1251  db_make_oid (value, oid);
1252  return;
1253  }
1254  mop_vid_info = mop->oid_info.vid_info;
1255 
1256  if (mop_vid_info)
1257  {
1258  *value = mop_vid_info->keys;
1259  value->need_clear = false;
1260  return;
1261  }
1262 
1263  return;
1264 }
1265 
1266 /*
1267  * vid_getall_mops() - fetch/lock all instances of a given proxy
1268  * return: DB_OBLIST of class_p' instances if all OK, NULL otherwise
1269  * class_mop(in): proxy/vclass class memory object pointer
1270  * class_p(in): proxy/vclass class object
1271  * purpose(in): DB_FETCH_READ or DB_FETCH_WRITE
1272  *
1273  *
1274  * Note:
1275  * Fetch/lock all instances (mops) of a given proxy/vclass.
1276  * The list of mops is returned to the caller.
1277  */
1278 
1279 DB_OBJLIST *
1280 vid_getall_mops (MOP class_mop, SM_CLASS * class_p, DB_FETCH_MODE purpose)
1281 {
1282  const char *class_name;
1283  int error = NO_ERROR;
1284  DB_OBJLIST *objlst, *new1;
1285  DB_QUERY_RESULT *qres;
1286  DB_QUERY_ERROR query_error;
1287  char query[2000];
1288  int t, tuple_cnt;
1289  DB_VALUE value;
1290  MOP mop;
1292 
1293  /* make sure we have reasonable arguments */
1294  if (!class_mop || !class_p)
1295  {
1296  return NULL;
1297  }
1298 
1299  /* flush any dirty instances */
1300  if (vid_flush_all_instances (class_mop, false) != NO_ERROR)
1301  {
1302  return NULL;
1303  }
1304 
1305  /* put together a query to get all instances of class_p */
1306  class_type = sm_get_class_type (class_p);
1307  class_name = db_get_class_name (class_mop);
1308  snprintf (query, sizeof (query) - 1, "SELECT [%s] FROM [%s]", class_name, class_name);
1309 
1310  /* run the query */
1311  error = db_compile_and_execute_local (query, &qres, &query_error);
1312  if (error != NO_ERROR)
1313  {
1314  return NULL;
1315  }
1316 
1317  /* how many instances */
1318  tuple_cnt = db_query_tuple_count (qres);
1319  if (tuple_cnt == 0)
1320  {
1321  return NULL;
1322  }
1323 
1324  /* start with an empty objlist */
1325  objlst = NULL;
1326 
1327  /* install instances into this workspace */
1328  for (t = 0; t < tuple_cnt; ++t)
1329  {
1330 
1331  /* advance to next row */
1332  error = db_query_next_tuple (qres);
1333 
1334  /* get instance mop */
1335  if (error == DB_CURSOR_SUCCESS)
1336  {
1337  error = db_query_get_tuple_value_by_name (qres, (char *) class_name, &value);
1338  }
1339 
1340  /* allocate objlist node */
1341  new1 = ml_ext_alloc_link ();
1342  if (error != NO_ERROR || new1 == NULL)
1343  {
1344  ml_ext_free (objlst);
1345  return NULL;
1346  }
1347 
1348  /* save instance mop into objlist */
1349  new1->op = mop = db_get_object (&value);
1350  new1->next = objlst;
1351  objlst = new1;
1352  }
1353 
1354  /* recycle query results */
1355  error = db_query_end (qres);
1356 
1357  /* convert purpose into a lock */
1358  switch (purpose)
1359  {
1360  case DB_FETCH_QUERY_WRITE:
1362  /*
1363  * we're forced to revert these back to DB_FETCH_WRITE because the
1364  * proxy locking code downstream recognizes only DB_FETCH_WRITE when
1365  * requesting xlocks, all other purpose values are treated as slock
1366  * requests.
1367  */
1368  purpose = DB_FETCH_WRITE;
1369  break;
1370  default:
1371  break;
1372  }
1373 
1374  /* if XLOCKs were requested, get them now */
1375  if (purpose == DB_FETCH_WRITE && db_fetch_list (objlst, purpose, 0) != NO_ERROR)
1376  {
1377  ml_ext_free (objlst);
1378  return NULL;
1379  }
1380  return objlst;
1381 }
1382 
1383 /*
1384  * vid_vobj_to_object() -
1385  * return: NO_ERROR if all OK, a negative ER code otherwise.
1386  * vobj(in): a DB_TYPE_VOBJ db_value
1387  * mop(out): object instance installed into workspace for vobj
1388  *
1389  * Note:
1390  * requires: vobj is a DB_TYPE_VOBJ db_value {view,proxy,keys}
1391  * modifies: ws table, mop
1392  * effects : lookup vobj in the workspace table
1393  * if not found then add vobj's object instance into ws table
1394  */
1395 int
1396 vid_vobj_to_object (const DB_VALUE * vobj, DB_OBJECT ** mop)
1397 {
1398  DB_SEQ *seq;
1399  int i, size, flags = 0;
1400  DB_VALUE elem_value, keys;
1401  DB_OBJECT *vclass = NULL, *bclass = NULL, *obj = NULL;
1402  int error = NO_ERROR;
1403  MOBJ inst;
1404 
1405  /* make sure we have a good input argument */
1406  if (!vobj || !mop || DB_VALUE_TYPE (vobj) != DB_TYPE_VOBJ || (seq = db_get_set (vobj)) == NULL
1407  || (size = db_set_size (seq)) != 3)
1408  {
1409  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_DL_ESYS, 1, "virtual object inconsistent");
1410  return ER_DL_ESYS;
1411  }
1412 
1413  keys.domain.general_info.is_null = 1;
1414  keys.need_clear = false;
1415 
1416  *mop = NULL;
1417 
1418  /*
1419  * get vobjs components into: {vclass,bclass,keys}.
1420  * a proxy instance will have a null vclass.
1421  * a virtual class instance may have a null bclass.
1422  */
1423  for (i = 0; i < size; i++)
1424  {
1425  db_set_get (seq, i, &elem_value);
1426 
1427  switch (i)
1428  {
1429  case 0:
1430 
1431  if (elem_value.domain.general_info.is_null != 0)
1432  {
1433  vclass = NULL;
1434  }
1435  else if (elem_value.domain.general_info.type == DB_TYPE_OBJECT)
1436  {
1437  vclass = db_get_object (&elem_value);
1438  /*
1439  * we need to guarantee that if this vclass
1440  * exists and it's not yet in the workspace, we must fetch
1441  * it in. Otherwise, db_decode_object() can fail.
1442  */
1443  if (vclass && vclass->object == NULL
1445  {
1446  assert (er_errid () != NO_ERROR);
1447  return er_errid ();
1448  }
1449  }
1450  else
1451  {
1452  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_DL_ESYS, 1, "view class inconsistent");
1453  return ER_DL_ESYS;
1454  }
1455  break;
1456 
1457  case 1:
1458  if (elem_value.domain.general_info.is_null != 0)
1459  {
1460  bclass = NULL;
1461  }
1462  else if (elem_value.domain.general_info.type == DB_TYPE_OBJECT)
1463  {
1464  bclass = db_get_object (&elem_value);
1465  if (bclass && bclass->object == NULL
1467  {
1468  assert (er_errid () != NO_ERROR);
1469  return er_errid ();
1470  }
1471  }
1472  else
1473  {
1474  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_DL_ESYS, 1, "base class inconsistent");
1475  return ER_DL_ESYS;
1476  }
1477  break;
1478 
1479  case 2:
1480  if (elem_value.domain.general_info.is_null == 0)
1481  {
1482  keys = elem_value; /* structure copy */
1483  }
1484  break;
1485  default:
1486  continue;
1487  }
1488 
1489  }
1490  if (keys.domain.general_info.is_null == 0)
1491  {
1492  /*
1493  * does it have a class/proxy component specified?
1494  * This would mean a real, updatable object.
1495  */
1496  if (bclass)
1497  {
1498  /* look it up or install it in the workspace */
1499  flags = VID_UPDATABLE | VID_BASE;
1500  obj = ws_vmop (bclass, flags, &keys);
1501  }
1502  else if (keys.domain.general_info.type == DB_TYPE_OBJECT)
1503  {
1504  /*
1505  * The vclass refers to a class, but we left
1506  * the class oid feild empty in the vobj.
1507  */
1508  obj = db_get_object (&keys);
1509  }
1510  else if (keys.domain.general_info.type == DB_TYPE_VOBJ)
1511  {
1512  assert (false);
1513  vid_vobj_to_object (&keys, &obj);
1514  }
1515  else
1516  {
1517  obj = NULL;
1518  }
1519 
1520 
1521  /* does it have a vclass component? */
1522  if (!vclass)
1523  {
1524  /*
1525  * with no view, then the result is the object
1526  * we just calculated.
1527  */
1528  *mop = obj;
1529  }
1530  else
1531  {
1532  DB_VALUE temp;
1533  if (obj)
1534  {
1535  /* a view on an updatable class or proxy */
1536  db_make_object (&temp, obj);
1537  flags = VID_UPDATABLE;
1538  *mop = ws_vmop (vclass, flags, &temp);
1539  }
1540  else
1541  {
1543  {
1544  /*
1545  * The vclass refers to a non-updatable view result.
1546  * look it up or install it in the workspace.
1547  */
1548  flags = 0;
1549  *mop = ws_vmop (vclass, flags, &keys);
1550 
1551  if (*mop)
1552  {
1553  error = vid_build_non_upd_object (*mop, &keys);
1554  }
1555  }
1556  }
1557  }
1558 
1559  if (!*mop)
1560  {
1561  if (error == NO_ERROR)
1562  {
1563  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_DL_ESYS, 1, "vobject error");
1564  error = ER_DL_ESYS;
1565  }
1566  }
1567  }
1568  pr_clear_value (&keys);
1569 
1570  return error;
1571 }
1572 
1573 /*
1574  * vid_oid_to_object() - turn an OID into an OBJECT type db_value
1575  * return: NO_ERROR if all OK, an er code otherwise
1576  * val(in/out): a db_value
1577  * mop(in):
1578  *
1579  * Note:
1580  * modifies: val
1581  * effects : if val is an OID or has an OID turn it into an OBJECT value
1582  */
1583 int
1584 vid_oid_to_object (const DB_VALUE * value, DB_OBJECT ** mop)
1585 {
1586  OID *oid;
1587 
1588  *mop = NULL;
1589  /* make sure we have a reasonable argument */
1590  if (!value)
1591  {
1592  return ER_GENERIC_ERROR;
1593  }
1594 
1595  /* OIDs must be turned into objects */
1596  switch (DB_VALUE_TYPE (value))
1597  {
1598  case DB_TYPE_OID:
1599  oid = (OID *) db_get_oid (value);
1600  if (oid != NULL && !OID_ISNULL (oid))
1601  {
1602  *mop = ws_mop (oid, NULL);
1603  }
1604  break;
1605 
1606  case DB_TYPE_SET:
1607  case DB_TYPE_MULTISET:
1608  case DB_TYPE_SEQUENCE:
1609  return set_convert_oids_to_objects (db_get_set (value));
1610 
1611  default:
1612  break;
1613  }
1614  return NO_ERROR;
1615 }
1616 
1617 /*
1618  * vid_object_to_vobj() -
1619  * return: NO_ERROR if all OK, a negative ER code otherwise
1620  * obj(in): a virtual object instance in the workspace
1621  * vobj(out): a DB_TYPE_VOBJ db_value
1622  *
1623  * Note:
1624  * requires: obj is a virtual mop in the workspace
1625  * modifies: vobj, set/seq memory pool
1626  * effects : builds the DB_TYPE_VOBJ db_value form of the given virtual mop
1627  */
1628 int
1630 {
1631  /* convert a workspace DB_TYPE_OBJECT to a DB_TYPE_VOBJ */
1632  const OID *view_oid;
1633  const OID *class_oid;
1634  DB_VALUE keys;
1635  DB_OBJECT *view_class;
1636  DB_OBJECT *real_class;
1637  DB_OBJECT *real_object;
1638 
1639  (vobj)->domain.general_info.is_null = 1;
1640  (vobj)->need_clear = false;
1641 
1642  if (!obj)
1643  {
1644  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_DL_ESYS, 1, "null virtual object");
1645  return ER_DL_ESYS;
1646  }
1647 
1648  class_oid = &oid_Null_oid;
1649  view_oid = &oid_Null_oid;
1650 
1651  view_class = db_get_class ((DB_OBJECT *) obj);
1652  real_object = db_real_instance ((DB_OBJECT *) obj);
1653  real_class = db_get_class (real_object);
1654 
1655  if (view_class)
1656  {
1657  view_oid = ws_oid (view_class);
1658  }
1659 
1660  if (real_class)
1661  {
1662  class_oid = ws_oid (real_class);
1663  }
1664 
1665  if (real_object)
1666  {
1667  vid_get_keys (real_object, &keys);
1668  }
1669  else
1670  {
1671  vid_get_keys ((DB_OBJECT *) obj, &keys);
1672  }
1673 
1674  return vid_make_vobj (view_oid, class_oid, &keys, vobj);
1675 }
1676 
1677 /*
1678  * vid_make_vid() - convert db_value into a virtual id
1679  * return: return NO_ERROR if all OK, ER_FAILED otherwise
1680  * view_id(in): vclass oid or NULL
1681  * proxy_id(in): proxy oid or NULL
1682  * val(in): a db_value (vobj's keys)
1683  * vobj(in): the encoded VOBJ
1684  *
1685  * Note:
1686  * requires: Caller must clear the created VOBJ db_value
1687  * modifies: vobj is filled with the triple: view_id, proxy_id, keys
1688  * effects : create the VOBJ encoding.
1689  */
1690 static int
1691 vid_make_vid (OID * view_id, OID * proxy_id, DB_VALUE * val, DB_VALUE * vobj)
1692 {
1693  int has_proxy, has_view;
1694  DB_VALUE tval;
1695  DB_SEQ *seq;
1696 
1697  has_proxy = (proxy_id && !OID_ISNULL (proxy_id));
1698  has_view = (view_id && !OID_ISNULL (view_id));
1699 
1700  seq = db_seq_create (NULL, NULL, 3);
1701  if (seq == NULL)
1702  {
1703  return ER_FAILED;
1704  }
1705 
1706  if (has_view)
1707  {
1708  db_make_oid (&tval, view_id);
1709  }
1710  else
1711  {
1713  OID_SET_NULL (&tval.data.oid);
1714  }
1715 
1716  if (db_seq_put (seq, 0, &tval) != NO_ERROR)
1717  {
1718  return ER_FAILED;
1719  }
1720 
1721  if (has_proxy)
1722  {
1723  db_make_oid (&tval, proxy_id);
1724  }
1725  else
1726  {
1728  OID_SET_NULL (&tval.data.oid);
1729  }
1730 
1731  if (db_seq_put (seq, 1, &tval) != NO_ERROR)
1732  {
1733  return ER_FAILED;
1734  }
1735 
1736  if (db_seq_put (seq, 2, val) != NO_ERROR)
1737  {
1738  return ER_FAILED;
1739  }
1740 
1741  db_make_sequence (vobj, seq);
1743 
1744  return NO_ERROR;
1745 }
1746 
1747 /*
1748  * vid_db_value_size() - size a db_value
1749  * return: packed size of db_value
1750  * dbval(in): dbvalue to size
1751  */
1752 static int
1754 {
1755  int val_size;
1756 
1757  val_size = pr_data_writeval_disk_size (dbval);
1758 
1759  /*
1760  * some OR_PUT functions assume data to be copied is always properly aligned,
1761  * so we oblige here at the cost of maybe some extra space
1762  */
1763  val_size = DB_ALIGN (val_size, MAX_ALIGNMENT);
1764 
1765  return val_size;
1766 }
1767 
1768 /*
1769  * vid_pack_db_value() - pack a db_value
1770  * return: new buf position
1771  * lbuf(in): the listfile destination buffer
1772  * dbval(in): dbvalue to pack
1773  *
1774  * Note:
1775  * requires: buf must have enough space for packed dbval
1776  * DB_IS_NULL(dbval) == false
1777  * modifies: buf
1778  * effects : pack val in its listfile form into buf
1779  */
1780 static char *
1781 vid_pack_db_value (char *lbuf, DB_VALUE * dbval)
1782 {
1783  OR_BUF buf;
1784  PR_TYPE *pr_type;
1785  int val_size;
1786  DB_TYPE dbval_type;
1787 
1788  dbval_type = DB_VALUE_DOMAIN_TYPE (dbval);
1789 
1790  if (dbval_type > DB_TYPE_LAST || dbval_type == DB_TYPE_TABLE)
1791  {
1792  return NULL;
1793  }
1794 
1795  pr_type = tp_Type_id_map[(int) dbval_type];
1796 
1797  val_size = pr_data_writeval_disk_size (dbval);
1798 
1799  or_init (&buf, lbuf, val_size);
1800 
1801  if (pr_type->data_writeval (&buf, dbval) != NO_ERROR)
1802  {
1803  return NULL;
1804  }
1805 
1806  lbuf += val_size;
1807 
1808  return lbuf;
1809 }
1810 
1811 /*
1812  * vid_pack_vobj() -
1813  * return: int
1814  * buf(in):
1815  * view(in):
1816  * proxy(in):
1817  * keys(in):
1818  * vobj_size(in):
1819  * buflen(in):
1820  */
1821 static int
1822 vid_pack_vobj (char *buf, OID * view, OID * proxy, DB_VALUE * keys, int *vobj_size, int buflen)
1823 {
1824  DB_VALUE vobj;
1825 
1826  if (vid_make_vid (view, proxy, keys, &vobj) != NO_ERROR)
1827  {
1828  return ER_FAILED;
1829  }
1830 
1831  *vobj_size = vid_db_value_size (&vobj);
1832 
1833  if (buf)
1834  {
1835  /*
1836  * vobj_size contains alignment bytes. When we encode this vobj during
1837  * packing, we need to have known values in the alignment bytes else
1838  * we can not reconstruct this vobj. Since we don't know the number of
1839  * alignment bytes, we'll zero the buffer. (Always use a canon to kill
1840  * a cat :-). This is probably okay since we're usually talking about
1841  * some number of bytes less than 100. -- dkh
1842  */
1843  if (buflen <= *vobj_size)
1844  {
1846  return ER_FAILED;
1847  }
1848  (void) memset (buf, 0, *vobj_size);
1849 
1850  buf = vid_pack_db_value (buf, &vobj);
1851  }
1852  db_value_clear (&vobj);
1853 
1854  return NO_ERROR;
1855 }
1856 
1857 /*
1858  * vid_encode_object() -
1859  * return: int
1860  * object(in):
1861  * string(in):
1862  * allocated_length(in):
1863  * actual_length(in):
1864  */
1865 int
1866 vid_encode_object (DB_OBJECT * object, char *string, int allocated_length, int *actual_length)
1867 {
1868  DB_OBJECT *class_;
1869  OID *temp_oid;
1870  int is_class = 0;
1871 
1872  if (object == NULL || (class_ = db_get_class (object)) == NULL)
1873  {
1875  return (ER_HEAP_UNKNOWN_OBJECT);
1876  }
1877 
1878  if (string == NULL || (allocated_length < MIN_STRING_OID_LENGTH))
1879  {
1881  return ER_OBJ_BUFFER_TOO_SMALL;
1882  }
1883 
1884  /*
1885  * classify the object into one of:
1886  * - instance of a class
1887  * - instance of a proxy
1888  * - instance of a vclass of a class
1889  * - instance of a vclass of a proxy
1890  * - nonupdatable object
1891  */
1892 
1893  class_ = db_get_class (object);
1894  if (class_ == NULL)
1895  {
1896  return ER_FAILED;
1897  }
1898 
1899  is_class = db_is_any_class (object);
1900  if (is_class < 0)
1901  {
1902  return is_class;
1903  }
1904  if (!is_class)
1905  {
1906  is_class = db_is_class (class_);
1907  if (is_class < 0)
1908  {
1909  return is_class;
1910  }
1911  }
1912  if (is_class)
1913  {
1914  /* if the specified string length is less than */
1915  /* MIN_STRING_OID_LENGTH, we return this actual length */
1917  {
1918  *actual_length = MIN_STRING_OID_LENGTH;
1919  return ER_OBJ_BUFFER_TOO_SMALL;
1920  }
1921 
1922  /* it's an instance of a local class */
1923  string[0] = DB_INSTANCE_OF_A_CLASS;
1924 
1925  /* make sure its oid is a good one */
1926  temp_oid = WS_OID (object);
1927  if (OID_ISTEMP (temp_oid))
1928  {
1929  if (locator_assign_permanent_oid (object))
1930  temp_oid = WS_OID (object);
1931  else
1932  {
1933  if (er_errid () == NO_ERROR)
1934  {
1936  }
1937  return er_errid ();
1938  }
1939  }
1940  /* encode oid into an ascii string */
1941  or_encode (&string[1], (const char *) temp_oid, OR_OID_SIZE);
1942  *actual_length = MIN_STRING_OID_LENGTH;
1943  return NO_ERROR;
1944  }
1945 
1946  {
1947  DB_OBJECT *real_object, *real_class;
1948  int vobj_len, i;
1949  OID *view, *proxy;
1950  DB_VALUE *keys, obj_key, val;
1951  DB_ATTRIBUTE *attrs;
1952  DB_SEQ *seq;
1953  char vobj_buf[MAX_STRING_OID_LENGTH];
1954 
1955  if (db_is_updatable_object (object))
1956  {
1957  /* it's updatable. get its real instance */
1958  real_object = db_real_instance (object);
1959  if (!real_object || real_object == object)
1960  {
1963  }
1964  /* get {view,proxy,keys} of this vclass instance */
1965  view = WS_OID (class_);
1966  real_class = db_get_class (real_object);
1967  is_class = db_is_class (real_class);
1968  if (is_class < 0)
1969  {
1970  return is_class;
1971  }
1972  else if (is_class > 0)
1973  {
1974  /*
1975  * it's an instance of a vclass of a class
1976  * represented in vobj form as {view,NULL,keys}
1977  */
1979  proxy = NULL;
1980  /*
1981  * since we're doing the reverse of crs_cp_vobj_to_dbvalue,
1982  * we form keys as a DB_TYPE_OBJECT db_value containing real_obj.
1983  * by forming keys this way, we let crs_cp_vobj_to_dbvalue yield
1984  * object back, given the {view,NULL,keys} built here.
1985  */
1986  keys = &obj_key;
1987  db_make_object (keys, real_object);
1988  /* fall through to vobj packing/encoding */
1989  }
1990  else
1991  {
1992  /*
1993  * a vclass of a vclass should have been resolved into
1994  * a vclass of a class or a proxy during compilation,
1995  * therefore it's considered an error at run-time.
1996  */
1999  }
2000  }
2001  else
2002  { /* its a nonupdatable object */
2004  view = WS_OID (class_);
2005  proxy = NULL;
2006  keys = &obj_key;
2007 
2008  /*
2009  * object has values only. it doesn't have any keys. so we form
2010  * object's values into a sequence of values to become vobj's keys
2011  */
2012  seq = db_seq_create (NULL, NULL, 0);
2013  db_make_sequence (keys, seq);
2014  /*
2015  * there may be a safe way to speed this up by getting
2016  * the values directly and bypassing authorization checks
2017  */
2018  for (attrs = db_get_attributes (object), i = 0; attrs; attrs = db_attribute_next (attrs), i++)
2019  {
2020  if (db_get (object, db_attribute_name (attrs), &val) < 0 || db_seq_put (seq, i, &val) < 0)
2021  {
2024  }
2025  }
2026  /* fall through to vobj packing/encoding */
2027  }
2028 
2029  /* pack {view,proxy,keys} in listfile form into vobj_buf */
2030  /* pass vobj_buf's allocated length here to avoid a memory overrun */
2031  if (vid_pack_vobj (vobj_buf, view, proxy, keys, &vobj_len, MAX_STRING_OID_LENGTH) != NO_ERROR)
2032  {
2034  return (ER_OBJ_CANT_ENCODE_VOBJ);
2035  }
2036 
2037  /* take care not to overrun str */
2038  *actual_length = ENCODED_LEN (vobj_len + OR_INT_SIZE) + 1;
2039  if (*actual_length > allocated_length)
2040  {
2042  return (ER_OBJ_BUFFER_TOO_SMALL);
2043  }
2044  /* stuff vobj_len+vobj into str */
2045  or_encode (&string[1], (const char *) &vobj_len, OR_INT_SIZE);
2046  or_encode (&string[1 + ENCODED_LEN (OR_INT_SIZE)], (const char *) vobj_buf, vobj_len);
2047  return NO_ERROR;
2048  }
2049 }
2050 
2051 /*
2052  * vid_decode_object()
2053  * return: int
2054  * string(in):
2055  * object(out):
2056  */
2057 int
2058 vid_decode_object (const char *string, DB_OBJECT ** object)
2059 {
2060  OID obj_id;
2061  DB_VALUE val;
2062  int vobj_len = 0, rc = NO_ERROR;
2063  size_t len;
2064  OR_BUF buf;
2065  char vobj_buf[MAX_STRING_OID_LENGTH], *bufp = vobj_buf;
2066 
2067  /* make sure we got reasonable arguments */
2068  if (object == NULL)
2069  {
2071  return (ER_OBJ_NULL_ADDR_OUTPUT_OBJ);
2072  }
2073 
2074  if (string == NULL || !strlen (string))
2075  {
2077  return ER_OBJ_INVALID_ARGUMENT;
2078  }
2079 
2080  /* guard against overrunning vobj_buf */
2081  len = strlen (string);
2082  if (len >= MAX_STRING_OID_LENGTH && (bufp = (char *) malloc (len)) == NULL)
2083  {
2085  return ER_OUT_OF_VIRTUAL_MEMORY;
2086  }
2087 
2088  switch (string[0])
2089  {
2091  /* decode rest of str into a MOP */
2092  or_decode (&string[1], (char *) &obj_id, OR_OID_SIZE);
2093  *object = ws_mop (&obj_id, NULL);
2094  break;
2097  /* decode vobj_len */
2098  or_decode (&string[1], (char *) &vobj_len, OR_INT_SIZE);
2099 
2100  /* decode vobj */
2101  or_decode (&string[1 + ENCODED_LEN (OR_INT_SIZE)], bufp, vobj_len);
2102 
2103  /* convert vobj into a db_object */
2104  or_init (&buf, bufp, vobj_len);
2105  if (cursor_copy_vobj_to_dbvalue (&buf, &val) != NO_ERROR)
2106  {
2107  *object = NULL;
2110  }
2111  else
2112  {
2113  *object = db_get_object (&val);
2114  }
2115  break;
2116  default:
2117  *object = NULL;
2120  break;
2121  }
2122 
2123  if (!(*object) && rc == NO_ERROR)
2124  {
2126  rc = ER_OBJ_DELETED;
2127  }
2128  /* free any dynamically allocated buffer */
2129  if (bufp != vobj_buf)
2130  {
2131  free_and_init (bufp);
2132  }
2133 
2134  return rc;
2135 }
2136 
2137 /*
2138  * vid_flush_instance() - Update the object to the driver
2139  * return: WS_MAP_CONTINUE if all OK, WS_MAP_FAIL otherwise
2140  * mop(in): Memory Object pointer of object to flush
2141  * arg(in): nonzero iff caller wants mop decached after the flush
2142  */
2143 int
2144 vid_flush_instance (MOP mop, void *arg)
2145 {
2146  int rc = WS_MAP_CONTINUE, isvid, isdirty;
2147  bool isupdatable, isbase;
2148  VID_INFO *mop_vid_info;
2149 
2150  isvid = mop->is_vid;
2151  isdirty = mop->dirty;
2152  isupdatable = vid_is_updatable (mop);
2153  isbase = vid_is_base_instance (mop);
2154 
2155  if (!mop->is_vid)
2156  {
2157  return rc;
2158  }
2159 
2160  if (isvid && isdirty)
2161  {
2162  if (isupdatable && isbase)
2163  {
2164  ws_clean (mop);
2165  if (mop->is_vid)
2166  {
2167  mop_vid_info = mop->oid_info.vid_info;
2168  if (mop_vid_info)
2169  {
2170  mop_vid_info->flags &= ~VID_NEW;
2171  }
2172  }
2173  }
2174 
2175  if (arg)
2176  {
2177  bool decache = *(bool *) arg;
2178  if (decache)
2179  {
2180  ws_decache (mop);
2181  }
2182  }
2183  }
2184 
2185  return rc;
2186 }
LC_FETCH_VERSION_TYPE
Definition: locator.h:178
MOP ws_vmop(MOP class_mop, int flags, DB_VALUE *keys)
Definition: work_space.c:754
#define ER_HEAP_UNKNOWN_CLASS_OF_INSTANCE
Definition: error_code.h:103
#define ER_WS_REHASH_VMOP_ERROR
Definition: error_code.h:924
void ws_clean(MOP op)
Definition: work_space.c:1681
#define WS_IS_DELETED(mop)
Definition: work_space.h:284
#define NO_ERROR
Definition: error_code.h:46
int cursor_copy_vobj_to_dbvalue(struct or_buf *buffer_p, DB_VALUE *value_p)
Definition: cursor.c:334
int db_value_put_null(DB_VALUE *value)
Definition: db_macro.c:122
DB_COLLECTION * db_get_set(const DB_VALUE *value)
MOBJ vid_fetch_instance(MOP mop, DB_FETCH_MODE purpose, LC_FETCH_VERSION_TYPE read_fetch_version_type)
int pr_data_writeval_disk_size(DB_VALUE *value)
char * obj_alloc(SM_CLASS *class_, int bound_bit_status)
static char * vid_pack_db_value(char *lbuf, DB_VALUE *dbval)
PR_TYPE * tp_Type_id_map[]
#define ER_WS_PIN_VIOLATION
Definition: error_code.h:405
const char * db_get_class_name(DB_OBJECT *class_)
Definition: db_info.c:608
MOP ws_mop(const OID *oid, MOP class_mop)
Definition: work_space.c:614
int data_writeval(struct or_buf *buf, const DB_VALUE *value) const
enum au_fetchmode AU_FETCHMODE
DB_ATTRIBUTE * db_get_attributes(DB_OBJECT *obj)
Definition: db_info.c:908
#define ER_SM_INVALID_ARGUMENTS
Definition: error_code.h:319
DB_OBJECT * db_real_instance(DB_OBJECT *obj)
Definition: db_virt.c:247
char * MOBJ
Definition: work_space.h:174
DB_SET * db_seq_create(MOP classop, const char *name, int size)
Definition: db_set.c:252
#define TP_IS_SET_TYPE(typenum)
#define ER_OBJ_CANT_ENCODE_VOBJ
Definition: error_code.h:952
int db_seq_get(DB_SET *set, int index, DB_VALUE *value)
Definition: db_set.c:712
void ws_dirty(MOP op)
Definition: work_space.c:1622
DB_TYPE
Definition: dbtype_def.h:670
int tp_value_equal(const DB_VALUE *value1, const DB_VALUE *value2, int do_coercion)
void ws_mark_deleted(MOP mop)
Definition: work_space.c:3081
bool vid_compare_non_updatable_objects(MOP mop1, MOP mop2)
#define ER_FAILED
Definition: error_code.h:47
DB_IDENTIFIER oid
Definition: dbtype_def.h:1068
int db_seq_put(DB_SET *set, int index, DB_VALUE *value)
Definition: db_set.c:745
#define ER_VID_LOST_NON_UPDATABLE_OBJECT
Definition: error_code.h:703
TP_DOMAIN * domain
Definition: class_object.h:444
#define ER_SM_OBJECT_NOT_UPDATABLE
Definition: error_code.h:572
VID_INFO * vid_info
Definition: work_space.h:64
int classobj_get_prop(DB_SEQ *properties, const char *name, DB_VALUE *pvalue)
DB_OBJLIST * ml_ext_alloc_link(void)
Definition: work_space.c:4777
int obj_assign_value(MOP op, SM_ATTRIBUTE *att, char *mem, DB_VALUE *value)
SM_ATTRIBUTE * attributes
Definition: class_object.h:721
int db_query_end(DB_QUERY_RESULT *result)
Definition: db_query.c:3362
static int vid_make_vid(OID *view_id, OID *proxy_id, DB_VALUE *val, DB_VALUE *vobj)
int db_make_object(DB_VALUE *value, DB_C_OBJECT *obj)
#define ER_OBJ_BUFFER_TOO_SMALL
Definition: error_code.h:944
DB_COLLECTION * set_create_sequence(int size)
Definition: set_object.c:2432
SM_CLASS_TYPE
Definition: class_object.h:289
int db_is_any_class(MOP obj)
Definition: db_info.c:356
static int class_type(DB_OBJECT *class_obj)
Definition: cas_execute.c:8143
int vid_oid_to_object(const DB_VALUE *value, DB_OBJECT **mop)
SM_CLASS_TYPE sm_get_class_type(SM_CLASS *class_)
OID * ws_oid(MOP mop)
Definition: work_space.c:2884
int vid_flush_and_rehash(MOP mop)
struct sm_component * next
Definition: class_object.h:384
#define OID_SET_NULL(oidp)
Definition: oid.h:85
#define SM_PROPERTY_VID_KEY
#define ER_WS_NO_CLASS_FOR_INSTANCE
Definition: error_code.h:403
int db_make_sequence(DB_VALUE *value, DB_C_SET *set)
void vid_get_keys(MOP mop, DB_VALUE *value)
int vid_object_to_vobj(const DB_OBJECT *obj, DB_VALUE *vobj)
#define ER_OBJ_DELETED
Definition: error_code.h:947
int er_errid(void)
DB_VALUE * vid_flush_and_rehash_lbl(DB_VALUE *value)
static int vid_get_class_object(MOP class_p, SM_CLASS **class_object_p)
int set_size(DB_COLLECTION *set)
Definition: set_object.c:3036
#define er_log_debug(...)
int getmem(void *memptr, const tp_domain *domain, DB_VALUE *value, bool copy=true) const
MOP locator_add_instance(MOBJ instance, MOP class_mop)
Definition: locator_cl.c:5782
PR_TYPE * tp_Type_object
void db_ws_free(void *ptr)
Definition: quick_fit.c:194
int ws_map_class(MOP class_op, MAPFUNC function, void *args)
Definition: work_space.c:2118
const char * db_attribute_name(DB_ATTRIBUTE *attribute)
Definition: db_info.c:1065
#define MAX_ALIGNMENT
Definition: memory_alloc.h:70
DB_VALUE keys
Definition: work_space.h:49
bool vid_att_in_obj_id(SM_ATTRIBUTE *attribute_p)
#define ER_DL_ESYS
Definition: error_code.h:463
#define ER_OBJ_CANT_ENCODE_NONUPD_OBJ
Definition: error_code.h:951
DB_DOMAIN_INFO domain
Definition: dbtype_def.h:1082
#define ER_OBJ_CANT_RESOLVE_VOBJ_TO_OBJ
Definition: error_code.h:950
static DB_OBJECT * is_class(OID *obj_oid, OID *class_oid)
Definition: compactdb.c:637
LOCK
bool pr_is_set_type(DB_TYPE type)
DB_DATA data
Definition: dbtype_def.h:1083
bool vid_inhibit_null_check
static int vid_db_value_size(DB_VALUE *dbval)
#define ER_OBJ_NULL_ADDR_OUTPUT_OBJ
Definition: error_code.h:953
#define WS_CLASS_MOP(mop)
Definition: work_space.h:296
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
void or_decode(const char *buffer, char *dest, int size)
Definition: db_set.h:35
int db_set_get(DB_SET *set, int index, DB_VALUE *value)
Definition: db_set.c:508
DB_OBJLIST * vid_getall_mops(MOP class_mop, SM_CLASS *class_p, DB_FETCH_MODE purpose)
#define assert(x)
#define ER_GENERIC_ERROR
Definition: error_code.h:49
int vid_decode_object(const char *string, DB_OBJECT **object)
static int vid_is_new_oobj(MOP mop)
int proxy_id
Definition: shard_proxy.c:45
void obj_free_memory(SM_CLASS *class_, MOBJ obj)
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
int db_seq_size(DB_SET *set)
Definition: db_set.c:848
int vid_encode_object(DB_OBJECT *object, char *string, int allocated_length, int *actual_length)
#define OID_ISTEMP(oidp)
Definition: oid.h:80
#define DB_VALUE_DOMAIN_TYPE(value)
Definition: dbtype.h:70
bool vid_is_base_instance(MOP mop)
DB_ATTRIBUTE * db_attribute_next(DB_ATTRIBUTE *attribute)
Definition: db_info.c:1020
DB_OBJECT * db_get_object(const DB_VALUE *value)
VID_OID oid_info
Definition: work_space.h:120
int db_query_get_tuple_value_by_name(DB_QUERY_RESULT *result, char *column_name, DB_VALUE *value)
Definition: db_query.c:2959
MOP ws_class_mop(MOP mop)
Definition: work_space.c:2907
#define TP_DOMAIN_TYPE(dom)
bool mq_is_updatable(DB_OBJECT *class_object)
#define NULL
Definition: freelistheap.h:34
OID oid
Definition: work_space.h:65
#define MIN_STRING_OID_LENGTH
LOCK ws_get_lock(MOP mop)
Definition: work_space.c:2942
int db_is_class(MOP obj)
Definition: db_info.c:310
DB_OBJECT * db_get_class(MOP obj)
Definition: db_info.c:589
DB_OBJLIST * ws_Resident_classes
Definition: work_space.c:97
struct pr_type * type
Definition: class_object.h:443
#define ER_OBJ_CANT_ASSIGN_OID
Definition: error_code.h:945
#define ER_OBJ_VOBJ_MAPS_INVALID_OBJ
Definition: error_code.h:949
int vid_flush_all_instances(MOP class_mop, bool decache)
int db_set_add(DB_SET *set, DB_VALUE *value)
Definition: db_set.c:465
int au_fetch_instance_force(MOP op, MOBJ *obj_ptr, AU_FETCHMODE fetchmode, LC_FETCH_VERSION_TYPE fetch_version_type)
#define TM_TRAN_READ_FETCH_VERSION()
#define DONT_DECACHE
Definition: locator_cl.h:49
DB_VALUE_COMPARE_RESULT set_compare(DB_COLLECTION *set1, DB_COLLECTION *set2, int do_coercion)
Definition: set_object.c:3411
void or_init(OR_BUF *buf, char *data, int length)
LOCK lock
Definition: work_space.h:134
const OID oid_Null_oid
Definition: oid.c:68
MOP vid_get_referenced_mop(MOP mop)
need_clear_type need_clear
Definition: dbtype_def.h:1084
struct db_objlist * next
Definition: dbtype_def.h:442
int vid_allflush(void)
int db_set_size(DB_SET *set)
Definition: db_set.c:557
int pr_clear_value(DB_VALUE *value)
int db_fetch_list(DB_OBJLIST *objects, DB_FETCH_MODE purpose, int quit_on_error)
Definition: db_admin.c:2254
int vid_vobj_to_object(const DB_VALUE *vobj, DB_OBJECT **mop)
DB_SEQ * properties
Definition: class_object.h:457
int db_is_updatable_object(DB_OBJECT *obj)
Definition: db_virt.c:342
#define DB_DEFAULT_SCALE
Definition: dbtype_def.h:561
struct db_domain_info::general_info general_info
static int vid_pack_vobj(char *buf, OID *view, OID *proxy, DB_VALUE *keys, int *vobj_size, int buflen)
#define ER_OBJ_INVALID_ARGUMENT
Definition: error_code.h:946
struct db_object * op
Definition: dbtype_def.h:443
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
void ws_set_lock(MOP mop, LOCK lock)
Definition: work_space.c:2954
unsigned int flags
Definition: class_object.h:459
static int rc
Definition: serial.c:50
#define DB_DEFAULT_PRECISION
Definition: dbtype_def.h:558
entry_workpool * instance
bool vid_is_updatable(MOP mop)
unsigned int flags
Definition: work_space.h:48
int db_query_next_tuple(DB_QUERY_RESULT *result)
Definition: db_query.c:2088
OID * locator_assign_permanent_oid(MOP mop)
Definition: locator_cl.c:6084
static int vid_build_non_upd_object(MOP mop, DB_VALUE *seq)
unsigned dirty
Definition: work_space.h:144
#define ARG_FILE_LINE
Definition: error_manager.h:44
int pr_clone_value(const DB_VALUE *src, DB_VALUE *dest)
void ws_decache(MOP mop)
Definition: work_space.c:2701
OID * db_get_oid(const DB_VALUE *value)
#define WS_OID(mop)
Definition: work_space.h:293
MOP vid_add_virtual_instance(MOBJ instance, MOP vclass_mop, MOP bclass_mop, SM_CLASS *bclass)
int vid_flush_instance(MOP mop, void *arg)
void * object
Definition: work_space.h:123
#define free_and_init(ptr)
Definition: memory_alloc.h:147
#define DB_ALIGN(offset, align)
Definition: memory_alloc.h:84
#define strlen(s1)
Definition: intl_support.c:43
void vid_rem_instance(MOP mop)
SM_COMPONENT header
Definition: class_object.h:441
#define ER_OBJ_INVALID_ARGUMENTS
Definition: error_code.h:275
#define ER_HEAP_UNKNOWN_OBJECT
Definition: error_code.h:102
#define DB_CURSOR_SUCCESS
Definition: dbtype_def.h:166
int db_get(DB_OBJECT *object, const char *attpath, DB_VALUE *value)
Definition: db_obj.c:233
void ml_ext_free(DB_OBJLIST *list)
Definition: work_space.c:4806
#define ER_SM_OBJECT_ID_ALREADY_SET
Definition: error_code.h:570
SM_CLASS_TYPE class_type
Definition: class_object.h:713
LOCK lock_Conv[12][12]
Definition: lock_table.c:179
MOP vid_build_virtual_mop(MOP bmop, MOP vclass_mop)
#define DB_VALUE_TYPE(value)
Definition: dbtype.h:72
int i
Definition: dynamic_load.c:954
int db_make_null(DB_VALUE *value)
DB_TYPE id
MOP vid_base_instance(MOP mop)
void vid_decache_instance(MOP mop)
void or_encode(char *buffer, const char *source, int size)
DB_SEQ * classobj_make_prop()
Definition: class_object.c:280
DB_FETCH_MODE
Definition: dbtype_def.h:215
int db_value_clear(DB_VALUE *value)
Definition: db_macro.c:1588
int db_make_int(DB_VALUE *value, const int num)
int db_make_oid(DB_VALUE *value, const OID *oid)
#define OID_ISNULL(oidp)
Definition: oid.h:81
unsigned pinned
Definition: work_space.h:147
#define ER_OBJ_INTERNAL_ERROR_IN_DECODING
Definition: error_code.h:954
int ws_find(MOP mop, MOBJ *obj)
Definition: work_space.c:3112
int db_compile_and_execute_local(const char *CSQL_query, void *result, DB_QUERY_ERROR *query_error)
Definition: db_vdb.c:3068
#define MAX_STRING_OID_LENGTH
int db_set_cardinality(DB_SET *set)
Definition: db_set.c:578
MOBJ vid_upd_instance(MOP mop)
#define ER_SM_INVALID_CLASS
Definition: error_code.h:365
int ws_has_dirty_objects(MOP op, int *isvirt)
Definition: work_space.c:3752
int vid_is_new_pobj(MOP mop)
int set_convert_oids_to_objects(DB_COLLECTION *set)
Definition: set_object.c:3273
bool ws_rehash_vmop(MOP mop, MOBJ classobj, DB_VALUE *newkey)
Definition: work_space.c:899
int au_fetch_class_force(MOP op, SM_CLASS **class_, AU_FETCHMODE fetchmode)
#define ENCODED_LEN(siz)
int vid_make_vobj(const OID *view_oid, const OID *class_oid, const DB_VALUE *keys, DB_VALUE *vobj)
int db_query_tuple_count(DB_QUERY_RESULT *result)
Definition: db_query.c:3089
int db_value_domain_init(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale)
Definition: db_macro.c:153
int classobj_put_prop(DB_SEQ *properties, const char *name, DB_VALUE *pvalue)
Definition: class_object.c:314
unsigned is_vid
Definition: work_space.h:148
int db_value_alter_type(DB_VALUE *value, const DB_TYPE type)
Definition: db_macro.c:1225