CUBRID Engine  latest
object_representation.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * object_representation.c: Low level functions that manipulate
21  * the disk representation of
22  */
23 
24 #ident "$Id$"
25 
26 #include "config.h"
27 
28 #include <string.h>
29 #if defined (WINDOWS)
30 #include <winsock2.h>
31 #endif /* WINDOWS */
32 #include <setjmp.h>
33 #include <assert.h>
34 
35 #include "db_json.hpp"
36 #include "dbtype.h"
37 #include "error_manager.h"
38 #include "file_io.h"
39 #include "log_lsa.hpp"
40 #include "method_def.hpp"
41 #include "object_primitive.h"
42 #include "object_representation.h"
43 #include "oid.h"
44 #include "porting_inline.hpp"
45 #include "query_list.h"
46 #include "set_object.h"
47 
48 #if defined (SUPPRESS_STRLEN_WARNING)
49 #define strlen(s1) ((int) strlen(s1))
50 #endif /* defined (SUPPRESS_STRLEN_WARNING) */
51 
52 /* simple macro to calculate minimum bytes to contain given bits */
53 #define BITS_TO_BYTES(bit_cnt) (((bit_cnt) + 7) / 8)
54 
55 /*
56  * Lookup to compute the MVCC header size faster:
57  * INDEX MVCC FLAGS SIZE
58  * 0 NO FLAGS REP_SIZE + CHN_SIZE
59  * 1 INSID REP_SIZE + CHN_SIZE + MVCCID_SIZE
60  * 2 DELID REP_SIZE + CHN_SIZE + MVCCID_SIZE
61  * 3 INSID | DELID REP_SIZE + CHN_SIZE + MVCCID_SIZE + MVCCID_SIZE
62  * 4 PREV_VERSION REP_SIZE + CHN_SIZE + PREV_VERSION_LSA_SIZE
63  * 5 INSID | PREV_VERSION REP_SIZE + CHN_SIZE + MVCCID_SIZE + PREV_VERSION_LSA_SIZE
64  * 6 DELID | PREV_VERSION REP_SIZE + CHN_SIZE + MVCCID_SIZE + PREV_VERSION_LSA_SIZE
65  * 7 INSID | DELID | PREV_VERSION REP_SIZE + CHN_SIZE + MVCCID_SIZE + MVCCID_SIZE + PREV_VERSION_LSA_SIZE
66  *
67  * Note: In case that the heap record header modifies, mvcc_header_size_lookup must be updated.
68  */
71  OR_MVCC_REP_SIZE + OR_CHN_SIZE + OR_MVCCID_SIZE,
72  OR_MVCC_REP_SIZE + OR_CHN_SIZE + OR_MVCCID_SIZE,
73  OR_MVCC_REP_SIZE + OR_CHN_SIZE + OR_MVCCID_SIZE + OR_MVCCID_SIZE,
75  OR_MVCC_REP_SIZE + OR_CHN_SIZE + OR_MVCCID_SIZE + OR_MVCC_PREV_VERSION_LSA_SIZE,
76  OR_MVCC_REP_SIZE + OR_CHN_SIZE + OR_MVCCID_SIZE + OR_MVCC_PREV_VERSION_LSA_SIZE,
77  OR_MVCC_REP_SIZE + OR_CHN_SIZE + OR_MVCCID_SIZE + OR_MVCCID_SIZE + OR_MVCC_PREV_VERSION_LSA_SIZE
78 };
79 
80 static TP_DOMAIN *unpack_domain (OR_BUF * buf, int *is_null);
81 static char *or_pack_method_sig (char *ptr, void *method_sig_ptr);
82 static char *or_unpack_method_sig (char *ptr, void **method_sig_ptr, int n);
83 #if defined(ENABLE_UNUSED_FUNCTION)
84 static char *unpack_str_array (char *buffer, char ***string_array, int count);
85 #endif
86 static int or_put_varchar_internal (OR_BUF * buf, char *string, int charlen, int align);
87 static int or_varbit_length_internal (int bitlen, int align);
88 static int or_varchar_length_internal (int charlen, int align);
89 static int or_put_varbit_internal (OR_BUF * buf, const char *string, int bitlen, int align);
90 static int or_packed_json_schema_length (const char *json_schema);
91 static int or_packed_json_validator_length (JSON_VALIDATOR * json_validator);
92 static char *or_unpack_var_table_internal (char *ptr, int nvars, OR_VARINFO * vars, int offset_size);
93 
94 /*
95  * classobj_get_prop - searches a property list for a value with the given name
96  * return: index of the found property, 0 iff not found
97  * properties(in): property sequence
98  * name(in): property name
99  * pvalue(out): value container for property value
100  *
101  * Note:
102  * Remember to clear the value with pr_clear_value or equivalent.
103  */
104 int
105 classobj_get_prop (DB_SEQ * properties, const char *name, DB_VALUE * pvalue)
106 {
107  int error;
108  int found, max, i;
109  DB_VALUE value;
110  const char *tmp_str;
111 
112  error = NO_ERROR;
113  found = 0;
114 
115  if (properties == NULL || name == NULL || pvalue == NULL)
116  {
117  goto error;
118  }
119 
120  max = set_size (properties);
121 
122  for (i = 0; i < max && !found && error == NO_ERROR; i += 2)
123  {
124  error = set_get_element (properties, i, &value);
125  if (error != NO_ERROR)
126  {
127  continue;
128  }
129 
130  if (DB_VALUE_TYPE (&value) != DB_TYPE_STRING || db_get_string (&value) == NULL)
131  {
132  error = ER_SM_INVALID_PROPERTY;
133  }
134  else
135  {
136  tmp_str = db_get_string (&value);
137  if (tmp_str && strcmp (name, tmp_str) == 0)
138  {
139  if ((i + 1) >= max)
140  {
141  error = ER_SM_INVALID_PROPERTY;
142  }
143  else
144  {
145  error = set_get_element (properties, i + 1, pvalue);
146  if (error == NO_ERROR)
147  {
148  found = i + 1;
149  }
150  }
151  }
152  }
153  pr_clear_value (&value);
154  }
155 
156 error:
157  if (error)
158  {
160  }
161 
162  return found;
163 }
164 
165 
166 /*
167  * classobj_decompose_property_oid - parse oid string from buffer
168  * return: zero if decompose error, 3 if successful
169  * buffer(in): buffer that contains oid string
170  * volid(out): volumn id
171  * fileid(out): file id
172  * pageid(out): pageid
173  *
174  */
175 int
176 classobj_decompose_property_oid (const char *buffer, int *volid, int *fileid, int *pageid)
177 {
178  char *ptr;
179  int result = 0;
180  int val;
181 
182  if (buffer == NULL)
183  {
184  return 0;
185  }
186 
187  result = str_to_int32 (&val, &ptr, buffer, 10);
188  *volid = val;
189  if (result != 0)
190  {
191  return 0;
192  }
193  buffer = ptr + 1;
194 
195  result = str_to_int32 (&val, &ptr, buffer, 10);
196  *fileid = val;
197  if (result != 0)
198  {
199  return 0;
200  }
201  buffer = ptr + 1;
202 
203  result = str_to_int32 (&val, &ptr, buffer, 10);
204  *pageid = val;
205  if (result != 0)
206  {
207  return 0;
208  }
209 
210  return 3;
211 }
212 
213 /*
214  * or_Type_sizes
215  * This is used primarily on the server but can be used on the client
216  * as well. Given a type identifier, return the disk size of values
217  * of this type, if they are fixed size. A value of -1 indicates that
218  * the values are of variable size.
219  * Must be kept in sync with the DB_TYPE enumeration in orh
220  * This information is duplicated in the PR_TYPE structures
221  * for use on the client. Should consider using this on the client
222  * side as well to avoid the duplication.
223  *
224  */
225 int or_Type_sizes[] = {
226 
227  0, /* null */
228  OR_INT_SIZE, /* integer */
229  OR_FLOAT_SIZE, /* float */
230  OR_DOUBLE_SIZE, /* double */
231  -1, /* string */
232  OR_OID_SIZE, /* object */
233  -1, /* set */
234  -1, /* multiset */
235  -1, /* sequence */
236  -1, /* elo */
237  OR_TIME_SIZE, /* time */
238  OR_UTIME_SIZE, /* utime */
239  OR_DATE_SIZE, /* date */
240  OR_MONETARY_SIZE, /* monetary */
241  -1, /* variable */
242  -1, /* substructure */
243  0, /* pointer */
244  0, /* error */
245  OR_INT_SIZE, /* short */
246  -1, /* virtual obj */
247  OR_OID_SIZE, /* oid */
248  0, /* last */
249  -1, /* numeric */
250  -1, /* bit */
251  -1, /* varbit */
252  -1, /* char */
253  -1, /* nchar */
254  -1, /* varnchar */
255 };
256 
257 /*
258  * RECDES DECODING FUNCTIONS
259  */
260 
261 /*
262  * These are called primarily by the locator to get information
263  * about the disk representation of an object stored in a disk
264  * record descirptor (RECDES).
265  */
266 
267 /*
268  * or_class_name - This is used to extract the class name from the disk
269  * representation of a class object
270  * return: class name string pointer inside recode data
271  * record(in): disk record
272  *
273  * Note:
274  * To avoid a lot of dependencies with the schema code, we make the
275  * assumption that the name field is always maintained as the first
276  * variable attribute of class objects.
277  * This will also be true for the root class.
278  *
279  * [PORTABILITY]
280  * This simply returns a pointer into the middle of the record. We may
281  * need to copy the string out of the record for some architectures
282  * if there are weird alignment or character set problems.
283  */
284 char *
286 {
287  char *start, *name;
288  int offset, len;
289 
290  /*
291  * the first variable attribute for both classes and the rootclass
292  * is the name - if this ever changes, we could check the class
293  * OID which should be NULL for the root class and special case
294  * from there
295  */
296 
297  offset = OR_VAR_OFFSET (record->data, 0);
298  start = &record->data[offset];
299 
300  /*
301  * kludge kludge kludge
302  * This is now an encoded "varchar" string, we need to skip over the length
303  * before returning it. Note that this also depends on the stored string
304  * being NULL terminated. This interface should be returning either a copy
305  * or performing an extraction into a user supplied buffer !
306  * Knowledge of the format of packed varchars should be in a different
307  * or_ function.
308  */
309  len = (int) *((unsigned char *) start);
310  if (len != 0xFF)
311  {
312  name = start + 1;
313  }
314  else
315  {
316  name = start + 1 + OR_INT_SIZE;
317  }
318 
319  return name;
320 }
321 
322 /*
323  * or_rep_id - Extracts the representation id from the disk representation of
324  * an object.
325  * return: representation of id of object. or NULL_REPRID for error
326  * record(in): disk record
327  */
328 int
329 or_rep_id (RECDES * record)
330 {
331  int rep = NULL_REPRID;
332 
333  assert (record != NULL && record->data != NULL);
334 
335  if (record->length < OR_HEADER_SIZE (record->data))
336  {
338  }
339  else
340  {
341  rep = OR_GET_MVCC_REPID (record->data);
342  }
343 
344  return rep;
345 }
346 
347 /*
348  * or_set_rep_id () - set representation id for record
349  * return : error code or NO_ERROR
350  * record (in/out): record
351  * repid (in) : new representation
352  *
353  * Note: This function changes the representation id of a record. It should
354  * only be used in update/insert operations on partitioned tables. Each
355  * partition is viewed by the heap/btree operations as a different class
356  * and it might have a different representation id than the one of the root
357  * table. However, when partitioning a table, we guarantee that the actual
358  * disk representation is the same as the one of the root table (even though
359  * the actual id might differ). Do not use this function in another context!
360  */
361 int
362 or_set_rep_id (RECDES * record, int repid)
363 {
364  OR_BUF orep, *buf;
365  unsigned int new_bits = 0;
366 
367  if (record->length < OR_HEADER_SIZE (record->data))
368  {
370  return ER_FAILED;
371  }
372 
373  OR_BUF_INIT (orep, record->data, record->area_size);
374  buf = &orep;
375 
376  new_bits = OR_GET_MVCC_REPID_AND_FLAG (record->data);
377 
378  /* Remove old repid */
379  new_bits &= ~OR_MVCC_REPID_MASK;
380 
381  /* Add new repid */
382  new_bits |= (repid & OR_MVCC_REPID_MASK);
383 
384  /* Set buffer pointer to the right position */
385  buf->ptr = buf->buffer + OR_REP_OFFSET;
386 
387  /* write new REPR_ID to the record */
388  or_put_int (buf, new_bits);
389 
390  return NO_ERROR;
391 }
392 
393 /*
394  * or_chn - extracts cache coherency number from the disk representation of an
395  * object
396  * return: cache coherency number (chn), or NULL_CHN for error
397  * record(in): disk record
398  */
399 int
400 or_chn (RECDES * record)
401 {
402  if (record->length < OR_CHN_OFFSET + OR_CHN_SIZE)
403  {
405  return NULL_CHN;
406  }
407 
408  return OR_GET_MVCC_CHN (record->data);
409 }
410 
411 /*
412  * or_replace_chn () -replace chn
413  *
414  * return : error
415  * record(in/out) : record
416  * chn(int): chn
417  *
418  * NOTE: It determines the type of record based on flag in record not system
419  * parameter.
420  */
421 int
422 or_replace_chn (RECDES * record, int chn)
423 {
424  OR_BUF orep, *buf;
425  int offset;
426  int error;
427 
428  OR_BUF_INIT (orep, record->data, record->area_size);
429  buf = &orep;
430 
431  offset = OR_CHN_OFFSET;
432  buf->ptr = buf->buffer + offset;
433 
434  error = or_put_int (buf, chn);
435 
436  return error;
437 }
438 
439 /*
440  * or_mvcc_get_repid_and_flags () - Gets MVCC representation id and flags.
441  *
442  * return : MVCC flags.
443  * buf (in/out) : or buffer
444  * error(out): NO_ERROR or error code
445  */
446 int
448 {
450 
451  if ((buf->ptr + OR_INT_SIZE) > buf->endptr)
452  {
453  *error = or_underflow (buf);
454  return 0;
455  }
456  else
457  {
458  int repid_and_flag_bits = 0;
459  repid_and_flag_bits = OR_GET_INT (buf->ptr);
460  buf->ptr += OR_INT_SIZE;
461  *error = NO_ERROR;
462  return repid_and_flag_bits;
463  }
464 }
465 
466 /*
467  * or_mvcc_set_repid_and_flags () - Set MVCC representation id and flags.
468  *
469  * return : nothing
470  * buf (in/out) : or buffer
471  * bound_bit(in) : bound bit
472  * variable_offset_size(in); variable offset size
473  * error(out): NO_ERROR or error code
474  */
475 int
476 or_mvcc_set_repid_and_flags (OR_BUF * buf, int mvcc_flag, int repid, int bound_bit, int variable_offset_size)
477 {
478  int repid_and_flags;
479 
480  /* Add repid */
481  repid_and_flags = repid;
482 
483  /* Set bound bit flag -> unchanged */
484  if (bound_bit)
485  {
486  repid_and_flags |= OR_BOUND_BIT_FLAG;
487  }
488  OR_SET_VAR_OFFSET_SIZE (repid_and_flags, variable_offset_size);
489 
490  repid_and_flags |= (mvcc_flag & OR_MVCC_FLAG_MASK) << OR_MVCC_FLAG_SHIFT_BITS;
491 
492  return or_put_int (buf, repid_and_flags);
493 }
494 
495 #if !defined (SERVER_MODE)
496 /*
497  * BOUND BIT FUNCTIONS
498  */
499 /*
500  * These manipulate the bound-bit array which can be found in the headers
501  * of objects and sets.
502  *
503  */
504 
505 #if defined(ENABLE_UNUSED_FUNCTION)
506 /*
507  * or_get_bound_bit - Extracts the bound bit for a particular element.
508  * return: bound bit (0 or 1) for element
509  * bound_bits(in): pointer to bound bits on disk
510  * element(in): index into the bound bit table
511  */
512 int
513 or_get_bound_bit (char *bound_bits, int element)
514 {
515  return (OR_GET_BOUND_BIT (bound_bits, element));
516 }
517 
518 /*
519  * or_put_bound_bit - his sets the value of a bound bit
520  * return: void
521  * bound_bits(out): pointer to bound bit array
522  * element(in): bound bit table index
523  * bound(in): value to set in the table
524  *
525  * Note:
526  * It assumes that the bound bit table is in memory format.
527  */
528 void
529 or_put_bound_bit (char *bound_bits, int element, int bound)
530 {
531  int mask;
532  char *byte, value;
533 
534  /* this could be a macro, but its getting pretty confusing */
535  mask = 1 << (element & 7);
536  byte = bound_bits + (element >> 3);
537  value = *byte;
538 
539  if (bound)
540  {
541  *byte = value | mask;
542  }
543  else
544  {
545  *byte = value & ~mask;
546  }
547 }
548 #endif /* ENABLE_UNUSED_FUNCTION */
549 #endif /* !SERVER_MODE */
550 
551 /*
552  * OR_BUF PACK/UNPACK FUNCTIONS
553  */
554 
555 /*
556  * or_overflow - called by the or_put_ functions when there is not enough
557  * room in the buffer to hold a particular value.
558  * return: ER_TF_BUFFER_OVERFLOW or long jump to buf->error_abort
559  * buf(in): translation state structure
560  *
561  * Note:
562  * Because of the recursive nature of the translation functions, we may
563  * be several levels deep so we can do a longjmp out to the top level
564  * if the user has supplied a jmpbuf.
565  * Because jmpbuf is not a pointer, we have to keep an additional flag
566  * called "error_abort" in the OR_BUF structure to indicate the validity
567  * of the jmpbuf.
568  * This is a fairly common ocurrence because the locator regularly calls
569  * the transformer with a buffer that is too small. When overflow
570  * is detected, it allocates a larger one and retries the operation.
571  * Because of this, a system error is not signaled here.
572  */
573 int
575 {
576  /*
577  * since this is normal behavior, don't set an error condition, the
578  * main transformer functions will need to test the status value
579  * for ER_TF_BUFFER_OVERFLOW and know that this isn't an error condition.
580  */
581 
582  if (buf->error_abort)
583  {
584  _longjmp (buf->env, ER_TF_BUFFER_OVERFLOW);
585  }
586 
587  return ER_TF_BUFFER_OVERFLOW;
588 }
589 
590 /*
591  * or_underflow - This is called by the or_get_ functions when there is
592  * not enough data in the buffer to extract a particular value.
593  * return: ER_TF_BUFFER_UNDERFLOW or long jump to buf->env
594  * buf(in): translation state structure
595  *
596  * Note:
597  * Unlike or_overflow this is NOT a common ocurrence and indicates a serious
598  * memory or disk corruption problem.
599  */
600 int
602 {
604 
605  if (buf->error_abort)
606  {
607  _longjmp (buf->env, ER_TF_BUFFER_UNDERFLOW);
608  }
609  return ER_TF_BUFFER_UNDERFLOW;
610 }
611 
612 /*
613  * or_abort - This is called if there was some fundemtal error
614  * return: void
615  * buf(in): translation state structure
616  *
617  * Note:
618  * An appropriate error message should have already been set.
619  */
620 void
622 {
623  /* assume an appropriate error has already been set */
624  if (buf->error_abort)
625  {
626  _longjmp (buf->env, er_errid ());
627  }
628 }
629 
630 /*
631  * or_init - initialize the field of an OR_BUF
632  * return: void
633  * buf(in/out): or buffer to initialize
634  * data(in): buffer data
635  * length(in): buffer data length
636  */
637 void
638 or_init (OR_BUF * buf, char *data, int length)
639 {
640  buf->buffer = data;
641  buf->ptr = data;
642 
643  if (length == 0 || length == -1 || length == DB_INT32_MAX)
644  {
645  buf->endptr = (char *) OR_INFINITE_POINTER;
646  }
647  else
648  {
649  buf->endptr = data + length;
650  }
651 
652  buf->error_abort = 0;
653  buf->fixups = NULL;
654 }
655 
656 /*
657  * or_put_align32 - pad zero bytes round up to 4 byte bound
658  * return: NO_ERROR or error code
659  * buf(in/out): or buffer
660  */
661 int
663 {
664  unsigned int bits;
665  int rc = NO_ERROR;
666 
667  bits = (UINTPTR) buf->ptr & 3;
668  if (bits)
669  {
670  rc = or_pad (buf, 4 - bits);
671  }
672 
673  return rc;
674 }
675 
676 /*
677  * or_get_align32 - adnvance or buf pointer to next 4 byte alignment position
678  * return: NO_ERROR or error code
679  * buf(in/out): or buffer
680  */
681 int
683 {
684  unsigned int bits;
685  int rc = NO_ERROR;
686 
687  bits = (UINTPTR) (buf->ptr) & 3;
688  if (bits)
689  {
690  rc = or_advance (buf, 4 - bits);
691  }
692 
693  return rc;
694 }
695 
696 /*
697  * or_get_align64 - adnvance or buf pointer to next 8 byte alignment position
698  * return: NO_ERROR or error code
699  * buf(in/out): or buffer
700  */
701 int
703 {
704  unsigned int bits;
705  int rc = NO_ERROR;
706 
707  bits = (UINTPTR) (buf->ptr) & 7;
708  if (bits)
709  {
710  rc = or_advance (buf, 8 - bits);
711  }
712 
713  return rc;
714 }
715 
716 /*
717  * or_get_align - adnvance or buf pointer to next alignment position
718  * return: NO_ERROR or error code
719  * buf(in/out): or buffer
720  * align(in):
721  */
722 int
724 {
725  char *ptr;
726 
727  ptr = PTR_ALIGN (buf->ptr, align);
728  if (ptr > buf->endptr)
729  {
730  return (or_overflow (buf));
731  }
732  else
733  {
734  buf->ptr = ptr;
735  return NO_ERROR;
736  }
737 }
738 
739 /*
740  * or_packed_varchar_length - returns length of place holder that can contain
741  * package varchar length. Also ajust length up to 4 byte boundary.
742  * return: length of placeholder that can contain packed varchar length
743  * charlen(in): varchar length
744  */
745 int
747 {
748  return or_varchar_length_internal (charlen, INT_ALIGNMENT);
749 }
750 
751 /*
752  * or_varchar_length - returns length of place holder that can contain
753  * package varchar length.
754  * return: length of place holder that can contain packed varchar length
755  * charlen(in): varchar length
756  */
757 int
758 or_varchar_length (int charlen)
759 {
760  return or_varchar_length_internal (charlen, CHAR_ALIGNMENT);
761 }
762 
763 int
765 {
766  return OR_INT_SIZE * 2 + or_packed_stream_length (length);
767 }
768 
769 static int
771 {
772  int len;
773 
775  {
776  len = OR_BYTE_SIZE + charlen;
777  }
778  else
779  {
780  /*
781  * Regarding the new encoding for VARCHAR and VARNCHAR, the strings stored in buffers have this representation:
782  * OR_BYTE_SIZE : First byte in encoding. If it's 0xFF, the string's length is greater than 255.
783  * : Otherwise, the first byte states the length of the string.
784  * 1st OR_INT_SIZE : string's compressed length
785  * 2nd OR_INT_SIZE : string's decompressed length
786  * charlen : string's disk length
787  */
788  len = OR_BYTE_SIZE + OR_INT_SIZE + OR_INT_SIZE + charlen;
789  }
790 
791  if (align == INT_ALIGNMENT)
792  {
793  /* size of NULL terminator */
794  len += OR_BYTE_SIZE;
795 
796  len = DB_ALIGN (len, INT_ALIGNMENT);
797  }
798 
799  return len;
800 }
801 
802 /*
803  * or_put_varchar - put varchar to or buffer
804  * return: NO_ERROR or error code
805  * buf(in/out): or buffer
806  * string(in): string to put into the or buffer
807  * charlen(in): string length
808  */
809 int
810 or_put_varchar (OR_BUF * buf, char *string, int charlen)
811 {
812  return or_put_varchar_internal (buf, string, charlen, CHAR_ALIGNMENT);
813 }
814 
815 /*
816  * or_packed_put_varchar - put varchar to or buffer
817  * return: NO_ERROR or error code
818  * buf(in/out): or buffer
819  * string(in): string to put into the or buffer
820  * charlen(in): string length
821  */
822 int
823 or_packed_put_varchar (OR_BUF * buf, char *string, int charlen)
824 {
825  return or_put_varchar_internal (buf, string, charlen, INT_ALIGNMENT);
826 }
827 
828 static int
829 or_put_varchar_internal (OR_BUF * buf, char *string, int charlen, int align)
830 {
831  int net_charlen = 0, compress_buffer_size;
832  char *compressed_string = NULL;
833  int rc = NO_ERROR;
834  bool compressable = false;
835  int compressed_length = 0;
836  int error_abort = 0;
837 
838  error_abort = buf->error_abort;
839 
840  buf->error_abort = 0;
841 
842  /* store the size prefix */
844  {
845  rc = or_put_byte (buf, charlen);
846  }
847  else
848  {
850  compressable = true;
851  }
852 
853  if (rc != NO_ERROR)
854  {
855  goto cleanup;
856  }
857 
858  if (compressable == true)
859  {
860  if (!pr_Enable_string_compression || charlen > LZ4_MAX_INPUT_SIZE) /* compression is not set */
861  {
862  compressed_length = 0;
863  goto after_compression;
864  }
865 
867 
868  /* Alloc memory for the compressed string */
869  compress_buffer_size = LZ4_compressBound (charlen);
870  compressed_string = (char *) malloc (compress_buffer_size);
871  if (compressed_string == NULL)
872  {
873  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (size_t) (compress_buffer_size));
875  goto cleanup;
876  }
877 
878  /* Compress the string */
879  compressed_length = LZ4_compress_default (string, compressed_string, charlen, compress_buffer_size);
880  if (compressed_length <= 0)
881  {
886  goto cleanup;
887  }
888  assert (compressed_length <= compress_buffer_size);
889 
890  if (compressed_length >= charlen - 8)
891  {
892  /* Compression successful but its length exceeds the original length of the string. */
893  compressed_length = 0;
894  }
895 
896  /* Store the compression size */
897  assert (compressed_length < charlen - 8);
898  after_compression:
899  OR_PUT_INT (&net_charlen, compressed_length);
900  rc = or_put_data (buf, (char *) &net_charlen, OR_INT_SIZE);
901  if (rc != NO_ERROR)
902  {
903  goto cleanup;
904  }
905 
906  net_charlen = 0;
907  /* Store the uncompressed data size */
908  OR_PUT_INT (&net_charlen, charlen);
909  rc = or_put_data (buf, (char *) &net_charlen, OR_INT_SIZE);
910  if (rc != NO_ERROR)
911  {
912  goto cleanup;
913  }
914 
915  if (compressed_length == 0)
916  {
917  /* Compression failed. */
918  /* Store the original string bytes */
919  rc = or_put_data (buf, string, charlen);
920  if (rc != NO_ERROR)
921  {
922  goto cleanup;
923  }
924  }
925  else
926  {
927  /* Store the compressed string bytes */
928  rc = or_put_data (buf, compressed_string, (int) compressed_length);
929  if (rc != NO_ERROR)
930  {
931  goto cleanup;
932  }
933  }
934  }
935  else
936  {
937  /* No compression needed */
938  /* Store the string in its raw form */
939  rc = or_put_data (buf, string, charlen);
940  if (rc != NO_ERROR)
941  {
942  goto cleanup;
943  }
944  }
945 
946  if (align == INT_ALIGNMENT)
947  {
948  /* kludge, temporary NULL terminator */
949  rc = or_put_byte (buf, 0);
950  if (rc != NO_ERROR)
951  {
952  goto cleanup;
953  }
954 
955  /* round up to a word boundary */
956  rc = or_put_align32 (buf);
957  }
958 
959 cleanup:
960 
961  if (compressed_string != NULL)
962  {
963  free_and_init (compressed_string);
964  }
965 
966  buf->error_abort = error_abort;
967 
968  if (rc == ER_TF_BUFFER_OVERFLOW)
969  {
970  return or_overflow (buf);
971  }
972 
973  return rc;
974 }
975 
976 #if defined(ENABLE_UNUSED_FUNCTION)
977 /*
978  * or_get_varchar - get varchar from or buffer
979  * return: varchar pointer read from the or buffer. or NULL for error
980  * buf(in/out): or buffer
981  * length_ptr(out): length of returned string
982  */
983 char *
984 or_get_varchar (OR_BUF * buf, int *length_ptr)
985 {
986  int rc = NO_ERROR;
987  int charlen;
988  char *new_;
989 
990  charlen = or_get_varchar_length (buf, &rc);
991 
992  if (rc != NO_ERROR)
993  {
994  return NULL;
995  }
996 
997  /* Allocate storage for the string including the kludge NULL terminator */
998  new_ = db_private_alloc (NULL, charlen + 1);
999 
1000  if (new_ == NULL)
1001  {
1002  or_abort (buf);
1003  return NULL;
1004  }
1005  rc = or_get_data (buf, new_, charlen + 1);
1006 
1007  if (rc == NO_ERROR)
1008  {
1009 
1010  /* return the length */
1011  if (length_ptr != NULL)
1012  {
1013  *length_ptr = charlen;
1014  }
1015 
1016  /* round up to a word boundary */
1017  rc = or_get_align32 (buf);
1018  }
1019  if (rc != NO_ERROR)
1020  {
1022  return NULL;
1023  }
1024  else
1025  {
1026  return new_;
1027  }
1028 }
1029 #endif /* ENABLE_UNUSED_FUNCTION */
1030 
1031 /*
1032  * or_get_varchar_length - get varchar length from or buffer
1033  * return: length of varchar or 0 if error.
1034  * buf(in/out): or buffer
1035  * rc(out): status code
1036  */
1037 int
1039 {
1040  int charlen, compressed_length = 0, decompressed_length = 0;
1041 
1042  *rc = or_get_varchar_compression_lengths (buf, &compressed_length, &decompressed_length);
1043 
1044  if (compressed_length > 0)
1045  {
1046  charlen = compressed_length;
1047  }
1048  else
1049  {
1050  charlen = decompressed_length;
1051  }
1052 
1053  return charlen;
1054 }
1055 
1056 /*
1057  * or_skip_varchar_remainder - skip varchar field of given length
1058  * return: NO_ERROR if successful, error code otherwise
1059  * buf(in/out): or buffer
1060  * charlen(in): length of varchar field to skip
1061  * align(in):
1062  */
1063 int
1064 or_skip_varchar_remainder (OR_BUF * buf, int charlen, int align)
1065 {
1066  int rc = NO_ERROR;
1067 
1068  if (align == INT_ALIGNMENT)
1069  {
1070  rc = or_advance (buf, charlen + 1);
1071  if (rc == NO_ERROR)
1072  {
1073  rc = or_get_align32 (buf);
1074  }
1075  }
1076  else
1077  {
1078  rc = or_advance (buf, charlen);
1079  }
1080 
1081  return rc;
1082 }
1083 
1084 /*
1085  * or_skip_varchar - skip varchar field (length + data) from or buffer
1086  * return: NO_ERROR or error code.
1087  * buf(in/out): or buffer
1088  * align(in):
1089  */
1090 int
1092 {
1093  int charlen, rc = NO_ERROR;
1094 
1095  charlen = or_get_varchar_length (buf, &rc);
1096 
1097  if (rc == NO_ERROR)
1098  {
1099  return (or_skip_varchar_remainder (buf, charlen, align));
1100  }
1101 
1102  return rc;
1103 }
1104 
1105 /*
1106  * or_packed_varbit_length - returns packed varbit length of or buffer encoding
1107  * return: packed varbit encoding length
1108  * bitlen(in): varbit length
1109  */
1110 int
1112 {
1113  return or_varbit_length_internal (bitlen, INT_ALIGNMENT);
1114 }
1115 
1116 /*
1117  * or_packed_varbit_length - returns packed varbit length of or buffer encoding
1118  * return: varbit encoding length
1119  * bitlen(in): varbit length
1120  */
1121 int
1122 or_varbit_length (int bitlen)
1123 {
1124  return or_varbit_length_internal (bitlen, CHAR_ALIGNMENT);
1125 }
1126 
1127 static int
1129 {
1130  int len;
1131 
1132  /* calculate size of length prefix */
1133  if (bitlen < 0xFF)
1134  {
1135  len = 1;
1136  }
1137  else
1138  {
1139  len = 1 + OR_INT_SIZE;
1140  }
1141 
1142  /* add in the string length in bytes */
1143  len += ((bitlen + 7) / 8);
1144 
1145  if (align == INT_ALIGNMENT)
1146  {
1147  /* round up to a word boundary */
1148  len = DB_ALIGN (len, INT_ALIGNMENT);
1149  }
1150  return len;
1151 }
1152 
1153 /*
1154  * or_put_varbit - put varbit into or buffer
1155  * return: NO_ERROR or error code
1156  * buf(in/out): or buffer
1157  * string(in): string contains varbit value
1158  * bitlen(in): length of varbit
1159  */
1160 int
1161 or_packed_put_varbit (OR_BUF * buf, const char *string, int bitlen)
1162 {
1163  return or_put_varbit_internal (buf, string, bitlen, INT_ALIGNMENT);
1164 }
1165 
1166 /*
1167  * or_put_varbit - put varbit into or buffer
1168  * return: NO_ERROR or error code
1169  * buf(in/out): or buffer
1170  * string(in): string contains varbit value
1171  * bitlen(in): length of varbit
1172  */
1173 int
1174 or_put_varbit (OR_BUF * buf, const char *string, int bitlen)
1175 {
1176  return or_put_varbit_internal (buf, string, bitlen, CHAR_ALIGNMENT);
1177 }
1178 
1179 static int
1180 or_put_varbit_internal (OR_BUF * buf, const char *string, int bitlen, int align)
1181 {
1182  int net_bitlen;
1183  int bytelen;
1184  char *start;
1185  int status;
1186  int valid_buf;
1187  jmp_buf save_buf;
1188 
1189  if (buf->error_abort)
1190  {
1191  memcpy (&save_buf, &buf->env, sizeof (save_buf));
1192  }
1193 
1194  valid_buf = buf->error_abort;
1195  buf->error_abort = 1;
1196  status = _setjmp (buf->env);
1197 
1198  if (status == 0)
1199  {
1200  start = buf->ptr;
1201  bytelen = BITS_TO_BYTES (bitlen);
1202 
1203  /* store the size prefix */
1204  if (bitlen < 0xFF)
1205  {
1206  or_put_byte (buf, bitlen);
1207  }
1208  else
1209  {
1210  or_put_byte (buf, 0xFF);
1211  OR_PUT_INT (&net_bitlen, bitlen);
1212  or_put_data (buf, (char *) &net_bitlen, OR_INT_SIZE);
1213  }
1214 
1215  /* store the string bytes */
1216  or_put_data (buf, string, bytelen);
1217 
1218  if (align == INT_ALIGNMENT)
1219  {
1220  /* round up to a word boundary */
1221  or_put_align32 (buf);
1222  }
1223  }
1224  else
1225  {
1226  if (valid_buf)
1227  {
1228  memcpy (&buf->env, &save_buf, sizeof (save_buf));
1229  _longjmp (buf->env, status);
1230  }
1231  }
1232 
1233  if (valid_buf)
1234  {
1235  memcpy (&buf->env, &save_buf, sizeof (save_buf));
1236  }
1237  else
1238  {
1239  buf->error_abort = 0;
1240  }
1241 
1242  if (status == 0)
1243  {
1244  return NO_ERROR;
1245  }
1246 
1247  return status;
1248 
1249 }
1250 
1251 int
1252 or_put_offset (OR_BUF * buf, int num)
1253 {
1254  return or_put_offset_internal (buf, num, BIG_VAR_OFFSET_SIZE);
1255 }
1256 
1257 int
1258 or_put_offset_internal (OR_BUF * buf, int num, int offset_size)
1259 {
1260  if (offset_size == OR_BYTE_SIZE)
1261  {
1262  return or_put_byte (buf, num);
1263  }
1264  else if (offset_size == OR_SHORT_SIZE)
1265  {
1266  return or_put_short (buf, num);
1267  }
1268  else
1269  {
1270  assert (offset_size == BIG_VAR_OFFSET_SIZE);
1271 
1272  return or_put_int (buf, num);
1273  }
1274 }
1275 
1276 int
1278 {
1279  return or_get_offset_internal (buf, error, BIG_VAR_OFFSET_SIZE);
1280 }
1281 
1282 int
1283 or_get_offset_internal (OR_BUF * buf, int *error, int offset_size)
1284 {
1285  if (offset_size == OR_BYTE_SIZE)
1286  {
1287  return or_get_byte (buf, error);
1288  }
1289  else if (offset_size == OR_SHORT_SIZE)
1290  {
1291  return or_get_short (buf, error);
1292  }
1293  else
1294  {
1295  assert (offset_size == BIG_VAR_OFFSET_SIZE);
1296  return or_get_int (buf, error);
1297  }
1298 }
1299 
1300 #if defined(ENABLE_UNUSED_FUNCTION)
1301 /*
1302  * or_get_varbit - get varbit from or buffer
1303  * return: NO_ERROR or error code
1304  * buf(in/out): or buffer
1305  * length_ptr(out): length of varbit read
1306  */
1307 char *
1308 or_get_varbit (OR_BUF * buf, int *length_ptr)
1309 {
1310  int bitlen, charlen;
1311  char *new_ = NULL;
1312  int rc = NO_ERROR;
1313 
1314  bitlen = or_get_varbit_length (buf, &rc);
1315 
1316  if (rc != NO_ERROR)
1317  {
1318  return NULL;
1319  }
1320 
1321  /* Allocate storage for the string including the kludge NULL terminator */
1322  charlen = BITS_TO_BYTES (bitlen);
1323  new_ = db_private_alloc (NULL, charlen + 1);
1324 
1325  if (new_ == NULL)
1326  {
1327  or_abort (buf);
1328  return NULL;
1329  }
1330  rc = or_get_data (buf, new_, charlen);
1331 
1332  if (rc == NO_ERROR)
1333  {
1334  /* return the length */
1335  if (length_ptr != NULL)
1336  {
1337  *length_ptr = bitlen;
1338  }
1339 
1340  /* round up to a word boundary */
1341  rc = or_get_align32 (buf);
1342  }
1343  if (rc != NO_ERROR)
1344  {
1345  if (new_)
1346  {
1348  }
1349  return NULL;
1350  }
1351 
1352  return new_;
1353 }
1354 #endif /* ENABLE_UNUSED_FUNCTION */
1355 
1356 /*
1357  * or_get_varbit_length - get varbit length from or buffer
1358  * return: length of varbit or 0 if error
1359  * buf(in/out): or buffer
1360  * rc(out): NO_ERROR or error code
1361  */
1362 int
1364 {
1365  int net_bitlen = 0, bitlen = 0;
1366 
1367  /* unpack the size prefix */
1368  bitlen = or_get_byte (buf, rc);
1369 
1370  if (*rc != NO_ERROR)
1371  {
1372  return bitlen;
1373  }
1374 
1375  if (bitlen == 0xFF)
1376  {
1377  *rc = or_get_data (buf, (char *) &net_bitlen, OR_INT_SIZE);
1378  bitlen = OR_GET_INT (&net_bitlen);
1379  }
1380  return bitlen;
1381 }
1382 
1383 /*
1384  * or_skip_varbit_remainder - skip varbit field of given length in or buffer
1385  * return: NO_ERROR or error code
1386  * buf(in/out): or buffer
1387  * bitlen(in): bitlen to skip
1388  * align(in):
1389  */
1390 int
1391 or_skip_varbit_remainder (OR_BUF * buf, int bitlen, int align)
1392 {
1393  int rc = NO_ERROR;
1394 
1395  rc = or_advance (buf, BITS_TO_BYTES (bitlen));
1396  if (rc == NO_ERROR && align == INT_ALIGNMENT)
1397  {
1398  rc = or_get_align32 (buf);
1399  }
1400  return rc;
1401 }
1402 
1403 /*
1404  * or_skip_varbit - skip varbit in or buffer
1405  * return: NO_ERROR or error code
1406  * buf(in/out): or buffer
1407  * align(in):
1408  */
1409 int
1411 {
1412  int bitlen;
1413  int rc = NO_ERROR;
1414 
1415  bitlen = or_get_varbit_length (buf, &rc);
1416  if (rc == NO_ERROR)
1417  {
1418  return (or_skip_varbit_remainder (buf, bitlen, align));
1419  }
1420  return rc;
1421 }
1422 
1423 /*
1424  * NUMERIC DATA TRANSFORMS
1425  * This set of functions handles the transformation of the
1426  * numeric types byte, short, integer, float, and double.
1427  *
1428  */
1429 
1430 
1431 /*
1432  * or_put_byte - put a byte to or buffer
1433  * return: NO_ERROR or error code
1434  * buf(out/out): or buffer
1435  * num(in): byte value
1436  */
1437 int
1438 or_put_byte (OR_BUF * buf, int num)
1439 {
1440  if ((buf->ptr + OR_BYTE_SIZE) > buf->endptr)
1441  {
1442  return (or_overflow (buf));
1443  }
1444  else
1445  {
1446  OR_PUT_BYTE (buf->ptr, num);
1447  buf->ptr += OR_BYTE_SIZE;
1448  }
1449  return NO_ERROR;
1450 }
1451 
1452 /*
1453  * or_get_byte - read a byte value from or buffer
1454  * return: byte value read
1455  * buf(in/out): or buffer
1456  * error(out): NO_ERROR or error code
1457  */
1458 int
1459 or_get_byte (OR_BUF * buf, int *error)
1460 {
1461  int value = 0;
1462 
1463  if ((buf->ptr + OR_BYTE_SIZE) > buf->endptr)
1464  {
1465  *error = or_underflow (buf);
1466  return 0;
1467  }
1468  else
1469  {
1470  value = OR_GET_BYTE (buf->ptr);
1471  buf->ptr += OR_BYTE_SIZE;
1472  *error = NO_ERROR;
1473  }
1474  return value;
1475 }
1476 
1477 /*
1478  * or_put_short - put a short value to or buffer
1479  * return: NO_ERROR or error code
1480  * buf(in/out): or buffer
1481  * num(in): short value to put
1482  */
1483 int
1484 or_put_short (OR_BUF * buf, int num)
1485 {
1487 
1488  if ((buf->ptr + OR_SHORT_SIZE) > buf->endptr)
1489  {
1490  return (or_overflow (buf));
1491  }
1492  else
1493  {
1494  OR_PUT_SHORT (buf->ptr, num);
1495  buf->ptr += OR_SHORT_SIZE;
1496  }
1497  return NO_ERROR;
1498 }
1499 
1500 /*
1501  * or_get_short - read a short value from or buffer
1502  * return: short value read
1503  * buf(in/out): or buffer
1504  * error(out): NO_ERROR or error code
1505  */
1506 int
1508 {
1509  int value = 0;
1510 
1512 
1513  if ((buf->ptr + OR_SHORT_SIZE) > buf->endptr)
1514  {
1515  *error = or_underflow (buf);
1516  return 0;
1517  }
1518  else
1519  {
1520  value = OR_GET_SHORT (buf->ptr);
1521  buf->ptr += OR_SHORT_SIZE;
1522  }
1523  *error = NO_ERROR;
1524  return value;
1525 }
1526 
1527 /*
1528  * or_put_int - put int value to or buffer
1529  * return: NO_ERROR or error code
1530  * buf(in/out): or buffer
1531  * num(in): int value to put
1532  */
1533 int
1534 or_put_int (OR_BUF * buf, int num)
1535 {
1536  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1537 
1538  if ((buf->ptr + OR_INT_SIZE) > buf->endptr)
1539  {
1540  return (or_overflow (buf));
1541  }
1542  else
1543  {
1544  OR_PUT_INT (buf->ptr, num);
1545  buf->ptr += OR_INT_SIZE;
1546  }
1547  return NO_ERROR;
1548 }
1549 
1550 /*
1551  * or_get_int - get int value from or buffer
1552  * return: int value read
1553  * buf(in/out): or buffer
1554  * error(out): NO_ERROR or error code
1555  */
1556 int
1557 or_get_int (OR_BUF * buf, int *error)
1558 {
1559  int value = 0;
1560 
1561  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1562 
1563  if ((buf->ptr + OR_INT_SIZE) > buf->endptr)
1564  {
1565  *error = or_underflow (buf);
1566  }
1567  else
1568  {
1569  value = OR_GET_INT (buf->ptr);
1570  buf->ptr += OR_INT_SIZE;
1571  *error = NO_ERROR;
1572  }
1573  return value;
1574 }
1575 
1576 /*
1577  * or_put_bigint - put bigint value to or buffer
1578  * return: NO_ERROR or error code
1579  * buf(in/out): or buffer
1580  * num(in): bigint value to put
1581  */
1582 int
1584 {
1585  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1586 
1587  if ((buf->ptr + OR_BIGINT_SIZE) > buf->endptr)
1588  {
1589  return (or_overflow (buf));
1590  }
1591  else
1592  {
1593  OR_PUT_BIGINT (buf->ptr, &num);
1594  buf->ptr += OR_BIGINT_SIZE;
1595  }
1596  return NO_ERROR;
1597 }
1598 
1599 /*
1600  * or_get_bigint - get bigint value from or buffer
1601  * return: bigint value read
1602  * buf(in/out): or buffer
1603  * error(out): NO_ERROR or error code
1604  */
1605 DB_BIGINT
1607 {
1608  DB_BIGINT value = 0;
1609 
1610  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1611 
1612  if ((buf->ptr + OR_BIGINT_SIZE) > buf->endptr)
1613  {
1614  *error = or_underflow (buf);
1615  }
1616  else
1617  {
1618  OR_GET_BIGINT (buf->ptr, &value);
1619  buf->ptr += OR_BIGINT_SIZE;
1620  *error = NO_ERROR;
1621  }
1622  return value;
1623 }
1624 
1625 /*
1626  * or_put_float - put a float value to or buffer
1627  * return: NO_ERROR or error code
1628  * buf(in/out): or buffer
1629  * fnum(in): float value to put
1630  */
1631 int
1632 or_put_float (OR_BUF * buf, float fnum)
1633 {
1635 
1636  if ((buf->ptr + OR_FLOAT_SIZE) > buf->endptr)
1637  {
1638  return (or_overflow (buf));
1639  }
1640  else
1641  {
1642  OR_PUT_FLOAT (buf->ptr, fnum);
1643  buf->ptr += OR_FLOAT_SIZE;
1644  }
1645  return NO_ERROR;
1646 }
1647 
1648 /*
1649  * or_get_float - read a float value from or buffer
1650  * return: float value read
1651  * buf(in/out): or buffer
1652  * error(out): NO_ERROR or error code
1653  */
1654 float
1656 {
1657  float value = 0.0;
1658 
1660 
1661  if ((buf->ptr + OR_FLOAT_SIZE) > buf->endptr)
1662  {
1663  *error = or_underflow (buf);
1664  }
1665  else
1666  {
1667  OR_GET_FLOAT (buf->ptr, &value);
1668  buf->ptr += OR_FLOAT_SIZE;
1669  *error = NO_ERROR;
1670  }
1671  return value;
1672 }
1673 
1674 /*
1675  * or_put_double - put a double value to or buffer
1676  * return: NO_ERROR or error code
1677  * buf(in/out): or buffer
1678  * dnum(in): double value to put
1679  */
1680 int
1681 or_put_double (OR_BUF * buf, double dnum)
1682 {
1683  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1684 
1685  if ((buf->ptr + OR_DOUBLE_SIZE) > buf->endptr)
1686  {
1687  return (or_overflow (buf));
1688  }
1689  else
1690  {
1691  OR_PUT_DOUBLE (buf->ptr, dnum);
1692  buf->ptr += OR_DOUBLE_SIZE;
1693  }
1694  return NO_ERROR;
1695 }
1696 
1697 /*
1698  * or_get_double - read a double value from or buffer
1699  * return: double value read
1700  * buf(in/out): or buffer
1701  * error(out): NO_ERROR or error code
1702  */
1703 double
1705 {
1706  double value = 0.0;
1707 
1708  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1709 
1710  if ((buf->ptr + OR_DOUBLE_SIZE) > buf->endptr)
1711  {
1712  *error = or_underflow (buf);
1713  }
1714  else
1715  {
1716  OR_GET_DOUBLE (buf->ptr, &value);
1717  buf->ptr += OR_DOUBLE_SIZE;
1718  *error = NO_ERROR;
1719  }
1720  return value;
1721 }
1722 
1723 /*
1724  * EXTENDED TYPE TRANSLATORS
1725  * This set of functions reads and writes the extended types time,
1726  * utime, date, and monetary.
1727  */
1728 
1729 /*
1730  * or_put_time - write a DB_TIME to or buffer
1731  * return: NO_ERROR or error code
1732  * buf(in/out): or buffer
1733  * timeval(in): time value to write
1734  */
1735 int
1736 or_put_time (OR_BUF * buf, DB_TIME * timeval)
1737 {
1738  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1739 
1740  if ((buf->ptr + OR_TIME_SIZE) > buf->endptr)
1741  {
1742  return (or_overflow (buf));
1743  }
1744  else
1745  {
1746  OR_PUT_TIME (buf->ptr, timeval);
1747  buf->ptr += OR_TIME_SIZE;
1748  }
1749  return NO_ERROR;
1750 }
1751 
1752 /*
1753  * or_get_time - read a DB_TIME from or buffer
1754  * return: NO_ERROR or error code
1755  * buf(in/out): or buffer
1756  * timeval(out): pointer to DB_TIME value
1757  */
1758 int
1759 or_get_time (OR_BUF * buf, DB_TIME * timeval)
1760 {
1761  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1762 
1763  if ((buf->ptr + OR_TIME_SIZE) > buf->endptr)
1764  {
1765  return or_underflow (buf);
1766  }
1767  else
1768  {
1769  OR_GET_TIME (buf->ptr, timeval);
1770  buf->ptr += OR_TIME_SIZE;
1771  }
1772  return NO_ERROR;
1773 }
1774 
1775 /*
1776  * or_put_utime - write a timestamp value to or buffer
1777  * return: NO_ERROR or error code
1778  * buf(in/out): or buffer
1779  * timeval(in): pointer to timestamp value
1780  */
1781 int
1782 or_put_utime (OR_BUF * buf, DB_UTIME * timeval)
1783 {
1784  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1785 
1786  if ((buf->ptr + OR_UTIME_SIZE) > buf->endptr)
1787  {
1788  return (or_overflow (buf));
1789  }
1790  else
1791  {
1792  OR_PUT_UTIME (buf->ptr, timeval);
1793  buf->ptr += OR_UTIME_SIZE;
1794  }
1795  return NO_ERROR;
1796 }
1797 
1798 /*
1799  * or_get_utime - read a timestamp value from or buffer
1800  * return: NO_ERROR or error code
1801  * buf(in/out): or buffer
1802  * timeval(out): pointer to timestamp value
1803  */
1804 int
1805 or_get_utime (OR_BUF * buf, DB_UTIME * timeval)
1806 {
1807  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1808 
1809  if ((buf->ptr + OR_UTIME_SIZE) > buf->endptr)
1810  {
1811  return or_underflow (buf);
1812  }
1813  else
1814  {
1815  OR_GET_UTIME (buf->ptr, timeval);
1816  buf->ptr += OR_UTIME_SIZE;
1817  }
1818  return NO_ERROR;
1819 }
1820 
1821 /*
1822  * or_put_timestamptz - write a timestamp with tz value to or buffer
1823  * return: NO_ERROR or error code
1824  * buf(in/out): or buffer
1825  * ts_tz(in): pointer to DB_TIMESTAMPTZ value
1826  */
1827 int
1829 {
1830  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1831 
1832  if ((buf->ptr + OR_TIMESTAMPTZ_SIZE) > buf->endptr)
1833  {
1834  return (or_overflow (buf));
1835  }
1836  else
1837  {
1838  OR_PUT_TIMESTAMPTZ (buf->ptr, ts_tz);
1839  buf->ptr += OR_TIMESTAMPTZ_SIZE;
1840  }
1841  return NO_ERROR;
1842 }
1843 
1844 /*
1845  * or_get_timestamptz - read a timestamp with tz value from or buffer
1846  * return: NO_ERROR or error code
1847  * buf(in/out): or buffer
1848  * ts_tz(out): pointer to DB_TIMESTAMPTZ value
1849  */
1850 int
1852 {
1853  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1854 
1855  if ((buf->ptr + OR_TIMESTAMPTZ_SIZE) > buf->endptr)
1856  {
1857  return or_underflow (buf);
1858  }
1859  else
1860  {
1861  OR_GET_TIMESTAMPTZ (buf->ptr, ts_tz);
1862  buf->ptr += OR_TIMESTAMPTZ_SIZE;
1863  }
1864  return NO_ERROR;
1865 }
1866 
1867 /*
1868  * or_put_date - write a DB_DATE value to or_buffer
1869  * return: NO_ERROR or error code
1870  * buf(in/out): or buffer
1871  * date(in): pointer to DB_DATE value
1872  */
1873 int
1874 or_put_date (OR_BUF * buf, DB_DATE * date)
1875 {
1876  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1877 
1878  if ((buf->ptr + OR_DATE_SIZE) > buf->endptr)
1879  {
1880  return (or_overflow (buf));
1881  }
1882  else
1883  {
1884  OR_PUT_DATE (buf->ptr, date);
1885  buf->ptr += OR_DATE_SIZE;
1886  }
1887  return NO_ERROR;
1888 }
1889 
1890 /*
1891  * or_get_date - read a DB_DATE value from or_buffer
1892  * return: NO_ERROR or error code
1893  * buf(in/out): or buffer
1894  * date(out): pointer to DB_DATE value
1895  */
1896 int
1897 or_get_date (OR_BUF * buf, DB_DATE * date)
1898 {
1899  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1900 
1901  if ((buf->ptr + OR_DATE_SIZE) > buf->endptr)
1902  {
1903  return or_underflow (buf);
1904  }
1905  else
1906  {
1907  OR_GET_DATE (buf->ptr, date);
1908  buf->ptr += OR_DATE_SIZE;
1909  }
1910  return NO_ERROR;
1911 }
1912 
1913 /*
1914  * or_put_datetime - write a datetime value to or buffer
1915  * return: NO_ERROR or error code
1916  * buf(in/out): or buffer
1917  * datetimeval(in): pointer to datetime value
1918  */
1919 int
1920 or_put_datetime (OR_BUF * buf, DB_DATETIME * datetimeval)
1921 {
1922  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1923 
1924  if ((buf->ptr + OR_DATETIME_SIZE) > buf->endptr)
1925  {
1926  return (or_overflow (buf));
1927  }
1928  else
1929  {
1930  OR_PUT_DATETIME (buf->ptr, datetimeval);
1931  buf->ptr += OR_DATETIME_SIZE;
1932  }
1933  return NO_ERROR;
1934 }
1935 
1936 /*
1937  * or_get_datetime - read a DB_DATETIME value from or_buffer
1938  * return: NO_ERROR or error code
1939  * buf(in/out): or buffer
1940  * date(out): pointer to DB_DATETIME value
1941  */
1942 int
1944 {
1945  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1946 
1947  if ((buf->ptr + OR_DATETIME_SIZE) > buf->endptr)
1948  {
1949  return or_underflow (buf);
1950  }
1951  else
1952  {
1953  OR_GET_DATETIME (buf->ptr, datetime);
1954  buf->ptr += OR_DATETIME_SIZE;
1955  }
1956  return NO_ERROR;
1957 }
1958 
1959 /*
1960  * or_put_datetimetz - write a datetime with tz value to or buffer
1961  * return: NO_ERROR or error code
1962  * buf(in/out): or buffer
1963  * datetimetz(in): pointer to DB_DATETIMETZ value
1964  */
1965 int
1967 {
1968  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1969 
1970  if ((buf->ptr + OR_DATETIMETZ_SIZE) > buf->endptr)
1971  {
1972  return (or_overflow (buf));
1973  }
1974  else
1975  {
1976  OR_PUT_DATETIMETZ (buf->ptr, datetimetz);
1977  buf->ptr += OR_DATETIMETZ_SIZE;
1978  }
1979  return NO_ERROR;
1980 }
1981 
1982 /*
1983  * or_get_datetimetz - read a datetime with tz value from or_buffer
1984  * return: NO_ERROR or error code
1985  * buf(in/out): or buffer
1986  * datetimetz(out): pointer to DB_DATETIMETZ value
1987  */
1988 int
1990 {
1991  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
1992 
1993  if ((buf->ptr + OR_DATETIMETZ_SIZE) > buf->endptr)
1994  {
1995  return or_underflow (buf);
1996  }
1997  else
1998  {
1999  OR_GET_DATETIMETZ (buf->ptr, datetimetz);
2000  buf->ptr += OR_DATETIMETZ_SIZE;
2001  }
2002  return NO_ERROR;
2003 }
2004 
2005 /*
2006  * or_put_monetary - write a DB_MONETARY value to or buffer
2007  * return: NO_ERROR or error code
2008  * buf(in/out): or buffer
2009  * monetary(in): pointer to DB_MONETARY value
2010  */
2011 int
2013 {
2014  int error;
2015 
2016  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
2017 
2018  /* check for valid currency type don't put default case in the switch!!! */
2019  error = ER_INVALID_CURRENCY_TYPE;
2020  switch (monetary->type)
2021  {
2022  case DB_CURRENCY_DOLLAR:
2023  case DB_CURRENCY_YEN:
2024  case DB_CURRENCY_WON:
2025  case DB_CURRENCY_TL:
2035  case DB_CURRENCY_EURO:
2046  error = NO_ERROR; /* it's a type we expect */
2047  break;
2048  default:
2049  break;
2050  }
2051 
2052  if (error != NO_ERROR)
2053  {
2054  er_set (ER_WARNING_SEVERITY, ARG_FILE_LINE, error, 1, monetary->type);
2055  return error;
2056  }
2057 
2058  if ((buf->ptr + OR_MONETARY_SIZE) > buf->endptr)
2059  {
2060  return (or_overflow (buf));
2061  }
2062  else
2063  {
2064  OR_PUT_MONETARY (buf->ptr, monetary);
2065  buf->ptr += OR_MONETARY_SIZE;
2066  }
2067 
2068  return error;
2069 }
2070 
2071 /*
2072  * or_get_monetary - read a DB_MONETARY from or buffer
2073  * return: NO_ERROR or error code
2074  * buf(in/out): or buffer
2075  * monetary(out): pointer to DB_MONETARY value
2076  */
2077 int
2079 {
2080  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
2081 
2082  if ((buf->ptr + OR_MONETARY_SIZE) > buf->endptr)
2083  {
2084  return or_underflow (buf);
2085  }
2086  else
2087  {
2088  OR_GET_MONETARY (buf->ptr, monetary);
2089  buf->ptr += OR_MONETARY_SIZE;
2090  }
2091  return NO_ERROR;
2092 }
2093 
2094 /*
2095  * or_put_oid - write content of an OID structure from or buffer
2096  * return: NO_ERROR or error code
2097  * buf(in/out): or buffer
2098  * oid(in): pointer to OID
2099  */
2100 int
2101 or_put_oid (OR_BUF * buf, const OID * oid)
2102 {
2103  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
2104 
2105  if ((buf->ptr + OR_OID_SIZE) > buf->endptr)
2106  {
2107  return (or_overflow (buf));
2108  }
2109  else
2110  {
2111  if (oid == NULL)
2112  {
2113  OR_PUT_NULL_OID (buf->ptr);
2114  }
2115  else
2116  {
2117  /* Cannot allow any temp oid's to be written */
2118  if (OID_ISTEMP (oid))
2119  {
2121  or_abort (buf);
2122  }
2123  OR_PUT_OID (buf->ptr, oid);
2124  }
2125  buf->ptr += OR_OID_SIZE;
2126  }
2127  return NO_ERROR;
2128 }
2129 
2130 /*
2131  * or_get_oid - read content of an OID structure from or buffer
2132  * return: NO_ERROR or error code
2133  * buf(in/out): or buffer
2134  * oid(out): pointer to OID
2135  */
2136 int
2137 or_get_oid (OR_BUF * buf, OID * oid)
2138 {
2139  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
2140 
2141  if ((buf->ptr + OR_OID_SIZE) > buf->endptr)
2142  {
2143  return or_underflow (buf);
2144  }
2145  else
2146  {
2147  OR_GET_OID (buf->ptr, oid);
2148  buf->ptr += OR_OID_SIZE;
2149  }
2150  return NO_ERROR;
2151 }
2152 
2153 /*
2154  * or_put_data - write an array of bytes to or buffer
2155  * return: NO_ERROR or error code
2156  * buf(in/out): or buffer
2157  * data(in): pointer to data
2158  * length(in): length in bytes
2159  */
2160 int
2161 or_put_data (OR_BUF * buf, const char *data, int length)
2162 {
2163  if ((buf->ptr + length) > buf->endptr)
2164  {
2165  return (or_overflow (buf));
2166  }
2167  else
2168  {
2169  (void) memcpy (buf->ptr, data, length);
2170  buf->ptr += length;
2171  }
2172  return NO_ERROR;
2173 }
2174 
2175 /*
2176  * or_get_data - read an array of bytes from or buffer for given length
2177  * return: NO_ERROR or error code
2178  * buf(in/out): or buffer
2179  * data(in): pointer to buffer to read data into
2180  * length(in): length of read data
2181  */
2182 int
2183 or_get_data (OR_BUF * buf, char *data, int length)
2184 {
2185  if ((buf->ptr + length) > buf->endptr)
2186  {
2187  return or_underflow (buf);
2188  }
2189  else
2190  {
2191  (void) memcpy (data, buf->ptr, length);
2192  buf->ptr += length;
2193  }
2194  return NO_ERROR;
2195 }
2196 
2197 /*
2198  * or_put_string - write string to or buf
2199  * return: NO_ERROR or error code
2200  * buf(in/out): or buffer
2201  * str(in): string to write
2202  *
2203  * Note:
2204  * Does byte padding on strings to bring them up to 4 byte boundary.
2205  *
2206  * There is no or_get_string since this is the same as or_get_data.
2207  * Since the workspace allocator (and most other Unix allocators) will
2208  * keep track of the size of allocated blocks (and they will be
2209  * in word multiples anyway), we can just include the disk padding
2210  * bytes with the string when it is brought in from disk even though
2211  * the total length may be more than that returned by strlen.
2212  */
2213 int
2214 or_put_string_aligned (OR_BUF * buf, char *str)
2215 {
2216  int len, bits, pad;
2217  int rc = NO_ERROR;
2218 
2219  if (str == NULL)
2220  {
2221  return rc;
2222  }
2223  len = strlen (str) + 1;
2224  rc = or_put_data (buf, str, len);
2225  if (rc == NO_ERROR)
2226  {
2227  /* PAD */
2228  bits = len & 3;
2229  if (bits)
2230  {
2231  pad = 4 - bits;
2232  rc = or_pad (buf, pad);
2233  }
2234  }
2235  return rc;
2236 }
2237 
2238 #if defined(ENABLE_UNUSED_FUNCTION)
2239 /*
2240  * or_length_string - returns the number of bytes required to hold the disk
2241  * representation of a string
2242  * return: number of bytes needed or 0 for error
2243  * string(in): string for calculation
2244  *
2245  * Note:
2246  * This will include any padding bytes up to 4 byte boundary
2247  */
2248 int
2249 or_length_string (char *string)
2250 {
2251  int len, bits;
2252 
2253  len = 0;
2254  if (string != NULL)
2255  {
2256  len = strlen (string) + 1;
2257  bits = len & 3;
2258  if (bits)
2259  {
2260  len += 4 - bits;
2261  }
2262  }
2263  return len;
2264 }
2265 
2266 /*
2267  * or_put_binary - Writes a binary array into the translation buffer.
2268  * return: NO_ERROR or error code
2269  * buf(in/out): or buffer
2270  * binary(in): binary data
2271  *
2272  * Note:
2273  * The length of the array is part of the binary data descriptor.
2274  * This is similar to or_put_string in that it also must pad out the
2275  * binary data to be on a word boundary.
2276  */
2277 int
2278 or_put_binary (OR_BUF * buf, DB_BINARY * binary)
2279 {
2280  int header, len, bits, pad;
2281  int rc = NO_ERROR;
2282 
2283  if (binary != NULL && binary->length < OR_BINARY_MAX_LENGTH)
2284  {
2285  len = binary->length + OR_INT_SIZE;
2286  pad = 0;
2287  bits = len & 3;
2288  if (bits)
2289  {
2290  pad = 4 - bits;
2291  }
2292  header = binary->length | (pad << OR_BINARY_PAD_SHIFT);
2293  rc = or_put_int (buf, header);
2294  if (rc == NO_ERROR)
2295  {
2296  rc = or_put_data (buf, (char *) binary->data, binary->length);
2297  if (rc == NO_ERROR)
2298  {
2299  rc = or_pad (buf, pad);
2300  }
2301  }
2302  }
2303  return rc;
2304 }
2305 
2306 /*
2307  * or_length_binary - Calculates the number of bytes required for the disk
2308  * representaion of binary data.
2309  * return: bytes required or 0 for error
2310  * binary(in): binary data
2311  *
2312  * Note:
2313  * Included in this number are any padding bytes required to bring the data
2314  * up to a word boundary.
2315  */
2316 int
2317 or_length_binary (DB_BINARY * binary)
2318 {
2319  int len, bits;
2320 
2321  len = 0;
2322  if (binary != NULL && binary->length < OR_BINARY_MAX_LENGTH)
2323  {
2324  len = binary->length + OR_INT_SIZE; /* always a header word for sizes */
2325  bits = len & 3;
2326  if (bits)
2327  {
2328  len += 4 - bits;
2329  }
2330  }
2331  return len;
2332 }
2333 #endif /* ENABLE_UNUSED_FUNCTION */
2334 
2335 /*
2336  * or_pad - This advances the translation pointer and adds bytes of zero.
2337  * return: NO_ERROR or error code
2338  * buf(in/out): or buffer
2339  * length(in): number of bytes to pad
2340  *
2341  * Note:
2342  * This advances the translation pointer and adds bytes of zero.
2343  * This is used add padding bytes to ensure proper alignment of
2344  * some data types.
2345  */
2346 int
2347 or_pad (OR_BUF * buf, int length)
2348 {
2349  if ((buf->ptr + length) > buf->endptr)
2350  {
2351  return (or_overflow (buf));
2352  }
2353  else
2354  {
2355  (void) memset (buf->ptr, 0, length);
2356  buf->ptr += length;
2357  }
2358  return NO_ERROR;
2359 }
2360 
2361 /*
2362  * or_advance - This advances the translation pointer
2363  * return: NO_ERROR or error code
2364  * buf(in/out): or buffer
2365  * offset(in): number of bytes to skip
2366  */
2367 int
2368 or_advance (OR_BUF * buf, int offset)
2369 {
2370  if ((buf->ptr + offset) > buf->endptr)
2371  {
2372  return (or_overflow (buf));
2373  }
2374  else
2375  {
2376  buf->ptr += offset;
2377  return NO_ERROR;
2378  }
2379 }
2380 
2381 /*
2382  * or_seek - This sets the translation pointer directly to a certain byte in
2383  * the buffer.
2384  * return: ERROR_SUCCESS or error code
2385  * buf(in/out): or buffer
2386  * psn(in): position within buffer
2387  */
2388 int
2389 or_seek (OR_BUF * buf, int psn)
2390 {
2391  if ((buf->buffer + psn) > buf->endptr)
2392  {
2393  return (or_overflow (buf));
2394  }
2395  else
2396  {
2397  buf->ptr = buf->buffer + psn;
2398  }
2399  return NO_ERROR;
2400 }
2401 
2402 /*
2403  * or_align () - Align current buffer pointer to given alignment.
2404  *
2405  * return : Error code.
2406  * buf (in/out) : Buffer.
2407  * alignment (in) : Desired alignment.
2408  */
2409 int
2410 or_align (OR_BUF * buf, int alignment)
2411 {
2412  char *new_ptr = PTR_ALIGN (buf->ptr, alignment);
2413  if (new_ptr > buf->endptr)
2414  {
2415  return (or_overflow (buf));
2416  }
2417  buf->ptr = new_ptr;
2418  return NO_ERROR;
2419 }
2420 
2421 /*
2422  * or_unpack_var_table - Extracts a variable offset table from the disk
2423  * representation of an object and converts it into a memory structure
2424  * return: advanced buffer pointer
2425  * ptr(in): pointer into a disk representation
2426  * nvars(in): number of variables expected
2427  * vars(out): array of var table info
2428  *
2429  * Note:
2430  * This is a little easier than dealing with the offset table in its raw
2431  * disk format. It assumes that you know the number of elements
2432  * in the table and have previously allocated an array of OR_VARINFO
2433  * structures that will be filled in.
2434  */
2435 char *
2436 or_unpack_var_table (char *ptr, int nvars, OR_VARINFO * vars)
2437 {
2438  return or_unpack_var_table_internal (ptr, nvars, vars, BIG_VAR_OFFSET_SIZE);
2439 }
2440 
2441 /*
2442  * or_unpack_var_table_internal - Extracts a variable offset table from the disk
2443  * representation of an object and converts it into a memory structure
2444  * return: advanced buffer pointer
2445  * ptr(in): pointer into a disk representation
2446  * nvars(in): number of variables expected
2447  * vars(out): array of var table info
2448  *
2449  * Note:
2450  * This is a little easier than dealing with the offset table in its raw
2451  * disk format. It assumes that you know the number of elements
2452  * in the table and have previously allocated an array of OR_VARINFO
2453  * structures that will be filled in.
2454  */
2455 static char *
2456 or_unpack_var_table_internal (char *ptr, int nvars, OR_VARINFO * vars, int offset_size)
2457 {
2458  int i, offset, offset2;
2459 
2460  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2461 
2462  if (nvars)
2463  {
2464  offset = OR_GET_OFFSET_INTERNAL (ptr, offset_size);
2465  ptr += offset_size;
2466 
2467  for (i = 0; i < nvars; i++)
2468  {
2469  offset2 = OR_GET_OFFSET_INTERNAL (ptr, offset_size);
2470  ptr += offset_size;
2471  vars[i].offset = offset;
2472  vars[i].length = offset2 - offset;
2473  offset = offset2;
2474  }
2475  ptr = PTR_ALIGN (ptr, INT_ALIGNMENT);
2476  }
2477  return ptr;
2478 }
2479 
2480 /*
2481  * or_get_var_table - Extracts an array of OR_VARINFO structures from a
2482  * disk variable offset table
2483  * return: array of OR_VARINFO structures
2484  * buf(in/out): or buffer
2485  * nvars(in): expected number of variables
2486  * allocator(in): allocator for return value allocation
2487  */
2488 OR_VARINFO *
2489 or_get_var_table (OR_BUF * buf, int nvars, char *(*allocator) (int))
2490 {
2491  return or_get_var_table_internal (buf, nvars, allocator, BIG_VAR_OFFSET_SIZE);
2492 }
2493 
2494 /*
2495  * or_get_var_table_internal - Extracts an array of OR_VARINFO structures from a
2496  * disk variable offset table
2497  * return: array of OR_VARINFO structures
2498  * buf(in/out): or buffer
2499  * nvars(in): expected number of variables
2500  * allocator(in): allocator for return value allocation
2501  */
2502 OR_VARINFO *
2503 or_get_var_table_internal (OR_BUF * buf, int nvars, char *(*allocator) (int), int offset_size)
2504 {
2505  OR_VARINFO *vars;
2506  int length;
2507 
2508  vars = NULL;
2509 
2510  if (!nvars)
2511  {
2512  return vars;
2513  }
2514 
2515  length = DB_ALIGN (offset_size * (nvars + 1), INT_ALIGNMENT);
2516 
2517  if ((buf->ptr + length) > buf->endptr)
2518  {
2519  or_underflow (buf);
2520  }
2521  else
2522  {
2523  vars = (OR_VARINFO *) (*allocator) (sizeof (OR_VARINFO) * nvars);
2524  if (vars == NULL && nvars)
2525  {
2526  or_abort (buf);
2527  }
2528  else
2529  {
2530  (void) or_unpack_var_table_internal (buf->ptr, nvars, vars, offset_size);
2531  }
2532  buf->ptr += length;
2533  }
2534  return vars;
2535 }
2536 
2537 /*
2538  * COMMUNICATION BUFFER PACK/UNPACK FUNCTIONS
2539  */
2540 
2541 
2542 /*
2543  * NUMERIC DATA TYPE TRANSLATORS
2544  * Translators for the numeric data types int, short, errcode, lock...
2545  */
2546 
2547 /*
2548  * or_pack_int - write int value to ptr
2549  * return: advanced buffer pointer
2550  * ptr(out): out buffer
2551  * number(in): int value
2552  */
2553 char *
2554 or_pack_int (char *ptr, int number)
2555 {
2556  if (ptr == NULL)
2557  {
2558  return NULL;
2559  }
2560 
2561  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2562 
2563  OR_PUT_INT (ptr, number);
2564  return (ptr + OR_INT_SIZE);
2565 }
2566 
2567 /*
2568  * or_unpack_int - read a int value
2569  * return: advanced buffer pointer
2570  * ptr(in): input buffer
2571  * number(out): int value
2572  */
2573 char *
2574 or_unpack_int (char *ptr, int *number)
2575 {
2576  if (ptr == NULL)
2577  {
2578  *number = 0;
2579  return NULL;
2580  }
2581 
2582  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2583 
2584  *number = OR_GET_INT (ptr);
2585  return (ptr + OR_INT_SIZE);
2586 }
2587 
2588 #if defined(ENABLE_UNUSED_FUNCTION)
2589 /*
2590  * or_pack_bigint - write bigint value to ptr
2591  * return: advanced buffer pointer
2592  * ptr(out): out buffer
2593  * number(in): bigint value
2594  */
2595 char *
2596 or_pack_bigint (char *ptr, DB_BIGINT number)
2597 {
2598  return or_pack_int64 (ptr, number);
2599 }
2600 
2601 /*
2602  * or_unpack_bigint - read a bigint value
2603  * return: advanced buffer pointer
2604  * ptr(in): input buffer
2605  * number(out): bigint value
2606  */
2607 char *
2608 or_unpack_bigint (char *ptr, DB_BIGINT * number)
2609 {
2610  return or_unpack_int64 (ptr, number);
2611 }
2612 #endif
2613 
2614 /*
2615  * or_pack_int64 - write INT64 value to ptr
2616  * return: advanced buffer pointer
2617  * ptr(out): out buffer
2618  * number(in): INT64 value
2619  */
2620 char *
2621 or_pack_int64 (char *ptr, INT64 number)
2622 {
2623  ptr = PTR_ALIGN (ptr, MAX_ALIGNMENT);
2624 
2625  OR_PUT_INT64 (ptr, &number);
2626  return (ptr + OR_INT64_SIZE);
2627 }
2628 
2629 /*
2630  * or_unpack_int64 - read a INT64 value
2631  * return: advanced buffer pointer
2632  * ptr(in): input buffer
2633  * number(out): INT64 value
2634  */
2635 char *
2636 or_unpack_int64 (char *ptr, INT64 * number)
2637 {
2638  ptr = PTR_ALIGN (ptr, MAX_ALIGNMENT);
2639 
2640  OR_GET_INT64 (ptr, number);
2641  return (ptr + OR_INT64_SIZE);
2642 }
2643 
2644 
2645 /*
2646  * or_pack_short - write a short value
2647  * return: advanced buffer pointer
2648  * ptr(out): output buffer
2649  * number(in): short value
2650  */
2651 char *
2652 or_pack_short (char *ptr, short number)
2653 {
2654  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2655 
2656  OR_PUT_INT (ptr, (int) number);
2657  return (ptr + OR_INT_SIZE);
2658 }
2659 
2660 /*
2661  * or_unpack_short - read a short value
2662  * return: advanced buffer pointer
2663  * ptr(in): input buffer
2664  * number(out): short value
2665  */
2666 char *
2667 or_unpack_short (char *ptr, short *number)
2668 {
2669  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2670 
2671  *number = (short) OR_GET_INT (ptr);
2672  return (ptr + OR_INT_SIZE);
2673 }
2674 
2675 /*
2676  * or_pack_errcode - write a errcode value
2677  * return: advanced buffer pointer
2678  * ptr(out): output buffer
2679  * error(in): int value
2680  */
2681 char *
2682 or_pack_errcode (char *ptr, int error)
2683 {
2684  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2685 
2686  OR_PUT_INT (ptr, (int) error);
2687  return (ptr + OR_INT_SIZE);
2688 }
2689 
2690 /*
2691  * or_unpack_errcode - read a errcode value
2692  * return: advanced buffer pointer
2693  * ptr(in): input buffer
2694  * error(out): int value
2695  */
2696 char *
2697 or_unpack_errcode (char *ptr, int *error)
2698 {
2699  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2700 
2701  *error = (int) OR_GET_INT (ptr);
2702  return (ptr + OR_INT_SIZE);
2703 }
2704 
2705 
2706 /*
2707  * or_pack_lock - write a LOCK value
2708  * return: advanced buffer pointer
2709  * ptr(out): output buffer
2710  * lock(in): LOCK value
2711  */
2712 char *
2713 or_pack_lock (char *ptr, LOCK lock)
2714 {
2715  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2716 
2717  OR_PUT_INT (ptr, (int) lock);
2718  return (ptr + OR_INT_SIZE);
2719 }
2720 
2721 /*
2722  * or_unpack_lock - read a LOCK value
2723  * return: advanced buffer pointer
2724  * ptr(in): input buffer
2725  * lock(out): LOCK value
2726  */
2727 char *
2728 or_unpack_lock (char *ptr, LOCK * lock)
2729 {
2730  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2731 
2732  *lock = (LOCK) OR_GET_INT (ptr);
2733  return (ptr + OR_INT_SIZE);
2734 }
2735 
2736 /*
2737  * or_pack_float - write a float value
2738  * return: advanced buffer pointer
2739  * ptr(out): output buffer
2740  * number(in): float value
2741  */
2742 char *
2743 or_pack_float (char *ptr, float number)
2744 {
2746 
2747  OR_PUT_FLOAT (ptr, number);
2748  return (ptr + OR_FLOAT_SIZE);
2749 }
2750 
2751 /*
2752  * or_unpack_float - read a float value
2753  * return: advanced buffer pointer
2754  * ptr(in): read buffer
2755  * number(out): float value
2756  */
2757 char *
2758 or_unpack_float (char *ptr, float *number)
2759 {
2761 
2762  OR_GET_FLOAT (ptr, number);
2763  return (ptr + OR_FLOAT_SIZE);
2764 }
2765 
2766 
2767 /*
2768  * or_pack_double - write a double value
2769  * return: advanced buffer pointer
2770  * ptr(out): output buffer
2771  * number(in): double value
2772  */
2773 char *
2774 or_pack_double (char *ptr, double number)
2775 {
2776  ptr = PTR_ALIGN (ptr, MAX_ALIGNMENT);
2777 
2778  OR_PUT_DOUBLE (ptr, number);
2779  return (ptr + OR_DOUBLE_SIZE);
2780 }
2781 
2782 /*
2783  * or_unpack_double - read a double value
2784  * return: advanced buffer pointer
2785  * ptr(in): input buffer
2786  * number(out): double value
2787  */
2788 char *
2789 or_unpack_double (char *ptr, double *number)
2790 {
2791  ptr = PTR_ALIGN (ptr, MAX_ALIGNMENT);
2792 
2793  OR_GET_DOUBLE (ptr, number);
2794  return (ptr + OR_DOUBLE_SIZE);
2795 }
2796 
2797 #if defined(ENABLE_UNUSED_FUNCTION)
2798 /*
2799  * or_pack_time - write a DB_TIME value
2800  * return: advanced buffer pointer
2801  * ptr(out): output buffer
2802  * time(in): DB_TIME value
2803  */
2804 char *
2805 or_pack_time (char *ptr, DB_TIME time)
2806 {
2807  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2808 
2809  OR_PUT_TIME (ptr, &time);
2810  return (ptr + OR_TIME_SIZE);
2811 }
2812 
2813 /*
2814  * or_unpack_time - read a DB_TIME value
2815  * return: advanced buffer pointer
2816  * ptr(in): input buffer
2817  * time(out): DB_TIME value
2818  */
2819 char *
2820 or_unpack_time (char *ptr, DB_TIME * time)
2821 {
2822  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2823 
2824  OR_GET_TIME (ptr, time);
2825  return (ptr + OR_TIME_SIZE);
2826 }
2827 
2828 /*
2829  * or_pack_utime - write a DB_UTIME value
2830  * return: advanced buffer pointer
2831  * ptr(out): output buffer
2832  * utime(in): DB_UTIME value
2833  */
2834 char *
2835 or_pack_utime (char *ptr, DB_UTIME utime)
2836 {
2837  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2838 
2839  OR_PUT_UTIME (ptr, &utime);
2840  return (ptr + OR_UTIME_SIZE);
2841 }
2842 
2843 /*
2844  * or_unpack_utime - read a DB_UTIME value
2845  * return: advanced buffer pointer
2846  * ptr(in): input buffer
2847  * utime(out): DB_UTIME value
2848  */
2849 char *
2850 or_unpack_utime (char *ptr, DB_UTIME * utime)
2851 {
2852  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2853 
2854  OR_GET_UTIME (ptr, utime);
2855  return (ptr + OR_UTIME_SIZE);
2856 }
2857 
2858 /*
2859  * or_pack_date - write a DB_DATE value
2860  * return: advanced buffer pointer
2861  * ptr(out): output buffer
2862  * date(in): DB_DATE value
2863  */
2864 char *
2865 or_pack_date (char *ptr, DB_DATE date)
2866 {
2867  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2868 
2869  OR_PUT_DATE (ptr, &date);
2870  return (ptr + OR_DATE_SIZE);
2871 }
2872 
2873 /*
2874  * or_unpack_date - read a DB_DATE value
2875  * return: advanced buffer pointer
2876  * ptr(in): input buffer
2877  * date(out): DB_DATE value
2878  */
2879 char *
2880 or_unpack_date (char *ptr, DB_DATE * date)
2881 {
2882  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2883 
2884  OR_GET_DATE (ptr, date);
2885  return (ptr + OR_DATE_SIZE);
2886 }
2887 
2888 /*
2889  * or_pack_monetary - write a DB_MONETARY value
2890  * return: advanced buffer pointer
2891  * ptr(out): output buffer
2892  * money(in): DB_MONETARY value
2893  */
2894 char *
2895 or_pack_monetary (char *ptr, DB_MONETARY * money)
2896 {
2897  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2898 
2899  OR_PUT_MONETARY (ptr, money);
2900  return (ptr + OR_MONETARY_SIZE);
2901 }
2902 
2903 /*
2904  * or_unpack_monetary - read a DB_MONETARY value
2905  * return: advanced buffer pointer
2906  * ptr(in): input buffer
2907  * money(out): DB_MONETARY value
2908  */
2909 char *
2910 or_unpack_monetary (char *ptr, DB_MONETARY * money)
2911 {
2912  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2913 
2914  OR_GET_MONETARY (ptr, money);
2915  return (ptr + OR_MONETARY_SIZE);
2916 }
2917 #endif /* ENABLE_UNUSED_FUNCTION */
2918 
2919 /*
2920  * or_unpack_int_array - extracts a array of integers from a buffer
2921  * return: advanced buffer pointer
2922  * ptr(in): current pointer in buffer
2923  * n(in): array length
2924  * number_array(out): result array
2925  */
2926 char *
2927 or_unpack_int_array (char *ptr, int n, int **number_array)
2928 {
2929  int i;
2930 
2931  *number_array = (int *) db_private_alloc (NULL, (n * sizeof (int)));
2932  if (*number_array)
2933  {
2934  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2935  for (i = 0; i < n; i++)
2936  {
2937  ptr = or_unpack_int (ptr, &(*number_array)[i]);
2938  }
2939  }
2940  else
2941  {
2942  ptr = NULL;
2943  }
2944 
2945  return ptr;
2946 }
2947 
2948 /*
2949  * DISK IDENTIFIER TRANSLATORS
2950  * Translators for the disk identifiers OID, HFID, BTID, EHID.
2951  */
2952 
2953 
2954 /*
2955  * or_pack_oid - write a OID value
2956  * return: advanced buffer pointer
2957  * ptr(out): output buffer
2958  * oid(in): OID value
2959  */
2960 char *
2961 or_pack_oid (char *ptr, const OID * oid)
2962 {
2963  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2964 
2965  if (oid != NULL)
2966  {
2967  OR_PUT_OID (ptr, oid);
2968  }
2969  else
2970  {
2971  OR_PUT_NULL_OID (ptr);
2972  }
2973  return (ptr + OR_OID_SIZE);
2974 }
2975 
2976 /*
2977  * or_pack_oid_array () - Pack an OID array.
2978  *
2979  * return : Pointer in buffer after the packed OID array.
2980  * ptr (in) : Pointer in buffer where OID array should be packed.
2981  * n (in) : Length of OID array.
2982  * oids (in) : OID array.
2983  */
2984 char *
2985 or_pack_oid_array (char *ptr, int n, const OID * oids)
2986 {
2987  int i;
2988 
2989  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
2990 
2991  if (ptr == NULL)
2992  {
2993  return NULL;
2994  }
2995 
2996  assert (n > 0 && oids != NULL);
2997  for (i = 0; i < n; i++)
2998  {
2999  ptr = or_pack_oid (ptr, &oids[i]);
3000  }
3001  return ptr;
3002 }
3003 
3004 /*
3005  * or_unpack_oid - read a OID value
3006  * return: advanced buffer pointer
3007  * ptr(in): input buffer
3008  * oid(out): OID value
3009  */
3010 char *
3011 or_unpack_oid (char *ptr, OID * oid)
3012 {
3013  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3014 
3015  OR_GET_OID (ptr, oid);
3016  return (ptr + OR_OID_SIZE);
3017 }
3018 
3019 /*
3020  * or_unpack_oid_array - read OID array values
3021  * return: advanced buffer pointer
3022  * ptr(in): input buffer
3023  * n(in): number of OIDs to read
3024  * oids(out): OID array
3025  */
3026 char *
3027 or_unpack_oid_array (char *ptr, int n, OID ** oids)
3028 {
3029  int i;
3030 
3031  *oids = (OID *) db_private_alloc (NULL, (n * sizeof (OID)));
3032 
3033  if (*oids == NULL)
3034  {
3035  ptr = NULL;
3036  return ptr;
3037  }
3038 
3039  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3040 
3041  for (i = 0; i < n; i++)
3042  {
3043  OR_GET_OID (ptr, &((*oids)[i]));
3044  ptr = ptr + OR_OID_SIZE;
3045  }
3046 
3047  return (ptr);
3048 }
3049 
3050 /*
3051  * or_pack_hfid - write a HFID value
3052  * return: advanced buffer pointer
3053  * ptr(out): output buffer
3054  * hfid(in): HFID value
3055  */
3056 char *
3057 or_pack_hfid (const char *ptr, const HFID * hfid)
3058 {
3059  char *new_;
3060 
3061  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3062 
3063  if (hfid != NULL)
3064  {
3065  OR_PUT_HFID (ptr, hfid);
3066  }
3067  else
3068  {
3069  OR_PUT_NULL_HFID (ptr);
3070  }
3071 
3072  /* kludge, need to have all of these accept and return const args */
3073  new_ = (char *) ptr + OR_HFID_SIZE;
3074  return new_;
3075 }
3076 
3077 /*
3078  * or_unpack_hfid - read a HFID value
3079  * return: advanced buffer pointer
3080  * ptr(in): input buffer
3081  * hfid(out): HFID value
3082  */
3083 char *
3084 or_unpack_hfid (char *ptr, HFID * hfid)
3085 {
3086  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3087 
3088  OR_GET_HFID (ptr, hfid);
3089  return (ptr + OR_HFID_SIZE);
3090 }
3091 
3092 /*
3093  * or_unpack_hfid_array - read HFID array
3094  * return: advanced buffer pointer
3095  * ptr(in): input buffer
3096  * n(in): number of HFIDs to read
3097  * hfids(out): HFID array
3098  */
3099 char *
3100 or_unpack_hfid_array (char *ptr, int n, HFID ** hfids)
3101 {
3102  int i = 0;
3103 
3104  *hfids = (HFID *) db_private_alloc (NULL, (n * sizeof (HFID)));
3105 
3106  if (*hfids == NULL)
3107  {
3108  ptr = NULL;
3109  return ptr;
3110  }
3111 
3112  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3113 
3114  for (i = 0; i < n; i++)
3115  {
3116  OR_GET_HFID (ptr, &((*hfids)[i]));
3117  ptr = ptr + OR_HFID_SIZE;
3118  }
3119 
3120  return ptr;
3121 }
3122 
3123 /*
3124  * or_pack_ehid - write a HFID value
3125  * return: advanced buffer pointer
3126  * ptr(out): output buffer
3127  * ehid(in): HFID value
3128  */
3129 char *
3130 or_pack_ehid (char *ptr, EHID * ehid)
3131 {
3132  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3133 
3134  OR_PUT_EHID (ptr, ehid);
3135 
3136  return (ptr + OR_EHID_SIZE);
3137 }
3138 
3139 char *
3141 {
3142  buf = or_pack_int (buf, recdes->length);
3143  buf = or_pack_short (buf, recdes->type);
3144  buf = or_pack_stream (buf, recdes->data, recdes->length);
3145  return buf;
3146 }
3147 
3148 /*
3149  * or_unpack_ehid - read a EHID value
3150  * return: advanced buffer pointer
3151  * ptr(in): input buffer
3152  * ehid(out): EHID value
3153  */
3154 char *
3155 or_unpack_ehid (char *ptr, EHID * ehid)
3156 {
3157  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3158 
3159  OR_GET_EHID (ptr, ehid);
3160 
3161  return (ptr + OR_EHID_SIZE);
3162 }
3163 
3164 /*
3165  * or_pack_btid - write a BTID value
3166  * return: advanced buffer pointer
3167  * ptr(out): output buffer
3168  * btid(in): BTID value
3169  */
3170 char *
3171 or_pack_btid (char *ptr, const BTID * btid)
3172 {
3173  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3174 
3175  if (btid)
3176  {
3177  OR_PUT_BTID (ptr, btid);
3178  }
3179  else
3180  {
3181  OR_PUT_NULL_BTID (ptr);
3182  }
3183 
3184 #if !defined(NDEBUG)
3185  /* to make valgrind quiet */
3186  OR_PUT_SHORT (ptr + OR_BTID_SIZE, 0);
3187 #endif
3188 
3189  return (ptr + OR_BTID_ALIGNED_SIZE);
3190 }
3191 
3192 /*
3193  * or_unpack_btid - read a BTID value
3194  * return: advanced buffer pointer
3195  * ptr(in): input buffer
3196  * btid(out): a BTID value
3197  */
3198 char *
3199 or_unpack_btid (char *ptr, BTID * btid)
3200 {
3201  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3202 
3203  OR_GET_BTID (ptr, btid);
3204 
3205  return (ptr + OR_BTID_ALIGNED_SIZE);
3206 }
3207 
3208 /*
3209  * or_pack_log_lsa - write a LOG_LSA value
3210  * return: advanced buffer pointer
3211  * ptr(out): output buffer
3212  * lsa(in): LOG_LSA value
3213  */
3214 char *
3215 or_pack_log_lsa (const char *ptr, const log_lsa * lsa)
3216 {
3217  char *new_;
3218 
3219  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3220 
3221  if (lsa != NULL)
3222  {
3223  OR_PUT_LOG_LSA (ptr, lsa);
3224  }
3225  else
3226  {
3227  OR_PUT_NULL_LOG_LSA (ptr);
3228  }
3229 
3230 #if !defined(NDEBUG)
3231  /* to make valgrind quiet */
3232  OR_PUT_SHORT (ptr + OR_LOG_LSA_SIZE, 0);
3233 #endif
3234 
3235  /* kludge, need to have all of these accept and return const args */
3236  new_ = (char *) ptr + OR_LOG_LSA_ALIGNED_SIZE;
3237  return new_;
3238 }
3239 
3240 /*
3241  * or_unpack_log_lsa - read a LOG_LSA value
3242  * return: advanced buffer pointer
3243  * ptr(in): input buffer
3244  * lsa(out): LOG_LSA value
3245  */
3246 char *
3247 or_unpack_log_lsa (char *ptr, log_lsa * lsa)
3248 {
3249  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3250 
3251  OR_GET_LOG_LSA (ptr, lsa);
3252  return (ptr + OR_LOG_LSA_ALIGNED_SIZE);
3253 }
3254 
3255 /*
3256  * or_unpack_set - read a set
3257  * return: advanced buffer pointer
3258  * ptr(in): input buffer
3259  * set(out): set value
3260  * domain(in): domain of the set (can be NULL)
3261  */
3262 char *
3263 or_unpack_set (char *ptr, setobj ** set, TP_DOMAIN * domain)
3264 {
3265  OR_BUF orbuf;
3266 
3267  or_init (&orbuf, ptr, 0);
3268  *set = or_get_set (&orbuf, domain);
3269 
3270  return orbuf.ptr;
3271 }
3272 
3273 /*
3274  * or_unpack_setref - unpack a set and get set reference for the set
3275  * return: advanced buffer pointer
3276  * ptr(in): input buffer
3277  * ref(out): reference for a set
3278  */
3279 char *
3280 or_unpack_setref (char *ptr, DB_SET ** ref)
3281 {
3282  SETOBJ *set = NULL;
3283 
3284  ptr = or_unpack_set (ptr, &set, NULL);
3285 
3286  if (set != NULL)
3287  {
3288  *ref = setobj_get_reference (set);
3289  }
3290  else
3291  {
3292  *ref = NULL;
3293  }
3294 
3295  return ptr;
3296 }
3297 
3298 
3299 /*
3300  * or_pack_string - Puts a string into the buffer.
3301  * return: advanced buffer pointer
3302  * ptr(out): current buffer pointer
3303  * string(in): string to pack
3304  * Note:
3305  * The string will be padded with extra bytes so that the ending pointer
3306  * is on a word boundary.
3307  * NOTE: This differs from or_put_string in that the length of the string
3308  * is stored before the string data. If the string is NULL the length
3309  * is -1. This is because comm buffers aren't formatted as objects
3310  * and therefore don't have an offset table that holds the size
3311  * of the string.
3312  */
3313 char *
3314 or_pack_string (char *ptr, const char *string)
3315 {
3316  int len, bits, pad;
3317 
3318  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3319 
3320  if (string == NULL)
3321  {
3322  OR_PUT_INT (ptr, -1);
3323  ptr += OR_INT_SIZE;
3324  }
3325  else
3326  {
3327  len = strlen (string) + 1;
3328  bits = len & 3;
3329  if (bits)
3330  {
3331  pad = 4 - bits;
3332  }
3333  else
3334  {
3335  pad = 0;
3336  }
3337  OR_PUT_INT (ptr, len + pad);
3338  ptr += OR_INT_SIZE;
3339  (void) memcpy (ptr, string, len);
3340  ptr += len;
3341  (void) memset (ptr, '\0', pad);
3342  ptr += pad;
3343  }
3344  return ptr;
3345 }
3346 
3347 
3348 /*
3349  * or_pack_string_with_null_padding - make stream to string and pack
3350  * return: advanced buffer pointer
3351  * ptr(out): current buffer pointer
3352  * string(in): string to pack
3353  * len(in): stream len
3354  */
3355 char *
3356 or_pack_string_with_null_padding (char *ptr, const char *string, size_t len)
3357 {
3358  char *ret_ptr;
3359 
3360  ret_ptr = or_pack_stream (ptr, string, len + 1);
3361 
3362  ptr[OR_INT_SIZE + len] = '\0'; /* NULL Padding */
3363 
3364  return ret_ptr;
3365 }
3366 
3367 /*
3368  * or_pack_stream - Puts a stream into the buffer.
3369  * return: advanced buffer pointer
3370  * ptr(out): current buffer pointer
3371  * stream(in): stream to pack
3372  */
3373 char *
3374 or_pack_stream (char *ptr, const char *stream, size_t len)
3375 {
3376  int bits, pad;
3377 
3378  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3379 
3380  if (stream == NULL)
3381  {
3382  OR_PUT_INT (ptr, -1);
3383  ptr += OR_INT_SIZE;
3384  }
3385  else
3386  {
3387  bits = len & 3;
3388  if (bits)
3389  {
3390  pad = 4 - bits;
3391  }
3392  else
3393  {
3394  pad = 0;
3395  }
3396  OR_PUT_INT (ptr, len + pad);
3397  ptr += OR_INT_SIZE;
3398  memcpy (ptr, stream, len);
3399  ptr += len;
3400  memset (ptr, '\0', pad);
3401  ptr += pad;
3402  }
3403  return ptr;
3404 }
3405 
3406 /*
3407  * or_pack_string_with_length - pack a string at most given length
3408  * return: advanced buffer pointer
3409  * ptr(out): output buffer
3410  * string(in): string
3411  * length(in): length
3412  */
3413 char *
3414 or_pack_string_with_length (char *ptr, const char *string, int length)
3415 {
3416  int len, bits, pad;
3417 
3418  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3419 
3420  if (string == NULL)
3421  {
3422  OR_PUT_INT (ptr, -1);
3423  ptr += OR_INT_SIZE;
3424  }
3425  else
3426  {
3427  len = length + 1;
3428  bits = len & 3;
3429  if (bits)
3430  {
3431  pad = 4 - bits;
3432  }
3433  else
3434  {
3435  pad = 0;
3436  }
3437  OR_PUT_INT (ptr, len + pad);
3438  ptr += OR_INT_SIZE;
3439  (void) memcpy (ptr, string, len);
3440  ptr += len;
3441  (void) memset (ptr, '\0', pad);
3442  ptr += pad;
3443  }
3444 
3445  return ptr;
3446 }
3447 
3448 /*
3449  * or_unpack_string - extracts a string from a buffer.
3450  * return: advanced pointer
3451  * ptr(in): current pointer
3452  * string(out): return pointer
3453  */
3454 char *
3455 or_unpack_string (char *ptr, char **string)
3456 {
3457  char *new_;
3458  int length;
3459 
3460  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3461 
3462  length = OR_GET_INT (ptr);
3463  ptr += OR_INT_SIZE;
3464  if (length == -1)
3465  {
3466  *string = NULL;
3467  }
3468  else
3469  {
3470  new_ = (char *) db_private_alloc (NULL, length);
3471  /* need to handle allocation errors */
3472  if (new_ == NULL)
3473  {
3474  ptr += length;
3475  }
3476  else
3477  {
3478  (void) memcpy (new_, ptr, length);
3479  ptr += length;
3480  }
3481  *string = new_;
3482  }
3483  return ptr;
3484 }
3485 
3486 /*
3487  * or_unpack_stream - extracts a stream from a buffer.
3488  * return: advanced pointer
3489  * ptr(in): current pointer
3490  * stream(out): return pointer
3491  */
3492 char *
3493 or_unpack_stream (char *ptr, char *stream, size_t len)
3494 {
3495  int length;
3496 
3497  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3498 
3499  length = OR_GET_INT (ptr);
3500  ptr += OR_INT_SIZE;
3501 
3502  assert_release ((size_t) length >= len);
3503 
3504  memcpy (stream, ptr, len);
3505  ptr += length;
3506  return ptr;
3507 }
3508 
3509 /*
3510  * or_unpack_string_alloc - extracts a string from a buffer.
3511  * return: advanced pointer
3512  * ptr(in): current pointer
3513  * string(out): return pointer
3514  *
3515  * Note: Unlike or_unpack_string which uses db_private_alloc to allocate
3516  * memory for the resulting string, this function uses malloc and the string
3517  * has to be freed using free_and_init.
3518  */
3519 char *
3520 or_unpack_string_alloc (char *ptr, char **string)
3521 {
3522  char *new_;
3523  int length;
3524 
3525  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3526 
3527  length = OR_GET_INT (ptr);
3528  ptr += OR_INT_SIZE;
3529  if (length == -1)
3530  {
3531  *string = NULL;
3532  }
3533  else
3534  {
3535  new_ = (char *) malloc (length * sizeof (char));
3536  /* need to handle allocation errors */
3537  if (new_ == NULL)
3538  {
3539  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (length * sizeof (char)));
3540  ptr += length;
3541  }
3542  else
3543  {
3544  (void) memcpy (new_, ptr, length);
3545  ptr += length;
3546  }
3547  *string = new_;
3548  }
3549  return ptr;
3550 }
3551 
3552 /*
3553  * or_unpack_string_nocopy - extracts a string from a buffer.
3554  * return: advanced pointer
3555  * ptr(in): current pointer
3556  * string(out): return pointer
3557  */
3558 char *
3559 or_unpack_string_nocopy (char *ptr, char **string)
3560 {
3561  int length;
3562 
3563  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3564 
3565  length = OR_GET_INT (ptr);
3566  ptr += OR_INT_SIZE;
3567  if (length == -1)
3568  {
3569  *string = NULL;
3570  }
3571  else
3572  {
3573  *string = ptr;
3574  ptr += length;
3575  }
3576  return ptr;
3577 }
3578 
3579 /*
3580  * or_packed_string_length - Determines the number of bytes required to hold
3581  * the packed representation of a string.
3582  * return: length of packed string
3583  * string(in): string to examine
3584  * strlen(out): strlen(string)
3585  *
3586  * Note: This includes padding bytes necessary to bring the length up to a
3587  * word boundary and also includes a word for the string length which is
3588  * stored at the top.
3589  */
3590 int
3591 or_packed_string_length (const char *string, int *strlenp)
3592 {
3593  int total, len, bits, pad;
3594 
3595  /* always have a length */
3596  total = OR_INT_SIZE;
3597  if (string != NULL)
3598  {
3599  if (strlenp != NULL)
3600  {
3601  len = (*strlenp = strlen (string)) + 1;
3602  }
3603  else
3604  {
3605  len = strlen (string) + 1;
3606  }
3607  bits = len & 3;
3608  if (bits)
3609  {
3610  pad = 4 - bits;
3611  }
3612  else
3613  {
3614  pad = 0;
3615  }
3616  total += len + pad;
3617  }
3618  else
3619  {
3620  if (strlenp != NULL)
3621  {
3622  *strlenp = 0;
3623  }
3624  }
3625  return total;
3626 }
3627 
3628 /*
3629  * or_packed_json_schema_length - Determines the number of bytes required to hold
3630  * the packed representation of a json_schema.
3631  * return: length of packed json_schema
3632  * json_schema(in): json_schema
3633  */
3634 static int
3635 or_packed_json_schema_length (const char *json_schema)
3636 {
3637  DB_VALUE val;
3638  db_make_string (&val, json_schema);
3639 
3640  int len = tp_String.get_disk_size_of_value (&val);
3641 
3642  pr_clear_value (&val);
3643 
3644  return len;
3645 }
3646 
3647 /*
3648  * or_packed_json_validator_length - Determines the number of bytes required to hold
3649  * the packed representation of a json_validator.
3650  * return: length of packed json_validator
3651  * json_validator(in): json_validator
3652  */
3653 static int
3655 {
3656  if (json_validator == NULL)
3657  {
3658  return 0;
3659  }
3661 }
3662 
3663 /*
3664  * or_packed_stream_length - Determines the number of bytes required to hold
3665  * the packed representation of a stream.
3666  * return: length of packed stream
3667  * len(in): length of stream
3668  */
3669 int
3671 {
3672  int total, bits, pad;
3673 
3674  /* always have a length */
3675  total = OR_INT_SIZE;
3676  if (len > 0)
3677  {
3678  bits = len & 3;
3679  if (bits)
3680  {
3681  pad = 4 - bits;
3682  }
3683  else
3684  {
3685  pad = 0;
3686  }
3687  total += (int) len + pad;
3688  }
3689  return total;
3690 }
3691 
3692 /*
3693  * or_pack_bool_array - write a bool array to pointer
3694  * return: advanced buffer pointer
3695  * ptr(out): out buffer
3696  * bools(in): bool array
3697  * size(in): size of bool array
3698  */
3699 char *
3700 or_pack_bool_array (char *ptr, const bool * bools, int size)
3701 {
3702  int bits, pad;
3703  if (ptr == NULL)
3704  {
3705  return NULL;
3706  }
3707 
3708  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3709  if (bools == NULL)
3710  {
3711  OR_PUT_INT (ptr, -1);
3712  ptr += OR_INT_SIZE;
3713  }
3714  else
3715  {
3716  bits = size & 3;
3717  if (bits)
3718  {
3719  pad = 4 - bits;
3720  }
3721  else
3722  {
3723  pad = 0;
3724  }
3725  OR_PUT_INT (ptr, size + pad);
3726  ptr += OR_INT_SIZE;
3727  (void) memcpy (ptr, bools, size);
3728  ptr += (size + pad);
3729  }
3730  return ptr;
3731 }
3732 
3733 /*
3734  * or_unpack_bool_array - read a bool array
3735  * return: advanced buffer pointer
3736  * ptr(in): input buffer
3737  * bools(out): bool array
3738  */
3739 char *
3740 or_unpack_bool_array (char *ptr, bool ** bools)
3741 {
3742  bool *new_;
3743  int length;
3744 
3745  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
3746 
3747  length = OR_GET_INT (ptr);
3748  ptr += OR_INT_SIZE;
3749  if (length == -1)
3750  {
3751  *bools = NULL;
3752  }
3753  else
3754  {
3755  new_ = (bool *) db_private_alloc (NULL, length);
3756  /* need to handle allocation errors */
3757  if (new_ == NULL)
3758  {
3759  ptr += length;
3760  }
3761  else
3762  {
3763  (void) memcpy (new_, ptr, length);
3764  ptr += length;
3765  }
3766  *bools = new_;
3767  }
3768 
3769  return ptr;
3770 }
3771 
3772 /*
3773  * or_packed_bool_array_length - Determines the number of bytes required to
3774  * hold the packed representation of a bool
3775  * array.
3776  * return: length of packed bool array
3777  * bools(in): bool array
3778  * size(in): the number of bool values in the array
3779  *
3780  * Note: This includes padding bytes necessary to bring the length up to a
3781  * word boundary and also includes a word for the array length which is
3782  * stored at the top.
3783  */
3784 int
3785 or_packed_bool_array_length (const bool * bools, int size)
3786 {
3787  int total, bits, pad;
3788 
3789  /* always have a length */
3790  total = OR_INT_SIZE;
3791  if (bools != NULL)
3792  {
3793  bits = size & 3;
3794  if (bits)
3795  {
3796  pad = 4 - bits;
3797  }
3798  else
3799  {
3800  pad = 0;
3801  }
3802  total += (size + pad);
3803  }
3804 
3805  return total;
3806 }
3807 
3808 #if defined(ENABLE_UNUSED_FUNCTION)
3809 /*
3810  * or_align_length - for a given length return aligned length
3811  * return: aligned length
3812  * length(in): given length
3813  */
3814 int
3815 or_align_length (int length)
3816 {
3817  int total, len, bits, pad;
3818 
3819  /* always have a length */
3820  total = OR_INT_SIZE;
3821 
3822  if (length != 0)
3823  {
3824  len = length + 1;
3825  bits = len & 3;
3826  if (bits)
3827  {
3828  pad = 4 - bits;
3829  }
3830  else
3831  {
3832  pad = 0;
3833  }
3834  total += len + pad;
3835  }
3836 
3837  return total;
3838 }
3839 #endif /* ENABLE_UNUSED_FUNCTION */
3840 
3841 /*
3842  * or_encode - Encodes the source data into the buffer so that only ascii
3843  * characters appear in the buffer.
3844  * return: void
3845  * buffer(out): buffer to encode into
3846  * source(in): source data
3847  * size(in): size of source data
3848  */
3849 void
3850 or_encode (char *buffer, const char *source, int size)
3851 {
3852  while (size--)
3853  {
3854  *buffer++ = ((*source & 0xf0) >> 4) + '@';
3855  *buffer++ = ((*source++ & 0xf) + '@');
3856  }
3857  *buffer = '\0';
3858 }
3859 
3860 /*
3861  * or_decode - Decodes the data in the buffer to dest.
3862  * return:
3863  * buffer(in): buffer to decode from
3864  * dest(out): destination data
3865  * size(in): size of destination data
3866  * Note: The buffer is assumed to be encoded by or_encode
3867  */
3868 void
3869 or_decode (const char *buffer, char *dest, int size)
3870 {
3871  char c1, c2;
3872 
3873  while (size--)
3874  {
3875  c1 = ((*buffer++ - '@') << 4) & 0xf0;
3876  c2 = (*buffer++ - '@') & 0xf;
3877  *dest++ = c1 | c2;
3878  }
3879 }
3880 
3881 /*
3882  * DOMAIN PACKING
3883  */
3884 
3885 /*
3886  * OR_DOMAIN_
3887  * Constants used to pick apart the first word of a packed domain.
3888  */
3889 
3890 /* note that this leaves room for only 63 type codes */
3891 #define OR_DOMAIN_TYPE_MASK (0x3F)
3892 #define OR_DOMAIN_NEXT_FLAG (0x80) /* domain following this one */
3893 
3894 #define OR_DOMAIN_NULL_FLAG (0x40) /* is a tagged NULL value */
3895 #define OR_DOMAIN_DESC_FLAG (0x40) /* asc/desc for only index key */
3896 
3897 #define OR_DOMAIN_CLASS_OID_FLAG (0x100) /* for object types */
3898 #define OR_DOMAIN_SET_DOMAIN_FLAG (0x100) /* for set types */
3899 #define OR_DOMAIN_BUILTIN_FLAG (0x100) /* for NULL type only */
3900 #define OR_DOMAIN_ENUMERATION_FLAG (0x100) /* for enumeration type only */
3901 #define OR_DOMAIN_ENUM_COLL_FLAG (0x200) /* for enumeration type only */
3902 #define OR_DOMAIN_SCHEMA_FLAG (0x400) /* for json */
3903 
3904 #define OR_DOMAIN_SCALE_MASK (0xFF00)
3905 #define OR_DOMAIN_SCALE_SHIFT (8)
3906 #define OR_DOMAIN_SCALE_MAX (0xFF)
3907 
3908 #define OR_DOMAIN_CODSET_MASK (0xFF00)
3909 #define OR_DOMAIN_CODSET_SHIFT (8)
3910 
3911 #define OR_DOMAIN_PRECISION_MASK (0xFFFF0000)
3912 #define OR_DOMAIN_PRECISION_SHIFT (16)
3913 #define OR_DOMAIN_PRECISION_MAX (0xFFFF)
3914 
3915 #define OR_DOMAIN_COLLATION_MASK (0x000000FF)
3916 #define OR_DOMAIN_COLL_ENFORCE_FLAG (0x80000000)
3917 #define OR_DOMAIN_COLL_LEAVE_FLAG (0x40000000)
3918 
3919 /*
3920  * or_packed_domain_size - calcualte the necessary buffer size required
3921  * to hold a packed representation of a hierarchical domain structure.
3922  * return: byte size of the packed domain
3923  * domain(in): domain to pack
3924  * include_classoids(in): non-zero to include class OIDs in the packing
3925  *
3926  * Note: It is generally called before using or_pack_domain() to store the
3927  * domain. The include_classoids flag can be used to selectively decide
3928  * whether or not to store the class OIDs with the domain. You'd better
3929  * call this function and or_pack_domain with the same include_classoids
3930  * flag value.
3931  */
3932 int
3933 or_packed_domain_size (TP_DOMAIN * domain, int include_classoids)
3934 {
3935  TP_DOMAIN *d;
3936  int size, precision, scale;
3937  DB_TYPE id;
3938 
3939  size = 0;
3940 
3941  /* hack, if this is a built-in domain, store a single word reference. */
3942  if (domain->built_in_index)
3943  {
3944  return OR_INT_SIZE;
3945  }
3946 
3947  /* now loop over the domains writing the disk representation */
3948  for (d = domain; d != NULL; d = d->next)
3949  {
3950 
3951  /* always have at least one word */
3952  size += OR_INT_SIZE;
3953 
3954  precision = 0;
3955  scale = 0;
3956 
3957  id = TP_DOMAIN_TYPE (d);
3958  switch (id)
3959  {
3960 
3961  case DB_TYPE_NUMERIC:
3962  precision = d->precision;
3963  scale = d->scale;
3964  /*
3965  * Safe guard for floating precision caused by incorrect type setting
3966  */
3967  if (precision <= TP_FLOATING_PRECISION_VALUE)
3968  {
3969  precision = DB_MAX_NUMERIC_PRECISION;
3970  }
3971  break;
3972 
3973  case DB_TYPE_NCHAR:
3974  case DB_TYPE_VARNCHAR:
3975  case DB_TYPE_CHAR:
3976  case DB_TYPE_VARCHAR:
3977  /* collation id */
3978  size += OR_INT_SIZE;
3979  /* FALLTHRU */
3980  case DB_TYPE_BIT:
3981  case DB_TYPE_VARBIT:
3982  /*
3983  * Hack, if the precision is -1, it is a special value indicating
3984  * either the maximum precision for the varying types or a floating
3985  * precision for the fixed types.
3986  */
3988  {
3989  precision = d->precision;
3990  }
3991 
3992  /*
3993  * Kludge, for temporary backward compatibility, treat varchar
3994  * types with the maximum precision as above. Need to change ourselves
3995  * to use -1 consistently for this after which this little
3996  * chunk of code can be removed.
3997  */
4000  || (id == DB_TYPE_VARBIT && d->precision == DB_MAX_VARBIT_PRECISION))
4001  {
4002  precision = 0;
4003  }
4004  break;
4005 
4006  case DB_TYPE_OBJECT:
4007  if (include_classoids)
4008  {
4009  size += OR_OID_SIZE;
4010  }
4011  break;
4012 
4013  case DB_TYPE_ENUMERATION:
4014  /* collation id */
4016  {
4017  size += OR_INT_SIZE;
4018  }
4020  break;
4021 
4022  case DB_TYPE_JSON:
4024  break;
4025 
4026  default:
4027  break;
4028  }
4029 
4030  if (precision >= OR_DOMAIN_PRECISION_MAX)
4031  {
4032  size += OR_INT_SIZE;
4033  }
4034 
4035  if (scale >= OR_DOMAIN_SCALE_MAX)
4036  {
4037  size += OR_INT_SIZE;
4038  }
4039 
4040  if (d->setdomain != NULL)
4041  {
4042  size += or_packed_domain_size (d->setdomain, include_classoids);
4043  }
4044  }
4045 
4046  return size;
4047 }
4048 
4049 /*
4050  * or_put_domain - creates the packed "disk" representation of a domain.
4051  * return: NO_ERROR or error code
4052  * buf(in/out): packing buffer
4053  * domain(in): domain to pack
4054  * include_classoids(in): non-zero if we're supposed to save class OIDs
4055  * is_null(in): use domain tags for "NULL" value
4056  * Note:
4057  * The is_null flag was added recently to allow domain tags for "NULL"
4058  * values without having to store something in addition to the domain
4059  * to indicate that the value was NULL.
4060  * This should only be on if the domain is being used to tag a value
4061  * and the value is logically NULL.
4062  */
4063 int
4064 or_put_domain (OR_BUF * buf, TP_DOMAIN * domain, int include_classoids, int is_null)
4065 {
4066  unsigned int carrier, extended_precision, extended_scale;
4067  int precision, scale;
4068  int has_oid, has_subdomain, has_enum;
4069  bool has_schema;
4070  bool has_collation;
4071  TP_DOMAIN *d;
4072  DB_TYPE id;
4073  int rc = NO_ERROR;
4074  unsigned int collation_storage;
4075 
4076  /*
4077  * Hack, if this is a built-in domain, store a single word reference.
4078  * This is only allowed for the top level domain.
4079  * Note that or_unpack_domain is probably not going to do the right
4080  * thing if we try to pack a builtin domain that is "inside" a hierarchical
4081  * domain. This isn't supposed to happen and can't in general because
4082  * two hierarchical domains are going to have potentially different "next"
4083  * pointers in the sub-domains.
4084  */
4085  if (domain->built_in_index)
4086  {
4088  | (domain->built_in_index << OR_DOMAIN_PRECISION_SHIFT));
4089  if (is_null)
4090  {
4091  carrier |= OR_DOMAIN_NULL_FLAG;
4092  }
4093  return (or_put_int (buf, carrier));
4094  }
4095 
4096  /* must pack a full domain description */
4097  for (d = domain; d != NULL; d = d->next)
4098  {
4099 
4100  id = TP_DOMAIN_TYPE (d);
4101 
4102  /*
4103  * Initial word has type, precision, scale, & codeset to the extent that
4104  * they will fit. High bit of the type byte is set if there
4105  * is another domain following this one. (e.g. for set or union domains).
4106  */
4107  carrier = id & OR_DOMAIN_TYPE_MASK;
4108  if (d->next != NULL)
4109  {
4110  carrier |= OR_DOMAIN_NEXT_FLAG;
4111  }
4112  if (d->is_desc)
4113  {
4114  carrier |= OR_DOMAIN_DESC_FLAG;
4115  }
4116  if (is_null)
4117  {
4118  carrier |= OR_DOMAIN_NULL_FLAG;
4119  }
4120 
4121  precision = 0;
4122  scale = 0;
4123  extended_precision = 0;
4124  extended_scale = 0;
4125  has_oid = 0;
4126  has_subdomain = 0;
4127  has_enum = 0;
4128  has_collation = false;
4129  has_schema = false;
4130 
4131  switch (id)
4132  {
4133 
4134  case DB_TYPE_NUMERIC:
4135  /* second byte contains scale, third & fourth bytes have precision */
4136 
4137  /* safe guard for scale */
4138  scale = d->scale;
4139  if (scale <= DB_DEFAULT_SCALE)
4140  {
4141  scale = 0;
4142  }
4143 
4144  if (scale < OR_DOMAIN_SCALE_MAX)
4145  {
4146  carrier |= scale << OR_DOMAIN_SCALE_SHIFT;
4147  }
4148  else
4149  {
4151  extended_scale = d->scale;
4152  }
4153  /* handle all precisions the same way at the end */
4154  precision = d->precision;
4155  /*
4156  * Safe guard for floating precision caused by incorrect type setting
4157  */
4158  if (precision <= TP_FLOATING_PRECISION_VALUE)
4159  {
4160  precision = DB_MAX_NUMERIC_PRECISION;
4161  }
4162  break;
4163 
4164  case DB_TYPE_NCHAR:
4165  case DB_TYPE_VARNCHAR:
4166  case DB_TYPE_CHAR:
4167  case DB_TYPE_VARCHAR:
4168  has_collation = true;
4169  /* FALLTHRU */
4170  case DB_TYPE_BIT:
4171  case DB_TYPE_VARBIT:
4172  carrier |= ((int) (d->codeset)) << OR_DOMAIN_CODSET_SHIFT;
4173 
4174  /*
4175  * Hack, if the precision is our special maximum/floating indicator,
4176  * store a zero in the precision field of the carrier.
4177  */
4179  {
4180  precision = d->precision;
4181  }
4182 
4183  /*
4184  * Kludge, for temporary backward compatibility, treat varchar
4185  * types with the maximum precision as the -1 case. See commentary
4186  * in or_packed_domain_size above.
4187  */
4190  || (id == DB_TYPE_VARBIT && d->precision == DB_MAX_VARBIT_PRECISION))
4191  {
4192  precision = 0;
4193  }
4194  break;
4195 
4196  case DB_TYPE_OBJECT:
4197  case DB_TYPE_OID:
4198  /*
4199  * If the include_classoids argument was specified, set a flag in the
4200  * disk representation indicating the presence of the class oids.
4201  * This isn't necessary when the domain is used for value tagging
4202  * since the class OID can always be be gotten from the instance oid.
4203  */
4204  if (include_classoids)
4205  {
4206  carrier |= OR_DOMAIN_CLASS_OID_FLAG;
4207  has_oid = 1;
4208  }
4209  break;
4210 
4211  case DB_TYPE_SET:
4212  case DB_TYPE_MULTISET:
4213  case DB_TYPE_SEQUENCE:
4214  case DB_TYPE_TABLE:
4215  case DB_TYPE_MIDXKEY:
4216  /*
4217  * we need to recursively store the sub-domains following this one,
4218  * since sets can have empty domains we need a flag to indicate this.
4219  */
4220  if (d->setdomain != NULL)
4221  {
4222  carrier |= OR_DOMAIN_SET_DOMAIN_FLAG;
4223  has_subdomain = 1;
4224  }
4225 
4226  if (id == DB_TYPE_MIDXKEY)
4227  {
4228  assert (d->precision > 0 && d->precision == tp_domain_size (d->setdomain));
4229  precision = d->precision;
4230  }
4231 
4232  break;
4233 
4234  case DB_TYPE_ENUMERATION:
4236  {
4237  has_collation = true;
4238  carrier |= OR_DOMAIN_ENUM_COLL_FLAG;
4239  }
4240  else
4241  {
4242  has_collation = false;
4243  }
4244  if (DOM_GET_ENUM_ELEMENTS (d) != NULL)
4245  {
4246  carrier |= OR_DOMAIN_ENUMERATION_FLAG;
4247  has_enum = 1;
4248  }
4249  break;
4250 
4251  case DB_TYPE_JSON:
4252  if (d->json_validator != NULL)
4253  {
4254  carrier |= OR_DOMAIN_SCHEMA_FLAG;
4255  has_schema = true;
4256  }
4257  break;
4258 
4259  default:
4260  break;
4261  }
4262 
4263  /* handle the precision if this type wanted one */
4264  if (precision)
4265  {
4266  if (precision < OR_DOMAIN_PRECISION_MAX)
4267  {
4268  carrier |= precision << OR_DOMAIN_PRECISION_SHIFT;
4269  }
4270  else
4271  {
4272  carrier |= (unsigned int) OR_DOMAIN_PRECISION_MAX << OR_DOMAIN_PRECISION_SHIFT;
4273  extended_precision = precision;
4274  }
4275  }
4276 
4277  /* store the first word */
4278  rc = or_put_int (buf, carrier);
4279  if (rc != NO_ERROR)
4280  {
4281  return rc;
4282  }
4283 
4284  if (has_collation)
4285  {
4286  collation_storage = d->collation_id;
4288  {
4289  collation_storage |= OR_DOMAIN_COLL_ENFORCE_FLAG;
4290  }
4291  else if (d->collation_flag == TP_DOMAIN_COLL_LEAVE)
4292  {
4293  collation_storage |= OR_DOMAIN_COLL_LEAVE_FLAG;
4294  }
4295 
4296  rc = or_put_int (buf, collation_storage);
4297  if (rc != NO_ERROR)
4298  {
4299  return rc;
4300  }
4301  }
4302 
4303  /* do we require any extended precision words ? */
4304  if (extended_precision)
4305  {
4306  rc = or_put_int (buf, extended_precision);
4307  if (rc != NO_ERROR)
4308  {
4309  return rc;
4310  }
4311  }
4312 
4313  if (extended_scale)
4314  {
4315  rc = or_put_int (buf, extended_scale);
4316  if (rc != NO_ERROR)
4317  {
4318  return rc;
4319  }
4320  }
4321 
4322  /* do we require a class OID ? */
4323  if (has_oid)
4324  {
4325  rc = or_put_oid (buf, &d->class_oid);
4326  if (rc != NO_ERROR)
4327  {
4328  return rc;
4329  }
4330  }
4331 
4332  if (has_enum)
4333  {
4334  rc = or_put_enumeration (buf, &DOM_GET_ENUMERATION (d));
4335 
4336  if (rc != NO_ERROR)
4337  {
4338  return rc;
4339  }
4340  }
4341 
4342  if (has_schema)
4343  {
4344  rc = or_put_json_validator (buf, d->json_validator);
4345  if (rc != NO_ERROR)
4346  {
4347  return rc;
4348  }
4349  }
4350 
4351  /*
4352  * Recurse on the sub domains if necessary, note that we don't
4353  * pass the NULL bit down here because that applies only to the
4354  * top level domain.
4355  */
4356  if (has_subdomain)
4357  {
4358  rc = or_put_domain (buf, d->setdomain, include_classoids, 0);
4359  if (rc != NO_ERROR)
4360  {
4361  return rc;
4362  }
4363  }
4364  }
4365  return rc;
4366 }
4367 
4368 
4369 /*
4370  * unpack_domain_2 - read a TP_DOMAIN from a buffer
4371  * return: TP_DOMAIN read
4372  * buf(in): input buffer
4373  * is_null(out): set 1 if NULL domain
4374  */
4375 static TP_DOMAIN *
4376 unpack_domain_2 (OR_BUF * buf, int *is_null)
4377 {
4378  TP_DOMAIN *domain, *last, *d;
4379  unsigned int carrier, precision, scale, codeset, has_classoid, has_setdomain, has_enum, collation_id,
4380  collation_storage;
4381  bool has_schema;
4382  bool more, auto_precision, is_desc, has_collation;
4383  DB_TYPE type;
4384  int index;
4385  int rc = NO_ERROR;
4386  unsigned char collation_flag;
4387 
4388  domain = last = NULL;
4389 
4390  more = true;
4391  while (more)
4392  {
4393 
4394  carrier = or_get_int (buf, &rc);
4395  if (rc != NO_ERROR)
4396  {
4397  goto error;
4398  }
4399 
4400  type = (DB_TYPE) (carrier & OR_DOMAIN_TYPE_MASK);
4401 
4402  /* check for the special NULL bit */
4403  if (is_null != NULL)
4404  {
4405  *is_null = ((carrier & OR_DOMAIN_NULL_FLAG) != 0);
4406  }
4407 
4408  /* Hack, check for references to built-in domains. */
4409  if (type == DB_TYPE_NULL && (carrier & OR_DOMAIN_BUILTIN_FLAG))
4410  {
4411  index = (carrier & OR_DOMAIN_PRECISION_MASK) >> OR_DOMAIN_PRECISION_SHIFT;
4412  /*
4413  * Recall that the builtin domain indexes are 1 based rather
4414  * than zero based, must adjust prior to indexing the table.
4415  */
4416  if (index < 1)
4417  {
4418  goto error;
4419  }
4420  domain = tp_domain_resolve_default ((DB_TYPE) (index - 1));
4421  /* stop the loop */
4422  more = false;
4423  }
4424  else
4425  {
4426  /* unpack a real domain */
4427 
4428  more = (carrier & OR_DOMAIN_NEXT_FLAG) ? true : false;
4429  precision = 0;
4430  scale = 0;
4431  codeset = 0;
4432  has_classoid = 0;
4433  has_setdomain = 0;
4434  has_enum = 0;
4435  has_schema = false;
4436  auto_precision = false;
4437  has_collation = false;
4438 
4439  if (carrier & OR_DOMAIN_DESC_FLAG)
4440  {
4441  is_desc = true;
4442  }
4443  else
4444  {
4445  is_desc = false;
4446  }
4447 
4448  switch (type)
4449  {
4450  case DB_TYPE_INTEGER:
4451  case DB_TYPE_SHORT:
4452  case DB_TYPE_BIGINT:
4453  case DB_TYPE_FLOAT:
4454  case DB_TYPE_DOUBLE:
4455  case DB_TYPE_DATE:
4456  case DB_TYPE_TIME:
4457  case DB_TYPE_TIMESTAMP:
4458  case DB_TYPE_TIMESTAMPTZ:
4459  case DB_TYPE_TIMESTAMPLTZ:
4460  case DB_TYPE_DATETIME:
4461  case DB_TYPE_DATETIMETZ:
4462  case DB_TYPE_DATETIMELTZ:
4463  case DB_TYPE_MONETARY:
4464  precision = tp_get_fixed_precision (type);
4465  break;
4466 
4467  case DB_TYPE_NUMERIC:
4468  precision = (carrier & OR_DOMAIN_PRECISION_MASK) >> OR_DOMAIN_PRECISION_SHIFT;
4469  scale = (carrier & OR_DOMAIN_SCALE_MASK) >> OR_DOMAIN_SCALE_SHIFT;
4470  break;
4471 
4472  case DB_TYPE_NCHAR:
4473  case DB_TYPE_VARNCHAR:
4474  case DB_TYPE_CHAR:
4475  case DB_TYPE_VARCHAR:
4476  has_collation = true;
4477  /* FALLTHRU */
4478  case DB_TYPE_BIT:
4479  case DB_TYPE_VARBIT:
4480  codeset = (carrier & OR_DOMAIN_CODSET_MASK) >> OR_DOMAIN_CODSET_SHIFT;
4481  precision = (carrier & OR_DOMAIN_PRECISION_MASK) >> OR_DOMAIN_PRECISION_SHIFT;
4482 
4483  if (precision == 0)
4484  {
4485  precision = TP_FLOATING_PRECISION_VALUE;
4486  auto_precision = true;
4487 
4488  if (type == DB_TYPE_VARCHAR)
4489  {
4490  precision = DB_MAX_VARCHAR_PRECISION;
4491  }
4492  else if (type == DB_TYPE_VARNCHAR)
4493  {
4494  precision = DB_MAX_VARNCHAR_PRECISION;
4495  }
4496  else if (type == DB_TYPE_VARBIT)
4497  {
4498  precision = DB_MAX_VARBIT_PRECISION;
4499  }
4500  }
4501  break;
4502 
4503  case DB_TYPE_OBJECT:
4504  has_classoid = carrier & OR_DOMAIN_CLASS_OID_FLAG;
4505  break;
4506 
4507  case DB_TYPE_SET:
4508  case DB_TYPE_MULTISET:
4509  case DB_TYPE_SEQUENCE:
4510  case DB_TYPE_TABLE:
4511  case DB_TYPE_MIDXKEY:
4512  has_setdomain = carrier & OR_DOMAIN_SET_DOMAIN_FLAG;
4513  if (type == DB_TYPE_MIDXKEY)
4514  {
4515  precision = (carrier & OR_DOMAIN_PRECISION_MASK) >> OR_DOMAIN_PRECISION_SHIFT;
4516  }
4517  break;
4518 
4519  case DB_TYPE_ENUMERATION:
4520  has_enum = carrier & OR_DOMAIN_ENUMERATION_FLAG;
4521  has_collation = ((carrier & OR_DOMAIN_ENUM_COLL_FLAG) == OR_DOMAIN_ENUM_COLL_FLAG);
4522  break;
4523 
4524  case DB_TYPE_JSON:
4525  has_schema = (carrier & OR_DOMAIN_SCHEMA_FLAG) != 0;
4526  break;
4527 
4528  default:
4529  break;
4530  }
4531 
4532  if (has_collation)
4533  {
4534  collation_storage = or_get_int (buf, &rc);
4535  if (rc != NO_ERROR)
4536  {
4537  goto error;
4538  }
4539  collation_id = collation_storage & OR_DOMAIN_COLLATION_MASK;
4540 
4541  if ((collation_storage & OR_DOMAIN_COLL_ENFORCE_FLAG) == OR_DOMAIN_COLL_ENFORCE_FLAG)
4542  {
4543  collation_flag = TP_DOMAIN_COLL_ENFORCE;
4544  }
4545  else if ((collation_storage & OR_DOMAIN_COLL_LEAVE_FLAG) == OR_DOMAIN_COLL_LEAVE_FLAG)
4546  {
4547  collation_flag = TP_DOMAIN_COLL_LEAVE;
4548  }
4549  else
4550  {
4551  collation_flag = TP_DOMAIN_COLL_NORMAL;
4552  }
4553  }
4554  else
4555  {
4556  collation_id = 0;
4557  collation_flag = TP_DOMAIN_COLL_NORMAL;
4558  }
4559 
4560  /* do we have an extra precision word ? */
4561  if (precision == OR_DOMAIN_PRECISION_MAX && !auto_precision)
4562  {
4563  precision = or_get_int (buf, &rc);
4564  }
4565 
4566  if (rc != NO_ERROR)
4567  {
4568  goto error;
4569  }
4570 
4571  /* do we have an extra scale word ? */
4572  if (scale == OR_DOMAIN_SCALE_MAX)
4573  {
4574  scale = or_get_int (buf, &rc);
4575  }
4576 
4577  if (rc != NO_ERROR)
4578  {
4579  goto error;
4580  }
4581 
4582  /* start building a transient domain */
4583  d = tp_domain_construct (type, NULL, precision, scale, NULL);
4584  if (d == NULL)
4585  {
4586  goto error;
4587  }
4588  if (last == NULL)
4589  {
4590  domain = last = d;
4591  }
4592  else
4593  {
4594  last->next = d;
4595  last = last->next;
4596  }
4597 
4598  /* do we have a class oid */
4599  if (has_classoid)
4600  {
4601  rc = or_get_oid (buf, &d->class_oid);
4602  if (rc != NO_ERROR)
4603  {
4604  goto error;
4605  }
4606 #if !defined (SERVER_MODE)
4607  /* swizzle the pointer if we're on the client */
4608  d->class_mop = ws_mop (&d->class_oid, NULL);
4609 #endif /* !SERVER_MODE */
4610  }
4611 
4612  /* store the codset if we had one */
4613  if (type == DB_TYPE_ENUMERATION)
4614  {
4615  if (has_collation)
4616  {
4617  /* collation id was read above, determine codeset */
4618  LANG_COLLATION *lc;
4619  lc = lang_get_collation (collation_id);
4620  assert (collation_id != LANG_COLL_ISO_BINARY);
4621  assert (lc != NULL);
4622  codeset = lc->codeset;
4623  }
4624  else
4625  {
4626  collation_id = LANG_COLL_ISO_BINARY;
4627  codeset = INTL_CODESET_ISO88591;
4628  }
4629 
4630  d->codeset = codeset;
4631  d->collation_id = collation_id;
4632  d->enumeration.collation_id = collation_id;
4633  d->collation_flag = (TP_DOMAIN_COLL_ACTION) collation_flag;
4634  }
4635  else
4636  {
4637  d->codeset = codeset;
4638  d->collation_id = collation_id;
4639  d->collation_flag = (TP_DOMAIN_COLL_ACTION) collation_flag;
4640  }
4641 
4642  if (has_enum)
4643  {
4644  rc = or_get_enumeration (buf, &DOM_GET_ENUMERATION (d));
4645  if (rc != NO_ERROR)
4646  {
4647  goto error;
4648  }
4649  }
4650 
4651  if (has_schema)
4652  {
4653  rc = or_get_json_validator (buf, d->json_validator);
4654  if (rc != NO_ERROR)
4655  {
4656  goto error;
4657  }
4658  }
4659 
4660  /*
4661  * Recurse to get set sub-domains if there are any, note that
4662  * we don't pass the is_null flag down here since NULLness only
4663  * applies to the top level domain.
4664  */
4665  if (has_setdomain)
4666  {
4667  d->setdomain = unpack_domain_2 (buf, NULL);
4668  if (d->setdomain == NULL)
4669  {
4670  goto error;
4671  }
4672  }
4673 
4674 #if !defined (NDEBUG)
4675  if (type == DB_TYPE_MIDXKEY)
4676  {
4677  assert (d->precision > 0 && d->precision == tp_domain_size (d->setdomain));
4678  }
4679 #endif /* NDEBUG */
4680 
4681  if (is_desc)
4682  {
4683  d->is_desc = 1;
4684  }
4685  else
4686  {
4687  d->is_desc = 0;
4688  }
4689  }
4690  }
4691 
4692  return domain;
4693 
4694 error:
4695  if (domain != NULL)
4696  {
4697  TP_DOMAIN *td, *next;
4698  for (td = domain, next = NULL; td != NULL; td = next)
4699  {
4700  next = td->next;
4701  tp_domain_free (td);
4702  }
4703  }
4704  return NULL;
4705 }
4706 
4707 
4708 /*
4709  * unpack_domain - unpack disk representation of domain
4710  * return: TP_DOMAIN structure
4711  * buf(in/out): or buffer
4712  * is_null(out): OR_DOMAIN_NULL_FLAG was on th packed domain?
4713  * Note:
4714  * OR_DOMAIN_NULL_FLAG will normally only be set if this domain was
4715  * used as a tag for a packed value.
4716  */
4717 static TP_DOMAIN *
4718 unpack_domain (OR_BUF * buf, int *is_null)
4719 {
4720  TP_DOMAIN *domain, *last, *dom;
4721  TP_DOMAIN *setdomain, *td, *next;
4722  DB_TYPE type;
4723  bool more, is_desc;
4724  unsigned int carrier, index;
4725  unsigned int precision, scale, codeset = 0, collation_id;
4726  OID class_oid;
4727  struct db_object *class_mop = NULL;
4728  int rc = NO_ERROR;
4729  DB_ENUMERATION db_enum = { NULL, 0, 0 };
4730  unsigned int collation_storage;
4731  unsigned char collation_flag;
4732 
4733  domain = last = dom = setdomain = NULL;
4734  precision = scale = 0;
4735 
4736  char *schema_raw = NULL;
4737 
4738  more = true;
4739  while (more)
4740  {
4741  carrier = or_get_int (buf, &rc);
4742  if (rc != NO_ERROR)
4743  {
4744  goto error;
4745  }
4746 
4747  type = (DB_TYPE) (carrier & OR_DOMAIN_TYPE_MASK);
4748 
4749  /* check for the special NULL bit */
4750  if (is_null != NULL)
4751  {
4752  *is_null = ((carrier & OR_DOMAIN_NULL_FLAG) != 0);
4753  }
4754 
4755  /* Hack, check for references to built-in domains. */
4756  if (type == DB_TYPE_NULL && (carrier & OR_DOMAIN_BUILTIN_FLAG))
4757  {
4758  index = (carrier & OR_DOMAIN_PRECISION_MASK) >> OR_DOMAIN_PRECISION_SHIFT;
4759  /* Recall that the builtin domain indexes are 1 based rather than zero based, must adjust prior to indexing
4760  * the table. */
4761  domain = tp_domain_resolve_default ((DB_TYPE) (index - 1));
4762  if (domain == NULL)
4763  {
4764  goto error;
4765  }
4766 
4767  /* stop the loop */
4768  more = false;
4769  }
4770  else
4771  {
4772  /* unpack a real domain */
4773  more = (carrier & OR_DOMAIN_NEXT_FLAG) ? true : false;
4774  is_desc = (carrier & OR_DOMAIN_DESC_FLAG) ? true : false;
4775 
4776  collation_id = 0;
4777  collation_flag = TP_DOMAIN_COLL_NORMAL;
4778 
4779  switch (type) /* try to find */
4780  {
4781  case DB_TYPE_INTEGER:
4782  case DB_TYPE_SHORT:
4783  case DB_TYPE_BIGINT:
4784  case DB_TYPE_FLOAT:
4785  case DB_TYPE_DOUBLE:
4786  case DB_TYPE_DATE:
4787  case DB_TYPE_TIME:
4788  case DB_TYPE_TIMESTAMP:
4789  case DB_TYPE_TIMESTAMPTZ:
4790  case DB_TYPE_TIMESTAMPLTZ:
4791  case DB_TYPE_DATETIME:
4792  case DB_TYPE_DATETIMETZ:
4793  case DB_TYPE_DATETIMELTZ:
4794  case DB_TYPE_MONETARY:
4795  precision = tp_get_fixed_precision (type);
4796  /* FALLTHRU */
4797 
4798  case DB_TYPE_NULL:
4799  case DB_TYPE_BLOB:
4800  case DB_TYPE_CLOB:
4801  dom = tp_domain_find_noparam (type, is_desc);
4802  break;
4803 
4804  case DB_TYPE_NUMERIC:
4805  /* get precision and scale */
4806  precision = (carrier & OR_DOMAIN_PRECISION_MASK) >> OR_DOMAIN_PRECISION_SHIFT;
4807  scale = (carrier & OR_DOMAIN_SCALE_MASK) >> OR_DOMAIN_SCALE_SHIFT;
4808  /* do we have an extra precision word ? */
4809  if (precision == OR_DOMAIN_PRECISION_MAX)
4810  {
4811  precision = or_get_int (buf, &rc);
4812  if (rc != NO_ERROR)
4813  {
4814  goto error;
4815  }
4816  }
4817  /* do we have an extra scale word ? */
4818  if (scale == OR_DOMAIN_SCALE_MAX)
4819  {
4820  scale = or_get_int (buf, &rc);
4821  if (rc != NO_ERROR)
4822  {
4823  goto error;
4824  }
4825  }
4826  dom = tp_domain_find_numeric (type, precision, scale, is_desc);
4827  break;
4828 
4829  case DB_TYPE_NCHAR:
4830  case DB_TYPE_VARNCHAR:
4831  case DB_TYPE_CHAR:
4832  case DB_TYPE_VARCHAR:
4833  collation_storage = or_get_int (buf, &rc);
4834  if (rc != NO_ERROR)
4835  {
4836  goto error;
4837  }
4838  collation_id = collation_storage & OR_DOMAIN_COLLATION_MASK;
4839 
4840  if ((collation_storage & OR_DOMAIN_COLL_ENFORCE_FLAG) == OR_DOMAIN_COLL_ENFORCE_FLAG)
4841  {
4842  collation_flag = TP_DOMAIN_COLL_ENFORCE;
4843  }
4844  else if ((collation_storage & OR_DOMAIN_COLL_LEAVE_FLAG) == OR_DOMAIN_COLL_LEAVE_FLAG)
4845  {
4846  collation_flag = TP_DOMAIN_COLL_LEAVE;
4847  }
4848  else
4849  {
4850  collation_flag = TP_DOMAIN_COLL_NORMAL;
4851  }
4852  /* FALLTHRU */
4853 
4854  case DB_TYPE_BIT:
4855  case DB_TYPE_VARBIT:
4856  codeset = ((carrier & OR_DOMAIN_CODSET_MASK) >> OR_DOMAIN_CODSET_SHIFT);
4857  precision = ((carrier & OR_DOMAIN_PRECISION_MASK) >> OR_DOMAIN_PRECISION_SHIFT);
4858  /* do we have an extra precision word ? */
4859  if (precision == OR_DOMAIN_PRECISION_MAX)
4860  {
4861  precision = or_get_int (buf, &rc);
4862  if (rc != NO_ERROR)
4863  {
4864  goto error;
4865  }
4866  }
4867  if (precision == 0)
4868  {
4869  /*
4870  * Kludge, restore maximum precision for the types that
4871  * aren't yet prepared for a -1. This can be removed
4872  * eventually, see commentary in the or_put_domain.
4873  */
4874  if (type == DB_TYPE_VARCHAR)
4875  {
4876  precision = DB_MAX_VARCHAR_PRECISION;
4877  }
4878  else if (type == DB_TYPE_VARNCHAR)
4879  {
4880  precision = DB_MAX_VARNCHAR_PRECISION;
4881  }
4882  else if (type == DB_TYPE_VARBIT)
4883  {
4884  precision = DB_MAX_VARBIT_PRECISION;
4885  }
4886  else
4887  {
4888  precision = TP_FLOATING_PRECISION_VALUE;
4889  }
4890  }
4891  dom = tp_domain_find_charbit (type, codeset, collation_id, collation_flag, precision, is_desc);
4892  break;
4893 
4894  case DB_TYPE_OBJECT:
4895  if (carrier & OR_DOMAIN_CLASS_OID_FLAG)
4896  {
4897  /* has classoid */
4898  rc = or_get_oid (buf, &class_oid);
4899  if (rc != NO_ERROR)
4900  {
4901  goto error;
4902  }
4903 #if !defined (SERVER_MODE)
4904  /* swizzle the pointer if we're on the client */
4905  class_mop = ws_mop (&class_oid, NULL);
4906 #endif /* !SERVER_MODE */
4907  }
4908  else
4909  {
4910  OID_SET_NULL (&class_oid);
4911  class_mop = NULL;
4912  }
4913  dom = tp_domain_find_object (type, &class_oid, class_mop, is_desc);
4914  break;
4915 
4916  case DB_TYPE_SET:
4917  case DB_TYPE_MULTISET:
4918  case DB_TYPE_SEQUENCE:
4919  case DB_TYPE_TABLE:
4920  case DB_TYPE_MIDXKEY:
4921  if (carrier & OR_DOMAIN_SET_DOMAIN_FLAG)
4922  {
4923  /* has setdomain */
4924  setdomain = unpack_domain_2 (buf, NULL);
4925  if (setdomain == NULL)
4926  {
4927  goto error;
4928  }
4929  }
4930  else
4931  {
4932  goto error;
4933  }
4934 
4935  if (type == DB_TYPE_MIDXKEY)
4936  {
4937  precision = (carrier & OR_DOMAIN_PRECISION_MASK) >> OR_DOMAIN_PRECISION_SHIFT;
4938  }
4939 
4940  dom = tp_domain_find_set (type, setdomain, is_desc);
4941  if (dom)
4942  {
4943  for (td = setdomain, next = NULL; td != NULL; td = next)
4944  {
4945  next = td->next;
4946  tp_domain_free (td);
4947  }
4948  }
4949  break;
4950 
4951  case DB_TYPE_ENUMERATION:
4952  if ((carrier & OR_DOMAIN_ENUM_COLL_FLAG) == OR_DOMAIN_ENUM_COLL_FLAG)
4953  {
4954  LANG_COLLATION *lc;
4955  collation_id = or_get_int (buf, &rc);
4956  assert (collation_id != LANG_COLL_ISO_BINARY);
4957  if (rc != NO_ERROR)
4958  {
4959  goto error;
4960  }
4961  lc = lang_get_collation (collation_id);
4962  assert (lc != NULL);
4963  codeset = lc->codeset;
4964  }
4965  else
4966  {
4967  collation_id = LANG_COLL_ISO_BINARY;
4968  codeset = INTL_CODESET_ISO88591;
4969  }
4970 
4971  db_enum.collation_id = collation_id;
4972 
4973  if (carrier & OR_DOMAIN_ENUMERATION_FLAG)
4974  {
4975  rc = or_get_enumeration (buf, &db_enum);
4976  if (rc != NO_ERROR)
4977  {
4978  goto error;
4979  }
4980  dom = tp_domain_find_enumeration (&db_enum, is_desc);
4981  if (dom != NULL)
4982  {
4983  /* we have to free the memory allocated for the enum above since we already have it cached */
4984  tp_domain_clear_enumeration (&db_enum);
4985  }
4986  }
4987  break;
4988 
4989  case DB_TYPE_JSON:
4990  if ((carrier & OR_DOMAIN_SCHEMA_FLAG) != 0)
4991  {
4992  rc = or_get_json_schema (buf, schema_raw);
4993  if (rc != NO_ERROR)
4994  {
4995  goto error;
4996  }
4997  or_align (buf, OR_INT_SIZE);
4998  assert (er_errid () == NO_ERROR);
4999  }
5000  break;
5001 
5002  default:
5003  break;
5004  }
5005 
5006  if (dom == NULL)
5007  {
5008  /* not found. need to construct one */
5009  dom = tp_domain_construct (type, NULL, precision, scale, setdomain);
5010  if (dom == NULL)
5011  {
5012  goto error;
5013  }
5014  DOM_SET_ENUM_ELEMENTS (dom, db_enum.elements);
5015  DOM_SET_ENUM_ELEMS_COUNT (dom, db_enum.count);
5016 
5017  switch (type)
5018  {
5019  case DB_TYPE_JSON:
5020  if (schema_raw != NULL)
5021  {
5022  rc = db_json_load_validator (schema_raw, dom->json_validator);
5023  db_private_free_and_init (NULL, schema_raw);
5024  if (rc != NO_ERROR)
5025  {
5026  ASSERT_ERROR ();
5027  goto error;
5028  }
5029  }
5030  else
5031  {
5032  dom->json_validator = NULL;
5033  }
5034  break;
5035  case DB_TYPE_NCHAR:
5036  case DB_TYPE_VARNCHAR:
5037  case DB_TYPE_CHAR:
5038  case DB_TYPE_VARCHAR:
5039  dom->collation_id = collation_id;
5040  dom->collation_flag = (TP_DOMAIN_COLL_ACTION) collation_flag;
5041  /* FALLTHRU */
5042  case DB_TYPE_BIT:
5043  case DB_TYPE_VARBIT:
5044  dom->codeset = codeset;
5045  break;
5046  case DB_TYPE_OBJECT:
5047  COPY_OID (&dom->class_oid, &class_oid);
5048 #if !defined (SERVER_MODE)
5049  dom->class_mop = class_mop;
5050 #endif /* !SERVER_MODE */
5051  break;
5052  case DB_TYPE_ENUMERATION:
5053  dom->collation_id = collation_id;
5054  dom->enumeration.collation_id = collation_id;
5055  dom->codeset = codeset;
5056  dom->collation_flag = (TP_DOMAIN_COLL_ACTION) collation_flag;
5057  default:
5058  break;
5059  }
5060 
5061 #if !defined (NDEBUG)
5062  if (type == DB_TYPE_MIDXKEY)
5063  {
5064  assert (dom->precision > 0 && dom->precision == tp_domain_size (dom->setdomain));
5065  }
5066 #endif /* NDEBUG */
5067 
5068  if (is_desc)
5069  {
5070  dom->is_desc = 1;
5071  }
5072  dom = tp_domain_cache (dom);
5073  }
5074 
5075 #if !defined (NDEBUG)
5076  if (type == DB_TYPE_MIDXKEY)
5077  {
5078  assert (dom->precision > 0 && dom->precision == tp_domain_size (dom->setdomain));
5079  }
5080 #endif /* NDEBUG */
5081 
5082  if (last == NULL)
5083  {
5084  domain = last = dom;
5085  }
5086  else
5087  {
5088  last->next = dom;
5089  last = last->next;
5090  }
5091  }
5092  }
5093 
5094  return domain;
5095 
5096 error:
5097  if (domain != NULL)
5098  {
5099  for (td = domain, next = NULL; td != NULL; td = next)
5100  {
5101  next = td->next;
5102  tp_domain_free (td);
5103  }
5104  }
5105  return NULL;
5106 }
5107 
5108 /*
5109  * or_get_domain - unpacks a domain from a buffer and returns a cached domain.
5110  * return: cached domain or NULL for error
5111  * buf(in/out): or buffer
5112  * caller_dom(in):
5113  * is_null(out): OR_DOMAIN_NULL_FLAG was on in the packed domain?
5114  */
5115 TP_DOMAIN *
5116 or_get_domain (OR_BUF * buf, TP_DOMAIN * caller_dom, int *is_null)
5117 {
5118  TP_DOMAIN *domain;
5119 
5120  if (caller_dom)
5121  {
5122  domain = unpack_domain_2 (buf, is_null);
5123  if (tp_domain_match (domain, caller_dom, TP_SET_MATCH))
5124  {
5125  tp_domain_free (domain);
5126  domain = caller_dom;
5127  }
5128  else if (domain != NULL && !domain->is_cached)
5129  {
5130  domain = tp_domain_cache (domain);
5131  }
5132  }
5133  else
5134  {
5135  domain = unpack_domain (buf, is_null);
5136  if (domain != NULL && !domain->is_cached)
5137  {
5138  domain = tp_domain_cache (domain);
5139  }
5140  }
5141  return domain;
5142 }
5143 
5144 /*
5145  * or_pack_domain - creates the packed "disk" representation of a domain
5146  * return: advanced pointer
5147  * ptr(out): output buffer
5148  * domain(in): domain to pack
5149  * include_classoids(in): non-zero if we're supposed to save class OIDs
5150  * is_null(in): use domain tags for "NULL" value
5151  *
5152  * Note:
5153  * Alternate interface for or_put_domain, see that function
5154  * for more information.
5155  */
5156 char *
5157 or_pack_domain (char *ptr, TP_DOMAIN * domain, int include_classoids, int is_null)
5158 {
5159  OR_BUF buf;
5160  int rc = 0;
5161 
5162  or_init (&buf, ptr, 0);
5163  rc = or_put_domain (&buf, domain, include_classoids, is_null);
5164  if (rc == NO_ERROR)
5165  {
5166  return buf.ptr;
5167  }
5168  else
5169  {
5170  return NULL;
5171  }
5172 }
5173 
5174 /*
5175  * or_unpack_domain - alternative interfaceto or_get_domain
5176  * return: advanced buffer pointer
5177  * ptr(in): pointer to buffer
5178  * domain_ptr(out): pointer to domain
5179  * is_null(out): use domain tags for "NULL" value
5180  */
5181 char *
5182 or_unpack_domain (char *ptr, struct tp_domain **domain_ptr, int *is_null)
5183 {
5184  OR_BUF buf;
5185  TP_DOMAIN *domain;
5186 
5187  or_init (&buf, ptr, 0);
5188 
5189  domain = or_get_domain (&buf, NULL, is_null);
5190  if (domain_ptr != NULL)
5191  {
5192  *domain_ptr = domain;
5193  }
5194 
5195  return buf.ptr;
5196 }
5197 
5198 /*
5199  * or_put_sub_domain - put DB_TYPE_SUB field to buffer
5200  * return: NO_ERROR or error code
5201  * buf(in/out): or buffer
5202  * Note:
5203  * This is a kludge until we have a more general mechanism for dealing
5204  * with "substrutcure" domains.
5205  * These are used in the disk representation of the class and indicate
5206  * the presence of nested instances, similar in theory to the ADT concept.
5207  * We've stored classes like this for some time, eventually this can
5208  * be replaced by true ADT's when they come on-line but hopefully the
5209  * representation will be identical.
5210  * We use this function to avoid having to actually create a bunch of
5211  * built-in domains for the meta classes though that wouldn't be all that
5212  * hard to add to the tp_Domain array.
5213  */
5214 int
5216 {
5217  unsigned int carrier;
5218 
5219  carrier = (DB_TYPE_SUB & OR_DOMAIN_TYPE_MASK);
5220  return (or_put_int (buf, carrier));
5221 }
5222 
5223 /*
5224  * SET PACKING
5225  */
5226 /*
5227  * or_packed_set_info - looks at the domain of the set and determines the
5228  * close to optimal storage configuration for it.
5229  * return: void
5230  * set_type(in): basic type of the set
5231  * domain(in): full domain of the set (optional)
5232  * include_domain(in): non-zero if the caller wants the domain in the set
5233  * bound_bits(out): set to 1 if the set is homogeneous
5234  * offset_table(out): set to the fixed width element size (-1 if variable)
5235  * element_tags(out): set to 1 if bound bits required
5236  * element_size(out): set to 1 if offset table is required
5237  *
5238  * Note:
5239  * This looks at the domain of the set and determines the close to
5240  * optimal storage configuration for it. There is some room for
5241  * interpretation here, and in fact, we can completely ignore the
5242  * domain and store set in their most general representation all the
5243  * time if there seems to be some problem dealing with compressed sets.
5244  * This may not need to be a public function, it is only called by
5245  * or_put_set and or_packed_set_size.
5246  */
5247 void
5248 or_packed_set_info (DB_TYPE set_type, TP_DOMAIN * domain, int include_domain, int *bound_bits, int *offset_table,
5249  int *element_tags, int *element_size)
5250 {
5251  TP_DOMAIN *element_domain;
5252  int homogeneous;
5253 
5254 
5255  /*
5256  * A set can be of fixed width only if the domain is fully specified and there
5257  * is only one fixed width data type in the set.
5258  * Note that for "attached" sets that may be fixed width, the domain must
5259  * have been assigned by now for us to determine this, if not, we punt
5260  * and assume its a variable width set.
5261  */
5262 
5263  /*
5264  * might only need bother with offset tables if this is an indexable
5265  * sequence ?
5266  */
5267  homogeneous = 0;
5268  *element_tags = 1;
5269  *element_size = -1;
5270  *bound_bits = 0;
5271  *offset_table = 0;
5272 
5273  if (domain != NULL)
5274  {
5275  element_domain = domain->setdomain;
5276  if (element_domain != NULL && element_domain->next == NULL)
5277  {
5278  /* set can contain only one type of thing */
5279  homogeneous = 1;
5280  /* returns -1 if this is a variable width thing */
5281  *element_size = tp_domain_disk_size (element_domain);
5282  }
5283  }
5284 
5285  if (homogeneous)
5286  {
5287  if (*element_size >= 0)
5288  {
5289  *bound_bits = 1;
5290  }
5291  else
5292  {
5293  *offset_table = 1;
5294  }
5295  }
5296  else
5297  {
5298  *offset_table = 1;
5299  }
5300 
5301  /*
5302  * Determine if we need to tag each value with its domain.
5303  * Normally, one would tag the elements if the domain is being excluded
5304  * from the set, but we'll allow it and assume that it will be passed
5305  * to the or_get_set function.
5306  */
5307  *element_tags = !homogeneous; /* || !include_domain */
5308 
5309  /*
5310  * If we have to have element tags, then don't bother with a bound
5311  * bit array.
5312  */
5313  if (*element_tags)
5314  {
5315  *bound_bits = 0;
5316  }
5317 }
5318 
5319 /*
5320  * or_put_set_header - write a set header containing the indicated information.
5321  * return: NO_ERROR or return code
5322  * buf(in/out): or buffer
5323  * set_type(in): basic type of the set
5324  * size(in): number of elements in the set
5325  * domain(in): non-zero if a domain will be packed
5326  * bound_bits(in): non-zero if a bound bit vector will be packed
5327  * offset_table(in): non-zero if an offset table will be packed
5328  * element_tags(in): non-zero if elements tags will be included
5329  * common_sub_header(in): non-zero if substructure tags will be included
5330  * Note:
5331  * This hides basically just hides the implementation of the header
5332  * word and flag constants so we can control who gets to see this.
5333  * Common sub_header is used only for class objects currently.
5334  *
5335  */
5336 int
5337 or_put_set_header (OR_BUF * buf, DB_TYPE set_type, int size, int domain, int bound_bits, int offset_table,
5338  int element_tags, int common_sub_header)
5339 {
5340  unsigned int header;
5341  int rc = NO_ERROR;
5342 
5343  header = set_type & 0xFF;
5344 
5345  if (offset_table)
5346  {
5347  header |= OR_SET_VARIABLE_BIT;
5348  }
5349  else if (bound_bits)
5350  {
5351  header |= OR_SET_BOUND_BIT;
5352  }
5353 
5354  if (domain)
5355  {
5356  header |= OR_SET_DOMAIN_BIT;
5357  }
5358  if (element_tags)
5359  {
5360  header |= OR_SET_TAG_BIT;
5361  }
5362  if (common_sub_header)
5363  {
5364  header |= OR_SET_COMMON_SUB_BIT;
5365  }
5366  rc = or_put_int (buf, header);
5367 
5368  if (rc == NO_ERROR)
5369  {
5370  rc = or_put_int (buf, size);
5371  }
5372 
5373  return rc;
5374 }
5375 
5376 /*
5377  * or_get_set_header - get set header from buffer
5378  * return: ER_SUCCSSS or error code
5379  * buf(in/out): or buffer
5380  * set_type(out): set to the basic set type
5381  * size(out): set to the element count
5382  * domain(out): set non-zero if there will be a domain
5383  * bound_bits(out): set non-zero if there will be bound bits
5384  * offset_table(out): set non-zero if there will be an offset table
5385  * element_tags(out): set non-zero if there will be element tags
5386  * common_sub(out): set non-zero if there will be substructure tags
5387  */
5388 int
5389 or_get_set_header (OR_BUF * buf, DB_TYPE * set_type, int *size, int *domain, int *bound_bits, int *offset_table,
5390  int *element_tags, int *common_sub)
5391 {
5392  unsigned int header;
5393  int rc = NO_ERROR;
5394 
5395  header = or_get_int (buf, &rc);
5396  if (rc == NO_ERROR)
5397  {
5398  *set_type = (DB_TYPE) (header & OR_SET_TYPE_MASK);
5399  *domain = ((header & OR_SET_DOMAIN_BIT) != 0);
5400  *bound_bits = ((header & OR_SET_BOUND_BIT) != 0);
5401  *offset_table = ((header & OR_SET_VARIABLE_BIT) != 0);
5402  *element_tags = ((header & OR_SET_TAG_BIT) != 0);
5403  if (common_sub != NULL)
5404  {
5405  *common_sub = ((header & OR_SET_COMMON_SUB_BIT) != 0);
5406  }
5407  *size = or_get_int (buf, &rc);
5408  }
5409  return rc;
5410 }
5411 
5412 /*
5413  * or_skip_set_header - skip over the set header
5414  * return: number of elements in set
5415  * buf(in/out): or buffer
5416  *
5417  * Note:
5418  * Used only by the class loader since it knows what the type
5419  * of the set is.
5420  */
5421 int
5423 {
5424  DB_TYPE set_type;
5425  int count, length, rc = NO_ERROR;
5426  int domain, bound_bits, offset_table, element_tags, sub_header;
5427 
5428  or_get_set_header (buf, &set_type, &count, &domain, &bound_bits, &offset_table, &element_tags, &sub_header);
5429 
5430  if (offset_table)
5431  {
5432  or_advance (buf, OR_VAR_TABLE_SIZE (count));
5433  }
5434 
5435  else if (bound_bits)
5436  {
5437  or_advance (buf, OR_BOUND_BIT_BYTES (count));
5438  }
5439 
5440  if (domain)
5441  {
5442  length = or_get_int (buf, &rc);
5443  or_advance (buf, length);
5444  }
5445 
5446  if (sub_header)
5447  {
5449  }
5450 
5451  return count;
5452 }
5453 
5454 /*
5455  * or_packed_set_length - Calculates the disk size of a set
5456  * return: disk length of the set
5457  * set(in): pointer to an internal set object (not a set reference)
5458  * include_domain(in): non-zero if the caller wants the domain in the set
5459  *
5460  * Note:
5461  * the length returned here will match the representation
5462  * created by or_put_set() only. There are some other set packers
5463  * floating around that represent sets as arrays of packed DB_VALUES,
5464  * these are not necessarily the same size.
5465  *
5466  * The include_domain flag is set if the set is to be packed with a full
5467  * domain description. This is normally off when the set is inside
5468  * an object since the domain can be determined from the class.
5469  * When "free" sets are packed in list files or as elements of nested
5470  * sets, the domain should be included.
5471  * This distinction may be somewhat difficult to make in the presence
5472  * of nested sets. Consider instead leaving the domain specified but
5473  * don't pack the class OIDs of object domains.
5474  */
5475 int
5476 or_packed_set_length (setobj * set, int include_domain)
5477 {
5478  DB_VALUE *value = NULL;
5479  int len, element_size, bound_bits, offset_table, element_tags, i, bits;
5480  int set_size;
5481  TP_DOMAIN *set_domain;
5482  DB_TYPE set_type;
5483  int error;
5484 
5485  len = 0;
5486  if (set == NULL)
5487  {
5488  return 0;
5489  }
5490 
5491  set_size = setobj_size (set);
5492  set_type = setobj_type (set);
5493  set_domain = setobj_domain (set);
5494 
5495  /* Determine storage characteristics based on the domain */
5496  or_packed_set_info (set_type, set_domain, include_domain, &bound_bits, &offset_table, &element_tags, &element_size);
5497 
5498  len = OR_SET_HEADER_SIZE;
5499 
5500  if (offset_table)
5501  {
5502  len += OR_VAR_TABLE_SIZE (set_size);
5503  }
5504  else if (bound_bits)
5505  {
5506  len += OR_BOUND_BIT_BYTES (set_size);
5507  }
5508 
5509  if (set_domain != NULL && include_domain)
5510  {
5511  len += OR_INT_SIZE;
5512  len += or_packed_domain_size (set_domain, 0);
5513  }
5514 
5515  /*
5516  * If we have a non-tagged fixed width set, can calculate the size without
5517  * mapping over the values.
5518  */
5519  if (bound_bits)
5520  {
5521  len += element_size * set_size;
5522  }
5523  else
5524  {
5525 
5526  for (i = 0; i < set_size; i++)
5527  {
5528  error = setobj_get_element_ptr (set, i, &value);
5529 
5530  /* Second argument indicates whether to "collapse_null" values into nothing. - can do this only if there is
5531  * an offset table. Third argument indicates whether or not to include the domain which - we do if the values
5532  * are tagged. Fourth argument indicates the desire to pack class OIDs which we never do since these are tag
5533  * domains. */
5534  len += or_packed_value_size (value, offset_table, element_tags, 0);
5535  if (offset_table)
5536  {
5537  bits = len & 3;
5538  if (bits)
5539  {
5540  len += (4 - bits);
5541  }
5542  }
5543  }
5544  }
5545 
5546  /* always pad out a packed set to a word boundary */
5547  bits = len & 3;
5548  if (bits)
5549  {
5550  len += (4 - bits);
5551  }
5552 
5553  return len;
5554 }
5555 
5556 /*
5557  * or_put_set - primary function for building the disk representation
5558  * of a set.
5559  * return: void
5560  * buf(in/out): or buffer
5561  * set(in): set object to encode
5562  * include_domain(in): non-zero to store full set domain too
5563  */
5564 void
5565 or_put_set (OR_BUF * buf, setobj * set, int include_domain)
5566 {
5567  DB_VALUE *value = NULL;
5568  unsigned int bound_word;
5569  int element_tags, element_size, bound_bits, offset_table;
5570  char *set_start, *element_start, *offset_ptr, *bound_ptr;
5571  int i, offset, bit = 0, len, is_null, length, bits;
5572  TP_DOMAIN *set_domain;
5573  DB_TYPE set_type;
5574  int set_size;
5575  int error;
5576 
5577  if (set == NULL)
5578  {
5579  return;
5580  }
5581 
5582  /* only pay attention to this if we actually have a domain to store */
5583  set_domain = setobj_domain (set);
5584  set_type = setobj_type (set);
5585  set_size = setobj_size (set);
5586 
5587  if (set_domain == NULL)
5588  {
5589  include_domain = 0;
5590  }
5591 
5592  /* determine storage characteristics based on the domain */
5593  set_start = buf->ptr;
5594  or_packed_set_info (set_type, set_domain, include_domain, &bound_bits, &offset_table, &element_tags, &element_size);
5595 
5596  or_put_set_header (buf, set_domain ? TP_DOMAIN_TYPE (set_domain) : set_type, set_size, include_domain, bound_bits,
5597  offset_table, element_tags, 0);
5598 
5599 
5600  /* reserve space for the offset table or bound bit vector if necessary */
5601  offset_ptr = NULL;
5602  bound_ptr = NULL;
5603  bound_word = 0;
5604  if (set_size)
5605  {
5606  if (offset_table)
5607  {
5608  offset_ptr = buf->ptr;
5609  len = OR_VAR_TABLE_SIZE (set_size);
5610  or_advance (buf, len);
5611  }
5612  else if (bound_bits)
5613  {
5614  bound_ptr = buf->ptr;
5615  len = OR_BOUND_BIT_BYTES (set_size);
5616  or_advance (buf, len);
5617  }
5618  }
5619 
5620  /* write the domain if necessary, don't include the class OID */
5621  if (include_domain)
5622  {
5623  or_put_int (buf, or_packed_domain_size (set_domain, 0));
5624  or_put_domain (buf, set_domain, 0, 0);
5625  }
5626 
5627  /* stop if we don't have any elements */
5628  if (set_size)
5629  {
5630 
5631  /* calculate the offset to the first value (in case we're building an offset table) */
5632  offset = (int) (buf->ptr - set_start);
5633 
5634  /* iterate over the values */
5635  for (i = 0; i < set_size; i++)
5636  {
5637  error = setobj_get_element_ptr (set, i, &value);
5638 
5639  /*
5640  * make an entry in the offset table or bound bit array if we
5641  * have them
5642  */
5643  is_null = 0;
5644  if (offset_ptr != NULL)
5645  {
5646  /* offset table entry */
5647  OR_PUT_OFFSET (offset_ptr, offset);
5648  offset_ptr += BIG_VAR_OFFSET_SIZE;
5649  }
5650  else if (bound_ptr != NULL)
5651  {
5652  bit = i & 0x1F;
5653  if (value != NULL && DB_VALUE_TYPE (value) != DB_TYPE_NULL)
5654  {
5655  bound_word |= 1L << bit;
5656  }
5657  else
5658  {
5659  is_null = 1;
5660  }
5661  if (bit == 0x1F)
5662  {
5663  OR_PUT_INT (bound_ptr, bound_word);
5664  bound_ptr += OR_INT_SIZE;
5665  bound_word = 0;
5666  }
5667  }
5668 
5669  /*
5670  * Write the value. Be careful with NULLs in fixed width sets, need
5671  * to leave space.
5672  */
5673  element_start = buf->ptr;
5674 
5675  if (bound_ptr != NULL && is_null)
5676  {
5677  /*
5678  * Could just use or_advance here but lets be nice and
5679  * zero out the space for debugging.
5680  */
5681  or_pad (buf, element_size);
5682  }
5683  else
5684  {
5685  /* Third argument indicates whether to "collapse_null" values into nothing. - can do this only if there
5686  * is an offset table. Fourth argument indicates whether or not to include the domain which we do if the
5687  * values are tagged. Fifth argument indicates the desire to pack class OIDs which we never do since
5688  * these are tag domains. */
5689  or_put_value (buf, value, offset_table, element_tags, 0);
5690  }
5691 
5692  if (offset_table)
5693  {
5694  length = CAST_BUFLEN (buf->ptr - element_start);
5695  bits = length & 3;
5696  if (bits)
5697  {
5698  or_pad (buf, 4 - bits);
5699  }
5700  }
5701 
5702  offset += (int) (buf->ptr - element_start);
5703  }
5704 
5705  /* store the ending offset in the table if we're using one */
5706  if (offset_ptr != NULL)
5707  {
5708  OR_PUT_OFFSET (offset_ptr, offset);
5709  }
5710 
5711  if (bound_ptr != NULL && bit != 0x1f)
5712  {
5713  OR_PUT_INT (bound_ptr, bound_word);
5714  }
5715  }
5716 
5717  /* always pad out a packed set to a word boundary */
5718  length = CAST_BUFLEN (buf->ptr - set_start);
5719  bits = length & 3;
5720  if (bits)
5721  {
5722  or_pad (buf, 4 - bits);
5723  }
5724 }
5725 
5726 /*
5727  * or_get_set - eads the stored representation of a set and builds the
5728  * corresponding memory represenation.
5729  * return: internal set object
5730  * buf(in/out): or buffer
5731  * domain(in): expected domain (optional)
5732  * Note:
5733  * The domain argument is required only if the domain set was packed
5734  * explicitly without a domain and the elements are not tagged. In that
5735  * case, the supplied domain must be used to interpret the element
5736  * format. It better be right. This is really only used for the
5737  * stored values of attributes since we can always get the correct
5738  * domain by looking in the catalog.
5739  */
5740 setobj *
5741 or_get_set (OR_BUF * buf, TP_DOMAIN * domain)
5742 {
5743  SETOBJ *set;
5744  DB_VALUE value;
5745  TP_DOMAIN *element_domain;
5746  DB_TYPE set_type;
5747  int size, fixed_element_size, element_size, offset, offset2, bit, i;
5748  int length, bits;
5749  unsigned int bound_word;
5750  char *offset_ptr, *bound_ptr;
5751  char *set_start;
5752  int has_domain, bound_bits, offset_table, element_tags;
5753  TP_DOMAIN *set_domain;
5754  int rc = NO_ERROR;
5755 
5756  set_start = buf->ptr;
5757 
5758  /* read the set header and decompose the various flags */
5759  or_get_set_header (buf, &set_type, &size, &has_domain, &bound_bits, &offset_table, &element_tags, NULL);
5760 
5761  set = setobj_create (set_type, size);
5762  if (set == NULL)
5763  {
5764  or_abort (buf);
5765  return NULL;
5766  }
5767 
5768  /*
5769  * If a domain was supplied, stick it in the set, probably should do a
5770  * sanity check in this and the doamin stored in the set. The domain
5771  * MUST be passed if the set was packed with the "include_domain" domain
5772  * flag at zero.
5773  */
5774  setobj_put_domain (set, domain);
5775 
5776  /* prepare for an offset table or bound bit array */
5777  offset_ptr = NULL;
5778  bound_ptr = NULL;
5779  offset = 0;
5780  bound_word = 0;
5781  if (offset_table)
5782  {
5783  offset_ptr = buf->ptr;
5784  or_advance (buf, OR_VAR_TABLE_SIZE (size));
5785  }
5786  else if (bound_bits)
5787  {
5788  bound_ptr = buf->ptr;
5789  or_advance (buf, OR_BOUND_BIT_BYTES (size));
5790  }
5791 
5792  if (has_domain)
5793  {
5794  (void) or_get_int (buf, &rc); /* skip the domain size */
5795  /* the domain returned here will be cached */
5796  setobj_put_domain (set, or_get_domain (buf, domain, NULL));
5797  /* If this is stored and the caller has supplied one as an argument to this function, they should be the same.
5798  * Might want to check this here. */
5799  }
5800 
5801  /*
5802  * Calculate the length of the fixed width elements if that's what we have.
5803  * This looks like it should be a little utilitiy function.
5804  */
5805  element_domain = NULL;
5806  fixed_element_size = -1;
5807  set_domain = setobj_domain (set);
5808 
5809  if (set_domain != NULL && set_domain->setdomain != NULL && set_domain->setdomain->next == NULL)
5810  {
5811  /* we only have one possible element domain */
5812  fixed_element_size = tp_domain_disk_size (set_domain->setdomain);
5813  element_domain = set_domain->setdomain;
5814  }
5815 
5816  if (size)
5817  {
5818  /* read the first offset or bound word */
5819  if (offset_table)
5820  {
5821  offset = OR_GET_OFFSET (offset_ptr);
5822  offset_ptr += BIG_VAR_OFFSET_SIZE;
5823  }
5824  else if (bound_bits)
5825  {
5826  bound_word = OR_GET_INT (bound_ptr);
5827  }
5828 
5829  /* loop over each element */
5830  for (i = 0; i < size; i++)
5831  {
5832 
5833  /* determine the length of the element if there is an offset table */
5834  element_size = -1;
5835  if (offset_ptr != NULL)
5836  {
5837  offset2 = OR_GET_OFFSET (offset_ptr);
5838  offset_ptr += BIG_VAR_OFFSET_SIZE;
5839  element_size = offset2 - offset;
5840  offset = offset2;
5841  }
5842  else if (bound_ptr != NULL)
5843  {
5844  element_size = fixed_element_size; /* this must be fixed width! */
5845  bit = i & 0x1F;
5846  if ((bound_word & (1L << bit)) == 0)
5847  {
5848  element_size = 0; /* its NULL */
5849  }
5850  if (bit == 0x1F)
5851  {
5852  bound_ptr += OR_INT_SIZE;
5853  bound_word = OR_GET_INT (bound_ptr);
5854  }
5855  }
5856 
5857  /*
5858  * 8 element_size will now be 0 if NULL, the true size, or -1 if * variable or unknown. */
5859 
5860  /* Read the element. */
5861  if (element_size == 0)
5862  {
5863  /*
5864  * we have to initlaize the domain too, since a set can
5865  * have several possible domains, just pick the first one.
5866  * Actually,for wildcard sets, we won't have a domain to select.
5867  * Since I guess the NULL "domain" can logically be a part of all
5868  * sets, initialize the domain for NULL.
5869  */
5871  db_make_null (&value);
5872  /*
5873  * if this is a fixed width element array, skip over the null
5874  * data
5875  */
5876  if (bound_ptr != NULL)
5877  {
5878  or_advance (buf, fixed_element_size);
5879  }
5880  }
5881  else
5882  {
5883  /*
5884  * read a packed value, pass the domain only if the
5885  * values are not tagged already tagged.
5886  */
5887  if (element_tags)
5888  {
5889  or_get_value (buf, &value, NULL, element_size, true);
5890  }
5891  else
5892  {
5893  or_get_value (buf, &value, element_domain, element_size, true);
5894  }
5895  }
5896 
5897  /*
5898  * This setobj interface function passes "ownership" of the memory
5899  * of value to the set. value need not be cleared after this call,
5900  * as its internal memory pointers are copied directly to the set
5901  * This function should only be used in construction of internal
5902  * setobj structure from temporary DB_VALUE's.
5903  */
5904  if (setobj_put_value (set, i, &value) != NO_ERROR)
5905  {
5906  /* if value not added to set, clear it */
5907  pr_clear_value (&value);
5908  }
5909  }
5910  }
5911 
5912  /* sets are always paded, cosume the padding */
5913  length = (int) (buf->ptr - set_start);
5914  bits = length & 3;
5915  if (bits)
5916  {
5917  or_advance (buf, 4 - bits);
5918  }
5919 
5920  return set;
5921 }
5922 
5923 /*
5924  * or_disk_set_size - determine set length.
5925  * return: set length
5926  * buf(in/out): or buffer
5927  * set_domain(in/out):
5928  * set_type(out): set type
5929  * Note:
5930  * This routine will leave the OR_BUF unaltered (pointing to the beginning
5931  * of the set.
5932  */
5933 int
5934 or_disk_set_size (OR_BUF * buf, TP_DOMAIN * set_domain, DB_TYPE * set_type)
5935 {
5936  TP_DOMAIN *element_domain;
5937  DB_TYPE disk_set_type;
5938  int size, fixed_element_size, element_size, offset, offset2, bit;
5939  int length, bits, i, total_length;
5940  unsigned int bound_word;
5941  char *offset_ptr, *bound_ptr;
5942  char *set_start;
5943  int has_domain, bound_bits, offset_table, element_tags;
5944  int rc = NO_ERROR;
5945 
5946  total_length = 0;
5947  set_start = buf->ptr;
5948 
5949  /* read the set header and decompose the various flags */
5950  or_get_set_header (buf, &disk_set_type, &size, &has_domain, &bound_bits, &offset_table, &element_tags, NULL);
5951 
5952  if (set_type)
5953  {
5954  *set_type = disk_set_type;
5955  }
5956 
5957  /* prepare for an offset table or bound bit array */
5958  offset_ptr = NULL;
5959  bound_ptr = NULL;
5960  offset = 0;
5961  bound_word = 0;
5962 
5963  if (offset_table)
5964  {
5965  offset_ptr = buf->ptr;
5966  or_advance (buf, OR_VAR_TABLE_SIZE (size));
5967  }
5968  else if (bound_bits)
5969  {
5970  bound_ptr = buf->ptr;
5971  or_advance (buf, OR_BOUND_BIT_BYTES (size));
5972  }
5973 
5974  if (has_domain)
5975  {
5976  (void) or_get_int (buf, &rc); /* skip the domain size */
5977  /* we have to unpack the domain */
5978  set_domain = or_get_domain (buf, set_domain, NULL);
5979  }
5980 
5981  /*
5982  * Calculate the length of the fixed width elements if that's what we have.
5983  * This looks like it should be a little utilitiy function.
5984  */
5985  element_domain = NULL;
5986  fixed_element_size = -1;
5987  if (set_domain != NULL && set_domain->setdomain != NULL && set_domain->setdomain->next == NULL)
5988  {
5989  /* we only have one possible element domain */
5990  fixed_element_size = tp_domain_disk_size (set_domain->setdomain);
5991  element_domain = set_domain->setdomain;
5992  }
5993 
5994  if (size)
5995  {
5996  /* read the first offset or bound word */
5997  if (offset_table)
5998  {
5999  offset = OR_GET_OFFSET (offset_ptr);
6000  offset_ptr += BIG_VAR_OFFSET_SIZE;
6001  }
6002  else if (bound_bits)
6003  {
6004  bound_word = OR_GET_INT (bound_ptr);
6005  }
6006 
6007  /* loop over each element */
6008  for (i = 0; i < size; i++)
6009  {
6010  /* determine the length of the element if there is an offset table */
6011  element_size = -1;
6012  if (offset_ptr != NULL)
6013  {
6014  offset2 = OR_GET_OFFSET (offset_ptr);
6015  offset_ptr += BIG_VAR_OFFSET_SIZE;
6016  element_size = offset2 - offset;
6017  offset = offset2;
6018  }
6019  else if (bound_ptr != NULL)
6020  {
6021  element_size = fixed_element_size; /* this must be fixed width! */
6022  bit = i & 0x1F;
6023  if ((bound_word & (1L << bit)) == 0)
6024  {
6025  element_size = 0; /* its NULL */
6026  }
6027 
6028  if (bit == 0x1F)
6029  {
6030  bound_ptr += OR_INT_SIZE;
6031  bound_word = OR_GET_INT (bound_ptr);
6032  }
6033  }
6034 
6035  /*
6036  * element_size will now be 0 if NULL, the true size, or -1 if
6037  * variable or unknown.
6038  */
6039 
6040  /*
6041  * Skip the element, we may have to actually unpack the element
6042  * to do this (if the size is variable), but no storage should be
6043  * allocated.
6044  */
6045  if (element_size == 0)
6046  {
6047  /*
6048  * if this is a fixed width element array, skip over the null
6049  * data
6050  */
6051  if (bound_ptr != NULL)
6052  {
6053  or_advance (buf, fixed_element_size);
6054  }
6055  }
6056  else if (element_size != -1)
6057  {
6058  /* in this case we can simply skip the element */
6059  or_advance (buf, element_size);
6060  }
6061  else
6062  {
6063  /* skip a packed value, pass the domain only if the values are not already tagged. The NULL db_value
6064  * tells the routine to skip the value rather than actually unpack it into a db_value container. */
6065  if (element_tags)
6066  {
6067  or_get_value (buf, NULL, NULL, element_size, true);
6068  }
6069  else
6070  {
6071  or_get_value (buf, NULL, element_domain, element_size, true);
6072  }
6073  }
6074  }
6075  }
6076 
6077  /* sets are always paded, consume the padding */
6078  length = (int) (buf->ptr - set_start);
6079  bits = length & 3;
6080  if (bits)
6081  {
6082  or_advance (buf, 4 - bits);
6083  }
6084 
6085  total_length = (int) (buf->ptr - set_start);
6086 
6087  /* reset the OR_BUF so that it looks like we didn't do anything */
6088  buf->ptr = set_start;
6089 
6090  return total_length;
6091 }
6092 
6093 /*
6094  * VALUE PACKING
6095  */
6096 
6097 /*
6098  * or_packed_value_size - calculating the size of the packed representation of
6099  * a value.
6100  * return: packed size in bytes
6101  * value(in): pointer to value
6102  * collapse_null(in): non-zero to "collapse" null values
6103  * include_domain(in): non-zero to include a domain tag
6104  * include_domain_classoids(in): non-zero to include the domain class OIDs
6105  */
6106 int
6107 or_packed_value_size (const DB_VALUE * value, int collapse_null, int include_domain, int include_domain_classoids)
6108 {
6109  PR_TYPE *type;
6110  TP_DOMAIN *domain;
6111  int size = 0, bits;
6112  DB_TYPE dbval_type;
6113 
6114  if (value == NULL)
6115  {
6116  return 0;
6117  }
6118 
6119  dbval_type = DB_VALUE_DOMAIN_TYPE (value);
6120  type = pr_type_from_id (dbval_type);
6121 
6122  if (type == NULL)
6123  {
6124  return 0;
6125  }
6126 
6127  /* If the value is NULL, either pack nothing or pack the domain with the special null flag enabled. */
6128  if (DB_VALUE_TYPE (value) == DB_TYPE_NULL)
6129  {
6130  if (!collapse_null || include_domain)
6131  {
6132  domain = tp_domain_resolve_value (value, NULL);
6133  if (domain != NULL)
6134  {
6135  size = or_packed_domain_size (domain, include_domain_classoids);
6136  }
6137  else
6138  {
6140  }
6141  }
6142  }
6143  else
6144  {
6145  if (include_domain)
6146  {
6147  domain = tp_domain_resolve_value (value, NULL);
6148  if (domain != NULL)
6149  {
6150  size = or_packed_domain_size (domain, include_domain_classoids);
6151  }
6152  else
6153  {
6154  /* shouldn't get here ! */
6156  return size;
6157  }
6158  }
6159  size += type->get_disk_size_of_value (value);
6160  }
6161 
6162  /* Values must as a unit be aligned to a word boundary. We can't do this inside the writeval function because that
6163  * may be used to place data inside disk structures that don't have alignment requirements. */
6164  if (include_domain)
6165  {
6166  bits = size & 3;
6167  if (bits)
6168  {
6169  size += (4 - bits);
6170  }
6171  }
6172 
6173  return size;
6174 }
6175 
6176 
6177 /*
6178  * or_put_value - pack a value
6179  * return: error on overflow
6180  * buf(out): packing buffer
6181  * value(in): value to ponder
6182  * collapse_null(in): non-zero to "collapse" null values
6183  * include_domain(in): non-zero to include a domain tag
6184  * include_domain_classoids(in): non-zero to include the domain class OIDs
6185  */
6186 int
6187 or_put_value (OR_BUF * buf, DB_VALUE * value, int collapse_null, int include_domain, int include_domain_classoids)
6188 {
6189  PR_TYPE *type;
6190  TP_DOMAIN *domain;
6191  char *start, length, bits;
6192  int rc = NO_ERROR;
6193  DB_TYPE dbval_type;
6194 
6195  if (value == NULL)
6196  {
6197  return ER_FAILED;
6198  }
6199 
6200  dbval_type = DB_VALUE_DOMAIN_TYPE (value);
6201  type = pr_type_from_id (dbval_type);
6202 
6203  if (type == NULL)
6204  {
6205  return ER_FAILED;
6206  }
6207 
6208  start = buf->ptr;
6209 
6210  if (DB_VALUE_TYPE (value) == DB_TYPE_NULL)
6211  {
6212  if (!collapse_null || include_domain)
6213  {
6214  domain = tp_domain_resolve_value (value, NULL);
6215  if (domain != NULL)
6216  {
6217  rc = or_put_domain (buf, domain, include_domain_classoids, 1);
6218  }
6219  else
6220  {
6221  /* shouldn't get here */
6222  rc = or_put_domain (buf, &tp_Null_domain, 0, 1);
6223  }
6224  }
6225  }
6226  else
6227  {
6228  if (include_domain)
6229  {
6230  domain = tp_domain_resolve_value (value, NULL);
6231  if (domain != NULL)
6232  {
6233  rc = or_put_domain (buf, domain, include_domain_classoids, 0);
6234  }
6235  else
6236  {
6237  /* shouldn't get here */
6238  rc = or_put_domain (buf, &tp_Null_domain, 0, 1);
6239  return NO_ERROR;
6240  }
6241  }
6242  /* probably should blow off writing the value if we couldn't determine the domain ? */
6243  if (rc == NO_ERROR)
6244  {
6245  rc = type->data_writeval (buf, value);
6246  }
6247  }
6248 
6249  /*
6250  * Values must as a unit be aligned to a word boundary. We can't do this
6251  * inside the writeval function becaue that may be used to place data inside
6252  * disk structures that don't have alignment requirements.
6253  */
6254  if (rc == NO_ERROR)
6255  {
6256  if (include_domain)
6257  {
6258  length = (int) (buf->ptr - start);
6259  bits = length & 3;
6260  if (bits)
6261  {
6262  rc = or_pad (buf, 4 - bits);
6263  }
6264  }
6265  }
6266  return rc;
6267 }
6268 
6269 
6270 /*
6271  * or_get_value - extracts a packed DB_VALUE
6272  * return: none
6273  * buf(in/out): packing buffer
6274  * value(out): value to ponder
6275  * domain(out): domain to use (optional, only if the value is not tagged)
6276  * expected(out): expected size of the value (optional, can be -1)
6277  * copy(in):
6278  * Note:
6279  * This extracts a packed DB_VALUE and whetever it contains.
6280  * If the value is tagged with its own domain, the domain argument to
6281  * this function must be NULL. If the value is not tagged, the
6282  * domain argument must be specified.
6283  *
6284  * The expected size is probably not necessary but its been passed around
6285  * for so long, I'm reluctant to yank it right now. It can be -1 if
6286  * we don't know the size but in that case we must be able to determine
6287  * the packed size by looking at the domain or by the looking
6288  * at the value header.
6289  *
6290  * The value can be NULL, in which case, we will simply advance the
6291  * OR_BUF past the current value.
6292  *
6293  */
6294 int
6295 or_get_value (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int expected, bool copy)
6296 {
6297  char *start;
6298  int is_null, total, pad;
6299  int rc = NO_ERROR;
6300 
6301  is_null = 0;
6302  start = buf->ptr;
6303 
6304  /*
6305  * Always make sure this is properly initialized.
6306  * If the domain is given here, we could use that for further initialization ?
6307  */
6308  if (value)
6309  {
6310  db_make_null (value);
6311  }
6312 
6313  /* If size is zero, this must have been a "collapsed" NULL value. */
6314  if (expected == 0)
6315  {
6316  return NO_ERROR;
6317  }
6318 
6319  /*
6320  * If a domain was supplied, use it to decode the value, otherwise we
6321  * assume that the vlaues must be tagged.
6322  */
6323  if (domain == NULL)
6324  {
6325  domain = or_get_domain (buf, NULL, &is_null);
6326  if (expected >= 0)
6327  {
6328  /* reduce the expected size by the amount consumed with the domain tag */
6329  expected -= CAST_BUFLEN (buf->ptr - start);
6330  start = buf->ptr;
6331  }
6332  }
6333 
6334  if (domain == NULL)
6335  {
6336  /* problems decoding the domain */
6338  or_abort (buf);
6339  return ER_FAILED;
6340  }
6341  else
6342  {
6343  if (value)
6344  {
6345  tp_init_value_domain (domain, value);
6346  }
6347 
6348  if (is_null && value)
6349  {
6350  /* this was a tagged NULL value, restore the domain but set the null flag */
6351  db_value_put_null (value);
6352 
6353  if (TP_IS_CHAR_TYPE (TP_DOMAIN_TYPE (domain)))
6354  {
6356  }
6357  else if (TP_DOMAIN_TYPE (domain) == DB_TYPE_ENUMERATION)
6358  {
6360  }
6361  else if (TP_DOMAIN_TYPE (domain) == DB_TYPE_JSON)
6362  {
6363  /* TODO find if schema_raw set here is ever used */
6364  value->data.json.schema_raw = NULL;
6365  }
6366  }
6367  else
6368  {
6369  if (value)
6370  {
6371  domain->type->data_readval (buf, value, domain, expected, copy, NULL, 0);
6372  }
6373  else
6374  {
6375  /* the NULL value, will cause readval to skip the value */
6376  domain->type->data_readval (buf, NULL, domain, expected, false, NULL, 0);
6377  }
6378 
6379  if (rc != NO_ERROR)
6380  {
6381  return rc;
6382  }
6383  }
6384  }
6385 
6386  /* Consume any padding bytes that may be left over. If the expected size was given, use that to determine the amount
6387  * of padding, otherwise we'll have to assume that we just need to be brought up to a word boundary. */
6388  total = (int) (buf->ptr - start);
6389  pad = 0;
6390  if (expected > 0)
6391  {
6392  pad = expected - total;
6393  }
6394  else if (expected < 0)
6395  {
6396  if (total & 3)
6397  pad = 4 - (total & 3);
6398  }
6399  if (pad > 0)
6400  {
6401  rc = or_advance (buf, pad);
6402  }
6403  return rc;
6404 }
6405 
6406 
6407 /*
6408  * or_pack_value - alternative interface to or_put_value
6409  * return: advanced pointer
6410  * buf(out): buffer pointer
6411  * value(in): value to store
6412  * Note:
6413  * Alternate interface to or_put_value, see that function for more
6414  * information.
6415  * Doesn't accept all of the fields required by or_put_value because
6416  * I don't think we need that level of control. May need to add
6417  * them later though.
6418  */
6419 char *
6420 or_pack_value (char *buf, DB_VALUE * value)
6421 {
6422  OR_BUF orbuf;
6423  char *aligned_buf;
6424 
6425  aligned_buf = PTR_ALIGN (buf, MAX_ALIGNMENT);
6426 
6427  or_init (&orbuf, aligned_buf, 0);
6428  /* don't collapse nulls, include the domain, and include domain class oids */
6429  or_put_value (&orbuf, value, 0, 1, 1);
6430 
6431  return orbuf.ptr;
6432 }
6433 
6434 char *
6435 or_pack_mem_value (char *ptr, DB_VALUE * value, int *packed_len_except_alignment)
6436 {
6437  OR_BUF orbuf, *buf;
6438  PR_TYPE *type;
6439  TP_DOMAIN *domain;
6440  char *start, length, bits;
6441  char *ptr_to_packed_value;
6442  int rc = NO_ERROR;
6443  DB_TYPE dbval_type;
6444 
6445  if (value == NULL)
6446  {
6447  return NULL;
6448  }
6449 
6450  buf = &orbuf;
6451  or_init (buf, ptr, 0);
6452  start = buf->ptr;
6453 
6454  or_get_align64 (buf);
6455 
6456  /* notice that it points to real starting ptr to packed value */
6457  ptr_to_packed_value = buf->ptr;
6458 
6459  dbval_type = DB_VALUE_DOMAIN_TYPE (value);
6460  type = pr_type_from_id (dbval_type);
6461  if (type == NULL)
6462  {
6463  return NULL;
6464  }
6465 
6466  if (DB_VALUE_TYPE (value) == DB_TYPE_NULL)
6467  {
6468  domain = tp_domain_resolve_value (value, NULL);
6469  if (domain != NULL)
6470  {
6471  rc = or_put_domain (buf, domain, 1, 1);
6472  }
6473  else
6474  {
6475  /* shouldn't get here */
6476  rc = or_put_domain (buf, &tp_Null_domain, 0, 1);
6477  }
6478  }
6479  else
6480  {
6481  domain = tp_domain_resolve_value (value, NULL);
6482  if (domain != NULL)
6483  {
6484  rc = or_put_domain (buf, domain, 1, 0);
6485  }
6486  else
6487  {
6488  /* shouldn't get here */
6489  rc = or_put_domain (buf, &tp_Null_domain, 0, 1);
6490  return buf->ptr;
6491  }
6492 
6493  if (rc == NO_ERROR)
6494  {
6495  or_get_align64 (buf);
6496  rc = type->data_writeval (buf, value);
6497  }
6498  }
6499 
6500  if (rc == NO_ERROR)
6501  {
6502  if (packed_len_except_alignment)
6503  {
6504  /* it excludes both leading and trailing alignments */
6505  *packed_len_except_alignment = (int) (buf->ptr - ptr_to_packed_value);
6506  }
6507 
6508  length = (int) (buf->ptr - start);
6509  bits = length & 3;
6510  if (bits)
6511  {
6512  rc = or_pad (buf, 4 - bits);
6513  }
6514 
6515  }
6516 
6517  return buf->ptr;
6518 }
6519 
6520 
6521 /*
6522  * or_unpack_value - alternate interface to or_get_value
6523  * return: advanced pointer
6524  * buf(in): buffer
6525  * value(out): value to unpack
6526  * Note:
6527  * Alternate interface to or_get_value, see that function for more
6528  * details.
6529  */
6530 char *
6531 or_unpack_value (const char *buf, DB_VALUE * value)
6532 {
6533  OR_BUF orbuf;
6534 
6535  buf = PTR_ALIGN (buf, MAX_ALIGNMENT);
6536  or_init (&orbuf, CONST_CAST (char *, buf) /* it is for read */ , 0);
6537  or_get_value (&orbuf, value, NULL, -1, true);
6538 
6539  return orbuf.ptr;
6540 }
6541 
6542 char *
6543 or_unpack_mem_value (char *ptr, DB_VALUE * value)
6544 {
6545  OR_BUF orbuf, *buf;
6546  TP_DOMAIN *domain;
6547  int is_null, rc = NO_ERROR;
6548  int total, pad;
6549  char *start;
6550 
6551  buf = &orbuf;
6552  or_init (buf, ptr, 0);
6553  start = buf->ptr;
6554  is_null = 0;
6555 
6556  or_get_align64 (buf);
6557 
6558  if (value)
6559  {
6560  db_make_null (value);
6561  }
6562 
6563  domain = or_get_domain (buf, NULL, &is_null);
6564  if (domain == NULL)
6565  {
6566  return NULL;
6567  }
6568  else if (is_null)
6569  {
6570  return buf->ptr;
6571  }
6572 
6573  or_get_align64 (buf);
6574  tp_init_value_domain (domain, value);
6575  if (is_null)
6576  {
6577  db_value_put_null (value);
6578  }
6579  else
6580  {
6581  rc = domain->type->data_readval (buf, value, domain, -1, true, NULL, 0);
6582  if (rc != NO_ERROR)
6583  {
6584  return NULL;
6585  }
6586  }
6587 
6588  total = (int) (buf->ptr - start);
6589  pad = 0;
6590  if (total & 3)
6591  {
6592  pad = 4 - (total & 3);
6593  }
6594  if (pad > 0)
6595  {
6596  rc = or_advance (buf, pad);
6597  }
6598 
6599  if (rc != NO_ERROR)
6600  {
6601  return NULL;
6602  }
6603 
6604  return buf->ptr;
6605 }
6606 
6607 /*
6608  * LIST ID PACKING
6609  */
6610 
6611 /*
6612  * or_pack_listid - packs a QFILE_LIST_ID descriptor
6613  * return: advanced buffer pointer
6614  * ptr(out): starting pointer
6615  * listid_ptr(in): QFILE_LIST_ID pointer
6616  * Note:
6617  * This packs a QFILE_LIST_ID descriptor. The arguments are passed as void*
6618  * so we can avoid unfortunate circular dependencies between query_list.h
6619  * and or.h. query_list.h is included at the top of this file so we have
6620  * the information necessary for casting.
6621  * The QFILE_LIST_ID doesn't have an OR_PUT macro because it is significantly
6622  * more complex than the other types and may be of variable size.
6623  */
6624 char *
6625 or_pack_listid (char *ptr, void *listid_ptr)
6626 {
6627  QFILE_LIST_ID *listid;
6628  int i;
6629 
6630  listid = (QFILE_LIST_ID *) listid_ptr;
6631 
6632  OR_PUT_PTR (ptr, listid->query_id);
6633  ptr += OR_PTR_SIZE;
6634  OR_PUT_PTR (ptr, listid->tfile_vfid);
6635  ptr += OR_PTR_SIZE;
6636 
6637  OR_PUT_INT (ptr, listid->tuple_cnt);
6638  ptr += OR_INT_SIZE;
6639 
6640  OR_PUT_INT (ptr, listid->page_cnt);
6641  ptr += OR_INT_SIZE;
6642  OR_PUT_INT (ptr, listid->first_vpid.pageid);
6643  ptr += OR_INT_SIZE;
6644  OR_PUT_INT (ptr, listid->first_vpid.volid);
6645  ptr += OR_INT_SIZE;
6646 
6647  OR_PUT_INT (ptr, listid->last_vpid.pageid);
6648  ptr += OR_INT_SIZE;
6649  OR_PUT_INT (ptr, listid->last_vpid.volid);
6650  ptr += OR_INT_SIZE;
6651 
6652  OR_PUT_INT (ptr, listid->last_offset);
6653  ptr += OR_INT_SIZE;
6654  OR_PUT_INT (ptr, listid->lasttpl_len);
6655  ptr += OR_INT_SIZE;
6656  OR_PUT_INT (ptr, listid->type_list.type_cnt);
6657  ptr += OR_INT_SIZE;
6658 
6659  for (i = 0; i < listid->type_list.type_cnt; i++)
6660  {
6661  /* do we want to pack the class oids?? */
6662  ptr = or_pack_domain (ptr, listid->type_list.domp[i], 0, 0);
6663  }
6664 
6665  return ptr;
6666 }
6667 
6668 char *
6670 {
6671  RECDES *tmp_recdes = NULL;
6672  int length;
6673 
6674  if (buf == NULL)
6675  {
6676  return NULL;
6677  }
6678 
6679  buf = or_unpack_int (buf, &length);
6680  tmp_recdes = (RECDES *) malloc (sizeof (RECDES) + length);
6681  if (tmp_recdes == NULL)
6682  {
6684  return NULL;
6685  }
6686 
6687  tmp_recdes->area_size = length;
6688  tmp_recdes->length = length;
6689  tmp_recdes->data = ((char *) tmp_recdes) + sizeof (RECDES);
6690 
6691  buf = or_unpack_short (buf, &tmp_recdes->type);
6692  buf = or_unpack_stream (buf, tmp_recdes->data, length);
6693 
6694  *recdes = tmp_recdes;
6695  return buf;
6696 }
6697 
6698 /*
6699  * or_unpack_listid - This unpacks a QFILE_LIST_ID descriptor from a buffer.
6700  * return: advanced buffer pointer
6701  * ptr(in): starting pointer
6702  * listid_ptr(out):
6703  * Note:
6704  * This unpacks a QFILE_LIST_ID descriptor from a buffer.
6705  * Kludge, the arguments are passed in as void* so we can avoid
6706  * unfortunate circular dependencies between query_list.h and or.h
6707  * query_list.h is included at the top of this file so we have the
6708  * information necessary for casting.
6709  */
6710 char *
6711 or_unpack_listid (char *ptr, void *listid_ptr)
6712 {
6713  QFILE_LIST_ID *listid;
6714 
6715  listid = (QFILE_LIST_ID *) listid_ptr;
6716 
6717  QFILE_CLEAR_LIST_ID (listid);
6718 
6719  listid->query_id = OR_GET_PTR (ptr);
6720  ptr += OR_PTR_SIZE;
6721 
6722  listid->tfile_vfid = (struct qmgr_temp_file *) OR_GET_PTR (ptr);
6723  ptr += OR_PTR_SIZE;
6724 
6725  listid->tuple_cnt = OR_GET_INT (ptr);
6726  ptr += OR_INT_SIZE;
6727 
6728  listid->page_cnt = OR_GET_INT (ptr);
6729  ptr += OR_INT_SIZE;
6730 
6731  listid->first_vpid.pageid = OR_GET_INT (ptr);
6732  ptr += OR_INT_SIZE;
6733  listid->first_vpid.volid = OR_GET_INT (ptr);
6734  ptr += OR_INT_SIZE;
6735 
6736  listid->last_vpid.pageid = OR_GET_INT (ptr);
6737  ptr += OR_INT_SIZE;
6738  listid->last_vpid.volid = OR_GET_INT (ptr);
6739  ptr += OR_INT_SIZE;
6740 
6741  listid->last_offset = OR_GET_INT (ptr);
6742  ptr += OR_INT_SIZE;
6743  listid->lasttpl_len = OR_GET_INT (ptr);
6744  ptr += OR_INT_SIZE;
6745  listid->type_list.type_cnt = OR_GET_INT (ptr);
6746  ptr += OR_INT_SIZE;
6747 
6748  return ptr;
6749 }
6750 
6751 /*
6752  * or_unpack_unbound_listid - This unpacks a QFILE_LIST_ID descriptor from a buffer.
6753  * return: advanced buffer pointer
6754  * ptr(in): starting pointer
6755  * listid_ptr(out):
6756  * Note:
6757  * This is a malloc used version for or_unpack_listid
6758  */
6759 char *
6760 or_unpack_unbound_listid (char *ptr, void **listid_ptr)
6761 {
6762  QFILE_LIST_ID *listid;
6763  int count, i;
6764 
6765  /*
6766  * tuple_cnt 4, vfid.fileid 4, vfid.volid 2, attr_list.oid_flg 2,
6767  * attr_list.attr_cnt 4, attr_list.attr_id 4 * n
6768  */
6769 
6770  listid = (QFILE_LIST_ID *) malloc (sizeof (QFILE_LIST_ID));
6771  if (listid == NULL)
6772  {
6774  goto error;
6775  }
6776 
6777  ptr = or_unpack_listid (ptr, listid);
6778 
6779  count = listid->type_list.type_cnt;
6780  if (count < 0)
6781  {
6782  goto error;
6783  }
6784 
6785  if (count > 0)
6786  {
6787  listid->type_list.domp = (TP_DOMAIN **) malloc (sizeof (TP_DOMAIN *) * count);
6788 
6789  if (listid->type_list.domp == NULL)
6790  {
6792  goto error;
6793  }
6794 
6795  for (i = 0; i < count; i++)
6796  {
6797  ptr = or_unpack_domain (ptr, &listid->type_list.domp[i], NULL);
6798  }
6799  }
6800 
6801  *listid_ptr = (void *) listid;
6802  return ptr;
6803 
6804 error:
6805  if (listid)
6806  {
6807  free_and_init (listid);
6808  }
6809  return NULL;
6810 }
6811 
6812 /*
6813  * or_listid_length - Calculates the number of bytes required to store the
6814  * disk/comm representation of a QFILE_LIST_ID structure.
6815  * return: length of the list representation in bytes
6816  * listid_ptr(in): opaque pointer to QFILE_LIST_ID structure
6817  * Note:
6818  * Calculates the number of bytes required to store the disk/comm
6819  * representation of a QFILE_LIST_ID structure. These are of variable size.
6820  * Kludge, the arguments are passed in as void* so we can avoid
6821  * unfortunate circular dependencies between query_list.h and or.h
6822  * query_list.h is included at the top of this file so we have the
6823  * information necesary for casting.
6824  */
6825 int
6826 or_listid_length (void *listid_ptr)
6827 {
6828  QFILE_LIST_ID *listid;
6829  int length = 0;
6830  int i;
6831 
6832  listid = (QFILE_LIST_ID *) listid_ptr;
6833 
6834  if (listid == NULL)
6835  {
6836  return length;
6837  }
6838 
6839  /* QFILE_LIST_ID 9 fixed item tuple_cnt page_cnt first_vpid.pageid first_vpid.volid last_vpid.pageid last_vpid.volid
6840  * last_offset lasttpl_len type_list_type_cnt */
6841  length = OR_INT_SIZE * 9;
6842 
6843  for (i = 0; i < listid->type_list.type_cnt; i++)
6844  {
6845  length += or_packed_domain_size (listid->type_list.domp[i], 0);
6846  }
6847 
6848  length += OR_PTR_SIZE /* query_id */ + OR_PTR_SIZE; /* tfile_vfid */
6849  return length;
6850 }
6851 
6852 /*
6853  * or_pack_method_sig - packs a METHOD_SIG descriptor.
6854  * return: advanced buffer pointer
6855  * ptr(out): starting pointer
6856  * method_sig_ptr(in): opaque pointer to METHOD_SIG structure
6857  */
6858 static char *
6859 or_pack_method_sig (char *ptr, void *method_sig_ptr)
6860 {
6861  METHOD_SIG *method_sig = (METHOD_SIG *) method_sig_ptr;
6862  int n;
6863 
6864  if (method_sig == (METHOD_SIG *) 0)
6865  {
6866  return ptr;
6867  }
6868 
6869  ptr = or_pack_method_sig (ptr, method_sig->next);
6870  ptr = or_pack_string (ptr, method_sig->method_name);
6871  ptr = or_pack_string (ptr, method_sig->class_name);
6872  ptr = or_pack_int (ptr, method_sig->method_type);
6873  ptr = or_pack_int (ptr, method_sig->num_method_args);
6874 
6875  for (n = 0; n < method_sig->num_method_args + 1; n++)
6876  {
6877  ptr = or_pack_int (ptr, method_sig->method_arg_pos[n]);
6878  }
6879 
6880  return ptr;
6881 }
6882 
6883 /*
6884  * or_unpack_method_sig - unpacks a METHOD_SIG descriptor from a buffer.
6885  * return: advanced buffer pointer
6886  * ptr(in): starting pointer
6887  * method_sig_ptr(out): method_sig descriptor
6888  * n(in):
6889  */
6890 static char *
6891 or_unpack_method_sig (char *ptr, void **method_sig_ptr, int n)
6892 {
6893  METHOD_SIG *method_sig;
6894 
6895  if (n == 0)
6896  {
6897  *(METHOD_SIG **) method_sig_ptr = (METHOD_SIG *) 0;
6898  return ptr;
6899  }
6900  method_sig = (METHOD_SIG *) db_private_alloc (NULL, sizeof (METHOD_SIG));
6901 
6902  if (method_sig == (METHOD_SIG *) 0)
6903  {
6904  return NULL;
6905  }
6906  ptr = or_unpack_method_sig (ptr, (void **) &method_sig->next, n - 1);
6907  ptr = or_unpack_string (ptr, &method_sig->method_name);
6908  ptr = or_unpack_string (ptr, &method_sig->class_name);
6909  ptr = or_unpack_int (ptr, (int *) &method_sig->method_type);
6910  ptr = or_unpack_int (ptr, &method_sig->num_method_args);
6911 
6912  method_sig->method_arg_pos = (int *) db_private_alloc (NULL, sizeof (int) * (method_sig->num_method_args + 1));
6913  if (method_sig->method_arg_pos == (int *) 0)
6914  {
6915  db_private_free_and_init (NULL, method_sig);
6916  return NULL;
6917  }
6918 
6919  for (n = 0; n < method_sig->num_method_args + 1; n++)
6920  {
6921  ptr = or_unpack_int (ptr, &method_sig->method_arg_pos[n]);
6922  }
6923 
6924  *(METHOD_SIG **) method_sig_ptr = method_sig;
6925 
6926  return ptr;
6927 }
6928 
6929 /*
6930  * or_pack_method_sig_list - write a method signature list
6931  * return: advanced buffer pointer
6932  * ptr(out): starting pointer
6933  * method_sig_list_ptr(in): method_sig_list descriptor
6934  * Note:
6935  * This packs a METHOD_SIG_LIST descriptor.
6936  */
6937 char *
6938 or_pack_method_sig_list (char *ptr, void *method_sig_list_ptr)
6939 {
6940  METHOD_SIG_LIST *method_sig_list = (METHOD_SIG_LIST *) method_sig_list_ptr;
6941 
6942  ptr = or_pack_int (ptr, method_sig_list->num_methods);
6943 
6944 #if !defined(NDEBUG)
6945  {
6946  int i = 0;
6947  METHOD_SIG *sig;
6948 
6949  for (sig = method_sig_list->method_sig; sig; sig = sig->next)
6950  {
6951  i++;
6952  }
6953  assert (method_sig_list->num_methods == i);
6954  }
6955 #endif
6956 
6957  ptr = or_pack_method_sig (ptr, method_sig_list->method_sig);
6958  return ptr;
6959 }
6960 
6961 /*
6962  * or_unpack_method_sig_list - read a method signature list
6963  * return: advanced buffer pointer
6964  * ptr(in): starting pointer
6965  * method_sig_list_ptr(out): method_sig_list descriptor
6966  * Note:
6967  * This unpacks a METHOD_SIG_LIST descriptor from a buffer.
6968  */
6969 char *
6970 or_unpack_method_sig_list (char *ptr, void **method_sig_list_ptr)
6971 {
6973 
6974  method_sig_list = (METHOD_SIG_LIST *) db_private_alloc (NULL, sizeof (METHOD_SIG_LIST));
6975  if (method_sig_list == (METHOD_SIG_LIST *) 0)
6976  {
6977  return NULL;
6978  }
6979 
6980  ptr = or_unpack_int (ptr, &method_sig_list->num_methods);
6981  ptr = or_unpack_method_sig (ptr, (void **) &method_sig_list->method_sig, method_sig_list->num_methods);
6982 
6983 #if !defined(NDEBUG)
6984  {
6985  int i = 0;
6986  METHOD_SIG *sig;
6987 
6988  for (sig = method_sig_list->method_sig; sig; sig = sig->next)
6989  {
6990  i++;
6991  }
6992  assert (method_sig_list->num_methods == i);
6993  }
6994 #endif
6995 
6996  *(METHOD_SIG_LIST **) method_sig_list_ptr = method_sig_list;
6997 
6998  return ptr;
6999 }
7000 
7001 /*
7002  * or_method_sig_list_length - get the length of method signature list
7003  * return: length of METHOD_SIG_LIST in bytes.
7004  * method_sig_list_ptr(in): method_sig_list descriptor
7005  * Note:
7006  * Calculates the number of bytes required to store the disk/comm
7007  * representation of a METHOD_SIG_LIST structure.
7008  */
7009 int
7010 or_method_sig_list_length (void *method_sig_list_ptr)
7011 {
7012  METHOD_SIG_LIST *method_sig_list = (METHOD_SIG_LIST *) method_sig_list_ptr;
7013  METHOD_SIG *method_sig;
7014  int length = OR_INT_SIZE; /* num_methods */
7015  int n;
7016 
7017  for (n = 0, method_sig = method_sig_list->method_sig; n < method_sig_list->num_methods;
7018  ++n, method_sig = method_sig->next)
7019  {
7020  length += or_packed_string_length (method_sig->method_name, NULL);
7021  length += or_packed_string_length (method_sig->class_name, NULL);
7022  length += OR_INT_SIZE * 2; /* method_type & num_method_args */
7023  /* + object ptr */
7024  length += OR_INT_SIZE * (method_sig->num_method_args + 1);
7025  /* method_arg_pos */
7026  }
7027  return length;
7028 }
7029 
7030 /*
7031  * GENERIC DB_VALUE PACKING
7032  */
7033 
7034 /*
7035  * or_pack_db_value - write a DB_VALUE
7036  * return: advanced buffer pointer
7037  * buffer(out): output buffer
7038  * var(in): DB_VALUE
7039  */
7040 char *
7041 or_pack_db_value (char *buffer, DB_VALUE * var)
7042 {
7043  return or_pack_value (buffer, var);
7044 }
7045 
7046 /*
7047  * or_db_value_size - get the packed size of DB_VALUE
7048  * return: packed size
7049  * var(in): DB_VALUE
7050  */
7051 int
7053 {
7054  /* don't collapse nulls, include the domain, and include domain class oids */
7055  return or_packed_value_size (var, 0, 1, 1);
7056 }
7057 
7058 /*
7059  * or_unpack_db_value - read a DB_VALUE
7060  * return: advanced buffer pointer
7061  * buffer(in): input buffer
7062  * val(out): DB_VALUE
7063  */
7064 char *
7065 or_unpack_db_value (char *buffer, DB_VALUE * val)
7066 {
7067  /* new interface, hopefully compatible */
7068  return or_unpack_value (buffer, val);
7069 }
7070 
7071 /*
7072  * or_packed_enumeration_size () - get the packed size of an enumeration
7073  * return: packed size
7074  * enumeration (in): enumeration
7075  */
7076 int
7078 {
7079  int size = 0, idx;
7080  DB_VALUE value;
7081  DB_ENUM_ELEMENT *db_enum = NULL;
7082 
7083  if (enumeration->count == 0)
7084  {
7085  return 0;
7086  }
7087  /* an enumeration is packed as a collection of strings */
7088  size += OR_SET_HEADER_SIZE;
7089 
7090  for (idx = 0; idx < enumeration->count; idx++)
7091  {
7092  db_enum = &enumeration->elements[idx];
7093 
7097  size += tp_String.get_disk_size_of_value (&value);
7098  pr_clear_value (&value);
7099  }
7100 
7101  return size;
7102 }
7103 
7104 /*
7105  * or_put_enumeration () - pack an enumeration
7106  * return: error code or NO_ERROR
7107  * enumeration (in): enumeration
7108  */
7109 int
7110 or_put_enumeration (OR_BUF * buf, const DB_ENUMERATION * enumeration)
7111 {
7112  int rc = NO_ERROR, idx;
7113  DB_VALUE value;
7114  DB_ENUM_ELEMENT *db_enum = NULL;
7115 
7116  if (enumeration->count == 0)
7117  {
7118  return rc;
7119  }
7120  /* an enumeration is packed as a collection of strings */
7121  rc = or_put_set_header (buf, DB_TYPE_SEQUENCE, enumeration->count, 0, 0, 0, 0, 0);
7122  if (rc != NO_ERROR)
7123  {
7124  return rc;
7125  }
7126 
7127  for (idx = 0; idx < enumeration->count; idx++)
7128  {
7129  db_enum = &enumeration->elements[idx];
7132  enumeration->collation_id);
7133  rc = tp_String.data_writeval (buf, &value);
7134  pr_clear_value (&value);
7135 
7136  if (rc != NO_ERROR)
7137  {
7138  break;
7139  }
7140  }
7141 
7142  return rc;
7143 }
7144 
7145 /*
7146  * or_get_enumeration - read enumeration from input buffer
7147  * return: NO_ERROR or error code
7148  * buf(in): input buffer
7149  * enumeration(in/out): pointer to enumeration holder
7150  */
7151 int
7153 {
7154  DB_ENUM_ELEMENT *enum_vals = NULL, *db_enum = NULL;
7155  int idx = 0, count = 0, error = NO_ERROR;
7156  DB_VALUE value;
7157  char *enum_str = NULL;
7158  const char *value_str = NULL;
7159  int str_size = 0;
7160  LANG_COLLATION *lc;
7161 
7162  db_make_null (&value);
7163 
7164  if (enumeration == NULL)
7165  {
7166  assert (false);
7167  return ER_FAILED;
7168  }
7169 
7170  count = or_skip_set_header (buf);
7171 
7172  if (count <= 0)
7173  {
7174  /* set header is not packed if count is 0 so this should never happen */
7175  enumeration->count = 0;
7176  enumeration->elements = NULL;
7177  assert (false);
7178  return ER_FAILED;
7179  }
7180 
7181  enum_vals = (DB_ENUM_ELEMENT *) malloc (sizeof (DB_ENUM_ELEMENT) * count);
7182  if (enum_vals == NULL)
7183  {
7185  return ER_OUT_OF_VIRTUAL_MEMORY;
7186  }
7187 
7188  for (idx = 0; idx < count; idx++)
7189  {
7190  db_enum = &enum_vals[idx];
7191  /* enum values are indexed starting with 1 */
7192  db_enum->short_val = idx + 1;
7193 
7194  /*
7195  * Make sure this starts off initialized so "readval" won't try to free
7196  * any existing contents.
7197  */
7198  db_make_null (&value);
7199 
7200  error = tp_String.data_readval (buf, &value, NULL, -1, false, NULL, 0);
7201  if (error != NO_ERROR)
7202  {
7203  goto error_return;
7204  }
7205 
7206  DB_GET_ENUM_ELEM_DBCHAR (db_enum).info = value.data.ch.info;
7207  str_size = db_get_string_size (&value);
7208  enum_str = (char *) malloc (str_size + 1);
7209  if (enum_str == NULL)
7210  {
7212  (size_t) (db_get_string_size (&value) + 1));
7213 
7215  goto error_return;
7216  }
7217  value_str = db_get_string (&value);
7218  if (value_str)
7219  {
7220  memcpy (enum_str, value_str, str_size);
7221  }
7222  else
7223  {
7224  assert_release (str_size == 0);
7225  }
7226  enum_str[str_size] = 0;
7227 
7228  DB_SET_ENUM_ELEM_STRING (db_enum, enum_str);
7229  DB_SET_ENUM_ELEM_STRING_SIZE (db_enum, str_size);
7230 
7231  lc = lang_get_collation (enumeration->collation_id);
7232  assert (lc != NULL);
7233  DB_SET_ENUM_ELEM_CODESET (db_enum, lc->codeset);
7234 
7235  pr_clear_value (&value);
7236  }
7237 
7238  enumeration->count = count;
7239  enumeration->elements = enum_vals;
7240 
7241  return NO_ERROR;
7242 
7243 error_return:
7244  if (enum_vals != NULL)
7245  {
7246  for (--idx; idx >= 0; idx--)
7247  {
7248  free_and_init (DB_GET_ENUM_ELEM_STRING (&enum_vals[idx]));
7249  }
7250  free_and_init (enum_vals);
7251  }
7252  pr_clear_value (&value);
7253 
7254  enumeration->count = 0;
7255  enumeration->elements = NULL;
7256  return error;
7257 }
7258 
7259 /*
7260  * or_header_size () - Return the record header size.
7261  *
7262  * return : header size
7263  */
7264 int
7265 or_header_size (char *ptr)
7266 {
7268 }
7269 
7270 #if defined(ENABLE_UNUSED_FUNCTION)
7271 /*
7272  * or_packed_string_array_length - get the amount of space needed to pack an
7273  * array of strings.
7274  * return: packed string array length
7275  * count(in): element count
7276  * string_array(out): packed string array
7277  * Note:
7278  */
7279 int
7280 or_packed_string_array_length (int count, const char **string_array)
7281 {
7282  int i;
7283  int size = OR_INT_SIZE;
7284 
7285  for (i = 0; i < count; i++)
7286  {
7287  size += or_packed_string_length (string_array[i]);
7288  }
7289 
7290  return size;
7291 }
7292 
7293 /*
7294  * or_packed_db_value_array_length - get the amount of space needed to pack an
7295  * array of db_values.
7296  * return: packed db value array length
7297  * count(in): array size
7298  * val(in): DB_VALUE array
7299  */
7300 int
7301 or_packed_db_value_array_length (int count, DB_VALUE * val)
7302 {
7303  int i;
7304  int size = OR_INT_SIZE;
7305 
7306  for (i = 0; i < count; i++)
7307  {
7308  size += or_db_value_size (val++);
7309  }
7310  return size;
7311 }
7312 
7313 /*
7314  * or_pack_int_array - write a int array
7315  * return: advanced buffer pointer
7316  * buffer(out): output buffer
7317  * count(in): array length
7318  * int_array(in): int array
7319  */
7320 char *
7321 or_pack_int_array (char *buffer, int count, int *int_array)
7322 {
7323  int i;
7324  char *ptr;
7325 
7326  if (!int_array)
7327  {
7328  /* there are no values to pack, so pack a count of 0 */
7329  ptr = or_pack_int (buffer, 0);
7330  }
7331  else
7332  {
7333  /* pack count + that many integers */
7334  ptr = or_pack_int (buffer, count);
7335  for (i = 0; i < count; i++)
7336  {
7337  ptr = or_pack_int (ptr, int_array[i]);
7338  }
7339  }
7340  return ptr;
7341 }
7342 
7343 /*
7344  * or_pack_string_array - write a string array
7345  * return: advanced buffer pointer
7346  * buffer(out): output buffer
7347  * count(in): string array length
7348  * string_array(in): string array
7349  */
7350 char *
7351 or_pack_string_array (char *buffer, int count, const char **string_array)
7352 {
7353  int i;
7354  char *ptr;
7355 
7356  ptr = or_pack_int (buffer, count);
7357  for (i = 0; i < count; i++)
7358  {
7359  ptr = or_pack_string (ptr, string_array[i]);
7360  }
7361  return ptr;
7362 }
7363 
7364 /*
7365  * unpack_str_array - read array of string
7366  * return: advanced buffer pointer
7367  * buffer(in): input buffer
7368  * string_array(out): array of string
7369  * count(in): length of array
7370  */
7371 static char *
7372 unpack_str_array (char *buffer, char ***string_array, int count)
7373 {
7374  int i;
7375  char *ptr, **array_p;
7376 
7377  ptr = buffer;
7378  if (count <= 0)
7379  {
7380  if (string_array)
7381  {
7382  *string_array = NULL;
7383  }
7384  }
7385  else
7386  {
7387  *string_array = (char **) db_private_alloc (NULL, (sizeof (char *) * count));
7388  if (*string_array == NULL)
7389  {
7390  ptr = NULL;
7391  }
7392  else
7393  {
7394  for (array_p = *string_array, i = 0; i < count; i++, array_p++)
7395  {
7396  ptr = or_unpack_string (ptr, array_p);
7397  }
7398  }
7399  }
7400  return ptr;
7401 }
7402 
7403 /*
7404  * or_unpack_string_array -
7405  * return:
7406  * buffer():
7407  * string_array():
7408  * cnt():
7409  */
7410 char *
7411 or_unpack_string_array (char *buffer, char ***string_array, int *cnt)
7412 {
7413  char *ptr = or_unpack_int (buffer, cnt);
7414  return unpack_str_array (ptr, string_array, *cnt);
7415 }
7416 
7417 /*
7418  * or_pack_db_value_array - write a DB_VALUE array
7419  * return: advanced buffer pointer
7420  * buffer(out): output buffer
7421  * count(in): array length
7422  * val(in): DB_VALUE array
7423  */
7424 char *
7425 or_pack_db_value_array (char *buffer, int count, DB_VALUE * val)
7426 {
7427  int i;
7428  char *ptr;
7429 
7430  if (!buffer)
7431  {
7432  return NULL;
7433  }
7434 
7435  ptr = or_pack_int (buffer, count);
7436  for (i = 0; i < count; i++)
7437  {
7438  ptr = or_pack_db_value (ptr, val++);
7439  }
7440  return ptr;
7441 }
7442 
7443 /*
7444  * or_unpack_db_value_array - write a DB_VALUE array
7445  * return: advanced buffer pointer
7446  * buffer(in): input buffer
7447  * val(out): DB_VALUE array
7448  * count(in): array length
7449  */
7450 char *
7451 or_unpack_db_value_array (char *buffer, DB_VALUE ** val, int *count)
7452 {
7453  int i;
7454  char *ptr;
7455  DB_VALUE *local_val;
7456 
7457  if (!buffer)
7458  {
7459  return NULL;
7460  }
7461 
7462  ptr = or_unpack_int (buffer, count);
7463  if (*count)
7464  {
7465  *val = (DB_VALUE *) db_private_alloc (NULL, sizeof (DB_VALUE) * (*count));
7466  if (*val == NULL)
7467  {
7468  ptr = NULL;
7469  }
7470  else
7471  {
7472  local_val = *val;
7473  for (i = 0; i < *count; i++)
7474  {
7475  ptr = (char *) or_unpack_db_value (ptr, local_val++);
7476  }
7477  }
7478  }
7479 
7480  return ptr;
7481 }
7482 #endif /* ENABLE_UNUSED_FUNCTION */
7483 
7484 /*
7485  * or_pack_ptr - write pointer value to ptr
7486  * return: advanced buffer pointer
7487  * ptr(out): out buffer
7488  * ptrval(in): pointer value
7489  */
7490 char *
7491 or_pack_ptr (char *ptr, UINTPTR ptrval)
7492 {
7493  ptr = PTR_ALIGN (ptr, PTR_ALIGNMENT);
7494 
7495  OR_PUT_PTR (ptr, ptrval);
7496  return (ptr + OR_PTR_SIZE);
7497 }
7498 
7499 /*
7500  * or_unpack_ptr - read a pointer value
7501  * return: advanced buffer pointer
7502  * ptr(in): input buffer
7503  * ptrval(out): pointer value
7504  */
7505 char *
7506 or_unpack_ptr (char *ptr, UINTPTR * ptrval)
7507 {
7508  ptr = PTR_ALIGN (ptr, PTR_ALIGNMENT);
7509 
7510  *ptrval = OR_GET_PTR (ptr);
7511  return (ptr + OR_PTR_SIZE);
7512 }
7513 
7514 /*
7515  * MVCCID:
7516  */
7517 /*
7518  * or_put_mvccid () - Put an MVCCID to OR Buffer.
7519  *
7520  * return : Error code.
7521  * buf (in) : OR Buffer
7522  * mvccid (in) : MVCCID
7523  */
7524 int
7525 or_put_mvccid (OR_BUF * buf, MVCCID mvccid)
7526 {
7527  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
7528 
7529  if ((buf->ptr + OR_MVCCID_SIZE) > buf->endptr)
7530  {
7531  return (or_overflow (buf));
7532  }
7533  else
7534  {
7535  OR_PUT_MVCCID (buf->ptr, &mvccid);
7536  buf->ptr += OR_MVCCID_SIZE;
7537  }
7538  return NO_ERROR;
7539 }
7540 
7541 /*
7542  * or_get_mvccid - get bigint value from or buffer
7543  * return: bigint value read
7544  * buf(in/out): or buffer
7545  * error(out): NO_ERROR or error code
7546  */
7547 /*
7548  * or_get_mvccid () - Get an MVCCID from OR Buffer.
7549  *
7550  * return : MVCCID
7551  * buf (in/out) : OR Buffer.
7552  * error (out) : Error code.
7553  */
7554 int
7555 or_get_mvccid (OR_BUF * buf, MVCCID * mvccid)
7556 {
7557  assert (mvccid != NULL);
7558  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
7559 
7560  *mvccid = MVCCID_NULL;
7561 
7562  if ((buf->ptr + OR_MVCCID_SIZE) > buf->endptr)
7563  {
7564  return or_underflow (buf);
7565  }
7566  else
7567  {
7568  OR_GET_MVCCID (buf->ptr, mvccid);
7569  buf->ptr += OR_MVCCID_SIZE;
7570  }
7571  return NO_ERROR;
7572 }
7573 
7574 /*
7575  * or_pack_mvccid () - Pack an MVCCID at the give pointer.
7576  *
7577  * return : Pointer after the packed MVCCID.
7578  * ptr (in) : Pointer where to pack the MVCCID.
7579  * mvccid (in) : MVCCID to pack.
7580  */
7581 char *
7582 or_pack_mvccid (char *ptr, const MVCCID mvccid)
7583 {
7584  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
7585 
7586  OR_PUT_MVCCID (ptr, &mvccid);
7587  return (((char *) ptr) + OR_MVCCID_SIZE);
7588 }
7589 
7590 /*
7591  * or_unpack_mvccid () - Unpack an MVCCID from the give pointer.
7592  *
7593  * return : Pointer after the packed MVCCID.
7594  * ptr (in) : Pointer where the MVCCID is packed.
7595  * mvccid (out) : MVCCID value.
7596  */
7597 char *
7598 or_unpack_mvccid (char *ptr, MVCCID * mvccid)
7599 {
7600  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
7601  assert (mvccid != NULL);
7602 
7603  OR_GET_MVCCID (ptr, mvccid);
7604  return (((char *) ptr) + OR_MVCCID_SIZE);
7605 }
7606 
7607 /* SHA-1 */
7608 
7609 
7610 /*
7611  * or_pack_sha1 () - Pack SHA-1 hash.
7612  *
7613  * return : Pointer after packed.
7614  * ptr (in) : Pointer where to pack.
7615  * sha1 (in) : Value to pack.
7616  */
7617 char *
7618 or_pack_sha1 (char *ptr, const SHA1Hash * sha1)
7619 {
7620  assert (sha1 != NULL);
7621 
7622  if (ptr == NULL)
7623  {
7624  return NULL;
7625  }
7626 
7627  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
7628 
7629  OR_PUT_SHA1 (ptr, sha1);
7630  return ptr + OR_SHA1_SIZE;
7631 }
7632 
7633 /*
7634  * or_unpack_sha1 () - Unpack SHA-1 hash.
7635  *
7636  * return : Pointer after unpacked.
7637  * ptr (in) : Pointer where to unpack.
7638  * sha1 (out) : Value to unpack.
7639  */
7640 char *
7641 or_unpack_sha1 (char *ptr, SHA1Hash * sha1)
7642 {
7643  assert (sha1 != NULL);
7644 
7645  if (ptr == NULL)
7646  {
7647  memset (sha1, 0, sizeof (*sha1));
7648  return NULL;
7649  }
7650 
7651  ASSERT_ALIGN (ptr, INT_ALIGNMENT);
7652 
7653  OR_GET_SHA1 (ptr, sha1);
7654  return ptr + OR_SHA1_SIZE;
7655 }
7656 
7657 /*
7658  * LITTLE ENDIAN TRANSFORMATION FUNCTIONS
7659  */
7660 
7661 /*
7662  * little endian support functions.
7663  * Could just leave these in all the time.
7664  * Try to speed these up, consider making them inline.
7665  *
7666  */
7667 #if OR_BYTE_ORDER == OR_LITTLE_ENDIAN
7668 
7669 #if !defined (OR_HAVE_NTOHS)
7670 unsigned short
7671 ntohs (unsigned short from)
7672 {
7673  unsigned short to;
7674  char *ptr, *vptr;
7675 
7676  ptr = (char *) &from;
7677  vptr = (char *) &to;
7678  vptr[0] = ptr[1];
7679  vptr[1] = ptr[0];
7680 
7681  return to;
7682 }
7683 #endif /* !OR_HAVE_NTOHS */
7684 
7685 #if !defined (OR_HAVE_NTOHL)
7686 unsigned int
7687 ntohl (unsigned int from)
7688 {
7689  unsigned int to;
7690  char *ptr, *vptr;
7691 
7692  ptr = (char *) &from;
7693  vptr = (char *) &to;
7694  vptr[0] = ptr[3];
7695  vptr[1] = ptr[2];
7696  vptr[2] = ptr[1];
7697  vptr[3] = ptr[0];
7698 
7699  return to;
7700 }
7701 #endif /* !OR_HAVE_NTOHL */
7702 
7703 #if !defined (OR_HAVE_NTOHF)
7704 float
7705 ntohf (UINT32 from)
7706 {
7707  char *ptr, *vptr;
7708  float to;
7709 
7710  ptr = (char *) &from;
7711  vptr = (char *) &to;
7712  vptr[0] = ptr[3];
7713  vptr[1] = ptr[2];
7714  vptr[2] = ptr[1];
7715  vptr[3] = ptr[0];
7716 
7717  return to;
7718 }
7719 #endif /* !OR_HAVE_NTOHF */
7720 
7721 #if !defined (OR_HAVE_NTOHD)
7722 double
7723 ntohd (UINT64 from)
7724 {
7725  char *ptr, *vptr;
7726  double to;
7727 
7728  ptr = (char *) &from;
7729  vptr = (char *) &to;
7730  vptr[0] = ptr[7];
7731  vptr[1] = ptr[6];
7732  vptr[2] = ptr[5];
7733  vptr[3] = ptr[4];
7734  vptr[4] = ptr[3];
7735  vptr[5] = ptr[2];
7736  vptr[6] = ptr[1];
7737  vptr[7] = ptr[0];
7738 
7739  return to;
7740 }
7741 #endif /* !OR_HAVE_NTOHD */
7742 
7743 UINT64
7744 ntohi64 (UINT64 from)
7745 {
7746  UINT64 to;
7747  char *ptr, *vptr;
7748 
7749  ptr = (char *) &from;
7750  vptr = (char *) &to;
7751  vptr[0] = ptr[7];
7752  vptr[1] = ptr[6];
7753  vptr[2] = ptr[5];
7754  vptr[3] = ptr[4];
7755  vptr[4] = ptr[3];
7756  vptr[5] = ptr[2];
7757  vptr[6] = ptr[1];
7758  vptr[7] = ptr[0];
7759 
7760  return to;
7761 }
7762 
7763 #if !defined (OR_HAVE_HTONS)
7764 unsigned short
7765 htons (unsigned short from)
7766 {
7767  return ntohs (from);
7768 }
7769 #endif /* !OR_HAVE_HTONS */
7770 
7771 #if !defined (OR_HAVE_HTONL)
7772 unsigned int
7773 htonl (unsigned int from)
7774 {
7775  return ntohl (from);
7776 }
7777 #endif /* !OR_HAVE_HTONL */
7778 
7779 UINT64
7780 htoni64 (UINT64 from)
7781 {
7782  return ntohi64 (from);
7783 }
7784 
7785 #if !defined (OR_HAVE_HTONF)
7786 UINT32
7787 htonf (float from)
7788 {
7789  UINT32 to;
7790  char *p, *q;
7791 
7792  p = (char *) &from;
7793  q = (char *) &to;
7794 
7795  q[0] = p[3];
7796  q[1] = p[2];
7797  q[2] = p[1];
7798  q[3] = p[0];
7799 
7800  return to;
7801 }
7802 #endif /* !OR_HAVE_HTONL */
7803 
7804 #if !defined (OR_HAVE_HTOND)
7805 UINT64
7806 htond (double from)
7807 {
7808  UINT64 to;
7809  char *p, *q;
7810 
7811  p = (char *) &from;
7812  q = (char *) &to;
7813 
7814  q[0] = p[7];
7815  q[1] = p[6];
7816  q[2] = p[5];
7817  q[3] = p[4];
7818  q[4] = p[3];
7819  q[5] = p[2];
7820  q[6] = p[1];
7821  q[7] = p[0];
7822 
7823  return to;
7824 }
7825 #endif /* ! OR_HAVE_HTOND */
7826 
7827 #endif /* OR_BYTE_ORDER == OR_LITTLE_ENDIAN */
7828 
7829 /*
7830  * or_packed_spacedb_size () - compute the size required to pack all space info
7831  *
7832  * return : total required size
7833  * all (in) : aggregated space information
7834  * vols (in) : space information for each volume (may be NULL)
7835  * files (in) : space information for files (may be NULL)
7836  */
7837 int
7838 or_packed_spacedb_size (const SPACEDB_ALL * all, const SPACEDB_ONEVOL * vols, const SPACEDB_FILES * files)
7839 {
7840  int size_total = 0;
7841 
7842  /* for each type without any, pack nvols, npage_used, npage_free */
7843  size_total = SPACEDB_ALL_COUNT * 3 * OR_INT_SIZE;
7844 
7845  if (vols != NULL)
7846  {
7847  /* we need to pack information on each volume. */
7848  int size_onevol = 5 * OR_INT_SIZE; /* we have 5 int values without the name */
7849  int i;
7850 
7851  size_total += size_onevol * all[SPACEDB_TOTAL_ALL].nvols;
7852 
7853  /* also volume names */
7854  for (i = 0; i < all[SPACEDB_TOTAL_ALL].nvols; i++)
7855  {
7856  size_total += or_packed_string_length (vols[i].name, NULL);
7857  }
7858  }
7859 
7860  if (files != NULL)
7861  {
7862  /* for each type without any, pack nfile, npage_used, npage_ftab and npage_reserved */
7863  size_total += SPACEDB_FILE_COUNT * 4 * OR_INT_SIZE;
7864  }
7865 
7866  return size_total;
7867 }
7868 
7869 /*
7870  * or_pack_spacedb () - pack space info
7871  *
7872  * return : new pointer after packed space info
7873  * ptr (in) : destination pointer for packed space info
7874  * all (in) : aggregated space information
7875  * vols (in) : space information for each volume (may be NULL)
7876  * files (in) : space information for files (may be NULL)
7877  */
7878 char *
7879 or_pack_spacedb (char *ptr, const SPACEDB_ALL * all, const SPACEDB_ONEVOL * vols, const SPACEDB_FILES * files)
7880 {
7881  int i;
7882 
7883  /* all */
7884  for (i = 0; i < SPACEDB_ALL_COUNT; i++)
7885  {
7886  ptr = or_pack_int (ptr, (int) all[i].nvols);
7887  ptr = or_pack_int (ptr, (int) all[i].npage_used);
7888  ptr = or_pack_int (ptr, (int) all[i].npage_free);
7889  }
7890 
7891  /* vols */
7892  if (vols != NULL)
7893  {
7894  int iter_vol = 0;
7895  for (iter_vol = 0; iter_vol < all[SPACEDB_TOTAL_ALL].nvols; iter_vol++)
7896  {
7897  ptr = or_pack_int (ptr, (int) vols[iter_vol].volid);
7898  ptr = or_pack_int (ptr, (int) vols[iter_vol].type);
7899  ptr = or_pack_int (ptr, (int) vols[iter_vol].purpose);
7900  ptr = or_pack_int (ptr, (int) vols[iter_vol].npage_used);
7901  ptr = or_pack_int (ptr, (int) vols[iter_vol].npage_free);
7902  ptr = or_pack_string (ptr, vols[iter_vol].name);
7903  }
7904  }
7905 
7906  if (files != NULL)
7907  {
7908  for (i = 0; i < SPACEDB_FILE_COUNT; i++)
7909  {
7910  ptr = or_pack_int (ptr, files[i].nfile);
7911  ptr = or_pack_int (ptr, (int) files[i].npage_user);
7912  ptr = or_pack_int (ptr, (int) files[i].npage_ftab);
7913  ptr = or_pack_int (ptr, (int) files[i].npage_reserved);
7914  }
7915  }
7916 
7917  return ptr;
7918 }
7919 
7920 /*
7921  * or_unpack_spacedb () - document me!
7922  *
7923  * return :
7924  * char * ptr (in) :
7925  * SPACEDB_ALL * all (in) :
7926  * SPACEDB_ONEVOL * * vols (in) :
7927  * SPACEDB_FILES * files (in) :
7928  */
7929 char *
7930 or_unpack_spacedb (char *ptr, SPACEDB_ALL * all, SPACEDB_ONEVOL ** vols, SPACEDB_FILES * files)
7931 {
7932  int i;
7933  int unpacked_value;
7934  char *volname;
7935 
7936  assert (all != NULL);
7937  assert (vols == NULL || *vols == NULL);
7938 
7939  /* note: for all/files, total values are not packed. we'll compute them here, while unpacking */
7940 
7941  /* all */
7942  for (i = 0; i < SPACEDB_ALL_COUNT; i++)
7943  {
7944  ptr = or_unpack_int (ptr, &unpacked_value);
7945  all[i].nvols = (DKNVOLS) unpacked_value;
7946  ptr = or_unpack_int (ptr, &unpacked_value);
7947  all[i].npage_used = (DKNPAGES) unpacked_value;
7948  ptr = or_unpack_int (ptr, &unpacked_value);
7949  all[i].npage_free = (DKNPAGES) unpacked_value;
7950  }
7951 
7952  /* vols */
7953  if (vols != NULL)
7954  {
7955  int iter_vol = 0;
7956 
7957  *vols = (SPACEDB_ONEVOL *) malloc (all[SPACEDB_TOTAL_ALL].nvols * sizeof (SPACEDB_ONEVOL));
7958  if (*vols == NULL)
7959  {
7961  all[SPACEDB_TOTAL_ALL].nvols * sizeof (SPACEDB_ONEVOL));
7962  return NULL;
7963  }
7964 
7965  for (iter_vol = 0; iter_vol < all[SPACEDB_TOTAL_ALL].nvols; iter_vol++)
7966  {
7967  ptr = or_unpack_int (ptr, &unpacked_value);
7968  (*vols)[iter_vol].volid = (VOLID) unpacked_value;
7969  ptr = or_unpack_int (ptr, &unpacked_value);
7970  (*vols)[iter_vol].type = (DB_VOLTYPE) unpacked_value;
7971  ptr = or_unpack_int (ptr, &unpacked_value);
7972  (*vols)[iter_vol].purpose = (DB_VOLPURPOSE) unpacked_value;
7973  ptr = or_unpack_int (ptr, &unpacked_value);
7974  (*vols)[iter_vol].npage_used = (DKNPAGES) unpacked_value;
7975  ptr = or_unpack_int (ptr, &unpacked_value);
7976  (*vols)[iter_vol].npage_free = (DKNSECTS) unpacked_value;
7977  ptr = or_unpack_string_nocopy (ptr, &volname);
7978  if (volname == NULL)
7979  {
7980  return NULL;
7981  }
7982  strncpy ((*vols)[iter_vol].name, volname, DB_MAX_PATH_LENGTH);
7983  }
7984  }
7985 
7986  /* files */
7987  if (files != NULL)
7988  {
7989  for (i = 0; i < SPACEDB_FILE_COUNT; i++)
7990  {
7991  ptr = or_unpack_int (ptr, &files[i].nfile);
7992  ptr = or_unpack_int (ptr, &unpacked_value);
7993  files[i].npage_user = (DKNPAGES) unpacked_value;
7994  ptr = or_unpack_int (ptr, &unpacked_value);
7995  files[i].npage_ftab = (DKNPAGES) unpacked_value;
7996  ptr = or_unpack_int (ptr, &unpacked_value);
7997  files[i].npage_reserved = (DKNPAGES) unpacked_value;
7998  }
7999  }
8000 
8001  return ptr;
8002 }
8003 
8004 /*
8005  * this function also adds
8006  * the length of the string to the buffer
8007  */
8008 int
8010 {
8011  int len;
8012  int rc = NO_ERROR;
8013 
8014  if (str == NULL)
8015  {
8016  return rc;
8017  }
8018  len = (int) strlen (str) + 1;
8019 
8020  rc = or_put_int (buf, len);
8021  if (rc != NO_ERROR)
8022  {
8023  return rc;
8024  }
8025 
8026  rc = or_put_data (buf, str, len);
8027  if (rc == NO_ERROR)
8028  {
8029  or_align (buf, OR_INT_SIZE);
8030  }
8031  return rc;
8032 }
8033 
8034 /*
8035  * classobj_initialize_default_expr() - Initializes default expression
8036  * return: nothing
8037  *
8038  * default_expr(out): default expression
8039  */
8040 void
8042 {
8043  assert (default_expr != NULL);
8044 
8045  default_expr->default_expr_type = DB_DEFAULT_NONE;
8046  default_expr->default_expr_format = NULL;
8048 }
8049 
8050 int
8052 {
8053  int rc;
8054  char *str = NULL;
8055 
8056  rc = or_get_json_schema (buf, str);
8057  if (rc != NO_ERROR)
8058  {
8059  validator = NULL;
8060  goto exit;
8061  }
8062 
8063  if (str == NULL || strlen (str) == 0)
8064  {
8065  rc = NO_ERROR;
8066  validator = NULL;
8067  goto exit;
8068  }
8069  else
8070  {
8071  rc = db_json_load_validator (str, validator);
8072  if (rc != NO_ERROR)
8073  {
8074  ASSERT_ERROR ();
8075  assert (validator == NULL);
8076  goto exit;
8077  }
8078  rc = NO_ERROR;
8079  }
8080 
8081 exit:
8082  if (str != NULL)
8083  {
8085  }
8086  return rc;
8087 }
8088 
8089 int
8091 {
8093 }
8094 
8095 int
8096 or_get_json_schema (OR_BUF * buf, REFPTR (char, schema))
8097 {
8098  DB_VALUE schema_value;
8099  int rc;
8100 
8101  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
8102 
8103  rc = tp_String.data_readval (buf, &schema_value, NULL, -1, false, NULL, 0);
8104  if (rc != NO_ERROR)
8105  {
8106  return rc;
8107  }
8108 
8109  if (db_get_string_size (&schema_value) == 0)
8110  {
8111  schema = NULL;
8112  }
8113  else
8114  {
8115  schema = db_private_strdup (NULL, db_get_string (&schema_value));
8116  }
8117 
8118  pr_clear_value (&schema_value);
8119  return NO_ERROR;
8120 }
8121 
8122 int
8123 or_put_json_schema (OR_BUF * buf, const char *schema)
8124 {
8125  int rc = NO_ERROR;
8126  DB_VALUE schema_raw;
8127 
8128  ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
8129 
8130  if (schema == NULL)
8131  {
8132  db_make_string (&schema_raw, "");
8133  }
8134  else
8135  {
8136  db_make_string (&schema_raw, schema);
8137  }
8138 
8139  rc = tp_String.data_writeval (buf, &schema_raw);
8140  if (rc != NO_ERROR)
8141  {
8142  goto exit;
8143  }
8144 
8145 exit:
8146  pr_clear_value (&schema_raw);
8147  return rc;
8148 }
int or_put_align32(OR_BUF *buf)
char * or_unpack_oid_array(char *ptr, int n, OID **oids)
#define OR_GET_DATE(ptr, value)
#define OR_SET_VAR_OFFSET_SIZE(val, offset_size)
setobj * or_get_set(OR_BUF *buf, TP_DOMAIN *domain)
int or_put_sub_domain(OR_BUF *buf)
int or_advance(OR_BUF *buf, int offset)
#define QFILE_CLEAR_LIST_ID(list_id)
Definition: query_list.h:445
Definition: sha1.h:50
int data_readval(struct or_buf *buf, DB_VALUE *value, const tp_domain *domain, int size, bool copy, char *copy_buf, int copy_buf_len) const
#define OR_BTID_ALIGNED_SIZE
#define OR_PUT_OFFSET(ptr, val)
#define OR_GET_HFID(ptr, hfid)
struct or_fixup * fixups
OR_VARINFO * or_get_var_table_internal(OR_BUF *buf, int nvars, char *(*allocator)(int), int offset_size)
int tp_domain_disk_size(TP_DOMAIN *domain)
#define OR_DOMAIN_SCALE_MASK
#define OR_PUT_OID(ptr, oid)
#define OR_TIME_SIZE
#define OR_SET_TYPE_MASK
char * or_unpack_short(char *ptr, short *number)
void OR_PUT_FLOAT(char *ptr, float val)
#define NO_ERROR
Definition: error_code.h:46
int or_put_data(OR_BUF *buf, const char *data, int length)
int built_in_index
Definition: object_domain.h:89
int or_packed_spacedb_size(const SPACEDB_ALL *all, const SPACEDB_ONEVOL *vols, const SPACEDB_FILES *files)
#define DB_GET_ENUM_ELEM_STRING(elem)
Definition: dbtype.h:103
int area_size
int db_value_put_null(DB_VALUE *value)
Definition: db_macro.c:122
int pr_Enable_string_compression
unsigned int length
#define LANG_GET_BINARY_COLLATION(c)
int or_get_oid(OR_BUF *buf, OID *oid)
int or_put_domain(OR_BUF *buf, TP_DOMAIN *domain, int include_classoids, int is_null)
#define OR_PUT_NULL_LOG_LSA(ptr)
static int or_put_varbit_internal(OR_BUF *buf, const char *string, int bitlen, int align)
STATIC_INLINE int or_get_varchar_compression_lengths(OR_BUF *buf, int *compressed_size, int *decompressed_size) __attribute__((ALWAYS_INLINE))
#define DB_SET_ENUM_ELEM_STRING(elem, str)
Definition: dbtype.h:116
int or_get_offset_internal(OR_BUF *buf, int *error, int offset_size)
#define OR_BINARY_MAX_LENGTH
char * or_unpack_int_array(char *ptr, int n, int **number_array)
int or_disk_set_size(OR_BUF *buf, TP_DOMAIN *set_domain, DB_TYPE *set_type)
void or_encode(char *buffer, const char *source, int size)
struct qmgr_temp_file * tfile_vfid
Definition: query_list.h:440
void or_put_set(OR_BUF *buf, setobj *set, int include_domain)
int or_get_datetime(OR_BUF *buf, DB_DATETIME *datetime)
#define ASSERT_ERROR()
#define ER_IO_LZ4_COMPRESS_FAIL
Definition: error_code.h:1118
QFILE_TUPLE_VALUE_TYPE_LIST type_list
Definition: query_list.h:428
int tp_get_fixed_precision(DB_TYPE domain_type)
const char * fileio_get_zip_level_string(FILEIO_ZIP_LEVEL zip_level)
Definition: file_io.c:10774
#define OR_DOMAIN_SCALE_MAX
QUERY_ID query_id
Definition: query_list.h:438
MOP ws_mop(const OID *oid, MOP class_mop)
Definition: work_space.c:614
static int or_put_varchar_internal(OR_BUF *buf, char *string, int charlen, int align)
int data_writeval(struct or_buf *buf, const DB_VALUE *value) const
char * or_pack_bool_array(char *ptr, const bool *bools, int size)
char * or_pack_method_sig_list(char *ptr, void *method_sig_list_ptr)
const char * schema_raw
Definition: dbtype_def.h:1039
char * or_pack_mvccid(char *ptr, const MVCCID mvccid)
METHOD_SIG * method_sig
Definition: method_def.hpp:69
unsigned char codeset
Definition: object_domain.h:91
char * or_unpack_stream(char *ptr, char *stream, size_t len)
#define FLOAT_ALIGNMENT
Definition: memory_alloc.h:63
char * or_pack_listid(char *ptr, void *listid_ptr)
static int or_varbit_length_internal(int bitlen, int align)
int or_get_json_schema(OR_BUF *buf, REFPTR(char, schema))
#define ER_TF_BUFFER_OVERFLOW
Definition: error_code.h:388
int or_listid_length(void *listid_ptr)
const char * fileio_get_zip_method_string(FILEIO_ZIP_METHOD zip_method)
Definition: file_io.c:10747
static char * or_pack_method_sig(char *ptr, void *method_sig_ptr)
PAGEID DKNPAGES
unsigned int htonl(unsigned int from)
#define OR_GET_OFFSET(ptr)
size_t align(size_t v)
Definition: align.h:19
char * method_name
Definition: method_def.hpp:57
int or_header_size(char *ptr)
char * or_pack_string(char *ptr, const char *string)
DB_TYPE
Definition: dbtype_def.h:670
int or_pad(OR_BUF *buf, int length)
unsigned short count
Definition: dbtype_def.h:1033
#define ER_FAILED
Definition: error_code.h:47
#define OR_GET_LOG_LSA(ptr, lsa)
UINT64 htond(double from)
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)
char * or_unpack_recdes(char *buf, RECDES **recdes)
#define OR_DOMAIN_NULL_FLAG
char * or_pack_double(char *ptr, double number)
#define OR_GET_TIMESTAMPTZ(ptr, ts_tz)
#define OR_MVCC_REPID_MASK
int or_put_date(OR_BUF *buf, DB_DATE *date)
int or_get_monetary(OR_BUF *buf, DB_MONETARY *monetary)
double ntohd(UINT64 from)
struct tp_domain * setdomain
Definition: object_domain.h:82
#define OR_BUF_INIT(buf, data, size)
#define OR_HFID_SIZE
int or_rep_id(RECDES *record)
#define OR_IS_STRING_LENGTH_COMPRESSABLE(str_length)
static TP_DOMAIN * unpack_domain(OR_BUF *buf, int *is_null)
TP_DOMAIN * tp_domain_find_enumeration(const DB_ENUMERATION *enumeration, bool is_desc)
#define OR_PUT_EHID(ptr, ehid)
#define OR_SET_DOMAIN_BIT
#define OR_CHN_SIZE
#define assert_release(e)
Definition: error_manager.h:96
void OR_PUT_DOUBLE(char *ptr, double val)
int or_get_date(OR_BUF *buf, DB_DATE *date)
int setobj_get_element_ptr(COL *col, int index, DB_VALUE **result)
Definition: set_object.c:5708
DB_COLLECTION * setobj_get_reference(COL *set)
Definition: set_object.c:6247
#define OR_DOMAIN_SCHEMA_FLAG
#define SHORT_ALIGNMENT
Definition: memory_alloc.h:60
METHOD_TYPE method_type
Definition: method_def.hpp:59
int or_get_time(OR_BUF *buf, DB_TIME *timeval)
INT16 VOLID
#define MVCCID_NULL
int classobj_get_prop(DB_SEQ *properties, const char *name, DB_VALUE *pvalue)
void setobj_put_domain(COL *set, TP_DOMAIN *domain)
Definition: set_object.c:6193
int or_put_oid(OR_BUF *buf, const OID *oid)
#define OR_PUT_NULL_HFID(ptr)
#define OR_MVCCID_SIZE
#define OR_PTR_SIZE
char * or_pack_log_lsa(const char *ptr, const log_lsa *lsa)
#define OID_SET_NULL(oidp)
Definition: oid.h:85
char * or_pack_mem_value(char *ptr, DB_VALUE *value, int *packed_len_except_alignment)
unsigned is_cached
#define OR_MVCC_FLAG_SHIFT_BITS
TP_DOMAIN * tp_domain_resolve_value(const DB_VALUE *val, TP_DOMAIN *dbuf)
char * or_unpack_listid(char *ptr, void *listid_ptr)
int or_get_utime(OR_BUF *buf, DB_UTIME *timeval)
#define OR_DOMAIN_COLL_ENFORCE_FLAG
char * data
#define OR_INT64_SIZE
#define OR_DOUBLE_SIZE
char * or_pack_float(char *ptr, float number)
#define OR_GET_BYTE(ptr)
struct or_varinfo OR_VARINFO
int32_t pageid
Definition: dbtype_def.h:879
TP_DOMAIN * tp_domain_find_charbit(DB_TYPE type, int codeset, int collation_id, unsigned char collation_flag, int precision, bool is_desc)
char * or_pack_hfid(const char *ptr, const HFID *hfid)
UINT64 htoni64(UINT64 from)
char * or_pack_stream(char *ptr, const char *stream, size_t len)
int or_put_varchar(OR_BUF *buf, char *string, int charlen)
#define OR_PUT_SHA1(ptr, value)
int er_errid(void)
char * or_unpack_ehid(char *ptr, EHID *ehid)
#define OR_BOUND_BIT_BYTES(count)
#define OR_SHORT_SIZE
#define ER_TF_BUFFER_UNDERFLOW
Definition: error_code.h:387
#define PTR_ALIGN(addr, boundary)
Definition: memory_alloc.h:77
int set_size(DB_COLLECTION *set)
Definition: set_object.c:3036
int or_get_mvccid(OR_BUF *buf, MVCCID *mvccid)
#define OR_GET_UTIME(ptr, value)
int or_packed_enumeration_size(const DB_ENUMERATION *enumeration)
TP_DOMAIN tp_Null_domain
int or_skip_set_header(OR_BUF *buf)
#define OR_DOMAIN_PRECISION_SHIFT
int or_get_value(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int expected, bool copy)
float or_get_float(OR_BUF *buf, int *error)
int or_put_utime(OR_BUF *buf, DB_UTIME *timeval)
int or_get_int(OR_BUF *buf, int *error)
#define OR_VAR_OFFSET(obj, index)
METHOD_SIG * next
Definition: method_def.hpp:56
int or_put_value(OR_BUF *buf, DB_VALUE *value, int collapse_null, int include_domain, int include_domain_classoids)
TP_DOMAIN * tp_domain_find_set(DB_TYPE type, TP_DOMAIN *setdomain, bool is_desc)
#define OR_GET_MVCCID
void or_abort(OR_BUF *buf)
#define MAX_ALIGNMENT
Definition: memory_alloc.h:70
int or_skip_varbit(OR_BUF *buf, int align)
char * or_unpack_mvccid(char *ptr, MVCCID *mvccid)
char * or_pack_int64(char *ptr, INT64 number)
#define COPY_OID(dest_oid_ptr, src_oid_ptr)
Definition: oid.h:63
#define OR_MONETARY_SIZE
char * or_pack_value(char *buf, DB_VALUE *value)
char * or_pack_spacedb(char *ptr, const SPACEDB_ALL *all, const SPACEDB_ONEVOL *vols, const SPACEDB_FILES *files)
int mvcc_header_size_lookup[8]
int or_packed_recdesc_length(int length)
#define OR_FLOAT_SIZE
#define OR_BTID_SIZE
int or_packed_string_length(const char *string, int *strlenp)
#define OR_DOMAIN_CODSET_MASK
#define OR_PUT_PTR(ptr, val)
int or_packed_varbit_length(int bitlen)
#define CHAR_ALIGNMENT
Definition: memory_alloc.h:59
#define OR_PUT_DATETIMETZ(ptr, datetimetz)
DB_DEFAULT_EXPR_TYPE default_expr_type
Definition: dbtype_def.h:1204
char * or_pack_errcode(char *ptr, int error)
VOLID DKNVOLS
static int or_packed_json_validator_length(JSON_VALIDATOR *json_validator)
#define OR_DATETIME_SIZE
int or_packed_bool_array_length(const bool *bools, int size)
char * or_unpack_spacedb(char *ptr, SPACEDB_ALL *all, SPACEDB_ONEVOL **vols, SPACEDB_FILES *files)
char * or_unpack_unbound_listid(char *ptr, void **listid_ptr)
LOCK
#define OR_VAR_TABLE_SIZE(vars)
int or_varbit_length(int bitlen)
int db_make_string(DB_VALUE *value, DB_CONST_C_CHAR str)
int or_get_datetimetz(OR_BUF *buf, DB_DATETIMETZ *datetimetz)
DB_DATA data
Definition: dbtype_def.h:1083
int or_put_short(OR_BUF *buf, int num)
void or_init(OR_BUF *buf, char *data, int length)
#define OR_GET_BTID(ptr, btid)
#define OR_DOMAIN_PRECISION_MASK
DB_JSON json
Definition: dbtype_def.h:1073
int or_get_align32(OR_BUF *buf)
#define DOM_GET_ENUM_ELEMENTS(dom)
Definition: object_domain.h:40
static int or_packed_json_schema_length(const char *json_schema)
char * or_unpack_string_alloc(char *ptr, char **string)
PR_TYPE * pr_type_from_id(DB_TYPE id)
#define DB_MAX_VARBIT_PRECISION
Definition: dbtype_def.h:552
char * or_unpack_value(const char *buf, DB_VALUE *value)
char * or_pack_db_value(char *buffer, DB_VALUE *var)
TP_DOMAIN * tp_domain_resolve_default(DB_TYPE type)
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
static char * or_unpack_method_sig(char *ptr, void **method_sig_ptr, int n)
Definition: db_set.h:35
INTL_CODESET codeset
LANG_COLLATION * lang_get_collation(const int coll_id)
int or_packed_put_varchar(OR_BUF *buf, char *string, int charlen)
#define OR_SET_BOUND_BIT
#define OR_PUT_NULL_BTID(ptr)
#define DB_MAX_VARCHAR_PRECISION
Definition: dbtype_def.h:536
int tp_domain_match(const TP_DOMAIN *dom1, const TP_DOMAIN *dom2, TP_MATCH exact)
#define NULL_DEFAULT_EXPRESSION_OPERATOR
Definition: dbtype_def.h:659
int or_get_varbit_length(OR_BUF *buf, int *rc)
#define DB_MAX_NUMERIC_PRECISION
Definition: dbtype_def.h:522
TP_DOMAIN * or_get_domain(OR_BUF *buf, TP_DOMAIN *caller_dom, int *is_null)
#define assert(x)
int or_put_offset_internal(OR_BUF *buf, int num, int offset_size)
char * or_unpack_hfid(char *ptr, HFID *hfid)
#define DOM_SET_ENUM_ELEMENTS(dom, elems)
Definition: object_domain.h:47
char * or_unpack_sha1(char *ptr, SHA1Hash *sha1)
#define OR_BINARY_PAD_SHIFT
#define OR_MVCC_FLAG_MASK
#define DB_SET_ENUM_ELEM_STRING_SIZE(elem, sz)
Definition: dbtype.h:119
#define ASSERT_ALIGN(ptr, alignment)
char * or_pack_btid(char *ptr, const BTID *btid)
int or_get_set_header(OR_BUF *buf, DB_TYPE *set_type, int *size, int *domain, int *bound_bits, int *offset_table, int *element_tags, int *common_sub)
#define OR_PUT_NULL_OID(ptr)
int or_db_value_size(DB_VALUE *var)
DB_BIGINT or_get_bigint(OR_BUF *buf, int *error)
char * db_private_strdup(THREAD_ENTRY *thrd, const char *s)
Definition: memory_alloc.c:675
int or_put_double(OR_BUF *buf, double dnum)
#define ER_GENERIC_ERROR
Definition: error_code.h:49
#define OR_PUT_UTIME(ptr, value)
int or_Type_sizes[]
struct db_char::@52 info
TP_DOMAIN_COLL_ACTION
Definition: object_domain.h:62
#define OR_PUT_TIME(ptr, value)
int or_put_json_validator(OR_BUF *buf, JSON_VALIDATOR *validator)
struct db_object * class_mop
Definition: work_space.h:121
int or_put_datetime(OR_BUF *buf, DB_DATETIME *datetimeval)
int or_get_align(OR_BUF *buf, int align)
#define OR_SET_HEADER_SIZE
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
#define REFPTR(T, name)
Definition: porting.h:1089
const char * db_json_get_schema_raw_from_validator(JSON_VALIDATOR *val)
Definition: db_json.cpp:2310
#define OID_ISTEMP(oidp)
Definition: oid.h:80
float ntohf(UINT32 from)
#define DOM_GET_ENUMERATION(dom)
Definition: object_domain.h:38
int tp_domain_size(const TP_DOMAIN *domain)
int or_put_monetary(OR_BUF *buf, DB_MONETARY *monetary)
#define OR_PUT_MONETARY(ptr, value)
char * or_unpack_int(char *ptr, int *number)
#define PTR_ALIGNMENT
Definition: memory_alloc.h:68
#define OR_DOMAIN_COLLATION_MASK
unsigned is_desc
TP_DOMAIN * setobj_domain(COL *set)
Definition: set_object.c:6175
#define OR_GET_OID(ptr, oid)
void tp_init_value_domain(TP_DOMAIN *domain, DB_VALUE *value)
COL * setobj_create(DB_TYPE collection_type, int size)
Definition: set_object.c:4289
char * or_unpack_int64(char *ptr, INT64 *number)
int or_replace_chn(RECDES *record, int chn)
#define OR_GET_DATETIME(ptr, datetime)
#define DB_VALUE_DOMAIN_TYPE(value)
Definition: dbtype.h:70
#define DB_INT32_MAX
Definition: dbtype_def.h:633
#define OR_SET_TAG_BIT
int or_put_string_aligned_with_length(OR_BUF *buf, const char *str)
int or_put_mvccid(OR_BUF *buf, MVCCID mvccid)
#define OR_DOMAIN_ENUMERATION_FLAG
int or_mvcc_get_repid_and_flags(OR_BUF *buf, int *error)
struct recdes RECDES
#define TP_DOMAIN_COLLATION(dom)
#define OR_HEADER_SIZE(ptr)
#define ER_INVALID_CURRENCY_TYPE
Definition: error_code.h:756
int * method_arg_pos
Definition: method_def.hpp:61
#define OR_DOMAIN_COLL_LEAVE_FLAG
#define OR_DOMAIN_SCALE_SHIFT
char * or_unpack_float(char *ptr, float *number)
short volid
Definition: dbtype_def.h:880
char * or_unpack_btid(char *ptr, BTID *btid)
DKNPAGES npage_used
void classobj_initialize_default_expr(DB_DEFAULT_EXPR *default_expr)
int db_string_put_cs_and_collation(DB_VALUE *value, const int codeset, const int collation_id)
Definition: db_macro.c:4164
#define OR_MVCC_PREV_VERSION_LSA_SIZE
void or_decode(const char *buffer, char *dest, int size)
#define OR_DOMAIN_TYPE_MASK
#define DB_MAX_PATH_LENGTH
#define TP_DOMAIN_TYPE(dom)
static void cleanup(int signo)
Definition: broker.c:717
int or_put_bigint(OR_BUF *buf, DB_BIGINT num)
#define OR_SUB_HEADER_SIZE
char * or_pack_int(char *ptr, int number)
char * or_unpack_db_value(char *buffer, DB_VALUE *val)
#define NULL
Definition: freelistheap.h:34
int str_to_int32(int *ret_p, char **end_p, const char *str_p, int base)
Definition: porting.c:2346
double or_get_double(OR_BUF *buf, int *error)
UINT64 MVCCID
TP_DOMAIN * tp_domain_find_noparam(DB_TYPE type, bool is_desc)
int or_get_timestamptz(OR_BUF *buf, DB_TIMESTAMPTZ *ts_tz)
struct pr_type * type
Definition: object_domain.h:76
#define OR_GET_DATETIMETZ(ptr, datetimetz)
DB_CHAR ch
Definition: dbtype_def.h:1070
#define OR_INFINITE_POINTER
DB_CURRENCY type
Definition: dbtype_def.h:832
if(extra_options)
Definition: dynamic_load.c:958
#define OR_BIGINT_SIZE
int setobj_put_value(COL *col, int index, DB_VALUE *value)
Definition: set_object.c:6211
int or_set_rep_id(RECDES *record, int repid)
DKNPAGES npage_user
char * or_pack_ptr(char *ptr, UINTPTR ptrval)
unsigned short htons(unsigned short from)
int or_packed_stream_length(size_t len)
#define OR_PUT_TIMESTAMPTZ(ptr, ts_tz)
unsigned char * data
#define OR_GET_BIGINT(ptr, val)
#define OR_GET_FLOAT(ptr, value)
TP_DOMAIN * tp_domain_cache(TP_DOMAIN *transient)
char * or_unpack_var_table(char *ptr, int nvars, OR_VARINFO *vars)
#define db_private_free_and_init(thrd, ptr)
Definition: memory_alloc.h:141
#define OR_PUT_BTID(ptr, btid)
int or_chn(RECDES *record)
char * or_pack_ehid(char *ptr, EHID *ehid)
#define OR_REP_OFFSET
int or_put_float(OR_BUF *buf, float fnum)
UINT64 ntohi64(UINT64 from)
char * or_unpack_lock(char *ptr, LOCK *lock)
int or_put_enumeration(OR_BUF *buf, const DB_ENUMERATION *enumeration)
int or_put_set_header(OR_BUF *buf, DB_TYPE set_type, int size, int domain, int bound_bits, int offset_table, int element_tags, int common_sub_header)
char * or_unpack_oid(char *ptr, OID *oid)
#define db_private_alloc(thrd, size)
Definition: memory_alloc.h:227
#define CONST_CAST(dest_type, expr)
Definition: porting.h:1060
int set_get_element(DB_COLLECTION *set, int index, DB_VALUE *value)
Definition: set_object.c:2575
int or_put_timestamptz(OR_BUF *buf, DB_TIMESTAMPTZ *ts_tz)
int or_put_int(OR_BUF *buf, int num)
int or_packed_set_length(setobj *set, int include_domain)
#define BIG_VAR_OFFSET_SIZE
char * or_pack_domain(char *ptr, TP_DOMAIN *domain, int include_classoids, int is_null)
#define OR_PUT_SHORT(ptr, val)
#define OR_LOG_LSA_ALIGNED_SIZE
#define OR_PUT_DATE(ptr, value)
#define OR_GET_INT64(ptr, val)
#define OR_DOMAIN_BUILTIN_FLAG
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
int pr_clear_value(DB_VALUE *value)
#define OR_DOMAIN_CODSET_SHIFT
#define OR_GET_SHA1(ptr, value)
int or_skip_varbit_remainder(OR_BUF *buf, int bitlen, int align)
int or_overflow(OR_BUF *buf)
DB_TYPE setobj_type(struct setobj *set)
Definition: set_object.c:6158
#define DB_DEFAULT_SCALE
Definition: dbtype_def.h:561
int or_put_offset(OR_BUF *buf, int num)
#define NULL_REPRID
#define max(a, b)
int64_t DB_BIGINT
Definition: dbtype_def.h:751
int or_varchar_length(int charlen)
#define OR_CHN_OFFSET
#define CAST_BUFLEN
Definition: porting.h:471
char * or_unpack_string(char *ptr, char **string)
DB_ENUMERATION enumeration
Definition: object_domain.h:84
#define TP_IS_CHAR_TYPE(typeid)
TP_DOMAIN_COLL_ACTION collation_flag
Definition: object_domain.h:94
#define OR_GET_TIME(ptr, value)
static char * or_unpack_var_table_internal(char *ptr, int nvars, OR_VARINFO *vars, int offset_size)
DB_VOLPURPOSE
Definition: dbtype_def.h:185
int or_packed_value_size(const DB_VALUE *value, int collapse_null, int include_domain, int include_domain_classoids)
static void error(const char *msg)
Definition: gencat.c:331
static int rc
Definition: serial.c:50
#define DB_DEFAULT_PRECISION
Definition: dbtype_def.h:558
#define DB_GET_ENUM_ELEM_STRING_SIZE(elem)
Definition: dbtype.h:105
TP_DOMAIN * tp_domain_construct(DB_TYPE domain_type, DB_OBJECT *class_obj, int precision, int scale, TP_DOMAIN *setdomain)
char * or_unpack_domain(char *ptr, struct tp_domain **domain_ptr, int *is_null)
#define OR_SET_COMMON_SUB_BIT
#define BITS_TO_BYTES(bit_cnt)
#define OR_GET_OFFSET_INTERNAL(ptr, offset_size)
#define ARG_FILE_LINE
Definition: error_manager.h:44
#define OR_PUT_MVCCID
PR_TYPE tp_String
#define OR_BYTE_SIZE
char * or_pack_sha1(char *ptr, const SHA1Hash *sha1)
char * or_unpack_bool_array(char *ptr, bool **bools)
#define OR_UTIME_SIZE
const char * default_expr_format
Definition: dbtype_def.h:1206
#define OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION
DB_VOLTYPE
Definition: dbtype_def.h:192
char * or_unpack_log_lsa(char *ptr, log_lsa *lsa)
char * or_pack_recdes(char *buf, RECDES *recdes)
unsigned int DB_TIME
Definition: dbtype_def.h:754
TP_DOMAIN * tp_domain_find_numeric(DB_TYPE type, int precision, int scale, bool is_desc)
static TP_DOMAIN * unpack_domain_2(OR_BUF *buf, int *is_null)
#define OR_EHID_SIZE
int or_put_time(OR_BUF *buf, DB_TIME *timeval)
#define OR_PUT_HFID(ptr, hfid)
DKNPAGES npage_reserved
unsigned short ntohs(unsigned short from)
OR_VARINFO * or_get_var_table(OR_BUF *buf, int nvars, char *(*allocator)(int))
unsigned int DB_DATE
Definition: dbtype_def.h:771
int or_method_sig_list_length(void *method_sig_list_ptr)
#define OR_GET_INT(ptr)
char * or_pack_short(char *ptr, short number)
#define OR_DOMAIN_DESC_FLAG
int or_align(OR_BUF *buf, int alignment)
int or_seek(OR_BUF *buf, int psn)
#define OR_SET_VARIABLE_BIT
#define DB_SET_ENUM_ELEM_CODESET(elem, cs)
Definition: dbtype.h:111
#define OR_PUT_LOG_LSA(ptr, lsa)
UINT32 htonf(float from)
#define OR_DOMAIN_SET_DOMAIN_FLAG
char * or_class_name(RECDES *record)
#define free_and_init(ptr)
Definition: memory_alloc.h:147
char * or_unpack_setref(char *ptr, DB_SET **ref)
#define DB_ALIGN(offset, align)
Definition: memory_alloc.h:84
#define strlen(s1)
Definition: intl_support.c:43
#define OR_PUT_INT64(ptr, val)
#define OR_GET_MVCC_FLAG(ptr)
#define OR_GET_EHID(ptr, ehid)
DB_ENUM_ELEMENT * elements
Definition: dbtype_def.h:1031
#define OR_DOMAIN_PRECISION_MAX
int or_skip_varchar(OR_BUF *buf, int align)
#define OR_GET_MVCC_CHN(ptr)
int db_enum_put_cs_and_collation(DB_VALUE *value, const int codeset, const int collation_id)
Definition: db_macro.c:4191
int or_put_datetimetz(OR_BUF *buf, DB_DATETIMETZ *datetimetz)
int or_put_string_aligned(OR_BUF *buf, char *str)
#define OR_TIMESTAMPTZ_SIZE
#define INT_ALIGNMENT
Definition: memory_alloc.h:61
#define OR_MVCC_REP_SIZE
char * or_unpack_hfid_array(char *ptr, int n, HFID **hfids)
#define OR_DOMAIN_CLASS_OID_FLAG
JSON_VALIDATOR * json_validator
#define OR_PUT_INT(ptr, val)
int db_json_load_validator(const char *json_schema_raw, JSON_VALIDATOR *&validator)
Definition: db_json.cpp:2362
int db_get_string_size(const DB_VALUE *value)
#define OR_GET_DOUBLE(ptr, value)
int classobj_decompose_property_oid(const char *buffer, int *volid, int *fileid, int *pageid)
char * or_pack_lock(char *ptr, LOCK lock)
int or_skip_varchar_remainder(OR_BUF *buf, int charlen, int align)
void tp_domain_clear_enumeration(DB_ENUMERATION *enumeration)
#define OR_DATETIMETZ_SIZE
int or_get_offset(OR_BUF *buf, int *error)
#define TP_FLOATING_PRECISION_VALUE
int or_get_varchar_length(OR_BUF *buf, int *rc)
void or_packed_set_info(DB_TYPE set_type, TP_DOMAIN *domain, int include_domain, int *bound_bits, int *offset_table, int *element_tags, int *element_size)
#define OR_GET_MVCC_REPID_AND_FLAG(ptr)
#define DB_VALUE_TYPE(value)
Definition: dbtype.h:72
int or_get_byte(OR_BUF *buf, int *error)
#define OR_GET_MVCC_REPID(ptr)
int i
Definition: dynamic_load.c:954
char * or_unpack_method_sig_list(char *ptr, void **method_sig_list_ptr)
int db_make_null(DB_VALUE *value)
int or_put_json_schema(OR_BUF *buf, const char *schema)
int or_packed_put_varbit(OR_BUF *buf, const char *string, int bitlen)
struct tp_domain * next
Definition: object_domain.h:74
DKNPAGES npage_ftab
INT16 type
char * or_unpack_string_nocopy(char *ptr, char **string)
#define OR_GET_MONETARY(ptr, value)
DKNPAGES npage_free
#define DB_MAX_VARNCHAR_PRECISION
Definition: dbtype_def.h:546
char * or_pack_string_with_null_padding(char *ptr, const char *string, size_t len)
int or_get_short(OR_BUF *buf, int *error)
char * or_pack_oid(char *ptr, const OID *oid)
unsigned int ntohl(unsigned int from)
struct db_object * class_mop
Definition: object_domain.h:81
static int or_varchar_length_internal(int charlen, int align)
#define OR_BOUND_BIT_FLAG
unsigned short short_val
Definition: dbtype_def.h:1023
char * or_unpack_set(char *ptr, setobj **set, TP_DOMAIN *domain)
#define OR_PUT_BIGINT(ptr, val)
DB_TIMESTAMP DB_UTIME
Definition: dbtype_def.h:761
char * or_unpack_ptr(char *ptr, UINTPTR *ptrval)
#define TP_DOMAIN_CODESET(dom)
int collation_id
Definition: object_domain.h:92
#define OR_GET_PTR(ptr)
#define OR_LOG_LSA_SIZE
#define DOM_SET_ENUM_ELEMS_COUNT(dom, cnt)
Definition: object_domain.h:49
char * or_unpack_errcode(char *ptr, int *error)
int or_put_byte(OR_BUF *buf, int num)
#define DB_GET_ENUM_ELEM_CODESET(elem)
Definition: dbtype.h:108
SECTID DKNSECTS
char * or_unpack_double(char *ptr, double *number)
#define OR_PUT_DATETIME(ptr, datetime)
int setobj_size(COL *col)
Definition: set_object.c:4948
int or_get_align64(OR_BUF *buf)
char * or_unpack_mem_value(char *ptr, DB_VALUE *value)
#define DB_GET_ENUM_ELEM_DBCHAR(elem)
Definition: dbtype.h:101
#define OR_DOMAIN_NEXT_FLAG
int or_mvcc_set_repid_and_flags(OR_BUF *buf, int mvcc_flag, int repid, int bound_bit, int variable_offset_size)
int or_packed_domain_size(TP_DOMAIN *domain, int include_classoids)
const char ** p
Definition: dynamic_load.c:945
char * or_pack_oid_array(char *ptr, int n, const OID *oids)
#define OR_DATE_SIZE
void tp_domain_free(TP_DOMAIN *dom)
DB_CONST_C_CHAR db_get_string(const DB_VALUE *value)
TP_DOMAIN * tp_domain_find_object(DB_TYPE type, OID *class_oid, struct db_object *class_mop, bool is_desc)
int or_underflow(OR_BUF *buf)
int or_get_enumeration(OR_BUF *buf, DB_ENUMERATION *enumeration)
#define OR_GET_SHORT(ptr)
int or_put_varbit(OR_BUF *buf, const char *string, int bitlen)
#define OR_GET_BOUND_BIT(bitptr, element)
int get_disk_size_of_value(const DB_VALUE *value) const
int or_packed_varchar_length(int charlen)
#define OR_PUT_BYTE(ptr, val)
int or_get_data(OR_BUF *buf, char *data, int length)
int or_get_json_validator(OR_BUF *buf, REFPTR(JSON_VALIDATOR, validator))
#define OR_DOMAIN_ENUM_COLL_FLAG
int db_value_domain_init(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale)
Definition: db_macro.c:153
char * or_pack_string_with_length(char *ptr, const char *string, int length)
#define ER_SM_INVALID_PROPERTY
Definition: error_code.h:368