CUBRID Engine  latest
load_sa_loader.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * load_sa_loader.cpp - Database loader (Optimized version)
21  */
22 
23 #include "config.h"
24 
25 #include <assert.h>
26 #include <ctype.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <fstream>
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #if defined (WINDOWS)
35 #include <io.h>
36 #else
37 #include <unistd.h>
38 #endif /* !WINDOWS */
39 
40 #include "authenticate.h"
41 #include "db.h"
42 #include "db_json.hpp"
43 #include "dbi.h"
44 #include "dbtype.h"
45 #include "elo.h"
46 #include "environment_variable.h"
47 #include "execute_schema.h"
48 #include "intl_support.h"
49 #include "language_support.h"
51 #include "load_driver.hpp"
52 #include "load_error_handler.hpp"
53 #include "load_object.h"
54 #include "load_object_table.h"
55 #include "load_sa_loader.hpp"
56 #include "load_scanner.hpp"
57 #include "locator_cl.h"
58 #include "memory_alloc.h"
59 #include "message_catalog.h"
60 #include "network.h"
61 #include "object_accessor.h"
62 #include "object_primitive.h"
63 #include "object_representation.h"
64 #include "porting.h"
65 #include "schema_manager.h"
66 #include "set_object.h"
67 #include "system_parameter.h"
68 #include "thread_manager.hpp"
69 #include "transaction_cl.h"
70 #include "trigger_manager.h"
71 #include "utility.h"
72 #include "work_space.h"
73 
74 using namespace cubload;
75 
76 const std::size_t LDR_MAX_ARGS = 32;
77 
78 /* filter out ignorable errid */
79 #define FILTER_OUT_ERR_INTERNAL(err, expr) \
80  ( err = ((expr) == NO_ERROR ? NO_ERROR : er_filter_errid(false)) )
81 
82 #define CHECK_ERR(err, expr) \
83  do { \
84  int inner_err = (expr); \
85  if (FILTER_OUT_ERR_INTERNAL(err, inner_err) != NO_ERROR) { \
86  display_error(0); \
87  goto error_exit; \
88  } \
89  if (inner_err != NO_ERROR && err == NO_ERROR ) { \
90  skip_current_instance = true; \
91  } \
92  } while (0)
93 
94 /*
95  * CHECK_PARSE_ERR is used by the element setters to output more information
96  * about the source token and destination attribute being processed, if
97  * an error occurs.
98  */
99 #define CHECK_PARSE_ERR(err, expr, cont, type, str) \
100  do { \
101  int inner_err = (expr); \
102  if (FILTER_OUT_ERR_INTERNAL(err, inner_err) != NO_ERROR) { \
103  display_error(0); \
104  parse_error(cont, type, str); \
105  goto error_exit; \
106  } \
107  if (inner_err != NO_ERROR && err == NO_ERROR) { \
108  skip_current_instance = true; \
109  } \
110  } while (0)
111 
112 #define CHECK_PTR(err, expr) \
113  do { \
114  if ((expr) == NULL) { \
115  display_error(0); \
116  if (err == NO_ERROR) { \
117  if ((err = er_errid()) == NO_ERROR) { /* need to set errid */ \
118  err = ER_GENERIC_ERROR; \
119  er_set(ER_ERROR_SEVERITY, ARG_FILE_LINE, err, 0); \
120  } \
121  } \
122  goto error_exit; \
123  } \
124  } while (0)
125 
126 #define CHECK_CONTEXT_VALIDITY(context, expr) \
127  do { \
128  if ((expr)) { \
129  ldr_increment_err_count (context, 1); \
130  context->valid = false; \
131  } \
132  } while (0)
133 
134 #define RETURN_IF_NOT_VALID(context) \
135  do { \
136  if (!context->valid) return; \
137  } while (0)
138 
139 #define RETURN_IF_NOT_VALID_WITH(context, ret) \
140  do { \
141  if (!context->valid) return (ret); \
142  } while (0)
143 
144 #define CHECK_VALIDATION_ONLY(context) \
145  do { \
146  if (context->validation_only) goto error_exit; \
147  } while (0)
148 
149 #define GET_DOMAIN(context, domain) \
150  do { \
151  if (context->collection == NULL && context->valid) \
152  domain = context->attrs[context->next_attr].att->domain; \
153  else \
154  domain = context->set_domain; \
155  } while (0)
156 
157 #define CHECK_SKIP() \
158  do { \
159  if (skip_current_class == true) { \
160  return; \
161  } \
162  } while (0)
163 
164 #define CHECK_SKIP_WITH(ret) \
165  do { \
166  if (skip_current_class == true) { \
167  return (ret); \
168  } \
169  } while (0)
170 
171 typedef struct ldr_context LDR_CONTEXT;
172 
173 typedef void (*LDR_POST_COMMIT_HANDLER) (int64_t);
174 typedef void (*LDR_POST_INTERRUPT_HANDLER) (int64_t);
175 
176 typedef int (*LDR_SETTER) (LDR_CONTEXT *, const char *, size_t, SM_ATTRIBUTE *);
177 typedef int (*LDR_ELEM) (LDR_CONTEXT *, const char *, size_t, DB_VALUE *);
178 
179 /*
180  * LDR_ATTDESC
181  * Loader attribute description structure.
182  * This contains the description, attribute, and fast setter function
183  * for the attribute.
184  * parser_* holds the parser token information and is used when parsing
185  * the constructor syntax, to simulate the parse phase when creating a
186  * constructor object.
187  */
188 
189 typedef struct LDR_ATTDESC
190 {
191 
192  DB_ATTDESC *attdesc; /* Attribute descriptor */
193  SM_ATTRIBUTE *att; /* Attribute */
194  LDR_SETTER setter[NUM_LDR_TYPES]; /* Setter functions indexed by type */
195 
196  char *parser_str; /* used as a holder to hold the parser strings when parsing method arguments. */
197  size_t parser_str_len; /* Length of parser token string */
198  size_t parser_buf_len; /* Length of parser token buffer */
199  data_type parser_type; /* Used when parsing method arguments, to store */
200  /* the type information. */
201 
202  DB_OBJECT *ref_class; /* Class referenced by object reference */
203  int instance_id; /* Instance id of instance referenced by ref_class object ref */
204  TP_DOMAIN *collection_domain; /* Best domain for collection */
205 
206 } LDR_ATTDESC;
207 
208 /*
209  * LDR_MOP_TEMPOID_MAP
210  * LDR_MOP_TEMPOID_MAPS
211  * Information about a temporary OID created while parsing the load file,
212  * LDR_MOP_TEMPOID_MAP.
213  * An array of these structures will be used to hold MOP -> CLASS_TABLE
214  * entry information, LDR_MOP_TEMPOID_MAPS. The CLASS_TABLE and id will
215  * be used to access the INST_INFO structure to directly access the
216  * oid pointer in the instances array of the loaders otable.
217  * Prior to flushing and LC_OIDSET is created with the list
218  * of mops in this structure. This set is sent to the server to obtain
219  * permanent OIDs. The loader's otable is updated with the permanent OIDs
220  * sent back from the server.
221  */
222 
223 typedef struct ldr_mop_tempoid_map
224 {
225 
226  MOP mop; /* Workspace MOP */
227  CLASS_TABLE *table; /* otable class table */
228  int id; /* instance identifier in table */
229 
231 
232 typedef struct ldr_mop_tempoid_maps
233 {
234 
235  int count; /* number of LDR_MOP_TEMPOID_MAP maps */
236  int index; /* next available slot */
237  int size; /* size of LDR_MOP_TEMPOID_MAP array */
238 
239  LDR_MOP_TEMPOID_MAP *mop_tempoid_maps; /* array of maps */
240 
242 
244 
245 /*
246  * LDR_CONTEXT
247  * The loader context, holds the state information for the parser actions
248  * to use when triggered.
249  */
250 
252 {
253  DB_OBJECT *cls; /* Current class */
254 
255  char *class_name; /* Class name of current class */
256 
257  DB_OBJECT *obj; /* Instance of class */
258  MOBJ mobj; /* Memory object of instance */
259  int obj_pin; /* pins returned when pinning the */
260  int class_pin; /* current class */
261  int class_type; /* not partitioned, partitioned, partition */
262  LDR_ATTDESC *attrs; /* array of attribute descriptors for */
263  /* the current class. */
264  int num_attrs; /* Number of attributes for class */
265  int next_attr; /* Index of current attribute */
266 
267  unsigned int instance_started:1; /* Instance stared flag */
268  bool valid; /* State of the loader. */
269 
270  load_args *args; /* loaddb executable arguments */
271 
272  int err_count; /* Current error count for instance */
273  int err_total; /* Total error counter */
274 
275  int64_t inst_count; /* Instance count for this class */
276  int64_t inst_total; /* Total instance count */
277  int inst_num; /* Instance id of current instance */
278 
279  int flush_total; /* Total number of flushes performed */
280  /* for the current class */
281  int flush_interval; /* The number of instances before a */
282  /* flush is performed */
283 
284  CLASS_TABLE *table; /* Table of instances currently */
285  /* accumlated for the class */
286 
287  bool validation_only; /* Syntax checking only flag */
288 
289  INTL_LANG lang_id; /* Current language */
290 
291  DB_COLLECTION *collection; /* Pointer to hang collection from */
292  TP_DOMAIN *set_domain; /* Set domain of current set if */
293  /* applicable. */
294 
295  SM_METHOD *constructor; /* Method constructor */
296  int arg_index; /* Index where arguments start in */
297  /* the attr descriptor array. */
298  int max_arg; /* Maximum number of arguments */
299  SM_METHOD_ARGUMENT **method_args; /* Pointer to the arguments */
300  int arg_count; /* argument counter */
301 
302  DB_OBJECT *id_class; /* Holds class ptr when processing ids */
303 
304  attribute_type attr_type; /* type of attribute if class */
305  /* attribute, shared, default */
306 
307  int status_count; /* Count used to indicate number of */
308  /* instances committed for internal */
309  /* debugging use only */
310  int status_counter; /* Internal debug instance counter */
311  int commit_counter; /* periodic commit counter */
312  int default_count; /* the number of instances with */
313 };
314 
315 static bool skip_current_class = false;
316 static bool skip_current_instance = false;
317 
318 extern bool locator_Dont_check_foreign_key; /* from locator_sr.h */
319 
320 /*
321  * ldr_Current_context, ldr_Context
322  * Global variables holding the parser current context information.
323  * This pointer is exported and used by the parser module ld.g
324  *
325  */
328 
329 // Global driver instance for client loader
331 
332 /*
333  * ldr_Hint_locks
334  * ldr_Hint_class_names
335  * ldr_Hint_subclasses
336  * ldr_Hint_flags
337  * Global array used to hold the class read, instance write lock
338  * set up at initialization. This will be used by ldr_find_class()
339  * This is a temporary solution to fix the client/server deadlock problem.
340  * This needs to be done for all classes, perhaps attached to the otable.
341  */
342 #define LDR_LOCKHINT_COUNT 1
347 
348 /*
349  * elem_converter
350  * array to fucntions indexed by attribute type for for setting elements in
351  * in a collection.
352  */
354 
355 /*
356  * Total_objects
357  * Global total object count.
358  */
359 static int64_t Total_objects = 0;
360 static int64_t Last_committed_line = 0;
361 static int Total_fails = 0;
362 static int64_t Total_objects_loaded = 0; /* The number of objects inserted if an interrupted occurred. */
363 
364 /*
365  * ldr_post_commit_handler
366  * Post commit callback function. Called with number of instances
367  * committed.
368  */
370 
371 /*
372  * ldr_post_interrupt_handler
373  * Post commit interrupt handler. Called with number of instances
374  * committed.
375  */
376 
378 
379 /*
380  * ldr_Load_interrupted
381  * Global flag which is turned on when an interrupt is received, via
382  * Values : interrupt_type :
383  * LDR_NO_INTERRUPT
384  * LDR_STOP_AND_ABORT_INTERRUPT
385  * LDR_STOP_AND_COMMIT_INTERRUPT
386  */
387 
390 
391 static jmp_buf *ldr_Jmp_buf_ptr = NULL;
392 static jmp_buf ldr_Jmp_buf; /* Jump buffer for loader to jump to if we have an interrupt */
393 
394 /*
395  * Id_map
396  * Id_map_size
397  * The global class id map.
398  * The class id map provides a textually shorter way to reference classes.
399  * When the %class <name> <id> statement is parsed, an entry will be made
400  * in this map table so the class can be referenced by id number rather
401  * than continually using the full class name.
402  */
403 static DB_OBJECT **Id_map = NULL;
404 static int Id_map_size = 0;
405 
406 /*
407  * internal_classes
408  * Global list of internal_classes.
409  * These are the classes that we don't allow to be loaded.
410  * Initialized by clist_init().
411  */
413 
414 /*
415  * DB_VALUE TEMPLATES
416  *
417  * These templates are used to avoid the overhead of calling
418  * db_value_domain_init incessantly. Incredibly, that adds up when you're
419  * dealing with thousands of attributes and values.
420  *
421  * This is very dangerous from a maintenance standpoint, because it means
422  * that this code now has to know and obey all of the quirks for the various
423  * fields. If any of the handling in dbtype.h and/or db_macro.c changes,
424  * this code will probably need to change, too.
425  */
426 
446 
447 /* default for 64 bit signed big integers, i.e., 9223372036854775807 (0x7FFFFFFFFFFFFFFF) */
448 #define MAX_DIGITS_FOR_BIGINT 19
449 /* default for 32 bit signed integers, i.e., 2147483647 (0x7FFFFFFF) */
450 #define MAX_DIGITS_FOR_INT 10
451 #define MAX_DIGITS_FOR_SHORT 5
452 
453 #define ROUND(x) (int)((x) > 0 ? ((x) + .5) : ((x) - .5))
454 
455 #define PARSE_ELO_STR(str, new_len) \
456 do \
457  { \
458  if (str[0] == '\"') \
459  str++; \
460  new_len = (int) strlen (str); \
461  if (new_len && str[new_len-1] == '\"') \
462  new_len--; \
463  } \
464 while (0)
465 
466 /*
467  * presize for mop_tempoid_map array.
468  * Also used as the increment size to grow the maps array.
469  */
470 #define LDR_MOP_TEMPOID_MAPS_PRESIZE 1000
471 #define LDR_ARG_GROW_SIZE 128
472 
473 /* Loader initialization and shutdown functions */
474 static int ldr_start ();
475 static int ldr_destroy (LDR_CONTEXT *context, int err);
476 static int ldr_init (load_args *args);
477 static void ldr_init_driver ();
478 static int ldr_final (void);
479 
480 /* Statistics updating/retrieving functions */
481 static void ldr_stats (int *errors, int64_t *objects, int *defaults, int64_t *lastcommit, int *fails);
482 static int ldr_update_statistics (void);
483 
484 /* Callback functions */
485 static void ldr_register_post_commit_handler ();
487 static void ldr_signal_handler (void);
488 static void ldr_report_num_of_commits (int64_t num_committed);
489 static void ldr_get_num_of_inserted_objects (int64_t num_objects);
490 
491 /* Action to initialize the parser context to deal with a new class */
492 static void ldr_act_init_context (LDR_CONTEXT *context, const char *class_name, size_t len);
493 
494 /* Action to deal with attribute names and argument names */
496 
497 static void ldr_act_add_attr (LDR_CONTEXT *context, const char *attr_name, size_t len);
498 
499 /* Actions for object references */
500 static void ldr_act_set_ref_class_id (LDR_CONTEXT *context, int id);
501 static void ldr_act_set_ref_class (LDR_CONTEXT *context, char *name);
502 static void ldr_act_set_instance_id (LDR_CONTEXT *context, int id);
503 static DB_OBJECT *ldr_act_get_ref_class (LDR_CONTEXT *context);
504 
505 /* Special action for class, shared, default attributes */
506 static void ldr_act_restrict_attributes (LDR_CONTEXT *context, attribute_type type);
507 
508 /* Actions for constructor syntax */
509 static int ldr_act_set_constructor (LDR_CONTEXT *context, const char *name);
510 static int ldr_act_add_argument (LDR_CONTEXT *context, const char *name);
511 
512 static void ldr_act_set_skip_current_class (char *class_name, size_t size);
513 static bool ldr_is_ignore_class (const char *class_name, size_t size);
514 
515 /* error handling functions */
516 static void ldr_increment_err_count (LDR_CONTEXT *context, int i);
517 
518 static void ldr_clear_err_count (LDR_CONTEXT *context);
519 static void ldr_clear_err_total (LDR_CONTEXT *context);
520 static const char *ldr_class_name (LDR_CONTEXT *context);
521 static const char *ldr_attr_name (LDR_CONTEXT *context);
522 static int select_set_domain (LDR_CONTEXT *context, TP_DOMAIN *domain, TP_DOMAIN **set_domain_ptr);
523 static int check_object_domain (LDR_CONTEXT *context, DB_OBJECT *class_, DB_OBJECT **actual_class);
524 static int check_class_domain (LDR_CONTEXT *context);
525 static void idmap_init (void);
526 static void idmap_final (void);
527 static int idmap_grow (int size);
528 static int ldr_assign_class_id (DB_OBJECT *class_, int id);
529 static DB_OBJECT *ldr_find_class (const char *class_name);
530 static DB_OBJECT *ldr_get_class_from_id (int id);
531 static void ldr_clear_context (LDR_CONTEXT *context);
532 static void ldr_clear_and_free_context (LDR_CONTEXT *context);
533 static void ldr_internal_error (LDR_CONTEXT *context);
534 static void display_error_line (int adjust);
535 static void display_error (int adjust);
536 static void ldr_invalid_class_error (LDR_CONTEXT *context);
537 static void parse_error (LDR_CONTEXT *context, DB_TYPE token_type, const char *token);
538 static int clist_init (void);
539 static void clist_final (void);
540 static int is_internal_class (DB_OBJECT *class_);
541 static void ldr_act_elem (LDR_CONTEXT *context, const char *str, size_t len, data_type type);
542 static void ldr_act_attr (LDR_CONTEXT *context, const char *str, size_t len, data_type type);
543 static void ldr_act_meth (LDR_CONTEXT *context, const char *str, size_t len, data_type type);
544 static int ldr_mismatch (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
545 static int ldr_ignore (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
546 static int ldr_generic (LDR_CONTEXT *context, DB_VALUE *value);
547 static int ldr_null_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
548 static int ldr_null_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
549 static int ldr_class_attr_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att,
550  DB_VALUE *val);
551 static void ldr_act_class_attr (LDR_CONTEXT *context, const char *str, size_t len, data_type type);
552 static int ldr_sys_user_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
553 static int ldr_sys_class_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
554 static int ldr_int_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
555 static int ldr_int_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
556 static int ldr_int_db_bigint (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
557 static int ldr_int_db_int (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
558 static int ldr_int_db_short (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
559 static int ldr_str_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
560 static int ldr_str_db_char (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
561 static int ldr_str_db_varchar (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
562 static int ldr_str_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
563 static int ldr_bstr_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
564 static int ldr_bstr_db_varbit (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
565 static int ldr_xstr_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
566 static int ldr_xstr_db_varbit (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
567 static int ldr_nstr_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
568 static int ldr_nstr_db_varnchar (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
569 static int ldr_numeric_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
570 static int ldr_numeric_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
571 static int ldr_double_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
572 static int ldr_float_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
573 static int ldr_real_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
574 static int ldr_real_db_float (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
575 static int ldr_real_db_double (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
576 static int ldr_date_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
577 static int ldr_date_db_date (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
578 static int ldr_time_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
579 static int ldr_time_db_time (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
580 static int ldr_timestamp_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
581 static int ldr_timestamp_db_timestamp (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
582 static int ldr_timestamptz_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
583 static int ldr_timestampltz_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
584 static int ldr_timestamptz_db_timestamptz (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
585 static int ldr_timestampltz_db_timestampltz (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
586 static int ldr_datetime_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
587 static int ldr_datetime_db_datetime (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
588 static int ldr_datetimetz_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
589 static int ldr_datetimeltz_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
590 static int ldr_datetimetz_db_datetimetz (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
591 static int ldr_datetimeltz_db_datetimeltz (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
592 static void ldr_date_time_conversion_error (const char *token, DB_TYPE type);
593 static int ldr_check_date_time_conversion (const char *str, data_type type);
594 static int ldr_elo_int_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
595 static int ldr_elo_int_db_elo (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
596 static int ldr_elo_ext_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
597 static int ldr_elo_ext_db_elo (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
598 static int ldr_mop_tempoid_maps_init (void);
599 static void ldr_mop_tempoid_maps_final (void);
600 static int ldr_add_mop_tempoid_map (MOP mop, CLASS_TABLE *table, int id);
601 static int ldr_assign_all_perm_oids (void);
602 static int find_instance (LDR_CONTEXT *context, DB_OBJECT *class_, OID *oid, int id);
603 static int ldr_class_oid_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
604 static int ldr_class_oid_db_object (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
605 static int ldr_oid_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
606 static int ldr_oid_db_object (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
607 static int ldr_monetary_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
608 static int ldr_monetary_db_monetary (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
609 static int ldr_collection_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
610 static int ldr_collection_db_collection (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
611 static int ldr_reset_context (LDR_CONTEXT *context);
612 static void ldr_flush (LDR_CONTEXT *context);
613 static int check_commit (LDR_CONTEXT *context);
614 static void ldr_restore_pin_and_drop_obj (LDR_CONTEXT *context, bool drop_obj);
615 static int ldr_finish_context (LDR_CONTEXT *context);
616 static int ldr_refresh_attrs (LDR_CONTEXT *context);
617 static int update_default_count (CLASS_TABLE *table, OID *oid);
618 static int update_default_instances_stats (LDR_CONTEXT *context);
619 static int insert_instance (LDR_CONTEXT *context);
620 static MOP construct_instance (LDR_CONTEXT *context);
621 static int insert_meth_instance (LDR_CONTEXT *context);
622 static int add_element (void ***elements, int *count, int *max, int grow);
623 static int add_argument (LDR_CONTEXT *context);
624 static void invalid_class_id_error (LDR_CONTEXT *context, int id);
625 static int ldr_init_loader (LDR_CONTEXT *context);
626 static void ldr_abort (void);
627 static void ldr_process_object_ref (object_ref_type *ref, int type);
628 static int ldr_act_add_class_all_attrs (const char *class_name);
629 static int ldr_json_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val);
630 static int ldr_json_db_json (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att);
631 
632 /* default action */
633 void (*ldr_act) (LDR_CONTEXT *context, const char *str, size_t len, data_type type) = ldr_act_attr;
634 
635 namespace cubload
636 {
637 
638  void
640  {
641  (void) clsid;
642  // do nothing on SA_MODE
643  }
644 
645  void
646  sa_class_installer::check_class (const char *class_name, int class_id)
647  {
648  DB_OBJECT *class_;
649  int err = NO_ERROR;
650  bool is_ignore_class;
651 
652  // moved from grammar file;
653  skip_current_class = false;
654 
655  if (!ldr_Current_context->validation_only)
656  {
657  class_ = ldr_find_class (class_name);
658  if (class_ != NULL)
659  {
660  ldr_Current_context->id_class = class_;
661  }
662  else
663  {
664  is_ignore_class = ldr_is_ignore_class (class_name, strlen (class_name));
665  if (!is_ignore_class)
666  {
667  display_error (0);
668  CHECK_CONTEXT_VALIDITY (ldr_Current_context, true);
669  }
670  else if (er_errid () == ER_LC_UNKNOWN_CLASSNAME)
671  {
672  er_clear ();
673  }
674  }
675  }
676 
677  if (ldr_Current_context->id_class != NULL)
678  {
679  ldr_Current_context->inst_num = class_id;
680  CHECK_ERR (err, ldr_assign_class_id (ldr_Current_context->id_class, class_id));
681  ldr_Current_context->id_class = NULL;
682  }
683 
684 error_exit:
685  CHECK_CONTEXT_VALIDITY (ldr_Current_context, err != NO_ERROR);
686  }
687 
688  int
689  sa_class_installer::install_class (const char *class_name)
690  {
691  ldr_act_init_context (ldr_Current_context, class_name, strlen (class_name));
692 
693  /*
694  * If there is no class or not authorized,
695  * Error message is printed and ER_FAILED is returned.
696  */
697  return ldr_act_add_class_all_attrs (class_name);
698  }
699 
700  void
702  {
703  if (class_name == NULL)
704  {
705  return;
706  }
707 
708  if (cmd_spec == NULL)
709  {
710  // fallback on default attribute list
711  install_class (class_name->val);
712  return;
713  }
714 
715  // setup class
716  ldr_act_set_skip_current_class (class_name->val, class_name->size);
717  ldr_act_init_context (ldr_Current_context, class_name->val, class_name->size);
718 
719  // setup class attributes
720  if (cmd_spec->attr_type != LDR_ATTRIBUTE_ANY)
721  {
722  ldr_act_restrict_attributes (ldr_Current_context, cmd_spec->attr_type);
723  }
724 
725  for (string_type *attr = cmd_spec->attr_list; attr; attr = attr->next)
726  {
727  ldr_act_add_attr (ldr_Current_context, attr->val, attr->size);
728  }
729 
730  ldr_act_check_missing_non_null_attrs (ldr_Current_context);
731 
732  // setup class constructor
733  if (cmd_spec->ctor_spec)
734  {
735  if (cmd_spec->ctor_spec->id_name)
736  {
737  ldr_act_set_constructor (ldr_Current_context, cmd_spec->ctor_spec->id_name->val);
738  }
739 
740  for (string_type *arg = cmd_spec->ctor_spec->arg_list; arg; arg = arg->next)
741  {
742  ldr_act_add_argument (ldr_Current_context, arg->val);
743  }
744  }
745  }
746 
747  void
749  {
750  (void) clsid;
751  // do nothing on SA_MODE
752  }
753 
754  void
756  {
757  /* do not display duplicate error msg */
758  int err = er_filter_errid (false);
759  if (ldr_destroy (ldr_Current_context, 0) && err == NO_ERROR)
760  {
761  display_error (-1);
762  }
763  }
764 
765  void
767  {
768  ; // Do nothing.
769  }
770 
771  std::size_t
773  {
774  // Do nothing on SA_MODE
775  assert (false);
776  return 0;
777  }
778 
779  /*
780  * sa_object_loader::start_line - Finishes off the previous instance and resets the
781  * context to deal with a new instance.
782  * return: void
783  * object_id(in): id of current instance.
784  * Note:
785  * This is called when a new instance if found by the parser.
786  */
787  void
789  {
790  // moved from grammar file;
791  skip_current_instance = false;
792 
793  CHECK_SKIP ();
794  if (ldr_Current_context->valid)
795  {
796 
797  ldr_Current_context->inst_num = object_id;
798 
799  if (ldr_reset_context (ldr_Current_context) != NO_ERROR)
800  {
801  display_error (-1);
802  }
803 
804  ldr_Current_context->instance_started = 1;
805  }
806  }
807 
808  void
810  {
811  CHECK_SKIP ();
812 
813  if (er_errid () != NO_ERROR)
814  {
815  display_error (0);
816  CHECK_CONTEXT_VALIDITY (ldr_Current_context, true);
817  ldr_abort ();
818  return;
819  }
820  if (cons != NULL && ldr_Current_context->num_attrs == 0)
821  {
823  /* diplay the msg 1 time for each class */
824  if (ldr_Current_context->valid)
825  {
826  display_error (0);
827  }
828  CHECK_CONTEXT_VALIDITY (ldr_Current_context, true);
829  ldr_abort ();
830  return;
831  }
832 
833  for (constant_type *c = cons; c != NULL; c = c->next)
834  {
835  switch (c->type)
836  {
837  case LDR_NULL:
838  (*ldr_act) (ldr_Current_context, NULL, 0, LDR_NULL);
839  break;
840 
841  case LDR_INT:
842  case LDR_FLOAT:
843  case LDR_DOUBLE:
844  case LDR_NUMERIC:
845  case LDR_DATE:
846  case LDR_TIME:
847  case LDR_TIMESTAMP:
848  case LDR_TIMESTAMPLTZ:
849  case LDR_TIMESTAMPTZ:
850  case LDR_DATETIME:
851  case LDR_DATETIMELTZ:
852  case LDR_DATETIMETZ:
853  case LDR_STR:
854  case LDR_NSTR:
855  {
856  string_type *str = (string_type *) c->val;
857 
858  (*ldr_act) (ldr_Current_context, str->val, str->size, c->type);
859  }
860  break;
861 
862  case LDR_MONETARY:
863  {
864  monetary_type *mon = (monetary_type *) c->val;
865  string_type *str = (string_type *) mon->amount;
866  /* buffer size for monetary : numeric size + grammar currency symbol + string terminator */
867  char full_mon_str[NUM_BUF_SIZE + 3 + 1];
868  char *full_mon_str_p = full_mon_str;
869  /* In Loader grammar always print symbol before value (position of currency symbol is not localized) */
870  char *curr_str = intl_get_money_esc_ISO_symbol ((DB_CURRENCY) mon->currency_type);
871  size_t full_mon_str_len = (str->size + strlen (curr_str));
872 
873  if (full_mon_str_len >= sizeof (full_mon_str))
874  {
875  full_mon_str_p = new char[full_mon_str_len + 1];
876  }
877 
878  strcpy (full_mon_str_p, curr_str);
879  strcat (full_mon_str_p, str->val);
880 
881  (*ldr_act) (ldr_Current_context, full_mon_str_p, strlen (full_mon_str_p), c->type);
882  if (full_mon_str_p != full_mon_str)
883  {
884  delete [] full_mon_str_p;
885  }
886 
887  delete mon;
888  }
889  break;
890 
891  case LDR_BSTR:
892  case LDR_XSTR:
893  case LDR_ELO_INT:
894  case LDR_ELO_EXT:
895  case LDR_SYS_USER:
896  case LDR_SYS_CLASS:
897  {
898  string_type *str = (string_type *) c->val;
899 
900  (*ldr_act) (ldr_Current_context, str->val, str->size, c->type);
901  }
902  break;
903 
904  case LDR_OID:
905  case LDR_CLASS_OID:
906  ldr_process_object_ref ((object_ref_type *) c->val, c->type);
907  break;
908 
909  case LDR_COLLECTION:
910  (*ldr_act) (ldr_Current_context, "{", 1, LDR_COLLECTION);
911  process_line ((constant_type *) c->val);
912  ldr_act_attr (ldr_Current_context, NULL, 0, LDR_COLLECTION);
913  break;
914 
915  default:
916  break;
917  }
918  }
919  }
920 
921  /*
922  * sa_object_loader::finish_line - Completes an instance line.
923  * return: void
924  * Note:
925  * If there are missing attributes/arguments an error is flagged. The
926  * instance is inserted if it is not a class attribute modification. If
927  * the flush interval has been reached, the current set of instances created
928  * are flushed.
929  */
930  void
932  {
933  int err = NO_ERROR;
934 
935  CHECK_SKIP ();
936  if (ldr_Current_context->valid)
937  {
938  if (ldr_Current_context->next_attr < (ldr_Current_context->num_attrs + ldr_Current_context->arg_count))
939  {
940  if (ldr_Current_context->arg_count && (ldr_Current_context->next_attr >= ldr_Current_context->arg_index))
941  {
943  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, err, 2, ldr_Current_context->arg_count,
944  ldr_Current_context->next_attr - ldr_Current_context->arg_index);
945  }
946  else
947  {
949  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, err, 2, ldr_Current_context->num_attrs,
950  ldr_Current_context->next_attr);
951  }
952  ldr_increment_err_count (ldr_Current_context, 1);
953  }
954  }
955 
956  ldr_restore_pin_and_drop_obj (ldr_Current_context, ((ldr_Current_context->err_count != 0) || (err != NO_ERROR))
958  CHECK_ERR (err, err);
959 
960  if (ldr_Current_context->valid && !ldr_Current_context->err_count && !skip_current_instance)
961  {
962  if (ldr_Current_context->constructor)
963  {
964  err = insert_meth_instance (ldr_Current_context);
965  }
966  else if (ldr_Current_context->attr_type == LDR_ATTRIBUTE_ANY)
967  {
968  err = insert_instance (ldr_Current_context);
969  }
970 
971  if (err == NO_ERROR)
972  {
973  if (ldr_Current_context->flush_interval
974  && ldr_Current_context->inst_count >= ldr_Current_context->flush_interval)
975  {
976  err = ldr_assign_all_perm_oids ();
977  if (err == NO_ERROR)
978  {
979  if (!ldr_Current_context->validation_only)
980  {
981  ldr_flush (ldr_Current_context);
982  err = er_errid ();
983  if (err != NO_ERROR)
984  {
985  /* flush failed */
986  err = er_filter_errid (true); /* ignore warning */
987  if (err == NO_ERROR)
988  {
989  /* Flush error was ignored. Objects in workspace must be decached for later flush */
990  ws_decache_all_instances (ldr_Current_context->cls);
991  }
992  }
993  CHECK_ERR (err, er_errid ());
994  }
995  }
996  else
997  {
998  ldr_increment_err_count (ldr_Current_context, 1);
999  }
1000  }
1001  }
1002  else
1003  {
1004  ldr_increment_err_count (ldr_Current_context, 1);
1005  }
1006  }
1007 
1008 error_exit:
1009  if (ldr_Current_context->err_count || (err != NO_ERROR))
1010  {
1011  ldr_abort ();
1012  }
1013  ldr_Current_context->instance_started = 0;
1014  }
1015 
1016 } // namespace cubload
1017 
1018 /*
1019  * ldr_increment_err_total - increment err_total count of the given context
1020  * return: void
1021  * context(out): context
1022  */
1023 void
1025 {
1026  if (ldr_Current_context)
1027  {
1028  ldr_Current_context->err_total += 1;
1029  }
1030 }
1031 
1032 /*
1033  * ldr_increment_fails - increment Total_fails count
1034  * return: void
1035  */
1036 void
1038 {
1039  Total_fails++;
1040 }
1041 
1042 /*
1043  * ldr_increment_err_count - increment err_count of the given context
1044  * return: void
1045  * context(out): context
1046  * i(in): count
1047  */
1048 static void
1050 {
1051  if (context)
1052  {
1053  context->err_count += i;
1054  }
1055 }
1056 
1057 /*
1058  * ldr_clear_err_count - clear err_count of a context
1059  * return: in
1060  * context(out): context
1061  */
1062 static void
1064 {
1065  if (context)
1066  {
1067  context->err_count = 0;
1068  }
1069 }
1070 
1071 /*
1072  * ldr_clear_err_total - clear err_total of a context
1073  * return: void
1074  * context(out): context
1075  */
1076 static void
1078 {
1079  if (context)
1080  {
1081  context->err_total = 0;
1082  }
1083 }
1084 
1085 /*
1086  * ldr_class_name - Returns the name of the class currently being loaded.
1087  * return: name
1088  * context(in): context
1089  * Note:
1090  * Used predominately to get the class name when an error occurs.
1091  */
1092 static const char *
1094 {
1095  static const char *name = NULL;
1096 
1097  if (context)
1098  {
1099  if (context->cls)
1100  {
1101  name = db_get_class_name (context->cls);
1102  }
1103  }
1104 
1105  return name;
1106 }
1107 
1108 /*
1109  * ldr_attr_name - Returns the name of the attribute we are currently dealing
1110  * with.
1111  * return: name
1112  * context(in): context
1113  * Note:
1114  * Used predominately to get the attribute name when an error occurs.
1115  */
1116 static const char *
1118 {
1119  static const char *name = NULL;
1120 
1121  if (context && context->attrs && context->valid)
1122  {
1123  if (context->num_attrs >= context->next_attr)
1124  {
1125  if (context->num_attrs)
1126  {
1127  name = context->attrs[context->next_attr].att->header.name;
1128  }
1129  else
1130  {
1131  /* haven't processed an attribute yet */
1132  name = "";
1133  }
1134  }
1135  else
1136  {
1137  /* should return some kind of string representation for the current method argument */
1138  name = "";
1139  }
1140  }
1141 
1142  return name;
1143 }
1144 
1145 /*
1146  * select_set_domain - looks through a domain list and selects a domain that
1147  * is one of the set types.
1148  * return: NO_ERROR if successful, error code otherwise
1149  * context(in): context
1150  * domain(in): target domain
1151  * set_domain_ptr(out): returned set domain
1152  * Note:
1153  * Work functions for ldr_act_add*() functions, when the target type is
1154  * collection.
1155  * In all current cases, there will be only one element in the target
1156  * domain list.
1157  * Assuming there were more than one, we should be smarter and select
1158  * the most "general" domain, for now, just pick the first one.
1159  * NOTE : This is similar to tp_domain_select(), expect we are not dealing
1160  * with a value here. The checking here should match the checking peformed
1161  * by relevant code in tp_domain_select()
1162  */
1163 static int
1164 select_set_domain (LDR_CONTEXT *context, TP_DOMAIN *domain, TP_DOMAIN **set_domain_ptr)
1165 {
1166  int err = NO_ERROR;
1167  TP_DOMAIN *best = NULL;
1168 
1169  /*
1170  * Must pick an appropriate set domain, probably we should pick
1171  * the most general if there are more than one possibilities.
1172  * In practice, this won't ever happen until we allow nested
1173  * sets or union domains.
1174  */
1175  for (TP_DOMAIN *d = domain; d != NULL && best == NULL; d = d->next)
1176  {
1177  if (TP_IS_SET_TYPE (TP_DOMAIN_TYPE (d)))
1178  {
1179  /* pick the first one */
1180  best = d;
1181  }
1182  }
1183 
1184  if (best == NULL)
1185  {
1186  err = ER_LDR_DOMAIN_MISMATCH;
1187  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, err, 4, ldr_attr_name (context), ldr_class_name (context),
1188  domain->type->name, db_get_type_name (DB_TYPE_SET));
1189  }
1190  else
1191  {
1192  if (set_domain_ptr != NULL)
1193  {
1194  *set_domain_ptr = best;
1195  }
1196  }
1197 
1198  return err;
1199 }
1200 
1201 /*
1202  * check_object_domain - checks the type of an incoming value against the
1203  * target domain.
1204  * return: NO_ERROR if successful, error code otherwise
1205  * context(in): context
1206  * class(in): class of incoming object reference
1207  * actual_class(out): class to expect (if first arg is NULL)
1208  * Note:
1209  * If they don't match LDR_DOMAIN_MISMATCH is returned.
1210  * If "class" is NULL, we try to determine what the class will really
1211  * be by examining the domain. If there is only one possible class
1212  * in the domain, we return it through "actual_class".
1213  * If there are more than one possible classes in the domain,
1214  * we return the LDR_AMBIGUOUS_DOMAIN error.
1215  */
1216 static int
1217 check_object_domain (LDR_CONTEXT *context, DB_OBJECT *class_, DB_OBJECT **actual_class)
1218 {
1219  int err = NO_ERROR;
1220  TP_DOMAIN *domain = NULL, *best = NULL;
1221 
1222  GET_DOMAIN (context, domain);
1223 
1224  if (class_ == NULL)
1225  {
1226  /* its an object but no domain was specified, see if we can unambiguously select one. */
1227  if (domain == NULL)
1228  {
1230  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, err, 2, ldr_attr_name (context), ldr_class_name (context));
1231  }
1232  else
1233  {
1234  for (TP_DOMAIN *d = domain; d != NULL; d = d->next)
1235  {
1236  if (d->type == tp_Type_object)
1237  {
1238  if (class_ == NULL && d->class_mop != NULL)
1239  {
1240  class_ = d->class_mop;
1241  }
1242  else
1243  {
1244  class_ = NULL;
1245  break;
1246  }
1247  }
1248  }
1249  if (class_ == NULL)
1250  {
1252  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, err, 2, ldr_attr_name (context), ldr_class_name (context));
1253  }
1254  }
1255  }
1256  else
1257  {
1258  if (domain != NULL)
1259  {
1260  /* make sure we have a compabile class in the domain list */
1261  best = tp_domain_select_type (domain, DB_TYPE_OBJECT, class_, 1);
1262  if (best == NULL)
1263  {
1265  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, err, 3, ldr_attr_name (context), ldr_class_name (context),
1266  db_get_class_name (class_));
1267  }
1268  }
1269  }
1270 
1271  if (actual_class != NULL)
1272  {
1273  *actual_class = class_;
1274  }
1275 
1276  return err;
1277 }
1278 
1279 /*
1280  * check_class_domain - checks the domain for an incoming reference to an
1281  * actual class object (not an instance).
1282  * return: NO_ERROR if successful, error code otherwise
1283  * context(in): context
1284  * Note:
1285  * For these references, the target domain must contain a wildcard
1286  * "object" domain.
1287  */
1288 static int
1290 {
1291  int err = NO_ERROR;
1292  TP_DOMAIN *domain = NULL;
1293 
1294  GET_DOMAIN (context, domain);
1295 
1296  /* the domain must support "object" */
1297  if (domain != NULL)
1298  {
1299  for (TP_DOMAIN *d = domain; d != NULL; d = d->next)
1300  {
1301  if (d->type == tp_Type_object && d->class_mop == NULL)
1302  {
1303  goto error_exit; /* we found it */
1304  }
1305  }
1306 
1307  /*
1308  * could make this more specific but not worth the trouble
1309  * right now, can only happen in internal trigger objects
1310  */
1313  }
1314 
1315 error_exit:
1316  return err;
1317 }
1318 
1319 /*
1320  * idmap_init - Initialize the global class id map.
1321  * return: void
1322  */
1323 static void
1325 {
1326  Id_map = NULL;
1327  Id_map_size = 0;
1328 }
1329 
1330 /*
1331  * idmap_final - free the class id map
1332  * return: void
1333  */
1334 static void
1336 {
1337  if (Id_map != NULL)
1338  {
1339  free_and_init (Id_map);
1340  Id_map_size = 0;
1341  }
1342 }
1343 
1344 /*
1345  * idmap_grow - This makes sure the class id map is large enough to accomodate
1346  * the given index.
1347  * return: NO_ERROR if successful, error code otherwise
1348  * size(in): element index we want to set
1349  */
1350 static int
1351 idmap_grow (int size)
1352 {
1353  int err = NO_ERROR;
1354  int newsize, i;
1355  DB_OBJECT **id_map_old;
1356 
1357  if (size > Id_map_size)
1358  {
1359  newsize = size + 10; /* some extra for growth */
1360  id_map_old = Id_map;
1361  Id_map = (DB_OBJECT **) realloc (Id_map, (sizeof (DB_OBJECT *) * newsize));
1362  if (Id_map == NULL)
1363  {
1364  /* Prevent leakage if we get a memory problem. */
1365  if (id_map_old)
1366  {
1367  free_and_init (id_map_old);
1368  }
1369  err = ER_LDR_MEMORY_ERROR;
1371  }
1372  else
1373  {
1374  for (i = Id_map_size; i < newsize; i++)
1375  {
1376  Id_map[i] = NULL;
1377  }
1378 
1379  Id_map_size = newsize;
1380  }
1381  }
1382 
1383  return err;
1384 }
1385 
1386 /*
1387  * ldr_assign_class_id - assign an id to a class
1388  * return: NO_ERROR if successful, error code otherwise
1389  * class(in): class object
1390  * id(in): id for this class
1391  * Note:
1392  * An entry will be made to the global class map.
1393  */
1394 static int
1396 {
1397  int err;
1398 
1399  err = idmap_grow (id + 1);
1400  if (err == NO_ERROR)
1401  {
1402  Id_map[id] = class_;
1403  }
1404 
1405  return err;
1406 }
1407 
1408 /*
1409  * ldr_find_class - find a class hinting that we need the class for reading and
1410  * for writing instances.
1411  * return: class db_object
1412  * class_name(in): string
1413  * Note:
1414  * This uses the ldr_Hint* arrays global arrays. The lock that we require
1415  * is setup once in ldr_init_loader().
1416  */
1417 static DB_OBJECT *
1418 ldr_find_class (const char *class_name)
1419 {
1420  LC_FIND_CLASSNAME find;
1421  DB_OBJECT *class_ = NULL;
1422  char realname[SM_MAX_IDENTIFIER_LENGTH];
1423 
1424  /* Check for internal error */
1425  if (class_name == NULL)
1426  {
1428  display_error (0);
1429  return NULL;
1430  }
1431 
1432  sm_downcase_name (class_name, realname, SM_MAX_IDENTIFIER_LENGTH);
1433  ldr_Hint_class_names[0] = realname;
1434 
1435  find =
1437  NULL_LOCK);
1438 
1439  if (find == LC_CLASSNAME_EXIST)
1440  {
1441  class_ = db_find_class (class_name);
1442  }
1443 
1445 
1446  return (class_);
1447 }
1448 
1449 /*
1450  * ldr_get_class_from_id - return the class with the given 'id' from global
1451  * class id map
1452  * return: class object
1453  * id(in): class id
1454  */
1455 static DB_OBJECT *
1457 {
1458  DB_OBJECT *class_ = NULL;
1459 
1460  if (id <= Id_map_size)
1461  {
1462  class_ = Id_map[id];
1463  }
1464 
1465  return (class_);
1466 }
1467 
1468 /*
1469  * ldr_clear_context - clears any information on the class/attribute/argument
1470  * definitions that have been made.
1471  * return: void
1472  * context(out): current context
1473  */
1474 static void
1476 {
1477  context->cls = NULL;
1478  context->class_name = NULL;
1479 
1480  context->obj = NULL;
1481  context->mobj = NULL;
1482  context->obj_pin = 0;
1483  context->class_pin = 0;
1485 
1486  context->attrs = NULL;
1487 
1488  context->num_attrs = 0;
1489  context->next_attr = 0;
1490 
1491  context->instance_started = 0;
1492  context->valid = false;
1493 
1494  /* verbose and periodic_commit are should be set out side this function */
1495 
1496  ldr_clear_err_count (context);
1497 
1498  /* error_total should not be reset here */
1499 
1500  context->inst_count = 0;
1501  context->inst_total = 0;
1502  context->inst_num = -1;
1503 
1504  // not sure the param helps, however I don't like to change the existing behavior.
1505  // We may remove it someday.
1507  if (context->args->periodic_commit <= context->flush_interval)
1508  {
1509  // deactive flush_interval, since it is useless for this case
1510  context->flush_interval = 0;
1511  }
1512 
1513  context->table = NULL;
1514 
1515  /* validation_only, lang_id flag should be set outside this function */
1516 
1517  context->collection = NULL;
1518  context->set_domain = NULL;
1519 
1520  context->constructor = NULL;
1521  context->arg_index = 0;
1522  context->max_arg = 0;
1523  context->method_args = NULL;
1524  context->arg_count = 0;
1525 
1526  context->id_class = NULL;
1527  context->attr_type = LDR_ATTRIBUTE_ANY;
1528 }
1529 
1530 /*
1531  * ldr_clear_and_free_context - Frees up the space allocated for the
1532  * constructor strings, attribute descriptors and args array.
1533  * return: void
1534  * context(in/out): current context
1535  * Note:
1536  * Called if we have an internal error, or when we finish processing each
1537  * class.
1538  */
1539 static void
1541 {
1542  int i;
1543 
1544  if (context->attrs)
1545  {
1546  for (i = 0; i < (context->num_attrs + context->arg_count); i += 1)
1547  {
1548  if (context->attrs[i].parser_str)
1549  {
1550  free_and_init (context->attrs[i].parser_str);
1551  }
1552  if (context->attrs[i].attdesc)
1553  {
1555  }
1556  context->attrs[i].attdesc = NULL;
1557  }
1558  free_and_init (context->attrs);
1559  }
1560 
1561  if (context->method_args)
1562  {
1563  free_and_init (context->method_args);
1564  }
1565 
1566  if (context->class_name)
1567  {
1568  free_and_init (context->class_name);
1569  }
1570 
1571  ldr_clear_context (context);
1572 }
1573 
1574 /*
1575  * LOADER ERROR NOTIFICATION
1576  *
1577  * There are two levels of error handling here. When a call
1578  * is made to a ldr_ function, those functions will return a int
1579  * and use er_set to set the global error state. For those errors,
1580  * we simply use db_error_string to get the text and display it.
1581  *
1582  * Other errors are detected by the action routines in this file.
1583  * For these, we don't use er_set since it isn't really necessary. Instead
1584  * we just have message catalog entries for the error text we wish
1585  * to display.
1586  *
1587  */
1588 
1589 /*
1590  * ldr_internal_error - handle internal error
1591  * return: void
1592  * context(in/out): context
1593  * Note:
1594  * This can be called by an upper level when an error is detected
1595  * and we need to reset the internal loader state.
1596  * Call this when serious errors are encountered and we need to
1597  * stop immediately. Probably we could longjmp out of parser here to
1598  * avoid parsing the rest of the file.
1599  */
1600 static void
1602 {
1603  ldr_clear_and_free_context (context);
1604  ldr_abort ();
1605 }
1606 
1607 /*
1608  * display_error_line - display error line
1609  * return: void
1610  * adjust(in): line number adjuster
1611  * Note:
1612  * This will display the line number of the current input file.
1613  * It is intended to give error messages context within the file.
1614  * Its public because there are a few places in the loader internals
1615  * where we need to display messages without propogating
1616  * errors back up to the action routine level.
1617  */
1618 static void
1620 {
1621  int lineno = 0;
1622  if (adjust != 0)
1623  {
1624  // In case of adjustment required, use the old behavior of using the scanner line.
1625  lineno = ldr_Driver->get_scanner ().lineno() + adjust;
1626  }
1627  else
1628  {
1629  // No adjustment needed, we can report the current line.
1630  lineno = ldr_Driver->get_start_line ();
1631  }
1632 
1633  if (lineno == 0)
1634  {
1635  // Most likely parsing hasn't started yet so we should not print the line number.
1636  return;
1637  }
1638 
1640 }
1641 
1642 /*
1643  * display_error - ldr_ function error handler
1644  * return: void
1645  * adjust(in): line number adjuster
1646  * Note:
1647  * This is called whenever one of the ldr_ functions returns
1648  * an error. In this case, a standard system error has been set
1649  * and the text is obtained through db_error_string.
1650  */
1651 static void
1652 display_error (int adjust)
1653 {
1654  const char *msg;
1655 
1656  display_error_line (adjust);
1657  msg = db_error_string (3);
1658  fprintf (stderr, msg);
1659  fprintf (stderr, "\n");
1660 }
1661 
1662 /*
1663  * ldr_invalid_class_error - invalid class error handler
1664  * return: void
1665  * context(in): context
1666  * Note:
1667  * Called when the name of an invalid class reference was specified.
1668  */
1669 static void
1671 {
1672  display_error_line (0);
1674  ldr_attr_name (context), ldr_class_name (context));
1675 }
1676 
1677 /*
1678  * parse_error - parse error handler
1679  * return: void
1680  * context(in): context
1681  * token_type(in): incoming token type
1682  * token(in): token string
1683  * Note:
1684  * Called when we have some sort of parsing problem with an incoming
1685  * token that made it past parser's initial level of checking.
1686  * System errors have not been set.
1687  * This is called by serveral of the setters.
1688  */
1689 static void
1690 parse_error (LDR_CONTEXT *context, DB_TYPE token_type, const char *token)
1691 {
1692  display_error_line (0);
1693 
1694  /*
1695  * This is called when we experience an error when performing a string to
1696  * DB_TYPE conversion. Called via CHECK_PARSE_ERR() macro.
1697  */
1699  db_get_type_name (token_type), ldr_attr_name (context), ldr_class_name (context));
1700 }
1701 
1702 /*
1703  * clist_init - Initializes the list of internal classes.
1704  * return: NO_ERROR if successful, error code otherwise
1705  * Note:
1706  * These are the classes that we don't allow to be loaded.
1707  */
1708 static int
1710 {
1711  DB_OBJECT *class_;
1712 
1713  internal_classes = NULL;
1714 
1715  class_ = db_find_class (AU_ROOT_CLASS_NAME);
1716  if (class_ != NULL)
1717  {
1718  if (ml_ext_add (&internal_classes, class_, NULL))
1719  {
1720  assert (er_errid () != NO_ERROR);
1721  return er_errid ();
1722  }
1723  }
1724  class_ = db_find_class (AU_USER_CLASS_NAME);
1725  if (class_ != NULL)
1726  {
1727  if (ml_ext_add (&internal_classes, class_, NULL))
1728  {
1729  assert (er_errid () != NO_ERROR);
1730  return er_errid ();
1731  }
1732  }
1734  if (class_ != NULL)
1735  {
1736  if (ml_ext_add (&internal_classes, class_, NULL))
1737  {
1738  assert (er_errid () != NO_ERROR);
1739  return er_errid ();
1740  }
1741  }
1742  class_ = db_find_class (AU_AUTH_CLASS_NAME);
1743  if (class_ != NULL)
1744  {
1745  if (ml_ext_add (&internal_classes, class_, NULL))
1746  {
1747  assert (er_errid () != NO_ERROR);
1748  return er_errid ();
1749  }
1750  }
1751  return NO_ERROR;
1752 }
1753 
1754 /*
1755  * clist_final - free the list of internal classes
1756  * return: void
1757  */
1758 static void
1760 {
1761  ml_ext_free (internal_classes);
1762  internal_classes = NULL;
1763 }
1764 
1765 /*
1766  * is_internal_class - test to see if a class is an internal class
1767  * return: non-zero if this is an internal class
1768  * class(in): class to examine
1769  */
1770 static int
1772 {
1773  return (ml_find (internal_classes, class_));
1774 }
1775 
1776 /*
1777  * LEXER ACTION ROUTINES
1778  *
1779  * These routines are, for the most part, just dispatchers. They allow us
1780  * factor out the information about the form of the incoming string (i.e.,
1781  * we know that it's an integer, a quoted string, a numeric, or a real),
1782  * which allows the the function we dispatch to to make certain significant
1783  * optimizations (usually based on the domain of the attribute it's known to
1784  * be setting).
1785  */
1786 
1787 /*
1788  * ldr_act_attr - Invokes the appropriate setter from a vector of setters
1789  * indexed by the parser type.
1790  * return: void
1791  * context(in/out): current context
1792  * str(in): parser token
1793  * len(in): length of token
1794  * type(in): Parser type
1795  */
1796 static void
1797 ldr_act_attr (LDR_CONTEXT *context, const char *str, size_t len, data_type type)
1798 {
1799  LDR_ATTDESC *attdesc;
1800  int err = NO_ERROR;
1801 
1802  CHECK_SKIP ();
1803 
1804  /* we have reached an invalid state, ignore the tuples */
1805 
1806  RETURN_IF_NOT_VALID (context);
1807 
1808  if (context->next_attr >= context->num_attrs)
1809  {
1810  context->valid = false;
1813  goto error_exit;
1814  }
1815 
1816  if (context->validation_only)
1817  {
1818  switch (type)
1819  {
1820  /*
1821  * For validation only simply parse the set elements, by switching
1822  * to the element setter
1823  */
1824  case LDR_COLLECTION:
1825  /* ending brace of collection */
1826  if (str == NULL)
1827  {
1829  goto error_exit;
1830  }
1831  else
1832  {
1834  return;
1835  }
1836  /* Check validity of date/time/timestamp string during validation */
1837  case LDR_TIME:
1838  case LDR_DATE:
1839  case LDR_TIMESTAMP:
1840  case LDR_TIMESTAMPLTZ:
1841  case LDR_TIMESTAMPTZ:
1842  case LDR_DATETIME:
1843  case LDR_DATETIMELTZ:
1844  case LDR_DATETIMETZ:
1845  CHECK_ERR (err, ldr_check_date_time_conversion (str, type));
1846  break;
1847  default:
1848  break;
1849  }
1850  }
1851  else
1852  {
1853  attdesc = &context->attrs[context->next_attr];
1854  CHECK_ERR (err, (* (attdesc->setter[type])) (context, str, len, attdesc->att));
1855  }
1856 
1857 error_exit:
1858  context->next_attr += 1;
1859  ldr_increment_err_count (context, (err != NO_ERROR));
1860 }
1861 
1862 /*
1863  * ldr_act_elem - Invokes the appropriate converter from a set of vectored
1864  * converters indexed by the parser type.
1865  * return: void
1866  * context(in/out): current context
1867  * str(in): parser token
1868  * len(in): length of token
1869  * type(in): Parser type
1870  * Note:
1871  * If an object reference is encountered we need to use a special
1872  * function set_new_element() to generate a collection element, since we
1873  * are dealing with DB_TYPE_OIDs not DB_TYPE_OBJECT.
1874  * assign_set_value(), called by set_add_element(), calls
1875  * tp_domain_check(), and tp_value_cast to determine if the domains are
1876  * compatible, for DB_TYPE_OID, these do not return DB_DOMAIN_COMPATIBLE
1877  * for DB_OBJECT and DB_OID.
1878  */
1879 static void
1880 ldr_act_elem (LDR_CONTEXT *context, const char *str, size_t len, data_type type)
1881 {
1882  DB_VALUE tempval;
1883  int err = NO_ERROR;
1884 
1885  /* we have reached an invalid state, ignore the tuples */
1886 
1887  RETURN_IF_NOT_VALID (context);
1888 
1889  if (context->validation_only)
1890  {
1891  switch (type)
1892  {
1893  /*
1894  * For validation only simply parse the set elements, by switching
1895  * to the element setter
1896  */
1897  case LDR_COLLECTION:
1898  err = ER_LDR_NESTED_SET;
1900  display_error (0);
1901  break;
1902  /* Check validity of date/time/timestamp string during validation */
1903  case LDR_TIME:
1904  case LDR_DATE:
1905  case LDR_TIMESTAMP:
1906  case LDR_TIMESTAMPLTZ:
1907  case LDR_TIMESTAMPTZ:
1908  case LDR_DATETIME:
1909  case LDR_DATETIMELTZ:
1910  case LDR_DATETIMETZ:
1911  CHECK_ERR (err, ldr_check_date_time_conversion (str, type));
1912  break;
1913  default:
1914  break;
1915  }
1916  }
1917  else
1918  {
1919  CHECK_ERR (err, (* (elem_converter[type])) (context, str, len, &tempval));
1920  if ((err = set_add_element (context->collection, &tempval)) == ER_SET_DOMAIN_CONFLICT)
1921  {
1922  display_error_line (0);
1924  ldr_attr_name (context), ldr_class_name (context), db_get_type_name (db_value_type (&tempval)));
1926  }
1927  else
1928  {
1929  CHECK_ERR (err, err);
1930  }
1931  }
1932 
1933 error_exit:
1934  ldr_increment_err_count (context, (err != NO_ERROR));
1935 }
1936 
1937 /*
1938  * ldr_act_meth - set up the attr desc for an instance generated via a
1939  * constructor.
1940  * return: void
1941  * context(in/out): current context
1942  * str(in): parser token
1943  * len(in): length of token
1944  * type(in): Parser type
1945  * Note:
1946  * This simulates the parse phase here.
1947  */
1948 static void
1949 ldr_act_meth (LDR_CONTEXT *context, const char *str, size_t len, data_type type)
1950 {
1951  int err = NO_ERROR;
1952  LDR_ATTDESC *attdesc = NULL;
1953 
1954  /* we have reached an invalid state, ignore the tuples */
1955 
1956  RETURN_IF_NOT_VALID (context);
1957 
1958  if ((context->next_attr) >= (context->num_attrs + context->arg_count))
1959  {
1962  }
1963  CHECK_VALIDATION_ONLY (context);
1964 
1965  attdesc = &context->attrs[context->next_attr];
1966 
1967  /*
1968  * Save the parser buffer and type information, this will be
1969  * used later to feed to the fast setters to populate the
1970  * constructor generated instance
1971  * Attempt to reuse the strings buffers.
1972  */
1973  if (attdesc->parser_buf_len == 0)
1974  {
1975  attdesc->parser_str = (char *) (malloc (len + 1));
1976  if (attdesc->parser_str == NULL)
1977  {
1979  }
1980  CHECK_PTR (err, attdesc->parser_str);
1981  attdesc->parser_buf_len = len;
1982  }
1983  else if (len > attdesc->parser_buf_len)
1984  {
1985  char *parser_str_old;
1986  parser_str_old = attdesc->parser_str;
1987  /* Prevent leak from realloc call failure */
1988  attdesc->parser_str = (char *) realloc (attdesc->parser_str, len + 1);
1989  if (attdesc->parser_str == NULL)
1990  {
1991  /* Prevent leakage if realloc fails */
1992  free_and_init (parser_str_old);
1994  }
1995  CHECK_PTR (err, attdesc->parser_str);
1996  attdesc->parser_buf_len = len;
1997  }
1998  memcpy (attdesc->parser_str, str, len + 1);
1999  attdesc->parser_type = type;
2000  attdesc->parser_str_len = len;
2001 
2002 error_exit:
2003  context->next_attr += 1;
2004  ldr_increment_err_count (context, (err != NO_ERROR));
2005 }
2006 
2007 /*
2008  * ldr_mismatch - always error handler.
2009  * return: ER_OBJ_DOMAIN_CONFLICT
2010  * context(in): not used
2011  * str(in): not used
2012  * len(in): not used
2013  * att(in): attribute
2014  */
2015 static int
2016 ldr_mismatch (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2017 {
2018  int err;
2019 
2022 error_exit:
2023  return err;
2024 }
2025 
2026 /*
2027  * ldr_ignore - always ignoring handler.
2028  * return: ER_OBJ_DOMAIN_CONFLICT
2029  * context(in): not used
2030  * str(in): not used
2031  * len(in): not used
2032  * att(in): not used
2033  */
2034 static int
2035 ldr_ignore (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2036 {
2037  /*
2038  * No need to set an error here, we've already issued a message when we were
2039  * studying the attribute in ldr_act_add_attr(). Just return an error code
2040  * so that the caller will increment context->err_count, causing us to
2041  * skip the row rather than flush it.
2042  */
2043  return ER_OBJ_DOMAIN_CONFLICT;
2044 }
2045 
2046 /*
2047  * ldr_generic - set attribute value
2048  * return: NO_ERROR if successful, error code otherwise
2049  * context(in): context
2050  * value(in): DB_VALUE
2051  */
2052 static int
2054 {
2055  int err;
2056 
2057  CHECK_ERR (err, obj_desc_set (context->obj, context->attrs[context->next_attr].attdesc, value));
2058 error_exit:
2059  return err;
2060 }
2061 
2062 /*
2063  * ldr_null_elem - set db value to null
2064  * return: NO_ERROR
2065  * context(in):
2066  * str(in): not used
2067  * len(in): not used
2068  * val(out): DB_VALUE
2069  */
2070 static int
2071 ldr_null_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
2072 {
2073  db_make_null (val);
2074  return NO_ERROR;
2075 }
2076 
2077 /*
2078  * ldr_null_db_generic - set attribute value to null
2079  * return:
2080  * context(in): context
2081  * str(in): not used
2082  * len(in): not used
2083  * att(att): memory representation of attribute
2084  */
2085 static int
2086 ldr_null_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2087 {
2088  int err = NO_ERROR;
2089  char *mem;
2090 
2091  if (att->flags & SM_ATTFLAG_NON_NULL)
2092  {
2093  char class_attr[512];
2094 
2095  snprintf (class_attr, 512, "%s.%s", context->class_name, att->header.name);
2098  }
2099  else
2100  {
2101  mem = context->mobj + att->offset;
2102  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, NULL));
2103  if (!att->domain->type->variable_p)
2104  {
2105  OBJ_CLEAR_BOUND_BIT (context->mobj, att->storage_order);
2106  }
2107  }
2108 
2109 error_exit:
2110  return err;
2111 }
2112 
2113 /*
2114  * ldr_class_attr_db_generic - set attribute of a class
2115  * return: NO_ERROR if successful, error code otherwise
2116  * context(in/out): context
2117  * str(in): not used
2118  * len(in): not used
2119  * att(in): memory representation of attribute
2120  * val(in): value to set
2121  * Note:
2122  * This is a special setter, and is not called via the same process as the
2123  * other setters. i.e., ldr_act(). This is called by ldr_act_class_attr().
2124  */
2125 static int
2126 ldr_class_attr_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att, DB_VALUE *val)
2127 {
2128  int err = NO_ERROR;
2129 
2131  {
2132  CHECK_ERR (err, obj_set_shared (context->cls, att->header.name, val));
2133  }
2134  else if (att->header.name_space == ID_CLASS_ATTRIBUTE)
2135  {
2136  CHECK_ERR (err, obj_set (context->cls, att->header.name, val));
2137  }
2138  else if (context->attr_type == LDR_ATTRIBUTE_DEFAULT)
2139  {
2140  CHECK_ERR (err, db_change_default (context->cls, att->header.name, val));
2141  }
2142 
2143 error_exit:
2144  return err;
2145 }
2146 
2147 /*
2148  * ldr_act_class_attr -
2149  * return:
2150  * context():
2151  * str():
2152  * len():
2153  * type():
2154  */
2155 static void
2156 ldr_act_class_attr (LDR_CONTEXT *context, const char *str, size_t len, data_type type)
2157 {
2158  int err = NO_ERROR;
2159  DB_VALUE src_val, dest_val, *val;
2160  TP_DOMAIN *domain;
2161 
2162  /* we have reached an invalid state, ignore the tuples */
2163 
2164  RETURN_IF_NOT_VALID (context);
2165 
2166  CHECK_VALIDATION_ONLY (context);
2167 
2168  if (context->next_attr >= context->num_attrs)
2169  {
2170  context->valid = false;
2173  }
2174 
2175  if (type == LDR_COLLECTION)
2176  {
2177  if (context->attrs[context->next_attr].collection_domain == NULL)
2178  {
2179  CHECK_CONTEXT_VALIDITY (context, true);
2181  context->attrs[context->next_attr].att->header.name);
2183  }
2184  CHECK_ERR (err, ldr_collection_db_collection (context, str, len, context->attrs[context->next_attr].att));
2185  }
2186  else
2187  {
2188  CHECK_ERR (err, (* (elem_converter[type])) (context, str, len, &src_val));
2189  GET_DOMAIN (context, domain);
2190  CHECK_ERR (err, db_value_domain_init (&dest_val, TP_DOMAIN_TYPE (domain), domain->precision, domain->scale));
2191 
2192  val = &dest_val;
2193  /* tp_value_cast does not handle DB_TYPE_OID coersions, simply use the value returned by the elem converter. */
2194  if (type == LDR_OID || type == LDR_CLASS_OID)
2195  {
2196  if (TP_DOMAIN_TYPE (domain) == DB_TYPE_OBJECT)
2197  {
2198  val = &src_val;
2199  }
2200  else
2201  {
2203  context->attrs[context->next_attr].att->header.name);
2205  }
2206  }
2207  else if (tp_value_cast (&src_val, &dest_val, domain, false))
2208  {
2210  context->attrs[context->next_attr].att->header.name);
2211  CHECK_PARSE_ERR (err, ER_OBJ_DOMAIN_CONFLICT, context, TP_DOMAIN_TYPE (domain), str);
2212  }
2213  CHECK_ERR (err, ldr_class_attr_db_generic (context, str, len, context->attrs[context->next_attr].att, val));
2214  }
2215 
2216 error_exit:
2217  context->next_attr += 1;
2218  ldr_increment_err_count (context, (err != NO_ERROR));
2219 }
2220 
2221 /*
2222  * ldr_sys_user_db_generic -
2223  * return:
2224  * context():
2225  * str():
2226  * len():
2227  * att():
2228  */
2229 static int
2230 ldr_sys_user_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2231 {
2232  display_error_line (0);
2234  "db_user");
2236  ldr_increment_err_count (context, 1);
2237  return (ER_GENERIC_ERROR);
2238 }
2239 
2240 /*
2241  * ldr_sys_class_db_generic -
2242  * return:
2243  * context():
2244  * str():
2245  * len():
2246  * att():
2247  */
2248 static int
2249 ldr_sys_class_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2250 {
2251  display_error_line (0);
2253  "*system class*");
2254  CHECK_CONTEXT_VALIDITY (context, true);
2255 
2256  ldr_increment_err_count (context, 1);
2257  return (NO_ERROR);
2258 }
2259 
2260 /*
2261  * INT SETTERS
2262  *
2263  * These functions (ldr_int_db_*) are called when int constants are
2264  * processed by the lexer. They probably only make sense for int, float,
2265  * double, and numeric types. An "int" string is known to consist only of
2266  * digits with an optional preceding sign character.
2267  *
2268  * Right now we don't have a special handler for DB_TYPE_SHORT attributes.
2269  * We may want to build one if they turn out to be prevalent. That handler
2270  * would have to be on the lookout for overflow situations. (For that
2271  * matter, ldr_int_db_int maybe ought to look out for it too.)
2272  */
2273 
2274 /*
2275  * ldr_int_elem -
2276  * return:
2277  * context():
2278  * str():
2279  * len():
2280  * val():
2281  */
2282 static int
2283 ldr_int_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
2284 {
2285  int err = NO_ERROR;
2286  int result = 0;
2287 
2288  /*
2289  * Watch out for really long digit strings that really are being
2290  * assigned into a DB_TYPE_NUMERIC attribute; they can hold more than a
2291  * standard integer can, and calling atol() on that string will lose
2292  * data.
2293  * Is there some better way to test for this condition?
2294  */
2295  if (len < MAX_DIGITS_FOR_INT || (len == MAX_DIGITS_FOR_INT && (str[0] == '0' || str[0] == '1')))
2296  {
2297  val->domain = ldr_int_tmpl.domain;
2298  result = parse_int (&val->data.i, str, 10);
2299  if (result != 0)
2300  {
2302  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, DB_TYPE_INTEGER, str);
2303  }
2304  }
2305  else if (len < MAX_DIGITS_FOR_BIGINT || (len == MAX_DIGITS_FOR_BIGINT && str[0] != '9'))
2306  {
2307  val->domain = ldr_bigint_tmpl.domain;
2308  result = parse_bigint (&val->data.bigint, str, 10);
2309  if (result != 0)
2310  {
2312  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, DB_TYPE_BIGINT, str);
2313  }
2314  }
2315  else
2316  {
2317  DB_NUMERIC num;
2318  DB_BIGINT tmp_bigint;
2319 
2320  numeric_coerce_dec_str_to_num (str, num.d.buf);
2321  if (numeric_coerce_num_to_bigint (num.d.buf, 0, &tmp_bigint) != NO_ERROR)
2322  {
2323 
2324  CHECK_PARSE_ERR (err, db_value_domain_init (val, DB_TYPE_NUMERIC, (int) len, 0), context, DB_TYPE_BIGINT, str);
2325  CHECK_PARSE_ERR (err, db_value_put (val, DB_TYPE_C_CHAR, (char *) str, (int) len), context, DB_TYPE_BIGINT, str);
2326  }
2327  else
2328  {
2329  val->domain = ldr_bigint_tmpl.domain;
2330  val->data.bigint = tmp_bigint;
2331  }
2332  }
2333 
2334 error_exit:
2335  return err;
2336 }
2337 
2338 /*
2339  * ldr_int_db_generic -
2340  * return:
2341  * context():
2342  * str():
2343  * len():
2344  * att():
2345  */
2346 static int
2347 ldr_int_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2348 {
2349  int err;
2350  DB_VALUE val;
2351 
2352  CHECK_ERR (err, ldr_int_elem (context, str, len, &val));
2353  CHECK_ERR (err, ldr_generic (context, &val));
2354 
2355 error_exit:
2356  return err;
2357 }
2358 
2359 /*
2360  * ldr_int_db_bigint -
2361  * return:
2362  * context():
2363  * str():
2364  * len():
2365  * att():
2366  */
2367 static int
2368 ldr_int_db_bigint (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2369 {
2370  char *mem;
2371  int err;
2372  int result = 0;
2373  DB_VALUE val;
2374 
2375  val.domain = ldr_bigint_tmpl.domain;
2376 
2377  /* Let try take the fastest path here, if we know that number we are getting fits into a long, use strtol, else we
2378  * need to convert it to a double and coerce it, checking for overflow. Note if integers with leading zeros are
2379  * entered this can take the slower route. */
2380  if (len < MAX_DIGITS_FOR_BIGINT || (len == MAX_DIGITS_FOR_BIGINT && str[0] != '9'))
2381  {
2382  result = parse_bigint (&val.data.bigint, str, 10);
2383  if (result != 0)
2384  {
2386  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, DB_TYPE_BIGINT, str);
2387  }
2388  }
2389  else
2390  {
2391  DB_NUMERIC num;
2392  DB_BIGINT tmp_bigint;
2393 
2394  numeric_coerce_dec_str_to_num (str, num.d.buf);
2395  if (numeric_coerce_num_to_bigint (num.d.buf, 0, &tmp_bigint) != NO_ERROR)
2396  {
2398  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, DB_TYPE_BIGINT, str);
2399  }
2400  else
2401  {
2402  val.data.bigint = tmp_bigint;
2403  }
2404  }
2405 
2406  mem = context->mobj + att->offset;
2407  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
2408  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
2409 
2410 error_exit:
2411  return err;
2412 }
2413 
2414 /*
2415  * ldr_int_db_int -
2416  * return:
2417  * context():
2418  * str():
2419  * len():
2420  * att():
2421  */
2422 static int
2423 ldr_int_db_int (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2424 {
2425  char *mem;
2426  int err;
2427  int result = 0;
2428  DB_VALUE val;
2429  char *str_ptr;
2430 
2431  val.domain = ldr_int_tmpl.domain;
2432 
2433  /* Let try take the fastest path here, if we know that number we are getting fits into a long, use strtol, else we
2434  * need to convert it to a double and coerce it, checking for overflow. Note if integers with leading zeros are
2435  * entered this can take the slower route. */
2436  if (len < MAX_DIGITS_FOR_INT || (len == MAX_DIGITS_FOR_INT && (str[0] == '0' || str[0] == '1')))
2437  {
2438  result = parse_int (&val.data.i, str, 10);
2439  if (result != 0)
2440  {
2442  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, DB_TYPE_INTEGER, str);
2443  }
2444  }
2445  else
2446  {
2447  double d;
2448  d = strtod (str, &str_ptr);
2449 
2450  if (str_ptr == str || OR_CHECK_INT_OVERFLOW (d))
2451  {
2453  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, DB_TYPE_INTEGER, str);
2454  }
2455  else
2456  {
2457  val.data.i = ROUND (d);
2458  }
2459  }
2460 
2461  mem = context->mobj + att->offset;
2462  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
2463  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
2464 
2465 error_exit:
2466  return err;
2467 }
2468 
2469 /*
2470  * ldr_int_db_short -
2471  * return:
2472  * context():
2473  * str():
2474  * len():
2475  * att():
2476  */
2477 static int
2478 ldr_int_db_short (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2479 {
2480  char *mem;
2481  int err;
2482  int result = 0;
2483  DB_VALUE val;
2484  char *str_ptr;
2485 
2486  val.domain = ldr_short_tmpl.domain;
2487 
2488  /* Let try take the fastest path here, if we know that number we are getting fits into a long, use strtol, else we
2489  * need to convert it to a double and coerce it, checking for overflow. Note if integers with leading zeros are
2490  * entered this can take the slower route. */
2491  if (len > MAX_DIGITS_FOR_SHORT)
2492  {
2493  double d;
2494  d = strtod (str, &str_ptr);
2495 
2496  if (str_ptr == str || OR_CHECK_SHORT_OVERFLOW (d))
2497  {
2499  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, DB_TYPE_SHORT, str);
2500  }
2501  else
2502  {
2503  val.data.sh = ROUND (d);
2504  }
2505  }
2506  else
2507  {
2508  int i_val;
2509  result = parse_int (&i_val, str, 10);
2510 
2511  if (result != 0)
2512  {
2514  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, DB_TYPE_SHORT, str);
2515  }
2516  val.data.sh = (short) i_val;
2517  }
2518 
2519  mem = context->mobj + att->offset;
2520  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
2521  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
2522 
2523 error_exit:
2524  return err;
2525 }
2526 
2527 /*
2528  * STRING SETTERS
2529  *
2530  * These functions (ldr_str_db_*) are called when quoted strings are
2531  * processed by the lexer. They probably only make sense for char, varchar,
2532  * nchar, varnchar, bit, and varbit domains.
2533  *
2534  * WARNING: these functions cheat and assume a char-is-a-byte model, which
2535  * won't work when dealing with non-ASCII (or non-Latin, at least) charsets.
2536  * We'll need new versions to cope with those other charsets, but DON'T ADD
2537  * CHARSET TESTING INTO THE BODIES OF THESE FUNCTIONS. Move those tests WAY
2538  * out into the initialization code, and initialize function pointers to
2539  * point to fast (ASCII) or slow (e.g., S-JIS) versions.
2540  */
2541 
2542 /*
2543  * ldr_str_elem -
2544  * return:
2545  * context():
2546  * str():
2547  * len():
2548  * val():
2549  */
2550 static int
2551 ldr_str_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
2552 {
2553  /* todo: switch this to db_make_string_copy and avoid any possible leaks */
2554  db_make_string (val, str);
2555  return NO_ERROR;
2556 }
2557 
2558 /*
2559  * ldr_str_db_char -
2560  * return:
2561  * context():
2562  * str():
2563  * len():
2564  * att():
2565  */
2566 static int
2567 ldr_str_db_char (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2568 {
2569  char *mem;
2570  int precision;
2571  int err;
2572  DB_VALUE val;
2573  int char_count = 0;
2574 
2575  precision = att->domain->precision;
2576 
2577  intl_char_count ((unsigned char *) str, (int) len, (INTL_CODESET) att->domain->codeset, &char_count);
2578 
2579  if (char_count > precision)
2580  {
2581  /*
2582  * May be a violation, but first we have to check for trailing pad
2583  * characters that might allow us to successfully truncate the
2584  * thing.
2585  */
2586  int safe;
2587  const char *p;
2588  int truncate_size;
2589 
2590  intl_char_size ((unsigned char *) str, precision, (INTL_CODESET) att->domain->codeset, &truncate_size);
2591 
2592  for (p = &str[truncate_size], safe = 1; p < &str[len]; p++)
2593  {
2594  if (*p != ' ')
2595  {
2596  safe = 0;
2597  break;
2598  }
2599  }
2600  if (safe)
2601  {
2602  len = truncate_size;
2603  }
2604  else
2605  {
2606  /*
2607  * It's a genuine violation; raise an error.
2608  */
2610  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, DB_TYPE_CHAR, str);
2611  }
2612  }
2613 
2614  val.domain = ldr_char_tmpl.domain;
2615  val.domain.char_info.length = char_count;
2616  val.data.ch.info.style = MEDIUM_STRING;
2617  val.data.ch.info.is_max_string = false;
2618  val.data.ch.info.compressed_need_clear = false;
2619  val.data.ch.medium.size = (int) len;
2620  val.data.ch.medium.buf = (char *) str;
2622  val.data.ch.medium.compressed_size = 0;
2623  mem = context->mobj + att->offset;
2624  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
2625  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
2626 
2627 error_exit:
2628  return err;
2629 }
2630 
2631 /*
2632  * ldr_str_db_varchar -
2633  * return:
2634  * context():
2635  * str():
2636  * len():
2637  * att():
2638  */
2639 static int
2640 ldr_str_db_varchar (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2641 {
2642  char *mem;
2643  int precision;
2644  int err;
2645  DB_VALUE val;
2646  int char_count = 0;
2647 
2648  precision = att->domain->precision;
2649  intl_char_count ((unsigned char *) str, (int) len, (INTL_CODESET) att->domain->codeset, &char_count);
2650 
2651  if (char_count > precision)
2652  {
2653  /*
2654  * May be a violation, but first we have to check for trailing pad
2655  * characters that might allow us to successfully truncate the
2656  * thing.
2657  */
2658  int safe;
2659  const char *p;
2660  int truncate_size;
2661 
2662  intl_char_size ((unsigned char *) str, precision, (INTL_CODESET) att->domain->codeset, &truncate_size);
2663  for (p = &str[truncate_size], safe = 1; p < &str[len]; p++)
2664  {
2665  if (*p != ' ')
2666  {
2667  safe = 0;
2668  break;
2669  }
2670  }
2671  if (safe)
2672  {
2673  len = truncate_size;
2674  }
2675  else
2676  {
2677  /*
2678  * It's a genuine violation; raise an error.
2679  */
2681  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, DB_TYPE_VARCHAR, str);
2682  }
2683  }
2684 
2685  val.domain = ldr_varchar_tmpl.domain;
2686  val.domain.char_info.length = char_count;
2687  val.data.ch.medium.size = (int) len;
2688  val.data.ch.medium.buf = (char *) str;
2689  val.data.ch.info.style = MEDIUM_STRING;
2690  val.data.ch.info.is_max_string = false;
2691  val.data.ch.info.compressed_need_clear = false;
2693  val.data.ch.medium.compressed_size = 0;
2694 
2695  mem = context->mobj + att->offset;
2696  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
2697  /*
2698  * No bound bit to be set for a variable length attribute.
2699  */
2700 
2701 error_exit:
2702  return err;
2703 }
2704 
2705 /*
2706  * ldr_str_db_generic -
2707  * return:
2708  * context():
2709  * str():
2710  * len():
2711  * att():
2712  */
2713 static int
2714 ldr_str_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2715 {
2716  DB_VALUE val;
2717 
2718  /* todo: switch this to db_make_string_copy and avoid any possible leaks */
2719  db_make_string (&val, str);
2720  return ldr_generic (context, &val);
2721 }
2722 
2723 /*
2724  * ldr_bstr_elem -
2725  * return:
2726  * context():
2727  * str():
2728  * len():
2729  * val():
2730  */
2731 static int
2732 ldr_bstr_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
2733 {
2734  int err = NO_ERROR;
2735  size_t dest_size;
2736  char *bstring;
2737  TP_DOMAIN *domain;
2738  DB_VALUE temp;
2739  TP_DOMAIN *domain_ptr, temp_domain;
2740 
2741  dest_size = (len + 7) / 8;
2742 
2743  CHECK_PTR (err, bstring = (char *) db_private_alloc (NULL, dest_size + 1));
2744 
2745  if (qstr_bit_to_bin (bstring, dest_size, (char *) str, (int) len) != (int) len)
2746  {
2748  context->attrs[context->next_attr].att->header.name);
2749  CHECK_PARSE_ERR (err, ER_OBJ_DOMAIN_CONFLICT, context, DB_TYPE_BIT, str);
2750  }
2751 
2752  db_make_varbit (&temp, TP_FLOATING_PRECISION_VALUE, bstring, (int) len);
2753  temp.need_clear = true;
2754 
2755  GET_DOMAIN (context, domain);
2756 
2757  if (domain == NULL)
2758  {
2760  DB_TYPE_BIT, str);
2761  }
2762  else
2763  {
2764  CHECK_PARSE_ERR (err, db_value_domain_init (val, TP_DOMAIN_TYPE (domain), domain->precision, domain->scale),
2765  context, DB_TYPE_BIT, str);
2766  }
2767  domain_ptr = tp_domain_resolve_value (val, &temp_domain);
2768  if (tp_value_cast (&temp, val, domain_ptr, false))
2769  {
2771  context->attrs[context->next_attr].att->header.name);
2772  CHECK_PARSE_ERR (err, ER_OBJ_DOMAIN_CONFLICT, context, DB_TYPE_BIT, str);
2773  }
2774 
2775 error_exit:
2776  /* cleanup */
2777  db_value_clear (&temp);
2778  return err;
2779 }
2780 
2781 /*
2782  * ldr_bstr_db_varbit -
2783  * return:
2784  * context():
2785  * str():
2786  * len():
2787  * att():
2788  */
2789 static int
2790 ldr_bstr_db_varbit (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2791 {
2792  int err;
2793  DB_VALUE val;
2794 
2795  CHECK_ERR (err, ldr_bstr_elem (context, str, len, &val));
2796  CHECK_ERR (err, ldr_generic (context, &val));
2797 
2798 error_exit:
2799  db_value_clear (&val);
2800  return err;
2801 }
2802 
2803 /*
2804  * ldr_xstr_elem -
2805  * return:
2806  * context():
2807  * str():
2808  * len():
2809  * val():
2810  */
2811 static int
2812 ldr_xstr_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
2813 {
2814  int err = NO_ERROR;
2815  size_t dest_size;
2816  char *bstring = NULL;
2817  TP_DOMAIN *domain;
2818  DB_VALUE temp;
2819  TP_DOMAIN *domain_ptr, temp_domain;
2820 
2821  db_make_null (&temp);
2822 
2823  dest_size = (len + 1) / 2;
2824 
2825  CHECK_PTR (err, bstring = (char *) db_private_alloc (NULL, dest_size + 1));
2826 
2827  if (qstr_hex_to_bin (bstring, dest_size, (char *) str, (int) len) != (int) len)
2828  {
2830  CHECK_PARSE_ERR (err, ER_OBJ_DOMAIN_CONFLICT, context, DB_TYPE_BIT, str);
2831  }
2832 
2833  db_make_varbit (&temp, TP_FLOATING_PRECISION_VALUE, bstring, (int) len * 4);
2834  temp.need_clear = true;
2835 
2836  /* temp takes ownership of this piece of memory */
2837  bstring = NULL;
2838 
2839  GET_DOMAIN (context, domain);
2840 
2841  if (domain == NULL)
2842  {
2844  }
2845  else
2846  {
2847  CHECK_PARSE_ERR (err, db_value_domain_init (val, TP_DOMAIN_TYPE (domain), domain->precision, domain->scale),
2848  context, DB_TYPE_BIT, str);
2849  }
2850  domain_ptr = tp_domain_resolve_value (val, &temp_domain);
2851  if (tp_value_cast (&temp, val, domain_ptr, false))
2852  {
2854  context->attrs[context->next_attr].att->header.name);
2855  CHECK_PARSE_ERR (err, ER_OBJ_DOMAIN_CONFLICT, context, DB_TYPE_BIT, str);
2856  }
2857 
2858 error_exit:
2859  /* cleanup */
2860  if (bstring != NULL)
2861  {
2862  db_private_free_and_init (NULL, bstring);
2863  }
2864 
2865  db_value_clear (&temp);
2866  return err;
2867 }
2868 
2869 /*
2870  * ldr_xstr_db_varbit -
2871  * return:
2872  * context():
2873  * str():
2874  * len():
2875  * att():
2876  */
2877 static int
2878 ldr_xstr_db_varbit (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2879 {
2880  int err;
2881  DB_VALUE val;
2882 
2883  CHECK_ERR (err, ldr_xstr_elem (context, str, len, &val));
2884  CHECK_ERR (err, ldr_generic (context, &val));
2885 
2886 error_exit:
2887  db_value_clear (&val);
2888  return err;
2889 }
2890 
2891 /*
2892  * ldr_nstr_elem -
2893  * return:
2894  * context():
2895  * str():
2896  * len():
2897  * val():
2898  */
2899 static int
2900 ldr_nstr_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
2901 {
2902 
2905  return NO_ERROR;
2906 }
2907 
2908 /*
2909  * ldr_nstr_db_varnchar -
2910  * return:
2911  * context():
2912  * str():
2913  * len():
2914  * att():
2915  */
2916 static int
2917 ldr_nstr_db_varnchar (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2918 {
2919  int err = NO_ERROR;
2920  DB_VALUE val;
2921 
2922  CHECK_ERR (err, ldr_nstr_elem (context, str, len, &val));
2923  CHECK_ERR (err, ldr_generic (context, &val));
2924 
2925 error_exit:
2926  return err;
2927 }
2928 
2929 /*
2930  * NUMERIC SETTERS
2931  *
2932  * A "numeric" string is known to have a decimal point in it but *not* to
2933  * have any exponent. It may also have a leading sign character. Most of
2934  * the interesting cases (float and double attributes) will be handled by
2935  * the ldr_numeric_db_{float, double} functions below, but this one will
2936  * catch assignments into actual numeric attributes.
2937  */
2938 
2939 /*
2940  * ldr_numeric_elem -
2941  * return:
2942  * context():
2943  * str():
2944  * len():
2945  * val():
2946  */
2947 static int
2948 ldr_numeric_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
2949 {
2950  int precision, scale;
2951  int err = NO_ERROR;
2952 
2953  precision = (int) len - 1 - (str[0] == '+' || str[0] == '-');
2954  scale = (int) len - (int) strcspn (str, ".") - 1;
2955 
2956  CHECK_PARSE_ERR (err, db_value_domain_init (val, DB_TYPE_NUMERIC, precision, scale), context, DB_TYPE_NUMERIC, str);
2957  CHECK_PARSE_ERR (err, db_value_put (val, DB_TYPE_C_CHAR, (char *) str, (int) len), context, DB_TYPE_NUMERIC, str);
2958 
2959 error_exit:
2960  return err;
2961 }
2962 
2963 /*
2964  * ldr_numeric_db_generic -
2965  * return:
2966  * context():
2967  * str():
2968  * len():
2969  * att():
2970  */
2971 static int
2972 ldr_numeric_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
2973 {
2974  int err;
2975  DB_VALUE val;
2976 
2977  CHECK_ERR (err, ldr_numeric_elem (context, str, len, &val));
2978  CHECK_ERR (err, ldr_generic (context, &val));
2979 
2980 error_exit:
2981  return err;
2982 }
2983 
2984 /*
2985  * ldr_double_elem -
2986  * return:
2987  * context():
2988  * str():
2989  * len():
2990  * val():
2991  */
2992 static int
2993 ldr_double_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
2994 {
2995  double d;
2996  char *str_ptr;
2997  int err = NO_ERROR;
2998 
2999  val->domain = ldr_double_tmpl.domain;
3000  d = strtod (str, &str_ptr);
3001 
3002  /* The ascii representation should be ok, check for overflow */
3003 
3004  if (str_ptr == str || OR_CHECK_DOUBLE_OVERFLOW (d))
3005  {
3006  TP_DOMAIN *domain;
3007 
3008  GET_DOMAIN (context, domain);
3009 
3011  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, TP_DOMAIN_TYPE (domain), str);
3012  }
3013  else
3014  {
3015  val->data.d = d;
3016  }
3017 
3018 error_exit:
3019  return err;
3020 }
3021 
3022 /*
3023  * ldr_float_elem -
3024  * return:
3025  * context():
3026  * str():
3027  * len():
3028  * val():
3029  */
3030 static int
3031 ldr_float_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
3032 {
3033  double d;
3034  char *str_ptr;
3035  int err = NO_ERROR;
3036 
3037  val->domain = ldr_float_tmpl.domain;
3038  d = strtod (str, &str_ptr);
3039 
3040  /* The ascii representation should be ok, check for overflow */
3041 
3042  if (str_ptr == str || OR_CHECK_FLOAT_OVERFLOW (d))
3043  {
3044  TP_DOMAIN *domain;
3045 
3046  GET_DOMAIN (context, domain);
3047 
3049  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, TP_DOMAIN_TYPE (domain), str);
3050  }
3051  else
3052  {
3053  val->data.f = (float) d;
3054  }
3055 
3056 error_exit:
3057  return err;
3058 }
3059 
3060 /*
3061  * ldr_real_db_generic -
3062  * return:
3063  * context():
3064  * str():
3065  * len():
3066  * att():
3067  */
3068 static int
3069 ldr_real_db_generic (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
3070 {
3071  int err;
3072  DB_VALUE val;
3073 
3074  CHECK_ERR (err, ldr_double_elem (context, str, len, &val));
3075  CHECK_ERR (err, ldr_generic (context, &val));
3076 
3077 error_exit:
3078  return err;
3079 }
3080 
3081 /*
3082  * ldr_real_db_float -
3083  * return:
3084  * context():
3085  * str():
3086  * len():
3087  * att():
3088  */
3089 static int
3090 ldr_real_db_float (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
3091 {
3092  char *mem;
3093  int err;
3094  DB_VALUE val;
3095  double d;
3096  char *str_ptr;
3097 
3098  val.domain = ldr_float_tmpl.domain;
3099  d = strtod (str, &str_ptr);
3100 
3101  /* The ascii representation should be ok, check for overflow */
3102 
3103  if (str_ptr == str || OR_CHECK_FLOAT_OVERFLOW (d))
3104  {
3105  TP_DOMAIN *domain;
3106 
3107  GET_DOMAIN (context, domain);
3108 
3110  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, TP_DOMAIN_TYPE (domain), str);
3111  }
3112  else
3113  {
3114  val.data.f = (float) d;
3115  }
3116 
3117  mem = context->mobj + att->offset;
3118  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
3119  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
3120 
3121 error_exit:
3122  return err;
3123 }
3124 
3125 /*
3126  * ldr_real_db_double -
3127  * return:
3128  * context():
3129  * str():
3130  * len():
3131  * att():
3132  */
3133 static int
3134 ldr_real_db_double (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
3135 {
3136  char *mem;
3137  int err;
3138  DB_VALUE val;
3139  double d;
3140  char *str_ptr;
3141 
3142  val.domain = ldr_double_tmpl.domain;
3143  d = strtod (str, &str_ptr);
3144 
3145  /* The ascii representation should be ok, check for overflow */
3146 
3147  if (str_ptr == str || OR_CHECK_DOUBLE_OVERFLOW (d))
3148  {
3149  TP_DOMAIN *domain;
3150 
3151  GET_DOMAIN (context, domain);
3152 
3154  CHECK_PARSE_ERR (err, ER_IT_DATA_OVERFLOW, context, TP_DOMAIN_TYPE (domain), str);
3155  }
3156  else
3157  {
3158  val.data.d = d;
3159  }
3160 
3161  mem = context->mobj + att->offset;
3162  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
3163  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
3164 
3165 error_exit:
3166  return err;
3167 }
3168 
3169 /*
3170  * DATE/TIME/TIMESTAMP/DATETIME SETTERS
3171  *
3172  * Any of the "date", "time" , "timestamp" or "datetime" strings have already
3173  * had the tag and surrounding quotes stripped off. We know which one we
3174  * have by virtue knowing which function has been called.
3175  */
3176 
3177 /*
3178  * ldr_date_elem -
3179  * return:
3180  * context():
3181  * str():
3182  * len():
3183  * val():
3184  */
3185 static int
3186 ldr_date_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
3187 {
3188  int err = NO_ERROR;
3189 
3190  val->domain = ldr_date_tmpl.domain;
3191  CHECK_PARSE_ERR (err, db_string_to_date (str, &val->data.date), context, DB_TYPE_DATE, str);
3192 
3193 error_exit:
3194  return err;
3195 }
3196 
3197 /*
3198  * ldr_date_db_date -
3199  * return:
3200  * context():
3201  * str():
3202  * len():
3203  * att():
3204  */
3205 static int
3206 ldr_date_db_date (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
3207 {
3208  int err;
3209  char *mem;
3210  DB_VALUE val;
3211 
3212  CHECK_ERR (err, ldr_date_elem (context, str, len, &val));
3213  mem = context->mobj + att->offset;
3214  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
3215  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
3216 
3217 error_exit:
3218  return err;
3219 }
3220 
3221 /*
3222  * ldr_time_elem -
3223  * return:
3224  * context():
3225  * str():
3226  * len():
3227  * val():
3228  */
3229 static int
3230 ldr_time_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
3231 {
3232  int err = NO_ERROR;
3233 
3234  val->domain = ldr_time_tmpl.domain;
3235  CHECK_PARSE_ERR (err, db_string_to_time (str, &val->data.time), context, DB_TYPE_TIME, str);
3236 
3237 error_exit:
3238  return err;
3239 }
3240 
3241 /*
3242  * ldr_time_db_time -
3243  * return:
3244  * context():
3245  * str():
3246  * len():
3247  * att():
3248  */
3249 static int
3250 ldr_time_db_time (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
3251 {
3252  int err;
3253  char *mem;
3254  DB_VALUE val;
3255 
3256  CHECK_ERR (err, ldr_time_elem (context, str, len, &val));
3257  mem = context->mobj + att->offset;
3258  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
3259  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
3260 
3261 error_exit:
3262  return err;
3263 }
3264 
3265 /*
3266  * ldr_timestamp_elem -
3267  * return:
3268  * context():
3269  * str():
3270  * len():
3271  * val():
3272  */
3273 static int
3274 ldr_timestamp_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
3275 {
3276  int err = NO_ERROR;
3277 
3278  val->domain = ldr_timestamp_tmpl.domain;
3279  CHECK_PARSE_ERR (err, db_string_to_timestamp (str, &val->data.utime), context, DB_TYPE_TIMESTAMP, str);
3280 
3281 error_exit:
3282  return err;
3283 }
3284 
3285 /*
3286  * ldr_timestamp_db_timestamp -
3287  * return:
3288  * context():
3289  * str():
3290  * len():
3291  * att():
3292  */
3293 static int
3294 ldr_timestamp_db_timestamp (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
3295 {
3296  int err;
3297  char *mem;
3298  DB_VALUE val;
3299 
3300  CHECK_ERR (err, ldr_timestamp_elem (context, str, len, &val));
3301  mem = context->mobj + att->offset;
3302  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
3303  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
3304 
3305 error_exit:
3306  return err;
3307 }
3308 
3309 /*
3310  * ldr_timestamptz_elem -
3311  * return:
3312  * context():
3313  * str():
3314  * len():
3315  * val():
3316  */
3317 static int
3318 ldr_timestamptz_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
3319 {
3320  int err = NO_ERROR;
3321  bool has_zone;
3322 
3323  val->domain = ldr_timestamptz_tmpl.domain;
3324  CHECK_PARSE_ERR (err, db_string_to_timestamptz (str, &val->data.timestamptz, &has_zone), context, DB_TYPE_TIMESTAMPTZ,
3325  str);
3326  /* if no zone text, than it is assumed session timezone */
3327 
3328 error_exit:
3329  return err;
3330 }
3331 
3332 /*
3333  * ldr_timestampltz_elem -
3334  * return:
3335  * context():
3336  * str():
3337  * len():
3338  * val():
3339  */
3340 static int
3341 ldr_timestampltz_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
3342 {
3343  int err = NO_ERROR;
3344 
3345  val->domain = ldr_timestampltz_tmpl.domain;
3346  CHECK_PARSE_ERR (err, db_string_to_timestampltz (str, &val->data.utime), context, DB_TYPE_TIMESTAMPLTZ, str);
3347  /* if no zone text, than it is assumed session timezone */
3348 
3349 error_exit:
3350  return err;
3351 }
3352 
3353 /*
3354  * ldr_timestamptz_db_timestamptz -
3355  * return:
3356  * context():
3357  * str():
3358  * len():
3359  * att():
3360  */
3361 static int
3362 ldr_timestamptz_db_timestamptz (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
3363 {
3364  int err;
3365  char *mem;
3366  DB_VALUE val;
3367 
3368  CHECK_ERR (err, ldr_timestamptz_elem (context, str, len, &val));
3369  mem = context->mobj + att->offset;
3370  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
3371  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
3372 
3373 error_exit:
3374  return err;
3375 }
3376 
3377 /*
3378  * ldr_timestampltz_db_timestampltz -
3379  * return:
3380  * context():
3381  * str():
3382  * len():
3383  * att():
3384  */
3385 static int
3386 ldr_timestampltz_db_timestampltz (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
3387 {
3388  int err;
3389  char *mem;
3390  DB_VALUE val;
3391 
3392  CHECK_ERR (err, ldr_timestampltz_elem (context, str, len, &val));
3393  mem = context->mobj + att->offset;
3394  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
3395  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
3396 
3397 error_exit:
3398  return err;
3399 }
3400 
3401 /*
3402  * ldr_datetime_elem -
3403  * return:
3404  * context():
3405  * str():
3406  * len():
3407  * val():
3408  */
3409 static int
3410 ldr_datetime_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
3411 {
3412  int err = NO_ERROR;
3413 
3414  val->domain = ldr_datetime_tmpl.domain;
3415  CHECK_PARSE_ERR (err, db_string_to_datetime (str, &val->data.datetime), context, DB_TYPE_DATETIME, str);
3416 
3417 error_exit:
3418  return err;
3419 }
3420 
3421 /*
3422  * ldr_datetime_db_datetime -
3423  * return:
3424  * context():
3425  * str():
3426  * len():
3427  * att():
3428  */
3429 static int
3430 ldr_datetime_db_datetime (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
3431 {
3432  int err;
3433  char *mem;
3434  DB_VALUE val;
3435 
3436  CHECK_ERR (err, ldr_datetime_elem (context, str, len, &val));
3437  mem = context->mobj + att->offset;
3438  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
3439  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
3440 
3441 error_exit:
3442  return err;
3443 }
3444 
3445 /*
3446  * ldr_datetimetz_elem -
3447  * return:
3448  * context():
3449  * str():
3450  * len():
3451  * val():
3452  */
3453 static int
3454 ldr_datetimetz_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
3455 {
3456  int err = NO_ERROR;
3457  bool has_zone;
3458 
3459  val->domain = ldr_datetimetz_tmpl.domain;
3460  CHECK_PARSE_ERR (err, db_string_to_datetimetz (str, &val->data.datetimetz, &has_zone), context, DB_TYPE_DATETIMETZ,
3461  str);
3462  /* if no zone text, than it is assumed session timezone */
3463 
3464 error_exit:
3465  return err;
3466 }
3467 
3468 /*
3469  * ldr_datetimeltz_elem -
3470  * return:
3471  * context():
3472  * str():
3473  * len():
3474  * val():
3475  */
3476 static int
3477 ldr_datetimeltz_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
3478 {
3479  int err = NO_ERROR;
3480 
3481  val->domain = ldr_datetimeltz_tmpl.domain;
3482  CHECK_PARSE_ERR (err, db_string_to_datetimeltz (str, &val->data.datetime), context, DB_TYPE_DATETIMELTZ, str);
3483  /* if no zone text, than it is assumed session timezone */
3484 
3485 error_exit:
3486  return err;
3487 }
3488 
3489 /*
3490  * ldr_datetimetz_db_datetimetz -
3491  * return:
3492  * context():
3493  * str():
3494  * len():
3495  * att():
3496  */
3497 static int
3498 ldr_datetimetz_db_datetimetz (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
3499 {
3500  int err;
3501  char *mem;
3502  DB_VALUE val;
3503 
3504  CHECK_ERR (err, ldr_datetimetz_elem (context, str, len, &val));
3505  mem = context->mobj + att->offset;
3506  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
3507  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
3508 
3509 error_exit:
3510  return err;
3511 }
3512 
3513 /*
3514  * ldr_datetimeltz_db_datetimeltz -
3515  * return:
3516  * context():
3517  * str():
3518  * len():
3519  * att():
3520  */
3521 static int
3522 ldr_datetimeltz_db_datetimeltz (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
3523 {
3524  int err;
3525  char *mem;
3526  DB_VALUE val;
3527 
3528  CHECK_ERR (err, ldr_datetimeltz_elem (context, str, len, &val));
3529  mem = context->mobj + att->offset;
3530  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
3531  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
3532 
3533 error_exit:
3534  return err;
3535 }
3536 
3537 /*
3538  * ldr_date_time_conversion_error - display date/time validation error
3539  * return: void
3540  * token(in): string that failed.
3541  * type(in): loader type
3542  */
3543 static void
3544 ldr_date_time_conversion_error (const char *token, DB_TYPE type)
3545 {
3546  display_error_line (0);
3548  db_get_type_name (type));
3549 }
3550 
3551 /*
3552  * ldr_check_date_time_conversion - check time/date/timestamp string w.r.t. type
3553  * return: NO_ERROR if successful, error code otherwise
3554  * str(in): string to convert
3555  * type(in): loader type
3556  * Note:
3557  * Strings are checked for correctness during the validation only phase
3558  */
3559 static int
3561 {
3562  int err = NO_ERROR;
3563  DB_TIME dummy_time;
3564  DB_DATE dummy_date;
3565  DB_TIMESTAMP dummy_timestamp;
3566  DB_TIMESTAMPTZ dummy_timestamptz;
3567  DB_DATETIME dummy_datetime;
3568  DB_DATETIMETZ dummy_datetimetz;
3569  DB_TYPE current_type = DB_TYPE_NULL;
3570  bool has_zone;
3571 
3572  /*
3573  * Flag invalid date/time/timestamp strings as errors.
3574  * e.g., DATE '01///' should be an error, this is not detected by the lexical
3575  * analysis phase since DATE 'str' is valid.
3576  * Attempt to do the string to type conversion here.
3577  */
3578  switch (type)
3579  {
3580  case LDR_TIME:
3581  current_type = DB_TYPE_TIME;
3582  err = db_string_to_time (str, &dummy_time);
3583  break;
3584  case LDR_DATE:
3585  current_type = DB_TYPE_DATE;
3586  err = db_string_to_date (str, &dummy_date);
3587  break;
3588  case LDR_TIMESTAMP:
3589  current_type = DB_TYPE_TIMESTAMP;
3590  err = db_string_to_timestamp (str, &dummy_timestamp);
3591  break;
3592  case LDR_TIMESTAMPLTZ:
3593  current_type = DB_TYPE_TIMESTAMPLTZ;
3594  err = db_string_to_timestampltz (str, &dummy_timestamp);
3595  break;
3596  case LDR_TIMESTAMPTZ:
3597  current_type = DB_TYPE_TIMESTAMPTZ;
3598  err = db_string_to_timestamptz (str, &dummy_timestamptz, &has_zone);
3599  break;
3600  case LDR_DATETIME:
3601  current_type = DB_TYPE_DATETIME;
3602  err = db_string_to_datetime (str, &dummy_datetime);
3603  break;
3604  case LDR_DATETIMELTZ:
3605  current_type = DB_TYPE_DATETIMELTZ;
3606  err = db_string_to_datetimeltz (str, &dummy_datetime);
3607  break;
3608  case LDR_DATETIMETZ:
3609  current_type = DB_TYPE_DATETIMETZ;
3610  err = db_string_to_datetimetz (str, &dummy_datetimetz, &has_zone);
3611  break;
3612  default:
3613  break;
3614  }
3615 
3616  if (err != NO_ERROR)
3617  {
3618  if (err == ER_DATE_CONVERSION)
3619  {
3620  ldr_date_time_conversion_error (str, current_type);
3621  }
3622  else
3623  {
3624  display_error (0);
3625  }
3626  }
3627 
3628  return err;
3629 }
3630 
3631 /*
3632  * ldr_elo_int_elem -
3633  * return:
3634  * context():
3635  * str():
3636  * len():
3637  * val():
3638  */
3639 static int
3640 ldr_elo_int_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
3641 {
3642  /* not implemented. should not be called */
3643  assert (0);
3644  return ER_FAILED;
3645 }
3646 
3647 /*
3648  * ldr_elo_int_db_elo -
3649  * return:
3650  * context():
3651  * str():
3652  * len():
3653  * att():
3654  */
3655 static int
3656 ldr_elo_int_db_elo (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
3657 {
3658  /* not implemented. should not be called */
3659  assert (0);
3660  return ER_FAILED;
3661 }
3662 
3663 /*
3664  * ldr_elo_ext_elem -
3665  * return:
3666  * context():
3667  * str():
3668  * len():
3669  * val():
3670  */
3671 static int
3672 ldr_elo_ext_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
3673 {
3674  DB_ELO elo;
3675  int err = NO_ERROR;
3676  int result = 0;
3677  int new_len;
3678  INT64 size;
3679  char *locator = NULL;
3680  char *meta_data = NULL;
3681 
3682  if (!context->valid)
3683  {
3684  err = ER_LDR_INVALID_STATE;
3686 
3687  /* reset the error count by adding -1, since this is not real error */
3688  ldr_increment_err_count (context, -1);
3689  return (err);
3690  }
3691 
3692  PARSE_ELO_STR (str, new_len);
3693 
3694  /* parse elo string: see process_value () in unload_object.c */
3695  if (new_len > 0)
3696  {
3697  DB_TYPE type;
3698  char *size_sp, *size_ep;
3699  const char *locator_sp, *locator_ep;
3700  const char *meta_sp, *meta_ep;
3701 
3702  /* db type */
3703  assert (str[0] == 'B' || str[0] == 'C');
3704  if (str[0] == 'B')
3705  {
3706  type = DB_TYPE_BLOB;
3707  val->domain = ldr_blob_tmpl.domain;
3708  }
3709  else
3710  {
3711  type = DB_TYPE_CLOB;
3712  val->domain = ldr_clob_tmpl.domain;
3713  }
3714 
3715  /* size */
3716  size_sp = (char *) (str + 1);
3717  size_ep = strchr (size_sp, '|');
3718  if (size_ep == NULL || size_ep - size_sp == 0)
3719  {
3720  /* FBO TODO: error message --> invalid elo format */
3721  err = ER_LDR_ELO_INPUT_FILE;
3722  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, err, 1, str);
3723  goto error_exit;
3724  }
3725 
3726  /* locator */
3727  locator_sp = size_ep + 1;
3728  locator_ep = strchr (locator_sp, '|');
3729  if (locator_ep == NULL || locator_ep - locator_sp == 0)
3730  {
3731  /* FBO TODO: error message --> invalid elo format */
3732  err = ER_LDR_ELO_INPUT_FILE;
3733  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, err, 1, str);
3734  goto error_exit;
3735  }
3736 
3737  /* meta_data */
3738  meta_ep = meta_sp = locator_ep + 1;
3739  while (*meta_ep)
3740  {
3741  meta_ep++;
3742  }
3743 
3744  /* make elo */
3745  elo_init_structure (&elo);
3746 
3747  result = str_to_int64 (&size, &size_ep, size_sp, 10);
3748  if (result != 0 || size < 0)
3749  {
3750  err = ER_LDR_ELO_INPUT_FILE;
3752  goto error_exit;
3753  }
3754 
3755  locator = (char *) db_private_alloc (NULL, locator_ep - locator_sp + 1);
3756  if (locator == NULL)
3757  {
3758  goto error_exit;
3759  }
3760  memcpy (locator, locator_sp, locator_ep - locator_sp);
3761  locator[locator_ep - locator_sp] = '\0';
3762 
3763  if (meta_ep - meta_sp > 0)
3764  {
3765  meta_data = (char *) db_private_alloc (NULL, meta_ep - meta_sp + 1);
3766  if (meta_data == NULL)
3767  {
3768  goto error_exit;
3769  }
3770  memcpy (meta_data, meta_sp, meta_ep - meta_sp);
3771  meta_data[meta_ep - meta_sp] = '\0';
3772  }
3773 
3774  elo.size = size;
3775  elo.locator = locator;
3776  elo.meta_data = meta_data;
3777  elo.type = ELO_FBO;
3778 
3779  err = db_make_elo (val, type, &elo);
3780  if (err == NO_ERROR)
3781  {
3782  val->need_clear = true;
3783  locator = NULL;
3784  meta_data = NULL;
3785  }
3786  }
3787 
3788 error_exit:
3789  if (locator != NULL)
3790  {
3791  db_private_free_and_init (NULL, locator);
3792  }
3793 
3794  if (meta_data != NULL)
3795  {
3796  db_private_free_and_init (NULL, meta_data);
3797  }
3798 
3799  if (err != NO_ERROR)
3800  {
3801  display_error (0);
3802  }
3803 
3804  return err;
3805 }
3806 
3807 /*
3808  * ldr_elo_ext_db_elo -
3809  * return:
3810  * context():
3811  * str():
3812  * len():
3813  * att():
3814  */
3815 static int
3816 ldr_elo_ext_db_elo (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
3817 {
3818  int err = NO_ERROR;
3819  char *mem;
3820  DB_VALUE val;
3821  char name_buf[8196];
3822  char *name = NULL;
3823  size_t new_len;
3824 
3825  db_make_null (&val);
3826 
3827  PARSE_ELO_STR (str, new_len);
3828  if (new_len >= 8196)
3829  {
3830  name = (char *) malloc (new_len);
3831 
3832  if (name == NULL)
3833  {
3834  err = ER_LDR_MEMORY_ERROR;
3836  CHECK_CONTEXT_VALIDITY (context, true);
3837  ldr_abort ();
3838  goto error_exit;
3839  }
3840  }
3841  else
3842  {
3843  name = &name_buf[0];
3844  }
3845 
3846  strncpy (name, str, new_len);
3847  name[new_len] = '\0';
3848  CHECK_ERR (err, ldr_elo_ext_elem (context, name, new_len, &val));
3849  mem = context->mobj + att->offset;
3850  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
3851  /* No bound bit to be set for a variable length attribute. */
3852 
3853 error_exit:
3854  if (name != NULL && name != &name_buf[0])
3855  {
3856  free (name);
3857  }
3858  db_value_clear (&val);
3859 
3860  return err;
3861 }
3862 
3863 /*
3864  * LDR_MOP_TEMPOID_MAP MAINTENANCE
3865  */
3866 
3867 /*
3868  * ldr_mop_tempoid_maps_init - initialize ldr_Mop_tempoid_maps
3869  * return: NO_ERROR if successful, error code otherwise
3870  */
3871 static int
3873 {
3874  int err = NO_ERROR;
3875  int presize = 0;
3876 
3877  if (ldr_Mop_tempoid_maps)
3878  {
3879  ldr_Mop_tempoid_maps->count = 0;
3880  ldr_Mop_tempoid_maps->index = 0;
3881  return (err);
3882  }
3883  ldr_Mop_tempoid_maps = NULL;
3884 
3885  if ((ldr_Mop_tempoid_maps = (LDR_MOP_TEMPOID_MAPS *) malloc (sizeof (LDR_MOP_TEMPOID_MAPS))) == NULL)
3886  {
3888  return ER_LDR_MEMORY_ERROR;
3889  }
3890 
3891  presize = LDR_MOP_TEMPOID_MAPS_PRESIZE;
3892 
3893  if ((ldr_Mop_tempoid_maps->mop_tempoid_maps =
3894  (LDR_MOP_TEMPOID_MAP *) malloc (presize * sizeof (LDR_MOP_TEMPOID_MAP))) == NULL)
3895  {
3897  err = ER_LDR_MEMORY_ERROR;
3898  ldr_Mop_tempoid_maps->count = -1;
3899  ldr_Mop_tempoid_maps->index = -1;
3900  ldr_Mop_tempoid_maps->size = 0;
3901  }
3902  else
3903  {
3904  int i = 0;
3905  while (i < presize)
3906  {
3907  ldr_Mop_tempoid_maps->mop_tempoid_maps[i].mop = NULL;
3908  ldr_Mop_tempoid_maps->mop_tempoid_maps[i].table = NULL;
3909  ldr_Mop_tempoid_maps->mop_tempoid_maps[i].id = 0;
3910  i += 1;
3911  }
3912  ldr_Mop_tempoid_maps->count = 0;
3913  ldr_Mop_tempoid_maps->index = 0;
3914  ldr_Mop_tempoid_maps->size = presize;
3915  }
3916 
3917  return err;
3918 }
3919 
3920 /*
3921  * ldr_mop_tempoid_maps_final - Frees ldr_Mop_tempoid_maps.
3922  * return: NO_ERROR if successful, error code otherwise
3923  */
3924 static void
3926 {
3927  if (!ldr_Mop_tempoid_maps)
3928  {
3929  return;
3930  }
3931 
3932  if (ldr_Mop_tempoid_maps->mop_tempoid_maps)
3933  {
3934  free_and_init (ldr_Mop_tempoid_maps->mop_tempoid_maps);
3935  }
3936  free_and_init (ldr_Mop_tempoid_maps);
3937 
3938  return;
3939 }
3940 
3941 /*
3942  * ldr_add_mop_tempoid_map - add a temporary oid mop to CLASS_TABLE mapping
3943  * to ldr_Mop_tempoid_maps.
3944  * return: NO_ERROR if successful, error code otherwise
3945  * mop(in): MOP to add
3946  * table(out): CLASS_TABLE
3947  * id(in): instance id.
3948  */
3949 static int
3951 {
3952  int err = NO_ERROR;
3953 
3954  if (ldr_Mop_tempoid_maps == NULL || ldr_Mop_tempoid_maps->mop_tempoid_maps == NULL)
3955  {
3956  err = ldr_mop_tempoid_maps_init ();
3957  if (err != NO_ERROR)
3958  {
3959  display_error (0);
3960  return err;
3961  }
3962  }
3963 
3964  ldr_Mop_tempoid_maps->mop_tempoid_maps[ldr_Mop_tempoid_maps->index].mop = mop;
3965  ldr_Mop_tempoid_maps->mop_tempoid_maps[ldr_Mop_tempoid_maps->index].table = table;
3966  ldr_Mop_tempoid_maps->mop_tempoid_maps[ldr_Mop_tempoid_maps->index].id = id;
3967  ldr_Mop_tempoid_maps->count += 1;
3968  ldr_Mop_tempoid_maps->index += 1;
3969 
3970  /* Grow array if required */
3971 
3972  if (ldr_Mop_tempoid_maps->index == ldr_Mop_tempoid_maps->size)
3973  {
3974  LDR_MOP_TEMPOID_MAP *mop_tempoid_maps_old;
3975 
3976  mop_tempoid_maps_old = ldr_Mop_tempoid_maps->mop_tempoid_maps;
3977 
3978  ldr_Mop_tempoid_maps->mop_tempoid_maps =
3979  (LDR_MOP_TEMPOID_MAP *) realloc (ldr_Mop_tempoid_maps->mop_tempoid_maps,
3980  sizeof (LDR_MOP_TEMPOID_MAP) * (ldr_Mop_tempoid_maps->size +
3982 
3983  if (ldr_Mop_tempoid_maps->mop_tempoid_maps == NULL)
3984  {
3985  /* Prevent realloc memory leak, if error occurs. */
3986  if (mop_tempoid_maps_old)
3987  {
3988  free_and_init (mop_tempoid_maps_old);
3989  }
3991  return ER_LDR_MEMORY_ERROR;
3992  }
3993  else
3994  {
3995  ldr_Mop_tempoid_maps->size += LDR_MOP_TEMPOID_MAPS_PRESIZE;
3996  }
3997  }
3998 
3999  return err;
4000 }
4001 
4002 /*
4003  * ldr_assign_all_perm_oids - traverses ldr_Mop_tempoid_maps and creates a
4004  * list LC_OIDSET, to send to the server to get permanent oids.
4005  * return: NO_ERROR if successful, error code otherwise
4006  */
4007 static int
4009 {
4010  int err = NO_ERROR;
4011  LC_OIDSET *oidset = NULL;
4012  LDR_MOP_TEMPOID_MAP *mop_tempoid_map = NULL;
4013  INST_INFO *inst;
4014  int i;
4015 
4016  if (!ldr_Mop_tempoid_maps)
4017  {
4018  return (err);
4019  }
4020 
4021  /* No permanent oids to assign */
4022  if (!ldr_Mop_tempoid_maps->count)
4023  {
4024  return (NO_ERROR);
4025  }
4026 
4027  oidset = locator_make_oid_set ();
4028  if (oidset == NULL)
4029  {
4030  assert (er_errid () != NO_ERROR);
4031  err = er_errid ();
4032  }
4033  else
4034  {
4035  i = 0;
4036  while (i < ldr_Mop_tempoid_maps->count)
4037  {
4038  mop_tempoid_map = & (ldr_Mop_tempoid_maps->mop_tempoid_maps[i]);
4039  if (mop_tempoid_map->mop && OID_ISTEMP (WS_REAL_OID (mop_tempoid_map->mop)))
4040  {
4041  if (locator_add_oidset_object (oidset, mop_tempoid_map->mop) == NULL)
4042  {
4043  CHECK_ERR (err, er_errid ());
4044  }
4045  }
4046  i += 1;
4047  if (oidset->total_oids > OID_BATCH_SIZE)
4048  {
4049  CHECK_ERR (err, locator_assign_oidset (oidset, NULL));
4050  locator_clear_oid_set (NULL, oidset);
4051  }
4052  }
4053  /* call locator_assign_oidset(). This will make a server call to get permanent oids. */
4054  if (oidset->total_oids)
4055  {
4056  CHECK_ERR (err, locator_assign_oidset (oidset, NULL));
4057  }
4058 
4059  /* At this point the mapping between mop -> permanent oid should be complete. Update the otable oids via the oid
4060  * pointer obtained from the CLASS_TABLE and id. */
4061 
4062  if (!ldr_Current_context->args->no_oid_hint)
4063  {
4064  i = 0;
4065  while (i < ldr_Mop_tempoid_maps->count)
4066  {
4067  mop_tempoid_map = & (ldr_Mop_tempoid_maps->mop_tempoid_maps[i]);
4068  CHECK_PTR (err, inst = otable_find (mop_tempoid_map->table, mop_tempoid_map->id));
4069  COPY_OID (& (inst->oid), WS_REAL_OID (mop_tempoid_map->mop));
4070  mop_tempoid_map->mop = NULL;
4071  mop_tempoid_map->table = NULL;
4072  mop_tempoid_map->id = 0;
4073  i += 1;
4074  }
4075  }
4076 
4077  ldr_Mop_tempoid_maps->index = 0;
4078  ldr_Mop_tempoid_maps->count = 0;
4079  }
4080 error_exit:
4081  if (oidset)
4082  {
4083  locator_free_oid_set (NULL, oidset);
4084  }
4085 
4086  return err;
4087 }
4088 
4089 /*
4090  * find_instance - locates an instance OID given the class and an instance id.
4091  * return: NO_ERROR if successful, error code otherwise
4092  * context(in): context
4093  * class(in): class object
4094  * oid(out): instance OID (returned)
4095  * id(in): instance identifier
4096  * Note:
4097  * If the instance does not exist, an OID is reserved for this
4098  * instance.
4099  * Note : the oid references return are temporary OIDs. This will be
4100  * when the objects are packed to be sent to the server, using a batch
4101  * oid set.
4102  * The oids in the workspace to which the references point to are updated
4103  * via the call ldr_assign_all_perm_oids()
4104  */
4105 static int
4106 find_instance (LDR_CONTEXT *context, DB_OBJECT *class_, OID *oid, int id)
4107 {
4108  int err = NO_ERROR;
4109  CLASS_TABLE *table;
4110  INST_INFO *inst;
4111 
4112  table = otable_find_class (class_);
4113 
4114  if (table == NULL)
4115  {
4116  OID_SET_NULL (oid);
4117  assert (er_errid () != NO_ERROR);
4118  err = er_errid ();
4119  }
4120  else
4121  {
4122  inst = otable_find (table, id);
4123  if (inst != NULL)
4124  {
4125  /* Backward reference */
4126  *oid = inst->oid;
4127  }
4128  else
4129  {
4130  /* Forward reference */
4131  if ((class_ == context->cls) && (context->inst_num == id))
4132  {
4133  /*
4134  * We have a reference to the current object being processed.
4135  * Simply use the oid of the object.
4136  */
4137  COPY_OID (oid, WS_REAL_OID (context->obj));
4138  }
4139  else
4140  {
4141  /* Forward reference */
4142  OID_SET_NULL (oid);
4143 
4144  /* sigh, should try to catch this at a higher level */
4145  if (is_internal_class (class_))
4146  {
4149  }
4150  else
4151  {
4152  MOP mop;
4153  INST_INFO *inst;
4154  /*
4155  * Create object, this will be used used when the instance
4156  * is defined in the load file.
4157  * We do not mark the MOP as released yet. This will be done
4158  * when we encounter the real instance.
4159  */
4160  CHECK_PTR (err, mop = db_create_internal (context->attrs[context->next_attr].ref_class));
4161  COPY_OID (oid, WS_REAL_OID (mop));
4162  CHECK_ERR (err, otable_reserve (table, oid, id));
4163  CHECK_PTR (err, inst = otable_find (table, id));
4164  /*
4165  * Mark forward references to class attributes so that we do
4166  * not cull the objects they point to after we encounter them.
4167  */
4168  if (context->attr_type != LDR_ATTRIBUTE_ANY)
4169  {
4170  otable_class_att_ref (inst);
4171  }
4172 
4173  /*
4174  * Add to the list of mops for which we need a permanent oid
4175  * for
4176  */
4177  CHECK_ERR (err, ldr_add_mop_tempoid_map (mop, table, id));
4178  }
4179  }
4180  }
4181  }
4182 error_exit:
4183  return (err);
4184 }
4185 
4186 /*
4187  * ldr_class_oid_elem -
4188  * return:
4189  * context():
4190  * str():
4191  * len():
4192  * val():
4193  */
4194 static int
4195 ldr_class_oid_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
4196 {
4197  int err = NO_ERROR;
4198 
4199  if (context->attrs[context->next_attr].ref_class == NULL)
4200  {
4201  ldr_internal_error (context);
4202  goto error_exit;
4203  }
4204 
4205  CHECK_ERR (err, check_class_domain (context));
4206  db_make_object (val, context->attrs[context->next_attr].ref_class);
4207 
4208 error_exit:
4209  return err;
4210 }
4211 
4212 /*
4213  * ldr_class_oid_db_object -
4214  * return:
4215  * context():
4216  * str():
4217  * len():
4218  * att():
4219  */
4220 static int
4221 ldr_class_oid_db_object (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
4222 {
4223  int err = NO_ERROR;
4224  DB_VALUE val;
4225  char *mem;
4226 
4227  CHECK_ERR (err, ldr_class_oid_elem (context, str, len, &val));
4228 
4229  /*
4230  * We need to treat shared attributes in the generic way.
4231  * There is a problem when setting the bound bit for shared attributes.
4232  */
4234  {
4235  ldr_generic (context, &val);
4236  }
4237  else
4238  {
4239  mem = context->mobj + att->offset;
4240  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
4241  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
4242  }
4243 
4244 error_exit:
4245  ldr_increment_err_count (context, (err != NO_ERROR));
4246  return err;
4247 }
4248 
4249 /*
4250  * ldr_oid_elem -
4251  * return:
4252  * context():
4253  * str():
4254  * len():
4255  * val():
4256  */
4257 static int
4258 ldr_oid_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
4259 {
4260  int err = NO_ERROR;
4261  DB_OBJECT *actual_class;
4262  OID oid;
4263 
4264  if (context->attrs[context->next_attr].ref_class == NULL)
4265  {
4266  ldr_internal_error (context);
4267  goto error_exit;
4268  }
4269 
4270  CHECK_ERR (err, check_object_domain (context, context->attrs[context->next_attr].ref_class, &actual_class));
4271  err = find_instance (context, actual_class, &oid, context->attrs[context->next_attr].instance_id);
4272  if (err == ER_LDR_INTERNAL_REFERENCE)
4273  {
4274  db_make_null (val);
4275  }
4276  else
4277  {
4278  DB_OBJECT *mop;
4279 
4280  if ((mop = ws_mop (&oid, context->attrs[context->next_attr].ref_class)) == NULL)
4281  {
4282  if ((err = er_errid ()) == NO_ERROR)
4283  {
4284  err = ER_GENERIC_ERROR;
4286  }
4287  CHECK_ERR (err, err);
4288  }
4289 
4290  db_make_object (val, mop);
4291  }
4292 
4293 error_exit:
4294  ldr_increment_err_count (context, (err != NO_ERROR));
4295  return err;
4296 }
4297 
4298 /*
4299  * ldr_oid_db_object -
4300  * return:
4301  * context():
4302  * str():
4303  * len():
4304  * att():
4305  */
4306 static int
4307 ldr_oid_db_object (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
4308 {
4309  int err = NO_ERROR;
4310  DB_VALUE val;
4311  char *mem;
4312 
4313  CHECK_ERR (err, ldr_oid_elem (context, str, len, &val));
4314 
4315  mem = context->mobj + att->offset;
4316 
4317  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
4318  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
4319 
4320 error_exit:
4321  return (err);
4322 }
4323 
4324 /*
4325  * ldr_monetary_elem -
4326  * return:
4327  * context():
4328  * str():
4329  * len():
4330  * val():
4331  */
4332 static int
4333 ldr_monetary_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
4334 {
4335  const unsigned char *p = (const unsigned char *) str;
4336  const unsigned char *token = (const unsigned char *) str;
4337  char *str_ptr;
4338  double amt;
4339  int err = NO_ERROR;
4340  int symbol_size = 0;
4341  DB_CURRENCY currency_type = DB_CURRENCY_NULL;
4342 
4343  if (len >= 2
4344  && intl_is_currency_symbol ((const char *) p, &currency_type, &symbol_size,
4346  {
4347  token += symbol_size;
4348  }
4349 
4350  if (currency_type == DB_CURRENCY_NULL)
4351  {
4352  currency_type = DB_CURRENCY_DOLLAR;
4353  }
4354 
4355  amt = strtod ((const char *) token, &str_ptr);
4356 
4357  if (str == str_ptr || OR_CHECK_DOUBLE_OVERFLOW (amt))
4358  {
4361  }
4362  else
4363  {
4364  db_make_monetary (val, currency_type, amt);
4365  }
4366 
4367 error_exit:
4368  return (err);
4369 }
4370 
4371 /*
4372  * ldr_monetary_db_monetary -
4373  * return:
4374  * context():
4375  * str():
4376  * len():
4377  * att():
4378  */
4379 static int
4380 ldr_monetary_db_monetary (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
4381 {
4382  int err;
4383  char *mem;
4384  DB_VALUE val;
4385 
4386  CHECK_ERR (err, ldr_monetary_elem (context, str, len, &val));
4387  mem = context->mobj + att->offset;
4388  CHECK_ERR (err, att->domain->type->setmem (mem, att->domain, &val));
4389  OBJ_SET_BOUND_BIT (context->mobj, att->storage_order);
4390 
4391 error_exit:
4392  return err;
4393 }
4394 
4395 /*
4396  * ldr_collection_elem -
4397  * return:
4398  * context():
4399  * str():
4400  * len():
4401  * val():
4402  */
4403 static int
4404 ldr_collection_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
4405 {
4406  int err = ER_LDR_NESTED_SET;
4408  display_error (0);
4409  (void) ldr_null_elem (context, str, len, val);
4410  return err;
4411 }
4412 
4413 /*
4414  * ldr_collection_db_collection -
4415  * return:
4416  * context():
4417  * str():
4418  * len():
4419  * att():
4420  */
4421 static int
4422 ldr_collection_db_collection (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
4423 {
4424  int err = NO_ERROR;
4425  LDR_ATTDESC *attdesc;
4426 
4427  attdesc = &context->attrs[context->next_attr];
4428 
4429  /* Set the approriate action function to deal with collection elements */
4430 
4432 
4433  if (context->collection == NULL)
4434  {
4435  /*
4436  * This kind of bites: we need to avoid advancing the next_attr
4437  * counter until we actually hit the closing brace. Since ldr_act_attr
4438  * (which has called this function) will increment the counter
4439  * unconditionally, we decrement it here to compensate. I with there
4440  * were a better way of dealing with this.
4441  */
4442  context->next_attr -= 1;
4443 
4444  /*
4445  * We've just seen the leading brace of a collection, and we need to
4446  * create the "holding" collection.
4447  */
4448  context->collection = db_col_create (TP_DOMAIN_TYPE (att->domain), 0, attdesc->collection_domain);
4449 
4450  if (context->collection == NULL)
4451  {
4452  assert (er_errid () != NO_ERROR);
4453  err = er_errid ();
4454  }
4455  else
4456  {
4457  context->set_domain = attdesc->collection_domain->setdomain;
4458  }
4459  }
4460  else
4461  {
4462  /*
4463  * We've seen the trailing brace that ends the collection, and it's
4464  * now time to assign the collection to the instance.
4465  */
4466  DB_VALUE tmp;
4467 
4468  db_make_collection (&tmp, context->collection);
4469 
4470  context->collection = NULL;
4471  context->set_domain = NULL;
4472 
4473  /* We finished dealing with elements of a collection, set the action function to deal with normal attributes. */
4474  if (context->attr_type == LDR_ATTRIBUTE_ANY)
4475  {
4477  err = ldr_generic (context, &tmp);
4478  }
4479  else
4480  {
4482  err = ldr_class_attr_db_generic (context, str, len, context->attrs[context->next_attr].att, &tmp);
4483  }
4484  }
4485  return err;
4486 }
4487 
4488 /*
4489  * ldr_reset_context -
4490  * return:
4491  * context():
4492  */
4493 static int
4495 {
4496  int err = NO_ERROR;
4497  INST_INFO *inst = NULL;
4498 
4499  /*
4500  * Check that we are not dealing with class attributes, use attribute_type
4501  * Do not create instances for class attributes.
4502  */
4503  if (context->cls && context->attr_type == LDR_ATTRIBUTE_ANY && context->constructor == NULL)
4504  {
4505 
4506  /* Check that this instance was not a forward reference */
4507  if (context->table && context->inst_num > -1)
4508  {
4509  inst = otable_find (context->table, context->inst_num);
4510  }
4511 
4512  if (inst && (inst->flags & INST_FLAG_RESERVED))
4513  {
4514  /*
4515  * This instance was already referenced and a workspace MOP created.
4516  */
4517  context->obj = ws_mop (& (inst->oid), context->cls);
4518  if (context->obj == NULL)
4519  {
4520  err = er_filter_errid (false);
4521  display_error (0);
4522  goto error_exit;
4523  }
4524  /*
4525  * If this was a forward reference from a class attribute than we
4526  * do not want to mark it as releasable.
4527  */
4528  if (! (inst->flags & INST_FLAG_CLASS_ATT))
4529  {
4530  ws_release_instance (context->obj);
4531  }
4532  }
4533  else
4534  {
4535  context->obj = db_create_internal (context->cls);
4536  if (context->obj == NULL)
4537  {
4538  err = er_filter_errid (false);
4539  display_error (0);
4540  goto error_exit;
4541  }
4542 
4543  /* set pruning type to be performed on this object */
4544  context->obj->pruning_type = context->class_type;
4545 
4546  /*
4547  * Mark this mop as released so that we can cull it when we
4548  * complete inserting this instance.
4549  */
4550  ws_release_instance (context->obj);
4551  }
4552  CHECK_ERR (err,
4554  ws_pin_instance_and_class (context->obj, &context->obj_pin, &context->class_pin);
4556  }
4557  context->next_attr = 0;
4558  ldr_clear_err_count (context);
4559 
4560 error_exit:
4561  CHECK_CONTEXT_VALIDITY (context, err != NO_ERROR);
4562  return err;
4563 }
4564 
4565 /*
4566  * ldr_flush -
4567  * return:
4568  * context():
4569  */
4570 static void
4572 {
4573  if (context->cls)
4574  {
4575  ws_intern_instances (context->cls);
4576  }
4577  context->flush_total += 1;
4578  context->inst_count = 0;
4579 }
4580 
4581 /*
4582  * check_commit - check interrupt and commit w.r.t. commit period
4583  * return: NO_ERROR if successful, error code otherwise
4584  * context(in): context
4585  * Note:
4586  * Checks to see if the interrupt flag was raised. If it was we check
4587  * the interrupt type. We abort or commit based on the interrupt type.
4588  * The interrupt type is determined by whether logging was enabled or not.
4589  * Checks the state of the periodic commit counters.
4590  * If this is enabled and the counter goes to zero, we commit
4591  * the transaction.
4592  */
4593 static int
4595 {
4596  int err = NO_ERROR;
4597  int64_t committed_instances = 0;
4598 
4599  /* Check interrupt flag */
4601  {
4603  {
4604  CHECK_ERR (err, db_abort_transaction ());
4605  display_error_line (-1);
4607  if (context->args->periodic_commit && Total_objects >= context->args->periodic_commit)
4608  {
4609  committed_instances = Total_objects - (context->args->periodic_commit - context->commit_counter);
4610  }
4611  else
4612  {
4613  committed_instances = 0;
4614  }
4615  }
4616  else
4617  {
4618  if (context->cls != NULL)
4619  {
4621  CHECK_ERR (err, db_commit_transaction ());
4622  Last_committed_line = ldr_Driver->get_scanner ().lineno () - 1;
4623  committed_instances = Total_objects + 1;
4624  display_error_line (-1);
4625  fprintf (stderr,
4627  }
4628  }
4629 
4630  /* Invoke post interrupt callback function */
4632  {
4633  (*ldr_post_interrupt_handler) (committed_instances);
4634  }
4635 
4636  if (ldr_Jmp_buf_ptr != NULL)
4637  {
4638  longjmp (*ldr_Jmp_buf_ptr, 1);
4639  }
4640  else
4641  {
4642  return (err);
4643  }
4644  }
4645 
4646  if (context->args->periodic_commit)
4647  {
4648  context->commit_counter--;
4649  if (context->commit_counter <= 0)
4650  {
4651  if (context->cls != NULL)
4652  {
4653  print_log_msg (context->args->verbose,
4656  CHECK_ERR (err, db_commit_transaction ());
4657  Last_committed_line = ldr_Driver->get_scanner ().lineno () - 1;
4658  context->commit_counter = context->args->periodic_commit;
4659 
4660  /* Invoke post commit callback function */
4662  {
4663  (*ldr_post_commit_handler) ((Total_objects + 1));
4664  }
4665 
4666  /* After a commit we need to ensure that our attributes and attribute descriptors are updated. The commit
4667  * process can pull these from under us if another client is also updating the class. */
4668  CHECK_ERR (err, ldr_refresh_attrs (context));
4669  }
4670  }
4671  }
4672 
4673 error_exit:
4674  if (err != NO_ERROR)
4675  {
4676  display_error_line (-1);
4677  fprintf (stderr, "%s\n", db_error_string (3));
4678  committed_instances = (-1);
4679  CHECK_CONTEXT_VALIDITY (context, true);
4680  ldr_increment_err_count (context, 1);
4681  }
4682  return err;
4683 }
4684 
4685 /*
4686  * ldr_restore_pin_and_drop_obj - restore pin flag of a object and delete the
4687  * object optionally
4688  * return: in
4689  * context(in/out):
4690  * drop_obj(in): if set, delete object also
4691  */
4692 static void
4694 {
4695  if (context->obj)
4696  {
4697  ws_restore_pin (context->obj, context->obj_pin, context->class_pin);
4698  if (drop_obj)
4699  {
4700  db_drop (context->obj);
4701  context->obj = NULL;
4702  }
4703  }
4704 }
4705 
4706 /*
4707  * ldr_fini_context - finish parse context
4708  * return: NO_ERROR if successful, error code otherwise
4709  * context(in/out): context
4710  */
4711 static int
4713 {
4714  int err = er_filter_errid (false);
4715 
4716  if (err != NO_ERROR)
4717  {
4718  CHECK_CONTEXT_VALIDITY (context, true);
4719  }
4720  else
4721  {
4722  if (!context->validation_only)
4723  {
4724  /*
4725  * Get permanent oids for the current class,
4726  * Note : we have to this even if the instance total is 0 since
4727  * we might have had forward object references, specified from
4728  * class DEFAULT, SHARED or CLASS attributes
4729  */
4731  /* Need to flush the class now, for class attributes. Class objects are flushed during a commit, if
4732  * ws_intern_instances() is called and culls object references from within a class_object the class_object
4733  * will loose these references. */
4734  if (context->attr_type != LDR_ATTRIBUTE_ANY)
4735  {
4736  if (locator_flush_class (context->cls) != NO_ERROR)
4737  {
4738  CHECK_ERR (err, er_errid ());
4739  }
4740  }
4741  }
4742  if (context->inst_total && context->valid)
4743  {
4744  if (!context->validation_only)
4745  {
4746  ldr_flush (context);
4747  CHECK_ERR (err, er_errid ());
4748  }
4749  if (context->args->verbose)
4750  {
4752  (context->class_name ? context->class_name : ""), context->inst_total);
4753  }
4754  }
4755  }
4756 
4757  /* Reset the action function to deal with attributes */
4759 
4760 #if defined(CUBRID_DEBUG)
4761  if ((err == NO_ERROR) && (envvar_get ("LOADER_DEBUG") != NULL))
4762  {
4763  if (context->inst_total)
4764  {
4765  printf ("%d %s %s inserted in %d %s\n", context->inst_total, ldr_class_name (context),
4766  context->inst_total == 1 ? "instance" : "instances", context->flush_total,
4767  context->flush_total == 1 ? "flush" : "flushes");
4768  }
4769 
4770  if (context->err_total)
4771  {
4772  printf ("%d %s %s ignored because of errors\n", context->err_total, ldr_class_name (context),
4773  context->err_total == 1 ? "instance" : "instances");
4774  }
4775  }
4776 #endif /* CUBRID_DEBUG */
4777 
4778  ldr_clear_and_free_context (context);
4779 
4780 error_exit:
4781  if (err != NO_ERROR)
4782  {
4783  ldr_abort ();
4784  }
4785  return (err);
4786 }
4787 
4788 /*
4789  * ldr_act_init_context -
4790  * return:
4791  * context():
4792  * class_name():
4793  * len():
4794  */
4795 static void
4796 ldr_act_init_context (LDR_CONTEXT *context, const char *class_name, size_t len)
4797 {
4798  int err = NO_ERROR;
4799  DB_OBJECT *class_mop;
4800 
4801  CHECK_SKIP ();
4802 
4803  er_clear ();
4804 
4805  err = ldr_finish_context (context);
4806  if (err != NO_ERROR)
4807  {
4808  display_error (-1);
4809  return;
4810  }
4811  if (class_name)
4812  {
4814  {
4815  display_error_line (0);
4818  CHECK_CONTEXT_VALIDITY (context, true);
4819  ldr_abort ();
4820  goto error_exit;
4821  }
4822 
4823  class_mop = ldr_find_class (class_name);
4824  if (class_mop == NULL)
4825  {
4826  display_error_line (0);
4828  class_name);
4829  CHECK_CONTEXT_VALIDITY (context, true);
4830  ldr_abort ();
4831  goto error_exit;
4832  }
4833  if (!context->validation_only)
4834  {
4835  context->cls = class_mop;
4836  /*
4837  * Cache the class name. This will be used if we have a periodic
4838  * commit and need to refresh the class
4839  * This is a temporary fix, we will have to cache all the class
4840  * names that we deal with, and refetch the classes and locks
4841  * after a periodic commit.
4842  */
4843  context->class_name = (char *) malloc (len + 1);
4844  if (context->class_name == NULL)
4845  {
4847  CHECK_CONTEXT_VALIDITY (context, true);
4848  ldr_abort ();
4849  goto error_exit;
4850  }
4851  strcpy (context->class_name, class_name);
4852 
4853  if (is_internal_class (context->cls))
4854  {
4855  err = ER_LDR_SYSTEM_CLASS;
4856  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, err, 1, class_name);
4857  CHECK_CONTEXT_VALIDITY (context, true);
4858  display_error (-1);
4859  ldr_abort ();
4860  CHECK_ERR (err, err);
4861  }
4862  err = sm_partitioned_class_type (class_mop, &context->class_type, NULL, NULL);
4863  if (err != NO_ERROR)
4864  {
4865  CHECK_CONTEXT_VALIDITY (context, true);
4866  ldr_abort ();
4867  goto error_exit;
4868  }
4869  }
4870  }
4871 
4872  context->valid = true;
4873  if (context->args->verbose && class_name != NULL)
4874  {
4876  class_name);
4877  fflush (stdout);
4878  }
4879 
4880  CHECK_VALIDATION_ONLY (context);
4881 
4882  if (context->cls)
4883  {
4884  if ((context->table = otable_find_class (context->cls)) == NULL)
4885  {
4886  err = ER_LDR_MEMORY_ERROR;
4888  display_error (-1);
4889  ldr_internal_error (context);
4890  CHECK_CONTEXT_VALIDITY (context, true);
4891  }
4892  }
4893 
4894 error_exit:
4895  return;
4896 }
4897 
4898 /*
4899  * ldr_act_check_missing_non_null_attrs - xxx
4900  * return:
4901  * context(in): current context
4902  * Note:
4903  * xxx
4904  */
4905 static int
4907 {
4908  int err = NO_ERROR;
4909  int i;
4910  DB_ATTDESC *db_attdesc;
4911  SM_CLASS *class_;
4912  SM_ATTRIBUTE *att;
4913 
4914  CHECK_SKIP_WITH (err);
4915  RETURN_IF_NOT_VALID_WITH (context, err);
4916 
4917  if (context->validation_only)
4918  {
4919  goto error_exit;
4920  }
4921 
4922  err = au_fetch_class (context->cls, &class_, AU_FETCH_READ, AU_SELECT);
4923  if (err != NO_ERROR)
4924  {
4925  goto error_exit;
4926  }
4927 
4928  switch (context->attr_type)
4929  {
4930  case LDR_ATTRIBUTE_CLASS:
4931  att = class_->class_attributes;
4932  break;
4933  case LDR_ATTRIBUTE_SHARED:
4934  att = class_->shared;
4935  break;
4936  case LDR_ATTRIBUTE_ANY:
4937  case LDR_ATTRIBUTE_DEFAULT:
4938  att = class_->attributes;
4939  break;
4940  default:
4941  att = NULL; /* impossible case */
4942  break;
4943  }
4944  if (att == NULL)
4945  {
4946  goto error_exit; /* do nothing */
4947  }
4948 
4949  for (; att != NULL; att = (SM_ATTRIBUTE *) att->header.next)
4950  {
4951  if (att->flags & SM_ATTFLAG_NON_NULL)
4952  {
4953  for (i = 0; i < context->num_attrs; i++)
4954  {
4955  db_attdesc = context->attrs[i].attdesc;
4956  if (db_attdesc->name_space == att->header.name_space
4957  && intl_identifier_casecmp (db_attdesc->name, att->header.name) == 0)
4958  {
4959  break;
4960  }
4961  }
4962 
4963  /* not found */
4964  if (i >= context->num_attrs)
4965  {
4966  char class_attr[512];
4967 
4968  snprintf (class_attr, 512, "%s.%s", context->class_name, att->header.name);
4971  }
4972  }
4973  }
4974 
4975 error_exit:
4976  if (err != NO_ERROR)
4977  {
4978  CHECK_CONTEXT_VALIDITY (context, true);
4979  ldr_abort ();
4980  }
4981  return err;
4982 }
4983 
4984 /*
4985  * ldr_act_add_attr - Sets up the appropriate setters for the dealing with the
4986  * attributes.
4987  * return: void
4988  * context(in/out): current context
4989  * attr_name(in): attribute name token
4990  * len(in): length of token
4991  * Note:
4992  * Determines the target type and sets the setter accordingly
4993  */
4994 static void
4995 ldr_act_add_attr (LDR_CONTEXT *context, const char *attr_name, size_t len)
4996 {
4997  int err = NO_ERROR;
4998  int i, n;
4999  LDR_ATTDESC *attdesc, *attrs_old;
5000  SM_CLASS *class_;
5001  SM_COMPONENT **comp_ptr = NULL;
5002 
5003  CHECK_SKIP ();
5004  RETURN_IF_NOT_VALID (context);
5005 
5006  if (context->validation_only)
5007  {
5008  context->num_attrs += 1;
5009  goto error_exit;
5010  }
5011 
5012  n = context->num_attrs + context->arg_count;
5013 
5014  attrs_old = context->attrs;
5015  context->attrs = (LDR_ATTDESC *) realloc (context->attrs, (n + 1) * sizeof (context->attrs[0]));
5016  if (context->attrs == NULL)
5017  {
5018  free_and_init (attrs_old); /* Prevent leakage if realloc fails */
5020  }
5021 
5022  CHECK_PTR (err, context->attrs);
5023  attdesc = &context->attrs[n];
5024 
5025  attdesc->attdesc = NULL;
5026  attdesc->att = NULL;
5027  attdesc->parser_str_len = 0;
5028  attdesc->parser_buf_len = 0;
5029  attdesc->parser_str = NULL;
5030  attdesc->ref_class = NULL;
5031  attdesc->collection_domain = NULL;
5032 
5033  /*
5034  * Initialize the setters to something that hopefully won't crash and
5035  * burn if either of the following initialization calls fails.
5036  */
5037  for (i = 0; i < NUM_LDR_TYPES; i++)
5038  {
5039  attdesc->setter[i] = &ldr_ignore;
5040  }
5041 
5042  if (context->constructor)
5043  {
5044  /*
5045  * At this point the parser has seen the CONSTRUCTOR syntax.
5046  * We are dealing with arguments for the constructor.
5047  * There is no attribute descriptor for method arguments so a check
5048  * to see that the number of args is within the number of args specified
5049  * is made and the function returns.
5050  */
5051  if (context->constructor->signatures->num_args
5052  && (context->arg_count >= context->constructor->signatures->num_args))
5053  {
5055  context->constructor->signatures->num_args);
5057  }
5058  return;
5059  }
5060 
5061  CHECK_ERR (err,
5062  db_get_attribute_descriptor (context->cls, attr_name, context->attr_type == LDR_ATTRIBUTE_CLASS, true,
5063  &attdesc->attdesc));
5064  comp_ptr = (SM_COMPONENT **) (&attdesc->att);
5065  CHECK_ERR (err, sm_get_descriptor_component (context->cls, attdesc->attdesc, 1, /* for update */
5066  &class_, comp_ptr));
5067 
5068  context->num_attrs += 1;
5069 
5070  /*
5071  * When dealing with class attributes the normal setters are not used, since
5072  * they rely on the use of an empty instance.
5073  */
5074  if (context->attr_type != LDR_ATTRIBUTE_ANY)
5075  {
5076  int invalid_attr = 0;
5077  /*
5078  * Set elements need to be gathhers in a collection value bucket
5079  * We can use the existing setter for this.
5080  */
5081  if (TP_IS_SET_TYPE (TP_DOMAIN_TYPE (attdesc->att->domain)))
5082  {
5084  CHECK_ERR (err, select_set_domain (context, attdesc->att->domain, & (attdesc->collection_domain)));
5085  }
5086  if (context->attr_type == LDR_ATTRIBUTE_SHARED)
5087  {
5088  if (attdesc->att->header.name_space != ID_SHARED_ATTRIBUTE)
5089  {
5090  invalid_attr = 1;
5091  }
5092  }
5093  else if (context->attr_type == LDR_ATTRIBUTE_CLASS)
5094  {
5095  if (attdesc->att->header.name_space != ID_CLASS_ATTRIBUTE)
5096  {
5097  invalid_attr = 1;
5098  }
5099  }
5100  if (invalid_attr)
5101  {
5103  ldr_class_name (context));
5105  }
5106  goto error_exit;
5107  }
5108 
5109  /*
5110  * Now that we know we really have an attribute descriptor and a
5111  * SM_ATTRIBUTE, we can go ahead and initialize our setters to
5112  * something that can exploit them.
5113  */
5114  for (i = 0; i < NUM_LDR_TYPES; i++)
5115  {
5116  attdesc->setter[i] = &ldr_mismatch;
5117  }
5118 
5119  attdesc->setter[LDR_NULL] = &ldr_null_db_generic;
5120  attdesc->setter[LDR_INT] = &ldr_int_db_generic;
5122  attdesc->setter[LDR_DOUBLE] = &ldr_real_db_generic;
5123  attdesc->setter[LDR_FLOAT] = &ldr_real_db_generic;
5124 
5125  /*
5126  * These two system object setters are setup to return an
5127  * appropriate error message to the user.
5128  */
5129 
5132 
5133  switch (TP_DOMAIN_TYPE (attdesc->att->domain))
5134  {
5135  case DB_TYPE_CHAR:
5136  attdesc->setter[LDR_STR] = &ldr_str_db_char;
5137  break;
5138 
5139  case DB_TYPE_VARCHAR:
5140  attdesc->setter[LDR_STR] = &ldr_str_db_varchar;
5141  break;
5142 
5143  case DB_TYPE_BIGINT:
5144  attdesc->setter[LDR_INT] = &ldr_int_db_bigint;
5145  break;
5146 
5147  case DB_TYPE_INTEGER:
5148  attdesc->setter[LDR_INT] = &ldr_int_db_int;
5149  break;
5150 
5151  case DB_TYPE_SHORT:
5152  attdesc->setter[LDR_INT] = &ldr_int_db_short;
5153  break;
5154 
5155  case DB_TYPE_FLOAT:
5156  attdesc->setter[LDR_INT] = &ldr_real_db_float;
5157  attdesc->setter[LDR_NUMERIC] = &ldr_real_db_float;
5158  attdesc->setter[LDR_DOUBLE] = &ldr_real_db_float;
5159  attdesc->setter[LDR_FLOAT] = &ldr_real_db_float;
5160  break;
5161 
5162  case DB_TYPE_DOUBLE:
5163  attdesc->setter[LDR_INT] = &ldr_real_db_double;
5164  attdesc->setter[LDR_NUMERIC] = &ldr_real_db_double;
5165  attdesc->setter[LDR_DOUBLE] = &ldr_real_db_double;
5166  attdesc->setter[LDR_FLOAT] = &ldr_real_db_double;
5167  break;
5168 
5169  case DB_TYPE_NUMERIC:
5170  attdesc->setter[LDR_INT] = &ldr_int_db_generic;
5172  attdesc->setter[LDR_DOUBLE] = &ldr_real_db_generic;
5173  attdesc->setter[LDR_FLOAT] = &ldr_real_db_generic;
5174  break;
5175 
5176  case DB_TYPE_DATE:
5177  attdesc->setter[LDR_STR] = &ldr_str_db_generic;
5178  attdesc->setter[LDR_DATE] = &ldr_date_db_date;
5179  break;
5180 
5181  case DB_TYPE_TIME:
5182  attdesc->setter[LDR_STR] = &ldr_str_db_generic;
5183  attdesc->setter[LDR_TIME] = &ldr_time_db_time;
5184  break;
5185 
5186  case DB_TYPE_TIMESTAMP:
5187  attdesc->setter[LDR_STR] = &ldr_str_db_generic;
5189  break;
5190 
5191  case DB_TYPE_TIMESTAMPLTZ:
5192  attdesc->setter[LDR_STR] = &ldr_str_db_generic;
5194  break;
5195 
5196  case DB_TYPE_TIMESTAMPTZ:
5197  attdesc->setter[LDR_STR] = &ldr_str_db_generic;
5199  break;
5200 
5201  case DB_TYPE_DATETIME:
5202  attdesc->setter[LDR_STR] = &ldr_str_db_generic;
5204  break;
5205 
5206  case DB_TYPE_DATETIMELTZ:
5207  attdesc->setter[LDR_STR] = &ldr_str_db_generic;
5209  break;
5210 
5211  case DB_TYPE_DATETIMETZ:
5212  attdesc->setter[LDR_STR] = &ldr_str_db_generic;
5214  break;
5215 
5216  case DB_TYPE_SET:
5217  case DB_TYPE_MULTISET:
5218  case DB_TYPE_SEQUENCE:
5220  CHECK_ERR (err, select_set_domain (context, attdesc->att->domain, & (attdesc->collection_domain)));
5221  break;
5222 
5223  case DB_TYPE_OBJECT:
5224  case DB_TYPE_VOBJ:
5226  attdesc->setter[LDR_OID] = &ldr_oid_db_object;
5227  break;
5228 
5229  case DB_TYPE_BIT:
5230  case DB_TYPE_VARBIT:
5231  attdesc->setter[LDR_BSTR] = &ldr_bstr_db_varbit;
5232  attdesc->setter[LDR_XSTR] = &ldr_xstr_db_varbit;
5233  break;
5234 
5235  case DB_TYPE_NCHAR:
5236  case DB_TYPE_VARNCHAR:
5237  attdesc->setter[LDR_NSTR] = &ldr_nstr_db_varnchar;
5238  break;
5239 
5240  case DB_TYPE_BLOB:
5241  case DB_TYPE_CLOB:
5242  attdesc->setter[LDR_ELO_EXT] = &ldr_elo_ext_db_elo;
5243  attdesc->setter[LDR_ELO_INT] = &ldr_elo_int_db_elo;
5244  break;
5245 
5246  case DB_TYPE_MONETARY:
5248  break;
5249  case DB_TYPE_JSON:
5250  attdesc->setter[LDR_STR] = &ldr_json_db_json;
5251  break;
5252 
5253  default:
5254  break;
5255  }
5256 
5257 error_exit:
5258  if (err != NO_ERROR)
5259  {
5260  CHECK_CONTEXT_VALIDITY (context, true);
5261  ldr_abort ();
5262  }
5263  return;
5264 }
5265 
5266 /*
5267  * ldr_refresh_attrs - refresh the attributes and attribute descriptors for
5268  * a class.
5269  * return: error code
5270  * context(in): context
5271  * Note:
5272  * This is called after a periodic commit to refresh the attributes and
5273  * attribute descriptors for a class. These may have been pulled from under
5274  * us if another client updated the class.
5275  * The attrs, LDR_ATTRS array, is traversed and each attribute, and
5276  * attribute descriptor is refreshed for the current class.
5277  */
5278 static int
5280 {
5281  int err = NO_ERROR;
5282  DB_ATTDESC *db_attdesc;
5283  LDR_ATTDESC *attdesc;
5284  int i;
5285  SM_CLASS *class_;
5286  SM_COMPONENT **comp_ptr = NULL;
5287 
5288  context->cls = ldr_find_class (context->class_name);
5289  if (context->cls == NULL)
5290  {
5291  display_error (0);
5292  return er_filter_errid (false);
5293  }
5294 
5295  for (i = 0; i < context->num_attrs; i += 1)
5296  {
5297  attdesc = & (context->attrs[i]);
5298  CHECK_ERR (err,
5299  db_get_attribute_descriptor (context->cls, attdesc->attdesc->name,
5300  context->attr_type == LDR_ATTRIBUTE_CLASS, true, &db_attdesc));
5301  /* Free existing descriptor */
5303  attdesc->attdesc = db_attdesc;
5304  /* Get refreshed attribute */
5305  comp_ptr = (SM_COMPONENT **) & attdesc->att;
5306  CHECK_ERR (err, sm_get_descriptor_component (context->cls, attdesc->attdesc, 1, /* for update */
5307  &class_, comp_ptr));
5308  }
5309 
5310 error_exit:
5311  return err;
5312 }
5313 
5314 /*
5315  * ldr_act_restrict_attributes - called after ldr_start_class to indicate that
5316  * the attributes being added are class/shared attributes rather than normal
5317  * instance attributes.
5318  * return: none
5319  * context(in):
5320  * type(in): type of attributes to expect
5321  */
5322 static void
5324 {
5325 
5326  CHECK_SKIP ();
5327  RETURN_IF_NOT_VALID (context);
5328 
5329  context->attr_type = type;
5330 
5331  if (!context->validation_only)
5332  {
5333  /* Set the appropriate functions to handle class attributes */
5335  }
5336 }
5337 
5338 /*
5339  * update_default_count - Updates the default instances counter.
5340  * return: none
5341  * table(out):
5342  * oid(in): not used
5343  */
5344 static int
5346 {
5347  ldr_Current_context->default_count++;
5348  table->total_inserts++;
5349  return NO_ERROR;
5350 }
5351 
5352 /*
5353  * update_default_instances_stats - Update the statics of the number of
5354  * instances referenced but never actually defined in the loader input file.
5355  * return: NO_ERROR if successful, error code otherwise
5356  * context(in): context
5357  * Note:
5358  * These will be inserted with all default values.
5359  */
5360 static int
5362 {
5363  int err;
5364 
5365  context->default_count = 0;
5366 
5367  /*
5368  * note that if we run out of space, the context->valid flag will get
5369  * turned off, insert_default_instance needs to check this
5370  */
5372 
5373  return err;
5374 }
5375 
5376 /*
5377  * ldr_destroy -
5378  * return:
5379  * context():
5380  * err():
5381  */
5382 static int
5383 ldr_destroy (LDR_CONTEXT *context, int err)
5384 {
5385  int finish_error = NO_ERROR;
5386 
5387  if (err)
5388  {
5389  ldr_clear_and_free_context (context);
5390  }
5391  else
5392  {
5393  finish_error = ldr_finish_context (context);
5394  if (!finish_error && !context->validation_only && ! (context->err_total))
5395  {
5396  finish_error = update_default_instances_stats (context);
5397  }
5398  }
5399 
5400  return finish_error;
5401 }
5402 
5403 /*
5404  * insert_instance - Adds the instance to the loader internal oid table,
5405  * otable, and adds the mop to the list of mops that require permanent oids,
5406  * prior to flushing.
5407  * return: NO_ERROR if successful, error code otherwise
5408  * context(in/out): context
5409  */
5410 static int
5412 {
5413  int err = NO_ERROR;
5414  INST_INFO *inst;
5415 
5416  if (!context->validation_only)
5417  {
5418  if (context->obj)
5419  {
5420  /*
5421  * Note : instances without ids are not inserted in the otable as
5422  * there can not be referenced from the load file.
5423  */
5424  if (context->inst_num >= 0)
5425  {
5426  if (context->args->no_oid_hint)
5427  {
5428  CHECK_ERR (err, ldr_add_mop_tempoid_map (context->obj, context->table, context->inst_num));
5429  }
5430  else
5431  {
5432  inst = otable_find (context->table, context->inst_num);
5433 
5434  if (inst == NULL || ! (inst->flags & INST_FLAG_RESERVED))
5435  {
5436  CHECK_ERR (err, otable_insert (context->table, WS_REAL_OID (context->obj), context->inst_num));
5437  CHECK_PTR (err, inst = otable_find (context->table, context->inst_num));
5438  CHECK_ERR (err, ldr_add_mop_tempoid_map (context->obj, context->table, context->inst_num));
5439  }
5440  else
5441  {
5442  err = otable_update (context->table, context->inst_num);
5443  }
5444 
5445  }
5446  }
5447  if (!err)
5448  {
5449  context->obj = NULL;
5450  context->table->total_inserts++;
5451  err = check_commit (context);
5452  }
5453  }
5454  }
5455 
5456  if (err)
5457  {
5458  ldr_internal_error (context);
5459  }
5460  else
5461  {
5462  context->inst_count++;
5463  context->inst_total += 1;
5464  Total_objects++;
5465 
5466  if (context->args->verbose && context->status_count)
5467  {
5468  context->status_counter++;
5469  if (context->status_counter >= context->status_count)
5470  {
5471  fprintf (stdout,
5473  context->inst_total);
5474  fflush (stdout);
5475  context->status_counter = 0;
5476  }
5477  }
5478  }
5479 
5480 error_exit:
5481  return err;
5482 }
5483 
5484 /*
5485  * construct_instance - called to insert an instance using the current
5486  * constructor method.
5487  * return: object pointer
5488  * context(in/out):
5489  * Note:
5490  * This simulates the token parsing here.
5491  */
5492 static MOP
5494 {
5495  DB_VALUE *meth_args[LDR_MAX_ARGS + 1];
5496  DB_VALUE retval;
5497  int err = NO_ERROR;
5498  MOP obj = NULL;
5499  DB_VALUE vals[LDR_MAX_ARGS];
5500  int i, a;
5501  LDR_ATTDESC *attdesc;
5502  SM_CLASS *class_;
5503  SM_COMPONENT **comp_ptr = NULL;
5504 
5505  for (i = 0, a = context->arg_index; i < context->arg_count && err == NO_ERROR && i < (int) LDR_MAX_ARGS; i++, a++)
5506  {
5507  err =
5508  (* (elem_converter[context->attrs[a].parser_type])) (context, context->attrs[a].parser_str,
5509  context->attrs[a].parser_str_len, &vals[i]);
5510  meth_args[i] = & (vals[i]);
5511  }
5512 
5513  meth_args[i] = NULL;
5514 
5515  err = db_send_argarray (context->cls, context->constructor->header.name, &retval, meth_args);
5516 
5517  if (!err && DB_VALUE_TYPE (&retval) == DB_TYPE_OBJECT)
5518  {
5519  obj = db_get_object (&retval);
5520  context->obj = obj;
5522  if (err == NO_ERROR)
5523  {
5524  ws_pin_instance_and_class (context->obj, &context->obj_pin, &context->class_pin);
5526  }
5527 
5528  /* now we have to initialize the instance with the supplied values */
5529  for (context->next_attr = 0; context->next_attr < context->arg_index && !err; context->next_attr++)
5530  {
5531  attdesc = &context->attrs[context->next_attr];
5532 
5533  comp_ptr = (SM_COMPONENT **) & attdesc->att;
5534  err = sm_get_descriptor_component (context->cls, attdesc->attdesc, 1, &class_, comp_ptr);
5535 
5536  if (!err)
5537  {
5538  err =
5539  (* (attdesc->setter[attdesc->parser_type])) (context, attdesc->parser_str, attdesc->parser_str_len,
5540  attdesc->att);
5541  }
5542  }
5543  }
5544  else
5545  {
5546  CHECK_ERR (err, ER_GENERIC_ERROR);
5547  ldr_internal_error (context);
5548  }
5549 
5550 error_exit:
5551  return context->obj;
5552 }
5553 
5554 /*
5555  * insert_meth_instance - Inserts the pending instance generated for by a
5556  * method call into the database.
5557  * return: NO_ERROR if successful, error code otherwise
5558  * context(in/out): context
5559  */
5560 static int
5562 {
5563  int err = NO_ERROR;
5564  INST_INFO *inst;
5565  MOP real_obj;
5566 
5567  if (!context->validation_only)
5568  {
5569  if (context->constructor != NULL)
5570  {
5571  CHECK_PTR (err, real_obj = construct_instance (context));
5572  if (real_obj == NULL)
5573  {
5574  CHECK_ERR (err, er_errid ());
5575  }
5576  else
5577  {
5578  ws_release_instance (real_obj);
5579  inst = otable_find (context->table, context->inst_num);
5580  if (inst == NULL || ! (inst->flags & INST_FLAG_RESERVED))
5581  {
5582  CHECK_ERR (err, otable_insert (context->table, WS_OID (real_obj), context->inst_num));
5583  CHECK_PTR (err, inst = otable_find (context->table, context->inst_num));
5584  CHECK_ERR (err, ldr_add_mop_tempoid_map (real_obj, context->table, context->inst_num));
5585  }
5586  else
5587  {
5590  }
5591  }
5592  }
5593  else
5594  {
5595  err = ER_GENERIC_ERROR;
5596  }
5597  }
5598 
5599  if (err)
5600  {
5601  ldr_internal_error (context);
5602  }
5603  else
5604  {
5605  context->inst_count++;
5606  context->inst_total += 1;
5607  Total_objects++;
5608 
5609  if (context->args->verbose && context->status_count)
5610  {
5611  context->status_counter++;
5612  if (context->status_counter >= context->status_count)
5613  {
5614  fprintf (stdout,
5616  context->inst_total);
5617  fflush (stdout);
5618  context->status_counter = 0;
5619  }
5620  }
5621  }
5622 error_exit:
5623  return err;
5624 }
5625 
5626 /*
5627  * ldr_act_set_constructor - Specifies a constructor method for the instances
5628  * of the current class.
5629  * return: NO_ERROR if successful, error code otherwise
5630  * context(in/out): context
5631  * name(in): method name
5632  * Note:
5633  * The name must be the name of a class method that when called will return
5634  * an instance. After this function, the loader will expect zero or more
5635  * calls to ldr_act_add_argument to specify any arguments that must be
5636  * passed to the constructor method.
5637  */
5638 static int
5639 ldr_act_set_constructor (LDR_CONTEXT *context, const char *name)
5640 {
5641  int err = NO_ERROR;
5642  SM_METHOD *meth;
5643 
5644  CHECK_SKIP_WITH (err);
5645  if (context->validation_only)
5646  {
5647  context->arg_index = context->num_attrs;
5648 
5649  /* setup the appropriate constructor handling functions */
5650 
5652  goto error_exit;
5653  }
5654 
5655  if (context->valid)
5656  {
5657  meth = db_get_class_method (context->cls, name);
5658  if (meth == NULL)
5659  {
5662  }
5663  else
5664  {
5665  /* for now, a method can have exactly one signature */
5666 
5667  context->constructor = meth;
5668  context->arg_index = context->num_attrs;
5669 
5670  /* setup the appropriate constructor handling functions */
5671 
5673  }
5674  }
5675 
5676 error_exit:
5677  if (err != NO_ERROR)
5678  {
5679  CHECK_CONTEXT_VALIDITY (context, true);
5680  ldr_abort ();
5681  }
5682  return err;
5683 }
5684 
5685 /*
5686  * add_element - add an element to either the loader's argument array
5687  * return: success code (non-zero if ok)
5688  * elements(in): pointer to an array of pointers
5689  * count(in/out): current index (and returned new index)
5690  * max(in/out): maximum size (and returned maximum size)
5691  * grow(in): amount to grow if necessary
5692  * Note:
5693  * We first check to see if *count is less than *max, if so we simply
5694  * increment count. If not, we extend the array, return the incremented
5695  * count and also returned the new max size.
5696  */
5697 static int
5698 add_element (void ***elements, int *count, int *max, int grow)
5699 {
5700  int new_ = -1, resize, i;
5701  int err = NO_ERROR;
5702  void ***elements_old;
5703 
5704  if (*count >= *max)
5705  {
5706 
5707  resize = *max + grow;
5708 
5709  elements_old = elements;
5710 
5711  *elements = (void **) realloc (*elements, sizeof (void *) * resize);
5712  if (*elements == NULL)
5713  {
5714  free_and_init (*elements_old); /* Prevent leak if realloc fails */
5716  }
5717  CHECK_PTR (err, *elements);
5718 
5719  for (i = *count; i < resize; i++)
5720  {
5721  (*elements)[i] = NULL;
5722  }
5723  *max = resize;
5724  }
5725  new_ = *count;
5726  *count = new_ + 1;
5727 
5728 error_exit:
5729  if (err != NO_ERROR || *elements == NULL)
5730  {
5731  return (-1);
5732  }
5733  return new_;
5734 }
5735 
5736 /*
5737  * add_argument - Extends the loader's argument array.
5738  * return: next argument index
5739  * context(out): context
5740  */
5741 static int
5743 {
5744  int index;
5745 
5746  index =
5747  add_element ((void ***) (& (context->method_args)), & (context->arg_count), & (context->max_arg), LDR_ARG_GROW_SIZE);
5748  return index;
5749 }
5750 
5751 /*
5752  * ldr_act_add_argument - specify parameters to an instance constructor method
5753  * previously specified with ldr_act_set_constructor.
5754  * return: NO_ERROR if successful, error code otherwise
5755  * context(in/out): context
5756  * name(in): argument name
5757  * Note:
5758  * The name isn't really important here since method argumetns don't
5759  * have domains. It is however important to specify as many arguments
5760  * as the method expects because the domain validation will be
5761  * done positionally according to the method signature in the schema.
5762  */
5763 static int
5764 ldr_act_add_argument (LDR_CONTEXT *context, const char *name)
5765 {
5766  int err = NO_ERROR;
5767  SM_METHOD_SIGNATURE *sig;
5768  SM_METHOD_ARGUMENT *arg;
5769  int index;
5770 
5771  CHECK_SKIP_WITH (err);
5772  if (context->validation_only)
5773  {
5774  context->arg_count += 1;
5775  goto error_exit;
5776  }
5777 
5778  if (context->valid)
5779  {
5780  if (context->constructor == NULL)
5781  {
5784  }
5785  else
5786  {
5787  sig = context->constructor->signatures;
5788  /* arg count of zero currently means "variable", not good */
5789  if (sig->num_args && (context->arg_count) >= sig->num_args)
5790  {
5793  }
5794  else
5795  {
5796  /* Locate the argument descriptor, remember to adjust for 1 based argument numbering. */
5797  arg = classobj_find_method_arg (&sig->args, context->arg_count, 0);
5798  /* This is called to setup the LDR_ATTDESC structure */
5799  ldr_act_add_attr (context, name, strlen (name));
5800  index = add_argument (context);
5801  if (index >= 0)
5802  {
5803  context->method_args[index] = arg;
5804  }
5805  else
5806  {
5807  err = ER_LDR_MEMORY_ERROR;
5809  ldr_internal_error (context);
5810  CHECK_ERR (err, err);
5811  }
5812  }
5813  }
5814  }
5815 error_exit:
5816  if (err != NO_ERROR)
5817  {
5818  CHECK_CONTEXT_VALIDITY (context, true);
5819  ldr_abort ();
5820  }
5821  return err;
5822 }
5823 
5824 /*
5825  * invalid_class_id_error - called when invalid class id is met.
5826  * return:
5827  * context(in):
5828  * id(in): class id
5829  */
5830 static void
5832 {
5833  display_error_line (0);
5835  ldr_attr_name (context), ldr_class_name (context));
5836  CHECK_CONTEXT_VALIDITY (context, true);
5837 }
5838 
5839 /*
5840  * ldr_act_set_ref_class - Find the class that is about to be used in an
5841  * instance reference.
5842  * return: void
5843  * context(in/out): context
5844  * name(in): class name
5845  */
5846 static void
5847 ldr_act_set_ref_class (LDR_CONTEXT *context, char *name)
5848 {
5849  DB_OBJECT *mop;
5850 
5851  CHECK_SKIP ();
5852  RETURN_IF_NOT_VALID (context);
5853 
5854  if (!context->validation_only)
5855  {
5856  mop = db_find_class (name);
5857  if (mop != NULL)
5858  {
5859  context->attrs[context->next_attr].ref_class = mop;
5860  }
5861  else
5862  {
5863  ldr_invalid_class_error (context);
5864  }
5865  }
5866 }
5867 
5868 /*
5869  * ldr_act_set_instance_id - Set the instance to be used from the reference
5870  * class
5871  * return: void
5872  * context(in/out): context
5873  * id(in): instance id for ref_class already set
5874  */
5875 static void
5877 {
5878  CHECK_SKIP ();
5879  RETURN_IF_NOT_VALID (context);
5880 
5881  if (!context->validation_only)
5882  {
5883  if (context->attrs[context->next_attr].ref_class != NULL)
5884  {
5885  context->attrs[context->next_attr].instance_id = id;
5886  }
5887  else
5888  {
5889  CHECK_CONTEXT_VALIDITY (context, true);
5890  }
5891  }
5892 }
5893 
5894 /*
5895  * ldr_act_set_ref_class_id - Find the class that is about to be used in an
5896  * instance reference
5897  * return: void
5898  * context(in/out): context
5899  * id(in): class id
5900  * Note:
5901  * Unlike act_set_ref_class, the class is identified through a previously
5902  * assigned id number.
5903  */
5904 static void
5906 {
5907  DB_OBJECT *class_;
5908 
5909  CHECK_SKIP ();
5910  RETURN_IF_NOT_VALID (context);
5911 
5912  if (!context->validation_only)
5913  {
5914  class_ = ldr_get_class_from_id (id);
5915  if (class_ != NULL)
5916  {
5917  context->attrs[context->next_attr].ref_class = class_;
5918  }
5919  else
5920  {
5921  invalid_class_id_error (context, id);
5922  }
5923  }
5924 }
5925 
5926 static DB_OBJECT *
5928 {
5929  RETURN_IF_NOT_VALID_WITH (context, NULL);
5930 
5931  if (!context->validation_only)
5932  {
5933  return context->attrs[context->next_attr].ref_class;
5934  }
5935 
5936  return NULL;
5937 }
5938 
5939 /*
5940  * ldr_init_loader - Initializes the global loader state.
5941  * return: NO_ERROR if successful, error code otherwise
5942  * context(in/out): context
5943  * Note:
5944  * This should be called once prior to loader operation.
5945  */
5946 static int
5948 {
5949  int i;
5950  int err = NO_ERROR;
5951  DB_DATETIME datetime;
5952  DB_DATETIMETZ datetimetz;
5953  DB_TIMESTAMPTZ timestamptz;
5954  DB_ELO *null_elo = NULL;
5955 
5956  /*
5957  * Definitely *don't* want to use oid preflushing in this app; it just
5958  * gives us some extra overhead that we don't care about.
5959  */
5960  tm_Use_OID_preflush = false;
5961 
5962  /* Set the appropriate action function for normal attribute values */
5963 
5965 
5966  /*
5967  * Optimization to avoid calling db_value_domain_init all of the time
5968  * during loading; we can simply copy these templates much more cheaply.
5969  */
5970  db_make_short (&ldr_short_tmpl, 0);
5971  db_make_int (&ldr_int_tmpl, 0);
5972  db_make_bigint (&ldr_bigint_tmpl, 0);
5973  db_make_char (&ldr_char_tmpl, 1, "a", 1, LANG_SYS_CODESET, LANG_SYS_COLLATION);
5974  db_make_varchar (&ldr_varchar_tmpl, 1, "a", 1, LANG_SYS_CODESET, LANG_SYS_COLLATION);
5975  db_make_float (&ldr_float_tmpl, (float) 0.0);
5976  db_make_double (&ldr_double_tmpl, (double) 0.0);
5977  db_make_date (&ldr_date_tmpl, 1, 1, 1996);
5978  db_make_time (&ldr_time_tmpl, 0, 0, 0);
5979  db_make_timestamp (&ldr_timestamp_tmpl, 0);
5980  timestamptz.timestamp = 0;
5981  timestamptz.tz_id = 0;
5982  db_make_timestampltz (&ldr_timestampltz_tmpl, 0);
5983  db_make_timestamptz (&ldr_timestamptz_tmpl, &timestamptz);
5984  db_datetime_encode (&datetime, 1, 1, 1996, 0, 0, 0, 0);
5985  db_make_datetime (&ldr_datetime_tmpl, &datetime);
5986  datetimetz.datetime = datetime;
5987  datetimetz.tz_id = 0;
5988  db_make_datetimeltz (&ldr_datetimeltz_tmpl, & (datetimetz.datetime));
5989  db_make_datetimetz (&ldr_datetimetz_tmpl, &datetimetz);
5990  db_make_elo (&ldr_blob_tmpl, DB_TYPE_BLOB, null_elo);
5991  db_make_elo (&ldr_clob_tmpl, DB_TYPE_CLOB, null_elo);
5992  db_make_bit (&ldr_bit_tmpl, 1, "0", 1);
5993  db_make_json (&ldr_json_tmpl, NULL, false);
5994 
5995  /*
5996  * Set up the conversion functions for collection elements. These
5997  * don't need to be done on a per-attribute basis (well, I suppose they
5998  * could if we were really worried about it, but for now we let the
5999  * usual domain coercion stuff take care of the dirty work).
6000  */
6001  for (i = 0; i < NUM_LDR_TYPES; i++)
6002  {
6004  }
6029 
6030  /* Set up the lockhint array. Used by ldr_find_class() when locating a class. */
6033  ldr_Hint_subclasses[0] = 0;
6035 
6036  Total_objects = 0;
6037  Total_fails = 0;
6038  ldr_clear_context (context);
6039  ldr_act_init_context (context, NULL, 0);
6040  ldr_Current_context = context;
6041  ldr_clear_err_total (context);
6042  context->validation_only = 0;
6043  context->valid = true;
6044  context->flush_total = 0;
6045 
6046  return (err);
6047 }
6048 
6049 /*
6050  * ldr_init - This prepares the loader for use.
6051  * return: none
6052  * verbose(in): non-zero to enable printing of status messages
6053  * Note:
6054  * If the verbose flag is on, status messages will be displayed
6055  * as the load proceeds.
6056  * The loader is initially configured for validation mode.
6057  * Call ldr_start() to clear the current state and enter
6058  * insertion mode.
6059  */
6060 static int
6062 {
6063  LDR_CONTEXT *context;
6064 
6065  ldr_Current_context = &ldr_Context;
6066  context = ldr_Current_context;
6067 
6068  context->args = args;
6069 
6070  if (ldr_init_loader (ldr_Current_context))
6071  {
6072  assert (er_errid () != NO_ERROR);
6073  return er_errid ();
6074  }
6075 
6076  idmap_init ();
6077 
6078  if (otable_init ())
6079  {
6080  assert (er_errid () != NO_ERROR);
6081  return er_errid ();
6082  }
6083 
6084  if (clist_init ())
6085  {
6086  assert (er_errid () != NO_ERROR);
6087  return er_errid ();
6088  }
6089 
6090  context->validation_only = true;
6091 
6092  context->status_count = 0;
6093  /* used to monitor the number of insertions performed */
6094  context->status_counter = 0;
6095 
6096  context->status_count = 10;
6097 
6099 
6100  return NO_ERROR;
6101 }
6102 
6103 /*
6104  * ldr_start - This prepares the loader for actual insertion of data.
6105  * return: none
6106  * periodic_commit(in): periodic_commit interval value
6107  * Note:
6108  * It is commonly called after the input file has been processed
6109  * once for syntax checking. It can also be called immediately
6110  * after ldr_init() to skip the syntax check and go right into
6111  * insertion mode.
6112  */
6113 static int
6115 {
6116  int err;
6117  LDR_CONTEXT *context;
6118 
6119  if (!ldr_Current_context)
6120  {
6121  ldr_Current_context = &ldr_Context;
6122  }
6123 
6124  context = ldr_Current_context;
6125 
6126  ldr_clear_context (context);
6127 
6128  /*
6129  * Initialize the mop -> temporary_oid, table used to obtain a mapping
6130  * between permanent OID and workspace mop, when permanent OIDs are obtained.
6131  */
6132  err = ldr_mop_tempoid_maps_init ();
6133  if (err != NO_ERROR)
6134  {
6135  return err;
6136  }
6137 
6138  context->validation_only = 0;
6139 
6140  if (context->args->periodic_commit <= 0)
6141  {
6142  context->args->periodic_commit = 0;
6143  }
6144  else
6145  {
6146  context->commit_counter = context->args->periodic_commit;
6147  }
6148 
6149  /* make sure we reset this to get accurate statistics */
6150  Total_objects = 0;
6151  Total_fails = 0;
6152  return NO_ERROR;
6153 }
6154 
6155 /*
6156  * ldr_final - shut down the loader.
6157  * return: void
6158  * Note:
6159  * Since there may be a pending instance that has not yet been inserted,
6160  * you must always call ldr_destroy to make sure this occurs.
6161  * If the caller detects an error and wishes to abort the load immediate,
6162  * pass in non-zero and the pending instance will not be inserted.
6163  * After this call, the loader cannot be used and the session
6164  * must begin again with a ldr_init() call.
6165  */
6166 static int
6168 {
6169  int shutdown_error = NO_ERROR;
6170  LDR_CONTEXT *context;
6171 
6172  context = ldr_Current_context;
6173 
6174  shutdown_error = ldr_destroy (context, 1);
6175 
6176  clist_final ();
6177  idmap_final ();
6178  otable_final ();
6180 
6181  return shutdown_error;
6182 }
6183 
6184 static void
6186 {
6187  if (ldr_Driver != NULL)
6188  {
6189  return;
6190  }
6191 
6192  ldr_Driver = new driver ();
6193 
6195 
6196  error_handler *error_handler_ = new error_handler ();
6197  class_installer *cls_installer = new sa_class_installer ();
6198  object_loader *obj_loader = new sa_object_loader ();
6199 
6200  ldr_Driver->initialize (cls_installer, obj_loader, error_handler_);
6201 }
6202 
6203 void
6204 ldr_sa_load (load_args *args, int *status, bool *interrupted)
6205 {
6206  int errors = 0;
6207  int64_t objects = 0;
6208  int defaults = 0;
6209  int fails = 0;
6210  int64_t lastcommit = 0;
6211  int ldr_init_ret = NO_ERROR;
6212 
6213  std::ifstream object_file (args->object_file);
6214 
6215  ldr_init_driver ();
6216 
6218  ldr_init (args);
6219 
6220  /* set the flag to indicate what type of interrupts to raise If logging has been disabled set commit flag. If
6221  * logging is enabled set abort flag. */
6222 
6223  if (args->ignore_logging)
6224  {
6226  }
6227  else
6228  {
6230  }
6231 
6232  if (args->periodic_commit)
6233  {
6234  /* register the post commit function */
6236  }
6237 
6238  /* Check if we need to perform syntax checking. */
6239  if (!args->load_only)
6240  {
6241  print_log_msg ((int) args->verbose,
6243  if (!args->table_name.empty ())
6244  {
6245  ldr_init_ret = ldr_Driver->get_class_installer ().install_class (args->table_name.c_str ());
6246  }
6247  ldr_Driver->parse (object_file);
6248  ldr_stats (&errors, &objects, &defaults, &lastcommit, &fails);
6249  }
6250  else
6251  {
6252  errors = 0;
6253  }
6254 
6255  if (errors)
6256  {
6258  }
6259  else if (ldr_init_ret == NO_ERROR && !args->syntax_check)
6260  {
6261  /* now do it for real if there were no errors and we aren't doing a simple syntax check */
6262  ldr_start ();
6263  object_file.close ();
6264 
6265  object_file.open (args->object_file, std::fstream::in | std::fstream::binary);
6266 
6267  if (object_file.is_open ())
6268  {
6269  print_log_msg ((int) args->verbose,
6271 
6272  /* make sure signals are caught */
6274 
6275  /* register function to call and jmp environment to longjmp to after aborting or committing. */
6277 
6278  if (setjmp (ldr_Jmp_buf) != 0)
6279  {
6280  /* We have had an interrupt, the transaction should have been already been aborted or committed by
6281  * the loader. If Total_objects_loaded is -1 an error occurred during rollback or commit. */
6282  if (Total_objects_loaded != -1)
6283  {
6284  print_log_msg (1,
6287  }
6288  ldr_stats (&errors, &objects, &defaults, &lastcommit, &fails);
6289  if (lastcommit > 0)
6290  {
6291  print_log_msg (1,
6293  LOADDB_MSG_LAST_COMMITTED_LINE), lastcommit);
6294  }
6295  *interrupted = true;
6296  *status = 3;
6297  }
6298  else
6299  {
6300  if (!args->table_name.empty ())
6301  {
6302  ldr_Driver->get_class_installer ().install_class (args->table_name.c_str ());
6303  }
6304 
6305  ldr_Driver->parse (object_file);
6306  ldr_stats (&errors, &objects, &defaults, &lastcommit, &fails);
6307 
6308  if (errors)
6309  {
6310  if (lastcommit > 0)
6311  {
6312  print_log_msg (1,
6314  LOADDB_MSG_LAST_COMMITTED_LINE), lastcommit);
6315  }
6316 
6317  util_log_write_errstr ("%s\n", db_error_string (3));
6318  /*
6319  * don't allow the transaction to be committed at
6320  * this point, note that if we ever move to a scheme
6321  * where we write directly to the heap without the
6322  * transaction context, we will have to unwind the
6323  * changes made if errors are detected !
6324  */
6326  }
6327  else
6328  {
6329  if (objects || fails)
6330  {
6331  print_log_msg (1,
6333  LOADDB_MSG_INSERT_AND_FAIL_COUNT), objects, fails);
6334  }
6335 
6336  if (defaults)
6337  {
6338  print_log_msg (1,
6340  LOADDB_MSG_DEFAULT_COUNT), defaults);
6341  }
6342  print_log_msg ((int) args->verbose,
6344 
6345  /* commit the transaction and then update statistics */
6346  if (!db_commit_transaction ())
6347  {
6348  if (!args->disable_statistics)
6349  {
6350  if (args->verbose)
6351  {
6352  print_log_msg (1,
6355  }
6356  if (!ldr_update_statistics ())
6357  {
6358  /*
6359  * would it be faster to update statistics
6360  * before the first commit and just have a
6361  * single commit ?
6362  */
6363  print_log_msg ((int) args->verbose,
6366  (void) db_commit_transaction ();
6367  }
6368  }
6369  }
6370  }
6371  }
6372  }
6373  }
6374 
6375  ldr_final ();
6376 
6377  if (ldr_Driver != NULL)
6378  {
6379  delete ldr_Driver;
6380  ldr_Driver = NULL;
6382  }
6383  if (object_file.is_open ())
6384  {
6385  object_file.close ();
6386  }
6387 }
6388 
6389 /*
6390  * ldr_register_post_interrupt_handler - registers a post interrupt callback
6391  * function.
6392  * return: void return, sets ldr_post_interrupt_handler
6393  */
6394 void static
6396 {
6399 }
6400 
6401 /*
6402  * ldr_register_post_commit_handler - registers a post commit callback
6403  * function.
6404  * return: void return, sets ldr_post_commit_handler
6405  */
6406 static void
6408 {
6410 }
6411 
6412 /*
6413  * ldr_stats - This is used to access the statistics maintained during loading.
6414  * return: void
6415  * errors(out): return error count
6416  * objects(out): return object count
6417  * defaults(out): return default object count
6418  * lastcommit(out):
6419  * fails(out): return fail count
6420  */
6421 static void
6422 ldr_stats (int *errors, int64_t *objects, int *defaults, int64_t *lastcommit, int *fails)
6423 {
6424  if (errors != NULL)
6425  {
6426  *errors = ldr_Current_context->err_total;
6427  }
6428 
6429  if (objects != NULL)
6430  {
6431  *objects = Total_objects;
6432  }
6433 
6434  if (defaults != NULL)
6435  {
6436  *defaults = ldr_Current_context->default_count;
6437  }
6438 
6439  if (lastcommit != NULL)
6440  {
6441  *lastcommit = Last_committed_line;
6442  }
6443  if (fails != NULL)
6444  {
6445  *fails = Total_fails;
6446  }
6447 }
6448 
6449 /*
6450  * ldr_update_statistics - update statistics
6451  * return: NO_ERROR if successful, error code otherwise
6452  * Note:
6453  * This can be called after loading has finished but BEFORE ldr_final
6454  * to update the statistics for the classes that were involved
6455  * in the load.
6456  */
6457 static int
6459 {
6460  int err = NO_ERROR;
6461  const char *class_name = NULL;
6462 
6463  for (CLASS_TABLE *table = Classes; table != NULL && !err; table = table->next)
6464  {
6465  if (ldr_Current_context->args->verbose)
6466  {
6467  class_name = sm_get_ch_name (table->class_);
6468  if (class_name == NULL)
6469  {
6470  err = er_errid ();
6471  assert (err != NO_ERROR);
6472  break;
6473  }
6474 
6476  class_name);
6477  fflush (stdout);
6478  }
6479  err = sm_update_statistics (table->class_, STATS_WITH_SAMPLING);
6480  }
6481  return err;
6482 }
6483 
6484 /*
6485  * ldr_abort - immediately error exit function
6486  * return: void
6487  */
6488 static void
6490 {
6492 
6494  {
6495  (*ldr_post_interrupt_handler) (-1);
6496  }
6497 
6498  if (ldr_Jmp_buf_ptr != NULL)
6499  {
6500  longjmp (*ldr_Jmp_buf_ptr, 1);
6501  }
6502 }
6503 
6504 static void
6505 ldr_act_set_skip_current_class (char *class_name, size_t size)
6506 {
6507  skip_current_class = ldr_is_ignore_class (class_name, size);
6508 
6509  if (skip_current_class && !ldr_Current_context->validation_only)
6510  {
6511  print_log_msg (1, "Class %s is ignored.\n", class_name);
6512  }
6513 }
6514 
6515 static bool
6516 ldr_is_ignore_class (const char *class_name, size_t size)
6517 {
6518  if (class_name == NULL)
6519  {
6520  return false;
6521  }
6522 
6523  if (IS_OLD_GLO_CLASS (class_name))
6524  {
6525  return true;
6526  }
6527 
6528  for (std::string &ignore_class : ldr_Current_context->args->ignore_classes)
6529  {
6530  if (intl_identifier_ncasecmp (ignore_class.c_str (), class_name, (int) MAX (ignore_class.size (), size)) == 0)
6531  {
6532  return true;
6533  }
6534  }
6535 
6536  return false;
6537 }
6538 
6539 static void
6541 {
6542  bool ignore_class = false;
6543  const char *class_name;
6544  DB_OBJECT *ref_class = NULL;
6545 
6546  if (ref->class_id && ref->class_id->val)
6547  {
6548  ldr_act_set_ref_class_id (ldr_Current_context, atoi (ref->class_id->val));
6549  }
6550  else
6551  {
6552  ldr_act_set_ref_class (ldr_Current_context, ref->class_name->val);
6553  }
6554 
6555  if (ref->instance_number && ref->instance_number->val)
6556  {
6557  ldr_act_set_instance_id (ldr_Current_context, atoi (ref->instance_number->val));
6558  }
6559  else
6560  {
6561  /* ldr_act_set_instance_id(ldr_Current_context, 0); *//* right?? */
6562  }
6563 
6564  ref_class = ldr_act_get_ref_class (ldr_Current_context);
6565  if (ref_class != NULL)
6566  {
6567  class_name = db_get_class_name (ref_class);
6568  ignore_class = ldr_is_ignore_class (class_name, ((class_name) ? strlen (class_name) : 0));
6569  }
6570 
6571  if (type == LDR_OID)
6572  {
6573  (*ldr_act) (ldr_Current_context, ref->instance_number->val,
6574  ((ref->instance_number->val == NULL) ? 0 : ref->instance_number->size),
6575  (ignore_class) ? LDR_NULL : LDR_OID);
6576  }
6577  else
6578  {
6579  /* right ?? */
6580  if (ref->class_name)
6581  {
6582  (*ldr_act) (ldr_Current_context, ref->class_name->val, ref->class_name->size,
6583  (ignore_class) ? LDR_NULL : LDR_CLASS_OID);
6584  }
6585  else
6586  {
6587  (*ldr_act) (ldr_Current_context, ref->class_id->val, ((ref->class_id->val == NULL) ? 0 : ref->class_id->size),
6588  (ignore_class) ? LDR_NULL : LDR_CLASS_OID);
6589  }
6590  }
6591 
6592  delete ref;
6593 }
6594 
6595 static int
6596 ldr_act_add_class_all_attrs (const char *class_name)
6597 {
6598  int err = NO_ERROR;
6599  SM_CLASS *class_;
6600  DB_OBJECT *class_mop;
6601 
6602  RETURN_IF_NOT_VALID_WITH (ldr_Current_context, ER_FAILED);
6603 
6604  if (ldr_Current_context->validation_only)
6605  {
6606  assert (ldr_Current_context->cls == NULL);
6607 
6608  class_mop = ldr_find_class (class_name);
6609  if (class_mop == NULL)
6610  {
6611  display_error_line (0);
6613  class_name);
6614  err = er_filter_errid (false);
6615  goto error_exit;
6616  }
6617  }
6618  else
6619  {
6620  class_mop = ldr_Current_context->cls;
6621  }
6622 
6623  CHECK_ERR (err, au_fetch_class (class_mop, &class_, AU_FETCH_READ, AU_SELECT));
6624 
6625  for (SM_ATTRIBUTE *att = class_->ordered_attributes; att != NULL; att = att->order_link)
6626  {
6627  ldr_act_add_attr (ldr_Current_context, att->header.name, strlen (att->header.name));
6628  }
6629 
6630  return NO_ERROR;
6631 
6632 error_exit:
6633  if (err != NO_ERROR)
6634  {
6635  CHECK_CONTEXT_VALIDITY (ldr_Current_context, true);
6636  ldr_abort ();
6637  }
6638 
6639  return ER_FAILED;
6640 }
6641 
6642 static int
6643 ldr_json_elem (LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
6644 {
6645  JSON_DOC *document = NULL;
6646  int error_code = NO_ERROR;
6647 
6648  error_code = db_json_get_json_from_str (str, document, len);
6649  if (error_code != NO_ERROR)
6650  {
6651  assert (document == NULL);
6652  return error_code;
6653  }
6654 
6655  db_make_json (val, document, true);
6656  return NO_ERROR;
6657 }
6658 
6659 static int
6660 ldr_json_db_json (LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
6661 {
6662  int err = NO_ERROR;
6663  DB_VALUE val;
6664 
6665  db_make_null (&val);
6666  CHECK_ERR (err, ldr_json_elem (context, str, len, &val));
6667  CHECK_ERR (err, ldr_generic (context, &val));
6668 
6669 error_exit:
6670  db_value_clear (&val);
6671  return err;
6672 }
6673 
6674 /*
6675  * ldr_signal_handler - signal handler registered via util_arm_signal_handlers
6676  * return: void
6677  */
6678 static void
6680 {
6683 }
6684 
6685 /*
6686  * ldr_report_num_of_commits - report number of commits
6687  * return: void
6688  * num_committed(in): number of commits
6689  *
6690  * Note:
6691  * registered as a callback function the loader will call this function
6692  * to report the number of insertion that have taken place if the '-vc',
6693  * verbose commit parameter was specified.
6694  */
6695 static void
6696 ldr_report_num_of_commits (int64_t num_committed)
6697 {
6698  print_log_msg (ldr_Current_context->args->verbose_commit,
6700  (ldr_Current_context->class_name ? ldr_Current_context->class_name : ""), num_committed);
6701 }
6702 
6703 /*
6704  * ldr_get_num_of_inserted_objects - set of object inserted value to
6705  * Total_objects_loaded global variable
6706  * return: void
6707  * num_objects(in): number of inserted object to set
6708  */
6709 static void
6710 ldr_get_num_of_inserted_objects (int64_t num_objects)
6711 {
6712  Total_objects_loaded = num_objects;
6713 }
static int ldr_reset_context(LDR_CONTEXT *context)
static int is_internal_class(DB_OBJECT *class_)
static int Total_fails
static int ldr_json_db_json(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
int intl_identifier_ncasecmp(const char *str1, const char *str2, const int len)
DB_OBJECT * db_find_class(const char *name)
Definition: db_info.c:133
CLASS_TABLE * table
static int idmap_grow(int size)
#define INST_FLAG_RESERVED
struct db_domain_info::char_info char_info
DB_TIME time
Definition: dbtype_def.h:1056
SM_ATTRIBUTE * shared
Definition: class_object.h:722
static int ldr_null_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
static DB_OBJLIST * internal_classes
#define RETURN_IF_NOT_VALID_WITH(context, ret)
static void ldr_stats(int *errors, int64_t *objects, int *defaults, int64_t *lastcommit, int *fails)
#define NUM_LDR_TYPES
Definition: load_common.hpp:33
int db_make_json(DB_VALUE *value, JSON_DOC *json_document, bool need_clear)
int db_make_datetime(DB_VALUE *value, const DB_DATETIME *datetime)
static int ldr_act_add_argument(LDR_CONTEXT *context, const char *name)
static int ldr_timestampltz_db_timestampltz(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
#define NO_ERROR
Definition: error_code.h:46
short sh
Definition: dbtype_def.h:1050
static LOCK ldr_Hint_locks[LDR_LOCKHINT_COUNT]
static void ldr_init_driver()
static int find_instance(LDR_CONTEXT *context, DB_OBJECT *class_, OID *oid, int id)
char buf[DB_SMALL_CHAR_BUF_SIZE]
Definition: dbtype_def.h:991
#define LANG_SYS_COLLATION
static DB_VALUE ldr_timestampltz_tmpl
void ws_class_has_object_dependencies(MOP class_mop)
Definition: work_space.c:3166
#define ER_LDR_MEMORY_ERROR
Definition: error_code.h:656
static void ldr_act_attr(LDR_CONTEXT *context, const char *str, size_t len, data_type type)
int otable_init(void)
int db_string_to_timestamp(const char *str, DB_TIMESTAMP *utime)
Definition: db_date.c:3802
int parse(std::istream &iss, int line_offset=0)
Definition: load_driver.cpp:83
static void clist_final(void)
size_t parser_str_len
static int ldr_int_db_bigint(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
static DB_VALUE ldr_datetimeltz_tmpl
const char * db_get_class_name(DB_OBJECT *class_)
Definition: db_info.c:608
static DB_VALUE ldr_int_tmpl
static int ldr_sys_class_db_generic(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
MOP ws_mop(const OID *oid, MOP class_mop)
Definition: work_space.c:614
const char * db_get_type_name(DB_TYPE type_id)
Definition: db_info.c:722
SM_COMPONENT header
Definition: class_object.h:591
TP_DOMAIN * collection_domain
static int ldr_monetary_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
unsigned char codeset
Definition: object_domain.h:91
static void ldr_restore_pin_and_drop_obj(LDR_CONTEXT *context, bool drop_obj)
char * MOBJ
Definition: work_space.h:174
static DB_OBJECT * ldr_act_get_ref_class(LDR_CONTEXT *context)
static DB_VALUE ldr_datetimetz_tmpl
void ldr_increment_fails()
#define TP_IS_SET_TYPE(typenum)
std::string object_file
static int ldr_destroy(LDR_CONTEXT *context, int err)
LDR_SETTER setter[NUM_LDR_TYPES]
int db_make_bigint(DB_VALUE *value, const DB_BIGINT num)
static int insert_meth_instance(LDR_CONTEXT *context)
int db_string_to_datetimetz(const char *str, DB_DATETIMETZ *dt_tz, bool *has_zone)
Definition: db_date.c:4520
DB_TIMESTAMP timestamp
Definition: dbtype_def.h:766
static void ldr_act_restrict_attributes(LDR_CONTEXT *context, attribute_type type)
DB_OBJECT * ref_class
DB_TYPE
Definition: dbtype_def.h:670
int parse_int(int *ret_p, const char *str_p, int base)
Definition: porting.c:2290
static int ldr_str_db_generic(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
static LDR_POST_COMMIT_HANDLER ldr_post_commit_handler
static void ldr_act_init_context(LDR_CONTEXT *context, const char *class_name, size_t len)
#define ER_FAILED
Definition: error_code.h:47
int db_make_varchar(DB_VALUE *value, const int max_char_length, DB_CONST_C_CHAR str, const int char_str_byte_size, const int codeset, const int collation_id)
#define WS_REAL_OID(mop)
Definition: work_space.h:294
static int ldr_mismatch(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
#define CHECK_PARSE_ERR(err, expr, cont, type, str)
static int ldr_start()
static LDR_CONTEXT * ldr_Current_context
struct tp_domain * setdomain
Definition: object_domain.h:82
#define ER_SET_DOMAIN_CONFLICT
Definition: error_code.h:381
TP_DOMAIN * domain
Definition: class_object.h:444
DB_ELO_TYPE type
Definition: dbtype_def.h:950
static void ldr_signal_handler(void)
#define MAX_DIGITS_FOR_SHORT
static void ldr_get_num_of_inserted_objects(int64_t num_objects)
static int ldr_act_set_constructor(LDR_CONTEXT *context, const char *name)
static void ldr_abort(void)
virtual int install_class(const char *class_name)=0
static int ldr_str_db_varchar(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
static MOP construct_instance(LDR_CONTEXT *context)
DB_DATETIME datetime
Definition: dbtype_def.h:1060
static jmp_buf * ldr_Jmp_buf_ptr
static DB_VALUE ldr_timestamptz_tmpl
#define ER_LDR_AMBIGUOUS_DOMAIN
Definition: error_code.h:661
static void ldr_internal_error(LDR_CONTEXT *context)
#define CHECK_ERR(err, expr)
#define ER_LDR_CLASS_OBJECT_REFERENCE
Definition: error_code.h:680
SM_ATTRIBUTE * attributes
Definition: class_object.h:721
TP_DOMAIN * tp_domain_select_type(const TP_DOMAIN *domain_list, DB_TYPE type, DB_OBJECT *class_mop, int allow_coercion)
static int64_t Total_objects
attribute_type attr_type
void otable_final(void)
int db_string_to_datetime(const char *str, DB_DATETIME *datetime)
Definition: db_date.c:4441
static int add_argument(LDR_CONTEXT *context)
int db_make_object(DB_VALUE *value, DB_C_OBJECT *obj)
static LDR_CONTEXT ldr_Context
#define SM_MAX_IDENTIFIER_LENGTH
#define CHECK_CONTEXT_VALIDITY(context, expr)
static void idmap_final(void)
void locator_clear_oid_set(THREAD_ENTRY *thread_p, LC_OIDSET *oidset)
Definition: locator.c:2153
static void display_error(int adjust)
unsigned int instance_started
const char * AU_PASSWORD_CLASS_NAME
Definition: authenticate.c:108
void util_arm_signal_handlers(SIG_HANDLER sigint_handler, SIG_HANDLER sigquit_handler)
Definition: util_func.c:222
int obj_desc_set(MOP op, SM_DESCRIPTOR *desc, DB_VALUE *value)
#define ER_LDR_INVALID_CONSTRUCTOR
Definition: error_code.h:666
static void ldr_clear_err_total(LDR_CONTEXT *context)
static DB_VALUE ldr_json_tmpl
static void ldr_act_elem(LDR_CONTEXT *context, const char *str, size_t len, data_type type)
struct sm_component * next
Definition: class_object.h:384
int db_make_date(DB_VALUE *value, const int month, const int day, const int year)
#define OID_SET_NULL(oidp)
Definition: oid.h:85
LDR_ATTDESC * attrs
int db_make_datetimeltz(DB_VALUE *value, const DB_DATETIME *datetime)
void sm_downcase_name(const char *name, char *buf, int maxlen)
const char * AU_USER_CLASS_NAME
Definition: authenticate.c:107
TP_DOMAIN * tp_domain_resolve_value(const DB_VALUE *val, TP_DOMAIN *dbuf)
static int ldr_datetimeltz_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
enum lc_prefetch_flags LC_PREFETCH_FLAGS
Definition: locator.h:339
static const char * ldr_class_name(LDR_CONTEXT *context)
static DB_VALUE ldr_timestamp_tmpl
static void ldr_act_class_attr(LDR_CONTEXT *context, const char *str, size_t len, data_type type)
SM_NAME_SPACE name_space
Definition: class_object.h:386
int er_errid(void)
void ldr_increment_err_total()
static int ldr_class_oid_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
static driver * ldr_Driver
int str_to_int64(INT64 *ret_p, char **end_p, const char *str_p, int base)
Definition: porting.c:2419
CLASS_TABLE * Classes
static int ldr_elo_ext_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
DB_OBJECT * cls
static DB_VALUE ldr_double_tmpl
static int ldr_final(void)
const char * name
SM_METHOD_ARGUMENT ** method_args
int otable_reserve(CLASS_TABLE *table, OID *instance, int id)
static int ldr_monetary_db_monetary(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
void start_line(int object_id) override
static DB_VALUE ldr_bigint_tmpl
static DB_VALUE ldr_float_tmpl
unsigned char style
Definition: dbtype_def.h:979
static int ldr_act_check_missing_non_null_attrs(LDR_CONTEXT *context)
PR_TYPE * tp_Type_object
int ml_find(DB_OBJLIST *list, MOP mop)
Definition: work_space.c:4465
static int ldr_datetime_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
static DB_VALUE ldr_short_tmpl
int db_make_elo(DB_VALUE *value, DB_TYPE type, const DB_ELO *elo)
#define ER_LDR_OBJECT_DOMAIN_MISMATCH
Definition: error_code.h:677
static void ldr_act_set_skip_current_class(char *class_name, size_t size)
bool locator_Dont_check_foreign_key
Definition: locator_sr.c:120
static int ldr_float_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
static void ldr_act_set_ref_class_id(LDR_CONTEXT *context, int id)
static int ldr_numeric_db_generic(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
#define COPY_OID(dest_oid_ptr, src_oid_ptr)
Definition: oid.h:63
static jmp_buf ldr_Jmp_buf
DB_DOMAIN_INFO domain
Definition: dbtype_def.h:1082
LC_OIDMAP * locator_add_oidset_object(LC_OIDSET *oidset, MOP obj_mop)
Definition: locator_cl.c:6629
int64_t inst_count
scanner & get_scanner()
static int ldr_act_add_class_all_attrs(const char *class_name)
int otable_insert(CLASS_TABLE *table, OID *instance, int id)
static void ldr_mop_tempoid_maps_final(void)
static int ldr_null_db_generic(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
#define RETURN_IF_NOT_VALID(context)
static void ldr_act_set_instance_id(LDR_CONTEXT *context, int id)
static DB_VALUE ldr_clob_tmpl
static void idmap_init(void)
int sm_get_descriptor_component(MOP op, SM_DESCRIPTOR *desc, int for_update, SM_CLASS **class_ptr, SM_COMPONENT **comp_ptr)
LOCK locator_fetch_mode_to_lock(DB_FETCH_MODE purpose, LC_OBJTYPE type, LC_FETCH_VERSION_TYPE fetch_version_type)
Definition: locator_cl.c:2068
#define MAX_DIGITS_FOR_INT
int db_make_short(DB_VALUE *value, const DB_C_SHORT num)
static int ldr_init_loader(LDR_CONTEXT *context)
LOCK
static int ldr_refresh_attrs(LDR_CONTEXT *context)
#define PARSE_ELO_STR(str, new_len)
int db_make_string(DB_VALUE *value, DB_CONST_C_CHAR str)
static int ldr_timestamp_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
int db_string_to_time(const char *str, DB_TIME *time)
Definition: db_date.c:3739
DB_BIGINT bigint
Definition: dbtype_def.h:1051
DB_DATA data
Definition: dbtype_def.h:1083
DB_CURRENCY
Definition: dbtype_def.h:799
DB_OBJECT * db_create_internal(DB_OBJECT *obj)
Definition: db_obj.c:93
int setmem(void *memptr, const tp_domain *domain, const DB_VALUE *value) const
unsigned int DB_TIMESTAMP
Definition: dbtype_def.h:759
#define OR_CHECK_DOUBLE_OVERFLOW(i)
static void ldr_process_object_ref(object_ref_type *ref, int type)
static int ldr_class_oid_db_object(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
static bool skip_current_instance
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
static const char * ldr_attr_name(LDR_CONTEXT *context)
#define ER_LDR_SYSTEM_CLASS
Definition: error_code.h:663
static int ldr_elo_int_db_elo(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
Definition: db_set.h:35
DB_TIMESTAMP utime
Definition: dbtype_def.h:1058
static int ldr_date_db_date(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
enum currency_check_mode CURRENCY_CHECK_MODE
Definition: intl_support.h:162
#define INST_FLAG_CLASS_ATT
static void ldr_act_add_attr(LDR_CONTEXT *context, const char *attr_name, size_t len)
const char * AU_ROOT_CLASS_NAME
Definition: authenticate.c:104
#define assert(x)
int db_make_monetary(DB_VALUE *value, const DB_CURRENCY type, const double amount)
static void parse_error(LDR_CONTEXT *context, DB_TYPE token_type, const char *token)
int set_add_element(DB_COLLECTION *set, DB_VALUE *value)
Definition: set_object.c:2641
static int ldr_str_db_char(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
int errors
static bool ldr_is_ignore_class(const char *class_name, size_t size)
#define ER_LC_UNKNOWN_CLASSNAME
Definition: error_code.h:121
static DB_OBJECT ** Id_map
static int ldr_Interrupt_type
LDR_MOP_TEMPOID_MAP * mop_tempoid_maps
int qstr_hex_to_bin(char *dest, int dest_size, const char *src, int src_size)
int prm_get_integer_value(PARAM_ID prm_id)
std::string table_name
#define ER_GENERIC_ERROR
Definition: error_code.h:49
int au_fetch_class(MOP op, SM_CLASS **class_ptr, AU_FETCHMODE fetchmode, DB_AUTH type)
#define LDR_ARG_GROW_SIZE
static bool skip_current_class
struct db_char::@52 info
void(* ldr_act)(LDR_CONTEXT *context, const char *str, size_t len, data_type type)
struct db_object * class_mop
Definition: work_space.h:121
int(* LDR_ELEM)(LDR_CONTEXT *, const char *, size_t, DB_VALUE *)
#define ER_IT_DATA_OVERFLOW
Definition: error_code.h:505
static int ldr_check_date_time_conversion(const char *str, data_type type)
DB_TYPE db_value_type(const DB_VALUE *value)
static int ldr_real_db_double(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
#define OID_ISTEMP(oidp)
Definition: oid.h:80
bool intl_is_currency_symbol(const char *src, DB_CURRENCY *currency, int *symbol_size, const CURRENCY_CHECK_MODE check_mode)
static void ldr_date_time_conversion_error(const char *token, DB_TYPE type)
#define OR_CHECK_SHORT_OVERFLOW(i)
static int insert_instance(LDR_CONTEXT *context)
SM_ATTRIBUTE * class_attributes
Definition: class_object.h:725
int compressed_size
Definition: dbtype_def.h:1001
int db_json_get_json_from_str(const char *json_raw, JSON_DOC *&doc, size_t json_raw_length)
Definition: db_json.cpp:1608
SM_ATTRIBUTE * att
DB_DATETIME datetime
Definition: dbtype_def.h:783
int sm_update_statistics(MOP classop, bool with_fullscan)
int intl_identifier_casecmp(const char *str1, const char *str2)
static int ldr_ignore(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
static int ldr_nstr_db_varnchar(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
static int ldr_double_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
char * compressed_buf
Definition: dbtype_def.h:1002
#define ER_LDR_FORWARD_CONSTRUCTOR
Definition: error_code.h:672
void ldr_sa_load(load_args *args, int *status, bool *interrupted)
void db_free_attribute_descriptor(DB_ATTDESC *descriptor)
Definition: db_obj.c:835
static int ldr_collection_db_collection(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
void set_class_id(class_id clsid) override
int locator_flush_class(MOP class_mop)
Definition: locator_cl.c:5068
const char * db_error_string(int level)
Definition: db_admin.c:2116
static DB_VALUE ldr_datetime_tmpl
static int ldr_oid_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
#define ROUND(x)
void ws_pin_instance_and_class(MOP obj, int *opin, int *cpin)
Definition: work_space.c:3020
#define OR_CHECK_INT_OVERFLOW(i)
#define LDR_MOP_TEMPOID_MAPS_PRESIZE
void ws_restore_pin(MOP obj, int opin, int cpin)
Definition: work_space.c:3052
static int select_set_domain(LDR_CONTEXT *context, TP_DOMAIN *domain, TP_DOMAIN **set_domain_ptr)
void process_line(constant_type *cons) override
INTL_LANG lang_id
void otable_class_att_ref(INST_INFO *inst)
cubload::driver * m_loaddb_driver
const char * sm_get_ch_name(MOP op)
#define CHECK_SKIP_WITH(ret)
DB_OBJECT * db_get_object(const DB_VALUE *value)
CLASS_TABLE * otable_find_class(MOP class_)
TP_DOMAIN * set_domain
static int64_t Last_committed_line
int db_make_timestamptz(DB_VALUE *value, const DB_C_TIMESTAMPTZ *ts_tz_val)
static int add_element(void ***elements, int *count, int *max, int grow)
struct LDR_ATTDESC LDR_ATTDESC
unsigned char buf[DB_NUMERIC_BUF_SIZE]
Definition: dbtype_def.h:794
static int ldr_collection_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
#define ER_LDR_MISSING_ATTRIBUTES
Definition: error_code.h:670
static DB_OBJECT * ldr_get_class_from_id(int id)
TP_DOMAIN_STATUS tp_value_cast(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain, bool implicit_coercion)
int db_abort_transaction(void)
Definition: db_admin.c:1114
SM_METHOD * constructor
#define TP_DOMAIN_TYPE(dom)
static void ldr_clear_and_free_context(LDR_CONTEXT *context)
int db_get_attribute_descriptor(DB_OBJECT *obj, const char *attname, int class_attribute, int for_update, DB_ATTDESC **descriptor)
Definition: db_obj.c:763
#define IS_OLD_GLO_CLASS(class_name)
#define CHECK_VALIDATION_ONLY(context)
int locator_assign_oidset(LC_OIDSET *oidset, LC_OIDMAP_CALLBACK callback)
Definition: locator_cl.c:6687
#define NULL
Definition: freelistheap.h:34
#define ER_OBJ_ATTRIBUTE_CANT_BE_NULL
Definition: error_code.h:276
struct pr_type * type
Definition: object_domain.h:76
data_type parser_type
DB_CHAR ch
Definition: dbtype_def.h:1070
SM_METHOD_SIGNATURE * signatures
Definition: class_object.h:593
unsigned char size
Definition: dbtype_def.h:990
#define MAX_DIGITS_FOR_BIGINT
int db_drop(DB_OBJECT *obj)
Definition: db_obj.c:190
DB_DATE date
Definition: dbtype_def.h:1057
static int update_default_count(CLASS_TABLE *table, OID *oid)
static int ldr_timestamptz_db_timestamptz(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
#define OBJ_SET_BOUND_BIT(obj, element)
static void ldr_register_post_interrupt_handler()
DB_TIMESTAMPTZ timestamptz
Definition: dbtype_def.h:1059
static int ldr_bstr_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
static void ldr_invalid_class_error(LDR_CONTEXT *context)
LC_FIND_CLASSNAME
static int update_default_instances_stats(LDR_CONTEXT *context)
int64_t inst_total
#define err(fd,...)
Definition: porting.h:431
static DB_VALUE ldr_blob_tmpl
#define db_private_free_and_init(thrd, ptr)
Definition: memory_alloc.h:141
constructor_spec_type * ctor_spec
bool tm_Use_OID_preflush
void check_class(const char *class_name, int class_id) override
LC_OIDSET * locator_make_oid_set(void)
Definition: locator.c:2116
static DB_VALUE ldr_char_tmpl
static DB_OBJECT * ldr_find_class(const char *class_name)
unsigned char is_max_string
Definition: dbtype_def.h:981
#define NUM_BUF_SIZE
Definition: string_opfunc.h:88
void init(class_id clsid) override
int ml_ext_add(DB_OBJLIST **list, MOP mop, int *added_ptr)
Definition: work_space.c:4877
int numeric_coerce_num_to_bigint(DB_C_NUMERIC arg, int scale, DB_BIGINT *answer)
#define db_private_alloc(thrd, size)
Definition: memory_alloc.h:227
int intl_char_size(const unsigned char *src, int length_in_chars, INTL_CODESET src_codeset, int *byte_count)
static int64_t Total_objects_loaded
#define ER_LDR_INVALID_CLASS_ATTR
Definition: error_code.h:960
need_clear_type need_clear
Definition: dbtype_def.h:1084
#define CHECK_PTR(err, expr)
static LDR_MOP_TEMPOID_MAPS * ldr_Mop_tempoid_maps
static void display_error_line(int adjust)
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
static int ldr_int_db_generic(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
#define ER_LDR_INVALID_STATE
Definition: error_code.h:655
int obj_set_shared(MOP op, const char *name, DB_VALUE *value)
int db_change_default(MOP class_, const char *name, DB_VALUE *value)
Definition: db_class.c:584
void locator_free_oid_set(THREAD_ENTRY *thread_p, LC_OIDSET *oidset)
Definition: locator.c:2227
int db_make_time(DB_VALUE *value, const int hour, const int minute, const int second)
#define ER_LDR_INTERNAL_REFERENCE
Definition: error_code.h:664
static int ldr_datetime_db_datetime(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
int er_filter_errid(bool ignore_warning)
Definition: load_object.c:1759
#define DB_DEFAULT_SCALE
Definition: dbtype_def.h:561
bool obt_enable_unique_checking(bool new_state)
int total_oids
Definition: locator.h:384
#define max(a, b)
INST_INFO * otable_find(CLASS_TABLE *table, int id)
static int ldr_sys_user_db_generic(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
int db_make_datetimetz(DB_VALUE *value, const DB_DATETIMETZ *datetimetz)
int64_t DB_BIGINT
Definition: dbtype_def.h:751
#define ER_DATE_CONVERSION
Definition: error_code.h:242
string_type * next
static int ldr_xstr_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
const char * envvar_get(const char *name)
static const char * ldr_Hint_class_names[LDR_LOCKHINT_COUNT]
int db_make_float(DB_VALUE *value, const DB_C_FLOAT num)
SM_NAME_SPACE name_space
Definition: class_object.h:904
static int Id_map_size
unsigned int flags
Definition: class_object.h:459
int qstr_bit_to_bin(char *dest, int dest_size, const char *src, int src_size)
#define OBJ_CLEAR_BOUND_BIT(obj, element)
#define DB_DEFAULT_PRECISION
Definition: dbtype_def.h:558
#define AU_UPDATE
Definition: authenticate.h:71
static int ldr_Load_interrupted
#define ER_LDR_NESTED_SET
Definition: error_code.h:662
int db_string_to_timestampltz(const char *str, DB_TIMESTAMP *ts)
Definition: db_date.c:3936
static int ldr_numeric_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
static void ldr_clear_err_count(LDR_CONTEXT *context)
#define OR_CHECK_FLOAT_OVERFLOW(i)
static int ldr_Hint_subclasses[LDR_LOCKHINT_COUNT]
static int ldr_add_mop_tempoid_map(MOP mop, CLASS_TABLE *table, int id)
#define AU_SELECT
Definition: authenticate.h:69
unsigned char compressed_need_clear
Definition: dbtype_def.h:982
#define ARG_FILE_LINE
Definition: error_manager.h:44
int otable_map_reserved(OTABLE_MAPFUNC mapfunc, int stop_on_error)
int sm_partitioned_class_type(DB_OBJECT *classop, int *partition_type, char *keyattr, MOP **partitions)
unsigned int INTL_LANG
Definition: intl_support.h:132
DB_OBJECT * obj
int db_send_argarray(MOP obj, const char *name, DB_VALUE *returnval, DB_VALUE **args)
Definition: db_obj.c:444
#define WS_OID(mop)
Definition: work_space.h:293
void print_log_msg(int verbose, const char *fmt,...)
Definition: load_db.c:82
unsigned int DB_TIME
Definition: dbtype_def.h:754
int obj_set(MOP op, const char *name, DB_VALUE *value)
LC_FIND_CLASSNAME locator_lockhint_classes(int num_classes, const char **many_classnames, LOCK *many_locks, int *need_subclasses, LC_PREFETCH_FLAGS *flags, int quit_on_errors, LOCK lock_rr_tran)
Definition: locator_cl.c:6260
static int clist_init(void)
static void ldr_register_post_commit_handler()
#define GET_DOMAIN(context, domain)
int db_make_varbit(DB_VALUE *value, const int max_bit_length, DB_CONST_C_BIT bit_str, const int bit_str_bit_size)
unsigned int DB_DATE
Definition: dbtype_def.h:771
static int ldr_class_attr_db_generic(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att, DB_VALUE *val)
int db_string_to_datetimeltz(const char *str, DB_DATETIME *datetime)
Definition: db_date.c:4555
static int ldr_bstr_db_varbit(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
static void ldr_report_num_of_commits(int64_t num_committed)
DB_COLLECTION * db_col_create(DB_TYPE type, int size, DB_DOMAIN *domain)
Definition: db_set.c:949
int intl_identifier_lower_string_size(const char *src)
static int check_object_domain(LDR_CONTEXT *context, DB_OBJECT *class_, DB_OBJECT **actual_class)
int db_make_collection(DB_VALUE *value, DB_C_SET *set)
char * locator
Definition: dbtype_def.h:948
#define ER_LDR_DOMAIN_MISMATCH
Definition: error_code.h:660
#define free_and_init(ptr)
Definition: memory_alloc.h:147
void numeric_coerce_dec_str_to_num(const char *dec_str, DB_C_NUMERIC result)
unsigned char pruning_type
Definition: work_space.h:138
#define strlen(s1)
Definition: intl_support.c:43
int db_datetime_encode(DB_DATETIME *datetime, int month, int day, int year, int hour, int minute, int second, int millisecond)
Definition: db_date.c:4597
int(* LDR_SETTER)(LDR_CONTEXT *, const char *, size_t, SM_ATTRIBUTE *)
int db_make_timestampltz(DB_VALUE *value, const DB_C_TIMESTAMP ts_val)
int install_class(const char *class_name) override
static int ldr_int_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
static int ldr_update_statistics(void)
class_installer & get_class_installer()
Definition: load_driver.cpp:96
DB_METHOD * db_get_class_method(DB_OBJECT *obj, const char *name)
Definition: db_info.c:1484
SM_COMPONENT header
Definition: class_object.h:441
static int ldr_oid_db_object(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
static int ldr_xstr_db_varbit(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
#define ER_LDR_ELO_INPUT_FILE
Definition: error_code.h:671
static DB_VALUE ldr_varchar_tmpl
int db_value_put(DB_VALUE *value, const DB_TYPE_C c_type, void *input, const int input_length)
Definition: db_macro.c:1256
enum intl_codeset INTL_CODESET
Definition: intl_support.h:190
int intl_char_count(const unsigned char *src, int length_in_bytes, INTL_CODESET src_codeset, int *char_count)
Definition: intl_support.c:983
static int ldr_timestamp_db_timestamp(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
static LDR_ELEM elem_converter[NUM_LDR_TYPES]
void ml_ext_free(DB_OBJLIST *list)
Definition: work_space.c:4806
void ws_intern_instances(MOP class_mop)
Definition: work_space.c:1548
std::size_t get_rows_number() override
int64_t size
Definition: dbtype_def.h:947
static int ldr_int_db_short(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
void ws_decache_all_instances(MOP mop)
Definition: work_space.c:2765
int util_log_write_errstr(const char *format,...)
Definition: util_func.c:493
#define OID_BATCH_SIZE
Definition: locator_cl.h:51
SM_METHOD_ARGUMENT * args
Definition: class_object.h:577
void(* LDR_POST_INTERRUPT_HANDLER)(int64_t)
void er_clear(void)
void elo_init_structure(DB_ELO *elo)
Definition: elo.c:127
int db_make_varnchar(DB_VALUE *value, const int max_nchar_length, DB_CONST_C_NCHAR str, const int nchar_str_byte_size, const int codeset, const int collation_id)
static int ldr_nstr_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
#define TP_FLOATING_PRECISION_VALUE
static int ldr_assign_all_perm_oids(void)
static int ldr_timestamptz_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
#define DB_VALUE_TYPE(value)
Definition: dbtype.h:72
static int ldr_elo_ext_db_elo(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
static int ldr_time_db_time(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
int i
Definition: dynamic_load.c:954
struct ldr_mop_tempoid_maps LDR_MOP_TEMPOID_MAPS
int db_make_null(DB_VALUE *value)
char * msgcat_message(int cat_id, int set_id, int msg_id)
static void ldr_act_set_ref_class(LDR_CONTEXT *context, char *name)
void initialize(class_installer *cls_installer, object_loader *obj_loader, error_handler *error_handler)
Definition: load_driver.cpp:65
#define ER_OBJ_DOMAIN_CONFLICT
Definition: error_code.h:285
static void ldr_act_meth(LDR_CONTEXT *context, const char *str, size_t len, data_type type)
const char * name
Definition: class_object.h:385
int db_make_double(DB_VALUE *value, const DB_C_DOUBLE num)
union db_numeric::@51 d
#define ER_LDR_VALUE_OVERFLOW
Definition: error_code.h:657
int parse_bigint(INT64 *ret_p, const char *str_p, int base)
Definition: porting.c:2318
static DB_VALUE ldr_time_tmpl
int au_fetch_instance(MOP op, MOBJ *obj_ptr, AU_FETCHMODE mode, LC_FETCH_VERSION_TYPE fetch_version_type, DB_AUTH type)
static int ldr_timestampltz_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
std::vector< std::string > ignore_classes
void(* LDR_POST_COMMIT_HANDLER)(int64_t)
const std::size_t LDR_MAX_ARGS
static int ldr_finish_context(LDR_CONTEXT *context)
int db_value_clear(DB_VALUE *value)
Definition: db_macro.c:1588
int db_make_timestamp(DB_VALUE *value, const DB_C_TIMESTAMP timeval)
int db_make_int(DB_VALUE *value, const int num)
#define CHECK_SKIP()
static int ldr_elo_int_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
static int ldr_str_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
entry & get_entry(void)
#define LDR_LOCKHINT_COUNT
static int ldr_json_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
#define STATS_WITH_SAMPLING
Definition: statistics.h:35
static int ldr_real_db_generic(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
int db_make_char(DB_VALUE *value, const int char_length, DB_CONST_C_CHAR str, const int char_str_byte_size, const int codeset, const int collation_id)
static int ldr_date_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
#define ER_LDR_UNEXPECTED_ARGUMENT
Definition: error_code.h:668
static int ldr_real_db_float(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
char * meta_data
Definition: dbtype_def.h:949
#define LANG_SYS_CODESET
int db_string_to_timestamptz(const char *str, DB_TIMESTAMPTZ *ts_tz, bool *has_zone)
Definition: db_date.c:3894
load_args * args
void ws_release_instance(MOP mop)
Definition: work_space.c:1565
static int ldr_datetimetz_db_datetimetz(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
static int ldr_time_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
string_type * instance_number
size_t parser_buf_len
SM_ATTRIBUTE * ordered_attributes
Definition: class_object.h:753
static int check_class_domain(LDR_CONTEXT *context)
static int ldr_generic(LDR_CONTEXT *context, DB_VALUE *value)
static void ldr_flush(LDR_CONTEXT *context)
static int ldr_datetimetz_elem(LDR_CONTEXT *context, const char *str, size_t len, DB_VALUE *val)
DB_ATTDESC * attdesc
DB_OBJECT * id_class
struct ldr_mop_tempoid_map LDR_MOP_TEMPOID_MAP
int otable_update(CLASS_TABLE *table, int id)
#define ER_LDR_NO_CLASS_OR_NO_ATTRIBUTE
Definition: error_code.h:667
static int ldr_datetimeltz_db_datetimeltz(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
int db_make_bit(DB_VALUE *value, const int bit_length, DB_CONST_C_BIT bit_str, const int bit_str_bit_size)
DB_COLLECTION * collection
static void ldr_increment_err_count(LDR_CONTEXT *context, int i)
int db_string_to_date(const char *str, DB_DATE *date)
Definition: db_date.c:3693
const char * AU_AUTH_CLASS_NAME
Definition: authenticate.c:109
float f
Definition: dbtype_def.h:1052
int class_id
Definition: load_common.hpp:40
const char ** p
Definition: dynamic_load.c:945
#define ER_LDR_MISSING_ARGUMENT
Definition: error_code.h:669
double d
Definition: dbtype_def.h:1053
SM_METHOD_ARGUMENT * classobj_find_method_arg(SM_METHOD_ARGUMENT **arglist, int index, int create)
static DB_VALUE ldr_bit_tmpl
struct db_char::@54 medium
static DB_VALUE ldr_date_tmpl
int db_commit_transaction(void)
Definition: db_admin.c:1091
static int ldr_assign_class_id(DB_OBJECT *class_, int id)
static LDR_POST_INTERRUPT_HANDLER ldr_post_interrupt_handler
static int ldr_int_db_int(LDR_CONTEXT *context, const char *str, size_t len, SM_ATTRIBUTE *att)
static LC_PREFETCH_FLAGS ldr_Hint_flags[LDR_LOCKHINT_COUNT]
char * intl_get_money_esc_ISO_symbol(const DB_CURRENCY currency)
int db_value_domain_init(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale)
Definition: db_macro.c:153
static int ldr_init(load_args *args)
static void ldr_clear_context(LDR_CONTEXT *context)
static int ldr_mop_tempoid_maps_init(void)
static int check_commit(LDR_CONTEXT *context)
static void invalid_class_id_error(LDR_CONTEXT *context, int id)
DB_DATETIMETZ datetimetz
Definition: dbtype_def.h:1061
#define MSGCAT_CATALOG_UTILS