CUBRID Engine  latest
object_template.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  * object_template.c - Object template module
21  *
22  * This contains code for attribute and method access, instance creation
23  * and deletion, and misc utilitities related to instances.
24  *
25  */
26 
27 #ident "$Id$"
28 
29 #include "config.h"
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <stdarg.h>
36 #include <assert.h>
37 
38 #include "db.h"
39 #include "dbtype.h"
40 #include "error_manager.h"
41 #include "system_parameter.h"
42 #include "server_interface.h"
43 #include "work_space.h"
44 #include "object_domain.h"
45 #include "object_primitive.h"
46 #include "object_representation.h"
47 #include "set_object.h"
48 #include "class_object.h"
49 #include "schema_manager.h"
50 #include "object_accessor.h"
51 #include "view_transform.h"
52 #include "authenticate.h"
53 #include "locator_cl.h"
54 #include "virtual_object.h"
55 #include "parser.h"
56 #include "transaction_cl.h"
57 #include "trigger_manager.h"
58 #include "environment_variable.h"
59 #include "transform.h"
60 #include "execute_statement.h"
61 #include "network_interface_cl.h"
62 
63 #include "dbtype.h"
64 
65 #define OBJ_INTERNAL_SAVEPOINT_NAME "*template-unique*"
66 
67 /*
68  * GLOBAL VARIABLES
69  */
70 /*
71  * State used when creating templates, to indicate whether unique constraint
72  * checking is enabled.
73  * This state can be modifed using obt_enable_unique_checking()
74  */
75 bool obt_Check_uniques = true;
76 
77 /*
78  * State variable used when creating object template, to indicate whether enable
79  * auto increment feature
80  */
82 
83 /*
84  * State variable used when generating AUTO_INCREMENT value,
85  * to set the first generated AUTO_INCREMENT value as LAST_INSERT_ID.
86  * It is only for client-side insertion.
87  */
89 
90 /*
91  * OBJECT MANAGER AREAS
92  */
93 
94 /*
95  * Template_area
96  * Assignment_area
97  *
98  * Note :
99  * Areas for the allocation of object templates and assignment
100  * templates. Since these can be referenced by the interpreter,
101  * we need to make sure that they serve as roots for the garbage
102  * collector.
103  *
104  */
105 
108 
109 /*
110  * obj_Template_traversal
111  *
112  *
113  */
114 
115 static unsigned int obj_Template_traversal = 0;
116 /*
117  * Must make sure template savepoints have unique names to allow for concurrent
118  * or nested updates. Could be resetting this at db_restart() time.
119  */
120 static unsigned int template_savepoint_count = 0;
121 
122 
123 static DB_VALUE *check_att_domain (SM_ATTRIBUTE * att, DB_VALUE * proposed_value);
124 static int check_constraints (SM_ATTRIBUTE * att, DB_VALUE * value, unsigned force_check_not_null);
125 static int quick_validate (SM_VALIDATION * valid, DB_VALUE * value);
126 static void cache_validation (SM_VALIDATION * valid, DB_VALUE * value);
127 static void begin_template_traversal (void);
128 static OBJ_TEMPLATE *make_template (MOP object, MOP classobj);
129 static int validate_template (OBJ_TEMPLATE * temp);
130 static OBJ_TEMPASSIGN *obt_make_assignment (OBJ_TEMPLATE * template_ptr, SM_ATTRIBUTE * att);
131 static void obt_free_assignment (OBJ_TEMPASSIGN * assign);
132 static void obt_free_template (OBJ_TEMPLATE * template_ptr);
133 static int populate_auto_increment (OBJ_TEMPLATE * template_ptr);
134 static int populate_defaults (OBJ_TEMPLATE * template_ptr);
135 static int obt_assign_obt (OBJ_TEMPLATE * template_ptr, SM_ATTRIBUTE * att, int base_assignment, OBJ_TEMPLATE * value);
136 static MOP create_template_object (OBJ_TEMPLATE * template_ptr);
137 static int access_object (OBJ_TEMPLATE * template_ptr, MOP * object, MOBJ * objptr);
138 static int obt_convert_set_templates (SETREF * setref, int check_uniques);
139 static int obt_final_check_set (SETREF * setref, int *has_uniques);
140 
141 static int obt_final_check (OBJ_TEMPLATE * template_ptr, int check_non_null, int *has_uniques);
142 static int obt_apply_assignment (MOP op, SM_ATTRIBUTE * att, char *mem, DB_VALUE * value, int check_uniques);
143 static int obt_apply_assignments (OBJ_TEMPLATE * template_ptr, int check_uniques, int level);
144 
145 static MOP make_temp_object (DB_OBJECT * class_, OBJ_TEMPLATE * object);
146 static void free_temp_object (MOP obj);
147 
148 /*
149  * obt_area_init
150  * return: NO_ERROR or error code.
151  *
152  */
153 
154 int
156 {
157  Template_area = area_create ("Object templates", sizeof (OBJ_TEMPLATE), 32);
158  if (Template_area == NULL)
159  {
160  goto error;
161  }
162 
163  Assignment_area = area_create ("Assignment templates", sizeof (OBJ_TEMPASSIGN), 64);
164  if (Assignment_area == NULL)
165  {
166  goto error;
167  }
168 
169  return NO_ERROR;
170 
171 error:
172  obt_area_final ();
173 
174  assert (er_errid () != NO_ERROR);
175 
176  return er_errid ();
177 }
178 
179 /*
180  * obt_area_final
181  * return: NO_ERROR or error code.
182  *
183  */
184 void
186 {
187  if (Template_area != NULL)
188  {
189  area_destroy (Template_area);
190  Template_area = NULL;
191  }
192 
193  if (Assignment_area != NULL)
194  {
195  area_destroy (Assignment_area);
196  Assignment_area = NULL;
197  }
198 }
199 
200 /*
201  * obt_find_attribute - locate an attribute for a template.
202  * return: error code
203  * template(in) :
204  * use_base_class(in) :
205  * name(in): attribute name
206  * attp(out): returned pointer to attribute descriptor
207  *
208  * Note:
209  * This is a bit simpler than the others since we have the class
210  * cached in the template.
211  *
212  */
213 
214 int
215 obt_find_attribute (OBJ_TEMPLATE * template_ptr, int use_base_class, const char *name, SM_ATTRIBUTE ** attp)
216 {
217  int error = NO_ERROR;
218  MOP classobj;
219  SM_CLASS *class_, *upgrade_class;
220  SM_ATTRIBUTE *att;
221 
222  att = NULL;
223 
224  class_ = (use_base_class) ? template_ptr->base_class : template_ptr->class_;
225 
226  att = classobj_find_attribute (class_, name, template_ptr->is_class_update);
227 
228  if (att != NULL && att->header.name_space == ID_SHARED_ATTRIBUTE)
229  {
230  /*
231  * Sigh, when we originally fetched the class, it was fetched
232  * with a read lock since we weren't sure of the intent. Now
233  * that we know we're about to update a shared attribute, we need to
234  * upgrade the lock to a write lock. We could use AU_FETCH_WRITE
235  * here rather than AU_FETCH_UPDATE and use locator_update_class later
236  * when we're sure the template can be applied without error.
237  */
238  if (!template_ptr->write_lock)
239  {
240  classobj = ((use_base_class) ? template_ptr->base_classobj : template_ptr->classobj);
241 
242  error = au_fetch_class (classobj, &upgrade_class, AU_FETCH_UPDATE, AU_ALTER);
243  template_ptr->write_lock = !error;
244 
245  /*
246  * This better damn well not re-fetch the class.
247  * If this can happen, we'll need a general "recache" function
248  * for the template.
249  */
250  if (class_ != upgrade_class)
251  {
252  error = ER_OBJ_TEMPLATE_INTERNAL;
254  }
255  }
256  }
257 
258  if (error == NO_ERROR && att == NULL)
259  {
260  ERROR1 (error, ER_OBJ_INVALID_ATTRIBUTE, name);
261  }
262 
263  *attp = att;
264  return error;
265 }
266 
267 /*
268  *
269  * ASSIGNMENT VALIDATION
270  *
271  *
272  */
273 
274 /*
275  * check_att_domain - This checks to see if a value is within the domain of an
276  * attribute.
277  *
278  * returns: actual value container
279  * att(in): attribute name (for error messages)
280  * proposed_value(in): original value container
281  *
282  * Note:
283  * It calls tp_domain_check & tp_domain_coerce to do the work, this
284  * function mostly serves to inerpret the return codes and set an
285  * appropriate error condition.
286  *
287  */
288 
289 static DB_VALUE *
290 check_att_domain (SM_ATTRIBUTE * att, DB_VALUE * proposed_value)
291 {
292  TP_DOMAIN_STATUS status;
293  DB_VALUE *value;
294  int is_ref = 0;
295 
296  value = proposed_value;
297 
298  is_ref = pt_is_reference_to_reusable_oid (value);
299  if (is_ref < 0)
300  {
301  return NULL;
302  }
303  if (is_ref > 0)
304  {
306  return NULL;
307  }
308 
309  /*
310  * Note that we set the "exact" match flag true to disallow "tolerance"
311  * matches. Some types (such as CHAR) may appear to overflow the domain,
312  * but can be truncated during the coercion process.
313  */
314  status = tp_domain_check (att->domain, value, TP_EXACT_MATCH);
315 
316  if (status != DOMAIN_COMPATIBLE)
317  {
318  value = pr_make_ext_value ();
319  if (value == NULL)
320  {
321  return NULL;
322  }
323  status = tp_value_cast (proposed_value, value, att->domain, !TP_IS_CHAR_TYPE (TP_DOMAIN_TYPE (att->domain)));
324  if (status != DOMAIN_COMPATIBLE)
325  {
326  (void) pr_free_ext_value (value);
327  }
328  }
329 
330  if (status != DOMAIN_COMPATIBLE)
331  {
332  switch (status)
333  {
334  case DOMAIN_ERROR:
335  /* error has already been set */
336  break;
337  case DOMAIN_OVERFLOW:
338  if (TP_IS_BIT_TYPE (DB_VALUE_DOMAIN_TYPE (proposed_value)))
339  {
341  att->domain->precision);
342  }
343  else
344  {
345  (void) tp_domain_status_er_set (status, ARG_FILE_LINE, proposed_value, att->domain);
346  assert (er_errid () != NO_ERROR);
347  }
348  break;
349  case DOMAIN_INCOMPATIBLE:
350  default:
351  /*
352  * the default case shouldn't really be encountered, might want to
353  * signal a different error. The OVERFLOW case should only
354  * be returned during coercion which wasn't requested, to be safe,
355  * treat these like a domain conflict. Probably need a more generic
356  * domain conflict error that uses full printed representations
357  * of the entire domain.
358  */
360  break;
361  }
362 
363  /* return NULL if incompatible */
364  value = NULL;
365  }
366 
367  return value;
368 }
369 
370 /*
371  * check_constraints - This function is used to check a proposed value
372  * against the integrity constraints defined
373  * for an attribute.
374  *
375  * returns: error code
376  *
377  * att(in): attribute descriptor
378  * value(in): value to verify
379  * force_check_not_null(in): force NOT NULL constraint check
380  *
381  * Note:
382  * If will return an error code if any of the constraints are violated.
383  *
384  */
385 
386 static int
387 check_constraints (SM_ATTRIBUTE * att, DB_VALUE * value, unsigned force_check_not_null)
388 {
389  int error = NO_ERROR;
390  MOP mop;
391 
392  /* check NOT NULL constraint */
393  if (value == NULL || DB_IS_NULL (value)
394  || (att->domain->type == tp_Type_object && (mop = db_get_object (value)) && WS_MOP_IS_NULL (mop)))
395  {
396  if (att->flags & SM_ATTFLAG_NON_NULL)
397  {
398  if ((att->flags & SM_ATTFLAG_AUTO_INCREMENT) && !force_check_not_null)
399  {
400  assert (DB_IS_NULL (value));
401  assert (att->domain->type != tp_Type_object);
402 
403  /* This is allowed to happen only during INSERT statements, since the next serial value will be filled in
404  * at a later time. For other cases, the force_check_not_null flag should be set. */
405  }
406  else
407  {
409  }
410  }
411  }
412  else
413  {
414  /* Check size constraints */
415  if (tp_check_value_size (att->domain, value) != DOMAIN_COMPATIBLE)
416  {
417  /* probably need an error message that isn't specific to "string" types */
419  }
420  }
421 
422  return error;
423 }
424 
425 /*
426  * quick_validate - This function is where we try to determine as fast as
427  * possible if a value is compatible with
428  * a certain attribute's domain.
429  * returns: non-zero if the value is known to be valid
430  * valid(in): validation cache
431  * value(in): value to ponder
432  */
433 
434 static int
436 {
437  int is_valid;
438  DB_TYPE type;
439 
440  if (valid == NULL || value == NULL)
441  return 0;
442 
443  is_valid = 0;
444  type = DB_VALUE_TYPE (value);
445 
446  switch (type)
447  {
448  case DB_TYPE_OBJECT:
449  {
450  DB_OBJECT *obj, *class_;
451 
452  obj = db_get_object (value);
453  if (obj != NULL)
454  {
455  class_ = db_get_class (obj);
456  if (class_ != NULL)
457  {
458  if (class_ == valid->last_class)
459  {
460  is_valid = 1;
461  }
462  else
463  {
464  /* wasn't on the first level cache, check the list */
465  is_valid = ml_find (valid->validated_classes, class_);
466  /* if its on the list, auto select this for the next time around */
467  if (is_valid)
468  {
469  valid->last_class = class_;
470  }
471  }
472  }
473  }
474  }
475  break;
476 
477  case DB_TYPE_SET:
478  case DB_TYPE_MULTISET:
479  case DB_TYPE_SEQUENCE:
480  {
481  DB_SET *set;
482  DB_DOMAIN *domain;
483 
484  set = db_get_set (value);
485  domain = set_get_domain (set);
486  if (domain == valid->last_setdomain)
487  {
488  is_valid = 1;
489  }
490  }
491  break;
492 
493  case DB_TYPE_CHAR:
494  case DB_TYPE_NCHAR:
495  case DB_TYPE_VARCHAR:
496  case DB_TYPE_VARNCHAR:
497  if (type == valid->last_type && DB_GET_STRING_PRECISION (value) == valid->last_precision)
498  {
499  is_valid = 1;
500  }
501  break;
502 
503  case DB_TYPE_BIT:
504  case DB_TYPE_VARBIT:
505  if (type == valid->last_type && DB_GET_BIT_PRECISION (value) == valid->last_precision)
506  {
507  is_valid = 1;
508  }
509  break;
510 
511  case DB_TYPE_NUMERIC:
512  if (type == valid->last_type && DB_GET_NUMERIC_PRECISION (value) == valid->last_precision
513  && DB_GET_NUMERIC_SCALE (value) == valid->last_scale)
514  {
515  is_valid = 1;
516  }
517  break;
518 
519  default:
520  if (type == valid->last_type)
521  {
522  is_valid = 1;
523  }
524  break;
525  }
526 
527  return is_valid;
528 }
529 
530 /*
531  * cache_validation
532  * return : none
533  * valid(in): validation cache
534  * value(in): value known to be good
535  *
536  * Note:
537  * Caches information about the data value in the validation cache
538  * so hopefully we'll be quicker about validating values of this
539  * form if we find them again.
540  *
541  */
542 
543 static void
545 {
546  DB_TYPE type;
547 
548  if (valid == NULL || value == NULL)
549  {
550  return;
551  }
552 
553  type = DB_VALUE_TYPE (value);
554  switch (type)
555  {
556  case DB_TYPE_OBJECT:
557  {
558  DB_OBJECT *obj, *class_;
559 
560  obj = db_get_object (value);
561  if (obj != NULL)
562  {
563  class_ = db_get_class (obj);
564  if (class_ != NULL)
565  {
566  valid->last_class = class_;
567  /*
568  * !! note that we have to be building an external object list
569  * here so these serve as GC roots. This is kludgey, we should
570  * be encapsulating structure rules inside cl_ where the
571  * SM_VALIDATION is allocated.
572  */
573  (void) ml_ext_add (&valid->validated_classes, class_, NULL);
574  }
575  }
576  }
577  break;
578 
579  case DB_TYPE_SET:
580  case DB_TYPE_MULTISET:
581  case DB_TYPE_SEQUENCE:
582  {
583  DB_SET *set;
584 
585  set = db_get_set (value);
586  valid->last_setdomain = set_get_domain (set);
587  }
588  break;
589 
590  case DB_TYPE_CHAR:
591  case DB_TYPE_NCHAR:
592  case DB_TYPE_VARCHAR:
593  case DB_TYPE_VARNCHAR:
594  case DB_TYPE_BIT:
595  case DB_TYPE_VARBIT:
596  valid->last_type = type;
597  valid->last_precision = db_value_precision (value);
598  valid->last_scale = 0;
599  break;
600 
601  case DB_TYPE_NUMERIC:
602  valid->last_type = type;
603  valid->last_precision = db_value_precision (value);
604  valid->last_scale = db_value_scale (value);
605  break;
606 
607  default:
608  valid->last_type = type;
609  valid->last_precision = 0;
610  valid->last_scale = 0;
611  break;
612  }
613 }
614 
615 /*
616  * obt_check_assignment - This is the main validation routine
617  * for attribute assignment.
618  * returns: value container
619  * att(in): attribute descriptor
620  * proposed_value(in): value to assign
621  * valid(in):
622  * force_check_not_null(in): force check for NOT NULL
623  * constraints
624  *
625  *
626  * Note:
627  * It is used both by the direct assignment function obj_set and also
628  * by object templates (which do grouped assignments). Any other function
629  * that does attribute value assignment should also use this function
630  * or be VERY careful about the rules contained here.
631  * The check_unique flag is normally turned on only if we're building
632  * an object template because we have to check for constraint violation
633  * before allowing the rest of the template to be built. For immediate
634  * attribute assignment (not using templates) we delay the checking for
635  * unique constraints until later (in assign_value) so we only have to
636  * do one server call instead of two. Would be nice if templates could
637  * have a way to "batch up" their unique attribute checks.
638  * This function will return NULL if an error was detected.
639  * It will return the propsed_value pointer if the assignment is
640  * acceptable.
641  * It will return a new value container if the proposed_value wasn't
642  * acceptable but it was coerceable to a valid value.
643  * The caller must check to see if the returned value is different
644  * and if so free it with pr_free_ext_value() when done.
645  *
646  */
647 
648 DB_VALUE *
649 obt_check_assignment (SM_ATTRIBUTE * att, DB_VALUE * proposed_value, SM_VALIDATION * valid,
650  unsigned force_check_not_null)
651 {
652  DB_VALUE *value;
653 
654  /* assume this will be ok */
655  value = proposed_value;
656 
657  /* for simplicity, convert this into a container with a NULL type */
658  if (value == NULL)
659  {
660  value = pr_make_ext_value ();
661  }
662  else
663  {
664  /*
665  * before we make the expensive checks, see if we've got some cached
666  * validation information handy
667  */
668  if (!quick_validate (valid, value))
669  {
670  value = check_att_domain (att, proposed_value);
671  if (value != NULL)
672  {
673  if (check_constraints (att, value, force_check_not_null) != NO_ERROR)
674  {
675  if (value != proposed_value)
676  {
677  (void) pr_free_ext_value (value);
678  }
679  value = NULL;
680  }
681  else
682  {
683  /*
684  * we're ok, if there was no coercion required, remember this for
685  * next time.
686  */
687  if (value == proposed_value)
688  {
689  cache_validation (valid, proposed_value);
690  }
691  }
692  }
693  }
694  }
695 
696  return value;
697 }
698 
699 /*
700  *
701  * OBJECT TEMPLATE ASSIGNMENT
702  *
703  *
704  */
705 
706 
707 /*
708  * begin_template_traversal - This "allocates" the traversal counter
709  * for a new template traversal.
710  * return : none
711  *
712  * Note :
713  * obj_Template_traversal is set to this value so it can
714  * be tested during traversal.
715  * This is in a function just so that the rules for skipping a traversal
716  * value of zero can be encapsulated.
717  *
718  */
719 
720 static void
722 {
723  /* increment the counter */
725 
726  /* don't let it be zero */
727  if (obj_Template_traversal == 0)
728  {
730  }
731 }
732 
733 /*
734  * make_template - This initializes a new object template.
735  * return: new object template
736  * object(in): the object that the template is being created for
737  * classobj(in): the class of the object
738  *
739  */
740 
741 static OBJ_TEMPLATE *
742 make_template (MOP object, MOP classobj)
743 {
744  OBJ_TEMPLATE *template_ptr;
746  AU_TYPE auth;
747  SM_CLASS *class_, *base_class;
748  MOP base_classobj, base_object;
749  MOBJ obj;
750  OBJ_TEMPASSIGN **vec;
751 
752  base_classobj = NULL;
753  base_class = NULL;
754  base_object = NULL;
755 
756  /* fetch & lock the class with the appropriate options */
757  mode = AU_FETCH_READ;
758  if (object == NULL)
759  {
760  auth = AU_INSERT;
761  }
762  else if (object != classobj)
763  {
764  auth = AU_UPDATE;
765  }
766  else
767  {
768  /*
769  * class variable update
770  * NOTE: It might be good to use AU_FETCH_WRITE here and then
771  * use locator_update_class to set the dirty bit after the template
772  * has been successfully applied.
773  */
774  mode = AU_FETCH_UPDATE;
775  auth = AU_ALTER;
776  }
777 
778  if (au_fetch_class (classobj, &class_, mode, auth))
779  {
780  return NULL;
781  }
782 
783 
784  /*
785  * we only need to keep track of the base class if this is a
786  * virtual class, for proxies, the instances look like usual
787  */
788 
789  if (class_->class_type == SM_VCLASS_CT /* a view, and... */
790  && object != classobj /* we are not doing a meta class update */ )
791  {
792  /*
793  * could use vid_is_updatable() if
794  * the instance was supplied but since this can be NULL for
795  * insert templates, use mq_is_updatable on the class object instead.
796  * NOTE: Don't call this yet, try to use mq_fetch_one_real_class()
797  * to perform the updatability test.
798  */
799  if (!mq_is_updatable (classobj))
800  {
802  return NULL;
803  }
804 
805 
806  base_classobj = mq_fetch_one_real_class (classobj);
807  if (base_classobj == NULL)
808  {
810  return NULL;
811  }
812 
813  if (au_fetch_class (base_classobj, &base_class, AU_FETCH_READ, auth))
814  {
815  return NULL;
816  }
817 
818  /* get the associated base object (if this isn't a proxy) */
819  if (object != NULL && !vid_is_base_instance (object))
820  {
821  base_object = vid_get_referenced_mop (object);
822  }
823  }
824 
825  /*
826  * If this is an instance update, fetch & lock the instance.
827  * NOTE: It might be good to use AU_FETCH_WRITE and use locator_update_instance
828  * to set the dirty bit after the template has been successfully applied.
829  *
830  * If this is a virtual instance on a non-proxy, could be locking
831  * the associated instance as well. Is this already being done ?
832  */
833  if (object != NULL && object != classobj)
834  {
836  {
837  return NULL;
838  }
839 
840  /*
841  * Could cache the object memory pointer this in the template as
842  * well but that would require that it be pinned for a long
843  * duration through code that we don't control. Dangerous.
844  */
845  }
846 
847  template_ptr = (OBJ_TEMPLATE *) area_alloc (Template_area);
848  if (template_ptr != NULL)
849  {
850  template_ptr->object = object;
851  template_ptr->classobj = classobj;
852 
853  /*
854  * cache the class info directly in the template, will need
855  * to remember the transaction id and chn for validation
856  */
857  template_ptr->class_ = class_;
858 
859  /* cache the base class if this is a virtual class template */
860  template_ptr->base_classobj = base_classobj;
861  template_ptr->base_class = base_class;
862  template_ptr->base_object = base_object;
863 
864  template_ptr->tran_id = tm_Tran_index;
865  template_ptr->schema_id = sm_local_schema_version ();
866  template_ptr->assignments = NULL;
867  template_ptr->label = NULL;
868  template_ptr->traversal = 0;
869  template_ptr->write_lock = mode != AU_FETCH_READ;
870  template_ptr->traversed = 0;
871  template_ptr->is_old_template = 0;
872  template_ptr->is_class_update = (object == classobj);
873  template_ptr->check_uniques = obt_Check_uniques;
875  {
876  template_ptr->check_serializable_conflict = 1;
877  }
878  else
879  {
880  template_ptr->check_serializable_conflict = 0;
881  }
882  template_ptr->uniques_were_modified = 0;
883  template_ptr->function_key_modified = 0;
884 
885  template_ptr->shared_was_modified = 0;
886  template_ptr->discard_on_finish = 1;
887  template_ptr->fkeys_were_modified = 0;
888  template_ptr->force_check_not_null = 0;
889  template_ptr->force_flush = 0;
890  template_ptr->is_autoincrement_set = 0;
891  template_ptr->pruning_type = DB_NOT_PARTITIONED_CLASS;
892  /*
893  * Don't do this until we've initialized the other stuff;
894  * OTMPL_NASSIGNS relies on the "class" attribute of the template.
895  */
896 
897  if (template_ptr->is_class_update)
898  {
899  template_ptr->nassigns = template_ptr->class_->class_attribute_count;
900  }
901  else
902  {
903  template_ptr->nassigns = (template_ptr->class_->att_count + template_ptr->class_->shared_count);
904  }
905 
906  vec = NULL;
907  if (template_ptr->nassigns)
908  {
909  int i;
910 
911  vec = (OBJ_TEMPASSIGN **) malloc (template_ptr->nassigns * sizeof (OBJ_TEMPASSIGN *));
912  if (!vec)
913  {
914  return NULL;
915  }
916  for (i = 0; i < template_ptr->nassigns; i++)
917  {
918  vec[i] = NULL;
919  }
920  }
921 
922  template_ptr->assignments = vec;
923  }
924 
925  return template_ptr;
926 }
927 
928 /*
929  * validate_template - This is used to validate a template before each operation
930  * return: error code
931  * temp(in): template to validate
932  *
933  */
934 
935 static int
937 {
938  int error = NO_ERROR;
939 
940  if (temp != NULL && (temp->tran_id != tm_Tran_index || temp->schema_id != sm_local_schema_version ()))
941  {
942  error = ER_OBJ_INVALID_TEMPLATE;
944  }
945 
946  return error;
947 }
948 
949 /*
950  * obt_make_assignment - This initializes a new assignment template.
951  * return: template assignment structure
952  * template(in):
953  * att(in):
954  *
955  * Note:
956  * It also adds it to a containing template.
957  */
958 
959 static OBJ_TEMPASSIGN *
961 {
962  OBJ_TEMPASSIGN *assign;
963 
964  assign = (OBJ_TEMPASSIGN *) area_alloc (Assignment_area);
965  if (assign != NULL)
966  {
967  assign->obj = NULL;
968  assign->variable = NULL;
969  assign->att = att;
970  assign->old_value = NULL;
971  assign->is_default = 0;
972  assign->is_auto_increment = 0;
973 
974  template_ptr->assignments[att->order] = assign;
976  {
977  template_ptr->uniques_were_modified = 1;
978  }
980  {
981  template_ptr->shared_was_modified = 1;
982  }
983 
985  {
986  template_ptr->fkeys_were_modified = 1;
987  }
989  {
990  template_ptr->function_key_modified = 1;
991  }
992  }
993 
994  return assign;
995 }
996 
997 /*
998  * obt_free_assignment - Work function for obt_free_template.
999  * return: none
1000  * assign(in): an assignment template
1001  *
1002  * Note :
1003  * Frees an attribute assignment template. If the assigment contains
1004  * an object template rather than a DB_VALUE, it will be freed by
1005  * recursively calling obj_free_template.
1006  *
1007  */
1008 
1009 static void
1011 {
1012  DB_VALUE *value = NULL;
1013  SETREF *setref;
1014  int i, set_size;
1015 
1016  if (assign != NULL)
1017  {
1018  if (assign->variable != NULL)
1019  {
1020 
1021  DB_TYPE av_type;
1022 
1023  /* check for nested templates */
1024  av_type = DB_VALUE_TYPE (assign->variable);
1025  if (av_type == DB_TYPE_POINTER)
1026  {
1028  db_make_pointer (assign->variable, NULL);
1029  }
1030  else if (TP_IS_SET_TYPE (av_type) && db_get_set (assign->variable) != NULL)
1031  {
1032  /* must go through and free any elements that may be template pointers */
1033  setref = db_get_set (assign->variable);
1034  if (setref->set != NULL)
1035  {
1036  set_size = setobj_size (setref->set);
1037  for (i = 0; i < set_size; i++)
1038  {
1039  setobj_get_element_ptr (setref->set, i, &value);
1040  if (value != NULL && DB_VALUE_TYPE (value) == DB_TYPE_POINTER)
1041  {
1043  db_make_pointer (value, NULL);
1044  }
1045  }
1046  }
1047  }
1048 
1049  (void) pr_free_ext_value (assign->variable);
1050 
1051  if (assign->old_value != NULL)
1052  {
1053  (void) pr_free_ext_value (assign->old_value);
1054  }
1055  }
1056 
1057  (void) area_free (Assignment_area, assign);
1058  }
1059 }
1060 
1061 /*
1062  * obt_free_template - This frees a hierarchical object template.
1063  * return: none
1064  * template(in): object template
1065  *
1066  * Note :
1067  * It will be called by obt_update when the template has been applied
1068  * or can be called by obt_quit to abort the creation of the template.
1069  * Since the template can contain circular references, must be careful and
1070  * use a traversal flag in each template.
1071  *
1072  */
1073 
1074 static void
1076 {
1077  OBJ_TEMPASSIGN *a;
1078  int i;
1079 
1080  if (!template_ptr->traversed)
1081  {
1082  template_ptr->traversed = 1;
1083 
1084  for (i = 0; i < template_ptr->nassigns; i++)
1085  {
1086  a = template_ptr->assignments[i];
1087  if (a == NULL)
1088  {
1089  continue;
1090  }
1091 
1092  if (a->obj != NULL)
1093  {
1094  obt_free_template (a->obj);
1095  }
1096 
1097  obt_free_assignment (a);
1098  }
1099 
1100  if (template_ptr->assignments)
1101  {
1102  free_and_init (template_ptr->assignments);
1103  }
1104 
1105  (void) area_free (Template_area, template_ptr);
1106  }
1107 }
1108 
1109 /*
1110  * populate_auto_increment - This populates a template with the
1111  * auto_increment values for a class.
1112  * return: error code
1113  * template(in): template to fill out
1114  *
1115  * Note :
1116  * This is necessary for INSERT templates. The assignments are marked
1117  * so that if an assignment is later made to the template with the
1118  * same name. we don't generate an error because its ok to override
1119  * a auto increment value.
1120  * If an assignment is already found with the name, it is assumed
1121  * that an initial value has already been given.
1122  *
1123  */
1124 
1125 static int
1127 {
1128  SM_ATTRIBUTE *att;
1129  OBJ_TEMPASSIGN *a, *exists;
1130  SM_CLASS *class_;
1131  int error = NO_ERROR;
1132  DB_VALUE val;
1133  DB_DATA_STATUS data_status;
1134  char auto_increment_name[AUTO_INCREMENT_SERIAL_NAME_MAX_LENGTH];
1135  MOP serial_class_mop = NULL, serial_mop;
1136  DB_IDENTIFIER serial_obj_id;
1137  const char *class_name;
1138  int cached_num;
1139 
1140  if (template_ptr->is_class_update)
1141  {
1142  return error;
1143  }
1144 
1145  class_ = template_ptr->class_;
1146 
1147  for (att = class_->ordered_attributes; att != NULL; att = att->order_link)
1148  {
1149  if (!(att->flags & SM_ATTFLAG_AUTO_INCREMENT))
1150  {
1151  continue;
1152  }
1153 
1154  if (att->auto_increment == NULL)
1155  {
1156  if (serial_class_mop == NULL)
1157  {
1158  serial_class_mop = sm_find_class (CT_SERIAL_NAME);
1159  }
1160 
1161  class_name = sm_get_ch_name (att->class_mop);
1162  if (class_name == NULL)
1163  {
1164  assert (er_errid () != NO_ERROR);
1165  goto auto_increment_error;
1166  }
1167 
1168  /* get original class's serial object */
1169  SET_AUTO_INCREMENT_SERIAL_NAME (auto_increment_name, class_name, att->header.name);
1170  serial_mop = do_get_serial_obj_id (&serial_obj_id, serial_class_mop, auto_increment_name);
1171  if (serial_mop == NULL)
1172  {
1173  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OBJ_INVALID_ATTRIBUTE, 1, auto_increment_name);
1174  goto auto_increment_error;
1175  }
1176 
1177  att->auto_increment = serial_mop;
1178  }
1179 
1180  exists = template_ptr->assignments[att->order];
1181  if (exists != NULL)
1182  {
1183  if (exists->variable == NULL || !DB_IS_NULL (exists->variable))
1184  {
1185  continue;
1186  }
1187  }
1188 
1189  a = obt_make_assignment (template_ptr, att);
1190  if (a == NULL)
1191  {
1192  goto auto_increment_error;
1193  }
1194 
1195  a->is_auto_increment = 1;
1196  a->variable = pr_make_ext_value ();
1197 
1198  if (a->variable == NULL)
1199  {
1200  goto auto_increment_error;
1201  }
1202 
1203  if (do_get_serial_cached_num (&cached_num, att->auto_increment) != NO_ERROR)
1204  {
1205  goto auto_increment_error;
1206  }
1207 
1208  db_make_null (&val);
1209  /* Do not update LAST_INSERT_ID during executing a trigger. */
1210  if (do_Trigger_involved == true || obt_Last_insert_id_generated == true)
1211  {
1212  error = serial_get_next_value (&val, &att->auto_increment->oid_info.oid, cached_num, 1, GENERATE_SERIAL);
1213  }
1214  else
1215  {
1216  error =
1218  if (error == NO_ERROR)
1219  {
1221  }
1222  }
1223  if (error != NO_ERROR)
1224  {
1225  goto auto_increment_error;
1226  }
1227 
1228  db_value_domain_init (a->variable, att->type->id, att->domain->precision, att->domain->scale);
1229 
1230  (void) numeric_db_value_coerce_from_num (&val, a->variable, &data_status);
1231  if (data_status != NO_ERROR)
1232  {
1233  goto auto_increment_error;
1234  }
1235  else
1236  {
1237  template_ptr->is_autoincrement_set = 1;
1238  }
1239  }
1240 
1241  return error;
1242 
1243 auto_increment_error:
1244  assert (er_errid () != NO_ERROR);
1245  return er_errid ();
1246 }
1247 
1248 /*
1249  * populate_defaults - This populates a template with the default values
1250  * for a class.
1251  * returns: error code
1252  * template(in): template to fill out
1253  *
1254  * Note :
1255  * This is necessary for INSERT templates. The assignments are marked
1256  * so that if an assignment is later made to the template with the
1257  * same name, we don't generate an error because its ok to override
1258  * a default value.
1259  * If an assignment is already found with the name, it is assumed
1260  * that an initial value has already been given and the default is
1261  * ignored.
1262  *
1263  */
1264 
1265 static int
1267 {
1268  SM_ATTRIBUTE *att, *base_att;
1269  OBJ_TEMPASSIGN *a, *exists;
1270  SM_CLASS *class_;
1271  DB_VALUE base_value;
1272  const char *base_name;
1273 
1274  db_make_null (&base_value);
1275 
1276  if (!template_ptr->is_class_update)
1277  {
1278  class_ = template_ptr->class_;
1279 
1280  if (template_ptr->base_class != NULL)
1281  {
1282  /*
1283  * first populate with the transformed default values of the
1284  * virtual class
1285  */
1286  for (att = template_ptr->class_->attributes; att != NULL; att = (SM_ATTRIBUTE *) att->header.next)
1287  {
1288 
1289  /* only update the attribute if it is updatable */
1290  if (mq_is_updatable_attribute (template_ptr->classobj, att->header.name, template_ptr->base_classobj))
1291  {
1292  if (mq_update_attribute (template_ptr->classobj, att->header.name, template_ptr->base_classobj,
1293  &att->default_value.value, &base_value, &base_name, DB_AUTH_INSERT))
1294  {
1295  assert (er_errid () != NO_ERROR);
1296  return er_errid ();
1297  }
1298 
1299  /* find the associated attribute definition in the base class */
1300  if (obt_find_attribute (template_ptr, 1, base_name, &base_att))
1301  {
1302  assert (er_errid () != NO_ERROR);
1303  return er_errid ();
1304  }
1305 
1306  exists = template_ptr->assignments[base_att->order];
1307  /*
1308  * if the tranformed virtual default is non-NULL we use it,
1309  * if the underlying base default is non-NULL, we let the virtual
1310  * default override it to NULL
1311  */
1312 
1313  if (exists == NULL && (!DB_IS_NULL (&base_value) || !DB_IS_NULL (&base_att->default_value.value)))
1314  {
1315  /* who owns base_value ? */
1316  a = obt_make_assignment (template_ptr, base_att);
1317  if (a == NULL)
1318  {
1319  goto memory_error;
1320  }
1321  a->is_default = 1;
1322  a->variable = pr_make_ext_value ();
1323  if (a->variable == NULL)
1324  {
1325  goto memory_error;
1326  }
1327  if (pr_clone_value (&base_value, a->variable))
1328  {
1329  goto memory_error;
1330  }
1331  }
1332  }
1333  }
1334 
1335  /*
1336  * change the class pointer to reference the base class rather
1337  * than the virtual class
1338  */
1339  class_ = template_ptr->base_class;
1340  }
1341 
1342  /*
1343  * populate with the standard default values, ignore duplicate
1344  * assignments if the virtual class has already supplied
1345  * a value for these.
1346  */
1347  for (att = class_->attributes; att != NULL; att = (SM_ATTRIBUTE *) att->header.next)
1348  {
1349  /*
1350  * can assume that the type is compatible and does not need
1351  * to be coerced
1352  */
1353 
1355  {
1356 
1357  exists = template_ptr->assignments[att->order];
1358 
1359  if (exists == NULL)
1360  {
1361  a = obt_make_assignment (template_ptr, att);
1362  if (a == NULL)
1363  {
1364  goto memory_error;
1365  }
1366  a->is_default = 1;
1367  a->variable = pr_make_ext_value ();
1368  if (a->variable == NULL)
1369  {
1370  goto memory_error;
1371  }
1372  /* would be nice if we could avoid copying here */
1373  if (pr_clone_value (&att->default_value.value, a->variable))
1374  {
1375  goto memory_error;
1376  }
1377  }
1378  }
1379  }
1380  }
1381 
1382  return (NO_ERROR);
1383 
1384 memory_error:
1385  /*
1386  * Here we couldn't allocate sufficient memory for the template and its
1387  * values. Probably the template should be marked as invalid and
1388  * the caller be forced to throw it away and start again since
1389  * its current state is unknown.
1390  */
1391  assert (er_errid () != NO_ERROR);
1392  return er_errid ();
1393 }
1394 
1395 /*
1396  * obt_def_object - This initializes a new template for an instance of
1397  * the given class.
1398  * return: new template
1399  * class(in): class of the new object
1400  *
1401  * Note :
1402  * This template can then be populated with assignments and given
1403  * to obt_update to create the instances.
1404  *
1405  */
1406 
1407 OBJ_TEMPLATE *
1408 obt_def_object (MOP class_mop)
1409 {
1410  OBJ_TEMPLATE *template_ptr = NULL;
1412 
1413  if (is_class < 0)
1414  {
1415  return NULL;
1416  }
1417  if (!is_class)
1418  {
1420  }
1421  else
1422  {
1423  template_ptr = make_template (NULL, class_mop);
1424  }
1425 
1426  return template_ptr;
1427 }
1428 
1429 /*
1430  * obt_edit_object - This is used to initialize an editing template
1431  * on an existing object.
1432  *
1433  * returns: template
1434  * object(in): existing instance
1435  *
1436  */
1437 
1438 OBJ_TEMPLATE *
1440 {
1441  OBJ_TEMPLATE *template_ptr = NULL;
1443 
1444  if (is_class < 0)
1445  {
1446  return NULL;
1447  }
1448  if (is_class)
1449  {
1450  /*
1451  * create a class object template, these are only allowed to
1452  * update class attributes
1453  */
1454  template_ptr = make_template (object, object);
1455  }
1456  else if (!object->is_temp)
1457  {
1458  DB_OBJECT *class_;
1459  /*
1460  * Need to make sure we have the class accessible, don't just
1461  * dereference obj->class. This gets a read lock early but that's ok
1462  * since we know we're dealing with an instance here.
1463  * Should be handling this inside make_template.
1464  */
1465  class_ = sm_get_class (object);
1466  if (class_ != NULL)
1467  {
1468  template_ptr = make_template (object, class_);
1469  }
1470  }
1471 
1472  else
1473  {
1475  }
1476 
1477  return template_ptr;
1478 }
1479 
1480 /*
1481  * obt_quit - This is used to abort the creation of an object template
1482  * and release all the allocated storage.
1483  * return: error code
1484  * template(in): template to throw away
1485  *
1486  */
1487 
1488 int
1489 obt_quit (OBJ_TEMPLATE * template_ptr)
1490 {
1491  if (template_ptr != NULL)
1492  {
1493  obt_free_template (template_ptr);
1494  }
1495 
1496  return NO_ERROR;
1497 }
1498 
1499 /*
1500  * obt_assign - This is used to assign a value to an attribute
1501  * in an object template.
1502  * return: error code
1503  * template(in): object template
1504  * att(in):
1505  * base_assignment(in): non-zero if attribute/value are base class values.
1506  * value(in): value to assign
1507  * valid(in):
1508  *
1509  * Note:
1510  * The usual semantic checking on assignment will be performed and
1511  * an error returned if the assignment would be invalid.
1512  * If the base_assignment flag is zero (normal), the name/value pair
1513  * must correspond to the virtual class definition and translation
1514  * will be performed if this is a template on a vclass. If the
1515  * base_assignment flag is non-zero, the name/value pair are assumed
1516  * to correspond to the base class and translation is not performed.
1517  * If this is not a template on a virtual class, the flag has
1518  * no effect.
1519  */
1520 
1521 int
1522 obt_assign (OBJ_TEMPLATE * template_ptr, SM_ATTRIBUTE * att, int base_assignment, DB_VALUE * value,
1523  SM_VALIDATION * valid)
1524 {
1525  int error = NO_ERROR;
1526  OBJ_TEMPASSIGN *assign;
1527  DB_VALUE *actual, base_value;
1528  const char *base_name;
1529  DB_AUTH auth;
1530  DB_OBJECT *object;
1531 
1532  db_make_null (&base_value);
1533 
1534  if ((template_ptr == NULL) || (att == NULL) || (value == NULL))
1535  {
1537  goto error_exit;
1538  }
1539 
1540  if (validate_template (template_ptr))
1541  {
1542  goto error_exit;
1543  }
1544 
1545  if (!base_assignment && template_ptr->base_class != NULL
1546  /* Don't translate class attributes */
1547  && template_ptr->object != template_ptr->classobj)
1548  {
1549  /*
1550  * it's virtual, we could check for assignment validity before calling
1551  * the value translator
1552  */
1553 
1554  auth = (template_ptr->object == NULL) ? DB_AUTH_INSERT : DB_AUTH_UPDATE;
1555 
1556  if (mq_update_attribute (template_ptr->classobj, att->header.name, template_ptr->base_classobj, value,
1557  &base_value, &base_name, auth))
1558  {
1559  goto error_exit;
1560  }
1561 
1562  /* find the associated attribute definition in the base class */
1563  if (obt_find_attribute (template_ptr, 1, base_name, &att))
1564  {
1565  goto error_exit;
1566  }
1567 
1568  /* switch to the translated value, who owns this ? */
1569  value = &base_value;
1570  }
1571 
1572  /* check for duplicate assignments */
1573  assign = NULL;
1574  if (template_ptr->assignments)
1575  {
1576  assign = template_ptr->assignments[att->order];
1577  }
1578 
1579  if (assign)
1580  {
1581  if (template_ptr->discard_on_finish)
1582  {
1584  goto error_exit;
1585  }
1586  }
1587 
1588  /* check assignment validity */
1589  object = OBT_BASE_OBJECT (template_ptr);
1590  actual = obt_check_assignment (att, value, valid, template_ptr->force_check_not_null);
1591  if (actual == NULL)
1592  {
1593  goto error_exit;
1594  }
1595  else
1596  {
1597  assign = obt_make_assignment (template_ptr, att);
1598  if (assign == NULL)
1599  {
1600  goto error_exit;
1601  }
1602  }
1603 
1604  if (actual != value)
1605  {
1606  if (assign->variable)
1607  {
1608  pr_free_ext_value (assign->variable);
1609  }
1610  assign->variable = actual;
1611  }
1612  else
1613  {
1614  if (assign->variable)
1615  {
1616  /*
1617  *
1618  * Clear the contents, but recycle the container.
1619  */
1620  (void) pr_clear_value (assign->variable);
1621  }
1622  else
1623  {
1624  assign->variable = pr_make_ext_value ();
1625  if (assign->variable == NULL)
1626  {
1627  goto error_exit;
1628  }
1629  }
1630  /*
1631  *
1632  * Note that this copies the set value, might not want to do this
1633  * when called by the interpreter under controlled conditions,
1634  *
1635  * !!! See about optimizing this so we don't do so much set copying !!!
1636  */
1637  error = pr_clone_value (value, assign->variable);
1638  }
1639 
1640  return error;
1641 
1642 error_exit:
1643  assert (er_errid () != NO_ERROR);
1644  return er_errid ();
1645 }
1646 
1647 /*
1648  * obt_assign_obt - This is used to assign another object template as
1649  * the value of an attribute in an object template
1650  * return: error code
1651  * template(in): object template
1652  * att(in):
1653  * base_assignment(in): non-zero if base_class assignment
1654  * value(in): nested object template to assign
1655  *
1656  * Note:
1657  * This is the way that hierarchies of nested objects are specified
1658  * using templates.
1659  * See the description of obt_assign() for more information
1660  * on the meaning of the base_assignment flag.
1661  * NOTE: obt_set_obt & obt_assign_obt were split to be consistent
1662  * with obt_set/obt_assign but we don't currently have a need
1663  * to use obt_assign_obt with a non-zero value for base_assignment.
1664  *
1665  */
1666 
1667 static int
1668 obt_assign_obt (OBJ_TEMPLATE * template_ptr, SM_ATTRIBUTE * att, int base_assignment, OBJ_TEMPLATE * value)
1669 {
1670  int error = NO_ERROR;
1671  OBJ_TEMPASSIGN *assign;
1672  DB_VALUE dummy_value, base_value;
1673  const char *base_name;
1674  DB_AUTH auth;
1675 
1676  db_make_null (&base_value);
1677  db_make_null (&dummy_value);
1678 
1679  if (value == NULL)
1680  {
1682  return error;
1683  }
1684 
1685  if (!base_assignment && template_ptr->base_class != NULL)
1686  {
1687  auth = (template_ptr->object == NULL) ? DB_AUTH_INSERT : DB_AUTH_UPDATE;
1688  if (mq_update_attribute (template_ptr->classobj, att->header.name, template_ptr->base_classobj, &dummy_value,
1689  &base_value, &base_name, auth))
1690  {
1691  assert (er_errid () != NO_ERROR);
1692  return er_errid ();
1693  }
1694 
1695  /* find the associated attribute definition in the base class */
1696  if (obt_find_attribute (template_ptr, 1, base_name, &att))
1697  {
1698  assert (er_errid () != NO_ERROR);
1699  return er_errid ();
1700  }
1701  }
1702 
1703  if (att->domain->type != tp_Type_object)
1704  {
1706  }
1707  else
1708  {
1709  /* check duplicate assigmnent */
1710  assign = template_ptr->assignments[att->order];
1711  if (assign != NULL && template_ptr->discard_on_finish)
1712  {
1714  }
1715  else
1716  {
1717  /*
1718  * obt_check_assignment doesn't accept templates, this is a rather
1719  * controled condition, the only thing we need to check for
1720  * is a valid class hierarchy
1721  */
1722  if (!sm_check_class_domain (att->domain, value->classobj))
1723  {
1724  /* if we don't free value now, it will leak */
1725  obt_free_template (value);
1726  ERROR1 (error, ER_OBJ_DOMAIN_CONFLICT, att->header.name);
1727  }
1728  else if (sm_is_reuse_oid_class (value->classobj))
1729  {
1730  obt_free_template (value);
1732  }
1733  else
1734  {
1735  assign = obt_make_assignment (template_ptr, att);
1736  if (assign == NULL)
1737  {
1738  assert (er_errid () != NO_ERROR);
1739  error = er_errid ();
1740  }
1741  else
1742  {
1743  assign->obj = value;
1744  }
1745  }
1746  }
1747  }
1748 
1749  return error;
1750 }
1751 
1752 /*
1753  * obt_set -
1754  * return: error code
1755  * template(in): attname
1756  * attname(in): value
1757  * value(in):
1758  *
1759  * Note:
1760  * This is just a shell around obt_assign that doesn't
1761  * make the base_assignment flag public.
1762  * Recognize the value type DB_TYPE_POINTER as meaning the pointer
1763  * is another template rather than an object.
1764  */
1765 
1766 int
1767 obt_set (OBJ_TEMPLATE * template_ptr, const char *attname, DB_VALUE * value)
1768 {
1769  int error = NO_ERROR;
1770  SM_ATTRIBUTE *att;
1771 
1772  if ((template_ptr == NULL) || (attname == NULL) || (value == NULL))
1773  {
1775  }
1776  else
1777  {
1778  if (validate_template (template_ptr))
1779  {
1780  assert (er_errid () != NO_ERROR);
1781  return er_errid ();
1782  }
1783 
1784  if (obt_find_attribute (template_ptr, 0, attname, &att))
1785  {
1786  assert (er_errid () != NO_ERROR);
1787  return er_errid ();
1788  }
1789 
1790  if (DB_VALUE_TYPE (value) == DB_TYPE_POINTER)
1791  {
1792  error = obt_assign_obt (template_ptr, att, 0, (OBJ_TEMPLATE *) db_get_pointer (value));
1793  }
1794  else
1795  {
1796  error = obt_assign (template_ptr, att, 0, value, NULL);
1797  }
1798  }
1799 
1800  return error;
1801 }
1802 
1803 /* temporary backward compatibility */
1804 /*
1805  * obt_set_obt -
1806  * return: error code
1807  * template(in):
1808  * attname(in):
1809  * value(in):
1810  *
1811  */
1812 int
1813 obt_set_obt (OBJ_TEMPLATE * template_ptr, const char *attname, OBJ_TEMPLATE * value)
1814 {
1815  DB_VALUE v;
1816 
1817  db_make_pointer (&v, value);
1818 
1819  return (obt_set (template_ptr, attname, &v));
1820 }
1821 
1822 /*
1823  * obt_set_desc - This is similar to obt_set() except that
1824  * the attribute is identified through a descriptor rather than
1825  * an attribute name.
1826  * return: error code
1827  * template(in): object template
1828  * desc(in): attribute descriptor
1829  * value(in): value to assign
1830  *
1831  */
1832 
1833 int
1834 obt_desc_set (OBJ_TEMPLATE * template_ptr, SM_DESCRIPTOR * desc, DB_VALUE * value)
1835 {
1836  int error = NO_ERROR;
1837  SM_CLASS *class_;
1838  SM_ATTRIBUTE *att;
1839 
1840  if ((template_ptr == NULL) || (desc == NULL) || (value == NULL))
1841  {
1843  }
1844  else
1845  {
1846  if (validate_template (template_ptr))
1847  {
1848  assert (er_errid () != NO_ERROR);
1849  return er_errid ();
1850  }
1851 
1852  /*
1853  * Note that we pass in the outer class MOP rather than an object
1854  * since we don't necessarily have an object at this point.
1855  */
1856  if (sm_get_descriptor_component (template_ptr->classobj, desc, 1, &class_, (SM_COMPONENT **) (&att)))
1857  {
1858  assert (er_errid () != NO_ERROR);
1859  return er_errid ();
1860  }
1861 
1862  if (DB_VALUE_TYPE (value) == DB_TYPE_POINTER)
1863  {
1864  error = obt_assign_obt (template_ptr, att, 0, (OBJ_TEMPLATE *) db_get_pointer (value));
1865  }
1866  else
1867  {
1868  error = obt_assign (template_ptr, att, 0, value, desc->valid);
1869  }
1870  }
1871 
1872  return error;
1873 }
1874 
1875 
1876 /*
1877  * create_template_object -
1878  * return: MOP of new object
1879  * template(in):
1880  */
1881 
1882 
1883 static MOP
1885 {
1886  MOP mop;
1887  char *obj;
1888  SM_CLASS *class_;
1889 
1890  mop = NULL;
1891 
1892  /* must flag this condition */
1894 
1895  class_ = template_ptr->class_;
1896 
1897  /*
1898  * NOTE: garbage collection can occur in either the call to locator_add_instance
1899  * or vid_add_virtual_instance (which calls locator_add_instance). The object
1900  * we're caching can't contain any object references that aren't rooted
1901  * elsewhere. Currently this is the case since the object is empty
1902  * and will be populated later with information from the template which IS
1903  * a GC root.
1904  */
1905  if (class_->class_type != SM_VCLASS_CT)
1906  {
1907  obj = obj_alloc (class_, 0);
1908  if (obj != NULL)
1909  {
1910  mop = locator_add_instance (obj, template_ptr->classobj);
1911  }
1912  }
1913  else
1914  {
1915  /* virtual instance, base_class must be supplied */
1916  obj = obj_alloc (template_ptr->base_class, 0);
1917  if (obj != NULL)
1918  {
1919  /* allocate 2 MOP's */
1920  mop =
1921  vid_add_virtual_instance (obj, template_ptr->classobj, template_ptr->base_classobj,
1922  template_ptr->base_class);
1923  }
1924  }
1925 
1926  if (mop != NULL)
1927  {
1928  template_ptr->object = mop;
1929 
1930  /* set the label if one is defined */
1931  if (template_ptr->label != NULL)
1932  {
1933  db_make_object (template_ptr->label, mop);
1934  }
1935 
1936  /* if this is a virtual instance insert, cache the base instance too */
1937  if (template_ptr->base_class != NULL)
1938  {
1939 
1940  /* probably don't need the first test in the if at this point */
1941  if (mop->is_vid && !vid_is_base_instance (mop))
1942  {
1943  template_ptr->base_object = vid_get_referenced_mop (mop);
1944  }
1945  else
1946  {
1947  template_ptr->base_object = mop;
1948  }
1949  }
1950  }
1951 
1952  return mop;
1953 }
1954 
1955 /*
1956  * access_object - This is a preprocessing function called by
1957  * obt_apply_assignments.
1958  * return: error code
1959  * template(in): object template
1960  * object(in):
1961  * objptr(out): pointer to instance (returned)
1962  *
1963  * Note:
1964  * It ensures that the object associated with the template is locked
1965  * and created if necessary.
1966  */
1967 static int
1968 access_object (OBJ_TEMPLATE * template_ptr, MOP * object, MOBJ * objptr)
1969 {
1970  int error = NO_ERROR;
1971  MOP classobj, mop;
1972  MOBJ obj;
1973 
1974  /*
1975  * The class and instance was already locked&fetched when the template was created.
1976  * The class pointer was cached since they are always pinned.
1977  * To avoid pinning the instance through a scope we don't control,
1978  * they aren't pinned during make_template but rather are "fetched"
1979  * again and pinned during obt_apply_assignments()
1980  * Authorization was checked when the template was created so don't
1981  * do it again.
1982  */
1983 
1984  if (template_ptr->is_class_update)
1985  {
1986  /* object is the class but there is no memory pointer */
1987  *object = OBT_BASE_CLASSOBJ (template_ptr);
1988  *objptr = NULL;
1989  return NO_ERROR;
1990  }
1991 
1992  obj = NULL;
1993 
1994  /*
1995  * First, check to see if this is an INSERT template and if so, create
1996  * the new object.
1997  */
1998  if (template_ptr->object == NULL)
1999  {
2000  if (create_template_object (template_ptr) == NULL)
2001  {
2002  assert (er_errid () != NO_ERROR);
2003  return er_errid ();
2004  }
2005  }
2006 
2007  /*
2008  * Now, fetch/lock the instance and mark the class.
2009  * At this point, we want to be dealing with only the base object.
2010  */
2011 
2012  if (template_ptr->base_classobj != NULL)
2013  {
2014  classobj = template_ptr->base_classobj;
2015  mop = template_ptr->base_object;
2016  }
2017  else
2018  {
2019  classobj = template_ptr->classobj;
2020  mop = template_ptr->object;
2021  }
2022 
2023  if (mop != NULL)
2024  {
2026  if (error == NO_ERROR)
2027  {
2028  /* must call this when updating instances */
2030  }
2031  }
2032 
2033  if (obj == NULL)
2034  {
2035  assert (er_errid () != NO_ERROR);
2036  error = er_errid ();
2037  }
2038  else
2039  {
2040  mop->pruning_type = template_ptr->pruning_type;
2041  *object = mop;
2042  *objptr = obj;
2043  }
2044 
2045  return error;
2046 }
2047 
2048 /*
2049  * obt_convert_set_templates - Work function for obt_apply_assignments.
2050  * return: error code
2051  * setref(in): set pointer from a template
2052  * check_uniques(in):
2053  *
2054  * Note:
2055  * This will iterate through the elements of a set (or sequence) and
2056  * convert any elements that are templates in to actual instances.
2057  * It will recursively call obt_apply_assignments for the templates
2058  * found in the set.
2059  */
2060 
2061 static int
2062 obt_convert_set_templates (SETREF * setref, int check_uniques)
2063 {
2064  int error = NO_ERROR;
2065  DB_VALUE *value = NULL;
2066  OBJ_TEMPLATE *template_ptr;
2067  int i, set_size;
2068  SETOBJ *set;
2069 
2070  if (setref != NULL)
2071  {
2072  set = setref->set;
2073  if (set != NULL)
2074  {
2075  set_size = setobj_size (set);
2076  for (i = 0; i < set_size && error == NO_ERROR; i++)
2077  {
2078  setobj_get_element_ptr (set, i, &value);
2079  if (value != NULL && DB_VALUE_TYPE (value) == DB_TYPE_POINTER)
2080  {
2081  /* apply the template for this element */
2082  template_ptr = (OBJ_TEMPLATE *) db_get_pointer (value);
2083  error = obt_apply_assignments (template_ptr, check_uniques, 1);
2084  /* 1 means do eager flushing of (set-nested) proxy objects */
2085  if (error == NO_ERROR && template_ptr != NULL)
2086  {
2087  db_make_object (value, template_ptr->object);
2088  obt_free_template (template_ptr);
2089  }
2090  }
2091  }
2092  }
2093  }
2094 
2095  return error;
2096 }
2097 
2098 /*
2099  * obt_final_check_set - This is called when a set value is encounterd in
2100  * a template that is in the final semantic checking phase.
2101  * return: error code
2102  * setref(in): object template that provked this call
2103  * has_uniques(in):
2104  *
2105  * Note:
2106  * We must go through the set and look for each element that is itself
2107  * a template for a new object.
2108  * When these are found, recursively call obt_final_check to make sure
2109  * these templates look ok.
2110  */
2111 
2112 static int
2113 obt_final_check_set (SETREF * setref, int *has_uniques)
2114 {
2115  int error = NO_ERROR;
2116  DB_VALUE *value = NULL;
2117  OBJ_TEMPLATE *template_ptr;
2118  SETOBJ *set;
2119  int i, set_size;
2120 
2121  if (setref != NULL)
2122  {
2123  set = setref->set;
2124  if (set != NULL)
2125  {
2126  set_size = setobj_size (set);
2127  for (i = 0; i < set_size && error == NO_ERROR; i++)
2128  {
2129  setobj_get_element_ptr (set, i, &value);
2130  if (value != NULL && DB_VALUE_TYPE (value) == DB_TYPE_POINTER)
2131  {
2132  template_ptr = (OBJ_TEMPLATE *) db_get_pointer (value);
2133  error = obt_final_check (template_ptr, 1, has_uniques);
2134  }
2135  }
2136  }
2137  }
2138 
2139  return error;
2140 }
2141 
2142 /*
2143  * obt_check_missing_assignments - This checks a list of attribute definitions
2144  * against a template and tries to locate missing
2145  * assignments in the template that are required
2146  * in order to process an insert template.
2147  * return: error code
2148  * template(in): template being processed
2149  *
2150  * Note:
2151  * This includes missing initializers for attributes that are defined
2152  * to be NON NULL.
2153  * It also includes attributes defined with a VID flag.
2154  */
2155 
2156 int
2158 {
2159  int error = NO_ERROR;
2160  SM_CLASS *class_;
2161  SM_ATTRIBUTE *att;
2162  OBJ_TEMPASSIGN *ass;
2163 
2164  /* only do this if its an insert template */
2165 
2166  if (template_ptr->object == NULL)
2167  {
2168  /* use the base_class if this is a virtual class insert */
2169  class_ = OBT_BASE_CLASS (template_ptr);
2170 
2171  for (att = class_->ordered_attributes; att != NULL && error == NO_ERROR; att = att->order_link)
2172  {
2173 
2174  if (((att->flags & SM_ATTFLAG_NON_NULL) && DB_IS_NULL (&att->default_value.value)
2176  || (att->flags & SM_ATTFLAG_VID))
2177  {
2178  ass = template_ptr->assignments[att->order];
2179  if (ass == NULL)
2180  {
2181  if (att->flags & SM_ATTFLAG_NON_NULL)
2182  {
2184  }
2185  if (att->flags & SM_ATTFLAG_VID)
2186  {
2187  ERROR1 (error, ER_SM_OBJECT_ID_NOT_SET, sm_ch_name ((MOBJ) (template_ptr->class_)));
2188  }
2189  }
2190  }
2191  }
2192  }
2193 
2194  return error;
2195 }
2196 
2197 /*
2198  * obt_final_check
2199  * return: error code
2200  * template(in): object template
2201  * check_non_null(in):
2202  * has_uniques(in):
2203  *
2204  */
2205 
2206 static int
2207 obt_final_check (OBJ_TEMPLATE * template_ptr, int check_non_null, int *has_uniques)
2208 {
2209  int error = NO_ERROR;
2210  OBJ_TEMPASSIGN *a;
2211  int i;
2212 
2213  /* have we already been here ? */
2214  if (template_ptr->traversal == obj_Template_traversal)
2215  {
2216  return NO_ERROR;
2217  }
2218  template_ptr->traversal = obj_Template_traversal;
2219 
2220  if (validate_template (template_ptr))
2221  {
2222  assert (er_errid () != NO_ERROR);
2223  return er_errid ();
2224  }
2225 
2226  if (!template_ptr->is_class_update)
2227  {
2228 
2229  /*
2230  * We locked the object when the template was created, this
2231  * should still be valid. If not, it should have been detected
2232  * by validate_template above.
2233  * Could create the new instances here but wait for a later step.
2234  */
2235 
2236  /*
2237  * Check missing assignments on an insert template, should be able
2238  * to optimize this, particularly when checking for uninitialized
2239  * shared attributes.
2240  */
2241  if (template_ptr->object == NULL)
2242  {
2243  if (obt_Enable_autoincrement == true && populate_auto_increment (template_ptr))
2244  {
2245  assert (er_errid () != NO_ERROR);
2246  return er_errid ();
2247  }
2248 
2249  if (populate_defaults (template_ptr))
2250  {
2251  assert (er_errid () != NO_ERROR);
2252  return er_errid ();
2253  }
2254 
2255  if (check_non_null && obt_check_missing_assignments (template_ptr))
2256  {
2257  assert (er_errid () != NO_ERROR);
2258  return er_errid ();
2259  }
2260  }
2261 
2262  /* does this template have uniques? */
2263  if (template_ptr->uniques_were_modified)
2264  {
2265  *has_uniques = 1;
2266  }
2267 
2268  /* this template looks ok, recursively go through the sub templates */
2269  for (i = 0; i < template_ptr->nassigns && error == NO_ERROR; i++)
2270  {
2271  a = template_ptr->assignments[i];
2272  if (a == NULL)
2273  {
2274  continue;
2275  }
2276  if (a->obj != NULL)
2277  {
2278  /* the non-null flag is only used for the outermost template */
2279  error = obt_final_check (a->obj, 1, has_uniques);
2280  }
2281  else
2282  {
2283  DB_TYPE av_type;
2284 
2285  av_type = DB_VALUE_TYPE (a->variable);
2286  if (TP_IS_SET_TYPE (av_type))
2287  {
2288  error = obt_final_check_set (db_get_set (a->variable), has_uniques);
2289  }
2290  }
2291  }
2292 
2293  /* check unique_constraints, but only if not disabled */
2294  /*
2295  * test & set interface doesn't work right now, full savepoints are instead
2296  * being performed in obt_update_internal.
2297  */
2298  }
2299  return (error);
2300 }
2301 
2302 /*
2303  * obt_apply_assignment - This is used to apply the assignments in an object
2304  * template after all of the appropriate semantic
2305  * checking has taken place.
2306  * return: error code
2307  * op(in): class or instance pointer
2308  * att(in): attribute descriptor
2309  * mem(in): instance memory pointer (instance attribute only)
2310  * value(in): value to assign
2311  * check_uniques(in):
2312  *
2313  * Note:
2314  * This used to be a lot more complicated because the translation
2315  * of virtual values to base values was deferred until this step.
2316  * Now, the values are translated immediately when they are added
2317  * to the template.
2318  */
2319 
2320 static int
2321 obt_apply_assignment (MOP op, SM_ATTRIBUTE * att, char *mem, DB_VALUE * value, int check_uniques)
2322 {
2323  int error = NO_ERROR;
2324 
2325  if (!TP_IS_SET_TYPE (TP_DOMAIN_TYPE (att->domain)))
2326  {
2327  error = obj_assign_value (op, att, mem, value);
2328  }
2329  else
2330  {
2331  /* for sets, first apply any templates in the set */
2332  error = obt_convert_set_templates (db_get_set (value), check_uniques);
2333  if (error == NO_ERROR)
2334  {
2335 
2336  /* BE VERY CAREFUL HERE, IN THE OLD VERSION THE SET WAS BEING COPIED ? */
2337  error = obj_assign_value (op, att, mem, value);
2338  }
2339  }
2340 
2341  return error;
2342 }
2343 
2344 /*
2345  * obt_apply_assignments -
2346  * return: error code
2347  * template(in): object template
2348  * check_uniques(in): true iff check unique constraints
2349  * level(in): level of recursion (0 for outermost call)
2350  *
2351  * Note:
2352  * This is used to apply the assignments in an object template after all
2353  * of the appropriate semantic checking has taken place. Technically,
2354  * there shouldn't be any errors here. If errors do occurr, they will
2355  * not cause a rollback of any partially applied assignments. The only
2356  * place this is likely to happen is if there are problems updating
2357  * the unique constraint table but even this would represent a serious
2358  * internal error that may have other consequences as well.
2359  * Update triggers on the individual instances are fired here.
2360  * If level==0 then do lazy flushing of proxy objects. If level > 0 then
2361  * do eager flushing of proxy objects because it's a nested proxy insert.
2362  */
2363 
2364 static int
2365 obt_apply_assignments (OBJ_TEMPLATE * template_ptr, int check_uniques, int level)
2366 {
2367  int error = NO_ERROR;
2368  OBJ_TEMPASSIGN *a;
2369  DB_VALUE val;
2370  int pin, trigstate;
2371  TR_STATE *trstate;
2372  DB_OBJECT *temp;
2373  DB_TRIGGER_EVENT event;
2374  SM_CLASS *class_;
2375  DB_OBJECT *object = NULL;
2376  MOBJ mobj = NULL;
2377  char *mem;
2378  int i;
2379 
2380  /* have we already been here ? */
2381  if (template_ptr->traversal == obj_Template_traversal)
2382  {
2383  return NO_ERROR;
2384  }
2385  template_ptr->traversal = obj_Template_traversal;
2386 
2387  /* make sure we have a good template */
2388  if (validate_template (template_ptr))
2389  {
2390  assert (er_errid () != NO_ERROR);
2391  return er_errid ();
2392  }
2393 
2394  /* perform all operations on the base class */
2395  class_ = OBT_BASE_CLASS (template_ptr);
2396 
2397  /*
2398  * figure out what kind of triggers to fire here, only do this
2399  * if the class indicates that there are active triggers
2400  */
2401  trigstate = sm_active_triggers (OBT_BASE_CLASSOBJ (template_ptr), class_, TR_EVENT_ALL);
2402  if (trigstate < 0)
2403  {
2404  assert (er_errid () != NO_ERROR);
2405  return er_errid ();
2406  }
2407 
2408  event = TR_EVENT_NULL;
2409  if (trigstate)
2410  {
2411  if (template_ptr->object == NULL)
2412  {
2413  event = TR_EVENT_INSERT;
2414  }
2415  else
2416  {
2417  event = TR_EVENT_UPDATE;
2418  }
2419  }
2420 
2421  /* Collect triggers */
2422  trstate = NULL;
2423  temp = NULL;
2424  if (event != TR_EVENT_NULL)
2425  {
2426  if (tr_prepare_class (&trstate, class_->triggers, OBT_BASE_CLASSOBJ (template_ptr), event))
2427  {
2428  assert (er_errid () != NO_ERROR);
2429  return er_errid ();
2430  }
2431  if (event == TR_EVENT_UPDATE)
2432  {
2433  for (i = 0; i < template_ptr->nassigns; i++)
2434  {
2435  a = template_ptr->assignments[i];
2436  if (a == NULL)
2437  {
2438  continue;
2439  }
2440  if (tr_prepare_class (&trstate, a->att->triggers, OBT_BASE_CLASSOBJ (template_ptr), event))
2441  {
2442  tr_abort (trstate);
2443 
2444  assert (er_errid () != NO_ERROR);
2445  return er_errid ();
2446  }
2447  }
2448  }
2449  }
2450 
2451  /* Evaluate BEFORE triggers */
2452  pin = -1;
2453  if (trstate == NULL)
2454  {
2455  /* no triggers, lock/create the object */
2456  error = access_object (template_ptr, &object, &mobj);
2457  if (error == NO_ERROR)
2458  {
2459  pin = ws_pin (object, 1);
2460  }
2461  }
2462  else
2463  {
2464  /* make the temporary object for the template */
2465  temp = make_temp_object (OBT_BASE_CLASSOBJ (template_ptr), template_ptr);
2466  if (temp == NULL)
2467  {
2468  assert (er_errid () != NO_ERROR);
2469  error = er_errid ();
2470  }
2471  else
2472  {
2473  if (event == TR_EVENT_INSERT)
2474  {
2475  /* evaluate triggers before creating the object */
2476  if (!(error = tr_before_object (trstate, NULL, temp)))
2477  {
2478  /* create the new object */
2479  if (!(error = access_object (template_ptr, &object, &mobj)))
2480  {
2481  pin = ws_pin (object, 1);
2482  }
2483  }
2484  else
2485  trstate = NULL;
2486  }
2487  else
2488  {
2489  /* lock the object first, then evaluate the triggers */
2490  if (!(error = access_object (template_ptr, &object, &mobj)))
2491  {
2492  if ((error = tr_before_object (trstate, object, temp)))
2493  {
2494  trstate = NULL;
2495  }
2496  }
2497 
2498  /* in some cases, the object has been decached in before trigger. we need fetch it again. */
2499  if (error == NO_ERROR && object->decached)
2500  {
2502  if (error != NO_ERROR)
2503  {
2504  if (trstate != NULL)
2505  {
2506  tr_abort (trstate);
2507  }
2508  if (temp != NULL)
2509  {
2510  free_temp_object (temp);
2511  }
2512 
2513  if (WS_IS_DELETED (object))
2514  {
2515  return NO_ERROR;
2516  }
2517 
2518  return error;
2519  }
2520  }
2521  /* set pin after before trigger */
2522  pin = ws_pin (object, 1);
2523  }
2524  }
2525  }
2526 
2527  /* Apply the assignments */
2528  for (i = 0; i < template_ptr->nassigns && error == NO_ERROR; i++)
2529  {
2530  a = template_ptr->assignments[i];
2531  if (a == NULL)
2532  continue;
2533 
2534  /* find memory pointer if this is an instance attribute */
2535  mem = NULL;
2536  if (a->att->header.name_space == ID_ATTRIBUTE && mobj != NULL)
2537  {
2538  mem = (char *) mobj + a->att->offset;
2539  }
2540 
2541  /* save old value for AFTER triggers */
2542  if (trstate != NULL && trstate->triggers != NULL && event == TR_EVENT_UPDATE)
2543  {
2544  a->old_value = pr_make_ext_value ();
2545  if (a->old_value == NULL)
2546  {
2547  assert (er_errid () != NO_ERROR);
2548  error = er_errid ();
2549  }
2550  else
2551  {
2552  /*
2553  * this will copy the value which is unfortunate since
2554  * we're just going to throw it away later
2555  */
2556  error = obj_get_value (object, a->att, mem, NULL, a->old_value);
2557  }
2558  }
2559 
2560  /*
2561  * The following code block is for handling LOB type.
2562  * If the client is the log applier, it doesn't care LOB type.
2563  */
2565  {
2566 
2567  if (a->att->type->id == DB_TYPE_BLOB || a->att->type->id == DB_TYPE_CLOB)
2568  {
2569  DB_VALUE old;
2570  DB_TYPE value_type;
2571 
2573  error = obj_get_value (object, a->att, mem, NULL, &old);
2574  if (error == NO_ERROR && !db_value_is_null (&old))
2575  {
2576  DB_ELO *elo;
2577 
2578  value_type = db_value_type (&old);
2579  assert (value_type == DB_TYPE_BLOB || value_type == DB_TYPE_CLOB);
2580  elo = db_get_elo (&old);
2581  if (elo)
2582  {
2583  error = db_elo_delete (elo);
2584  }
2585  db_value_clear (&old);
2586  error = (error >= 0 ? NO_ERROR : error);
2587  }
2588  if (error == NO_ERROR && !db_value_is_null (a->variable))
2589  {
2590  DB_ELO dest_elo, *elo_p;
2591  char *save_meta_data;
2592 
2593  value_type = db_value_type (a->variable);
2594  assert (value_type == DB_TYPE_BLOB || value_type == DB_TYPE_CLOB);
2595  elo_p = db_get_elo (a->variable);
2596 
2597  assert (sm_ch_name ((MOBJ) class_) != NULL);
2598  save_meta_data = elo_p->meta_data;
2599  elo_p->meta_data = (char *) sm_ch_name ((MOBJ) class_);
2600  error = db_elo_copy (db_get_elo (a->variable), &dest_elo);
2601  elo_p->meta_data = save_meta_data;
2602 
2603  error = (error >= 0 ? NO_ERROR : error);
2604  if (error == NO_ERROR)
2605  {
2606  db_value_clear (a->variable);
2607  db_make_elo (a->variable, value_type, &dest_elo);
2608  (a->variable)->need_clear = true;
2609  }
2610  }
2611  } /* if (a->att->type->id == DB_TYPE_BLOB) || */
2612  } /* if (db_get_client_type () != */
2613 
2614  if (error == NO_ERROR)
2615  {
2616  /* check for template assignment that needs to be expanded */
2617  if (a->obj != NULL)
2618  {
2619  /* this is a template assignment, recurse on this template */
2620  error = obt_apply_assignments (a->obj, check_uniques, level + 1);
2621  if (error == NO_ERROR)
2622  {
2623  db_make_object (&val, a->obj->object);
2624  error = obt_apply_assignment (object, a->att, mem, &val, check_uniques);
2625  }
2626  }
2627  else
2628  {
2629  /* non-template assignment */
2630  error = obt_apply_assignment (object, a->att, mem, a->variable, check_uniques);
2631  }
2632  }
2633  }
2634 
2635  if ((error == NO_ERROR) && (object != NULL))
2636  {
2637  ws_dirty (object);
2638  }
2639 
2640  /* if we updated any shared attributes, we need to mark the class dirty */
2641  if (template_ptr->shared_was_modified)
2642  {
2643  ws_dirty (OBT_BASE_CLASSOBJ (template_ptr));
2644  }
2645 
2646  /* unpin the object */
2647  if (pin != -1)
2648  {
2649  (void) ws_pin (object, pin);
2650  }
2651 
2652  /* run after triggers */
2653  if (trstate != NULL)
2654  {
2655  if (error)
2656  {
2657  tr_abort (trstate);
2658  }
2659  else
2660  {
2661  if (event == TR_EVENT_INSERT)
2662  {
2663  error = tr_after_object (trstate, object, NULL);
2664  }
2665  else
2666  {
2667  /* mark the template as an "old" object */
2668  template_ptr->is_old_template = 1;
2669  error = tr_after_object (trstate, object, temp);
2670  }
2671  }
2672  }
2673 
2674  if (temp != NULL)
2675  {
2676  /* free this after both before and after triggers have run */
2677  free_temp_object (temp);
2678  }
2679 
2680  /*
2681  * If this is a virtual instance, we used to flush it back to the server
2682  * at this point. But that early flushing is too expensive. Consider, for
2683  * example, that all db_template-based proxy inserts go thru this code and
2684  * experience a 25-30 fold performance slowdown. Therefore, we delay
2685  * flushing dirty proxy mops for non-nested proxy inserts. It's not clear
2686  * under what conditions we can safely delay flushing of nested proxy
2687  * inserts, so we don't.
2688  */
2689  if (level > 0 && error == NO_ERROR && object && object->is_vid && vid_is_base_instance (object))
2690  {
2691  error = vid_flush_and_rehash (object);
2692  }
2693  else if (error != NO_ERROR && object && object->is_vid && vid_is_base_instance (object))
2694  {
2695  /*
2696  * if an error occurred in a nested proxy insert such as this
2697  * insert into c_h_employee values ('new_e', 123456789,
2698  * (insert into c_h_department (dept_no) values (11)),NULL)
2699  * we must decache the outer proxy object, otherwise a later flush
2700  * will generate incorrect results. Note that vid_flush_and_rehash
2701  * already decaches any offending inner nested proxy inserts.
2702  */
2703  ws_decache (object);
2704  }
2705 
2706  /*
2707  * check for unique constraint violations.
2708  * if the object has uniques and this is an insert, we must
2709  * flush the object to ensure that the btrees for the uniques
2710  * are updated correctly.
2711  * NOTE: Performed for updates now too since test & set doesn't work.
2712  */
2713  if (error == NO_ERROR)
2714  {
2715  if ((check_uniques && template_ptr->uniques_were_modified) || template_ptr->fkeys_were_modified
2716  || template_ptr->function_key_modified || template_ptr->force_flush
2717  || (template_ptr->check_serializable_conflict && template_ptr->object
2718  && !OID_ISTEMP (&(template_ptr->object->oid_info.oid))))
2719  {
2720  if ((locator_flush_class (OBT_BASE_CLASSOBJ (template_ptr)) != NO_ERROR)
2721  || (locator_flush_instance (OBT_BASE_OBJECT (template_ptr)) != NO_ERROR))
2722  {
2723  assert (er_errid () != NO_ERROR);
2724  error = er_errid ();
2725  }
2726  /* update template object if this was a partitioned class */
2727  object = OBT_BASE_OBJECT (template_ptr);
2728  }
2729  }
2730 
2731  return error;
2732 }
2733 
2734 /*
2735  * obt_set_label - This is called by the interpreter when a certain template
2736  * is referenced by a interpreter variable (label).
2737  * return: none
2738  * template(in): object template
2739  * label(in): pointer to MOP pointer
2740  *
2741  * Note :
2742  * In this case, when the template is converted into a MOP, the pointer
2743  * supplied is also set to the value of this mop.
2744  *
2745  */
2746 
2747 void
2748 obt_set_label (OBJ_TEMPLATE * template_ptr, DB_VALUE * label)
2749 {
2750  template_ptr->label = label;
2751 }
2752 
2753 /*
2754  * obt_disable_unique_checking
2755  * return: none
2756  * template(in): object template
2757  *
2758  * Note :
2759  * This is called by the interpreter when doing a bulk update to disable
2760  * unique constraint checking on a per instance basis. It is the
2761  * interpreter's responsibility to check for constraints.
2762  *
2763  */
2764 
2765 void
2767 {
2768  if (template_ptr)
2769  {
2770  template_ptr->check_uniques = 0;
2771  }
2772 }
2773 
2774 /*
2775  * obt_disable_serializable_conflict_checking : disable SERIALIZABLE conflicts
2776  * checking
2777  * return: none
2778  * template(in): object template
2779  */
2780 void
2782 {
2783  if (template_ptr)
2784  {
2785  template_ptr->check_serializable_conflict = 0;
2786  }
2787 }
2788 
2789 /*
2790  * obt_enable_unique_checking - This is used by the loader to disable unique
2791  * constraint checking for all templates created.
2792  * When templates are created this state is
2793  * incorporated in the template, see make_template()
2794  * return: The previous state is returned.
2795  * TRUE : global unique checking is enabled.
2796  * FALSE : global unique checking is disabled.
2797  * new_state(in):
2798  *
2799  */
2800 bool
2802 {
2803  bool old_state = obt_Check_uniques;
2804 
2805  obt_Check_uniques = new_state;
2806  return (old_state);
2807 }
2808 
2809 /*
2810  * obj_set_force_flush - set force_flush flag of the template
2811  *
2812  * return : void
2813  * template_ptr (in/out)
2814  */
2815 void
2817 {
2818  assert (template_ptr != NULL);
2819 
2820  template_ptr->force_flush = 1;
2821 }
2822 
2823 /*
2824  * obj_reset_force_flush - reset force_flush flag of the template
2825  *
2826  * return : void
2827  * template_ptr (in/out)
2828  */
2829 void
2831 {
2832  assert (template_ptr != NULL);
2833 
2834  template_ptr->force_flush = 0;
2835 }
2836 
2837 /*
2838  * obt_retain_after_finish
2839  * return: none
2840  * template(in):
2841  *
2842  */
2843 void
2845 {
2846  assert (template_ptr != NULL);
2847 
2848  template_ptr->discard_on_finish = 0;
2849 }
2850 
2851 /*
2852  * obt_update_internal
2853  * return: error code
2854  * template(in): object template
2855  * newobj(in): return pointer to mop of new instance
2856  * check_non_null(in): set if this is an internally defined template
2857  *
2858  */
2859 int
2860 obt_update_internal (OBJ_TEMPLATE * template_ptr, MOP * newobj, int check_non_null)
2861 {
2862  int error = NO_ERROR;
2863  char savepoint_name[80];
2864  int has_uniques = 0;
2865  int savepoint_used = 0;
2866 
2867  if (template_ptr != NULL)
2868  {
2869  error = validate_template (template_ptr);
2870  if (error == NO_ERROR)
2871  {
2872  /* allocate a new traversal counter for the check pass */
2874  error = obt_final_check (template_ptr, check_non_null, &has_uniques);
2875  if (error == NO_ERROR)
2876  {
2877 
2879  {
2880  /*
2881  * Only one of the log_applier can apply replication
2882  * logs at the same time.
2883  * Therefore, log_applier don't need to perform
2884  * savepoint at this time to maintain unique indexes.
2885  */
2886 
2887  /* do nothing */
2888  ;
2889  }
2890  else if ((template_ptr->check_uniques && has_uniques) || template_ptr->fkeys_were_modified
2891  || template_ptr->function_key_modified || template_ptr->force_flush)
2892  {
2893  /* Must perform savepoint to handle unique maintenance until the time when test & set will work
2894  * correctly. We must do a savepoint if this template or any sub template has uniques. The actual
2895  * unique tests will be done in obt_apply_assignments(). */
2896 
2897  sprintf (savepoint_name, "%s-%d", OBJ_INTERNAL_SAVEPOINT_NAME, template_savepoint_count++);
2898  if (tran_system_savepoint (savepoint_name) != NO_ERROR)
2899  {
2900  assert (er_errid () != NO_ERROR);
2901  return er_errid ();
2902  }
2903  savepoint_used = 1;
2904  }
2905 
2906  /* allocate another traversal counter for the assignment pass */
2908  error = obt_apply_assignments (template_ptr, template_ptr->check_uniques, 0);
2909  if (error == NO_ERROR)
2910  {
2911  if (newobj != NULL)
2912  {
2913  *newobj = template_ptr->object;
2914  }
2915 
2916  /* When discard_on_finish is false, caller should explictly free template */
2917  if (template_ptr->discard_on_finish)
2918  {
2919  obt_free_template (template_ptr);
2920  }
2921  }
2922  }
2923  }
2924  }
2925 
2926  /*
2927  * do we need to rollback due to failure? We don't rollback if the
2928  * trans has already been aborted.
2929  */
2930  if (error != NO_ERROR && savepoint_used && error != ER_LK_UNILATERALLY_ABORTED)
2931  {
2932  (void) tran_abort_upto_system_savepoint (savepoint_name);
2933  }
2934 
2935  return error;
2936 }
2937 
2938 /*
2939  * Don't change the external interface to allow setting the check_non_null
2940  * flag.
2941  */
2942 /*
2943  * obt_update - This will take an object template and apply all of
2944  * the assignments, creating new objects as necessary
2945  * return: error code
2946  * template(in): object template
2947  * newobj(in): return pointer to mop of new instance
2948  *
2949  * Note:
2950  * If the top level template is for a new object, the mop will be returned
2951  * through the "newobj" parameter.
2952  * Note that the template will be freed here if successful
2953  * so the caller must not asusme that it can be reused.
2954  * The check_non_null flag is set in the case where the template
2955  * is being created in response to the obj_create() function which
2956  * implements the db_create() and db_create_by_name API functions.
2957  * Unfortunately, as the functions are defined, there is no way
2958  * to supply initial values. If the class has attributes that are
2959  * defined with the NON NULL constraint, the usual template processing
2960  * refuses to create the object until the missing values
2961  * are supplied. This means that it is impossible for the "atomic"
2962  * functions like db_create() to make an object whose attributes
2963  * have the constraint. This is arguably the correct behavior but
2964  * it hoses 4GE since it isn't currently prepared to go check for
2965  * creation dependencies and use full templates instead.
2966  */
2967 int
2968 obt_update (OBJ_TEMPLATE * template_ptr, MOP * newobj)
2969 {
2970  return obt_update_internal (template_ptr, newobj, 1);
2971 }
2972 
2973 /*
2974  * make_temp_object - This is used to create a temporary object for use
2975  * in trigger processing.
2976  * return: temporary object MOP
2977  * class(in):
2978  * object(in): object template with values
2979  *
2980  */
2981 static MOP
2983 {
2984  MOP obj = NULL;
2985 
2986  if (class_ == NULL || object == NULL)
2987  {
2989  }
2990  else
2991  {
2992  obj = ws_make_temp_mop ();
2993  if (obj != NULL)
2994  {
2995  obj->class_mop = class_;
2996  obj->object = (void *) object;
2997  obj->pruning_type = object->pruning_type;
2998  /*
2999  * We have to be very careful here - we need to mimick the old oid
3000  * for "old" to behave correctly.
3001  */
3002  if (object->object)
3003  {
3004  obj->oid_info.oid = object->object->oid_info.oid;
3005  }
3006  }
3007  }
3008 
3009  return obj;
3010 }
3011 
3012 /*
3013  * free_temp_object - This frees the temporary object created by
3014  * make_temp_object. It does NOT free the template,
3015  * only the MOP.
3016  * return: none
3017  * obj(in): temporary object
3018  *
3019  */
3020 static void
3022 {
3023  if (obj != NULL)
3024  {
3025  obj->class_mop = NULL;
3026  obj->object = NULL;
3027  ws_free_temp_mop (obj);
3028  }
3029 }
3030 
3031 /*
3032  * obt_populate_known_arguments - Populate default and auto_increment
3033  * arguments of template_ptr
3034  * return: error code if unsuccessful
3035  *
3036  * template_ptr(in): temporary object
3037  *
3038  * Note :
3039  * This is necessary for INSERT templates. The assignments are marked
3040  * so that if an assignment is later made to the template with the
3041  * same name, we don't generate an error because its ok to override
3042  * a default value or an auto_increment value.
3043  * If an assignment is already found with the name, it is assumed
3044  * that an initial value has already been given and the default or
3045  * auto_increment value is ignored.
3046  *
3047  */
3048 int
3050 {
3051  if (validate_template (template_ptr))
3052  {
3053  assert (er_errid () != NO_ERROR);
3054  return er_errid ();
3055  }
3056 
3057  if (template_ptr->is_class_update)
3058  {
3059  return NO_ERROR;
3060  }
3061 
3062  if (populate_defaults (template_ptr) != NO_ERROR)
3063  {
3064  assert (er_errid () != NO_ERROR);
3065  return er_errid ();
3066  }
3067 
3068  if (obt_Enable_autoincrement != true)
3069  {
3070  return NO_ERROR;
3071  }
3072 
3073  if (populate_auto_increment (template_ptr) != NO_ERROR)
3074  {
3075  assert (er_errid () != NO_ERROR);
3076  return er_errid ();
3077  }
3078 
3079  return NO_ERROR;
3080 }
3081 
3082 /*
3083  * obt_begin_insert_values -
3084  *
3085  * return: none
3086  *
3087  */
3088 void
3090 {
3092 }
struct tr_schema_cache * triggers
Definition: class_object.h:463
unsigned decached
Definition: work_space.h:152
#define ER_LK_UNILATERALLY_ABORTED
Definition: error_code.h:130
static void begin_template_traversal(void)
DB_VALUE * old_value
int tran_system_savepoint(const char *savept_name)
#define DB_GET_STRING_PRECISION(v)
Definition: dbtype.h:139
bool classobj_has_unique_constraint(SM_CONSTRAINT *constraints)
#define ER_OBJ_INVALID_TEMPLATE
Definition: error_code.h:303
#define WS_IS_DELETED(mop)
Definition: work_space.h:284
#define NO_ERROR
Definition: error_code.h:46
DB_COLLECTION * db_get_set(const DB_VALUE *value)
int db_value_scale(const DB_VALUE *value)
void ws_class_has_object_dependencies(MOP class_mop)
Definition: work_space.c:3166
static void obt_free_template(OBJ_TEMPLATE *template_ptr)
char * obj_alloc(SM_CLASS *class_, int bound_bit_status)
unsigned discard_on_finish
TP_DOMAIN_STATUS tp_domain_check(const TP_DOMAIN *domain, const DB_VALUE *value, TP_MATCH exact_match)
int serial_get_next_value(DB_VALUE *value, OID *oid_p, int cached_num, int num_alloc, int is_auto_increment)
int do_get_serial_cached_num(int *cached_num, MOP serial_obj)
#define ER_OBJ_TEMPLATE_INTERNAL
Definition: error_code.h:281
static void obt_free_assignment(OBJ_TEMPASSIGN *assign)
unsigned is_autoincrement_set
enum au_fetchmode AU_FETCHMODE
void area_destroy(AREA *area)
Definition: area_alloc.c:247
char * MOBJ
Definition: work_space.h:174
unsigned function_key_modified
bool obt_Last_insert_id_generated
#define TP_IS_SET_TYPE(typenum)
static int obt_apply_assignments(OBJ_TEMPLATE *template_ptr, int check_uniques, int level)
#define DB_GET_NUMERIC_SCALE(val)
Definition: dbtype.h:136
static DB_VALUE * check_att_domain(SM_ATTRIBUTE *att, DB_VALUE *proposed_value)
void ws_dirty(MOP op)
Definition: work_space.c:1622
void obt_begin_insert_values(void)
int tm_Tran_index
#define ER_REFERENCE_TO_NON_REFERABLE_NOT_ALLOWED
Definition: error_code.h:1231
DB_TYPE
Definition: dbtype_def.h:670
#define AU_TYPE
Definition: authenticate.h:67
int mq_update_attribute(DB_OBJECT *vclass_object, const char *attr_name, DB_OBJECT *real_class_object, DB_VALUE *virtual_value, DB_VALUE *real_value, const char **real_name, int db_auth)
int obt_populate_known_arguments(OBJ_TEMPLATE *template_ptr)
int shared_count
Definition: class_object.h:723
void obt_area_final(void)
int sm_check_class_domain(TP_DOMAIN *domain, MOP class_)
TP_DOMAIN * domain
Definition: class_object.h:444
unsigned uniques_were_modified
void tr_abort(TR_STATE *state)
int obj_assign_value(MOP op, SM_ATTRIBUTE *att, char *mem, DB_VALUE *value)
SM_ATTRIBUTE * attributes
Definition: class_object.h:721
struct setobj * set
Definition: db_set.h:43
unsigned int traversal
int obt_set(OBJ_TEMPLATE *template_ptr, const char *attname, DB_VALUE *value)
int db_make_object(DB_VALUE *value, DB_C_OBJECT *obj)
DB_VALUE * label
int db_make_pointer(DB_VALUE *value, DB_C_POINTER ptr)
int obt_update(OBJ_TEMPLATE *template_ptr, MOP *newobj)
int setobj_get_element_ptr(COL *col, int index, DB_VALUE **result)
Definition: set_object.c:5708
OBJ_TEMPASSIGN ** assignments
SM_DEFAULT_VALUE default_value
Definition: class_object.h:451
int vid_flush_and_rehash(MOP mop)
struct sm_component * next
Definition: class_object.h:384
bool obt_Check_uniques
static int access_object(OBJ_TEMPLATE *template_ptr, MOP *object, MOBJ *objptr)
int db_elo_copy(DB_ELO *src, DB_ELO *dest)
Definition: db_elo.c:102
void ws_free_temp_mop(MOP op)
Definition: work_space.c:356
static int check_constraints(SM_ATTRIBUTE *att, DB_VALUE *value, unsigned force_check_not_null)
SM_ATTRIBUTE * classobj_find_attribute(SM_CLASS *class_, const char *name, int class_attribute)
void obt_reset_force_flush(OBJ_TEMPLATE *template_ptr)
SM_NAME_SPACE name_space
Definition: class_object.h:386
int er_errid(void)
int set_size(DB_COLLECTION *set)
Definition: set_object.c:3036
const char * name
enum tp_domain_status TP_DOMAIN_STATUS
#define OBT_BASE_CLASS(template_ptr)
void obt_retain_after_finish(OBJ_TEMPLATE *template_ptr)
TR_TRIGLIST * triggers
MOP locator_add_instance(MOBJ instance, MOP class_mop)
Definition: locator_cl.c:5782
PR_TYPE * tp_Type_object
int ml_find(DB_OBJLIST *list, MOP mop)
Definition: work_space.c:4465
int db_make_elo(DB_VALUE *value, DB_TYPE type, const DB_ELO *elo)
#define AU_ALTER
Definition: authenticate.h:73
unsigned force_flush
DB_VALUE * obt_check_assignment(SM_ATTRIBUTE *att, DB_VALUE *proposed_value, SM_VALIDATION *valid, unsigned force_check_not_null)
AREA * area_create(const char *name, size_t element_size, size_t alloc_count)
Definition: area_alloc.c:146
SM_VALIDATION * valid
Definition: class_object.h:901
DB_ELO * db_get_elo(const DB_VALUE *value)
unsigned fkeys_were_modified
#define ERROR0(error, code)
Definition: error_manager.h:48
unsigned shared_was_modified
int db_elo_delete(DB_ELO *elo)
Definition: db_elo.c:115
static AREA * Template_area
int sm_get_descriptor_component(MOP op, SM_DESCRIPTOR *desc, int for_update, SM_CLASS **class_ptr, SM_COMPONENT **comp_ptr)
#define CT_SERIAL_NAME
Definition: transform.h:135
DB_DEFAULT_EXPR_TYPE default_expr_type
Definition: dbtype_def.h:1204
static DB_OBJECT * is_class(OID *obj_oid, OID *class_oid)
Definition: compactdb.c:637
int pr_free_ext_value(DB_VALUE *value)
static unsigned int obj_Template_traversal
unsigned force_check_not_null
int att_count
Definition: class_object.h:720
int class_attribute_count
Definition: class_object.h:724
DB_DEFAULT_EXPR default_expr
Definition: class_object.h:395
static AREA * Assignment_area
static unsigned int template_savepoint_count
#define ER_IT_NOT_UPDATABLE_STMT
Definition: error_code.h:506
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
Definition: db_set.h:35
const char * sm_ch_name(const MOBJ clobj)
struct tr_schema_cache * triggers
Definition: class_object.h:756
bool mq_is_updatable_attribute(DB_OBJECT *vclass_object, const char *attr_name, DB_OBJECT *real_class_object)
int obt_quit(OBJ_TEMPLATE *template_ptr)
int tran_abort_upto_system_savepoint(const char *savepoint_name)
#define assert(x)
int obt_set_obt(OBJ_TEMPLATE *template_ptr, const char *attname, OBJ_TEMPLATE *value)
void obt_set_force_flush(OBJ_TEMPLATE *template_ptr)
#define AUTO_INCREMENT_SERIAL_NAME_MAX_LENGTH
Definition: transform.h:180
unsigned check_uniques
int au_fetch_class(MOP op, SM_CLASS **class_ptr, AU_FETCHMODE fetchmode, DB_AUTH type)
#define ERROR1(error, code, arg1)
Definition: error_manager.h:56
int tp_domain_status_er_set(TP_DOMAIN_STATUS status, const char *file_name, const int line_no, const DB_VALUE *src, const TP_DOMAIN *domain)
int ws_pin(MOP mop, int pin)
Definition: work_space.c:2989
static OBJ_TEMPLATE * make_template(MOP object, MOP classobj)
struct db_object * class_mop
Definition: work_space.h:121
OBJ_TEMPLATE * obt_def_object(MOP class_mop)
static int obt_assign_obt(OBJ_TEMPLATE *template_ptr, SM_ATTRIBUTE *att, int base_assignment, OBJ_TEMPLATE *value)
DB_TYPE db_value_type(const DB_VALUE *value)
#define OID_ISTEMP(oidp)
Definition: oid.h:80
#define ER_SM_OBJECT_ID_NOT_SET
Definition: error_code.h:571
static int obt_final_check_set(SETREF *setref, int *has_uniques)
static int populate_auto_increment(OBJ_TEMPLATE *template_ptr)
int numeric_db_value_coerce_from_num(DB_VALUE *src, DB_VALUE *dest, DB_DATA_STATUS *data_status)
struct obj_template * obj
#define DB_VALUE_DOMAIN_TYPE(value)
Definition: dbtype.h:70
DB_OBJECT * mq_fetch_one_real_class(DB_OBJECT *vclass_object)
int locator_flush_class(MOP class_mop)
Definition: locator_cl.c:5068
int obt_assign(OBJ_TEMPLATE *template_ptr, SM_ATTRIBUTE *att, int base_assignment, DB_VALUE *value, SM_VALIDATION *valid)
static enum scanner_mode mode
bool vid_is_base_instance(MOP mop)
const char * sm_get_ch_name(MOP op)
DB_OBJECT * db_get_object(const DB_VALUE *value)
static void cache_validation(SM_VALIDATION *valid, DB_VALUE *value)
VID_OID oid_info
Definition: work_space.h:120
int classobj_get_cached_constraint(SM_CONSTRAINT *constraints, SM_CONSTRAINT_TYPE type, BTID *id)
TP_DOMAIN_STATUS tp_value_cast(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain, bool implicit_coercion)
#define ER_OBJ_DUPLICATE_ASSIGNMENT
Definition: error_code.h:298
static int obt_convert_set_templates(SETREF *setref, int check_uniques)
#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
void obt_disable_serializable_conflict_checking(OBJ_TEMPLATE *template_ptr)
#define ER_OBJ_ATTRIBUTE_CANT_BE_NULL
Definition: error_code.h:276
struct pr_type * type
Definition: object_domain.h:76
DB_OBJECT * db_get_class(MOP obj)
Definition: db_info.c:589
struct pr_type * type
Definition: class_object.h:443
int pt_is_reference_to_reusable_oid(DB_VALUE *val)
static MOP make_temp_object(DB_OBJECT *class_, OBJ_TEMPLATE *object)
DB_VALUE * pr_make_ext_value(void)
unsigned int schema_id
#define ERROR3(error, code, arg1, arg2, arg3)
Definition: error_manager.h:72
int au_fetch_instance_force(MOP op, MOBJ *obj_ptr, AU_FETCHMODE fetchmode, LC_FETCH_VERSION_TYPE fetch_version_type)
#define ER_OBJ_INVALID_ATTRIBUTE
Definition: error_code.h:273
int ml_ext_add(DB_OBJLIST **list, MOP mop, int *added_ptr)
Definition: work_space.c:4877
int obt_desc_set(OBJ_TEMPLATE *template_ptr, SM_DESCRIPTOR *desc, DB_VALUE *value)
int tr_prepare_class(TR_STATE **state_p, TR_SCHEMA_CACHE *cache, MOP class_mop, DB_TRIGGER_EVENT event)
static OBJ_TEMPASSIGN * obt_make_assignment(OBJ_TEMPLATE *template_ptr, SM_ATTRIBUTE *att)
MOP vid_get_referenced_mop(MOP mop)
int pr_clear_value(DB_VALUE *value)
unsigned is_auto_increment
#define AU_INSERT
Definition: authenticate.h:70
int sm_active_triggers(MOP class_mop, SM_CLASS *class_, DB_TRIGGER_EVENT event_type)
#define DB_DEFAULT_SCALE
Definition: dbtype_def.h:561
bool obt_enable_unique_checking(bool new_state)
SM_CONSTRAINT * constraints
Definition: class_object.h:454
TP_DOMAIN_STATUS tp_check_value_size(TP_DOMAIN *domain, DB_VALUE *value)
int locator_flush_instance(MOP mop)
Definition: locator_cl.c:5236
SM_CLASS * base_class
int obt_check_missing_assignments(OBJ_TEMPLATE *template_ptr)
#define TP_IS_CHAR_TYPE(typeid)
unsigned is_class_update
int obt_area_init(void)
static void error(const char *msg)
Definition: gencat.c:331
TP_DOMAIN * set_get_domain(DB_COLLECTION *set)
Definition: set_object.c:3319
unsigned int flags
Definition: class_object.h:459
#define DB_DEFAULT_PRECISION
Definition: dbtype_def.h:558
#define ER_OBJ_ATTRIBUTE_TYPE_CONFLICT
Definition: error_code.h:274
#define AU_UPDATE
Definition: authenticate.h:71
static int obt_final_check(OBJ_TEMPLATE *template_ptr, int check_non_null, int *has_uniques)
bool db_value_is_null(const DB_VALUE *value)
DB_AUTH
Definition: dbtype_def.h:239
#define ARG_FILE_LINE
Definition: error_manager.h:44
DB_VALUE * variable
MOP ws_make_temp_mop(void)
Definition: work_space.c:336
unsigned is_default
DB_OBJLIST * validated_classes
Definition: class_object.h:880
int pr_clone_value(const DB_VALUE *src, DB_VALUE *dest)
void ws_decache(MOP mop)
Definition: work_space.c:2701
DB_OBJECT * last_class
Definition: class_object.h:879
static int quick_validate(SM_VALIDATION *valid, DB_VALUE *value)
MOP vid_add_virtual_instance(MOBJ instance, MOP vclass_mop, MOP bclass_mop, SM_CLASS *bclass)
int db_get_client_type(void)
Definition: db_admin.c:489
DB_DATA_STATUS
SM_ATTRIBUTE * att
DB_DOMAIN * last_setdomain
Definition: class_object.h:882
void * object
Definition: work_space.h:123
#define free_and_init(ptr)
Definition: memory_alloc.h:147
unsigned char pruning_type
Definition: work_space.h:138
bool sm_is_reuse_oid_class(MOP op)
int obj_get_value(MOP op, SM_ATTRIBUTE *att, void *mem, DB_VALUE *source, DB_VALUE *dest)
SM_COMPONENT header
Definition: class_object.h:441
int db_value_precision(const DB_VALUE *value)
#define ERROR2(error, code, arg1, arg2)
Definition: error_manager.h:64
static int obt_apply_assignment(MOP op, SM_ATTRIBUTE *att, char *mem, DB_VALUE *value, int check_uniques)
#define ER_OBJ_INVALID_ARGUMENTS
Definition: error_code.h:275
DB_TRIGGER_EVENT
Definition: dbtype_def.h:356
void obt_set_label(OBJ_TEMPLATE *template_ptr, DB_VALUE *label)
OBJ_TEMPLATE * obt_edit_object(MOP object)
bool obt_Enable_autoincrement
void * area_alloc(AREA *area)
Definition: area_alloc.c:360
SM_CLASS_TYPE class_type
Definition: class_object.h:713
#define ER_OBJ_STRING_OVERFLOW
Definition: error_code.h:293
void obt_disable_unique_checking(OBJ_TEMPLATE *template_ptr)
int area_free(AREA *area, void *ptr)
Definition: area_alloc.c:514
unsigned int sm_local_schema_version(void)
int tr_before_object(TR_STATE *state, DB_OBJECT *current, DB_OBJECT *temp)
static MOP create_template_object(OBJ_TEMPLATE *template_ptr)
#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
#define DB_IS_NULL(value)
Definition: dbtype.h:63
#define ER_OBJ_DOMAIN_CONFLICT
Definition: error_code.h:285
#define OBJ_INTERNAL_SAVEPOINT_NAME
bool classobj_has_function_constraint(SM_CONSTRAINT *constraints)
static int populate_defaults(OBJ_TEMPLATE *template_ptr)
MOP sm_get_class(MOP obj)
#define DB_GET_NUMERIC_PRECISION(val)
Definition: dbtype.h:133
#define ER_OBJ_MISSING_NON_NULL_ASSIGN
Definition: error_code.h:296
unsigned is_temp
Definition: work_space.h:149
const char * name
Definition: class_object.h:385
int au_fetch_instance(MOP op, MOBJ *obj_ptr, AU_FETCHMODE mode, LC_FETCH_VERSION_TYPE fetch_version_type, DB_AUTH type)
struct sm_attribute * order_link
Definition: class_object.h:461
bool do_Trigger_involved
int db_value_clear(DB_VALUE *value)
Definition: db_macro.c:1588
int obt_find_attribute(OBJ_TEMPLATE *template_ptr, int use_base_class, const char *name, SM_ATTRIBUTE **attp)
DB_TYPE last_type
Definition: class_object.h:884
MOP sm_find_class(const char *name)
unsigned traversed
#define OBT_BASE_CLASSOBJ(template_ptr)
#define OBT_BASE_OBJECT(template_ptr)
#define SET_AUTO_INCREMENT_SERIAL_NAME(SR_NAME, CL_NAME, AT_NAME)
Definition: transform.h:176
int locator_is_class(MOP mop, DB_FETCH_MODE hint_purpose)
Definition: locator_cl.c:239
char * meta_data
Definition: dbtype_def.h:949
unsigned write_lock
#define WS_MOP_IS_NULL(mop)
Definition: work_space.h:328
SM_ATTRIBUTE * ordered_attributes
Definition: class_object.h:753
int obt_update_internal(OBJ_TEMPLATE *template_ptr, MOP *newobj, int check_non_null)
int tr_after_object(TR_STATE *state, DB_OBJECT *current, DB_OBJECT *temp)
static void free_temp_object(MOP obj)
DB_C_POINTER db_get_pointer(const DB_VALUE *value)
MOP do_get_serial_obj_id(DB_IDENTIFIER *serial_obj_id, DB_OBJECT *serial_class_mop, const char *serial_name)
#define TP_IS_BIT_TYPE(typeid)
static int validate_template(OBJ_TEMPLATE *temp)
SM_CLASS * class_
int setobj_size(COL *col)
Definition: set_object.c:4948
#define ER_OBJ_NOT_A_CLASS
Definition: error_code.h:288
unsigned check_serializable_conflict
#define ER_OBJ_INVALID_TEMP_OBJECT
Definition: error_code.h:302
#define DB_GET_BIT_PRECISION(v)
Definition: dbtype.h:142
unsigned is_old_template
#define TM_TRAN_ISOLATION()
int db_value_domain_init(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale)
Definition: db_macro.c:153
unsigned is_vid
Definition: work_space.h:148